Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.

[XP] Script Immediate Action con ejemplos de aplicación

Ver el tema anterior Ver el tema siguiente Ir abajo

RPG Maker XP [XP] Script Immediate Action con ejemplos de aplicación

Mensaje por Wecoc el 2018-09-30, 15:01

Este script es bastante especial y algo complejo porque la batalla por defecto del maker no lo pone nada fácil. Lo que hace el script es añadir la posibilidad de implementar una acción immediata en cualquier fase de batalla, y luego una vez acabada seguir donde se interrumpió.

Es compatible con todo excepto scripts que modifiquen el modo en el que funciona el scope, por ejemplo el Advanced Scopes que publiqué hace tiempo, o bien sistemas de batalla completos que modifiquen mucho el funcionamiento de los turnos.
Tenéis las instrucciones en el script.

Código:
#==============================================================================
# ** [XP] Immediate Action
#------------------------------------------------------------------------------
# Como usarlo: En cualquier fase de batalla puedes añadir una acción inmediata
# dada una condición (la más habitual es phase4_step6, justo tras hacer
# otra acción.
#------------------------------------------------------------------------------
# Para ello simplemente se añade la línea
#   immediate_action(battler, target_index, action_kind, action_id)
#   battler - Game_Battler que corresponde al que hace la acción
#   target_index - Posición en la party o troop del actor o enemy que la recibe
#   action_kind - 0: acción física, 1: habilidad
#   action_id = Si action_kind es 0, entonces este es:
#      0: atacar, 1: defensar, 2: escapar, 3: nada
#     Si action_kind es 1 action_id corresponde a la skill ID
#------------------------------------------------------------------------------
# Pon el script encima de main y en el mismo al final añade las aplicaciones
# que quieras para hacerlo efectivo
#==============================================================================

class Scene_Battle
  #--------------------------------------------------------------------------
  # * Memorize current phase
  #--------------------------------------------------------------------------
  def phase_memorize
    @memorized_phase = @phase
    @memorized_phase_step = 1
    if @memorized_phase == 4
      @memorized_phase_step = @phase4_step
    end
  end
  #--------------------------------------------------------------------------
  # * Restore current phase
  #--------------------------------------------------------------------------
  def phase_restore
    if !@memorized_phase.nil?
      @phase = @memorized_phase
      if @phase == 4
        @phase4_step = @memorized_phase_step
      end
      @memorized_phase = nil
      @memorized_phase_step = nil
    end
  end
  #--------------------------------------------------------------------------
  # * Start Immediate Action
  #--------------------------------------------------------------------------
  def immediate_action(battler, target_index, action_kind, action_id)
    phase_memorize
    battler.current_action.kind = action_kind
    if battler.current_action.kind == 0
      battler.current_action.basic = action_id
    else
      battler.current_action.skill_id = action_id
    end
    if target_index == -2
      if battler.is_a?(Game_Enemy)
        battler.current_action.decide_last_target_for_enemy
      else
        battler.current_action.decide_last_target_for_actor
      end
    elsif target_index == -1
      if battler.is_a?(Game_Enemy)
        battler.current_action.decide_random_target_for_enemy
      else
        battler.current_action.decide_random_target_for_actor
      end
    elsif target_index >= 0
      battler.current_action.target_index = target_index
    end
    battler.current_action.forcing = true
    $game_temp.forcing_battler = battler
    @phase = 4
    @phase4_step = 1
  end
  #--------------------------------------------------------------------------
  # * End Immediate Action
  #--------------------------------------------------------------------------
  alias wecmemo_p4s6 update_phase4_step6 unless $@
  def update_phase4_step6
    wecmemo_p4s6
    phase_restore
  end
end

class Game_Battler
  #--------------------------------------------------------------------------
  # * Get index in party or troop (add-on)
  #--------------------------------------------------------------------------
  def get_index
    if self.is_a?(Game_Actor)
      return $game_party.actors.index(self)
    elsif self.is_a?(Game_Enemy)
      return $game_troop.enemies.index(self)
    end
    return -1
  end
end

