Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.

[XP] Control de pasabilidad por mapa

Ver el tema anterior Ver el tema siguiente Ir abajo

RPG Maker XP [XP] Control de pasabilidad por mapa

Mensaje por Wecoc el 2015-09-07, 08:03

Éste script permite controlar la pasabilidad, prioridad y terrain tag de los tiles del mapa actual mediante llamadas de script.
No es para novatos, si no sabéis cómo van los IDs de los tiles (tutorial), los valores de las pasabilidades (bueno, eso no lo sé ni yo xD haré una tabla pronto), las prioridades y los IDs de terreno no podréis usar todas sus funciones.

Con $game_map.set_passage defines la pasabilidad de un tile en concreto, por ejemplo:
$game_map.set_passage(384, 0x00) --> El primer tile (p.e. hierba) sumando los 384 de los autotiles, es pasable.
$game_map.set_passage(384, 0x0f) --> Ese primer tile ya no es pasable.

Recordad que algunas propiedades especiales del tile como el bush (hierba alta) o el counter (mostrador) vienen definidas con la passabilidad.

Con $game_map.set_priority defines la prioridad de un tile en concreto, por ejemplo:
$game_map.set_priority(384, 0) --> El primer tile (p.e. hierba) sumando los 384 de los autotiles, tiene prioridad 0 (debajo de los charas).
$game_map.set_priority(384, 1) --> Ese primer tile ahora tiene prioridad 1.

Con $game_map.set_terrain_tag defines el terrain tag de un tile en concreto, por ejemplo:
$game_map.set_terrain_tag(384, 0) --> El primer tile (p.e. hierba) sumando los 384 de los autotiles, tiene ID de terreno 0.
$game_map.set_terrain_tag(384, 1) --> Ese primer tile ahora tiene  ID de terreno 1.

Además también se pueden definir los mismos parámetros por coordenada, es decir aplicándolo en un tile concreto del mapa en vez de todos los tiles de determinado ID.

$game_map.set_map_passage(8, 10, 0, 0x00) --> El tile de la coordenada (8, 10) de la primera capa (0) ahora es pasable.
$game_map.set_map_priority(8, 10, 0, 0) --> El tile de la coordenada (8, 10) de la primera capa ahora tendría prioridad 0. ATENCIÓN, aunque hice la base del script el método no tiene efecto, porque la prioridad de cada uno de los tiles de un mapa va definida dentro del refresh del Tilemap. Por lo tanto para aplicar cambios de éste comando se necesita un Tilemap personalizado. Pronto haré el script como un Add-On al Poccil Tilemap (es el que uso siempre de ejemplo en scripts que lo requieren).
$game_map.set_map_terrain_tag(8, 10, 0, 0) --> El tile de la coordenada (8, 10) de la primera capa (0) ahora es tiene ID de terreno 0.

Autor: Wecoc
No requiere créditos.

Código:
#==============================================================================
# ** Control de pasabilidad por mapa
#==============================================================================

class Game_Map
  
  attr_reader :map_priorities
  
  alias map_passage_ini initialize unless $@
  def initialize
    map_passage_ini
    @map_passages = {}
    @map_priorities = {}
    @map_terrain_tags = {}
  end
  
  alias map_passage_setup setup unless $@
  def setup(map_id)
    map_passage_setup(map_id)
    @map_passages.clear
    @map_passages.default = 0
    @map_priorities.clear
    @map_priorities.default = 0
    @map_terrain_tags.clear
    @map_terrain_tags.default = 0
  end
  
#------------------------------------------------------------------------------
  
  def get_passage(tile_id)
    return @passages[tile_id].read_passage
  end
  
  def set_passage(tile_id, passage)
    if passage.is_a?(String)
      passage = passage.to_i(16)
    end
    @passages[tile_id] = passage
  end
  
  def get_map_passage(x, y, i)
    if @map_passages.keys.include?([x, y, i])
      return @map_passages[[x, y, i]].read_passage
    else
      tile_id = data[x, y, i]
      return get_passage(tile_id)
    end
  end
  
  def set_map_passage(x, y, i, passage)
    if passage.is_a?(String)
      passage = passage.to_i(16)
    end
    @map_passages[[x, y, i]] = passage
  end
  
#------------------------------------------------------------------------------
  
  def get_priority(tile_id)
    return @priorities[tile_id]
  end
  
  def set_priority(tile_id, priority)
    @priorities[tile_id] = priority.to_i
  end
  
  def get_map_priority(x, y, i)
    if @map_priorities.keys.include?([x, y, i])
      return @map_priorities[[x, y, i]]
    else
      tile_id = data[x, y, i]
      return get_priority(tile_id)
    end
  end
  
  def set_map_priority(x, y, i, priority)
    @map_priorities[[x, y, i]] = priority.to_i
  end

#------------------------------------------------------------------------------

  def get_terrain_tag(tile_id)
    return @terrain_tags[tile_id]
  end
  
  def set_terrain_tag(tile_id, terrain_tag)
    @terrain_tags[tile_id] = terrain_tag.to_i
  end
  
  def get_map_terrain_tag(x, y, i)
    if @map_terrain_tags.keys.include?([x, y, i])
      return @map_terrain_tags[[x, y, i]]
    else
      tile_id = data[x, y, i]
      return get_terrain_tag(tile_id)
    end
  end
  
  def set_map_terrain_tag(x, y, i, terrain_tag)
    @map_terrain_tags[[x, y, i]] = terrain_tag.to_i
  end
  
