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

Project1

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

[原创发布] 【VA】可堆叠状态系统

[复制链接]

Lv3.寻梦者

梦石
0
星屑
1803
在线时间
133 小时
注册时间
2013-10-6
帖子
193
跳转到指定楼层
1
发表于 2022-5-19 03:47:39 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式

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

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

x
本帖最后由 不死鸟之翼 于 2022-5-19 03:57 编辑

# 简介

该系统可以让状态变得可堆叠,也就是说重复获得状态时会累计层数。同时,该系统支持将状态作为战斗资源使用,可以让技能以消费状态层数的方式打出。



# 使用方式

将脚本粘贴到数据库的单独一页内。

# 如何配置状态
给希望可堆叠的状态的备注栏加入一行:
[stackable]
这样重复获得状态时,不仅会刷新持续时间,还会增加计数。
如果希望限制最大层数,可以增加max属性:
[stackable max=3]

# 如何配置技能的发动条件
给希望消费状态的技能的备注栏加入一行:
[consume_state state=状态在数据库内的编号]
默认会消费全部层数的状态。如果想指定消费数量,可以使用count属性,例如:
[consume_state state=26 count=1]
这会消费一层26号状态。
特别地,如果count为0,表示只有在该状态下才能使出技能,但不会消费状态。

# 如何在脚本中读取状态的层数
使用Game_Battler的state_stack_count(skill_id)方法。

# 如何根据技能消费的状态层数决定威力
虽然理论上可以使用state_stack_count,但是由于VA的默认脚本会先支付技能消耗后使出技能,所以在计算伤害时状态层数已经变化了。
Game_Battler实例的last_state_cost属性表示上一次消耗的状态层数。
例如,伤害公式可以写成
1000 * a.last_state_cost
表示造成1000*攻击者发动技能前身上状态层数的伤害。

# 课后作业
1. 如何实现最多可蓄力3次的攻击?
2. 如何实现宝可梦系列的集气拳类技能(一回合蓄力后下一回合发动,但期间若受到攻击则蓄力会被打消而失败)?
3. 如何实现可以叠加威力的中毒debuff?
4. 如何实现技能连击系统(按照特定顺序使出特定技能的话会获得额外收益)?
5. 如何实现状态叠加到5层时即死?

# 使用许可
MIT