Pero el script de por sí no hace nada, para lograr efectos con esto al final del script tendréis que añadir las condiciones concretas en las que ocurre.
Eso puede ir de muy simple a muy complicado, así que he decidido poneros dos ejemplos habituales de los complicados para hacerlo más fácil.

Counter Attack - Con este añadido podréis hacer actores y enemigos que contraatacan según determinadas condiciones.
Ver instrucciones en el script.

Código:
#==============================================================================
# ** [XP] Immediate Action - Counter Attack
#------------------------------------------------------------------------------
# Esto solo es un ejemplo de implementación del script Immediate Action
# Dentro de update_phase4_step6 se definen los contraataques que se quiera
# y dentro de las condiciones que se quiera. Es algo complejo, aviso xD
#------------------------------------------------------------------------------
# La llamada es la siguiente:
#   counter_attack(target_type, target_id, action_kind, action_id,
#     response_kind, response_id, prob)
#   target_type - Tipo de target que hará el contraataque, 0: Actor, 1: Enemigo
#   target_id - ID de este actor o enemigo
#   action_kind - Ataque que le han hecho, 0: Físico, 1: Habilidad
#   action_id - 0 en ataque físico, ID de habilidad kind vale 1
#   response_kind - Contraataque, 0: Físico, 1: Habilidad
#   response_id - 0 en ataque físico, ID de habilidad kind vale 1
#   prob - Probabilidad de que ocurra el contraataque, de 0 a 100
#==============================================================================

class Scene_Battle
  #--------------------------------------------------------------------------
  # * Counter Attack Configuration
  #--------------------------------------------------------------------------
  alias counter_attack_p4s6 update_phase4_step6 unless $@
  def update_phase4_step6
    response = false
    if @memorized_phase.nil?
      # Si el atacante tiene un ID de enemigo concreto
      if @active_battler.is_a?(Game_Enemy) && @active_battler.id == 1
        # Definie contraataque:
        #   Actor, Actor ID, Físico, Ataque, Resp. Físico, Resp. Ataque, 50%)
        response = counter_attack(0, 1, 0, 0, 0, 0, 50)
      end
      # Definir un enemigo que siempre contraataca contra ataques físicos
      # Definie contraataque:
      #   Enemigo, Enemigo ID, Físico, Ataque, Resp. Habilidad, Fuego, 100%)
      response = counter_attack(1, 1, 0, 0, 1, 7, 100)
      # Añade aquí otros posibles contraataques
    end
    return if response == true
    counter_attack_p4s6
  end
  #--------------------------------------------------------------------------
  # * Counter Attack Method
  #--------------------------------------------------------------------------
  def counter_attack(target_type, target_id, action_kind, action_id,
      response_kind, response_id, prob)
    return false if target_type == 0 && @active_battler.is_a?(Game_Actor)
    return false if target_type == 1 && @active_battler.is_a?(Game_Enemy)
    target_type_class = target_type == 0 ? Game_Actor : Game_Enemy
    condition = @target_battlers.select do |target|
      target.is_a?(target_type_class) &&
      target.id == target_id &&
      target.exist?
    end
    return false if condition.size == 0
    battler = condition[0]
    target = @active_battler.get_index
    action = @active_battler.current_action
    return false if action.kind != action_kind
    if action.kind == 0
      return false if action.basic != action_id
    elsif action.kind == 1
      return false if action.skill_id != action_id
    end
    if rand(100) < prob
      immediate_action(battler, target, response_kind, response_id)
      return true
    end
  end
end

Auto Heal - Con este añadido podréis hacer actores y enemigos que se curan directamente al empezar el turno si tienen poca vida.

Código:
#==============================================================================
# ** [XP] Immediate Action - Auto-Heal
#------------------------------------------------------------------------------
# Esto solo es un ejemplo de implementación del script Immediate Action
# Al iniciar turno si un actor concreto tiene muy poca vida se curará
#==============================================================================

class Scene_Battle
  alias autoheal_sp4 start_phase4
  def start_phase4
    autoheal_sp4
    if @memorized_phase.nil?
      # Actor ID 1 con HP menor que 100
      actor = $game_actors[1]
      # Nota: El actor tiene que tener la habilidad
      # Si se quiere que la use sin tenerla, cambia esto:
      #   actor.skill_can_use?(1)
      # por esto:
      #   actor.sp >= $data_skills[1].sp_cost
      # En ambos casos 1 es la ID de la habilidad
      if actor.hp < 100 && actor.skill_can_use?(1)
        # Auto-heal
        immediate_action(actor, actor.get_index, 1, 1)
        return
      end
    end
  end
