设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 12972|回复: 26
打印 上一主题 下一主题

[原创发布] 默认战斗中调用公共事件

[复制链接]

Lv5.捕梦者 (版主)

梦石
1
星屑
23999
在线时间
3339 小时
注册时间
2011-7-8
帖子
3926

开拓者

跳转到指定楼层
1
发表于 2017-3-7 21:33:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 guoxiaomi 于 2017-3-12 21:38 编辑

范例在 2 楼

仅对默认战斗有效。但是思路是可以拓展到其他的战斗里。我以为 1 个小时就能写完的……结果搞了快 3 个小时。。。

1 楼是行动前后调用公共事件

战斗前后调用在 7 楼

回合开始时调用公共事件在 8 楼


至此,给出了 5 个常见的需要调用公共事件的 “时间点”,可以对默认战斗进行方便又强力的改动。

修改在 Scene_Battle 4 的 71 行的 update_phase4 方法:

RUBY 代码复制
  1. class Scene_Battle  
  2.   attr_reader :active_battler
  3.   attr_reader :target_battlers
  4.   #--------------------------------------------------------------------------
  5.   # ● 刷新画面 (主回合)
  6.   #--------------------------------------------------------------------------
  7.   def update_phase4   
  8.     case @phase4_step
  9.     when 1      
  10.       update_phase4_step1
  11.       if @phase4_step == 2 && @active_battler.exist?
  12.         # 显示连续伤害时 执行 1 号公共事件
  13.         $game_system.battle_interpreter.setup($data_common_events[1].list, 0)
  14.       end
  15.     when 2
  16.       update_phase4_step2
  17.     when 3
  18.       update_phase4_step3
  19.     when 4
  20.       update_phase4_step4
  21.     when 5
  22.       update_phase4_step5
  23.       # 显示伤害数字时 执行 2 号公共事件
  24.       $game_system.battle_interpreter.setup($data_common_events[2].list, 0)
  25.     when 6
  26.       update_phase4_step6
  27.     end   
  28.   end  
  29. end


1. 选取的 2 个时机,都是显示伤害数字的时候,这样的话就可以顺利播放动画
2. 要保留原来显示的伤害数字,得在公共事件里添加等待命令让原来的伤害数字先显示完毕,再显示新的伤害数字(比如“伤害处理”)。否则新的伤害数字会立即覆盖掉正在显示的伤害数字。要判断是否有伤害数字待显示,用 battler.damage_pop
3. 第 1 处的公共事件,在角色行动前。
    3.1 参见Scene_Battle 4 的 make_action_orders 中把所有的单位都加入了行动列表,所以每个行动者都会正常执行 phase4_step1 并进入 phase4_step2。
    3.2 由于添加了 @active_battler.exist? 的判断,行动者被隐藏,或者死亡,第 1 处的公共事件就不会发动。不存在的此行动者在 phase4_step2 一开始就会立即结束自己的回合。
    3.3 @hidden属性 = true 的角色被隐藏(比如中途出现的敌人),但是也会执行 phase4_step1 ,所以同样会受到“持续伤害”和“状态移除”的效果。
4. 第 2 处的公共事件,在角色行动后。再然后才是物品、技能的公共事件,在 phase4_step6 结束后执行
5. 使用 $scene.active_battler 和 $scene.target_battlers 获取行动者和目标对象数组,但是注意第 1 处是没有 $scene.target_battlers 的。
6. 尚不清楚与战斗事件各条件的先后顺序,待测试。适当设置事件触发条件应该无冲突都能触发。



需要播放动画、等待、显示文字的时候,公共事件比Ruby代码好使。在这里添加一些判断也可以制造特殊的战斗效果。

第 1 处行动前的公共事件的可能用途比较容易想到,比如角色每次行动时会回复HP/SP。此外,由于这里尚未执行行动,可以修改 @active_battler.current_action 使得接下来的行动方式、目标发生改变。

第 2 处行动后的公共事件,看上去似乎可以用物品、技能的公共事件代替。实际上并不是这样。这里举 2 个例子:
1. 在第 2 处行动后的公共事件的最前面添加事件脚本,可以消除原来的伤害数字,假设消除的是第一个目标身上的伤害数字:
RUBY 代码复制
  1. @battler = $scene.target_battlers[0]
  2. @battler.damage_pop = false
  3. # 猜猜这行注释干什么用?