# 源代码
RUBY 代码复制
  1. # Stackable States by AzureFx
  2. # Revision 20220519.1
  3. # Licensed under the MIT License
  4.  
  5. def parse_note(note)
  6.   result=[]
  7.   note.each_line{|line|
  8.     m=/\[\s*([^\s=]+)\s*([^\]]+)?\s*\]/i.match(line)
  9.     if m!=nil
  10.       elem=m[1]
  11.       attr={}
  12.       attr_s=m[2]
  13.       if attr_s!=nil
  14.         attr_s.to_enum(:scan, /([^=\s]+)\s*=\s*([^=\s]+)/)
  15.           .map{Regexp.last_match}
  16.           .each{|m|attr[m[1]]=m[2]}
  17.       end
  18.       result.push([elem,attr])
  19.     end
  20.   }
  21.   result
  22. end
  23.  
  24.  
  25. class RPG::State
  26.   def stackable?
  27.     if @stackable==nil
  28.       parse_note_stackable
  29.     end
  30.     return @stackable
  31.   end
  32.  
  33.   def max_stack
  34.     if @max_stack==nil
  35.       parse_note_stackable
  36.     end
  37.     return @max_stack
  38.   end
  39.  
  40.   def parse_note_stackable
  41.     stackable=false
  42.     max_stack=0
  43.     parse_note(note).each{|entry|
  44.     elem, attr=entry
  45.       if elem=='stackable'
  46.         stackable=true
  47.         if attr['max']!=nil
  48.           max_stack=attr['max'].to_i
  49.         end
  50.       end
  51.     }
  52.     @stackable=stackable
  53.     @max_stack=max_stack
  54.   end
  55.  
  56. end
  57.  
  58. class RPG::Skill
  59.   def consume_stack
  60.     if @consume_stack_parsed==nil
  61.       parse_consume_stack
  62.       @consume_stack_parsed=true
  63.     end
  64.     @consume_stack
  65.   end
  66.  
  67.   def parse_consume_stack
  68.     parse_note(note).each{|entry|
  69.       elem, attr=entry
  70.       if elem=='consume_state'
  71.         if attr['state']!=nil
  72.           state_id=attr['state'].to_i
  73.           @consume_stack={state: state_id}
  74.           if attr['count']!=nil
  75.             @consume_stack[:count]=attr['count'].to_i
  76.           end
  77.         end
  78.       end
  79.     }
  80.   end
  81. end
  82.  
  83. class Game_BattlerBase
  84.   alias clear_states_b1f2b6 clear_states
  85.   def clear_states
  86.     clear_states_b1f2b6
  87.     @state_stacks={}
  88.   end
  89.  
  90.   alias erase_state_b1f2b6 erase_state
  91.   def erase_state(state_id)
  92.     erase_state_b1f2b6(state_id)
  93.     @state_stacks.delete(state_id)
  94.   end
  95.  
  96.   def state_stack_count(state_id)
  97.     @state_stacks[state_id]||0
  98.   end
  99.  
  100.   def decrease_state_stack(state_id, count)
  101.     new_count=state_stack_count(state_id)-count
  102.     if new_count<=0
  103.       erase_state(state_id)
  104.     else
  105.       @state_stacks[state_id]=new_count
  106.     end
  107.   end
  108.  
  109.   alias skill_cost_payable_b1f2b6? skill_cost_payable?
  110.   def skill_cost_payable?(skill)
  111.     cs=skill.consume_stack
  112.     if cs!=nil
  113.       count=state_stack_count(cs[:state])
  114.       cost=cs[:count]||-1
  115.       return false unless count>0&&count>=cost
  116.     end
  117.     skill_cost_payable_b1f2b6?(skill)
  118.   end
  119.  
  120.   alias pay_skill_cost_b1f2b6 pay_skill_cost
  121.   def pay_skill_cost(skill)
  122.     pay_skill_cost_b1f2b6(skill)
  123.     cs=skill.consume_stack
  124.     if cs!=nil
  125.       cost=cs[:count]||-1
  126.       if cost<0
  127.         cost=state_stack_count(cs[:state])
  128.       end
  129.       @@last_state_cost=cost
  130.       decrease_state_stack(cs[:state], cost)
  131.     end
  132.   end
  133.  
  134.   def last_state_cost
  135.     @@last_state_cost
  136.   end
  137. end
  138.  
  139. class Game_Battler
  140.   alias reset_state_counts_b1f2b6 reset_state_counts
  141.   def reset_state_counts(state_id)
  142.     reset_state_counts_b1f2b6(state_id)
  143.     state = $data_states[state_id]
  144.     if state.stackable?
  145.       if @state_stacks[state_id]==nil
  146.         @state_stacks[state_id]=0
  147.       end
  148.       if state.max_stack<=0||@state_stacks[state_id]<state.max_stack
  149.         @state_stacks[state_id]+=1
  150.       end
  151.     end
  152.   end
  153.  
  154.   alias on_action_end_b1f2b6 on_action_end
  155.   def on_action_end
  156.     on_action_end_b1f2b6
  157.     @@last_state_cost=nil
  158.   end
  159. end
  160.  
  161. STACK_COUNT_FONT_SIZE=14
  162. STACK_COUNT_FONT=Font.new
  163. STACK_COUNT_FONT.size=STACK_COUNT_FONT_SIZE
  164. STACK_COUNT_FONT.color=Color.new(0,255,0)
  165. STACK_COUNT_FONT.bold=true
  166. STACK_COUNT_FONT.outline=false
  167. STACK_COUNT_FONT.shadow=true
  168.  
  169. class Window_Base
  170.   alias draw_actor_icons_b1f2b6 draw_actor_icons
  171.   def draw_actor_icons(actor, x, y, width = 96)
  172.     draw_actor_icons_b1f2b6(actor, x, y, width)
  173.     last_font=contents.font
  174.     last_size=last_font.size
  175.     last_bold=last_font.bold
  176.     contents.font=STACK_COUNT_FONT
  177.     actor.states.select{|s|s.icon_index!=0}.each_with_index {|s, i|
  178.       if s.stackable?
  179.         count=actor.state_stack_count(s.id)
  180.         contents.draw_text(x, y+1, 22, STACK_COUNT_FONT_SIZE, count, 2)
  181.       end
  182.     }
  183.     contents.font=last_font
  184.     contents.font.size=last_size
  185.     contents.font.bold=last_bold
  186.   end
  187. end


