- Joined
- Feb 20, 2014
- Messages
- 81
- Reaction score
- 27
- First Language
- English
- Primarily Uses
- N/A
Hello!
So, this isn't necessarily a concise "script", but it is related to scripting, so I thought it would be appropriate to place here. Basically, it's a method I devised for creating battler actions that reference many variables or perform complex actions. I came up with this because it was becoming difficult to cram a bunch of code into the notes box in the skills editor. In addition, it can be built from scratch, although there are some scripts out there that perform similar functions.
The Battle Extension Class -
You first need to create a new class. I called mine Game_BattleExtension and assigned it to a global variable $battle_extension, because it works like an extension of the Scene_Battle class and I plan to interact with it across many classes. Although making it global isn't necessary in all cases. Also, because it might be used to display text often, you might want to give it full access to the Scene_Battle's log_window object. You'll want to create an instance of your Battle Extension class around here:
class Scene_Battle def start super create_spriteset create_all_windows create_battle_extension BattleManager.method_wait_for_message = method
wait_for_message) end def create_battle_extension $battle_extension = Game_BattleExtension.new(@log_window) # over here! end ...endSo, let's say you want an Action to do some damage, but you want it to alter the game in some way before it executes, maybe display a certain line of text before damage is dealt. You'll want to create a method in your Battle Extension class that is called before an Action is executed, as such:
class Game_BattleExtension def initialize(log_window) @log_window = log_window end def pre_invocation_processing(action, subject, target) # right here! endendThe Pre-* Method -
You'll see that I call this method right before the invoke_item method is called, thus it is named pre_invocation_processing. However, you can call such a method any time during the processing/execution of the action and thus give it any name (i.e. pre_processing, pre_execution, etc.). I also pass the action, the action subject, and the action target as parameters. In reality, all you truly need is the action object itself.
class Scene_Battle ... def use_item ... targets.each { |target| item.repeats.times { $battle_extension.pre_invocation_processing(action, @subject, target) # right here! invoke_item(target, item) } } end ...endNow for the cool part! This is why the Ruby programming language is awesome.
You'll want to add some code like this:
def pre_invocation_processing(action, subject, target) method_name = action.item.name.downcase.gsub(/[ ,\.]/, "_") return unless methods.include?(method_name.to_sym) method(method_name).call(action, subject, target)endHere's what this does:
[*]The fourth line references a method object--the Action Method--from the method name (which should correspond to a particular method later in the class) and calls it
The Action Method -
So, lets say I wanted, before invoking an action, to make some text appear. I name my action "Dipper Pines" in the editor. I do everything as mentioned before, and then I create an Action Method dipper_pines in the Battle Extension class. Like so:
def dipper_pines @log_window.add_text("Mabel! Stop bedazzling all of my stuff!!")endSo when this action is processed, the Scene_Battle class will call on the pre_invocation_method, which will notice that there is a method that corresponds to this particular action and execute it, thus displaying the text.
An Example -
There's a LOT of stuff you can do when you aren't hindered by the strictness of the editor. Here's an example of one thing I did:
I created an action named "Swing" that chooses a random object to swing at an opponent. In the Battle Extension class, I initialized a hash called @swing_objects containing strings like "flimsy stick", "iron pipe", "fists" matched to numbers like 0.5, 3, 1, respectively that correspond to relative damage. the "swing" Action Method, when called, displays a message describing what object is being swung. It then proceeds to change the action's damage formula depending on the number that was chosen. When handling returns to the Scene_Battle, the new damage formula is used to do damage (This in itself is a complex topic as well, so don't worry about how it can be done for now, just know that the damage changes considerably for the object that's chosen).
def swing(action, subject, target) pair = @swing_objects.to_a.sample object = pair[0] coefficient = pair[1] @log_window.add_text(sprintf(Vocab::Skill_Swing, subject.name, object)) clear_item_formula(action.item) action.item.damage.formula = sprintf(action.item.damage.formula, coefficient.to_s)end
Conclusion -
What's awesome is that, using Ruby, you can VERY easily check if there's a method to be called and then actually transform a string that is a method name into an actual method call! And, if there is no special processing to be done, the code takes care of it, returning early.
Hope this was interesting! If you didn't understand any bit (even with my fancy color-coded text), feel free to ask a question. Also, I encourage people to find more efficient ways of doing this and sharing it on this thread.
So, this isn't necessarily a concise "script", but it is related to scripting, so I thought it would be appropriate to place here. Basically, it's a method I devised for creating battler actions that reference many variables or perform complex actions. I came up with this because it was becoming difficult to cram a bunch of code into the notes box in the skills editor. In addition, it can be built from scratch, although there are some scripts out there that perform similar functions.
The Battle Extension Class -
You first need to create a new class. I called mine Game_BattleExtension and assigned it to a global variable $battle_extension, because it works like an extension of the Scene_Battle class and I plan to interact with it across many classes. Although making it global isn't necessary in all cases. Also, because it might be used to display text often, you might want to give it full access to the Scene_Battle's log_window object. You'll want to create an instance of your Battle Extension class around here:
class Scene_Battle def start super create_spriteset create_all_windows create_battle_extension BattleManager.method_wait_for_message = method
class Game_BattleExtension def initialize(log_window) @log_window = log_window end def pre_invocation_processing(action, subject, target) # right here! endendThe Pre-* Method -
You'll see that I call this method right before the invoke_item method is called, thus it is named pre_invocation_processing. However, you can call such a method any time during the processing/execution of the action and thus give it any name (i.e. pre_processing, pre_execution, etc.). I also pass the action, the action subject, and the action target as parameters. In reality, all you truly need is the action object itself.
class Scene_Battle ... def use_item ... targets.each { |target| item.repeats.times { $battle_extension.pre_invocation_processing(action, @subject, target) # right here! invoke_item(target, item) } } end ...endNow for the cool part! This is why the Ruby programming language is awesome.
You'll want to add some code like this:
def pre_invocation_processing(action, subject, target) method_name = action.item.name.downcase.gsub(/[ ,\.]/, "_") return unless methods.include?(method_name.to_sym) method(method_name).call(action, subject, target)endHere's what this does:
- The second line translates the action's "name" (what you called it in the editor) into a method name, like so:Super Attack --> super_attack
- Valence Electron_3 --> valence_electron_3
- Magic Homerun 2.0 --> magic_homerun_2_0
[*]The fourth line references a method object--the Action Method--from the method name (which should correspond to a particular method later in the class) and calls it
The Action Method -
So, lets say I wanted, before invoking an action, to make some text appear. I name my action "Dipper Pines" in the editor. I do everything as mentioned before, and then I create an Action Method dipper_pines in the Battle Extension class. Like so:
def dipper_pines @log_window.add_text("Mabel! Stop bedazzling all of my stuff!!")endSo when this action is processed, the Scene_Battle class will call on the pre_invocation_method, which will notice that there is a method that corresponds to this particular action and execute it, thus displaying the text.
An Example -
There's a LOT of stuff you can do when you aren't hindered by the strictness of the editor. Here's an example of one thing I did:
I created an action named "Swing" that chooses a random object to swing at an opponent. In the Battle Extension class, I initialized a hash called @swing_objects containing strings like "flimsy stick", "iron pipe", "fists" matched to numbers like 0.5, 3, 1, respectively that correspond to relative damage. the "swing" Action Method, when called, displays a message describing what object is being swung. It then proceeds to change the action's damage formula depending on the number that was chosen. When handling returns to the Scene_Battle, the new damage formula is used to do damage (This in itself is a complex topic as well, so don't worry about how it can be done for now, just know that the damage changes considerably for the object that's chosen).
def swing(action, subject, target) pair = @swing_objects.to_a.sample object = pair[0] coefficient = pair[1] @log_window.add_text(sprintf(Vocab::Skill_Swing, subject.name, object)) clear_item_formula(action.item) action.item.damage.formula = sprintf(action.item.damage.formula, coefficient.to_s)end
Conclusion -
What's awesome is that, using Ruby, you can VERY easily check if there's a method to be called and then actually transform a string that is a method name into an actual method call! And, if there is no special processing to be done, the code takes care of it, returning early.
Hope this was interesting! If you didn't understand any bit (even with my fancy color-coded text), feel free to ask a question. Also, I encourage people to find more efficient ways of doing this and sharing it on this thread.
Last edited by a moderator:
