查看: 9902|回复: 35

[原创发布] 技能消耗你想消耗的一切,除了SP!!!v1.3更新整合

[复制链接]

遠航の猫咪

梦石
3
星屑
26947
在线时间
2423 小时
注册时间
2005-10-15
回帖
987

开拓者

发表于 2017-11-2 19:24:38 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 SailCat 于 2017-11-22 02:02 编辑

以为3小时能搞定了,搞了4个多小时……对RGSS1的脚本风格无力吐槽
以此贴终结所有技能消耗XXXX,技能需要XXXX的求助贴吧!
需要“数据库通用备注接口”插件,XP加了备注果然无比强大……
该插件所在地址:https://rpg.blue/thread-403415-1-1.html


更新:
v1.3
整合到2.0版本的数据库备注插件系列
v1.2
修复了一个冷却判定的bug,感谢@89444640测试
v1.1
能力值限制现在可以用更自由的写法,例如str300-400,hp25-,sp50+,dex=200
所有集都可以改用子界表示甚至嵌套子界表示,如[4..6, 9..11, -104...-101]实际相当于[4, 5, 6, 9, 10, 11, -104, -103, -102],节省备注书写空间


关于和魔改Scene_Skill脚本的冲突说明:
XP因为没有Scene_Base的超级类,所有场景的处理都是写在大段的update_xxxx中各种条件分歧里而不是模块化的,实际上这个脚本需要修改的只是:
在消耗SP时,也同样消耗其他东西。
如果你魔改了Scene_Skill类,插入脚本后删除426行以下内容,然后在Scene_Skill类中搜索如同"xxx.sp -= @skill.sp_cost"这样的脚本,然后在后面加上一句
xxx.skill_cost_extra(@skill)
即可。


一些写法技巧:
牺牲技(放完自己会死):#ch=9999
满血才能放技能:#cn:hp100
黄血才能放技能:#cn:hp25-
需要特定类别的武器放技能:武器不多的话直接列#cq=[-5, -3, -1]这样,武器太多或未设定完成的话,用属性法设置武器类别,然后#ce=属性,武器编号连续可以写成#cq=[-6..-2]
技能要求某变量大于某值(但不消耗):#cf:v[xx]>yyy
技能要求某部位装备为空值(如不能装盾):#cf:a.armor1_id==0

实际上提供cf接口你可以写出你想设定的任何条件了……

[fold=点击查看完整代码]
[pre lang="ruby"]
#==============================================================================
# ■ 技能消耗依赖 v1.3 by SailCat
#------------------------------------------------------------------------------
#   方法:本脚本插入到Main之前使用,并依赖数据库通用备注接口插件(在其之后)
#   版本:v1.3 (Build 171122)
#   效果:
#     1. 技能消耗SP以外的游戏数据,包括HP、道具、武器、防具、金钱、经验、变量
#     2. 技能使用场合依赖游戏条件,包括开关、状态、地图相关、装备、能力、步数等
#     3. 技能消耗额外的回合(技能冷却)
#   配置:插件为即插即用型,没有任何配置项,也不需要在脚本中设定任何东西
#   冲突:其他同类脚本,以及魔改了Scene_Skill的脚本
#   说明:
#     1. 技能消耗道具、武器、防具、金钱、变量时,有使用检查,不够消耗不让用。
#     2. 技能消耗HP、经验时,无使用检查,扣到0为止。
#     3. 技能依赖开关、状态、地图、地形、装备、属性均检查至所有条件严格相符。
#     4. 技能依赖能力检查条件为能力在指定范围内,步数检查条件为指定步数以上。
#     5. 备注写法:
#        (写在描述里,不同条件可以叠加用分号隔开,备注和描述以#号分隔)
#        (当[XX集]内容只有一条时,方括号可省略,当内容序号连续时,可写成子界)
#        (条件太多写不下时,可用超长备注法,见依赖插件的说明)
#        a) 技能消耗HP:ch=值
#        b) 技能消耗道具:ci=[消耗道具ID集]
#        消耗道具个数>1的情况下,ID后缀两位小数为消耗个数,如4.05消耗4号道具5个
#        写成4和4.00是不一样的,前者消耗4号道具1个,后者要求持有4号道具但不消耗
#        c) 技能消耗武器:cw=[消耗武器ID集],说明同道具,消耗的是持有的武器
#        d) 技能消耗防具:ca=[消耗防具ID集],说明同道具,消耗的是持有的防具
#        e) 技能消耗金钱:cg=值
#        f) 技能消耗经验:cx=值
#        g) 技能消耗变量:cv={变量ID=>消耗值},写成hash形式,不能省略花括号
#        h) 技能消耗回合:cd=值
#        i) 技能依赖开关:cs=[开关集],开关ID为正数要求ON,为负数要求OFF
#        j) 技能依赖状态:cc=[状态集],状态ID为正数要求有,为负数要求没有
#        k) 技能依赖地图:cm=[地图ID集],地图ID为正数要求在,为负数要求不在
#        l) 技能依赖地形:ct=[地形标志集],标志为正数要求是,为负数要求不是
#        m) 技能依赖装备:cq=[装备ID集],查身上装备,武器ID写负数,防具ID写正数
#        n) 技能依赖步数:cp=值
#        o) 技能依赖属性:ce=[属性ID集],查装备属性,正数要求有,负数要求没有
#        p) 技能依赖能力:cn=能力字符串,如"str300",有多个条件直接连写
#        能力可以用hp/sp/str/dex/agi/int,大小写不敏感
#        条件值的写法:300或300+表示大于等于300;300-表示小于等于300;
#                      =300表示恰好300;300~400表示300到400之间(闭区间)
#        q) 技能依赖茂密:cb+(要求茂密处)或cb-(要求非茂密处)
#        r) 技能依赖公式:cf:公式脚本字符串,公式要能返回true或false的真伪值
#        公式中可以使用a代表技能使用者,v代表变量,s代表开关
#==============================================================================
#==============================================================================
# ■ SailCat's 插件公用
#==============================================================================
module SailCat
  $sailcat_import ||= {}
  #--------------------------------------------------------------------------
  # ● 植入与依赖检查
  #--------------------------------------------------------------------------
  if $sailcat_import[:DataNoteCore].to_f >= 2.0
    $sailcat_import[:SkillCost] = 1.3
  else
    raise "缺少依赖插件,通用数据库备注接口(v2.0以上版本)"
  end
