SOME WAYS TO STORE RGSS3 CODE STRINGS IN NOTETAGS

Share the 2 such ways I know so far

  • DoubleX
  • 04/25/2015 04:20 AM
  • 1117 views
Storing RGSS3 code strings in the notebox
Using this way, users need to write a complete RGSS3 code string for each notebox with each corresponding notetag. As sometimes it's just outright impossible to fit in just 1 line, the notetag must be able to read the multiline RGSS3 code strings. The below are some examples:

Yanfly Engine Ace - Skill Restrictions
# <restrict eval>
#  string
#  string
# </restrict eval>
# For the more advanced users, replace string with code to determine whether
# or not the skill is restricted. If multiple lines are used, they are all
# considered part of the same line.

RESTRICT_EVAL_ON  = /<(?:RESTRICT_EVAL|restrict eval)>/i
RESTRICT_EVAL_OFF = /<\/(?:RESTRICT_EVAL|restrict eval)>/i

self.note.split(/[\r\n]+/).each { |line|
      case line
      #---
      when YEA::REGEXP::SKILL::COOLDOWN
        @cooldown = $1.to_i
      when YEA::REGEXP::SKILL::WARMUP
        @warmup = $1.to_i
      when YEA::REGEXP::SKILL::LIMITED_USES
        @limited_uses = $1.to_i
      #---
      when YEA::REGEXP::SKILL::CHANGE_COOLDOWN
        @change_cooldown[0] = $1.to_i
      when YEA::REGEXP::SKILL::STYPE_COOLDOWN
        @change_cooldown[$1.to_i] = $2.to_i
      when YEA::REGEXP::SKILL::SKILL_COOLDOWN
        @skill_cooldown[$1.to_i] = $2.to_i
      #---
      when YEA::REGEXP::SKILL::RESTRICT_IF_SWITCH
        @restrict_any_switch.push($1.to_i)
      when YEA::REGEXP::SKILL::RESTRICT_ANY_SWITCH
        $1.scan(/\d+/).each { |num|
        @restrict_any_switch.push(num.to_i) if num.to_i > 0 }
      when YEA::REGEXP::SKILL::RESTRICT_ALL_SWITCH
        $1.scan(/\d+/).each { |num|
        @restrict_all_switch.push(num.to_i) if num.to_i > 0 }
      #---
      when YEA::REGEXP::SKILL::RESTRICT_EVAL_ON
        @restrict_eval_on = true
      when YEA::REGEXP::SKILL::RESTRICT_EVAL_OFF
        @restrict_eval_off = true
      else
        @restrict_eval += line.to_s if @restrict_eval_on
      #---
      end
    } # self.note.split

So the restrict eval can be used like this:
<restrict eval>
if actor? && state?(x); 
  if $game_variables[y] > z; 
    auto_battle?; 
  else; 
    confusion?; 
  end; 
else; 
  @hp != mhp; 
end
</restrict eval>

And @restrict_eval should become this:
if actor? && state?(x); if $game_variables[y] > z; auto_battle?; else; confusion?; end; else; @hp != mhp; end


State Add/Remove Commands(Written by Shaz)
# To execute a command when a state is added, add the following line to the
# state's notes:
#    onadd: command
#
# To execute a command when a state is removed, add the following line to the
# state's notes:
#    onremove: command
#
# command is a RGSS script command that will be eval'd, so it may consist of
# any valid script command.  It may extend over more than one line, and may
# consist of several commands separated by semi-colons, but it must NOT be
# broken by pressing the Enter key (just keep typing and let the editor put
# in its own line breaks by default).

#--------------------------------------------------------------------------
  # * State Add Commands
  #--------------------------------------------------------------------------
  def state_add_command(state_id)
    $data_states[state_id].note.split(/[\r\n]/).each do |line|
      case line
      when /onadd:\s*(.*)/i
        eval($1)
      end
    end
  end
  #--------------------------------------------------------------------------
  # * State Remove Commands
  #--------------------------------------------------------------------------
  def state_remove_command(state_id)
    $data_states[state_id].note.split(/[\r\n]/).each do |line|
      case line
      when /onremove:\s*(.*)/i
        eval($1)
      end
    end
  end

