Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.

[XP] Map Tile Setter

Ver el tema anterior Ver el tema siguiente Ir abajo

[XP] Map Tile Setter

Mensaje por Wecoc el 2018-02-09, 21:18

Este script permite cambiar los tiles del mapa de modo que los autotiles no pierden su propiedad de enlazarse correctamente entre sí.
Es muy fácil de usar, solo seguid las instrucciones.

Código:
#==============================================================================
# ** [XP] Map Tile Setter v1.0
#------------------------------------------------------------------------------
# Este script permite cambiar los tiles del mapa a mitad del juego de modo
# que los autotiles no pierden su propiedad de enlazarse correctamente entre sí.
# Para usarlo se pueden usar las siguientes llamadas de script:
# * Asignar un tile en el mapa
#   $game_map.set_tile(x, y, layer, tile_id)
#         x, y:    Coorenadas del mapa
#         layer:   Capa (0 - abajo, 1 - intermedia, 2 - arriba)
#         tile_id: ID del tile, ya sea 0 para "blanco" o mayor de 384
#                  para cualquier tile del tileset
# * Asignar un autotile en el mapa
#   $game_map.set_autotile(x, y, layer, autotile_id)
#         autotile_id: ID del autotile, de 1 a 7
# * Definir si la propiedad de autocompletar los autotiles está activa o no
#   $game_system.autotile_autocomplete = true / false
#------------------------------------------------------------------------------
# Autor: Wecoc (no requiere créditos)
#==============================================================================

#==============================================================================
# ** AutotileData
#==============================================================================