end
module RPG
  #============================================================================
  # ■ Skill_ItemCost
  #----------------------------------------------------------------------------
  #  处理技能消耗道具、武器、防具的内部类
  #============================================================================
  class Skill_ItemCost
    #--------------------------------------------------------------------------
    # ● 定义实例变量
    #--------------------------------------------------------------------------
    attr_accessor :id                     # 消耗的物品ID
    attr_accessor :number                 # 消耗的数目
    #--------------------------------------------------------------------------
    # ● 初期化
    #--------------------------------------------------------------------------
    def initialize(n)
      n = 0 unless n.is_a?(Numeric)
      n += 0.01 if n.is_a?(Fixnum)
      @id = Integer(n).abs
      @number = [Integer((n - @id) * 100.0 + 1e-6), 0].max
    end
    #--------------------------------------------------------------------------
    # ● 检查符合性
    #--------------------------------------------------------------------------
    def match?(proc)
      return true if @id == 0
      proc.call(@id) >= [@number, 1].max
    end
  end
  #============================================================================
  # ■ Skill_EquipCheck
  #----------------------------------------------------------------------------
  #  处理技能依赖装备状态的内部类
  #============================================================================
  class Skill_EquipCheck
    #--------------------------------------------------------------------------
    # ● 定义实例变量
    #--------------------------------------------------------------------------
    attr_accessor :weapons                # 依赖的武器ID(空为不检查)
    attr_accessor :armors1                # 依赖的盾牌ID(空为不检查)
    attr_accessor :armors2                # 依赖的头盔ID(空为不检查)
    attr_accessor :armors3                # 依赖的护甲ID(空为不检查)
    attr_accessor :armors4                # 依赖的饰品ID(空为不检查)
    #--------------------------------------------------------------------------
    # ● 初期化
    #--------------------------------------------------------------------------
    def initialize(ary)
      @weapons = @armors1 = @armors2 = @armors3 = @armors4 = []
      ary.map! {|i| i.to_a}.flatten!
      ary.each do |i|
        if i < 0
          @weapon_id.push(-i)
        else
          kind = $data_armors.kind + 1
          instance_eval("@armors#{kind}.push(#{i})") rescue nil
        end
      end
    end
    #--------------------------------------------------------------------------
    # ● 检查符合性
    #--------------------------------------------------------------------------
    def match?(a)
      return false if !@weapons.empty? and !@weapons.include?(a.weapon_id)
      return false if !@armors1.empty? and !@armors1.include?(a.armor1_id)
      return false if !@armors2.empty? and !@armors2.include?(a.armor2_id)
      return false if !@armors3.empty? and !@armors3.include?(a.armor3_id)
      return false if !@armors4.empty? and !@armors4.include?(a.armor4_id)
      return true
    end
  end
  #============================================================================
  # ■ Skill_AbilityCheck
  #----------------------------------------------------------------------------
  #  处理技能依赖能力的内部类
  #============================================================================
  class Skill_AbilityCheck
    #--------------------------------------------------------------------------
    # ● 常量
    #--------------------------------------------------------------------------
    REGEX = /(hp|sp|str|dex|agi|int)(=?([0-9]+)([+\-~])?([0-9]+)?)/i
    #--------------------------------------------------------------------------
    # ● 定义实例变量
    #--------------------------------------------------------------------------
    attr_accessor :hp_range               # 依赖的 HP % 范围
    attr_accessor :sp_range               # 依赖的 SP % 范围
    attr_accessor :str_range              # 依赖的力量值范围
    attr_accessor :dex_range              # 依赖的灵巧值范围
    attr_accessor :agi_range              # 依赖的速度值范围
    attr_accessor :int_range              # 依赖的魔力值范围
    #--------------------------------------------------------------------------
    # ● 初期化
    #--------------------------------------------------------------------------
    def initialize(str)
      @hp_range = @sp_range = 0..100
      @str_range = @dex_range = @agi_range = @int_range = 0..999
      ary = str.scan(REGEX)
      ary.each do |a|
        name = a[0].downcase
        min = a[2]
        max = a[4] || a[2]
        if a[1][0] != 61
          max = (name[1] == 112 ? 100 : 999) if a[3] == nil or a[3] == "+"
          min = 0 if a[3] == "-" and a[4] == nil
        end
        instance_eval("@#{name}_range = #{min}..#{max}") rescue nil
      end
    end
    #--------------------------------------------------------------------------
    # ● 检查符合性
    #--------------------------------------------------------------------------
    def match?(a)
      return false unless @hp_range === a.hp * 100 / a.maxhp
      return false unless @sp_range === a.sp * 100 / [a.maxsp, 1].max
      return false unless @str_range === a.str
      return false unless @dex_range === a.dex
      return false unless @agi_range === a.agi
      return false unless @int_range === a.int
      return true
    end
  end
  #============================================================================
  # ■ RPG::Skill
  #----------------------------------------------------------------------------
  #  数据库的技能类扩展
  #============================================================================
  class Skill
    #--------------------------------------------------------------------------
    # ● 备注定义
    #--------------------------------------------------------------------------
    def hp_cost;       _ch(0).abs;                                        end
    def exp_cost;      _cx(0).abs;                                        end
    def gold_cost;     _cg(0).abs;                                        end
    def cooldown;      _cd(0).abs;                                        end
    def variable_cost; _cv({});                                           end
    def item_cost;     _ci([]).to_a.map {|f| Skill_ItemCost.new(f)};      end
    def weapon_cost;   _cw([]).to_a.map {|f| Skill_ItemCost.new(f)};      end
    def armor_cost;    _ca([]).to_a.map {|f| Skill_ItemCost.new(f)};      end
    def switch_check;  flat_array(_cs([]));                               end
    def state_check;   flat_array(_cc([]));                               end
    def map_check;     flat_array(_cm([]));                               end
    def terrain_check; flat_array(_ct([]));                               end
    def element_check; flat_array(_ce([]));                               end
    def bush_check;    _cb(nil);                                          end
    def step_check;    _cp(0).abs;                                        end
    def equip_check;   Skill_EquipCheck.new(_cq([]).to_a);                end
    def ability_check; Skill_AbilityCheck.new(_cn("").to_s);              end
    def eval_check;    _cf("true");                                       end
    #--------------------------------------------------------------------------
    # ● 公式依赖判定
    #--------------------------------------------------------------------------
    def eval_match?(actor)
      result = lambda {|a, s, v| eval(eval_check) rescue true}
      result.call(actor, $game_switches, $game_variables)
    end
    #--------------------------------------------------------------------------
    # ● 通用正负依赖判定
    #--------------------------------------------------------------------------
    def pn_match?(set, obj, proc = Proc.new{|a, b| a == b})
      (set.reject {|s| (s > 0) == proc.call(obj, s.abs)}).empty?
    end
    #--------------------------------------------------------------------------
    # ● 变量消耗判定
    #--------------------------------------------------------------------------
    def variable_match?
      variable_cost.each do |k, v|
        return false if $game_variables[k] < v
      end
      return true
    end
    #--------------------------------------------------------------------------
    # ● 道具消耗判定
    #--------------------------------------------------------------------------
    def item_match?(set, proc)
      set.each do |s|
        return false unless s.match?(proc)
      end
      return true
    end
  end