end
avatar
Wecoc
Administrador
Administrador



Créditos 12275

Gracias : 645

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Script Immediate Action con ejemplos de aplicación

Mensaje por RJJR el 2018-10-01, 01:44

Socio, esto me puede servir hora de meterle mano a ver si me funciona muchas gracias, te estoy comunicando el resultado :)
avatar
RJJR
Iniciado
Iniciado

0/3

Créditos 24

Gracias : 2

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Script Immediate Action con ejemplos de aplicación

Mensaje por silvanash el 2018-10-01, 14:25

Add-on para el script, que me da pereza hacer tema nuevo para esto:

Código:
class Scene_Battle
 
  #--------------------------------------------------------------------------
  # * Frame Update (main phase step 5 : damage display)
  #--------------------------------------------------------------------------
  def update_phase4_step5
    # Hide help window
    @help_window.visible = false
    # Refresh status window
    @status_window.refresh
    # Display damage
    for target in @target_battlers
      if target.damage != nil
        # Extra line here to check for random shit
        extra_effects_on_animation(target)
        target.damage_pop = true
      end
    end
    # Shift to step 6
    @phase4_step = 6
  end
 
  def extra_effects_on_animation(target)
    # Placeholder
  end
 
end

Hay que pegar eso encima de mi add-on. Pegarlo por debajo hará que el Maker crashee por nomethod.

Código:
# Requires Wecoc's Inmediate Action

class Game_Battler
 
  attr_accessor :slv_press_the_attack
 
  alias slv_press_the_attack_init initialize unless $@
 
  def initialize
    slv_press_the_attack_init
    @slv_press_the_attack = 0
  end
 
end

class Scene_Battle
 
  alias slv_press_the_attack_extra extra_effects_on_animation unless $@
 
  def extra_effects_on_animation(target)
    slv_press_the_attack_extra(target)
    if !target.damage.nil? and target.damage != "Miss" and target.damage > 0
      # Increases the "press the attack counter" if the attack did damage
      target.slv_press_the_attack += 1
    end
  end

  alias slv_press_the_attack_phase4_step6 update_phase4_step6 unless $@
 
  def update_phase4_step6
    pressed_the_attack = false
    if @memorized_phase.nil?
      for actor in @target_battlers
        next if actor.dead? or !actor.exist?
        # Stacks of "press the attack" required to proc it
        if actor.slv_press_the_attack >= 4
          # Counter is reset to -1 because the animation will add 1 to it
          actor.slv_press_the_attack = -1
          immediate_action(actor, actor.get_index, 1, 7)
          pressed_the_attack = true
        end
      end
    end
    return if pressed_the_attack
    slv_press_the_attack_phase4_step6
  end
 
  alias slv_press_the_attack_battle_end battle_end unless $@
 
  def battle_end(results)
    for actor in $game_party.actors
      # Resets the press the attack counter
      actor.slv_press_the_attack = 0
    end
    slv_press_the_attack_battle_end(results)
  end
 
end

"Press the attack" hace que los enemigos reciban daño adicional tras ser atacados X cantidad de veces. Ese daño adicional es una inmediate_action que ejecuta una skill sobre ellos. Esa skill debe estar configurada en la base de datos como "daño sobre usuario" y consumir 0 MPs. "Atacados" incluye cualquier acción que ejecute animación sobre el actor y que haga daño superior a 0.

La cantidad de veces que hay que atacar está en la línea 34; es la línea que pone ">= 4". La skill que se usa es el último número de la línea 37; hice que la skill 7 del Maker (Fuego) hiciera daño sobre usuario para probar el script.
avatar
silvanash
Aventurero
Aventurero

0/3

Créditos 205

Gracias : 251

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Script Immediate Action con ejemplos de aplicación

Mensaje por silvanash el 2018-10-01, 15:44

Otro add-on y doble post porque soy así de chulo. Éste no requiere del script extra que modifica update_phase4_step5.

