Jump to content
Nérylis

Script - Damage to all at same time

Recommended Posts

Hello,

 

This is my first topic in this forum and I hope that I post in right section (I'm French and i don't understand all that I read).

 

By default in RPG Maker VX Ace, when we configurate a skill which hit all ennemies, damages are applicated in each ennemy one after the other.

 

I would like a script to apply the damage and status on all enemies simultaneously.

 

Can you help me, please ?

Share this post


Link to post
Share on other sites

If I recall correctly, Yanfly Battle Engine has the function.

You only need to put the tag <one animation> in your skill notebox

However, the script also change how the battle screen looks like

Share this post


Link to post
Share on other sites

TheoAllen is recommending that you use it xD 

 

Yanfly Battle Engine

 

Copy the script, open your project, click

 

AA0mK0R.png

 

 

Then click the empty line below materials, and paste the script.

B2de64C.png

 

After that, follow TheoAllen's instructions.

Share this post


Link to post
Share on other sites


class Scene_Battle < Scene_Base

def apply_item_effects(target, item)

target.item_apply(@subject, item)

refresh_status

@all_targets.push([target,item])

end

alias all_target_use_item use_item

def use_item

@all_targets = []

all_target_use_item

@all_targets.each do |target,item|

@log_window.display_action_results(target, item)

end

end

end

 

Edited by Demintika

Share this post


Link to post
Share on other sites

I don't understand. I copy and paste your script below materials. This is what I should do ?

Nah, I just guess things wrong. Never used default battle system myself so I guess the "damage" is only shown as some text in the log window.

How the damages is shown?

Share this post


Link to post
Share on other sites

The default battle systems plays animation and displays the results in the battle log, one by one, for each enemy.

 

The request is to have this all occur simultaneously, so presumably the battle log will show

 

Slime A was hit for 200 HP
Slime B was hit for 220 HP
Slime C was hit for 182 HP
Instead of showing them one by one.

Share this post


Link to post
Share on other sites

An extremely lazy and quick dirty snippet for this :)

 

 

#==============================================================================|
#  ** You need not edit this part as it's about how this snippet works         |
#------------------------------------------------------------------------------|

#------------------------------------------------------------------------------|
#  * Edit class: Window_BattleLog                                              |
#------------------------------------------------------------------------------|

class Window_BattleLog < Window_Selectable

  #----------------------------------------------------------------------------|
  #  New public instance variable                                              |
  #----------------------------------------------------------------------------|
  attr_writer :last_line_number
  attr_writer :log_window_display

  #----------------------------------------------------------------------------|
  #  Alias method: wait_log_window_display                                     |
  #----------------------------------------------------------------------------|
  alias wait_log_window_display wait
  def wait
    # Rewritten to wait only when asked by this snippet
    wait_log_window_display if @wait
    #
  end # wait

  #----------------------------------------------------------------------------|
  #  Rewrite method: display_counter                                           |
  #----------------------------------------------------------------------------|
  def display_counter(target, item)
    # Rewritten to show all the information until the max line number's reached
    @last_line_number ||= line_number
    Sound.play_evasion
    add_text(sprintf(Vocab::CounterAttack, target.name))
    process_max_line_number_breach(@last_line_number)
    #
  end # display_counter

  #----------------------------------------------------------------------------|
  #  Rewrite method: display_reflection                                        |
  #----------------------------------------------------------------------------|
  def display_reflection(target, item)
    # Rewritten to show all the information until the max line number's reached
    @last_line_number ||= line_number
    Sound.play_reflection
    add_text(sprintf(Vocab::MagicReflection, target.name))
    process_max_line_number_breach(@last_line_number)
    #
  end # display_reflection

  #----------------------------------------------------------------------------|
  #  Rewrite method: display_substitute                                        |
  #----------------------------------------------------------------------------|
  def display_substitute(substitute, target)
    # Rewritten to show all the information until the max line number's reached
    @last_line_number ||= line_number
    add_text(sprintf(Vocab::Substitute, substitute.name, target.name))
    process_max_line_number_breach(@last_line_number)
    #
  end # display_substitute

  #----------------------------------------------------------------------------|
  #  Rewrite method: display_action_results                                    |
  #----------------------------------------------------------------------------|
  def display_action_results(target, item)
    # Rewritten to store and display the stored information if
    # log_window_display is false and true respectively
    if @log_window_display
      last_line_number = line_number
      @wait = false
      @targets.each { |target_item|
        next unless target_item[0].result.used
        [:display_critical, :display_damage, :display_affected_status,
         :display_failure].each { |method|
          send(method, target_item[0], target_item[1])
          process_max_line_number_breach(last_line_number)
        }
      }
      return clear_action_results
    end
    store_action_results(target, item)
    #
  end # display_action_results

  #----------------------------------------------------------------------------|
  #  New method: store_action_results                                          |
  #----------------------------------------------------------------------------|
  def store_action_results(target, item)
    @index ||= 0
    @targets ||= []
    @targets.push([target, item])
  end # store_action_results

  #----------------------------------------------------------------------------|
  #  New method: process_max_line_number_breach                                |
  #----------------------------------------------------------------------------|
  def process_max_line_number_breach(last_line_number)
    return unless line_number > max_line_number
    @wait = true
    wait
    @wait = false
    back_to(last_line_number)
    @last_line_number = line_number
  end # process_max_line_number_breach

  #----------------------------------------------------------------------------|
  #  New method: clear_action_results                                          |
  #----------------------------------------------------------------------------|
  def clear_action_results
    @index = 0
    @targets = []
    @wait = true
  end # clear_action_results