然后紧接着一个脚本:
RUBY 代码复制
  1. @battler.damage = '无可奉告'
  2. @battler.damage_pop = true
用来表示 BOSS 的深不可测
2. 不仅可以消除伤害数字,在第 2 处可以任意修改技能、物品的后续效果,比如:
RUBY 代码复制
  1. $scene.target_battlers.each do |battler|
  2. if battler.hp == 0 && battler.state?(10)
  3.   battler.hp = 1
  4. end
  5. end
这样就能使附加上 10 号状态的角色 hp 至少为 1,制造出“薄葬”的效果。
如果在物品、技能附带公共事件里添加这段代码,是没有“薄葬”效果的。原因是在 phase4_step5 结束后,尚未进入 phase4_step6 执行物品、技能公共事件就已经结算了hp = 0的死亡效果。
同样,在这里也可以轻易的给出击杀者,或者制造魔法盾等等丰富多彩的技能


关于这些想法,最初是从 sailcat 的脚本里得到启发。原帖见这里:https://rpg.blue/forum.php?mod=viewthread&tid=31747

评分

参与人数 7星屑 +918 梦石 +2 +1 收起 理由
adssdass00 + 1 塞糖
jenganchan + 10 我很赞同
RyanBern + 666 + 2 以后回答问题就可以扔链接了
b565185756 + 100 我很赞同
stevenrock + 36 很厉害呢
y967 + 40 终于有了,实用
夜狠简单 + 66 塞糖

查看全部评分

熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *

Lv5.捕梦者 (版主)

梦石
1
星屑
23999
在线时间
3339 小时
注册时间
2011-7-8
帖子
3926

开拓者

2
 楼主| 发表于 2017-3-8 20:55:15 | 只看该作者
本帖最后由 guoxiaomi 于 2017-4-3 22:44 编辑

继续说一点,Sailcat 前辈的脚本为了解决回血的问题——即在显示伤害数字(@phase4_step = 5)的时候目标的血量实际上已经扣除——将 phase4 的几个 step 位置移动了。我的这个脚本里没有这么做,所以对于减伤的技能效果,实现起来要困难一些。但是其他的效果也算是比较容易实现了。
下面会举一些例子,其实大部分实现方法跟 Sailcat 前辈差不多,所以我这里着重讲几个区别比较大的地方。

1. 连击(单回合多次行动)
连击的话,思路很清楚,在第 2 处公共事件里,或者在物品、技能的公共事件里,设置 $scene.phase4_step = 2。这样在 step = 5(或6) 结束后,会回到 step = 2,此时@active_battler没有改变,就会重复执行之前的行动。
所以要把 phase4_step 给拿出来,同时为了方便添加说明文字,把 help_window 也拿出来。
RUBY 代码复制
  1. class Scene_Battle
  2.   attr_reader   :help_window  
  3.   attr_accessor :phase4_step
  4. end

比如说,在技能 1 释放后会追加 1 次攻击。事件脚本:
RUBY 代码复制
  1. @battler = $scene.active_battler
  2. a = @battler.current_action
  3. if a.kind == 1 && a.skill_id == 1
  4.   a.kind, a.basic = 0, 0
  5.   $scene.phase4_step = 2
  6.   $scene.help_window.set_text("追加攻击", 1)
  7.   $scene.help_window.visible = true
  8. end


2. 技能暴击(添加暴击字符串)
技能暴击,关键是要添加一个暴击字符串,然后修正对象HP。在第 2 处公共事件判断技能ID、概率决定后面的处理。添加以下的事件脚本,这里分成 2 个,其实写成 1 个也没问题。
RUBY 代码复制
  1. @battler = $scene.active_battler
  2. @targets =  $scene.target_battlers

RUBY 代码复制
  1. a = @battler.current_action
  2. if a.kind == 1 && a.skill_id == 57
  3. @targets.each do |t|
  4.   if t.damage.is_a?(Numeric) && rand < 0.25
  5.    t.hp = [t.hp-t.damage,0].max
  6.    t.damage = t.damage * 2   
  7.    t.critical = true
  8.   end
  9. end
  10. end