Shaz also gave some examples:
# Examples:
# - this will just print a line of text to the console when the state is added
#   onadd: p 'state added'
#
# - this will print a line of text to the console AND reserve a common event
#   to be run on the map when the state is removed - note it's done over
#   two commands/lines (the second line will automatically wrap to 2 lines)
#   onremove: p 'state removed'
#   onremove: $game_temp.reserve_common_event(1)
#
# - this will run one of two commands based on the battler's current hp when
#   a state is added (enter key is not used here to go to a second line)
#   onadd: if hp_rate < 0.5; p 'low hp - need topup';
#   else; p 'hp good'; end;


Storing RGSS3 code strings in the script's user editable region
Using this way, users need to write all the complete or partial RGSS3 code strings in the script's user editable region, each of which is stored by a constant added by users. Then the notetag using those RGSS3 code strings need to store the name of the constant storing the RGSS3 code string to be used. For example:

DoubleX RMVXA State Triggers
#------------------------------------------------------------------------------|
#  * State Notetags:                                                           |
#    1. <timing state trigger: STCX, STAX>                                     |
#       - Sets a state to trigger STAX when timing and STCX are met            |
#       - timing can be either add, turn or remove                             |
#       - add means the state's just added                                     |
#       - turn means the state's remaining turn's just reduced by 1            |
#       - remove means the state's just removed                                |
#       - STCX can be set in State Trigger Condition Notetag Values            |
#       - STAX can be set in State Trigger Action Notetag Values               |
#------------------------------------------------------------------------------|

#--------------------------------------------------------------------------|
    #  State Trigger Condition Notetag Values                                  |
    #  - Setups STCX used by this script's notetags                            |
    #--------------------------------------------------------------------------|
    # STCX are used at:
    # 1. Game_Battler
    #    - eval(trigger[timing][1]) if trigger[timing] && 
    #      eval(trigger[timing][0]) in eval_state_triggers
    # STCX are strings of RGSS3 codes
    # STCX names can only use alphanumeric characters
    # The below STCX are examples added to help you set your STCX
    # You can freely use, rewrite and/or delete these examples

    # Sets the state trigger condition as always true
    STC1 = "true"

    # Sets the state trigger condition as always false
    STC2 = "false"

    # Sets the state trigger condition as needing switch with id x to be on
    STC3 = "$game_switches[x]"

    # Adds new STCX here
    

    #--------------------------------------------------------------------------|
    #  State Trigger Action Notetag Values                                     |
    #  - Setups STAX used by this script's notetags                            |
    #--------------------------------------------------------------------------|
    # STAX are used at:
    # 1. Game_Battler
    #    - eval(trigger[timing][1]) if trigger[timing] && 
    #      eval(trigger[timing][0]) in eval_state_triggers
    # STAX are strings of RGSS3 codes
    # STAX names can only use alphanumeric characters
    # The below STAX are examples added to help you set your STAX
    # You can freely use, rewrite and/or delete these examples

    # Sets the state trigger action as what Special Effect Escape does
    STA1 = "hide"

    # Sets the state trigger action as calling common event with id
    # common_event_id
    STA2 = "$game_temp.reserve_common_event(common_event_id)"

    # Sets the state trigger action as executing damage equal to the value of
    # game variable with id x to self with type equal to that of skill with id
    # equal to y
    STA3 = "@result.clear; @result.make_damage($game_variables[x], 
            $data_skills[y]); execute_damage(self)"

    # Adds new STAX here

If I want to add a state trigger with the timing, conditions and actions triple as add, STC1 and STA1, turn, STC2 and STA2, and remove, STC3 and STA3, to a state, I need to add the below notetags to that state's notebox:
<add state trigger: STC1, STA1>
<turn state trigger: STC2, STA2>
<remove state trigger: STC3, STA3>

