Automatic Updating Switches and Variables
By SailCat
Introduction
This script turns switches and variables into auto-updating by binding an expression to it.
Features
XP, unlike VX or VA, allows only switches, variables and self switches to be used for events. So it is difficult to set an NPC to be available when, say, Alexus is present, or a key item is held in inventory. The two conditions are available in later maker versions.
This script makes a turnaround by setting a switch (variable as well) as always ready to represent a certain expression.
If you want a switch to indicate whether Alexus is present, write its name as "=\P.i?(\N[1])" (remove quotation mark).
If you want a switch to indicate whether a key is held, write its name as "=\I(29)>0"
The first char, =, tells the plugin that the target switch is an auto-updating one. So instead of normally turning it on or off, it will instead evaluate the expression after it.
You can far do more than what VX/VA can achieve.
To test if Alexus is wielding mithril sword, name a switch as "=\N[1].w?(4)"
To set an enemy to act in a way when party level is BELOW a certain value: name a switch as "=\L<15", and then set this switch as an action trigger, since default action triggers only allows party level ABOVE a certain value.
To test whether you have collected enough items from anywhere (drops, NPCs, treasures).
You had to:
1. Set a common event to be parallel upon some switch
2. Let the event judge the item number every frame, until you fulfill it
3. Do the processes, and turn off the switch(to prevent the process from triggering a second time)
Now with this script:
1. Set a common event to be automatic upon some switch, and name the switch such as "=\I(x)>y && !s[z]"
2. Do the processes, and turn on switch z(to prevent the process from triggering a second time)
This saves the engine from updating an extra parallel common event every frame.
To make an event like granting you Excalibur II when you reach it in less than 12 hours.
You had to:
1. Set the target event to be automatic in the first page, and use a second and third(empty) page.
2. In the first page, use operate variables to load elapsed time, and turn Self Switch A on (to stop automatic processing)
3. Set the second page to be on self switch A, and grant the reward on this page.
4. Set the third page to be empty on "self switch A" and "variable > 43200" to hide the reward when time expires.
Now with the script:
1. Name a variable as "=-\F"
2. Set the target event on "variable > -43200", and give the reward on the first page.
3. No extra processing or pages required.
How to Use
Refer to the comment before plugin script.
Terms and Credits
Feel free to use in any kind of games.
Please credit me by leaving the second line of the script.
Redistributions are OK. Secondary development is not allowed.
Ruby:
- #==============================================================================
- # ■ Automated Switches & Variables by SailCat
- #------------------------------------------------------------------------------
- # Introduction:
- # This script turns switches and variables into auto-updating by binding
- # an expression to it.
- #
- # Installation Guide:
- # Insert this script before the "Main" section.
- #
- # Date of release:
- # Sep. 6, 2024 (version 1.0)
- #
- # Effects:
- # 1. Allows auto-updating switches bound to Ruby expressions.
- # 2. Allows auto-updating variables bound to Ruby expressions.
- # 3. The auto-updating switches or variables do not update per frame (as this
- # may greatly the system frame rates). Instead, they are updated
- # only when their values are used to allow optimal performance.
- # 4. You can not turn auto-updating switches on or off, nor can you assign
- # values to auto-updating switches, either by event commands or by script.
- #
- # How to use:
- # 1. Any switch or variable with its name starting with "=" char is considered
- # to be auto-updating. (The char can be configured in the script)
- # 2. In this case, the remaining 39 chars of the name can be written as valid
- # Ruby expression by which the switch or variable is evaluated upon update.
- # 3. To save space, abbreviations are allowed in the expression as follows:
- # Abbr Equivalent to Meaning Example
- # ------------------------------------------------------------------------
- # \N $game_actors Get actor by ID \N[1].str
- # \P $game_party.actors Get actor by party pos \P[0].name
- # \E $game_troop.enemies Get enemy by troop pos \E[2].level
- # \M $game_map.events Get map event by ID \M[3]
- # \L $game_party.max_level Get party level \L
- # \G $game_party.gold Get gold deposit \G
- # \B $game_party.steps Get step count \B
- # \T $game_system.timer / Get timer \T
- # Graphics.frame_rate (cast in seconds)
- # \F Graphics.frame_count / Get elapsed time \F
- # Graphics.frame_rate (cast in seconds)
- # \C $game_screen.weather_type Get weather type \C
- # \I $game_party.item_number Get item number by ID \I(12)
- # \W $game_party.weapon_number Get weapon number by ID \W(2)
- # \A $game_party.armor_number Get armor number by ID \A(31)
- # .k? .skill_learn? Skill learned by actor \N[1].k?(6)
- # .w? (omitted for complexity) Weapon equipped by actor \N[4].w?(8)
- # .a? (omitted for complexity) Armor equipped by actor \P[2].a?(9)
- # .s? .state? State present by battler \E[5].s?(3)
- # .i? .include? Element in array or set \P.i?(\N[7])
- # a (omitted for complexity) Current active battler a.maxhp
- # b (omitted for complexity) Targeted battlers b[0].dead?
- # l $game_player The player character l.x
- # s $game_switches Switches s[23]
- # v $game_variables Variables v[112]
- # f $game_self_switches Self switches f[[1,2,"A"]]
- # m $game_map Map data m.map_id
- # t $game_temp Temporary data t.in_battle
- # y $game_system System data y.save_count
- # r $game_screen Screen data r.tone.red
- # 4. Auto-updating switches are evaluated and forcingly cast as true or false.
- # Failed expressions are considered as false.
- # 5. Auto-updating variables are evaluated and forcingly cast as integers.
- # Failed expressions are considered as zero (0).
- # If you need non-integer values, turn the setting off in configurations.
- # 6. This plugin also supports multiple condition referring to switches or
- # variables:
- # ss(range or array of switch IDs): any switch in set is true
- # Ex: ss(5..7) is the same as s[5] || s[6] || s[7]
- # tt(range or array of switch IDs): all switches in set are true
- # Ex: tt([98,132,142]) is the same as s[98] && s[132] && s[142]
- # vv(range or array of variable IDs): any variable in set is non-zero
- # Ex: vv(12..14) is the same as v[12] != 0 || v[13] != 0 || v[14] != 0
- # xx(range or array of variable IDs): all variables in set are non-zero
- # Ex: xx([17, 28]) is the same as v[17] != 0 && v[28] != 0
- # uu(range or array of variable IDs): the sum value of variables in set
- # Ex: uu(1..6) is the same as v[1]+v[2]+v[3]+v[4]+v[5]+v[6]
- #==============================================================================
- #==============================================================================
- # ■ SailCat's XP Plugins
- #==============================================================================
- module SailCat
- #--------------------------------------------------------------------------
- # ● Configurations
- #--------------------------------------------------------------------------
- module System_Config
- EVAL_PREFIX = ?= # Prefix char for auto-updating expression
- DISABLE_SUB = ?\ # Escape char to stop macro replacing
- FORCE_INT_V = true # Force variables into integers
- end
- end
-
- #==============================================================================
- # ■ NameParser
- #------------------------------------------------------------------------------
- # The module parsing switch and variable names
- #==============================================================================
- module NameParser
- include SailCat::System_Config
- #--------------------------------------------------------------------------
- # ● Cached expressions for macro replacement
- #--------------------------------------------------------------------------
- @@exp_cache = Hash.new do |hash, exp|
- key = exp.clone
- unless exp[0] == DISABLE_SUB
- exp.gsub!(/\\N/) { "$game_actors" }
- exp.gsub!(/\\P/) { "$game_party.actors" }
- exp.gsub!(/\\E/) { "$game_troop.enemies" }
- exp.gsub!(/\\M/) { "$game_map.events" }
- exp.gsub!(/\\L/) { "$game_party.max_level" }
- exp.gsub!(/\\G/) { "$game_party.gold" }
- exp.gsub!(/\\B/) { "$game_party.steps" }
- exp.gsub!(/\\T/) { "$game_system.timer / Graphics.frame_rate" }
- exp.gsub!(/\\F/) { "Graphics.frame_count / Graphics.frame_rate" }
- exp.gsub!(/\\C/) { "$game_screen.weather_type" }
- exp.gsub!(/\\I/) { "$game_party.item_number" }
- exp.gsub!(/\\W/) { "$game_party.weapon_number" }
- exp.gsub!(/\\A/) { "$game_party.armor_number" }
- exp.gsub!(/\.k\?/) { ".skill_learn?" }
- exp.gsub!(/\.w\?/) { ".weapon_id==" }
- exp.gsub!(/\.a\?/) { ".to_a.map{|a|[a.armor1_id,a.armor2_id,"+
- "a.armor3_id,a.armor4_id]}.flatten.i?" }
- exp.gsub!(/\.s\?/) { ".state?" }
- exp.gsub!(/\.i\?/) { ".include?" }
- else
- exp.slice!(0, 1)
- end
- hash[key] = exp
- end
- #--------------------------------------------------------------------------
- # ● Parse expression
- # exp : The expression written in name
- #--------------------------------------------------------------------------
- def self.parse(exp)
- lambda {|a, b, l, s, v, f, m, t, y, r| eval(@@exp_cache[exp])}.call(
- $game_temp.in_battle ?
- $scene.instance_variable_get(:@active_battler) : nil,
- $game_temp.in_battle ?
- $scene.instance_variable_get(:@target_battlers) : nil,
- $game_player, $game_switches, $game_variables, $game_self_switches,
- $game_map, $game_temp, $game_system, $game_screen
- )
- end
- #--------------------------------------------------------------------------
- # ● Set judging functions to allow simple multi-evaluation
- #--------------------------------------------------------------------------
- def self.ss(set); set.to_a.any? {|id| $game_switches[id]}; end
- def self.tt(set); set.to_a.all? {|id| $game_switches[id]}; end
- def self.vv(set); set.to_a.any? {|id| $game_variables[id] != 0}; end
- def self.xx(set); set.to_a.all? {|id| $game_variables[id] != 0}; end
- def self.uu(set); set.to_a.inject(0){|a,id| a+$game_variables[id]}; end
- end
-
- #==============================================================================
- # ■ Game_Switches
- #==============================================================================
- class Game_Switches
- include SailCat::System_Config
- #--------------------------------------------------------------------------
- # ● Retrieve auto-updating switches
- # id : Switch ID
- #--------------------------------------------------------------------------
- alias sailcat_autosw :[]
- def [](id)
- if $data_system.switches[id].to_s[0] == EVAL_PREFIX then
- !!NameParser::parse($data_system.switches[id][1..-1]) rescue false
- else
- sailcat_autosw(id)
- end
- end
- end
-
- #==============================================================================
- # ■ Game_Variables
- #==============================================================================
- class Game_Variables
- include SailCat::System_Config
- #--------------------------------------------------------------------------
- # ● Retrieve auto-updating variables
- # id : Variable ID
- #--------------------------------------------------------------------------
- alias sailcat_autova :[]
- def [](id)
- if $data_system.variables[id].to_s[0] == EVAL_PREFIX then
- value = (NameParser::parse($data_system.variables[id][1..-1]) rescue 0)
- FORCE_INT_V ? (value.to_i rescue 0) : value
- else
- sailcat_autova(id)
- end
- end
- end
复制代码
本贴来自国际rpgmaker官方论坛作者:SailCat处,因国际论坛即将永久关站,为了存档多年珍贵资料,署名转载到本论坛存档,由于官方帖子为英文原帖,需要中文翻译请点击论坛顶部切换语言为中文就可以将帖子翻译成中文浏览,方便大家随时查看,原文地址:
https://forums.rpgmakerweb.com/threads/automatic-updating-switches-and-variables-xp.171725/