则 57 号技能有 25% 的概率造成 2 倍伤害,并显示 Critical 字样。

3. 魔法盾(减伤+伤害SP)
减伤比较麻烦的地方在于,damage 里记录的是造成的伤害值,而不是 hp 的损失值。比如 damage > 现有 hp,直接致死,但是在第 2 处公共事件触发时 hp = 0,所以如果回血直接 hp += damage 就不对了。
有 2 种解决方案:
1. 在扣血前记录对象方 HP。
2. 附加状态防御以减伤。
第 1 种方法就不细说了,只要在第 1 处公共事件里记录下所有敌人、队友的HP值即可。
第 2 种方法的思路还是比较巧妙的:
要实现 60% 的伤害被 SP 吸收,首先保证实际造成的伤害不能高于 40%,否则对象方 hp < 0 再回血就BUG了。首先要做以下准备工作:
  1. 设置技能附带属性和状态,假设是属性:[魔法攻击]和状态:[受到魔法伤害]
  2. 设置 2 个状态,分别是[魔法盾],[减伤1],都能防御属性:[魔法攻击],持续 3 回合
  3. 设置[魔法盾]状态,附加[减伤1] 这个状态
这样由于 2 重属性防御使得最终受到的伤害为 25% < 40%,从而确保此技能不会有伤害溢出。流程如下:
1. 发动攻击,属性[魔法攻击],对象方附加上状态[受到魔法伤害]
2. 由于对象方带有状态[魔法盾],[减伤1],所以对属性[魔法攻击] 2 次减伤,无 Miss 的情况下承受 25% 的伤害
3. 进入行动后公共事件,由于对象方带有状态[魔法盾],[受到魔法伤害],且伤害不为 Miss,魔法盾效果发动
4. 对象方再次承受 15% 的伤害,并且根据 SP 的量承受额外的伤害,以及损失 SP
5. 显示最终的伤害值,移除[受到魔法伤害]的状态
这里,状态 20 是[受到魔法伤害] 状态 21 是[魔法盾] 状态 22 是[减伤1]
RUBY 代码复制
  1. @battler = $scene.active_battler
  2. @targets =  $scene.target_battlers

RUBY 代码复制
  1. @targets.each do |t|
  2. next if not t.state?(21)
  3. if t.damage.is_a?(Numeric) && t.state?(20)
  4.   t.damage = t.damage * 4
  5.   a = t.damage * 60/100 - t.sp
  6.   t.hp = t.hp - t.damage * 15/100
  7.   t.damage -= (a>0)? t.sp : t.damage*60/100  
  8.   t.sp = (a>0)? 0 : -a
  9.   t.hp = (a>0)? t.hp - a : t.hp
  10. end
  11. end

RUBY 代码复制
  1. @targets.each do |t|
  2. t.remove_state(20)
  3. end


4. 多合一范例
范例里十字斩可以200%暴击、追加随机攻击;魔法盾减少60%十字斩的伤害,不减少攻击伤害;敌人会自带魔法盾,和 5 回合的薄葬效果,并且每回合回复 100 HP。
公共事件里按照触发顺序依次是,关闭伤害显示 -> 判断暴击(施加伤害) -> 判断魔法盾(承受伤害) -> 显示伤害、移除标记 -> 判断薄葬 -> 判断连击
公共事件战斗.zip (202.72 KB, 下载次数: 287)

5. 理想的设置
理想的设置是这样的:
1. 武器、技能会附带[物理伤害]、[魔法伤害]、[纯粹伤害]中的一种属性,并且给对象方施加[承受物理伤害]、[承受魔法伤害]、[承受纯粹伤害]的状态。
2. 魔法盾等伤害减免的效果,响应哪种类型的技能,就对此技能进行减伤,然后根据对象方身上承受伤害类型的状态来决定后续的处理。
3. 最后显示伤害数字,并且移除对象方[承受物理伤害]、[承受魔法伤害]、[承受纯粹伤害]的状态。
4. 目标受到的伤害数字 t.damage 会收到不同的技能效果而发生变化并传递给下一个技能效果,最终得到一个伤害数字,然后显示。
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
42436
在线时间
7603 小时
注册时间
2009-7-6
帖子
13506