end
#==============================================================================
# ■ Game_Battler
#==============================================================================
class Game_Battler
  #--------------------------------------------------------------------------
  # ● 使用技能的额外消耗
  #     skill : 特技
  #--------------------------------------------------------------------------
  def skill_cost_extra(skill)
    self.hp -= skill.hp_cost
  end
end
#==============================================================================
# ■ Game_Actor
#==============================================================================
class Game_Actor
  #--------------------------------------------------------------------------
  # ● 定义实例变量
  #--------------------------------------------------------------------------
  attr_reader   :cooldowns             # 冷却中的技能集
  #--------------------------------------------------------------------------
  # ● 方法重定义
  #--------------------------------------------------------------------------
  unless method_defined? :sailcat_skill_can_use?
    alias sailcat_skillcost_skill_can_use? skill_can_use?
  end
  #--------------------------------------------------------------------------
  # ● 可以使用特技判定
  #     skill_id : 特技 ID
  #--------------------------------------------------------------------------
  def skill_can_use?(skill_id)
    # 获得对应的特技实体
    skill = $data_skills[skill_id]
    # 装备不符的情况下,不能使用
    if not skill.equip_check.match?(self)
      return false
    # 能力不符的情况下,不能使用
    elsif not skill.ability_check.match?(self)
      return false
    # 步数不够的情况下,不能使用
    elsif $game_party.steps < skill.step_check
      return false
    # 金钱不够的情况下,不能使用
    elsif $game_party.gold < skill.gold_cost
      return false
    # 属性不符的情况下,不能使用
    elsif not skill.pn_match?(skill.element_check, self, Proc.new{|a,b|
      a.element_set.include?(b) or ([a.armor1_id, a.armor2_id,
      a.armor3_id, a.armor4_id].inject(false) {|res, id|
        res |= id > 0 and $data_armors[id].guard_element_set.include?(b)})
      })
      return false
    # 地图不符的情况下,不能使用
    elsif not skill.pn_match?(skill.map_check, $game_map.map_id)
      return false
    # 地形不符的情况下,不能使用
    elsif not skill.pn_match?(skill.terrain_check, $game_player.terrain_tag)
      return false
    # 状态不符的情况下,不能使用
    elsif not skill.pn_match?(skill.state_check, self,
      Proc.new{|a, b| a.state?(b)})
      return false
    # 茂盛不符的情况下,不能使用
    elsif skill.bush_check != nil and
      skill.bush_check != ($game_player.bush_depth == 12)
      return false
    # 开关不符的情况下,不能使用
    elsif not skill.pn_match?(skill.switch_check, $game_switches,
      Proc.new{|a, b| a})
      return false
    # 战斗时,冷却中的情况下,不能使用
    elsif $game_temp.in_battle and cooldown?(skill_id)
      return false
    # 变量不符的情况下,不能使用
    elsif not skill.variable_match?
      return false
    # 道具不够的情况下,不能使用
    elsif not skill.item_match?(skill.item_cost,
      Proc.new{|n| $game_party.item_number(n)})
      return false
    # 武器不够的情况下,不能使用
    elsif not skill.item_match?(skill.weapon_cost,
      Proc.new{|n| $game_party.weapon_number(n)})
      return false
    # 防具不够的情况下,不能使用
    elsif not skill.item_match?(skill.armor_cost,
      Proc.new{|n| $game_party.armor_number(n)})
      return false
    # 公式计算为false或nil的情况下,不能使用
    elsif not skill.eval_match?(self)
      return false
    end
    # 进行原始判定
    sailcat_skillcost_skill_can_use?(skill_id)
  end
  #--------------------------------------------------------------------------
  # ● 清除冷却技能
  #--------------------------------------------------------------------------
  def reset_cooldown
    @cooldowns = {}
  end
  #--------------------------------------------------------------------------
  # ● 设置冷却技能
  #     skill_id : 特技 ID
  #--------------------------------------------------------------------------
  def set_cooldown(skill_id)
    if $data_skills[skill_id].cooldown > 0
      @cooldowns[skill_id] = $data_skills[skill_id].cooldown
    end
  end
  #--------------------------------------------------------------------------
  # ● 更新冷却技能,该方法一回合调用一次
  #--------------------------------------------------------------------------
  def update_cooldown
    @cooldowns.each_key {|k| @cooldowns[k] -= 1}
    @cooldowns.delete_if {|k, v| v == 0}
  end
  #--------------------------------------------------------------------------
  # ● 冷却中判定
  #     skill_id : 特技 ID
  #--------------------------------------------------------------------------
  def cooldown?(skill_id)
    @cooldowns.has_key?(skill_id)
  end
  #--------------------------------------------------------------------------
  # ● 使用技能的额外消耗
  #     skill : 特技 ID
  #--------------------------------------------------------------------------
  def skill_cost_extra(skill)
    super
    self.exp -= skill.exp_cost
    $game_party.lose_gold(skill.gold_cost)
    skill.item_cost.each {|i| $game_party.lose_item(i.id, i.number)}
    skill.weapon_cost.each {|i| $game_party.lose_weapon(i.id, i.number)}
    skill.armor_cost.each {|i| $game_party.lose_armor(i.id, i.number)}
    skill.variable_cost.each_pair {|k, v| $game_variables[k] -= v}
    set_cooldown(skill.id) if $game_temp.in_battle
  end
