| 赞 | 0 |
| VIP | |
| 好人卡 | |
| 积分 | 1 |
| 经验 | |
| 最后登录 | 2020-6-2 |
| 在线时间 | 132 小时 |
- 梦石
- 0
- 星屑
- 80
- 在线时间
- 132 小时
- 注册时间
- 2014-5-7
- 回帖
- 143
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有账号?注册会员
×
本帖最后由 Silentever 于 2015-10-30 14:28 编辑
2015-10-28 最终更新
2015-10-09 更新:修复BUG,写法优化,追加无视行动限制的自发技能,追加简化定义
删除:自发技能使用成功分歧判定(感觉没什么用处)
2015-09-19 追加功能:追加last_act定义,追加自发技能使用成功分歧判定
2015-09-12 追加功能:支持让敌人也使用自发技能,追加地图自发技能,追加目标对象的选择机制
此脚本的功能是让战斗成员在通常行动以外可以追加额外行动,做出了可以根据特定条件发动的自动技能。灵感是来自世界树迷宫跟第七龙神这一类的RPG游戏,像是在战斗开始的时候一定几率发动的全体攻击,或战斗结束时恢复一定程度的HP之类的技能让人印象深刻。不过这东西的潜力远比原本预期的功能要高,能用来做什么还得看使用者的想象力了。
基础说明:
需要在脚本内相应的时机中填入“Ask[ID] = {各种参数}”。战斗过程中会判断填入的技能是否有成功发动,并且执行。
举个例子来说,如果填入“Ask[3] = { '时机'=>'战斗开始', '几率'=>'50', '条件'=>'state?(2)' }”,会在战斗开始,玩家输入前让所有学会了3号技能、持有2号状态、通过50%随机判定的成员执行该技能。默认数据库中3号是连续攻击,2号状态是剧毒,会变成中毒的成员有50%的几率使用连续攻击。
概念就是这种用几率跟条件去判断是否执行的技能。具体请看脚本内的详细说明。
【新手向】条件设置的写法基本上可以参考这里的内容,个人认为容易理解并实用:http://rpg.blue/thread-307316-1-1.html
与上面不同的地方是无法指定一个对象(B),并且指定使用者的时候不需要在前面加任何东西:写“atk”的时候会直接获取使用者的攻击力(不过防御力则需要加上“self.”)。
另外,可以联动我的另一个脚本“技能开关”,被关闭的技能不会发动:https://rpg.blue/thread-383392-1-1.html
[fold=代码]- #==============================================================================
- #
- # 自发技能 by Silentever(夜光云)
- # (自动发动技能)
- #
- # 2015-10-28 更新:修复BUG,最终版
- # 2015-10-09 更新:修复BUG,写法优化,追加无视行动限制的自发技能,追加简化定义
- # 删除:自发技能使用成功分歧判定
- # 2015-09-19 更新:追加:last_act定义,自发技能使用成功分歧判定
- # 2015-09-12 更新:修复BUG,支持让敌人也使用自发技能,追加地图自发技能,追加对象选择机制
- # 2015-08-17 发布
- #
- #==============================================================================
- # ▼ 设定
- # 填入【 Ask[ID] = { '参数名' => '算法' (用','分开) } 】
- #
- # ID.......技能ID。对指定的技能无任何要求(可以发动任何技能)。
- #
- # 参数列表:
- # 几率...发动几率(0~100),不填写时为默认100。
- # 只要是返回数字,可以用变量计算;超出范围不会出错请安心。
- # 条件...发动先置条件(返回true/false),不填写时为默认true(无先置条件)。
- # 时机...限定发动的时机,详细在下面1。
- # 范围...设置方法请看下面2。
- # 强制...设定为true的场合,技能将会无视此脚本设置的条件与学会条件以外的,
- # 任何技能的常规发动条件(MP不足,行动不能等)。
- #
- # 例子:
- # Ask[1] = {} => 使用1号技能(没有任何参数用空'{}')
- # Ask[2] = { '几率' => '50' } => 50%几率使用2号技能
- # Ask[3] = { '条件' => 'luk > 50' } => 幸运高于50(不包括等于)使用3号技能
- # Ask[4] = { '条件' => 'state?(2)',
- # '几率' => '100 - @state_turns[2] * 10'}
- # => 持有2号状态的情况下,以(100-2号状态剩余回合数*10)的几率发动
- #
- # 填写时请把所有的参数跟其内容用 '' 或 "" 号包封。
- # 【注意】使用自发技能的第一个先置条件是学会(不论升级或特性添加),
- # 有必要让想让使用该技能的角色学会;另外敌人必须使用特性添加技能才能使用
- # 技能的使用会受到基础使用条件的限制(MP不足,使用场合不符,角色无法行动等)。
- #
- # 补充:
- # 1) 重复添加相同的ID技能,【没办法】重复使用,写在后面的内容会覆盖先前的内容。
- # 2) 同一个时机中有复数自发技能行动角色时,会根据行动速度进行排列。
- # 3) 只能在战斗中使用,关于地图技能请看下面。
- # 4) 填写时注意使用全部半角的标点符号。
- #
- #
- # ■【时机】(2015-10-09 更新中自发技能从发动时机分离)
- # 在参数中加入【 '时机' => '战斗开始, 战斗结束' 】
- # 可以把自发技能的使用锁定在后面填入的时机中。以上例子是把时机限定在了战斗开始跟结束。
- # 因为不填写时会每个时机都使用一次,因此【强烈】建议填写。
- #
- # 时机与以往不变:
- # 战斗开始,战斗结束 => 敌人出现时,胜利或逃跑后
- # 回合开始,回合结束 => 全部选择好行动后,回合正式开始的时候,以及回合结束
- # 行动前,行动后 => 自己进行主要行动(使用技能/道具)的前后
- # 受伤前,受伤后 => 自己成为技能/道具的对象,效果处理前/后
- # 直接把以上部分直接输入,用 , 分开。
- #
- #
- # ■【范围】
- # 因为这部分比较复杂,慎入。注意在最后全部都用 '' 或 "" 号包封。
- # 不填写时,会自动选择对象(遵守原使用范围)。
- # 设置对象群体时,将会无视技能本身的使用范围。
- #
- # 设置时,可以放3部分,用“,”互相分开。其中1号是必须放在最前,其余可以随意排序。
- # 1) 范围的对象群体。用“+”追加,“-”排除。此外必须在每个运算符号前后留个空格。
- # self是使用者自己。last是最后一个对象。重复加入会复数处理效果。
- # 最后一个对象指最后一次输入指令时选择的对象索引(每个角色独立)。
- # 2) 定成“max或min : 比较数值 : 采取数量”,不填写数量时当作1处理。
- # 会从范围中选择该数量的,持有最高/最低指定数值的单位。
- # 3) 用代码进行计算返回true/false,从范围选择所有符合条件的单位。
- # 计算代码可以使用跟伤害公式一样的变量:a=使用者,b=单独对象,v=游戏变量。
- # 不存在可选对象时,技能不发动。
- #
- # 例子:
- # Ask[5] = { '范围' => 'self + last' }
- # => 将目标对象锁定成自身与自身的最后对象
- # Ask[6] = { '范围' => 'party - self, max:hp:2' }
- # => 在玩家队伍成员中,除使用者以外,选择HP最高的2个角色
- # Ask[7] = { '范围' => 'troop, b.state?(10)' }
- # => 从敌群中选择所有持有10号状态的成员
- # Ask[8] = { '范围' => 'allies, b.state?(1), max:mhp' }
- # => 从持有1号状态的同伴中选择HP上限最高的1个成员(敌人使用会选择敌人)
- # Ask[9] = { '范围' => 'party + self, min:hp:3, b.hp > 0' }
- # => 从HP高于0的玩家队伍以及自身中选取3个HP最低的成员。
- # 注意角色使用的场合会把自身计算2此,因此会占有2个对象,并受到2次技能效果。
- #
- #
- # ■【仅限伤害处理】
- # 仅在伤害处理可以使用user与item。
- # User...攻击使用者的单位(敌人)。在对象组中填入“user”可以指定该单位做对象。
- # Item...攻击单位所使用的技能。
- # 此外,受到伤害之后还能调用“dmg(:hp)”等变量获得伤害量,
- #
- # 例子2:
- # Ask[10] = { '时机' => '受伤前',
- # '范围' => 'user' }
- # => 对攻击单位使用技能10号反击。
- # Ask[11] = { '时机' => '受伤后',
- # '条件' => 'dmg(:hp) >= 20' }
- # => 受到20HP以上的伤害时发动(限伤害后)。
- #
- # 其他方法(限定在受伤后使用):
- # dmg( ) => 获取伤害量,括号中填入种类“:hp”,“:mp”或“:tp”
- # drn( ) => 获取吸收量,括号中填入“:hp”或“:mp”
- # missed? => 是否击中(输出true/false)
- # evaded? => 是否被回避(输出true/false)
- # critical? => 是否暴击成功(输出true/false)
- #
- #
- # ■【追加定义:party/troop/allies/oppons】
- # 为了方便输入简化了队伍与敌群的变量名。
- #
- # party => 获取玩家队伍(数组)
- # party(1) => 获取队伍中首位的角色(角色)
- # troop => 获取全体敌群(数组)
- # troop(1) => 获取1号敌人(敌人)
- #
- # allies => 获取使用者的同伴,角色的场合玩家队伍,敌人的场合敌群
- # allies(1) => 获取同伴1号
- # oppons => 获取使用者的对手,角色的场合敌群,敌人的场合玩家队伍
- # oppons(1) => 获取对手1号
- #
- #
- # ■【追加定义:last_act】
- # 获取玩家输入的行动指令,玩家在游戏中输入攻击行动,可以通过此方法获取。
- # 注意获取的是行动而不是技能(道具的使用也是行动)。
- # 只有重新输入行动后才会更新,因此会保留到下次战斗。
- # 因为这个行动不会被执行所以没有修改的意义。
- # 具体参考Game_Action。
- #
- # 方法预览:
- # last_act.attack? => 是否普通攻击(true/false)
- # last_act.guard? => 是否防御(true/false)
- #
- # last_act.skill? => 是否技能(true/false)
- # last_act.skill?(id) => 是否为id号技能(true/false)
- #
- # last_act.item? => 是否道具(true/false)
- # last_act.item?(id) => 是否为id号道具(true/false)
- #
- # last_act.valid? => 判断角色是否可以执行该行动(true/false)
- # last_act.item => 获取行动的技能或使用道具(对象物品)
- #
- #------------------------------------------------------------------------------
- #
- # ▼ 地图发动的自发技能
- # 使用【 Msk[ID] = { '参数名' => '算法' (用','分开) } 】
- # 注意参数与战斗用的设置不一定相同。
- #
- # 频率...发动频率,玩家每行走此数值的步数使用1次。不填入不会发动。
- # 默认系统中20步会算作1回合(参考用)。
- # 条件...同战斗设置。
- # 范围...同战斗设置。注意在地图上不存在$game_troop。
- # 显示...是否显示使用消息,填入true会弹出对话框,否则无任何提示。
- #
- #==============================================================================
- module AutoSkill; Ask, Msk = {}, {}
- #==============================================================================
- # ● 请在这里填写技能设置;没有填写限制。
- #==============================================================================
- #------------------------------------------------------------------------------
- end # Do not remove
- #==============================================================================
- # ▼ 脚本内容:不可编辑
- #==============================================================================
- class Game_Battler < Game_BattlerBase
- #--------------------------------------------------------------------------
- include AutoSkill
- Ask.each_value {|s| s.default = ''}
- Msk.each_value {|s| s.default = ''}
-
- # NewMethods: 追加简易定义
- def party(n = nil)
- return $game_party.members unless n
- return $game_party.members[n] end
- def troop(n = nil)
- return $game_troop.members unless n
- return $game_troop.members[n] end
- def allies(n = nil)
- return party(n) if actor?
- return troop(n) if enemy?; end
- def oppons(n = nil)
- return party(n) if enemy?
- return troop(n) if actor?; end
-
- def dmg(type = :hp); eval "@result_log.#{type.to_s}_damage" end
- def drn(type = :hp); eval "@result_log.#{type.to_s}_drain" end
- def missed?; @result_log.missed end
- def evaded?; @result_log.evaded end
- def critical?; @result_log.critical end
-
- def user; @attack_user end
- def item; @attack_item end
- def last
- return allies(last_act.target_index) if last_act.item.for_friend?
- return oppons(last_act.target_index) if last_act.item.for_opponent?
- end
-
- # NewMethod: 最后一个主要行动
- def last_act; @last_act; end
- def set_last_action
- @last_act = current_action if !current_action.is_a? Game_AutoAction
- end
- # AliasMethod: 记录战斗结果
- attr_reader :result_log
- def set_result_log
- @result_log = @result.clone end
- # AliasMethod: 初始化
- alias :initialize_ask :initialize
- def initialize; initialize_ask
- @last_act = Game_Action.new(self)
- @result_log = Game_ActionResult.new(self) end
-
- # NewMethod: 自发技能处理
- def proc_auto_skill(timing = nil, user = nil, item = nil)
- return unless SceneManager.scene_is?(Scene_Battle)
- @attack_user, @attack_item = user, item
- Ask.each {|i, v| skill = $data_skills[i]
- next unless skills.include?(skill)
- set_auto_skill(i, v, timing)}
- end
-
- # NewMethod: 自发技能设置
- def set_auto_skill(i, v, t)
- return unless v['时机'].empty? or v['时机'].split(',').map{|s|s.strip}.include?(t)
- return unless v['几率'].empty? or eval(v['几率']).to_i > rand(100)
- return unless v['条件'].empty? or eval(v['条件'])
- action = Game_AutoAction.new(self, eval(v['强制']), i)
- unless make_auto_targets(action, v['范围']).empty?
- @actions.insert(0, action)
- BattleManager.autoskill_users.push(self)
- end end
-
- # NewMethod: 设置行动对象
- def make_auto_targets(action, scope)
- if !scope.empty?; scope = scope.split(',')
- unit = []; scope.shift.split(' ').each_with_index{|s, i|
- @oper = '+' unless @oper; if i % 2 == 1; @oper = s; next end
- unit.push(eval(s)) if @oper['+']
- unit.reject!{|bat| [eval(s)].flatten.include?(bat)} if @oper['-']
- unit.flatten!}; remove_instance_variable :@oper
- if requir = scope.reject{|s| s[/max|min/]}[0]; unit.select!{|member|
- a, b, v = self, member, $game_variables; eval requir}; end
- if prior = scope.find{|s| s[/max|min/]}; prior = prior.split(':').map{|s|s.strip}
- unit = unit.sort_by(&prior[1].to_sym); n = eval(prior[2]) rescue n = 1
- unit = unit.first(n) if prior[0]['min']
- unit = unit.last(n) if prior[0]['max']
- end end
- return action.auto_targets = unit if unit
- return action.auto_targets = [:rand]
- end
-
- # NewMethod: 地图技能
- def proc_map_skill
- return unless SceneManager.scene_is?(Scene_Map)
- Msk.each {|i, v| skill = $data_skills[i]
- h = {}; v.each {|i, v| h[i] = v.split(',').map{|s| s.strip}}
- next unless skills.include?(skill)
- next unless usable?(skill)
- next unless h['步数'].empty? or $game_party.steps % eval(h['步数']) == 0
- next unless h['条件'].empty? or eval(h['条件'])
- pay_skill_cost(skill)
- item.effects.each {|effect| item_global_effect_apply(effect)} if
- eval(h['消息'])
- make_auto_targets(action, h['范围']).each {|target|
- skill.repeats.times {target.item_apply(self, skill)}}}
- end
- #--------------------------------------------------------------------------
- end
- #==============================================================================
- class Game_Actor < Game_Battler
- #--------------------------------------------------------------------------
- # AliasMethod: 地图画面上回合结束的处理
- alias :turn_end_on_map_ask :turn_end_on_map
- def turn_end_on_map; turn_end_on_map_ask
- proc_map_skill end
- #--------------------------------------------------------------------------
- end
- #==============================================================================
- class Game_Enemy < Game_Battler
- #--------------------------------------------------------------------------
- # NewMethod: 获取技能实例的数组
- def skills
- added_skills.sort.collect {|id| $data_skills[id] }
- end
- #--------------------------------------------------------------------------
- end
- #==============================================================================
- class Game_Action
- #--------------------------------------------------------------------------
- # 判断用定义
- def guard?; item == $data_skills[subject.guard_skill_id] end
- def skill?(id = 0)
- return item == $data_skills[id] if id > 0
- return item.is_a?(RPG::Skill) end
- def item?(id = 0)
- return item == $data_items[id] if id > 0
- return item.is_a?(RPG::Item) end
- #--------------------------------------------------------------------------
- end
- #==============================================================================
- class Game_AutoAction < Game_Action
- #--------------------------------------------------------------------------
- attr_accessor :auto_action
- attr_accessor :auto_targets
-
- # 初始化对象
- def initialize(subject, forcing, skill_id)
- super(subject, forcing)
- set_skill(skill_id) end
-
- # 清除
- def clear; super
- @auto_action = false
- @auto_targets = [] end
- # 生成目标数组
- def make_targets
- return super if @auto_targets.include?(:rand)
- return @auto_targets end
-
- # 目标为队友
- def targets_for_friends
- @target_index = rand(subject.friends_unit.members.size) if
- @auto_targets.include?(:rand)
- super end
- #--------------------------------------------------------------------------
- end
- #==============================================================================
- class Scene_Battle < Scene_Base
- #--------------------------------------------------------------------------
- # AliasMethod: 更新画面
- alias :update_ask :update
- def update; update_ask
- BattleManager.terminate unless process_autoskill
- end
-
- # AliasMethod: 开始队伍指令的选择
- alias :start_party_command_selection_ask :start_party_command_selection
- def start_party_command_selection
- return if BattleManager.judge_win_loss
- start_party_command_selection_ask
- end
-
- # AliasMethod: 回合开始
- alias :turn_start_ask :turn_start
- def turn_start; turn_start_ask
- all_battle_members.each {|battler| battler.set_last_action}
- check_auto_skills(all_battle_members, '回合开始')
- end
-
- # AliasMethod: 回合结束
- alias :turn_end_ask :turn_end
- def turn_end
- check_auto_skills(all_battle_members, '回合结束')
- turn_end_ask end
-
- # OverWrite: 处理战斗行动
- def process_action
- return if scene_changing?
- if !@subject || !@subject.current_action
- @subject = BattleManager.next_subject end
- return turn_end unless @subject
- return unless @subject
- check_auto_skills([@subject], '行动前')
- process_action_b
- process_action_end unless @subject.current_action
- check_auto_skills([@subject], '行动后')
- end
-
- # NewMethod: 处理战斗行动
- def process_action_b
- if @subject.current_action
- @subject.current_action.prepare
- if @subject.current_action.valid?
- @status_window.open
- execute_action
- end
- @subject.remove_current_action
- end
- end
-
- # NewMethod: 处理自动技能
- def process_autoskill
- return false if BattleManager.autoskill_users.empty?
- @log_window.wait
- last_subject = @subject if @subject
- @subject = BattleManager.autoskill_users.shift
- @using_auto_skill = true
- process_action_b
- @subject = last_subject if last_subject
- @using_auto_skill = false
- return true
- end
-
- # AliasMethod: 使用技能/物品
- alias :use_item_ask :use_item
- def use_item
- if @using_auto_skill
- use_item_ask
- else; use_item_no_autoskill end
- end
-
- # NewMethod: 使用非自发技能/物品
- def use_item_no_autoskill
- item = @subject.current_action.item
- @log_window.display_use_item(@subject, item)
- @subject.use_item(item)
- refresh_status
- targets = @subject.current_action.make_targets.compact
- show_animation(targets, item.animation_id)
- check_auto_skills(targets, '受伤前', @subject, item)
- targets.each {|target| item.repeats.times { invoke_item(target, item) } }
- check_auto_skills(targets, '受伤后', @subject, item)
- end
-
- # AliasMethod: 应用技能/物品效果
- alias :apply_item_effects_ask :apply_item_effects
- def apply_item_effects(target, item)
- apply_item_effects_ask(target, item)
- target.set_result_log
- end
-
- # NewMethod: 使用自发技能
- def check_auto_skills(subjects = [], *args)
- subjects.each {|subject| subject.proc_auto_skill(*args) if subject}
- while process_autoskill
- end end
- #--------------------------------------------------------------------------
- end
- #==============================================================================
- module BattleManager
- #--------------------------------------------------------------------------
- class << self
- alias :battle_start_ask :battle_start
- alias :on_encounter_ask :on_encounter; end
-
- # AliasMethod: 战斗开始
- def self.battle_start
- @battle_result = nil
- battle_start_ask
- SceneManager.scene.check_auto_skills($game_party.members+$game_troop.members, '战斗开始')
- on_encounter_ask
- if @preemptive
- $game_message.add(sprintf(Vocab::Preemptive, $game_party.name))
- elsif @surprise
- $game_message.add(sprintf(Vocab::Surprise, $game_party.name))
- end
- wait_for_message
- end
-
- # AliasMethod: 遇敌时的处理
- def self.on_encounter; end
-
- # OverWrite: 胜利时的处理
- def self.process_victory
- play_battle_end_me
- replay_bgm_and_bgs
- $game_message.add(sprintf(Vocab::Victory, $game_party.name))
- display_exp
- gain_gold
- gain_drop_items
- gain_exp
- battle_end(0)
- return true
- end
-
- # OverWrite: 中止时的处理
- def self.process_abort
- replay_bgm_and_bgs
- battle_end(1)
- return true
- end
-
- # OverWrite: 全灭时的处理
- def self.process_defeat
- $game_message.add(sprintf(Vocab::Defeat, $game_party.name))
- wait_for_message
- replay_bgm_and_bgs if @can_lose
- battle_end(2)
- return true
- end
-
- # OverWrite: 战斗结束 > 结果(0:胜利 1:撤退 2:全灭)
- def self.battle_end(result)
- @phase = nil
- @battle_result = result
- $game_party.on_battle_end
- $game_troop.on_battle_end
- SceneManager.scene.check_auto_skills($game_party.members, '战斗结束')
- end
-
- # NewMethod: 退出管理器
- def self.terminate
- return unless @battle_result
- revive_battle_members if @battle_result == 2 && @can_lose
- @event_proc.call(@battle_result) if @event_proc
- SceneManager.return
- SceneManager.goto(Scene_Gameover) if @battle_result == 2 && !@can_lose
- SceneManager.exit if $BTEST
- end
-
- # NewMethod: 自发技能行动列表
- def self.autoskill_users
- @autoskill_users ||= []
- @autoskill_users.each {|battler| battler.make_speed }
- @autoskill_users.sort! {|a,b| b.speed - a.speed }
- return @autoskill_users
- end
- #--------------------------------------------------------------------------
- end
- #==============================================================================
- # ▼ END
- #==============================================================================
复制代码 [/fold]
脚本应用:
在这里让我向大家展示一种并不包括在原本构思的用法:设置拥有每次行动前,25%几率无法行动的麻痹状态。不知道有没有人玩口袋,因为默认系统无法制作这样的状态略有些遗憾,果然还是觉得“麻痹就应该是这个样子的”。
方法是设置2个麻痹状态A、B与1个麻痹专用技能。先获得本身没有效果的麻痹A,但带有添加“麻痹技能”的特性。麻痹技能则是行动前有25的几率发动,会对使用者自己附加麻痹B状态。麻痹B就是无法行动的状态,设置效果1回合。这样在麻痹A持续的期间,每次行动前会有25%的几率无法行动(不包括自发技能的行动)。
[fold=麻痹状态]
麻痹状态
麻痹状态B(幽灵状态)
麻痹技能(幽灵技能)
[/fold]
麻痹麻痹的好像一直在说脏话……
像一开始说的一样,应用方法超出了预期的功能也让我吃了一惊!以上只是提供一个思路,说不定还有很多不同类型的用法。
另外想要关闭技能,可以让装备附加自发技能来达到这样的效果。
兼容性问题:
兼容性问题就请自力,脚本里面都标注了哪些内容是覆盖式的写法(搜索OverWright)
这次大概会是最后一次更新……大概。有bug请留言或通知我。 |
评分
-
查看全部评分
|