じ☆ve冰风 发表于 2026-7-11 13:14:39

Map Tile Setter

This script allows to change the tiles on the map in a way that the autotiles don't lose their property to join properly.

Author: Wecoc
First Release: February 2018
Last Version: February 2018

Terms of use
- Giving credits (Wecoc) for using this script is optional, but appreciated.
- You can repost this code.
- You can edit this code freely, and distribute the edits as well.
- This code can be used on commercial games.

                Ruby:       
#==============================================================================# ** Map Tile Setter v1.0#------------------------------------------------------------------------------# This script allows to change the tiles on the map in a way that the autotiles# don't lose their property to join properly.#------------------------------------------------------------------------------# Script calls:# * Set tile#   $game_map.set_tile(x, y, layer, tile_id)#         x, y:    Map coordinates#         layer:   Map layer (0 - bottom, 1 - middle, 2 - top)#         tile_id: Tile ID, either 0 for blank or greater than 384 for any tile#                  on the tileset# * Set autotile#   $game_map.set_autotile(x, y, layer, autotile_id)#         autotile_id: Autotile index, from 1 to 7# * Change the property to autocomplete the autotiles#   $game_system.autotile_autocomplete = true / false#------------------------------------------------------------------------------# Author: Wecoc (no credits required)#==============================================================================#==============================================================================# ** AutotileData#==============================================================================module AutotileDatamodule_function#----------------------------------------------------------------------------SUBTILES ={0=> , 1=> [ 5, 28, 33, 34], 2=> ,   3=> [ 5,6, 33, 34], 4=> , 5=> [ 5, 28, 33, 12],   6=> , 7=> [ 5,6, 33, 12], 8=> ,   9=> [ 5, 28, 11, 34], 10 => , 11 => [ 5,6, 11, 34],   12 => , 13 => [ 5, 28, 11, 12], 14 => ,   15 => [ 5,6, 11, 12], 16 => , 17 => ,   18 => , 19 => , 20 => ,   21 => , 22 => , 23 => ,   24 => , 25 => , 26 => [ 5, 30, 35, 36],   27 => [ 5, 30, 11, 36], 28 => , 29 => [ 5, 40, 45, 46],   30 => , 31 => [ 5,6, 45, 46], 32 => ,   33 => , 34 => , 35 => ,   36 => , 37 => , 38 => ,   39 => [ 5, 42, 47, 48], 40 => , 41 => ,   42 => , 43 => , 44 => ,   45 => , 46 => , 47 => [ 1,2,7,8]}#----------------------------------------------------------------------------n = nilNEIGHBORTILES ={0=> , 1=> ,   2=> , 3=> ,   4=> , 5=> ,   6=> , 7=> ,   8=> , 9=> ,   10 => , 11 => ,   12 => , 13 => ,   14 => , 15 => ,   16 => , 17 => ,   18 => , 19 => ,   20 => , 21 => ,   22 => , 23 => ,   24 => , 25 => ,   26 => , 27 => ,   28 => , 29 => ,   30 => , 31 => ,   32 => , 33 => ,   34 => , 35 => ,   36 => , 37 => ,   38 => , 39 => ,   40 => , 41 => ,   42 => , 43 => ,   44 => , 45 => ,   46 => }#--------------------------------------------------------------------------# * Get the autotile frame based on the sorroundings#--------------------------------------------------------------------------def get_autotile_frame(pattern)    result = NEIGHBORTILES.values.clone    for i in 0...9      next if pattern.nil?      result.delete_if{|x| x != nil && x != pattern}    end    return nil if result.size == 0    return NEIGHBORTILES.key(result)endend#==============================================================================# ** Hash#==============================================================================class Hashdef key(value)    for k in self.keys      return k if self == value    end    return nilendend#==============================================================================# ** Game_System#==============================================================================class Game_Systemattr_accessor :autotile_autocompletealias autotile_comp_ini initialize unless $@def initialize    autotile_comp_ini    @autotile_autocomplete = trueendend#==============================================================================# ** Game_Map#==============================================================================class Game_Map#--------------------------------------------------------------------------# * Get autotile#--------------------------------------------------------------------------def get_autotile(x, y, layer=0)    tile = self.data    return nil if tile.nil? or tile >= 384 or tile == 0    return tileend#--------------------------------------------------------------------------# * Get tile#--------------------------------------------------------------------------def get_tile(x, y, layer=0)    tile = self.data    return nil if tile.nil? or (tile < 384 and tile != 0)    return tileend#--------------------------------------------------------------------------# * Fix autotile based on sorroundings#--------------------------------------------------------------------------def fix_autotile(x, y, layer, autotile_id)    pattern = []    for iy in -1..1      for ix in -1..1      tile = self.data      if tile == nil or (ix == 0 && iy == 0)          pattern.push(nil)          next      end      if tile < 384 && same_autotile?((tile.to_f / 48).floor, autotile_id)          pattern.push(1)      else          pattern.push(0)      end      end    end    frame = AutotileData.get_autotile_frame(pattern)    return if frame.nil?    self.data = autotile_id * 48 + frameend#--------------------------------------------------------------------------# * Check if two autotiles are the same#--------------------------------------------------------------------------def same_autotile?(a, b)    return true if a == b    return falseend#--------------------------------------------------------------------------# * Set tile#--------------------------------------------------------------------------def set_tile(x, y, layer, new_tile)    tile = self.data    return nil if tile.nil? or (new_tile < 384 and new_tile != 0)    autotile = get_autotile(x, y, layer)    self.data = new_tile    return unless $game_system.autotile_autocomplete    return if autotile.nil?    autotile_id = (tile.to_f / 48).floor    for iy in -1..1      for ix in -1..1      current = self.data      next if current.nil?      next if current >= 384 or current == 0      next if !same_autotile?((current.to_f / 48).floor, autotile_id)      fix_autotile(x + ix, y + iy, layer, autotile_id)      end    endend#--------------------------------------------------------------------------# * Set autotile#--------------------------------------------------------------------------def set_autotile(x, y, layer, new_autotile_id)    tile = self.data    return nil if tile.nil? or (new_autotile_id < 1 and new_autotile_id > 7)    self.data = (new_autotile_id) * 48    return unless $game_system.autotile_autocomplete    for iy in -1..1      for ix in -1..1      current = self.data      next if current.nil?      next if current >= 384 or current == 0      autotile_id = (current.to_f / 48).floor      fix_autotile(x + ix, y + iy, layer, autotile_id)      end    endendend#==============================================================================# ** Bugfix for autotiles that are bound together (like RTP Ocean)#==============================================================================class Bitmapdef same_as?(bitmap, check_max = nil)    return false if self.width != bitmap.width or self.height != bitmap.height    i = 0    for iy in 0...self.height      for ix in 0...self.width      i += 1      a = self.get_pixel(ix, iy)      b = bitmap.get_pixel(ix, iy)      return false if a != b      return true if (check_max != nil && i >= check_max)      end    end    return trueendendclass Game_Mapalias shared_tiles_setup setup unless $@def setup(*args)    shared_tiles_setup(*args)    @shared_tiles = {}    for i in 0...7      autotile = @autotile_names      next if autotile.nil?      autotile = RPG::Cache.autotile(autotile)      next if autotile.height == 32      tile = Bitmap.new(32, 32)      tile.blt(0, 0, autotile, Rect.new(0, 0, 32, 32))      for j in 0...7      next if i == j      autotile = @autotile_names      next if autotile.nil?      autotile = RPG::Cache.autotile(autotile)      next if autotile.height == 32      shared = Bitmap.new(32, 32)      shared.blt(0, 0, autotile, Rect.new(32, 0, 32, 32))      if tile.same_as?(shared, 32)          if @shared_tiles.keys.include?(tile)            @shared_tiles.push(i)          else            @shared_tiles =           end      end      end    endend   def same_autotile?(a, b)    return true if a == b    if @shared_tiles.keys.include?(a)      return true if @shared_tiles.include?(b)    end    return falseendend


I think the best way to explain what this script does is with images.

By default you can change the map tile using $game_map.data = ID
If you try to set a grass tile over a water tile, this will happen:





This still works as always, I didn't change any of that.
But now, with this script you have the option to use this call instead: $game_map.set_tile(x, y, layer, ID)
If you have the autocomplete flag activated on the script, now this will happen:





The last part of the script is optional and allows bounded autotiles (like the RTP Ocean) to work properly as well, this way it works exactly like in the editor.


本贴来自国际rpgmaker官方论坛作者:Wecoc处,因国际论坛即将永久关站,为了存档多年珍贵资料,署名转载到本论坛存档,由于官方帖子为英文原帖,需要中文翻译请点击论坛顶部切换语言为中文就可以将帖子翻译成中文浏览,方便大家随时查看,原文地址:https://forums.rpgmakerweb.com/threads/map-tile-setter.138723/
页: [1]
查看完整版本: Map Tile Setter