module AutotileData
  module_function
  #----------------------------------------------------------------------------
  SUBTILES =
  {0  => [27, 28, 33, 34], 1  => [ 5, 28, 33, 34], 2  => [27,  6, 33, 34],
   3  => [ 5,  6, 33, 34], 4  => [27, 28, 33, 12], 5  => [ 5, 28, 33, 12],
   6  => [27,  6, 33, 12], 7  => [ 5,  6, 33, 12], 8  => [27, 28, 11, 34],
   9  => [ 5, 28, 11, 34], 10 => [27,  6, 11, 34], 11 => [ 5,  6, 11, 34],
   12 => [27, 28, 11, 12], 13 => [ 5, 28, 11, 12], 14 => [27,  6, 11, 12],
   15 => [ 5,  6, 11, 12], 16 => [25, 26, 31, 32], 17 => [25,  6, 31, 32],
   18 => [25, 26, 31, 12], 19 => [25,  6, 31, 12], 20 => [15, 16, 21, 22],
   21 => [15, 16, 21, 12], 22 => [15, 16, 11, 22], 23 => [15, 16, 11, 12],
   24 => [29, 30, 35, 36], 25 => [29, 30, 11, 36], 26 => [ 5, 30, 35, 36],
   27 => [ 5, 30, 11, 36], 28 => [39, 40, 45, 46], 29 => [ 5, 40, 45, 46],
   30 => [39,  6, 45, 46], 31 => [ 5,  6, 45, 46], 32 => [25, 30, 31, 36],
   33 => [15, 16, 45, 46], 34 => [13, 14, 19, 20], 35 => [13, 14, 19, 12],
   36 => [17, 18, 23, 24], 37 => [17, 18, 11, 24], 38 => [41, 42, 47, 48],
   39 => [ 5, 42, 47, 48], 40 => [37, 38, 43, 44], 41 => [37,  6, 43, 44],
   42 => [13, 18, 19, 24], 43 => [13, 14, 43, 44], 44 => [37, 42, 43, 48],
   45 => [17, 18, 47, 48], 46 => [13, 18, 43, 48], 47 => [ 1,  2,  7,  8]}
  #----------------------------------------------------------------------------
  n = nil
  NEIGHBORTILES =
  {0  => [1, 1, 1,  1, n, 1,  1, 1, 1], 1  => [0, 1, 1,  1, n, 1,  1, 1, 1],
   2  => [1, 1, 0,  1, n, 1,  1, 1, 1], 3  => [0, 1, 0,  1, n, 1,  1, 1, 1],
   4  => [1, 1, 1,  1, n, 1,  1, 1, 0], 5  => [0, 1, 1,  1, n, 1,  1, 1, 0],
   6  => [1, 1, 0,  1, n, 1,  1, 1, 0], 7  => [0, 1, 0,  1, n, 1,  1, 1, 0],
   8  => [1, 1, 1,  1, n, 1,  0, 1, 1], 9  => [0, 1, 1,  1, n, 1,  0, 1, 1],
   10 => [1, 1, 0,  1, n, 1,  0, 1, 1], 11 => [0, 1, 0,  1, n, 1,  0, 1, 1],
   12 => [1, 1, 1,  1, n, 1,  0, 1, 0], 13 => [0, 1, 1,  1, n, 1,  0, 1, 0],
   14 => [1, 1, 0,  1, n, 1,  0, 1, 0], 15 => [0, 1, 0,  1, n, 1,  0, 1, 0],
   16 => [n, 1, 1,  0, n, 1,  n, 1, 1], 17 => [n, 1, 0,  0, n, 1,  n, 1, 1],
   18 => [n, 1, 1,  0, n, 1,  n, 1, 0], 19 => [n, 1, 0,  0, n, 1,  n, 1, 0],
   20 => [n, 0, n,  1, n, 1,  1, 1, 1], 21 => [n, 0, n,  1, n, 1,  1, 1, 0],
   22 => [n, 0, n,  1, n, 1,  0, 1, 1], 23 => [n, 0, n,  1, n, 1,  0, 1, 0],
   24 => [1, 1, n,  1, n, 0,  1, 1, n], 25 => [1, 1, n,  1, n, 0,  0, 1, n],
   26 => [0, 1, n,  1, n, 0,  1, 1, n], 27 => [0, 1, n,  1, n, 0,  0, 1, n],
   28 => [1, 1, 1,  1, n, 1,  n, 0, n], 29 => [0, 1, 1,  1, n, 1,  n, 0, n],
   30 => [1, 1, 0,  1, n, 1,  n, 0, n], 31 => [0, 1, 0,  1, n, 1,  n, 0, n],
   32 => [n, 1, n,  0, n, 0,  n, 1, n], 33 => [n, 0, n,  1, n, 1,  n, 0, n],
   34 => [n, 0, n,  0, n, 1,  n, 1, 1], 35 => [n, 0, n,  0, n, 1,  n, 1, 0],
   36 => [n, 0, n,  1, n, 0,  1, 1, n], 37 => [n, 0, n,  1, n, 0,  0, 1, n],
   38 => [1, 1, n,  1, n, 0,  n, 0, n], 39 => [0, 1, n,  1, n, 0,  n, 0, n],
   40 => [n, 1, 1,  0, n, 1,  n, 0, n], 41 => [n, 1, 0,  0, n, 1,  n, 0, n],
   42 => [n, 0, n,  0, n, 0,  n, 1, n], 43 => [n, 0, n,  0, n, 1,  n, 0, n],
   44 => [n, 1, n,  0, n, 0,  n, 0, n], 45 => [n, 0, n,  1, n, 0,  n, 0, n],
   46 => [n, 0, n,  0, n, 0,  n, 0, n]}
  #--------------------------------------------------------------------------
  # * [Interno] Obtener autotile correcto según los de alrededor
  #--------------------------------------------------------------------------
  def get_autotile_frame(pattern)
    result = NEIGHBORTILES.values.clone
    for i in 0...9
      next if pattern[i].nil?
      result.delete_if{|x| x[i] != nil && x[i] != pattern[i]}
    end
    return nil if result.size == 0
    return NEIGHBORTILES.key(result[0])
  end
end

#==============================================================================
# ** Hash
#==============================================================================

class Hash
  def key(value)
    for k in self.keys
      return k if self[k] == value
    end
    return nil
  end
end

#==============================================================================
# ** Game_System
#==============================================================================

class Game_System
  attr_accessor :autotile_autocomplete
  alias autotile_comp_ini initialize unless $@
  def initialize
    autotile_comp_ini
    @autotile_autocomplete = true
  end
end

#==============================================================================
# ** Game_Map
#==============================================================================

