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

Project1

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

使用目标的扩展

[复制链接]

…あたしは天使なんかじゃないわ

梦石
0
星屑
2207
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

跳转到指定楼层
1
发表于 2014-12-14 19:18:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 taroxd 于 2015-1-18 17:31 编辑

RUBY 代码复制
  1. #--------------------------------------------------------------------------
  2. # ● require Taroxd基础设置
  3. #    设置技能、物品的使用目标。
  4. #--------------------------------------------------------------------------
  5. #
  6. # 使用方法:
  7. #   在技能/物品的备注栏写下类似于下面例子的备注。
  8. #   备注后,若效果范围为单体,则我方选择目标时只能从设置的目标中选择,
  9. #     敌人使用技能时随机选择其中一个。
  10. #   若效果范围为全体,则目标就是设置的目标。
  11. #   若效果范围为随机目标,则从设置的目标中随机选出指定的个数。
  12. #
  13. #   该脚本不影响菜单中使用技能/物品。
  14. #
  15. #   用 a 指代使用者,b 或 self 指代目标。
  16. #
  17. #   例1:存活队员中 hp 最小者。
  18. #   <target>
  19. #     select: alive?
  20. #     min_by: hp_rate
  21. #   </target>
  22. #
  23. #   例2:所有 hp 大于 50 的队员
  24. #   <target>
  25. #     select: hp > 50
  26. #   </target>
  27. #
  28. #   例3:除自己之外的全体队友
  29. #   <target>
  30. #     select: alive? && b != a
  31. #   </target>
  32. #
  33. #   例4:无视生死
  34. #   <target></target>
  35. #
  36. #--------------------------------------------------------------------------
  37.  
  38. # 模块方法用于解析备注栏中的备注
  39. # 实例方法用于战斗中技能目标的选择
  40. module Taroxd::TargetExt
  41.  
  42.   RE_OUTER = /<target>(.*?)<\/target>/mi # 整体设置
  43.   SEPARATOR = ':'                        # 每一行中的分隔符
  44.  
  45.   # 实例方法,用于选择目标的窗口中
  46.  
  47.   # 返回可以选择的所有目标
  48.   def targets_to_select
  49.     []
  50.   end
  51.  
  52.   # 返回设置的目标
  53.   # 若 actor 未初始化,或没有设置目标,返回 nil
  54.   def selectable_targets
  55.     actor = BattleManager.actor
  56.     return unless actor
  57.     item = actor.input.item
  58.     return unless item
  59.     item.get_targets(actor, targets_to_select)
  60.   end
  61.  
  62.   # 由于父类可能未定义,不调用 super
  63.   def enable?(battler)
  64.     !selectable_targets || selectable_targets.include?(battler)
  65.   end
  66.  
  67.   def current_item_enabled?
  68.     super && enable?(targets_to_select[index])
  69.   end
  70.  
  71.   # 模块方法,用于读取备注
  72.  
  73.   def self.parse_note(note)
  74.     note =~ RE_OUTER ? parse_settings($1) : false
  75.   end
  76.  
  77.   private
  78.  
  79.   # lambda do |battlers, a|
  80.   #   battlers.select { |b| b.instance_eval { alive? && b != a } }
  81.   # end
  82.   def self.parse_settings(settings)
  83.     eval %(
  84.       lambda do |battlers, a|
  85.         battlers#{extract_settings(settings)}
  86.       end
  87.     )
  88.   end
  89.  
  90.   def self.extract_settings(settings)
  91.     settings.each_line.map { |line|
  92.       method, _, block = line.partition(SEPARATOR).map(&:strip)
  93.       if method.empty?
  94.         ''
  95.       elsif block.empty?
  96.         ".#{method}"
  97.       else
  98.         ".#{method} { |b| b.instance_eval { #{block} } }"
  99.       end
  100.     }.join
  101.   end
  102.  
  103. end
  104.  
  105. class RPG::UsableItem < RPG::BaseItem
  106.  
  107.   # 缓存并返回生成的 lambda。
  108.   # 如果不存在,返回 nil。
  109.   def get_target_lambda
  110.     @get_target = Taroxd::TargetExt.parse_note(@note) if @get_target.nil?
  111.     @get_target if @get_target
  112.   end
  113.  
  114.   # 返回目标的数组。a:使用者。
  115.   # 如果没有设置,返回 nil。
  116.   def get_targets(a, battlers = nil)
  117.     return unless get_target_lambda
  118.     battlers ||= (for_friend? ? a.friends_unit : a.opponents_unit).members
  119.     Array(get_target_lambda.call(battlers, a))
  120.   end
  121.  
  122. end
  123.  
  124. class Game_Action
  125.  
  126.   def_chain :targets_for_opponents do |old|
  127.     targets = item.get_targets(@subject)
  128.     if !targets
  129.       old.call
  130.     elsif item.for_random?
  131.       Array.new(item.number_of_targets) { random_target(targets) }
  132.     elsif item.for_one?
  133.       num = 1 + (attack? ? subject.atk_times_add.to_i : 0)
  134.       target = if @target_index < 0
  135.         random_target(targets)
  136.       else
  137.         eval_smooth_target(opponents_unit, @target_index)
  138.       end
  139.       Array.new(num, target)
  140.     else
  141.       targets
  142.     end
  143.   end
  144.  
  145.   def_chain :targets_for_friends do |old|
  146.     targets = item.get_targets(@subject)
  147.     if !targets
  148.       old.call
  149.     elsif item.for_user?
  150.       [subject]
  151.     else
  152.       if item.for_one?
  153.         if @target_index < 0
  154.           [random_target(targets)]
  155.         else
  156.           [eval_smooth_target(friends_unit, @target_index)]
  157.         end
  158.       else
  159.         targets
  160.       end
  161.     end
  162.   end
  163.  
  164.   private
  165.  
  166.   def eval_smooth_target(unit, index)
  167.     unit[index] || unit[0]
  168.   end
  169.  
  170.   def random_target(targets)
  171.     tgr_rand = rand * targets.sum(&:tgr)
  172.     targets.each do |target|
  173.       tgr_rand -= target.tgr
  174.       return target if tgr_rand < 0
  175.     end
  176.     targets.first
  177.   end
  178. end
  179.  
  180. class Game_BattlerBase
  181.   # 如果设置了目标,必须存在目标才可使用
  182.   def_and :usable_item_conditions_met? do |item|
  183.     targets = item.get_targets(self)
  184.     !targets || !targets.empty?
  185.   end
  186. end
  187.  
  188. class Game_Battler < Game_BattlerBase
  189.   # 如果设置了目标,删除是否死亡的测试
  190.   def_chain :item_test do |old, user, item|
  191.     if item.get_target_lambda
  192.       return true if $game_party.in_battle
  193.       return true if item.for_opponent?
  194.       return true if item.damage.recover? && item.damage.to_hp? && hp < mhp
  195.       return true if item.damage.recover? && item.damage.to_mp? && mp < mmp
  196.       return true if item_has_any_valid_effects?(user, item)
  197.       false
  198.     else
  199.       old.call(user, item)
  200.     end
  201.   end
  202. end
  203.  
  204. class Window_BattleActor < Window_BattleStatus
  205.  
  206.   include Taroxd::TargetExt
  207.  
  208.   def targets_to_select
  209.     $game_party.battle_members
  210.   end
  211.  
  212.   def draw_actor_name(actor, x, y, width = 112)
  213.     change_color(hp_color(actor), enable?(actor))
  214.     draw_text(x, y, width, line_height, actor.name)
  215.   end
  216. end
  217.  
  218. class Window_BattleEnemy < Window_Selectable
  219.  
  220.   include Taroxd::TargetExt
  221.  
  222.   def targets_to_select
  223.     $game_troop.alive_members
  224.   end
  225.  
  226.   def draw_item(index)
  227.     enemy = $game_troop.alive_members[index]
  228.     change_color(normal_color, enable?(enemy))
  229.     name = enemy.name
  230.     draw_text(item_rect_for_text(index), name)
  231.   end
  232.  
  233. end

评分

参与人数 2星屑 +1 梦石 +1 收起 理由
chd114 + 1 难道这个不是目标对象的扩展吗···.
VIPArcher + 1 认可答案

查看全部评分

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

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

GMT+8, 2024-5-1 12:43

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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