Friday Script – Making it Rain

Reddit user Rubh has a really interesting idea for a riff on the traditional poison attack. The attack – called “Arrow Rain” – will be a standard AOE physical attack doing the traditional a.atk*4 – b.def*2 damage to each (with a little variance). Our archer can then attack in his next turn, but at the end of the next few turns, arrows continue to rain down, dealing more damage.

Normally, poison would help us out here. It’s a damage over time effect that happens every turn, and frees up the caster to do his own thing. So what’s the problem? Poison doesn’t remember the applier. Sure, we can level up poison by having more draining poisons, but in all instances, we’re depleting a percentage of the poisoned person’s HP. In short, with poison we can’t do a.atk*4 – b.def*2 damage.

To get our intended effect, we need to do a fair amount of work. Luckily, once it’s in place, it’s mercifully easy to change and also repeat.

In The Database

We have a little bit of work to do in the database before we get going with a script. Specifically, we need to create our skill and also set a a global variable. The skill is easy, you can set any parameter you want. Here, I’ve added a TP cost, and made the required weapon a bow. I’ve added animation 18: Pierce Special 2 (important, remember that), disabled critical, made sure it hits all enemies in battle…all of the usual stuff you’d do for a skill.

Use animations, damage, etc. as you see fit. Just remember it all for your script!

Use animations, damage, etc. as you see fit. Just remember it all for your script!

The trick is in the damage formula here. Notice that after the standard damage, I’ve added

; $game_variables[10] = 4

I talk more about using the formula as a script call in this blog post. Suffice it to say that I’m setting variable 10 to the number 4. I’ll explain why in a second.

That’s all you have to do here. There are no states, no common events, no changes to the troops or enemies.

Alias

Sometimes, we want to change or modify the way RPG Maker handles a task. For this skill, I want to change what happens when a battle turn ends. All of that information is handled in our scripts in, unsurprisingly, Scene_Battle.turn_end.

It’s a bad idea to fiddle with this stuff directly. Once you start tinkering with the default RPG Maker default scripts, you’ll end up making a change that you can’t undo, you’ll delete something critical – basically, you’ll dig yourself a nasty hole.

So instead, we do something called “aliasing”. What this means is:

  1. We change the name of Scene_Battle.turn_end to old_turn_end
  2. We write a new function called Scene_Battle.turn_end
  3. In that new function, we do whatever we want, and then call old_turn_end

This is a good way to segregate our code from RPG Maker’s default. It is what every plug-n-play script does, including those made by Yanfly, Victor, Hime, Fomar, and everyone else. It looks like this:

class Scene_Battle
 alias :old_turn_end :turn_end 
 
 def turn_end
     #do all of our stuff here
     old_turn_end
 end
 
end

Write The Code

Now, we want to actually do all of our stuff in turn_end. We need to do a few things:

1) Check to see if we should even both with arrow rain. If no, just run old_turn_end and be done with it.

2) Play the attack animation and show text as to what’s happening.

3) For each enemy, damage them and show text reflecting how much damage it took

4) Reduce the number of turns arrow rain will last by 1

So let’s explore each one at a time:

Check the Time of Rain of Arrows

Remember way above when I set the Variable[10] to 4? I’m using this variable to track how many turns Arrow Rain will run. The line is:

    if (1..3).include?($game_variables[10])

Wait, range 1-3? Why not range 1-4? We set it to 4! Because arrow rain has already attacked the first turn we set it. We don’t want the Archer to cast it and then also for it to trigger at the end of that turn. We do, however, want to reduce the variable regardless. so something like:

def turn_end
 if (1..3).include?($game_variables[10])
      #re-cast Arrow Rain
      $game_variables[10] -= 1
 elsif $game_variables[10] == 4
      $game_variables[10] -= 1
 end
 old_turn_end
end

Now, we’ll correctly re-cast Arrow Rain for 3 turns, starting on the turn after it’s cast.

Play Attack Animation and Text

This one is easy. We use @log_window to refer to that battle log window that is typically at the top of the screen, and show_animation to play attack animations.

 @log_window.add_text("Arrows continued to rain from the sky!") 
 show_animation($game_troop.members, 18)

Remember, 18 is the animation I chose in my skill in the database!

Damage

This one is complicated. As stated wayyyy up at the top of the article, we use a.atk*4 – b.def*2 to represent the damage done. But we also have a variance of about 20% in either direction in the skill.

Variance makes it so that you don't always do the exact same damage to the same type of enemy over and over again.

Variance makes it so that you don’t always do the exact same damage to the same type of enemy over and over again.

How do we get this? Let’s define the high and low:

 low = ((($game_actors[1].atk * 4) - (enemy.def * 2)) * 0.8).floor
 high = ((($game_actors[1].atk * 4) - (enemy.def * 2)) * 1.2).ceil

We can’t use “a” and “b” because the script doesn’t know who they are. $game_actors[1] is our first actor (presumably our archer), and we’ll define enemy in a second. We then multiple one by .8, one by 1.2, and then round those down and up respectively. Then we can choose a damage number somewhere between these two.

 damage = (low..high).to_a.sample
 enemy.hp -= damage
 enemy.perform_damage_effect
 @log_window.add_text("#{enemy.name} took #{damage} damage!")
 wait(60)

We reduce the enemy hp by “damage”, we play the flinch effect, and we add text in the log that says they took damage. We wait 60 frames(1 second) between each enemy to give the player a chance to catch up, and to mirror RPG Maker’s normal AOE attacks.

“Enemy” is used to refer to a member of the troop.

Putting it All Together

So what does this all mean? This is our completed Arrow Rain script. Drop it in your materials section, build the skill in your database, and make it rain!

 

class Scene_Battle
 
 alias :old_turn_end :turn_end 
 
 def turn_end
      if (1..3).include?($game_variables[10])
           @log_window.add_text("Arrows continued to rain from the sky!") 
           show_animation($game_troop.members, 18)
           $game_troop.members.each { |enemy| 
                low = ((($game_actors[1].atk * 4) - (enemy.def * 2)) * 0.8).floor
                high = ((($game_actors[1].atk * 4) - (enemy.def * 2)) * 1.2).ceil
                damage = (low..high).to_a.sample
                enemy.hp -= damage
                enemy.perform_damage_effect
                @log_window.add_text("#{enemy.name} took #{damage} damage!")
                wait(60)
           }
           $game_variables[10] -= 1
      elsif $game_variables[10] == 4
           $game_variables[10] -= 1
      end
      old_turn_end
 end
end

Challenge

This script doesn’t do a lot of things:

  • Miss
  • Hit critically
  • Account for the fact that a player could cast Arrow Rain two turns in a row
  • Allow for multiple player characters to use the ability
  • Account for the fact that a player’s attack value might change after they cast Arrow Rain (and thus increase the damage of all subsequent waves)

How might we handle those situations in the script? Check back in a few weeks for an update with the solutions!

 

 

 

Advertisements

5 thoughts on “Friday Script – Making it Rain

  1. (Rubh’s not-a-throwaway here) You rock! Thanks for the taking the time. I’m sure lots of people will find this useful. And it can have many uses (Firey-field DoT?) Thanks again!

  2. Pingback: Making it Rain Round 2 – Missing and Evading | The Iron Shoe
  3. Pingback: New Skill – Guardian Angel | The Iron Shoe
  4. Pingback: Summon Shield | The Iron Shoe

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s