end
#==============================================================================
# ■ Game_Party
#==============================================================================
class Game_Party
  #--------------------------------------------------------------------------
  # ● 清除冷却技能
  #--------------------------------------------------------------------------
  def reset_cooldown
    actors.each {|a| a.reset_cooldown}
  end
  #--------------------------------------------------------------------------
  # ● 更新冷却技能,该方法一回合调用一次
  #--------------------------------------------------------------------------
  def update_cooldown
    actors.each {|a| a.update_cooldown}
  end
end
#==============================================================================
# ■ Scene_Battle
#==============================================================================
class Scene_Battle
  #--------------------------------------------------------------------------
  # ● 方法重定义
  #--------------------------------------------------------------------------
  unless method_defined? :sailcat_start_phase1
    alias sailcat_skillcost_start_phase1 start_phase1
    alias sailcat_skillcost_start_phase4 start_phase4
    alias sailcat_skillcost_make_skill_action_result make_skill_action_result
  end
  #--------------------------------------------------------------------------
  # ● 开始自由战斗回合
  #--------------------------------------------------------------------------
  def start_phase1
    # 调用原方法
    sailcat_skillcost_start_phase1
    # 清除技能冷却
    $game_party.reset_cooldown
  end
  #--------------------------------------------------------------------------
  # ● 开始主回合
  #--------------------------------------------------------------------------
  def start_phase4
    # 调用原方法
    sailcat_skillcost_start_phase4
    # 更新技能冷却
    $game_party.update_cooldown
  end
  #--------------------------------------------------------------------------
  # ● 生成特技行动结果
  #--------------------------------------------------------------------------
  def make_skill_action_result
    # 调用原方法
    sailcat_skillcost_make_skill_action_result
    # 额外消耗
    @active_battler.skill_cost_extra(@skill)
  end
end
#==============================================================================
# ■ Scene_Skill
#==============================================================================
class Scene_Skill
  #--------------------------------------------------------------------------
  # ● 刷新画面 (特技窗口被激活的情况下)
  #--------------------------------------------------------------------------
  def update_skill
    # 按下 B 键的情况下
    if Input.trigger?(Input::B)
      # 演奏取消 SE
      $game_system.se_play($data_system.cancel_se)
      # 切换到菜单画面
      $scene = Scene_Menu.new(1)
      return
    end
    # 按下 C 键的情况下
    if Input.trigger?(Input::C)
      # 获取特技窗口现在选择的特技的数据
      @skill = @skill_window.skill
      # 不能使用的情况下
      if @skill == nil or not @actor.skill_can_use?(@skill.id)
        # 演奏冻结 SE
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      # 演奏确定 SE
      $game_system.se_play($data_system.decision_se)
      # 效果范围是我方的情况下
      if @skill.scope >= 3
        # 激活目标窗口
        @skill_window.active = false
        @target_window.x = (@skill_window.index + 1) % 2 * 304
        @target_window.visible = true
        @target_window.active = true
        # 设置效果范围 (单体/全体) 的对应光标位置
        if @skill.scope == 4 || @skill.scope == 6
          @target_window.index = -1
        elsif @skill.scope == 7
          @target_window.index = @actor_index - 10
        else
          @target_window.index = 0
        end
      # 效果在我方以外的情况下
      else
        # 公共事件 ID 有效的情况下
        if @skill.common_event_id > 0
          # 预约调用公共事件
          $game_temp.common_event_id = @skill.common_event_id
          # 演奏特技使用时的 SE
          $game_system.se_play(@skill.menu_se)
          # 消耗 SP
          @actor.sp -= @skill.sp_cost
          # 额外的消耗
          @actor.skill_cost_extra(@skill)
          # 再生成各窗口的内容
          @status_window.refresh
          @skill_window.refresh
          @target_window.refresh
          # 切换到地图画面
          $scene = Scene_Map.new
          return
        end
      end
      return
    end
    # 按下 R 键的情况下
    if Input.trigger?(Input::R)
      # 演奏光标 SE
      $game_system.se_play($data_system.cursor_se)
      # 移至下一位角色
      @actor_index += 1
      @actor_index %= $game_party.actors.size
      # 切换到别的特技画面
      $scene = Scene_Skill.new(@actor_index)
      return
    end
    # 按下 L 键的情况下
    if Input.trigger?(Input::L)
      # 演奏光标 SE
      $game_system.se_play($data_system.cursor_se)
      # 移至上一位角色
      @actor_index += $game_party.actors.size - 1
      @actor_index %= $game_party.actors.size
      # 切换到别的特技画面
      $scene = Scene_Skill.new(@actor_index)
      return
    end
  end
  #--------------------------------------------------------------------------
  # ● 刷新画面 (目标窗口被激活的情况下)
  #--------------------------------------------------------------------------
  def update_target
    # 按下 B 键的情况下
    if Input.trigger?(Input::B)
      # 演奏取消 SE
      $game_system.se_play($data_system.cancel_se)
      # 删除目标窗口
      @skill_window.active = true
      @target_window.visible = false
      @target_window.active = false
      return
    end
    # 按下 C 键的情况下
    if Input.trigger?(Input::C)
      # 因为 SP 不足而无法使用的情况下
      unless @actor.skill_can_use?(@skill.id)
        # 演奏冻结 SE
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      # 目标是全体的情况下
      if @target_window.index == -1
        # 对同伴全体应用特技使用效果
        used = false
        for i in $game_party.actors
          used |= i.skill_effect(@actor, @skill)
        end
      end
      # 目标是使用者的情况下
      if @target_window.index <= -2
        # 对目标角色应用特技的使用效果
        target = $game_party.actors[@target_window.index + 10]
        used = target.skill_effect(@actor, @skill)
      end
      # 目标是单体的情况下
      if @target_window.index >= 0
        # 对目标角色应用特技的使用效果
        target = $game_party.actors[@target_window.index]
        used = target.skill_effect(@actor, @skill)
      end
      # 使用特技的情况下
      if used
        # 演奏特技使用时的 SE
        $game_system.se_play(@skill.menu_se)
        # 消耗 SP
        @actor.sp -= @skill.sp_cost
        # 额外的消耗
        @actor.skill_cost_extra(@skill)
        # 再生成各窗口内容
        @status_window.refresh
        @skill_window.refresh
        @target_window.refresh
        # 全灭的情况下
        if $game_party.all_dead?
          # 切换到游戏结束画面
          $scene = Scene_Gameover.new
          return
        end
        # 公共事件 ID 有效的情况下
        if @skill.common_event_id > 0
          # 预约调用公共事件
          $game_temp.common_event_id = @skill.common_event_id
          # 切换到地图画面
          $scene = Scene_Map.new
          return
        end
      end
      # 无法使用特技的情况下
      unless used
        # 演奏冻结 SE
        $game_system.se_play($data_system.buzzer_se)
      end
      return
    end
  end