end # Window_BattleLog

#------------------------------------------------------------------------------|
#  * Edit class: Scene_Battle                                                  |
#------------------------------------------------------------------------------|

class Scene_Battle < Scene_Base

  #----------------------------------------------------------------------------|
  #  Alias method: use_item                                                    |
  #----------------------------------------------------------------------------|
  alias use_item_log_window_display use_item
  def use_item
    # Added to ask the log window to store the logs instead of displaying them
    @log_window.last_line_number = nil
    @log_window.log_window_display = false
    #
    use_item_log_window_display
    # Added to ask the log window to display all the stored logs
    @log_window.log_window_display = true
    @log_window.display_action_results(nil, nil)
    @log_window.last_line_number = nil
    @log_window.log_window_display = false
    #
  end # use_item

end # Scene_Battle

#==============================================================================|

 

 

 

I'd guess my snippet doesn't have a good compatibility and robustness(I don't think my mind's clear enough here and it seems to me it may produce some weird results on some cases already XD) though as I haven't think about them at all lol :D

Edited by DoubleX

Share this post


Link to post
Share on other sites

It is strange, it does not work on the basic fights of RPG Maker. But in my fights, I integrated a system to be able to play events when the HP of an enemy arrives at 0 before dying (from the beginning of the fight, I put a status Anti-ko which I remove when I finished the events which I wanted). And in that case, the damages are applied well at the same time but not the statutes.

Edited by Nérylis

Share this post


Link to post
Share on other sites

This version might be at least a bit better:

 

 

#==============================================================================|
#  ** You need not edit this part as it's about how this snippet works         |
#------------------------------------------------------------------------------|

#------------------------------------------------------------------------------|
#  * Edit class: Window_BattleLog                                              |
#------------------------------------------------------------------------------|

