#============================================================================== # ■ 技能消耗依赖 v1.3 by SailCat #------------------------------------------------------------------------------ # 方法:本脚本插入到Main之前使用,并依赖数据库通用备注接口插件(在其之后) # 版本:v1.3 (Build 171122) # 效果: # 1. 技能消耗SP以外的游戏数据,包括HP、道具、武器、防具、金钱、经验、变量 # 2. 技能使用场合依赖游戏条件,包括开关、状态、地图相关、装备、能力、步数等 # 3. 技能消耗额外的回合(技能冷却) # 配置:插件为即插即用型,没有任何配置项,也不需要在脚本中设定任何东西 # 冲突:其他同类脚本,以及魔改了Scene_Skill的脚本 # 说明: # 1. 技能消耗道具、武器、防具、金钱、变量时,有使用检查,不够消耗不让用。 # 2. 技能消耗HP、经验时,无使用检查,扣到0为止。 # 3. 技能依赖开关、状态、地图、地形、装备、属性均检查至所有条件严格相符。 # 4. 技能依赖能力检查条件为能力在指定范围内,步数检查条件为指定步数以上。 # 5. 备注写法: # (写在描述里,不同条件可以叠加用分号隔开,备注和描述以#号分隔) # (当[XX集]内容只有一条时,方括号可省略,当内容序号连续时,可写成子界) # (条件太多写不下时,可用超长备注法,见依赖插件的说明) # a) 技能消耗HP:ch=值 # b) 技能消耗道具:ci=[消耗道具ID集] # 消耗道具个数>1的情况下,ID后缀两位小数为消耗个数,如4.05消耗4号道具5个 # 写成4和4.00是不一样的,前者消耗4号道具1个,后者要求持有4号道具但不消耗 # c) 技能消耗武器:cw=[消耗武器ID集],说明同道具,消耗的是持有的武器 # d) 技能消耗防具:ca=[消耗防具ID集],说明同道具,消耗的是持有的防具 # e) 技能消耗金钱:cg=值 # f) 技能消耗经验:cx=值 # g) 技能消耗变量:cv={变量ID=>消耗值},写成hash形式,不能省略花括号 # h) 技能消耗回合:cd=值 # i) 技能依赖开关:cs=[开关集],开关ID为正数要求ON,为负数要求OFF # j) 技能依赖状态:cc=[状态集],状态ID为正数要求有,为负数要求没有 # k) 技能依赖地图:cm=[地图ID集],地图ID为正数要求在,为负数要求不在 # l) 技能依赖地形:ct=[地形标志集],标志为正数要求是,为负数要求不是 # m) 技能依赖装备:cq=[装备ID集],查身上装备,武器ID写负数,防具ID写正数 # n) 技能依赖步数:cp=值 # o) 技能依赖属性:ce=[属性ID集],查装备属性,正数要求有,负数要求没有 # p) 技能依赖能力:cn=能力字符串,如"str300",有多个条件直接连写 # 能力可以用hp/sp/str/dex/agi/int,大小写不敏感 # 条件值的写法:300或300+表示大于等于300;300-表示小于等于300; # =300表示恰好300;300~400表示300到400之间(闭区间) # q) 技能依赖茂密:cb+(要求茂密处)或cb-(要求非茂密处) # r) 技能依赖公式:cf:公式脚本字符串,公式要能返回true或false的真伪值 # 公式中可以使用a代表技能使用者,v代表变量,s代表开关 #============================================================================== #============================================================================== # ■ SailCat's 插件公用 #============================================================================== module SailCat $sailcat_import ||= {} #-------------------------------------------------------------------------- # ● 植入与依赖检查 #-------------------------------------------------------------------------- if $sailcat_import[:DataNoteCore].to_f >= 2.0 $sailcat_import[:SkillCost] = 1.3 else raise "缺少依赖插件,通用数据库备注接口(v2.0以上版本)" end end module RPG #============================================================================ # ■ Skill_ItemCost #---------------------------------------------------------------------------- # 处理技能消耗道具、武器、防具的内部类 #============================================================================ class Skill_ItemCost #-------------------------------------------------------------------------- # ● 定义实例变量 #-------------------------------------------------------------------------- attr_accessor :id # 消耗的物品ID attr_accessor :number # 消耗的数目 #-------------------------------------------------------------------------- # ● 初期化 #-------------------------------------------------------------------------- def initialize(n) n = 0 unless n.is_a?(Numeric) n += 0.01 if n.is_a?(Fixnum) @id = Integer(n).abs @number = [Integer((n - @id) * 100.0 + 1e-6), 0].max end #-------------------------------------------------------------------------- # ● 检查符合性 #-------------------------------------------------------------------------- def match?(proc) return true if @id == 0 proc.call(@id) >= [@number, 1].max end end #============================================================================ # ■ Skill_EquipCheck #---------------------------------------------------------------------------- # 处理技能依赖装备状态的内部类 #============================================================================ class Skill_EquipCheck #-------------------------------------------------------------------------- # ● 定义实例变量 #-------------------------------------------------------------------------- attr_accessor :weapons # 依赖的武器ID(空为不检查) attr_accessor :armors1 # 依赖的盾牌ID(空为不检查) attr_accessor :armors2 # 依赖的头盔ID(空为不检查) attr_accessor :armors3 # 依赖的护甲ID(空为不检查) attr_accessor :armors4 # 依赖的饰品ID(空为不检查) #-------------------------------------------------------------------------- # ● 初期化 #-------------------------------------------------------------------------- def initialize(ary) @weapons = @armors1 = @armors2 = @armors3 = @armors4 = [] ary.map! {|i| i.to_a}.flatten! ary.each do |i| if i < 0 @weapon_id.push(-i) else kind = $data_armors[i].kind + 1 instance_eval("@armors#{kind}.push(#{i})") rescue nil end end end #-------------------------------------------------------------------------- # ● 检查符合性 #-------------------------------------------------------------------------- def match?(a) return false if !@weapons.empty? and !@weapons.include?(a.weapon_id) return false if !@armors1.empty? and !@armors1.include?(a.armor1_id) return false if !@armors2.empty? and !@armors2.include?(a.armor2_id) return false if !@armors3.empty? and !@armors3.include?(a.armor3_id) return false if !@armors4.empty? and !@armors4.include?(a.armor4_id) return true end end #============================================================================ # ■ Skill_AbilityCheck #---------------------------------------------------------------------------- # 处理技能依赖能力的内部类 #============================================================================ class Skill_AbilityCheck #-------------------------------------------------------------------------- # ● 常量 #-------------------------------------------------------------------------- REGEX = /(hp|sp|str|dex|agi|int)(=?([0-9]+)([+\-~])?([0-9]+)?)/i #-------------------------------------------------------------------------- # ● 定义实例变量 #-------------------------------------------------------------------------- attr_accessor :hp_range # 依赖的 HP % 范围 attr_accessor :sp_range # 依赖的 SP % 范围 attr_accessor :str_range # 依赖的力量值范围 attr_accessor :dex_range # 依赖的灵巧值范围 attr_accessor :agi_range # 依赖的速度值范围 attr_accessor :int_range # 依赖的魔力值范围 #-------------------------------------------------------------------------- # ● 初期化 #-------------------------------------------------------------------------- def initialize(str) @hp_range = @sp_range = 0..100 @str_range = @dex_range = @agi_range = @int_range = 0..999 ary = str.scan(REGEX) ary.each do |a| name = a[0].downcase min = a[2] max = a[4] || a[2] if a[1][0] != 61 max = (name[1] == 112 ? 100 : 999) if a[3] == nil or a[3] == "+" min = 0 if a[3] == "-" and a[4] == nil end instance_eval("@#{name}_range = #{min}..#{max}") rescue nil end end #-------------------------------------------------------------------------- # ● 检查符合性 #-------------------------------------------------------------------------- def match?(a) return false unless @hp_range === a.hp * 100 / a.maxhp return false unless @sp_range === a.sp * 100 / [a.maxsp, 1].max return false unless @str_range === a.str return false unless @dex_range === a.dex return false unless @agi_range === a.agi return false unless @int_range === a.int return true end end #============================================================================ # ■ RPG::Skill #---------------------------------------------------------------------------- # 数据库的技能类扩展 #============================================================================ class Skill #-------------------------------------------------------------------------- # ● 备注定义 #-------------------------------------------------------------------------- def hp_cost; _ch(0).abs; end def exp_cost; _cx(0).abs; end def gold_cost; _cg(0).abs; end def cooldown; _cd(0).abs; end def variable_cost; _cv({}); end def item_cost; _ci([]).to_a.map {|f| Skill_ItemCost.new(f)}; end def weapon_cost; _cw([]).to_a.map {|f| Skill_ItemCost.new(f)}; end def armor_cost; _ca([]).to_a.map {|f| Skill_ItemCost.new(f)}; end def switch_check; flat_array(_cs([])); end def state_check; flat_array(_cc([])); end def map_check; flat_array(_cm([])); end def terrain_check; flat_array(_ct([])); end def element_check; flat_array(_ce([])); end def bush_check; _cb(nil); end def step_check; _cp(0).abs; end def equip_check; Skill_EquipCheck.new(_cq([]).to_a); end def ability_check; Skill_AbilityCheck.new(_cn("").to_s); end def eval_check; _cf("true"); end #-------------------------------------------------------------------------- # ● 公式依赖判定 #-------------------------------------------------------------------------- def eval_match?(actor) result = lambda {|a, s, v| eval(eval_check) rescue true} result.call(actor, $game_switches, $game_variables) end #-------------------------------------------------------------------------- # ● 通用正负依赖判定 #-------------------------------------------------------------------------- def pn_match?(set, obj, proc = Proc.new{|a, b| a == b}) (set.reject {|s| (s > 0) == proc.call(obj, s.abs)}).empty? end #-------------------------------------------------------------------------- # ● 变量消耗判定 #-------------------------------------------------------------------------- def variable_match? variable_cost.each do |k, v| return false if $game_variables[k] < v end return true end #-------------------------------------------------------------------------- # ● 道具消耗判定 #-------------------------------------------------------------------------- def item_match?(set, proc) set.each do |s| return false unless s.match?(proc) end return true end end end #============================================================================== # ■ Game_Battler #============================================================================== class Game_Battler #-------------------------------------------------------------------------- # ● 使用技能的额外消耗 # skill : 特技 #-------------------------------------------------------------------------- def skill_cost_extra(skill) self.hp -= skill.hp_cost end end #============================================================================== # ■ Game_Actor #============================================================================== class Game_Actor #-------------------------------------------------------------------------- # ● 定义实例变量 #-------------------------------------------------------------------------- attr_reader :cooldowns # 冷却中的技能集 attr_reader :last_cooldowns # 剩余冷却值 #-------------------------------------------------------------------------- # ● 方法重定义 #-------------------------------------------------------------------------- unless method_defined? :sailcat_skill_can_use? alias sailcat_skillcost_skill_can_use? skill_can_use? end #-------------------------------------------------------------------------- # ● 可以使用特技判定 # skill_id : 特技 ID #-------------------------------------------------------------------------- def skill_can_use?(skill_id) # 获得对应的特技实体 skill = $data_skills[skill_id] # 装备不符的情况下,不能使用 if not skill.equip_check.match?(self) return false # 能力不符的情况下,不能使用 elsif not skill.ability_check.match?(self) return false # 步数不够的情况下,不能使用 elsif $game_party.steps < skill.step_check return false # 金钱不够的情况下,不能使用 elsif $game_party.gold < skill.gold_cost return false # 属性不符的情况下,不能使用 elsif not skill.pn_match?(skill.element_check, self, Proc.new{|a,b| a.element_set.include?(b) or ([a.armor1_id, a.armor2_id, a.armor3_id, a.armor4_id].inject(false) {|res, id| res |= id > 0 and $data_armors[id].guard_element_set.include?(b)}) }) return false # 地图不符的情况下,不能使用 elsif not skill.pn_match?(skill.map_check, $game_map.map_id) return false # 地形不符的情况下,不能使用 elsif not skill.pn_match?(skill.terrain_check, $game_player.terrain_tag) return false # 状态不符的情况下,不能使用 elsif not skill.pn_match?(skill.state_check, self, Proc.new{|a, b| a.state?(b)}) return false # 茂盛不符的情况下,不能使用 elsif skill.bush_check != nil and skill.bush_check != ($game_player.bush_depth == 12) return false # 开关不符的情况下,不能使用 elsif not skill.pn_match?(skill.switch_check, $game_switches, Proc.new{|a, b| a[b]}) return false # 战斗时,冷却中的情况下,不能使用 elsif $game_temp.in_battle and cooldown?(skill_id) and $game_variables[100]==0 return false # 变量不符的情况下,不能使用 elsif not skill.variable_match? return false # 道具不够的情况下,不能使用 elsif not skill.item_match?(skill.item_cost, Proc.new{|n| $game_party.item_number(n)}) return false # 武器不够的情况下,不能使用 elsif not skill.item_match?(skill.weapon_cost, Proc.new{|n| $game_party.weapon_number(n)}) return false # 防具不够的情况下,不能使用 elsif not skill.item_match?(skill.armor_cost, Proc.new{|n| $game_party.armor_number(n)}) return false # 公式计算为false或nil的情况下,不能使用 elsif not skill.eval_match?(self) return false end # 进行原始判定 sailcat_skillcost_skill_can_use?(skill_id) end #-------------------------------------------------------------------------- # ● 清除冷却技能 #-------------------------------------------------------------------------- def reset_cooldown @cooldowns = {} end #-------------------------------------------------------------------------- # ● 设置冷却技能 # skill_id : 特技 ID #-------------------------------------------------------------------------- def set_cooldown(skill_id) if $data_skills[skill_id].cooldown > 0 @cooldowns[skill_id] = $data_skills[skill_id].cooldown end end #-------------------------------------------------------------------------- # ● 更新冷却技能,该方法一回合调用一次 #-------------------------------------------------------------------------- def update_cooldown p "冷却更新" p @cooldowns p @cooldowns[0] @cooldowns.each_key {|k|@cooldowns[k] -= 1} @cooldowns.delete_if {|k, v| v == 0} end #-------------------------------------------------------------------------- # ● 冷却中判定 # skill_id : 特技 ID #-------------------------------------------------------------------------- def cooldown?(skill_id) @cooldowns.has_key?(skill_id) end #-------------------------------------------------------------------------- # ● 使用技能的额外消耗 # skill : 特技 ID #-------------------------------------------------------------------------- def skill_cost_extra(skill) super self.exp -= skill.exp_cost $game_party.lose_gold(skill.gold_cost) skill.item_cost.each {|i| $game_party.lose_item(i.id, i.number)} skill.weapon_cost.each {|i| $game_party.lose_weapon(i.id, i.number)} skill.armor_cost.each {|i| $game_party.lose_armor(i.id, i.number)} skill.variable_cost.each_pair {|k, v| $game_variables[k] -= v} set_cooldown(skill.id) if $game_temp.in_battle end end #============================================================================== # ■ Game_Party #============================================================================== class Game_Party #-------------------------------------------------------------------------- # ● 清除冷却技能 #-------------------------------------------------------------------------- def reset_cooldown actors.each {|a| a.reset_cooldown} end #-------------------------------------------------------------------------- # ● 更新冷却技能,该方法一回合调用一次 #-------------------------------------------------------------------------- def update_cooldown p "总角色更新" actors.each {|a| a.update_cooldown} end end #============================================================================== # ■ Scene_Battle #============================================================================== class Scene_Battle #-------------------------------------------------------------------------- # ● 方法重定义 #-------------------------------------------------------------------------- unless method_defined? :sailcat_start_phase1 alias sailcat_skillcost_start_phase1 start_phase1 alias sailcat_skillcost_start_phase4 start_phase4 alias sailcat_skillcost_make_skill_action_result make_skill_action_result end #-------------------------------------------------------------------------- # ● 开始自由战斗回合 #-------------------------------------------------------------------------- def start_phase1 # 调用原方法 sailcat_skillcost_start_phase1 # 清除技能冷却 $game_party.reset_cooldown end #-------------------------------------------------------------------------- # ● 开始主回合 #-------------------------------------------------------------------------- def start_phase4 # 调用原方法 sailcat_skillcost_start_phase4 # 更新技能冷却 p "主回合更新" $game_party.update_cooldown end #-------------------------------------------------------------------------- # ● 生成特技行动结果 #-------------------------------------------------------------------------- def make_skill_action_result # 调用原方法 sailcat_skillcost_make_skill_action_result # 额外消耗 @active_battler.skill_cost_extra(@skill) end end #============================================================================== # ■ Scene_Skill #============================================================================== class Scene_Skill #-------------------------------------------------------------------------- # ● 刷新画面 (特技窗口被激活的情况下) #-------------------------------------------------------------------------- def update_skill # 按下 B 键的情况下 if Input.trigger?(Input::B) # 演奏取消 SE $game_system.se_play($data_system.cancel_se) # 切换到菜单画面 $scene = Scene_Menu.new(1) return end # 按下 C 键的情况下 if Input.trigger?(Input::C) # 获取特技窗口现在选择的特技的数据 @skill = @skill_window.skill # 不能使用的情况下 if @skill == nil or not @actor.skill_can_use?(@skill.id) # 演奏冻结 SE $game_system.se_play($data_system.buzzer_se) return end # 演奏确定 SE $game_system.se_play($data_system.decision_se) # 效果范围是我方的情况下 if @skill.scope >= 3 # 激活目标窗口 @skill_window.active = false @target_window.x = (@skill_window.index + 1) % 2 * 304 @target_window.visible = true @target_window.active = true # 设置效果范围 (单体/全体) 的对应光标位置 if @skill.scope == 4 || @skill.scope == 6 @target_window.index = -1 elsif @skill.scope == 7 @target_window.index = @actor_index - 10 else @target_window.index = 0 end # 效果在我方以外的情况下 else # 公共事件 ID 有效的情况下 if @skill.common_event_id > 0 # 预约调用公共事件 $game_temp.common_event_id = @skill.common_event_id # 演奏特技使用时的 SE $game_system.se_play(@skill.menu_se) # 消耗 SP @actor.sp -= @skill.sp_cost # 额外的消耗 @actor.skill_cost_extra(@skill) # 再生成各窗口的内容 @status_window.refresh @skill_window.refresh @target_window.refresh # 切换到地图画面 $scene = Scene_Map.new return end end return end # 按下 R 键的情况下 if Input.trigger?(Input::R) # 演奏光标 SE $game_system.se_play($data_system.cursor_se) # 移至下一位角色 @actor_index += 1 @actor_index %= $game_party.actors.size # 切换到别的特技画面 $scene = Scene_Skill.new(@actor_index) return end # 按下 L 键的情况下 if Input.trigger?(Input::L) # 演奏光标 SE $game_system.se_play($data_system.cursor_se) # 移至上一位角色 @actor_index += $game_party.actors.size - 1 @actor_index %= $game_party.actors.size # 切换到别的特技画面 $scene = Scene_Skill.new(@actor_index) return end end #-------------------------------------------------------------------------- # ● 刷新画面 (目标窗口被激活的情况下) #-------------------------------------------------------------------------- def update_target # 按下 B 键的情况下 if Input.trigger?(Input::B) # 演奏取消 SE $game_system.se_play($data_system.cancel_se) # 删除目标窗口 @skill_window.active = true @target_window.visible = false @target_window.active = false return end # 按下 C 键的情况下 if Input.trigger?(Input::C) # 因为 SP 不足而无法使用的情况下 unless @actor.skill_can_use?(@skill.id) # 演奏冻结 SE $game_system.se_play($data_system.buzzer_se) return end # 目标是全体的情况下 if @target_window.index == -1 # 对同伴全体应用特技使用效果 used = false for i in $game_party.actors used |= i.skill_effect(@actor, @skill) end end # 目标是使用者的情况下 if @target_window.index <= -2 # 对目标角色应用特技的使用效果 target = $game_party.actors[@target_window.index + 10] used = target.skill_effect(@actor, @skill) end # 目标是单体的情况下 if @target_window.index >= 0 # 对目标角色应用特技的使用效果 target = $game_party.actors[@target_window.index] used = target.skill_effect(@actor, @skill) end # 使用特技的情况下 if used # 演奏特技使用时的 SE $game_system.se_play(@skill.menu_se) # 消耗 SP @actor.sp -= @skill.sp_cost # 额外的消耗 @actor.skill_cost_extra(@skill) # 再生成各窗口内容 @status_window.refresh @skill_window.refresh @target_window.refresh # 全灭的情况下 if $game_party.all_dead? # 切换到游戏结束画面 $scene = Scene_Gameover.new return end # 公共事件 ID 有效的情况下 if @skill.common_event_id > 0 # 预约调用公共事件 $game_temp.common_event_id = @skill.common_event_id # 切换到地图画面 $scene = Scene_Map.new return end end # 无法使用特技的情况下 unless used # 演奏冻结 SE $game_system.se_play($data_system.buzzer_se) end return end end end
202.58 KB, 下载次数: 82
QQ图片20180522095424.png (82.73 KB, 下载次数: 16)
soulsaga 发表于 2019-5-1 17:05
Window_Skill *里面
def update_help
@help_window.set_text2(skill,@actor)#★★★★★
欢迎光临 Project1 (https://rpg.blue/) | Powered by Discuz! X3.1 |