Código:
# Requires Wecoc's Inmediate Action

module SLV_Config
 
  BLOWS_UP = {
    # Enemy_ID => [HP, chance (%), skill_id],
    1 => [95, 100, 8],
  }

end

class Game_Enemy < Game_Battler
 
  attr_accessor :slv_blew_up_flag
 
end

class Scene_Battle
 
  alias slv_blew_up_phase4_step5 update_phase4_step5 unless $@
 
  def update_phase4_step5
    if @active_battler.is_a?(Game_Enemy) and @active_battler.slv_blew_up_flag
      @active_battler.damage = "Selfdestruct!"
      @active_battler.hp = 0
      @active_battler.damage_pop = true
    end
    slv_blew_up_phase4_step5
  end
 
  alias slv_self_destruct_phase4_step6 update_phase4_step6 unless $@
 
  def update_phase4_step6
    blew_up = false
    for actor in @target_battlers
      next if !actor.is_a?(Game_Enemy)
      next if actor.dead? or !actor.exist?
      next if !SLV_Config::BLOWS_UP.has_key?(actor.id)
      next if actor.hp * 100 / actor.maxhp > SLV_Config::BLOWS_UP[actor.id][0]
      next if rand(100) > SLV_Config::BLOWS_UP[actor.id][1]
      actor.slv_blew_up_flag = true
      immediate_action(actor, actor.get_index, 1, SLV_Config::BLOWS_UP[actor.id][2])
      blew_up = true
    end
    return if blew_up == true
    slv_self_destruct_phase4_step6
  end
 
end

Este script hace que algunos enemigos se autodestruyan si sus HPs caen por debajo de cierto porcentaje. Se configura en la hash que hay al principio. Tal y como está ahora, los fantasmas del RTP se autodestruirán el 100% de las veces que sus HPs caigan por debajo del 95%. Al autodestruirse, los enemigos ejecutan la skill que está seleccionada. Esa skill debe estar configurada para "dañar al grupo enemigo".
avatar
silvanash
Aventurero
Aventurero

0/3

Créditos 205

Gracias : 251

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Script Immediate Action con ejemplos de aplicación

Mensaje por silvanash el 2018-10-01, 16:38

Triple postaco. Debería estar trabajando en mi juego, pero meh.

Código:
module SLV_Config
 
  HIT_THE_MARK = {
    # Actor_ID => [consecutive_attacks, skill_id],
    1 => [2, 16],
  }
 
end

class Game_Enemy < Game_Battler
 
  attr_accessor :slv_hit_the_mark
 
  alias slv_hit_the_mark_init initialize
 
  def initialize(troop_id, member_index)
    slv_hit_the_mark_init(troop_id, member_index)
    @slv_hit_the_mark = {}
  end
 
end

class Scene_Battle
 
  alias slv_hit_the_mark_phase4_step6 update_phase4_step6 unless $@
 
  def update_phase4_step6
    if @memorized_phase.nil? and @active_battler.is_a?(Game_Actor) and
      @target_battlers.size == 1 and @target_battlers[0].is_a?(Game_Enemy) and
      SLV_Config::HIT_THE_MARK.keys.include?(@active_battler.id)
      # Resets the "hit the mark counter" from all enemies
      for entity in $game_troop.enemies
        next if entity.dead? or !entity.exist?
        entity.slv_hit_the_mark[@active_battler.id] = 0 if entity != @target_battlers[0]
      end
      @target_battlers[0].slv_hit_the_mark[@active_battler.id] ||= 0
      @target_battlers[0].slv_hit_the_mark[@active_battler.id] += 1
      if @target_battlers[0].slv_hit_the_mark[@active_battler.id] >= SLV_Config::HIT_THE_MARK[@active_battler.id][0]
        @target_battlers[0].slv_hit_the_mark[@active_battler.id] = -1
        if @active_battler.skill_can_use?(SLV_Config::HIT_THE_MARK[@active_battler.id][1])
          immediate_action(@active_battler, -2, 1, SLV_Config::HIT_THE_MARK[@active_battler.id][1])
          return
        end
      end
    end
    slv_hit_the_mark_phase4_step6
  end
 