class Window_BattleLog < Window_Selectable

  #----------------------------------------------------------------------------|
  #  New public instance variable                                              |
  #----------------------------------------------------------------------------|
  attr_writer :last_line_number
  attr_writer :log_window_display

  #----------------------------------------------------------------------------|
  #  Alias method: wait                                                        |
  #----------------------------------------------------------------------------|
  alias wait_log_window_display wait
  def wait
    # Rewritten to wait only when asked by this snippet
    wait_log_window_display if @wait
    #
  end # wait

  #----------------------------------------------------------------------------|
  #  Alias method: wait_for_effect                                             |
  #----------------------------------------------------------------------------|
  alias wait_for_effect_log_window_display wait
  def wait_for_effect
    # Rewritten to wait for effect only when asked by this snippet
    wait_for_effect_log_window_display if @wait
    #
  end # wait_for_effect

  #----------------------------------------------------------------------------|
  #  Rewrite method: display_counter                                           |
  #----------------------------------------------------------------------------|
  def display_counter(target, item)
    # Rewritten to show all the information until the max line number's reached
    @last_line_number ||= line_number
    Sound.play_evasion
    add_text(sprintf(Vocab::CounterAttack, target.name))
    process_max_line_number_breach(@last_line_number)
    #
  end # display_counter

  #----------------------------------------------------------------------------|
  #  Rewrite method: display_reflection                                        |
  #----------------------------------------------------------------------------|
  def display_reflection(target, item)
    # Rewritten to show all the information until the max line number's reached
    @last_line_number ||= line_number
    Sound.play_reflection
    add_text(sprintf(Vocab::MagicReflection, target.name))
    process_max_line_number_breach(@last_line_number)
    #
  end # display_reflection

  #----------------------------------------------------------------------------|
  #  Rewrite method: display_substitute                                        |
  #----------------------------------------------------------------------------|
  def display_substitute(substitute, target)
    # Rewritten to show all the information until the max line number's reached
    @last_line_number ||= line_number
    add_text(sprintf(Vocab::Substitute, substitute.name, target.name))
    process_max_line_number_breach(@last_line_number)
    #
  end # display_substitute

  #----------------------------------------------------------------------------|
  #  Rewrite method: display_action_results                                    |
  #----------------------------------------------------------------------------|
  def display_action_results(target, item)
    # Rewritten to store and display the stored information if
    # log_window_display is false and true respectively
    if @log_window_display
      last_line_number = line_number
      @wait = false
      @targets.each { |target_item|
        next unless target_item[0].result.used
        [:display_critical, :display_damage, :display_affected_status, 
         :display_failure].each { |method|
          send(method, target_item[0], target_item[1])
          process_max_line_number_breach(last_line_number)
        }
      }
      return clear_action_results
    end
    store_action_results(target, item)
    #
  end # display_action_results

  #----------------------------------------------------------------------------|
  #  New method: store_action_results                                          |
  #----------------------------------------------------------------------------|
  def store_action_results(target, item)
    @index ||= 0
    @targets ||= []
    @targets.push([target, item])
  end # store_action_results

  #----------------------------------------------------------------------------|
  #  New method: process_max_line_number_breach                                |
  #----------------------------------------------------------------------------|
  def process_max_line_number_breach(last_line_number)
    return unless line_number > max_line_number
    @wait = true
    wait
    @wait = false
    back_to(last_line_number)
    @last_line_number = line_number
  end # process_max_line_number_breach

  #----------------------------------------------------------------------------|
  #  New method: clear_action_results                                          |
  #----------------------------------------------------------------------------|
  def clear_action_results
    @index = 0
    @targets = []
    @wait = true
  end # clear_action_results

end # Window_BattleLog

#------------------------------------------------------------------------------|
#  * Edit class: Scene_Battle                                                  |
#------------------------------------------------------------------------------|

class Scene_Battle < Scene_Base

  #----------------------------------------------------------------------------|
  #  Alias method: use_item                                                    |
  #----------------------------------------------------------------------------|
  alias use_item_log_window_display use_item
  def use_item
    # Added to ask the log window to store the logs instead of displaying them
    @log_window.last_line_number = nil
    @log_window.log_window_display = false
    #
    use_item_log_window_display
    # Added to ask the log window to display all the stored logs
    @log_window.log_window_display = true
    @log_window.display_action_results(nil, nil)
    @log_window.last_line_number = nil
    @log_window.log_window_display = false
    #
  end # use_item

  #----------------------------------------------------------------------------|
  #  Rewrite method: apply_item_effects                                        |
  #----------------------------------------------------------------------------|
  def apply_item_effects(target, item)
    target.item_apply(@subject, item)
    # Rewritten to refresh the target only instead of the whole status window
    @status_window.draw_item(target.index) if target.actor? && target.index >= 0
    #
    @log_window.display_action_results(target, item)
  end # apply_item_effects

  #----------------------------------------------------------------------------|
  #  Rewrite method: invoke_counter_attack                                     |
  #----------------------------------------------------------------------------|
  def invoke_counter_attack(target, item)
    @log_window.display_counter(target, item)
    attack_skill = $data_skills[target.attack_skill_id]
    @subject.item_apply(target, attack_skill)
    # Rewritten to refresh the target only instead of the whole status window
    if @subject.actor? && @subject.index >= 0
      @status_window.draw_item(@subject.index)
    end
    #
    @log_window.display_action_results(@subject, attack_skill)
  end # invoke_counter_attack