end
[/pre]
[/fold]


写法示意:
p1.png
十字斩消耗1号防具1枚,必须在茂密处使用,不能在沉默时使用,冷却2回合,需要身上带有冰属性,消耗90金,消耗18HP,等等……

范例工程:
DataNoteEx.zip (211.74 KB, 下载次数: 270)



评分

参与人数 6星屑 +50 赞 +6 收起 理由
被礼赞的白杨 + 1 跪谢属于是
miantouchi + 1 发现宝藏了
灯笼菜刀王 + 1 精品文章
y967 + 1 精品文章
guoxiaomi + 50 + 1 我很赞同
hyrious + 1 塞糖

查看全部评分

SailCat (小猫子·要开心一点) 共上站 24 次,发表过 11 篇文章 上 次 在: [2006年01月28日11:41:18 星期六] 从 [162.105.120.91] 到本站一游。
梦石
0
星屑
395
在线时间
37 小时
注册时间
2017-2-18
回帖
1
发表于 2017-11-2 20:25:22 | 显示全部楼层
给力啊,很有意思的脚本
回复

使用道具 举报

遠航の猫咪

梦石
3
星屑
26947
在线时间
2423 小时
注册时间
2005-10-15
回帖
987

开拓者

 楼主| 发表于 2017-11-3 09:13:17 | 显示全部楼层
update了一些说明并补充了范例工程
SailCat (小猫子·要开心一点) 共上站 24 次,发表过 11 篇文章 上 次 在: [2006年01月28日11:41:18 星期六] 从 [162.105.120.91] 到本站一游。
回复

使用道具 举报

梦石
0
星屑
9557
在线时间
5074 小时
注册时间
2013-6-21
回帖
3459

开拓者贵宾剧作品鉴家

发表于 2017-11-3 10:19:54 | 显示全部楼层
这个集成的功能真心实用,期待后续反响。
回复

使用道具 举报

梦石
0
星屑
35248
在线时间
4171 小时
注册时间
2007-12-15
回帖
9489
发表于 2017-11-3 10:26:43 | 显示全部楼层
本帖最后由 89444640 于 2017-11-3 12:39 编辑

我感觉会跟技能分类脚本冲突……先试一下
临时整出来个技能,乾坤一掷,先测试固定数值金钱投掷造成伤害。
02.jpg
但是…
技能分类脚本是@+技能名字, 然后@后面的数据也给显示了出来,总算效果是正常,使用后金钱减少了固定的数值……但是显示不完美啊

01.jpg

请问该如何处理?

按照这个技能分类脚本的样子,恐怕,后面是数值不一样肯定会分类到单独的技能里去……除非就不分类了,按照普通技能算……

以下是技能分类脚本代码
技能分类脚本 战斗部分
[pre lang="ruby"] #本脚本来自www.66RPG.com
class Scene_Battle
#--------------------------------------------------------------------------
# ● 刷新画面 (角色命令回合 : 选择特技) ★★★★★★★★★★★★★★★★★
#--------------------------------------------------------------------------
def update_phase3_skill_select
   # 设置特技窗口为可视状态
   @skill_window.visible = true
   @itemcommand_window.visible = true
   @itemcommand_window.update
   if @command_index != @itemcommand_window.index
     @command_index = @itemcommand_window.index
     @skill_window.set_item(@itemcommand_window.commands[@command_index])
     @skill_window.index = 0
   end
   @skill_window.update
   # 按下 B 键的情况下
   if Input.trigger?(Input::B)
     # 演奏取消 SE
     $game_system.se_play($data_system.cancel_se)
     if @itemcommand_window.active==false
       @itemcommand_window.active = true
       @skill_window.active = false
       return
     end
     # 结束特技选择
     end_skill_select
     return
   end
   # 按下 C 键的情况下
   if Input.trigger?(Input::C)
     if @itemcommand_window.active
       @itemcommand_window.active = false
       @skill_window.active = true
       # 演奏确定 SE
       $game_system.se_play($data_system.decision_se)
       return
     end
     # 获取特技选择窗口现在选择的特技的数据
     @skill = @skill_window.skill
     # 无法使用的情况下
     if @skill == nil or not @active_battler.skill_can_use?(@skill.id)
       # 演奏冻结 SE
       $game_system.se_play($data_system.buzzer_se)
       return
     end
     # 演奏确定 SE
     $game_system.se_play($data_system.decision_se)
     # 设置行动
     @active_battler.current_action.skill_id = @skill.id
     # 设置特技窗口为不可见状态
     @skill_window.visible = false
     @itemcommand_window.visible = false
     # 效果范围是敌单体的情况下
     if @skill.scope == 1
       # 开始选择敌人
       start_enemy_select
     # 效果范围是我方单体的情况下
     elsif @skill.scope == 3 or @skill.scope == 5
       # 开始选择角色
       start_actor_select
     # 效果范围不是单体的情况下
     else
       # 选择特技结束
       end_skill_select
       # 转到下一位角色的指令输入
       phase3_next_actor
     end
     return
   end