# 版本历史
Revision 20220519.1 初次在P1发布
←你看到一只经常潜水的萌新。

Lv1.梦旅人

梦石
0
星屑
65
在线时间
10 小时
注册时间
2020-2-9
帖子
7
17
发表于 2022-8-23 17:30:17 | 只看该作者
alexncf125 发表于 2022-8-23 17:19
啊这...怎么我这边有三个状态时的输出会是
108
0

谢谢大佬!
回复 支持 反对

使用道具 举报

Lv5.捕梦者

梦石
0
星屑
24514
在线时间
5086 小时
注册时间
2016-3-8
帖子
1624
16
发表于 2022-8-23 17:19:44 | 只看该作者
本帖最后由 alexncf125 于 2022-8-23 17:25 编辑
FSword9 发表于 2022-8-23 16:38
只有一个状态时每次输出是
108
0


啊这...怎么我这边有三个状态时的输出会是
108
0
108
1
108
2

不过这也不太重要, 反正有108跟0, 1, 2, 3, ...
就能知道正确的算式了(ps 图标的宽是24像素
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
65
在线时间
10 小时
注册时间
2020-2-9
帖子
7
15
发表于 2022-8-23 16:38:07 | 只看该作者
alexncf125 发表于 2022-8-23 16:05
那么在前插入一行p x一行p i之后, 看看控制台都输出了什么

只有一个状态时每次输出是
108
0
两个状态是
108
0
0
1
三个状态是
108
0
0
1
1
2
四个状态
108
0
0
1
1
2
2
3
回复 支持 反对

使用道具 举报

Lv5.捕梦者

梦石
0
星屑
24514
在线时间
5086 小时
注册时间
2016-3-8
帖子
1624
14
发表于 2022-8-23 16:05:07 | 只看该作者
FSword9 发表于 2022-8-23 15:49
在180行前插入一行写了一个x=i之后,计数器堆叠在了角色名字的位置

那么在前插入一行p x一行p i之后, 看看控制台都输出了什么
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
65
在线时间
10 小时
注册时间
2020-2-9
帖子
7
13
发表于 2022-8-23 15:49:35 | 只看该作者
alexncf125 发表于 2022-8-23 12:35
177至182行中,
把180行的 x 拿177行的 i 来计算

在180行前插入一行写了一个x=i之后,计数器堆叠在了角色名字的位置
回复 支持 反对

使用道具 举报

Lv5.捕梦者

梦石
0
星屑
24514
在线时间
5086 小时
注册时间
2016-3-8
帖子
1624
12
发表于 2022-8-23 12:35:10 | 只看该作者
FSword9 发表于 2022-8-23 12:28
请问同一个角色身上出现多个可堆叠状态时,所有计数器都显示在同一位置而没有跟随图标移动的问题应该怎么解 ...

177至182行中,
把180行的 x 拿177行的 i 来计算
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
65
在线时间
10 小时
注册时间
2020-2-9
帖子
7
11
发表于 2022-8-23 12:28:23 | 只看该作者
本帖最后由 FSword9 于 2022-8-23 12:29 编辑

请问同一个角色身上出现多个可堆叠状态时,所有计数器都显示在同一位置而没有跟随图标移动的问题应该怎么解决?

回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
2698
在线时间
360 小时
注册时间
2015-1-29
帖子
13
10
发表于 2022-7-25 19:07:08 | 只看该作者
这脚本只累计层数,无法叠加特性啊。
一个状态+10%攻击力,就算有3层也只+10%攻击力。
回复 支持 反对

使用道具 举报

Lv2.观梦者

梦石
0
星屑
346
在线时间
63 小时
注册时间
2020-2-24
帖子
13
9
发表于 2022-7-17 15:17:12 | 只看该作者
这个他会更改字体 不希望它更改得话应该怎么做呢
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-5-22 05:49

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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