The below shows how those notetags are read:
#----------------------------------------------------------------------------|
  #  New method: load_notetags_state_triggers                                  |
  #  - Loads each <timing state trigger: STCX, STAX> notetag from its notebox  |
  #----------------------------------------------------------------------------|
  def load_notetags_state_triggers
    # Stores all timing, STCX and STAX triples from matching lines sequentially
    @state_triggers = { :add => [], :turn => [], :remove => [] }
    st = "DoubleX_RMVXA::State_Triggers::"
    @note.split(/[\r\n]+/).each { |line|
      next unless line =~ /<(\w+) state trigger:\s*(\w+)\s*,\s*(\w+)\s*>/
      @state_triggers[$1.to_sym].push([eval("#{st}#{$2}"), eval("#{st}#{$3}")])
    }
    #
  end # load_notetags_state_triggers

Using the above notetag usage example, @state_triggers should become:
{
  :add => ["true", "hide"],
  :turn => ["false", "$game_temp.reserve_common_event(common_event_id)"],
  :remove => ["$game_switches[x]", "@result.clear; @result.make_damage($game_variables[x],
            $data_skills[y]); execute_damage(self)"]
}


Comparison between the above 2 ways
I'm not going to say which one is objectively better, as I think that each has their own advantages and disadvantages, making some cases preferring the 1st way and some preferring the 2nd one.

Advantages of the 1st way over the 2nd one
1. More straightforward
To set a new RGSS3 code string to be used by a notetag, you just need to directly put it inside that notetag in the 1st way, while you first need to add a new constant storing that RGSS3 code string, then put the name of that constant inside that notetag in the 2nd way.
2. Smaller script user editable region
In the 1st way, no RGSS3 string code's stored in the script user editable region at all, making that region more user friendly; In the 2nd way, all those RGSS3 string codes are stored in the script user editable region, making that region less user friendly, unless the users don't mind having a long list of RGSS3 string codes in the script user editable region and have at least little scripting proficiency(In all of my scripts using the 2nd way, decent scripting proficiency's needed to fully utilize it).

Advantages of the 2nd way over the 1st one
1. Better RGSS3 string code reusability
If many notetags uses the same RGSS3 string code and you want to change that code itself(and not just specific notetags using it), you'll have to apply that change to all notetags using it in the 1st way, while you just need to change the constant storing that RGSS3 string code in the 2nd way.
2. Better RGSS3 string code flexibility
In the 1st way, you always have to put complete RGSS3 string codes into notetags using them; In the 2nd way, you can break them into new constants storing their building blocks, and build the constants storing the complete RGSS3 code strings by combining those storing their building blocks. When many complete RGSS3 string codes share the same common part and you want to change that common part, you'll have to change that part in all those complete RGSS3 string codes, and apply the changes to all notetags using them in the 1st way, while you can break that common part as a constant storing it, make all constants storing those complete RGSS3 string codes use that constant storing that common part, and just change that constant storing that common part in the 2nd way.
For example, I need to use the below 3 complete RGSS3 string codes:
"code_part_1; code_part_2"

"code_part_2; code_part_3"

"code_part_3; code_part_1"

In the 1st way, you always have to input each of the above 3 codes completely into its corresponding notetags; In the 2nd way, you can break the above 3 codes into this:
CP1 = "code_part_1"
CP2 = "code_part_2"
CP3 = "code_part_3"
CC1 = CP1 + "; " + CP2
CC2 = CP2 + "; " + CP3
CC3 = CP3 + "; " + CP1

Then just put CC1, CC2 and CC3 into their corresponding notetags.
In the 1st way, When I want to change the common part code_part_2, I'll have to change both the 1st and 2nd complete RGSS3 code strings using it and apply the changes to all notetags using those complete RGSS3 code strings:
"code_part_1; edited_code_part_2"

"edited_code_part_2; code_part_3"

In the 2nd way, I just have to change CP2:
CP2 = "edited_code_part_2"


What do you think about the aforementioned 2 ways? Do you have other ways to store the RGSS3 code strings in notetags? Again, I won't claim what I said as absolute truths, so feel free to correct me :)