end

#--------------------------------------------------------------------------
# ● 开始选择特技 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★
#--------------------------------------------------------------------------
def start_skill_select
   @skill_window = Liuliu_Window_SkillList.new(@active_battler)
   @skill_window.help_window = @help_window
   @itemcommand_window = Liuliu_Window_SkillCommand.new(@active_battler)
   @itemcommand_window.opacity = 160
   @itemcommand_window.y = 64
   @itemcommand_window.height -= 32
   @itemcommand_window.active = true
   @itemcommand_window.help_window = @help_window
   @skill_window.active = false
   @command_index = @itemcommand_window.index
   @skill_window.set_item(@itemcommand_window.commands[@command_index])
   @actor_command_window.active = false
   @actor_command_window.visible = false
end
#--------------------------------------------------------------------------
# ● 选择特技结束 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★
#--------------------------------------------------------------------------
def end_skill_select
   # 释放特技窗口
   @itemcommand_window.dispose
   @itemcommand_window = nil
   @skill_window.dispose
   @skill_window = nil
   # 隐藏帮助窗口
   @help_window.visible = false
   # 有效化角色指令窗口
   @actor_command_window.active = true
   @actor_command_window.visible = true
end
end
[/pre]



技能分类_常规部分 修改self.back_opacity
[pre lang="ruby"]#==============================================================================
# 本脚本来自www.66RPG.com,使用和转载请保留此信息
#==============================================================================


#==============================================================================
# ■ Liuliu_Window_SkillCommand
#==============================================================================

class Liuliu_Window_SkillCommand < Window_Selectable
attr_accessor :commands
#--------------------------------------------------------------------------
# ● 初始化,生成commands窗口
#--------------------------------------------------------------------------
  def initialize(actor)
  super(0, 0, 160, 288)
  self.z = 9999
  @commands = []
  #————————生成commands窗口
  for i in 0...actor.skills.size
    skill = $data_skills[actor.skills]
    if skill != nil
      push = true
      for com in @commands
        if com == skill.desc
          push = false
        end
      end
      if push == true
        @commands.push(skill.desc)
      end
    end
  end
  if @commands == []
    @commands.push("未分组技能")
  end      
  @item_max = @commands.size
  self.contents = Bitmap.new(width - 32, @item_max*32)
  refresh
  self.index = 0
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def refresh
   self.contents.clear
   for i in 0...@item_max
     draw_item(i, normal_color)
   end
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def draw_item(index, color)
   self.contents.font.color = color
   y = index * 32
   self.contents.draw_text(4, y, 128, 32, @commands[index])
   self.contents.draw_text(4, y, 128, 32, @commands[index])
end
#--------------------------------------------------------------------------
# 只描绘原文字
#--------------------------------------------------------------------------
def update_help
   @help_window.set_text(@commands[self.index])
end
end

#==============================================================================
# ■ Window_Skill
#==============================================================================

class Liuliu_Window_SkillList < Window_Selectable
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def initialize(actor)
   super(160, 0, 480, 416)
   @actor = actor
   refresh
   self.index = 0
   # 战斗中的情况下将窗口移至中央并将其半透明化
   if $game_temp.in_battle
     self.y = 64
     self.height = 256
     self.back_opacity = 160
     self.z = 9999 #此行为修改
   end
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def skill
   return @data[self.index]
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def refresh
   if self.contents != nil
     self.contents.dispose
     self.contents = nil
   end
   @data = []
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def set_item(command)
   refresh
   for i in 0...@actor.skills.size
     skill = $data_skills[@actor.skills]
     if skill != nil and skill.desc == command
       @data.push(skill)
     end
   end
   @item_max = @data.size
   if @item_max > 0
     self.contents = Bitmap.new(width - 32, row_max * 32)
     self.contents.clear
     for i in 0...@item_max
       draw_item(i)
     end
   end
end
#-----------------------------------------------------------------------
#--------------------------------------------------------------------------
def draw_item(index)
   skill = @data[index]
   if @actor.skill_can_use?(skill.id)
     self.contents.font.color = normal_color
   else
     self.contents.font.color = disabled_color
   end
   x = 4
   y = index * 32
   rect = Rect.new(x, y, self.width / @column_max - 32, 32)
   self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
   bitmap = RPG::Cache.icon(skill.icon_name)
   opacity = self.contents.font.color == normal_color ? 255 : 128
   self.contents.blt(x, y, bitmap, Rect.new(0, 0, 32, 32), opacity)
   self.contents.draw_text(x + 32, y, 204, 32, skill.name, 0)
   self.contents.draw_text(x + 390, y, 16, 32, ":", 1)
   self.contents.draw_text(x + 400, y, 40, 32, skill.sp_cost.to_s, 2)
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def update_help
   @help_window.set_text(self.skill == nil ? "" : self.skill.description)
end
end

#==============================================================================
# ■ Liuliu_Scene_Skill
#==============================================================================

