查看: 88|回复: 0

[转载发布] 【VA】可堆叠状态系统

[复制链接]
  • TA的每日心情
    开心
    前天 00:56
  • 签到天数: 33 天

    连续签到: 1 天

    [LV.5]常住居民I

    2022

    主题

    32

    回帖

    7144

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    VIP
    0
    卡币
    5074
    OK点
    16
    积分
    7144
    发表于 同元一千年二月十一日(春) | 显示全部楼层 |阅读模式
    # 简介

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



    # 使用方式

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

    # 如何配置状态
    给希望可堆叠的状态的备注栏加入一行:
    [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 代码

    [Ruby] 纯文本查看 复制代码
    # Stackable States by AzureFx
    # Revision 20220519.1
    # Licensed under the MIT License
     
    def parse_note(note)
      result=[]
      note.each_line{|line|
        m=/\[\s*([^\s=]+)\s*([^\]]+)?\s*\]/i.match(line)
        if m!=nil
          elem=m[1]
          attr={}
          attr_s=m[2]
          if attr_s!=nil
            attr_s.to_enum(:scan, /([^=\s]+)\s*=\s*([^=\s]+)/)
              .map{Regexp.last_match}
              .each{|m|attr[m[1]]=m[2]}
          end
          result.push([elem,attr])
        end
      }
      result
    end
     
     
    class RPG::State
      def stackable?
        if @stackable==nil
          parse_note_stackable
        end
        return @stackable
      end
     
      def max_stack
        if @max_stack==nil
          parse_note_stackable
        end
        return @max_stack
      end
     
      def parse_note_stackable
        stackable=false
        max_stack=0
        parse_note(note).each{|entry|
        elem, attr=entry
          if elem=='stackable'
            stackable=true
            if attr['max']!=nil
              max_stack=attr['max'].to_i
            end
          end
        }
        @stackable=stackable
        @max_stack=max_stack
      end
     
    end
     
    class RPG::Skill
      def consume_stack
        if @consume_stack_parsed==nil
          parse_consume_stack
          @consume_stack_parsed=true
        end
        @consume_stack
      end
     
      def parse_consume_stack
        parse_note(note).each{|entry|
          elem, attr=entry
          if elem=='consume_state'
            if attr['state']!=nil
              state_id=attr['state'].to_i
              @consume_stack={state: state_id}
              if attr['count']!=nil
                @consume_stack[:count]=attr['count'].to_i
              end
            end
          end
        }
      end
    end
     
    class Game_BattlerBase
      alias clear_states_b1f2b6 clear_states
      def clear_states
        clear_states_b1f2b6
        @state_stacks={}
      end
     
      alias erase_state_b1f2b6 erase_state
      def erase_state(state_id)
        erase_state_b1f2b6(state_id)
        @state_stacks.delete(state_id)
      end
     
      def state_stack_count(state_id)
        @state_stacks[state_id]||0
      end
     
      def decrease_state_stack(state_id, count)
        new_count=state_stack_count(state_id)-count
        if new_count<=0
          erase_state(state_id)
        else
          @state_stacks[state_id]=new_count
        end
      end
     
      alias skill_cost_payable_b1f2b6? skill_cost_payable?
      def skill_cost_payable?(skill)
        cs=skill.consume_stack
        if cs!=nil
          count=state_stack_count(cs[:state])
          cost=cs[:count]||-1
          return false unless count>0&&count>=cost
        end
        skill_cost_payable_b1f2b6?(skill)
      end
     
      alias pay_skill_cost_b1f2b6 pay_skill_cost
      def pay_skill_cost(skill)
        pay_skill_cost_b1f2b6(skill)
        cs=skill.consume_stack
        if cs!=nil
          cost=cs[:count]||-1
          if cost<0
            cost=state_stack_count(cs[:state])
          end
          @@last_state_cost=cost
          decrease_state_stack(cs[:state], cost)
        end
      end
     
      def last_state_cost
        @@last_state_cost
      end
    end
     
    class Game_Battler
      alias reset_state_counts_b1f2b6 reset_state_counts
      def reset_state_counts(state_id)
        reset_state_counts_b1f2b6(state_id)
        state = $data_states[state_id]
        if state.stackable?
          if @state_stacks[state_id]==nil
            @state_stacks[state_id]=0
          end
          if state.max_stack<=0||@state_stacks[state_id]<state.max_stack
            @state_stacks[state_id]+=1
          end
        end
      end
     
      alias on_action_end_b1f2b6 on_action_end
      def on_action_end
        on_action_end_b1f2b6
        @@last_state_cost=nil
      end
    end
     
    STACK_COUNT_FONT_SIZE=14
    STACK_COUNT_FONT=Font.new
    STACK_COUNT_FONT.size=STACK_COUNT_FONT_SIZE
    STACK_COUNT_FONT.color=Color.new(0,255,0)
    STACK_COUNT_FONT.bold=true
    STACK_COUNT_FONT.outline=false
    STACK_COUNT_FONT.shadow=true
     
    class Window_Base
      alias draw_actor_icons_b1f2b6 draw_actor_icons
      def draw_actor_icons(actor, x, y, width = 96)
        draw_actor_icons_b1f2b6(actor, x, y, width)
        last_font=contents.font
        last_size=last_font.size
        last_bold=last_font.bold
        contents.font=STACK_COUNT_FONT
        actor.states.select{|s|s.icon_index!=0}.each_with_index {|s, i|
          if s.stackable?
            count=actor.state_stack_count(s.id)
            contents.draw_text(x, y+1, 22, STACK_COUNT_FONT_SIZE, count, 2)
          end
        }
        contents.font=last_font
        contents.font.size=last_size
        contents.font.bold=last_bold
      end
    end



    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    天天去同能,天天有童年!
    回复 论坛版权

    使用道具 举报

    ahome_bigavatar:guest
    ahome_bigavatar:welcomelogin
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

    GMT+8, 2024-4-30 13:05 , Processed in 0.052930 second(s), 47 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

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