class Game_Map
  #--------------------------------------------------------------------------
  # * [Interno] Obtener autotile actual del mapa en una det. coordenada
  #--------------------------------------------------------------------------
  def get_autotile(x, y, layer=0)
    tile = self.data[x, y, layer]
    return nil if tile.nil? or tile >= 384 or tile == 0
    return tile
  end
  #--------------------------------------------------------------------------
  # * [Interno] Obtener tile actual del mapa en una det. coordenada
  #--------------------------------------------------------------------------
  def get_tile(x, y, layer=0)
    tile = self.data[x, y, layer]
    return nil if tile.nil? or (tile < 384 and tile != 0)
    return tile
  end
  #--------------------------------------------------------------------------
  # * [Interno] Arreglar autotile según los de alrededor
  #--------------------------------------------------------------------------
  def fix_autotile(x, y, layer, autotile_id)
    pattern = []
    for iy in -1..1
      for ix in -1..1
        tile = self.data[x + ix, y + iy, layer]
        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[x, y, layer] = autotile_id * 48 + frame
  end
  #--------------------------------------------------------------------------
  # * [Interno] Comprobar si dos autotiles son el mismo
  #--------------------------------------------------------------------------
  def same_autotile?(a, b)
    return true if a == b
    return false
  end
  #--------------------------------------------------------------------------
  # * Asignar tile en el mapa
  #--------------------------------------------------------------------------
  def set_tile(x, y, layer, new_tile)
    tile = self.data[x, y, layer]
    return nil if tile.nil? or (new_tile < 384 and new_tile != 0)
    autotile = get_autotile(x, y, layer)
    self.data[x, y, layer] = 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[x + ix, y + iy, layer]
        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
    end
  end
  #--------------------------------------------------------------------------
  # * Asignar autotile en el mapa
  #--------------------------------------------------------------------------
  def set_autotile(x, y, layer, new_autotile_id)
    tile = self.data[x, y, layer]
    return nil if tile.nil? or (new_autotile_id < 1 and new_autotile_id > 7)
    self.data[x, y, layer] = (new_autotile_id) * 48
    return unless $game_system.autotile_autocomplete
    for iy in -1..1
      for ix in -1..1
        current = self.data[x + ix, y + iy, layer]
        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
    end
  end
end

#==============================================================================
# ** Bugfix - Autotiles enlazados (Opcional)
#==============================================================================

class Bitmap
  def 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 true
  end
end

class Game_Map
  alias shared_tiles_setup setup unless $@
  def setup(*args)
    shared_tiles_setup(*args)
    @shared_tiles = {}
    for i in 0...7
      autotile = @autotile_names[i]
      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[j]
        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[j].push(i)
          else
            @shared_tiles[j] = [i]
          end
        end
      end
    end
  end
  
  def same_autotile?(a, b)
    return true if a == b
    if @shared_tiles.keys.include?(a)
      return true if @shared_tiles[a].include?(b)
    end
    return false
  end
end

Para que entendáis mejor qué hace el script:
Por defecto para cambiar un tile en el mapa se hace usando $game_map.data[x, y, layer] = ID
Si usando eso intentáis asignar un tile de hierba donde antes había agua, ocurrirá algo así:



Eso sigue funcionando como siempre.
Pero en cambio si usáis el script con autocompletar activado y ésta llamada $game_map.set_tile(x, y, layer, ID)
Entonces intentando exactamente lo mismo ocurrirá lo siguiente:



Además la última parte del script (que es opcional) hace que también vaya bien lo de varios autotiles enlazados mediante el tile central, tal como ocurre en el editor por defecto.
avatar
Wecoc
Administrador
Administrador



Créditos 12334

Gracias : 578

Volver arriba Ir abajo

Re: [XP] Map Tile Setter

Mensaje por Jeffthelove el 2018-02-09, 23:19

Por fin algo que si es útil tener en el XP Very Happy , gracias wecoc por este script tan hermoso y útil.

Wecoc, sigue haciendo scripts como el chigüire mayor manda Cool
avatar
Jeffthelove
Iniciado
Iniciado

0/3

Créditos 32

Gracias : 5

Volver arriba Ir abajo

Re: [XP] Map Tile Setter

Mensaje por xXIsrael0499Xx el 2018-02-10, 10:00

Oh vaya, esto es de mi interés...
Luego probare a si bien a lo loco para ver si no hay ningún fallo que me vaya a molestar a futuro.

Saludos
avatar
xXIsrael0499Xx
Veterano
Veterano

0/3

Créditos 1171

Gracias : 87

Volver arriba Ir abajo

Re: [XP] Map Tile Setter

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


Permisos de este foro:
No puedes responder a temas en este foro.