end # Scene_Battle

#==============================================================================|

 

 

 

Basically, my snippet aims to:

1. Store all the battle log information and display all the information when the information would otherwise breach the battle log window max line number or no more information would be added

2. Reduce the time needed to apply the effects of an action to its targets

I wonder if it can do its job though ;)

Edited by DoubleX

Share this post


Link to post
Share on other sites

It works better. I still have some problems.

 

When a character use a weapon with some hits, damage are calculated as if it were an attack on multiple enemies. This script should work only for skills whose target is All enemies.

 

My other problem is not with the script itself. In my game, as I said, I use a system to play events when HP of an enemy arrives at 0 before dying (from the beginning of the fight, I put a status Anti-ko which I remove when I finished the events which I wanted). These events include to activate switches and to change variables. After, I remove Anti-Ko status and I give Ko status manually. it's useful to me for a side quest. Suddenly, with the script, the damage are well applied simultaneously but not status. I don't find a solution to resolve this problem. Can you help me ?

Share this post


Link to post
Share on other sites

Try this version instead(facepalm on the previous ones, they clearly showed I didn't grasp the core of the issue at all lol):

 

 

#==============================================================================|
#  ** You need not edit this part as it's about how this snippet works         |
#------------------------------------------------------------------------------|

#------------------------------------------------------------------------------|
#  * Edit class: Window_BattleLog                                              |
#------------------------------------------------------------------------------|

class Window_BattleLog < Window_Selectable

  #----------------------------------------------------------------------------|
  #  New public instance variable                                              |
  #----------------------------------------------------------------------------|
  attr_writer :last_line_number

  #----------------------------------------------------------------------------|
  #  Alias method: wait                                                        |
  #----------------------------------------------------------------------------|
  alias wait_log_window_display wait
  def wait
    # Rewritten to wait only when asked by this snippet
    wait_log_window_display if @wait
    #
  end # wait

  #----------------------------------------------------------------------------|
  #  Alias method: wait_for_effect                                             |
  #----------------------------------------------------------------------------|
  alias wait_for_effect_log_window_display wait
  def wait_for_effect
    # Rewritten to wait for effect only when asked by this snippet
    wait_for_effect_log_window_display if @wait
    #
  end # wait_for_effect

  #----------------------------------------------------------------------------|
  #  Rewrite method: display_counter                                           |
  #----------------------------------------------------------------------------|
  def display_counter(target, item)
    # Rewritten to show all logs until the max line number's reached
    @last_line_number ||= line_number
    Sound.play_evasion
    add_text(sprintf(Vocab::CounterAttack, target.name))
    process_max_line_number_breach(item) if line_number >= max_line_number
    #
  end # display_counter

  #----------------------------------------------------------------------------|
  #  Rewrite method: display_reflection                                        |
  #----------------------------------------------------------------------------|
  def display_reflection(target, item)
    # Rewritten to show all logs until the max line number's reached
    @last_line_number ||= line_number
    Sound.play_reflection
    add_text(sprintf(Vocab::MagicReflection, target.name))
    process_max_line_number_breach(item) if line_number >= max_line_number
    #
  end # display_reflection

  #----------------------------------------------------------------------------|
  #  Rewrite method: display_substitute                                        |
  #----------------------------------------------------------------------------|
  def display_substitute(substitute, target)
    # Rewritten to show all logs until the max line number's reached
    @last_line_number ||= line_number
    add_text(sprintf(Vocab::Substitute, substitute.name, target.name))
    process_max_line_number_breach(item) if line_number >= max_line_number
    #
  end # display_substitute

  #----------------------------------------------------------------------------|
  #  Rewrite method: display_action_results                                    |
  #----------------------------------------------------------------------------|
  def display_action_results(target, item)
    # Rewritten to show all logs until the max line number's reached
    @last_line_number ||= line_number
    @wait = !item.for_all?
    if target.result.used
      [:display_critical, :display_damage, :display_affected_status,
       :display_failure].each{ |method|
        send(method, target,item)
        process_max_line_number_breach(item) if line_number >= max_line_number
      }
    end
    @wait = true
    #
  end # display_action_results

  #----------------------------------------------------------------------------|
  #  New method: process_max_line_number_breach                                |
  #----------------------------------------------------------------------------|
  def process_max_line_number_breach(item)
    @wait = true
    wait
    @wait = !item.for_all?
    back_to(@last_line_number)
    @last_line_number = line_number
  end # process_max_line_number_breach

end # Window_BattleLog

#------------------------------------------------------------------------------|
#  * Edit class: Scene_Battle                                                  |
#------------------------------------------------------------------------------|

class Scene_Battle < Scene_Base

  #----------------------------------------------------------------------------|
  #  Alias method: use_item                                                    |
  #----------------------------------------------------------------------------|
  alias use_item_log_window_display use_item
  def use_item
    # Added to clear the battle log window last line number data
    @log_window.last_line_number = nil
    #
    use_item_log_window_display
  end # use_item

  #----------------------------------------------------------------------------|
  #  Rewrite method: apply_item_effects                                        |
  #----------------------------------------------------------------------------|
  def apply_item_effects(target, item)
    target.item_apply(@subject, item)
    # Rewritten to refresh the target only instead of the whole status window
    @status_window.draw_item(target.index) if target.actor? && target.index >= 0
    #
    @log_window.display_action_results(target, item)
  end # apply_item_effects

  #----------------------------------------------------------------------------|
  #  Rewrite method: invoke_counter_attack                                     |
  #----------------------------------------------------------------------------|
  def invoke_counter_attack(target, item)
    @log_window.display_counter(target, item)
    attack_skill = $data_skills[target.attack_skill_id]
    @subject.item_apply(target, attack_skill)
    # Rewritten to refresh the target only instead of the whole status window
    if @subject.actor? && @subject.index >= 0
      @status_window.draw_item(@subject.index)
    end
    #
    @log_window.display_action_results(@subject, attack_skill)
  end # invoke_counter_attack

end # Scene_Battle

#==============================================================================|

 

 

I'm still not 100% sure if it'd work ideally, but at least it should be noticeably better :)

 

 