#------------------------------------------------------------------------------
  
  def passable?(x, y, d, self_event = nil)
    unless valid?(x, y)
      return false
    end
    bit = (1 << (d / 2 - 1)) & 0x0f
    for event in events.values
      if event.tile_id >= 0 and event != self_event and
         event.x == x and event.y == y and not event.through
        if @passages[event.tile_id] & bit != 0
          return false
        elsif @passages[event.tile_id] & 0x0f == 0x0f
          return false
        elsif @priorities[event.tile_id] == 0
          return true
        end
      end
    end
    for i in [2, 1, 0]
      return false if data[x, y, i] == nil
      passage = get_map_passage(x, y, i).to_i(16)
      if passage & bit != 0
        return false
      elsif passage & 0x0f == 0x0f
        return false
      end
      priority = get_map_priority(x, y, i)
      if priority == 0
        return true
      end
    end
    return true
  end

  def bush?(x, y)
    if @map_id != 0
      for i in [2, 1, 0]
        return false if data[x, y, i] == nil
        passage = get_map_passage(x, y, i).to_i(16)
        if passage & 0x40 == 0x40
          return true
        end
      end
    end
    return false
  end

  def counter?(x, y)
    if @map_id != 0
      for i in [2, 1, 0]
        return false if data[x, y, i] == nil
        passage = get_map_passage(x, y, i).to_i(16)
        if passage & 0x80 == 0x80
          return true
        end
      end
    end
    return false
  end

  def terrain_tag(x, y)
    if @map_id != 0
      for i in [2, 1, 0]
        return 0 if data[x, y, i] == nil
        terrain = get_map_terrain_tag(x, y, i)
        if terrain > 0
          return terrain
        end
      end
    end
    return 0
  end
end

class Integer
  def read_passage
    return sprintf("%#4.2x", self)
  end
end
avatar
Wecoc
Administrador
Administrador



Créditos 12234

Gracias : 638

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Control de pasabilidad por mapa

Mensaje por orochii el 2015-09-07, 14:37

Mmmmmmm bueno seré sincero. Como experimentación está interesante, e incluso para usos específicos. Pero en general creo que sería más útil hacer directamente un cambio de tileset y listo. Porque setear un buen número de tiles de una sóla vez va a ser liado. Con cambiar tileset, en cambio, tienes la ventaja de la interfaz. Haces dos tilesets parecidos en la base de datos, los cambias con un comando (de script, porque el XP por default no lo trae -¿alguna vez hablamos de las cosas que el 2k3 tiene que los otros no? xD-), y listo :^D.

Pero como dije, está interesante :^).
avatar
orochii
Reportero

0/3

Créditos 7760

Gracias : 456

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Control de pasabilidad por mapa

Mensaje por Wecoc el 2015-09-07, 21:12

Para pasabilidad y prioridad estoy contigo, se cambia de tileset o de tile con $game_map.data si es un punto específico; pero con el terrain tag consideré más adecuado poder cambiarlo manualmente, además que así rompes el límite de terrain tags que hay por defecto.

Lo de la pasabilidad y la prioridad en realidad lo hice para intentar solucionar lo que llamo el "bug del acantilado" pero sigue siendo tan difícil que aún teniendo éste script lo abandoné xD Pero pensé "para algo más servirá" xD

Ese bug es que no se puede hacer que un tile tenga esas dos propiedades a la vez.


A parte en éste caso concreto además he tenido que desactivar el bush (hierba alta) porque si no aún causaba otro problema en la primera screen.

Y no vale un cambio de mapa o de tileset porque te puedes encontrar casos de acantilados múltiples en un mismo mapa.

La idea era cambiar ese tile concreto de pasabilidad, prioridad y bush según desde qué dirección se alcanzara, pero a parte de la dificultad de hacer que funcione no solo en jugador sinó en eventos, si un evento estuviera abajo y otro arriba a la vez seguiría siendo un problemón.
avatar
Wecoc
Administrador
Administrador



Créditos 12234

Gracias : 638

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Control de pasabilidad por mapa

Mensaje por orochii el 2015-09-08, 01:25

@Wecoc escribió:La idea era cambiar ese tile concreto de pasabilidad, prioridad y bush según desde qué dirección se alcanzara, pero a parte de la dificultad de hacer que funcione no solo en jugador sinó en eventos, si un evento estuviera abajo y otro arriba a la vez seguiría siendo un problemón.
Y esa es la razón de porqué en Dreki, el pueblo de Fierro está desértico por fuera (?). "orz.

¿Quiza que lo que cambie sea el Z del evento/personaje al llegar a cada "subida" del acantilado? Y hacer tiles con comportamientos múltiples para cosas de pasabilidad y direcciones, que dependan del "nivel de altura" o Z del personaje.

Qué se yo xD.
avatar
orochii
Reportero

0/3

Créditos 7760

Gracias : 456

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Control de pasabilidad por mapa

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.