じ☆ve冰风 发表于 2024-4-12 16:44:12

【VA】可堆叠状态系统

# 简介

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



# 使用方式

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

# 如何配置状态
给希望可堆叠的状态的备注栏加入一行:

这样重复获得状态时,不仅会刷新持续时间,还会增加计数。
如果希望限制最大层数,可以增加max属性:


# 如何配置技能的发动条件
给希望消费状态的技能的备注栏加入一行:

默认会消费全部层数的状态。如果想指定消费数量,可以使用count属性,例如:

这会消费一层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 代码

# 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
      attr={}
      attr_s=m
      if attr_s!=nil
      attr_s.to_enum(:scan, /([^=\s]+)\s*=\s*([^=\s]+)/)
          .map{Regexp.last_match}
          .each{|m|attr]=m}
      end
      result.push()
    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||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=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
    if state.stackable?
      if @state_stacks==nil
      @state_stacks=0
      end
      if state.max_stack<=0||@state_stacks<state.max_stack
      @state_stacks+=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


页: [1]
查看完整版本: 【VA】可堆叠状态系统