#==============================================================================
# ■ [Automated Switches/Variables Indie] 自更新开关变量独立版 v1.0 by SailCat
#------------------------------------------------------------------------------
# 方法:本脚本插入到Main之前使用,且需在所有依赖此脚本的其他插件之前
# 依赖:无
# 版本:v1.0 (Build 220122)
# 效果:开关和变量可以自更新(设置为自更新则无法进行赋值)
# 配置:自更新标记前导字符
# 冲突:无
# 说明:
# 1. 自更新的识别很简单:将变量或开关名称的首个字符写成前导字符即可
# 插件识别到前导字符,就会认为这是一个自更新的开关或者变量
# 2. 前导符是“=”(半角等号,可以配置)时,表示这是一个自更新的开关或变量
# = 符号之后的部分,是用于自更新的 Ruby 表达式
# 由于输入长度限制,为便利书写,表达式中可使用以下标识符,注意大小写
# 标识符 等价表达式 说明 示例写法
# ------------------------------------------------------------------------
# \N $game_actors 按ID号取角色(数组) \N[1].str
# \P $game_party.actors 按队序取角色(数组) \P[0].name
# \E $game_troop.enemies 按队序取敌人(数组) \E[2].level
# \M $game_map.events 按ID号取事件(哈希) \M[3]
# \L $game_party.max_level 全队等级(值) \L
# \G $game_party.gold 金钱(值) \G
# \B $game_party.steps 步数(值) \B
# \T $game_system.timer / 计时器(值) \T
# Graphics.frame_rate (换算为秒数)
# \F Graphics.frame_count / 游戏时间(值) \F
# Graphics.frame_rate (换算为秒数)
# \C $game_screen.weather_type 天气 类型(值) \C
# \I $game_party.item_number 道具 持有数(函数) \I(12)
# \W $game_party.weapon_number 武器 持有数(函数) \W(2)
# \A $game_party.armor_number 防具 持有数(函数) \A(31)
# .k? .skill_learn? 技能 习得否(函数) \N[1].k?(6)
# .w? (过于复杂,略) 武器 装备否(函数) \N[4].w?(8)
# .a? (过于复杂,略) 防具 装备否(函数) \P[2].a?(9)
# .s? .state? 状态 存在否(函数) \E[5].s?(3)
# .i? .include? 集合 包含否(函数) \P.i?(\N[7])
# --若将表达式开头加上反斜杠(\)符号会停止识别以上标识符,以下依然有效---
# a (过于复杂,略) 当前战斗者(仅战斗) a.maxhp
# b (过于复杂,略) 当前对象者(仅战斗) b[0].dead?
# l $game_player 主角 l.x
# s $game_switches 开关 s[23]
# v $game_variables 变量 v[112]
# f $game_self_switches 独立开关 f[[1,2,"A"]]
# m $game_map 地图数据 m.map_id
# t $game_temp 临时游戏数据 t.in_battle
# y $game_system 系统游戏数据 y.save_count
# r $game_screen 屏幕元素 r.tone.red
# 3. 表达式的执行上下文是Game_Switches或者Game_Variables,约等于没有上下文
# 所以并不存在事件系统中指定“本事件”或者类似的功能,书写时请注意
# 4. 出于游戏数据统一处理的需要,所有自更新开关会被强制转换为true或false
# 转换不成功的数据或运算失败的表达式,会自动识别成false,该功能不可关闭
# 5. 出于游戏数据统一处理的需要,所有自更新变量会被强制转换成整数
# 转换不成功的数据或运算失败的表达式,会自动识别成0,该功能可配置关闭
# 6. 由于编辑器输入限制,包括前导符在内的变量和开关名称最长40字符,无法突破
# 为了方便复杂条件的书写,本插件中的表达式功能额外提供以下判定写法
# ss(开关编号集):指定范围编号的开关是否有至少1个为true
# tt(开关编号集):指定范围编号的开关是否全部为true
# vv(变量编号集):指定范围编号的变量是否有至少1个不为0
# xx(变量编号集):指定范围编号的变量是否全部不为0
# uu(变量编号集):指定范围编号的变量值之和
#==============================================================================
#==============================================================================
# ■ SailCat's 插件公用
#==============================================================================
module SailCat
module System_Config
EVAL_PREFIX = ?= # 自更新开关/变量 前导识别符
DISABLE_SUB = ?\ # 自更新表达式停止宏替换标记符
FORCE_INT_V = true # 自更新的变量值是否强制转为整数
end
end
#==============================================================================
# ■ NameParser
#------------------------------------------------------------------------------
# 解析开关和变量名称的模块。
#==============================================================================
module NameParser
include SailCat::System_Config
#--------------------------------------------------------------------------
# ● 表达式缓存和宏替换
#--------------------------------------------------------------------------
@@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
#--------------------------------------------------------------------------
# ● 表达式计算
# exp : 名称中所含的表达式
#--------------------------------------------------------------------------
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
#--------------------------------------------------------------------------
# ● 辅助判定函数
#--------------------------------------------------------------------------
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
#--------------------------------------------------------------------------
# ● 获取自更新开关
# id : 开关 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
#--------------------------------------------------------------------------
# ● 获取自更新变量
# id : 变量 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