注册会员 登录
Project1 返回首页

鼠窝 https://rpg.blue/?335626 [收藏] [复制] [分享] [RSS] ~外站脚本图书馆~

日志

敌人AI

已有 338 次阅读2014-5-17 13:42 |个人分类:外站脚本

#===============================================================================
# Enemy AI : Targeting Priority Manipulator
#   by Shad3Light
#
# 2014/03/20
# Link: http://shad3light.blogspot.com/2014/03/enemy-ai-targeting-priority-manipulator.html
#===============================================================================
 
 
=begin
================================================================================
Description
 
The default VX Ace's enemy targeting behavior just pick a random target for
any actions.
This script adds some AI targeting priority. With this script, the enemies
become able to pick a target based on the action specific priority.
 
--------------------------------------------------------------------------------
History
 
v1.0 (2014/03/20)
  Initial release
   
--------------------------------------------------------------------------------
Terms of Use
 
- You are free to use this script for non-commercial projects.
- For commercial projects, at least contact me first.
- This script is provided as-is. Don't expect me to give support.
- Reported bug will be fixed, but no guarantee on requested features.
- No guarantee either for compatibility fixes.
- Give credit to Shad3Light (me), and do not delete this header.
--------------------------------------------------------------------------------
Installation
 
Put this script below ¥ Materials and above ¥ Main Process.
If there are scripts that overwrite the aliased methods below,
put this script below said script.
--------------------------------------------------------------------------------
Usage
 
In an enemy notebox, you can add some tags.
  <target [action_id] [shortcut]>
where [action_id] corresponds to the enemy's action list, and [shortcut] 
corresponds to one of the implemented targeting priority method.
 
Example:
  <target 1 high_hp>
This will make the enemy target the battlers with the highest HP value when
using action number 1 (by default Attack).
   
  <target 2 low_hp_rate>
This will make the enemy target the battler with the lowest HP percentage when
using action number 2. If the action no. 2 is set to Heal, the enemy will 
proceed to heal its ally with the lowest percentage of health.
 
Available targeting shortcut is as follows:
  low_hp
  high_hp
  low_hp_rate
  high_hp_rate
  low_mp
  high_mp
  low_mp_rate
  high_mp_rate
  low_tp
  high_tp
  low_tp_rate
  high_tp_rate
  self
  not_self
   
If you want to make your own targeting condition, use
  <target eval [action_id]>
  [eval]
  </target eval>
where [eval] is a ruby expression that takes returns -1, 0, or 1.
In the eval, a and b denotes the battlers that would be sorted.
 
For example, to make the enemy prioritize Eric when doing its ultimate skill,
the tag will be
  <target eval 8>
  if a.name == "Eric"
    -1
  elsif b.name == "Eric"
    1
  else
    a.hp <=> b.hp
  end
  </target eval>
 
 
Do note that target selection is done at the start of the turn, like actors.
The enemy will not suddenly change target mid-turn, for example if its target
had already healed.
Also, TGR have no effect on acquiring target.
================================================================================
=end
 
if $imported && $imported[:SHD_TargetingManipulator]
  msgbox "Warning: Targeting Priority Manipulator script is imported twice."
else
 
$imported = {} if $imported.nil?
$imported[:SHD_TargetingManipulator] = true
 
#===============================================================================
# Configuration Module
#
# None.
#
# Configuration Module End
#===============================================================================
 
#===============================================================================
# Code Start
#   Configuration ends here. Edit what's below at your own risk.
#-------------------------------------------------------------------------------
# Aliased methods:
#   DataManager
#     self.load_database
#   Game_Action
#     set_enemy_action
#
# New methods:
#   DataManager
#     self.load_notetags_adv_ai_target
#   RPG::Enemy
#     load_notetags_adv_ai_target
#   RPG::Enemy::Action
#     targeting_shortcut (attr_reader)
#     targeting_shortcut=
#     targeting_eval (attr_reader)
#     targeting_eval=
#     use_adv_targeting?
#   Game_Action
#     set_ai_target
#     set_ai_opponent_target
#     set_ai_friend_target
#     ai_sorting
#     ai_sorting_extension
#===============================================================================
   
#-------------------------------------------------------------------------------
# Module SHD
# Mainly contains Regular Expressions.

module SHD
   
  module REGEXP
    ENEMY_TARG_EVAL = /<targ(?:et){,1}?[-_ ]?eval[: ]+(\d+)[ ]*>(.*?)<\/targ(:?et){,1}?[-_ ]?eval>/im
    ENEMY_TARG_SHORTCUT = /<targ(?:et){,1}?[: ]+(\d+)[, ]+(\w+)>/i
  end
   
end

# End Module SHD
#-------------------------------------------------------------------------------
 
 
#-------------------------------------------------------------------------------
# Module DataManager
# Adding methods for reading enemy notetags.