end

"Hit the mark" ejecuta una skill sobre un enemigo si un actor le ataca X veces seguidas. Cambiar de objetivo o usar skills/objectos en área resetea el contador. La skill ejecutada en "hit the mark" aumenta el contador de "press the attack".
avatar
silvanash
Aventurero
Aventurero

0/3

Créditos 205

Gracias : 251

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Script Immediate Action con ejemplos de aplicación

Mensaje por Wecoc el 2018-10-01, 18:11

Me sorprente que hayas hecho todo eso solo partiendo de ese mini-script xD Luego dicen que mis scripts no son útiles
Se me da muy mal testear batallas pero así por encima no ví problemas. Me gustan los arreglos, especialmente el de autodestrucción.

Spoiler:
# Extra line here to check for random shit
avatar
Wecoc
Administrador
Administrador



Créditos 12275

Gracias : 645

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Script Immediate Action con ejemplos de aplicación

Mensaje por silvanash el 2018-10-01, 19:34

El script es inútil. La gente que no sepa de scripts no va a poder darle uso, e, irónicamente, la gente que sabe de scripts es la que menos razones tiene para usarlo porque ya tienen sistemas de combate propios (véase Dreki, Birdsite, MS3).

Código:
class Game_Battler
 
  attr_reader :slv_took_damage
 
  alias slv_attack_effect_damage_flag attack_effect unless $@
 
  def attack_effect(attacker)
    @slv_took_damage = hp
    flag = slv_attack_effect_damage_flag(attacker)
    @slv_took_damage = if hp < @slv_took_damage then true else false end
    return flag
  end
 
  alias slv_skill_effect_damage_flag skill_effect unless $@
 
  def skill_effect(user, skill)
    @slv_took_damage = hp
    flag = slv_skill_effect_damage_flag(user, skill)
    @slv_took_damage = if hp < @slv_took_damage then true else false end
    return flag
  end
 
  alias slv_item_effect_damage_flag item_effect unless $@
 
  def item_effect(item)
    @slv_took_damage = hp
    flag = slv_item_effect_damage_flag(item)
    @slv_took_damage = if hp < @slv_took_damage then true else false end
    return flag
  end
 
end

Add-on para Game_Battler. slv_took_damage se setea a true si el battler recibió daño en su última acción (sus HPs tras la acción son inferiores a sus HPs originales). Esto sirve para insertar acciones en puntos donde actor.damage se ha reseteado a nil porque ya se ha ejecutado la animación.

actor.damage > 0 no sirve en esas situaciones porque damage es nil; slv_took_damage seguirá valiendo true hasta que el battler sea targeteado por otra acción.

Código:
# Requires Wecoc's Inmediate Action
# Requires slv Game_Battler extension

module SLV_Config
 
  HIT_THE_MARK = {
    # Actor_ID => [consecutive_attacks, skill_id],
    1 => [2, 16],
  }
 
end

class Game_Enemy < Game_Battler
 
  attr_accessor :slv_hit_the_mark
 
  alias slv_hit_the_mark_init initialize
 
  def initialize(troop_id, member_index)
    slv_hit_the_mark_init(troop_id, member_index)
    @slv_hit_the_mark = {}
  end
 
end

class Scene_Battle
 
  alias slv_hit_the_mark_phase4_step6 update_phase4_step6 unless $@
 
  def update_phase4_step6
    if @memorized_phase.nil? and @active_battler.is_a?(Game_Actor) and
      @target_battlers.size == 1 and @target_battlers[0].is_a?(Game_Enemy) and
      SLV_Config::HIT_THE_MARK.keys.include?(@active_battler.id)
      # Resets the "hit the mark counter" from all enemies
      for entity in $game_troop.enemies
        next if entity.dead? or !entity.exist?
        entity.slv_hit_the_mark[@active_battler.id] = 0 if entity != @target_battlers[0]
      end
      if @target_battlers[0].slv_took_damage
        @target_battlers[0].slv_hit_the_mark[@active_battler.id] ||= 0
        @target_battlers[0].slv_hit_the_mark[@active_battler.id] += 1
        if @target_battlers[0].slv_hit_the_mark[@active_battler.id] >= SLV_Config::HIT_THE_MARK[@active_battler.id][0]
          @target_battlers[0].slv_hit_the_mark[@active_battler.id] = -1
          if @active_battler.skill_can_use?(SLV_Config::HIT_THE_MARK[@active_battler.id][1])
            immediate_action(@active_battler, -2, 1, SLV_Config::HIT_THE_MARK[@active_battler.id][1])
            return
          end
        end
      end
    end
    slv_hit_the_mark_phase4_step6
  end
 