I just realized that storing the logs is completely pointless, as the core issue is the wait of the battle log window. Now the logic of the snippet should be much clearer :D

 

 

Edited by DoubleX

Share this post


Link to post
Share on other sites

Yes, it works well. There is some actions which are faster. It's normal ? I would reduce it a little if it's possible.

 

Have you thought of something for my other problem ? To illustrate it, Here's an example of my method to play events when every enemy dies but before the end of the battle :

 

456315Capture.jpg

 

I translate :

 

When HP of an enemy arrive to 0 :

I activate a switch.

I modify a variable.

I remove Anti-Ko status.

I add Ko status

Wait if there is an other enemy still alive.

 

These events are necessary to me for a side quest. Is there another way to play these events differently when every enemy dies ? Because of that, the Ko status does not apply simultaneously to all enemies.

Edited by Nérylis

Share this post


Link to post
Share on other sites

May you please illustrate how some actions are actually faster?

 

For the event problem, I'd try -

When HP of an enemy arrives to 0:

I activate a switch

I modify a variable

I use another variable to store the number of dead enemies(so it should be set to 0 at the start of the battle and increased by 1 here)

If that another variable equals to the number of enemies, I remove Anti-Ko status from and add Ko status to all enemies

That's just my wild guess though :)

Share this post


Link to post
Share on other sites

When enemies attack, these actions are faster. The time between the attack of my actor 1 and the action of my actor 2 is reduced.

My actors which have successive attacks (as my monk for example and his two punches), these actions are also faster (although in this case, it does not bother me).

 

Your system is good but he can not be applied because another variable is increased by 1 in every page (one by enemy). When I use a skill which targer all, this another variable increased by 1, then by 1... The condition to verify if another variable equals to the number of enemies is never reached in this case.

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.

  • Recently Browsing   0 members

    No registered users viewing this page.

×