开拓者贵宾

3
发表于 2017-3-9 10:53:59 | 只看该作者
仅仅是作为自己使用的话,没什么问题,但这样不便于管理,效率也低。
其实战斗前后执行事件才是个比较棘手的问题,楼主或许可以试试23333

评分

参与人数 1星屑 +66 收起 理由
RyanBern + 66 提出了醋瞎的问题

查看全部评分

RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
23999
在线时间
3339 小时
注册时间
2011-7-8
帖子
3926

开拓者

4
 楼主| 发表于 2017-3-9 11:16:35 | 只看该作者
本帖最后由 guoxiaomi 于 2017-3-9 11:21 编辑
fux2 发表于 2017-3-9 10:53
仅仅是作为自己使用的话,没什么问题,但这样不便于管理,效率也低。
其实战斗前后执行事件才是个比较棘手 ...


我其实一直以为战斗前后不是问题……我目前的想法是
战斗前:在队伍里设置 0+0回合 ~
战斗后:在战斗结束返回 Scene_Map 前修改 $game_temp.comment_event_id,或者打开一个开关

不知道这样会不会有什么BUG……
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
42436
在线时间
7603 小时
注册时间
2009-7-6
帖子
13506

开拓者贵宾

5
发表于 2017-3-9 18:47:23 | 只看该作者
guoxiaomi 发表于 2017-3-9 11:16
我其实一直以为战斗前后不是问题……我目前的想法是
战斗前:在队伍里设置 0+0回合 ~
战斗后:在战斗结束 ...

队伍里,难道所有队伍都添加一个事件页吗- -
战后,如果这场战斗本身就在事件指令中,战后的公共事件预约根本不会生效。

点评

应该解决了……  发表于 2017-3-10 00:19
了解,我再想想  发表于 2017-3-9 21:47
RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 支持 反对

使用道具 举报

Lv2.观梦者

梦石
0
星屑
596
在线时间
797 小时
注册时间
2014-7-1
帖子
578

开拓者

6
发表于 2017-3-9 19:02:14 | 只看该作者
很想用 等哪天有空就好好用一下,正好正在填坑的游戏需要战前自动释放一个技能。
就是开场就自动触发一个技能,就是怕卡{:2_248:}

点评

已经解决~  发表于 2017-3-10 00:19
开场自动触发一个技能,我这里并没有实现。目前的想法仍然是回合 0+0x ……等想好了会再更新此贴的~  发表于 2017-3-9 21:49
学习使我疲劳,打工使我疲惫,恋爱使我伤身,吸烟伤我肺腑,饮酒损我形象,旅游使我破费,月底不见铜板,只有在论坛里面看看各种大佬才能使我进去
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
23999
在线时间
3339 小时
注册时间
2011-7-8
帖子
3926

开拓者

7
 楼主| 发表于 2017-3-10 00:16:44 | 只看该作者
本帖最后由 guoxiaomi 于 2017-3-10 01:29 编辑

战斗前后调用公共事件,这个目前看来没有BUG

战斗前:
修改 Scene_Battle 1 的第 21 行,原来是初始化解释器:
  1. $game_system.battle_interpreter.setup(nil, 0)
复制代码

改为执行第 3 号公共事件:
  1. $game_system.battle_interpreter.setup($data_common_events[3].list, 0)
复制代码


如果想在战斗前释放技能、执行动作,添加下面的事件脚本:
RUBY 代码复制
  1. a = $game_actors[1].current_action
  2. a.kind = 1
  3. a.skill_id = 57
  4. a.decide_random_target_for_actor
  5. $scene.help_window.set_text("优先回合", 1)
  6. $scene.help_window.visible = true
  7. $game_temp.battle_turn = -1
  8. $scene.start_phase4


这里其实是分 3 段:
1. 设置角色要执行的技能(current_action),这里设置 1 号角色使用 57 号技能:十字斩。可以设置多个角色。
2. 设置help_window,显示一行说明文字,可以不要。
3. 设置回合数为 -1, 并跳转到 Scene Battle 的 Phase 4