module DataManager
   
  class <<self
    alias :load_database_adv_ai_target :load_database
  end
   
  def self.load_database
    load_database_adv_ai_target
    load_notetags_adv_ai_target
  end
   
  def self.load_notetags_adv_ai_target
    $data_enemies.each do |o|
      next if o.nil?
      o.load_notetags_adv_ai_target
    end
  end
   
end

# End Module DataManager
#-------------------------------------------------------------------------------
 
 
#-------------------------------------------------------------------------------
# Class RPG::Enemy

class RPG::Enemy < RPG::BaseItem
   
  def load_notetags_adv_ai_target
    self.note.split(/[\r\n]+/).each { |line|
      if line =~ SHD::REGEXP::ENEMY_TARG_SHORTCUT
        action_id = $1.to_i - 1
        if @actions[action_id]
          @actions[action_id].targeting_shortcut = $2.downcase.to_sym
        end
      end
    }
    self.note.scan(SHD::REGEXP::ENEMY_TARG_EVAL).each { |match|
      action_id = match[0].to_i - 1
      if @actions[action_id]
        @actions[action_id].targeting_eval = match[1]
      end
    }
  end
   
end

# End Class RPG::Enemy
#-------------------------------------------------------------------------------
 
 
#-------------------------------------------------------------------------------
# Class RPG::Enemy::Action

class RPG::Enemy::Action
   
  attr_reader :targeting_shortcut
  attr_reader :targeting_eval
   
  def use_adv_targeting?
    @use_adv_targeting
  end
   
  def targeting_shortcut=(symbol)
    @targeting_shortcut = symbol
    @use_adv_targeting = true
  end
   
  def targeting_eval=(string)
    @targeting_shortcut = :eval
    @targeting_eval = string
    @use_adv_targeting = true
  end
   
end

# End Class RPG::Enemy::Action
#-------------------------------------------------------------------------------
 
 
#-------------------------------------------------------------------------------
# Class Game_Action

class Game_Action
   
  #-----------------------------------------------------------------------------
  # Alias Method: set_enemy_action
  # 
  alias :set_enemy_action_ai_prio :set_enemy_action
  def set_enemy_action(action)
    set_enemy_action_ai_prio(action)
    set_ai_target(action) if action
  end
   
  #-----------------------------------------------------------------------------
  # New Method: set_ai_target
  # 
  def set_ai_target(action)
    return unless action.use_adv_targeting?
    if item.for_opponent?
      set_ai_opponent_target(action)
    elsif item.for_friend?
      set_ai_friend_target(action)
    end
  end
   
  #-----------------------------------------------------------------------------
  # New Method: set_ai_opponent_target
  # 
  def set_ai_opponent_target(action)
    candidates = opponents_unit.alive_members
    candidates.sort! { |a, b| ai_sorting(a, b, action) }
    @target_index = candidates[0].index
  end
   
  #-----------------------------------------------------------------------------
  # New Method: set_ai_friend_target
  # 
  def set_ai_friend_target(action)
    if item.for_dead_friend?
      candidates = friends_unit.dead_members
    else
      candidates = friends_unit.alive_members
    end
    candidates.sort! { |a, b| ai_sorting(a, b, action) }
    @target_index = candidates[0].index
  end
   
  #-----------------------------------------------------------------------------
  # New Method: ai_sorting
  # 
  def ai_sorting(a, b, action)
    case action.targeting_shortcut
       
    when :low_hp
      return a.hp <=> b.hp
       
    when :high_hp
      return b.hp <=> a.hp
       
    when :low_hp_rate
      return a.hp_rate <=> b.hp_rate
       
    when :high_hp_rate
      return b.hp_rate <=> a.hp_rate
       
    when :low_mp
      return a.mp <=> b.mp
       
    when :high_mp
      return b.mp <=> a.mp
       
    when :low_mp_rate
      return a.mp_rate <=> b.mp_rate
       
    when :high_mp_rate
      return b.mp_rate <=> a.mp_rate
       
    when :low_tp
      return a.tp <=> b.tp
       
    when :high_tp
      return b.tp <=> a.tp
       
    when :low_tp_rate
      return a.tp_rate <=> b.tp_rate
       
    when :high_tp_rate
      return b.tp_rate <=> a.tp_rate
       
    when :self
      return a == subject ? -1 : rand(2)
       
    when :not_self
      return a != subject ? rand(2) - 1 : 1
       
    when :eval
      return eval(action.targeting_eval)
       
    else
      return ai_sorting_extension(a, b, action)
       
    end
  end
   
  #-----------------------------------------------------------------------------
  # New Method: ai_sorting_extension
  # To be aliased by script extensions.
  # 
  def ai_sorting_extension(a, b, action)
    return 0
  end
   
end

# End Class Game_Action
#-------------------------------------------------------------------------------
 
end #if $imported

鸡蛋

鲜花

评论 (0 个评论)

facelist doodle 涂鸦笔

您需要登录后才可以评论 登录 | 注册会员

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

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

GMT+8, 2024-4-28 22:00

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

返回顶部