end

Versión actualizada de hit the mark, usando slv_took_damage. La versión anterior se activa incluso si el actor falla. La nueva versión sólo se activa si el ataque acierta.
avatar
silvanash
Aventurero
Aventurero

0/3

Créditos 205

Gracias : 251

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Script Immediate Action con ejemplos de aplicación

Mensaje por RJJR el 2018-10-01, 22:09

Pues cierta mente me fallo intente ver si lograba hacerlo funcioncar pero nada :(, uso el sistema de batala laterar Enu SBS Tanketai XP ¿sera que este scrip me funcionaria? o pues si es posible ¿me recomindan otro sistema de batalla?
avatar
RJJR
Iniciado
Iniciado

0/3

Créditos 24

Gracias : 2

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Script Immediate Action con ejemplos de aplicación

Mensaje por Wecoc el 2018-10-01, 22:38

Silvanash: Bueno quien no sepa mucho de script solo usando los añadidos y configurándolos creo que puede lograrlo.

RJJR: Ya lo dije, con scripts de batalla completos es muy posible que dé problemas, como pasa con muchos de los scripts de complementos de batalla. Está pensado básicamente para batalla default. La solución no pasa por cambiar el sistema de batalla sino por hacer un script específico para que funcione con el que usas. El que hice te podría servir a medias pero debe de tener alguna incompatibilidad así que habría que adaptarlo bien.

No puedo ir adaptando mis scripts a todos los scripts de batalla no default con los que den problemas porque cada script de batalla va distinto, sería de locos y además las batallas no default no son para nada mi fuerte y son muy tediosos (es de lo más complejo en cuanto a scripts de sistema se refiere). Si quieres usar ambos alguien tendrá que arreglarlo específicamente para tu juego.

Igualmente debo decir que no es un script con demasiados problemas de incompatibilidad, no reescribe nada importante, todo son alias o bien métodos importantes. Eso significa que tiene sentido que sea incompatible con scripts no default que lo cambian todo, pero con otros complementos a la batalla default no debería haber problema.
avatar
Wecoc
Administrador
Administrador



Créditos 12275

Gracias : 645

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Script Immediate Action con ejemplos de aplicación

Mensaje por RJJR el 2018-10-02, 01:39

ok entendido, gracias por el aporte :)
avatar
RJJR
Iniciado
Iniciado

0/3

Créditos 24

Gracias : 2

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Script Immediate Action con ejemplos de aplicación

Mensaje por silvanash el 2018-10-09, 15:25

Debería hacer un tema nuevo para evitar confusión, pero soy un malnacido y, además, nadie va a usar el script, así que spam:

Código:
# Wecoc's Immediate Action Extended

class Scene_Battle

  alias slv_phase_memorize phase_memorize unless $@
 
  def phase_memorize
    return if !@memorized_phase.nil?
    slv_phase_memorize
  end
 
  alias slv_update_phase1 update_phase1 unless $@
 
  def update_phase1
    @slv_immediate_actions ||= []
    slv_update_phase1
  end
 
  alias slvmemo_p4s6 update_phase4_step6 unless $@

  def update_phase4_step6
    slvmemo_p4s6
    if !@slv_immediate_actions.empty?
      action = @slv_immediate_actions.delete_at(0)
      immediate_action(action[0], action[1], action[2], action[3])
      return
    end
    phase_restore if @slv_immediate_actions.empty?
  end
 
  def store_immediate_action(battler, target_index, action_kind, action_id)
    @slv_immediate_actions.push([battler, target_index, action_kind, action_id])
  end
 
end