注意:
1. 如此设置的执行顺序是,在此公共事件执行结束后,执行 0+0x 的战斗事件,然后跳转到 Scene Battle 的 Phase 4 开始行动。
2. 因为是正常的行动,行动前后会执行前面里设置的行动前、后公共事件。如果不想执行,判断 $game_temp.battle_turn != 0 即可。

战斗后:
在 battle_end 里面打开开关 2,然后设置 4 号公共事件并行处理,开关为 2。如此即可在战斗后回到地图中执行 4 号公共事件。
RUBY 代码复制
  1. class Scene_Battle
  2.   alias _old_battle_end battle_end
  3.   def battle_end(result)
  4.     _old_battle_end(result)
  5.     # 打开开关 2
  6.     $game_switches[2] = true
  7.   end
  8. end


范例:
公共事件战斗1.zip (191.51 KB, 下载次数: 184)

点评

恩,上班中,晚上回去用上!太感谢了!  发表于 2017-3-10 08:34

评分

参与人数 1星屑 +30 收起 理由
jiushiainilip19 + 30 塞糖

查看全部评分

熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
23999
在线时间
3339 小时
注册时间
2011-7-8
帖子
3926

开拓者

8
 楼主| 发表于 2017-3-12 21:34:58 | 只看该作者
本帖最后由 guoxiaomi 于 2017-3-12 21:45 编辑

回合开始(队伍命令前)调用公共事件:

在 start_phase2 中加入公共事件的调用:

  1. class Scene_Battle
  2.   alias _old_start_phase2 start_phase2
  3.   def start_phase2
  4.     _old_start_phase2
  5.     # 执行公共事件 5
  6.     $game_system.battle_interpreter.setup($data_common_events[5].list, 0)
  7.   end
  8. end
复制代码


每个回合开始前调用公共事件 5,从第 1 回合开始才会调用,故不影响战斗前的公共事件,但是由于在 phase4 才会增加 $game_temp.battle_turn 的值,所以在此事件里的回合数是从 0 开始的。
到此为止,战斗前、回合开始、行动前、行动后、战斗后(地图画面)这 5 种时间点都可以调用公共事件,同时与原有的战斗事件兼容。
默认战斗用这种方法可以进行方便又强力的改动。
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv2.观梦者

梦石
0
星屑
910
在线时间
94 小时
注册时间
2005-10-22
帖子
397
9
发表于 2018-3-24 20:58:40 | 只看该作者
这些都是10年前我在研究的东东啊

评分

参与人数 1+1 收起 理由
guoxiaomi + 1 我很赞同

查看全部评分

做脚本先从修改脚本做起,我只修改自己觉得能用到的东西。
以后的任何作品都将不会进行分享。
Bilibili:https://space.bilibili.com/288814521
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
23999
在线时间
3339 小时
注册时间
2011-7-8
帖子
3926

开拓者

10
 楼主| 发表于 2018-4-16 11:42:42 | 只看该作者
最近在更新游戏的战斗系统,借(chao)鉴(xi)了dota2的各种设定。

dota2里的天赋很有趣,比如说“+900寒霜之足AOE”,“+175连锁闪电伤害”,“重生不消耗魔法”。这些都是对原来的技能进行修改的特性,RM的话,通常方案就是做2个技能,学了就换掉,但是如果大胆的操作,可以在战斗前or行动前直接修改$data_skills战斗后or行动后改回来。

同样的也可以修改装备的武器($data_weapons)、防具数据($data_armors)甚至状态($data_states),因为RM会在每次计算攻击力、防御力的时候,都会读取这些数据,而不是在战斗一开始的时候读好缓存起来。

优点:
1. 几乎不与其他脚本冲突:因为绝大部分脚本都不会动数据库
2. 更加灵活:根据变化的值设置技能效果,比如技能伤害+变量1的值,或者给武器附上不同的属性。做多个技能的话,每个技能的数据仍然是固定不变的,后者需要设置多个武器。

缺点:
1. 需要对战斗系统有足够的了解,至少要知道这些数据在哪里被用到

熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 0 反对 1

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-27 10:12

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表