class Scene_Skill
#--------------------------------------------------------------------------
# ● 初始化对像
#     actor_index : 角色索引
#--------------------------------------------------------------------------
def initialize(actor_index = 0)
   @actor_index = actor_index
   @actor = $game_party.actors[@actor_index]
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def main
   @status_window = Window_SkillStatus.new(@actor)
   @itemcommand_window = Liuliu_Window_SkillCommand.new($game_party.actors[@actor_index])
   @command_index = @itemcommand_window.index
   @skill_window = Liuliu_Window_SkillList.new($game_party.actors[@actor_index])
   @skill_window.active = false
   @help_window = Window_Help.new
   @help_window.x = 0
   @help_window.y = 416
   @itemcommand_window.help_window = @help_window
   @skill_window.help_window = @help_window
   @target_window = Window_Target.new
   @target_window.visible = false
   @target_window.active = false
   @skill_window.set_item(@itemcommand_window.commands[@command_index])
   Graphics.transition
   loop do
     Graphics.update
     Input.update
     update
     if $scene != self
       break
     end
   end
   Graphics.freeze
   @itemcommand_window.dispose
   @skill_window.dispose
   @status_window.dispose
   @help_window.dispose
   @target_window.dispose
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def update
   @itemcommand_window.update
   @skill_window.update
   @help_window.update
   @target_window.update
   if @command_index != @itemcommand_window.index
     @command_index = @itemcommand_window.index
     @skill_window.set_item(@itemcommand_window.commands[@command_index])
   end
   if @itemcommand_window.active
     update_itemcommand
     return
   end
   if @skill_window.active
     update_itemlist
     return
   end
   if @target_window.active
     update_target
     return
   end
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def update_itemcommand
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     $scene = Scene_Menu.new(0)
     return
   end
   if Input.trigger?(Input::C)
     $game_system.se_play($data_system.decision_se)
     @itemcommand_window.active = false
     @skill_window.active = true
     @skill_window.index = 0
     return
   end
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def update_itemlist
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     @itemcommand_window.active = true
     @skill_window.active = false
     @skill_window.index = 0
     @itemcommand_window.index = @command_index
     return
   end
   if Input.trigger?(Input::C)
     # 获取特技窗口现在选择的特技的数据
     @skill = @skill_window.skill
     # 不能使用的情况下
     if @skill == nil or not @actor.skill_can_use?(@skill.id)
       # 演奏冻结 SE
       $game_system.se_play($data_system.buzzer_se)
       return
     end
     # 演奏确定 SE
     $game_system.se_play($data_system.decision_se)
     # 效果范围是我方的情况下
     if @skill.scope >= 3
       # 激活目标窗口
       @skill_window.active = false
       @target_window.x = (@skill_window.index + 1) % 2 * 304
       @target_window.visible = true
       @target_window.active = true
       # 设置效果范围 (单体/全体) 的对应光标位置
       if @skill.scope == 4 || @skill.scope == 6
         @target_window.index = -1
       elsif @skill.scope == 7
         @target_window.index = @actor_index - 10
       else
         @target_window.index = 0
       end
     # 效果在我方以外的情况下
     else
       # 公共事件 ID 有效的情况下
       if @skill.common_event_id > 0
         # 预约调用公共事件
         $game_temp.common_event_id = @skill.common_event_id
         # 演奏特技使用时的 SE
         $game_system.se_play(@skill.menu_se)
         # 消耗 SP
         @actor.sp -= @skill.sp_cost
         # 再生成各窗口的内容
         @status_window.refresh
         @skill_window.refresh
         @target_window.refresh
         # 切换到地图画面
         $scene = Scene_Map.new
         return
       end
     end
     return
   end
end
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
def update_target
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     @skill_window.refresh
     @skill_window.active = true
     @target_window.visible = false
     @target_window.active = false
     @skill_window.set_item(@itemcommand_window.commands[@command_index])
     return
   end
   
   # 按下 C 键的情况下
   if Input.trigger?(Input::C)
     # 因为 SP 不足而无法使用的情况下
     unless @actor.skill_can_use?(@skill.id)
       # 演奏冻结 SE
       $game_system.se_play($data_system.buzzer_se)
       return
     end
     # 目标是全体的情况下
     if @target_window.index == -1
       # 对同伴全体应用特技使用效果
       used = false
       for i in $game_party.actors
         used |= i.skill_effect(@actor, @skill)
       end
     end
     # 目标是使用者的情况下
     if @target_window.index <= -2
       # 对目标角色应用特技的使用效果
       target = $game_party.actors[@target_window.index + 10]
       used = target.skill_effect(@actor, @skill)
     end
     # 目标是单体的情况下
     if @target_window.index >= 0
       # 对目标角色应用特技的使用效果
       target = $game_party.actors[@target_window.index]
       used = target.skill_effect(@actor, @skill)
     end
     # 使用特技的情况下
     if used
       # 演奏特技使用时的 SE
       $game_system.se_play(@skill.menu_se)
       # 消耗 SP
       @actor.sp -= @skill.sp_cost
       # 再生成各窗口内容
       @status_window.refresh
       #@skill_window.refresh
       @target_window.refresh
       # 全灭的情况下
       if $game_party.all_dead?
         # 切换到游戏结束画面
         $scene = Scene_Gameover.new
         return
       end
       # 公共事件 ID 有效的情况下
       if @skill.common_event_id > 0
         # 预约调用公共事件
         $game_temp.common_event_id = @skill.common_event_id
         # 切换到地图画面
         $scene = Scene_Map.new
         return
       end
     end
     # 无法使用特技的情况下
     unless used
       # 演奏冻结 SE
       $game_system.se_play($data_system.buzzer_se)
     end
     return
   end
end
end
#==============================================================================
# ■ Window_SkillStatus
#------------------------------------------------------------------------------
#  显示特技画面、特技使用者的窗口。
#==============================================================================

class Window_SkillStatus < Window_Base
#--------------------------------------------------------------------------
# ● 初始化对像
#     actor : 角色
#--------------------------------------------------------------------------
def initialize(actor)
   super(0, 288, 160, 128)
   self.contents = Bitmap.new(width - 32, height - 32)
   @actor = actor
   refresh
end
#--------------------------------------------------------------------------
# ● 刷新
#--------------------------------------------------------------------------
def refresh
   self.contents.clear
   draw_actor_name(@actor, 4, 0)
   draw_actor_hp(@actor, 4, 32, 120)
   draw_actor_sp(@actor, 4, 64, 120)
end
end

#==============================================================================
# ■ RPG追加定义,使用@符号分类
#==============================================================================

module RPG
class Skill
   def description
     description = @description.split(/@/)[0]
     return description != nil ? description : ''
   end
   def desc
     desc = @description.split(/@/)[1]
     return desc != nil ? desc : "普通技能"
   end
end
end

#==============================================================================
# 本脚本来自www.66RPG.com,使用和转载请保留此信息
#==============================================================================
[/pre]






回复

使用道具 举报

遠航の猫咪