Eso de ahí es una extensión para el Immediate Action, para solucionar uno de sus problemas más hardcore: no funciona cuando hay que ejecutar Immediate Actions sobre más de un battler a la vez. Esto es evidente sobre todo en el self-destruct que posteé; configurar los fantasmas para hacer self-destruct el 100% de las veces que su HP sea el 100% o menor no hace que se autodestruyan si el jugador usa una skill grupal, sino que se activa en uno de los fantasmas, y luego se activa otro self-destruct más tarde. Este apaño guarda las inmediate actions en un array y luego bloquea el update de phase4_step6 hasta que todas las inmediate actions se hayan ejecutado.

Para usarlo, en lugar de llamar a immediate_action(params), llama a store_immediate_action(params), usando los mismos parámetros y en el mismo orden.

Código:
class Scene_Battle
 
  alias slv_press_the_attack_extra extra_effects_on_animation unless $@
 
  def extra_effects_on_animation(target)
    slv_press_the_attack_extra(target)
    if !target.damage.nil? and target.damage != "Miss" and target.damage > 0
      # Increases the "press the attack counter" if the attack did damage
      target.slv_press_the_attack += 1
    end
  end

  alias slv_press_the_attack_phase4_step6 update_phase4_step6 unless $@
 
  def update_phase4_step6
    pressed_the_attack = false
    if @memorized_phase.nil?
      for actor in @target_battlers
        next if actor.dead? or !actor.exist?
        # Stacks of "press the attack" required to proc it
        if actor.slv_press_the_attack >= 2
          # Counter is reset to -1 because the animation will add 1 to it
          actor.slv_press_the_attack = -1
          store_immediate_action(actor, actor.get_index, 1, 7)
          pressed_the_attack = true
        end
      end
    end
    slv_press_the_attack_phase4_step6
  end
 
  alias slv_press_the_attack_battle_end battle_end unless $@
 
  def battle_end(results)
    for actor in $game_party.actors
      # Resets the press the attack counter
      actor.slv_press_the_attack = 0
    end
    slv_press_the_attack_battle_end(results)
  end
 
end

Aquí está "press the attack" usando Extend en lugar de default.

Nota: no he comprobado la compatibilidad de Extend al encadenar varias Immediate actions seguidas. Tampoco me importa mucho porque MS3 tiene un motor propio y no uso el script.
avatar
silvanash
Aventurero
Aventurero

0/3

Créditos 205

Gracias : 251

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Script Immediate Action con ejemplos de aplicación

Mensaje por Wecoc el 2018-10-09, 17:17

Gracias por la extensión del script, la verdad es que como era un arreglo para un par de casos muy concretos no fui tan lejos con esto.

@silvanash escribió:Eso de ahí es una extensión para el Immediate Action, para solucionar uno de sus problemas más hardcore: no funciona cuando hay que ejecutar Immediate Actions sobre más de un battler a la vez.

Tampoco sobre el mismo battler; el mío no soporta encadenar varias immediate actions seguidas, se podía llegar a hacer con una variable temporal iniciada con la primera acción y hacer que la segunda no se ejecutara hasta que esa variable fuera apagada, pero es tan chapuza como suena. Tu método almacenándolas en una array es más apropiado en esos casos. Aún así dejaré ambas versiones separadamente porque en algunos casos la versión simple basta y sobra xD
avatar
Wecoc
Administrador
Administrador



Créditos 12275

Gracias : 645

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Script Immediate Action con ejemplos de aplicación

Mensaje por silvanash el 2018-10-09, 18:45

El Immediate Action default puede ejecutar múltiples acciones sobre el mismo battler. "Hit the mark" podía activar "press the attack" sobre el mismo target, abusando de múltiples alias de phase4_step6. El problema estaba en que las skills grupales no funcionaban correctamente (y por eso "hit the mark" tiene un bloque enorme comprobando que en @target_battlers sólo haya un enemigo).

En teoría no debería de haber problemas usando el Extend en lugar de el default para todo. Lo único que hay que hacer es reemplazar todas las llamadas a "immediate_action(params") por el "store".

Nota: el Extend no funciona sin el default. Es una extensión, no un reemplazo completo.
avatar
silvanash
Aventurero
Aventurero

0/3

Créditos 205

Gracias : 251

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Script Immediate Action con ejemplos de aplicación

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.