梦石
3
星屑
26947
在线时间
2423 小时
注册时间
2005-10-15
回帖
987

开拓者

 楼主| 发表于 2017-11-3 13:31:41 | 显示全部楼层
398行以后冲突,大家都在用description备注信息不冲突才怪……
def description这个定义删掉
def desc改成
def desc; _dc("普通技能"); end

然后数据库里用#cg=1000;dc:技能分类
如果不想改技能分类写法那就只删掉def description定义

点评

你把def description删掉,把#cg=1000写到技能分类的@符号之前,再加一个半角分号试试看,即#cg=1000;@仙剑  发表于 2017-11-3 23:29
改成dc什么的技能分类全得重写,放弃,删了def description以后发现没什么变化,description = @description.split(/@/)[0]什么的是干啥用的。  发表于 2017-11-3 23:26
SailCat (小猫子·要开心一点) 共上站 24 次,发表过 11 篇文章 上 次 在: [2006年01月28日11:41:18 星期六] 从 [162.105.120.91] 到本站一游。
回复

使用道具 举报

梦石
0
星屑
35248
在线时间
4171 小时
注册时间
2007-12-15
回帖
9489
发表于 2017-11-3 23:46:52 | 显示全部楼层
本帖最后由 89444640 于 2017-11-4 08:03 编辑

改成了这样
module RPG
class Skill
def desc; _dc("普通技能");
  end
end
end
后果是菜单进不了,跳出这个
01.png

技能分类脚本也废了,只剩下一个普通技能。

def cooldown?(skill_id)
    @cooldowns.has_key?(skill_id)
  end

可能是共同占用了@造成的?
可否考虑整合一下技能分类脚本,加个新的定义项什么的,
因为这个脚本真的是不能舍弃的,技能多了归纳起来很方便。
是这样吗?
module RPG
class Skill
   def desc
     desc = @description.split(/@/)[1]
     return desc != nil ? desc : "普通技能"
   end
end
end
跟我这种程序一窍不通的说确实费力 辛苦了。战斗中的过去了,
01.png

但是菜单依然打不开,还是跳刚才那个错误


请看下脚本库,莫非其他什么奇怪地方调用造成的?
我回合制没设定过什么冷却啊。
错误出现的行数
01.png



点评

成功了!非常感谢,明天再继续测试别的可能出现问题的地方,辛苦了。  发表于 2017-11-4 00:25
找到了,把我的脚本里 elsif cooldown?(skill_id) 改成 elsif $game_temp.in_battle and cooldown?(skill_id) 我的问题  发表于 2017-11-4 00:19
莫非其他地方有调用?我给你那个sc什么脚本文件你看下吧  发表于 2017-11-4 00:15
set_cooldown(skill.id) if $game_temp.in_battle 有,新开游戏开菜单也是这个毛病。  发表于 2017-11-4 00:12
你查一下set_cooldown(skill.id)这句后面有没有 if $game_temp.in_battle,如果没有的话加上(同一行后面),最早我可能忘了写……  发表于 2017-11-4 00:08
回复

使用道具 举报

梦石
5
星屑
3525
在线时间
403 小时
注册时间
2016-6-25
回帖
217
发表于 2017-11-4 13:50:06 | 显示全部楼层
本帖最后由 零教授 于 2017-11-4 14:08 编辑
89444640 发表于 2017-11-3 10:26
我感觉会跟技能分类脚本冲突……先试一下
临时整出来个技能,乾坤一掷,先测试固定数值金钱投掷造成伤害。
...
技能分类.png 技能分类2.png

感谢层主提供的分类脚本

嘛因为我懒得新增一个窗口了所以借用了module做了个我自认为比较low的分类法
视觉和选择上麻烦了点但是放技能方便了一步,总而言之还是感谢提供思路

点评

按照顺序来的吗?技能看上去好复杂--,我这技能随着加,数据库类东西折腾不起啊  发表于 2017-11-4 18:22
横版类魂动作游戏《幻恋夜宴》好评发售中!https://store.steampowered.com/app/1684100
恋恋冒险CRPG《东方恋迷踪》~~火热开发中~~

回复

使用道具 举报

梦石
0
星屑
35248
在线时间
4171 小时
注册时间
2007-12-15
回帖
9489
发表于 2017-11-5 09:57:37 | 显示全部楼层
本帖最后由 89444640 于 2017-11-5 10:35 编辑

又出问题了- -b
01.png

没有设定任何特殊效果的技能,道具,总之一切分类后的道具,都会在末尾显示分类文字。
我试了一下,还得把所有道具都补个#才可以。
成百上千的手动改可够累人的。有办法批量处理一下吗--b

手动加吧--b,然后试了一下另外的效果。
技能依赖状态。
这是以前做好的,但是因为很多解决不了的问题只能凑合,各种恶心--b我为了调节平衡愣是说成喝酒醉了会掉血,然后本来是技能使用三回合后就不能用了,愣是说成可以多用一次……我这给逼成啥德行呜呜呜……(哭泣声)

醉仙望月步,只有在醉酒状态下才能使用,也就是说先要有个前置技能。
然后这个效果实现是用的上面那个好几千行的脚本,设定个技能有个特殊属性,攻击2次,持续4回合。效果如下。
大gif传不了怎么破?我随便找一个看看能不能看。

但是好像不给让普通攻击也是两次。因为普通攻击不算特技没法写注释?啊!好像可以注释到武器上……







点评

那就只能手动加了- -b上千个ORZ,个别的可能还字不够。  发表于 2017-11-5 10:23
rb的原贴见https://rpg.blue/thread-375515-1-1.html  发表于 2017-11-5 10:23
这就是通用备注插件和你那个物品分类插件的冲突了,用rb的话来说就是“以前的备注插件根本没考虑备注会一处多用的事”  发表于 2017-11-5 10:21
回复

使用道具 举报

梦石
0
星屑
2109
在线时间
242 小时
注册时间
2018-3-23
回帖
94
发表于 2018-3-28 22:11:40 | 显示全部楼层
有了超级版XP的感觉 感谢楼主分享
RMXP天下第一!
回复

使用道具 举报

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

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部