赞 | 170 |
VIP | 6 |
好人卡 | 208 |
积分 | 229 |
经验 | 137153 |
最后登录 | 2024-10-31 |
在线时间 | 8633 小时 |
Lv5.捕梦者
- 梦石
- 0
- 星屑
- 22873
- 在线时间
- 8633 小时
- 注册时间
- 2011-12-31
- 帖子
- 3367
|
叧一个- #==============================================================================
- # ** TDS Custom Action AI (Skill Use AI)
- # Ver: 1.4 BETA
- #------------------------------------------------------------------------------
- # * Description:
- # This script allows you to set requirements for enemies to use skills. Such
- # as its target not having a certain state or its HP being above a certain
- # value
- #------------------------------------------------------------------------------
- # * Features:
- # Adds a simple AI to enemies to decide which skill to use.
- #------------------------------------------------------------------------------
- # * Instructions:
- # To add AI to a skill, put this in the enemy's notebox:
- #
- # <Skill_Use_AI: ID>
- # AI_TAGS
- # </skill_use_AI>
- #
- # ID = Is the ID of the skill to apply the AI to.
- # AI_TAGS = These are the tags that determine how the AI for the skill will
- # work. A list is below.
- #
- # Examples:
- #
- # Here are some examples of AI based on certain scenarios. (The default RMVXACE
- # is used for them)
- #
- # Scenario:
- # The enemy has the skill "Heal II" (ID 27) and only wants to use it on
- # targets that do not have full HP. It also wants to select whoever has
- # the least HP to heal them.
- #
- # Here is how it would translate into tags.
- #
- # <Skill_Use_AI: 27>
- # Remove_If: (t.hp_rate * 100) == 100
- # Sort_by: t.hp_rate
- # Select_First
- # </Skill_Use_AI>
- #
- #
- # Scenario:
- # The enemy has the skill "Poison" (ID 27) and only wants to use it on
- # targets that are not already afflicted with the state Poison (ID 2). It
- # also wants to select whoever has the highest HP.
- #
- # Here is how it would translate into tags.
- #
- # <Skill_Use_AI: 35>
- # Remove_If: t.state?(2)
- # Sort_by: t.hp
- # Select_First
- # </Skill_Use_AI>
- #
- #------------------------------------------------------------------------------
- # * AI Commands List:
- #------------------------------------------------------------------------------
- # Condition Shorcuts:
- # Some tags use conditions as part of their process and these are some
- # shorcuts to relevant objects such as targets, user, switches and variables.
- #------------------------------------------------------------------------------
- # t = Target within a block of code of targets array.
- # u = Action AI user. (Battler that is processing skill AI)
- # s = Switches. (s[1] would be the same as Switch ID 1 or $game_switches[1])
- # v = Variables. (v[1] would be the same as Variable ID 1 or $game_variables[1])
- #
- # Examples:
- # t.hp (This would get you the HP of a target)
- # s[1] == true (This would be true if Switch ID 1 is ON)
- # v[10] < 100 (This would be true if the value of Variable ID 1 is less than 100)
- #
- #------------------------------------------------------------------------------
- # Requirements:
- # Requirement tags are required parameters from the user in order to use the
- # skill.
- #------------------------------------------------------------------------------
- # Required_Turn: Turn_A, Turn_B
- # Req_HP/MP: Min, Max
- # ^ HP/MP Should be replaced with either.
- # ^ Min and Max are the ranges the HP or MP must be between. (As Float values)
- # ^ Example: Req_HP: 0.5, 1.0
- #
- # Required_State: State_ID
- # Required_Party_Level: Level
- # Required_Switch: Switch_ID, State
- # ^ State is the state of the switch to check (ON or OFF)
- #
- # Require: Condition
- # ^ Require that Condition code is true.
- #
- # TRequire(_ALL):
- # ^ Targets must meet required conditions.
- # ^ If _All is part of the tag then all targets must meet the condition.
- # ^ Example: TRequire: t.hp > 100 or TRequire_All: t.hp < 100
- #------------------------------------------------------------------------------
- # Remove:
- # Remove tags remove targets if the tag requirements are met.
- #------------------------------------------------------------------------------
- # TRemove_If: Condition
- # ^ Remove target if conditions code is true.
- # ^ Example: t.hp > 100
- #
- #------------------------------------------------------------------------------
- # Select:
- # Select tags allow you select a specific target if necessary.
- #------------------------------------------------------------------------------
- # Sort_By: Condition
- # ^ Sorts targets by condition code. (Must be a comparable value)
- # ^ This tag is meant to be used with others like "Select_First/Last"
- #
- # Select_(First/Last)(: Min)
- # ^ First/Last Should be replaced with either for selection.
- # ^ Min is the minimun amount of random targets to select. (Optional)
- # ^ Example: Select_First or Select_First: 2
- #
- # Select_Default
- # ^ Selects amounts of targets based on the scope of the skill.
- #
- # Select_If: Condition
- # ^ Select Targets if condition code is true.
- # ^ Example: t.id == 20
- #
- # Select_Random(: Min)
- # ^ Min is the minimun amount of random targets to select. (Optional)
- # ^ If no value is used then the default 1 will be used.
- # ^ Example: Select_Random or Select_Random: 3
- #
- # Select_Targeting_User
- # ^ Selects targets whose actions are targeting the AI user.
- #
- #------------------------------------------------------------------------------
- # * Notes:
- # None.
- #------------------------------------------------------------------------------
- # WARNING:
- #
- # Do not release, distribute or change my work without my expressed written
- # consent, doing so violates the terms of use of this work.
- #
- # If you really want to share my work please just post a link to the original
- # site.
- #
- # * Not Knowing English or understanding these terms will not excuse you in any
- # way from the consequenses.
- #==============================================================================
- # * Import to Global Hash *
- #==============================================================================
- ($imported ||= {})[:TDS_Custom_Action_AI] = true
- #==============================================================================
- # ** Scene_Battle
- #------------------------------------------------------------------------------
- # This class performs battle screen processing.
- #==============================================================================
- class Scene_Battle < Scene_Base
- #--------------------------------------------------------------------------
- # * Alias Listing
- #--------------------------------------------------------------------------
- alias tds_custom_action_ai_scene_battle_execute_action execute_action
- #--------------------------------------------------------------------------
- # * Execute Battle Actions
- #--------------------------------------------------------------------------
- def execute_action
- # Evaluate Enemy Battle AI
- evaluate_custom_action_ai(@subject) if @subject.enemy?
- # Run Original Method
- tds_custom_action_ai_scene_battle_execute_action
- end
- #--------------------------------------------------------------------------
- # * Evaluate Custom Action Battle AI
- #--------------------------------------------------------------------------
- def evaluate_custom_action_ai(battler)
- # Return if Battler is nil or Subject is not an enemy
- return if battler.nil?
- # Create AI Targets
- @ai_targets = []
- # Selected Skill
- skill = nil
- # Get All Battler Custom Skill AI
- ai_actions = battler.all_custom_skill_ai
- # Go Through AI Actions
- ai_actions.each {|a|
- # Get Skill Object
- skill = $data_skills[a.at(0)]
- # Next if Skill is not usable
- next if !battler.usable?(skill)
- # Process Battle Action AI
- break if process_battle_action_ai(battler, skill, a.at(1))
- }
- # Set Current Action to Selected Skill
- battler.current_action.set_skill(skill.id) if !skill.nil?
- # Set Current Action Custom Action AI Targets
- battler.current_action.custom_action_ai_targets = @ai_targets
- end
- #--------------------------------------------------------------------------
- # * Conver Match String value to proper Numerical
- #--------------------------------------------------------------------------
- def convert_match_value(string)
- # Return if string is not a number
- return nil if !(string =~ /^\d+/)
- # Convert String to float if it contains a period
- return string.to_f if string =~ /\./
- # Convert String to integer
- return string.to_i
- end
- #--------------------------------------------------------------------------
- # * Process Battle Action AI
- #--------------------------------------------------------------------------
- def process_battle_action_ai(battler, skill, ai_list)
- # Clear AI Targets
- @ai_targets.clear
- # Return if AI List is empty
- return true if ai_list.empty?
- # Get Targets Avaiable for skill
- @ai_targets = skill.for_opponent? ? battler.opponents_unit.members.dup : battler.friends_unit.members.dup
- # Delete Dead Members if Skill is not for dead friends
- @ai_targets.delete_if {|t| t.dead? and !skill.for_dead_friend?}
- # Go Through AI List
- ai_list.each {|ai|
- # Process Required, Remove and Select Action AI Tags
- process_battle_required_action_ai(battler, skill, ai) if !@ai_targets.empty?
- process_battle_remove_action_ai(battler, skill, ai) if !@ai_targets.empty?
- process_battle_select_action_ai(battler, skill, ai) if !@ai_targets.empty?
- # Break if Targets is empty
- break if @ai_targets.empty?
- }
- # Return if AI Targets is empty
- return false if @ai_targets.empty?
- # Return true
- return true
- end
- #--------------------------------------------------------------------------
- # * [Required] Process Battle Action AI
- #--------------------------------------------------------------------------
- def process_battle_required_action_ai(battler, skill, ai)
- # Set Object Shorcuts
- v = $game_variables ; s = $game_switches ; u = battler
- # AI Case
- case ai
- # Require User conditions are met. (Condition)
- when /\bRequire\b: (?'condition'.+)/i
- # Get Match Information
- m = Regexp.last_match
- # Clear AI Targets (Breaking Loop)
- @ai_targets.clear if !eval(m[:condition])
- # Require Target conditions are met for one or all targets. (Condition)
- when /\bTRequire[_]?(?'con'ALL)?: (?'condition'.+)/i
- # Get Match Information
- m = Regexp.last_match
- # Clear AI Targets (Breaking Loop)
- @ai_targets.clear if m[:con] =~ /ALL/i and !@ai_targets.all? {|t| eval(m[:condition])}
- @ai_targets.clear if m[:con].nil? and !@ai_targets.any? {|t| eval(m[:condition])}
- # Required Turn to use skill (Turn A, Turn B)
- when /Required_Turn: (?'turn_a'[\d]+), (?'turn_b'[\d]+)/i
- # Get Match Information
- m = Regexp.last_match
- # Get Turns and A & B Parameters
- n = $game_troop.turn_count ; a = m[:turn_a].to_i ; b = m[:turn_b].to_i
- # Clear AI Targets (Breaking Loop)
- @ai_targets.clear if (b == 0 and n != a) or (b > 0 and (n < 1 or n < a or n % b != a % b))
- # Required HP/MP to use skill (Min, Max) rates
- when /Required_(?'type'HP|MP): (?'min'[\.\d]+), (?'max'[\.\d]+)/i
- # Get Match Information
- m = Regexp.last_match
- # Get Converted String Values
- min = convert_match_value(m[:min]) ; max = convert_match_value(m[:max])
- # Clear All AI Targets (Breaking the loop)
- @ai_targets.clear if m[:type] =~ /HP/i and !battler.hp_rate.between?(min, max)
- @ai_targets.clear if m[:type] =~ /MP/i and !battler.mp_rate.between?(min, max)
- # Required State to have to use the skill (State ID)
- when /Required_State: (?'id'[\d]+)/i
- # Get Match Information
- m = Regexp.last_match
- # Clear All AI Targets (Breaking the loop)
- @ai_targets.clear if !battler.state?(m[:id].to_i)
- # Minimun Party Level Required to use the skill (Level)
- when /Required_Party_Level: (?'level'[\d]+)/i
- # Get Match Information
- m = Regexp.last_match
- # Clear All AI Targets (Breaking the loop)
- @ai_targets.clear if $game_party.highest_level < m[:level].to_i
- # Required Active Switch to use the skill (Switch ID, State)
- when /Required_Switch: (?'id'[\d]+), (?'state'[ON|OFF]+)/i
- # Get Match Information
- m = Regexp.last_match
- # Clear All AI Targets (Breaking the loop)
- @ai_targets.clear if m[:state] =~ /ON/i and $game_switches[m[:id].to_i] == false
- @ai_targets.clear if m[:state] =~ /OFF/i and $game_switches[m[:id].to_i] == true
- # Require Variable conditions are met. (Condition)
- when /Required_Variable: (?'condition'.+)/i
- # Get Match Information
- m = Regexp.last_match
- # Clear AI Targets (Breaking Loop)
- @ai_targets.clear if !eval(m[:condition])
- # Require Code conditions are met. (Condition)
- when /Required_Code: (?'condition'.+)/
- # Get Match Information
- m = Regexp.last_match
- # Clear AI Targets (Breaking Loop)
- @ai_targets.clear if !eval(m[:condition])
- end
- end
- #--------------------------------------------------------------------------
- # * [Remove] Process Battle Action AI
- #--------------------------------------------------------------------------
- def process_battle_remove_action_ai(battler, skill, ai)
- # Set Object Shorcuts
- v = $game_variables ; s = $game_switches ; u = battler
- # AI Case
- case ai
- # Remove Dead Targets
- when /Remove_Dead/i ; @ai_targets.delete_if {|t| t.dead?}
- # Remove Alive Targets
- when /Remove_Alive/i ; @ai_targets.delete_if {|t| t.alive?}
- # Remove Target if conditions are met. (Condition)
- when /Remove_If: (?'condition'.+)/i
- # Get Match Information
- m = Regexp.last_match
- # Process Target Removal Condition
- @ai_targets.delete_if {|t| eval(m[:condition])}
- end
- end
- #--------------------------------------------------------------------------
- # * [Select] Process Battle Action AI
- #--------------------------------------------------------------------------
- def process_battle_select_action_ai(battler, skill, ai)
- # Set Object Shorcuts
- v = $game_variables ; s = $game_switches ; u = battler
- # AI Case
- case ai
- # Sort Targets Array by condition
- when /Sort_by: (?'condition'.+)/i
- # Get Match Information
- m = Regexp.last_match
- # Sort Targets Array
- @ai_targets.sort_by! {|t| eval(m[:condition])}
- # Select Targets by Default Targetting Scope (Skill Range)
- when /Select_Default/i
- # Select User As Target if skill is for user
- @ai_targets = [battler] if skill.for_user?
- # If Skill is for one target (Select one randomly)
- @ai_targets = [@ai_targets.sample] if skill.for_one?
- # Select Random Targets
- @ai_targets = [@ai_targets.sample(skill.number_of_targets)].flatten if skill.for_random?
- # Select First or Last Targets in the Targets Array (Min Amount to Select)
- when /Select_(?'type'First|Last)[:]?(?'min'\s\d+)?/i
- # Get Match Information
- m = Regexp.last_match
- # Get First Targets from Target Array
- @ai_targets = @ai_targets.take([m[:min].to_i, 1].max) if m[:type] =~ /First/i
- # Get Last Targets from Target Array
- @ai_targets = @ai_targets.reverse.take([m[:min].to_i, 1].max) if m[:type] =~ /Last/i
- # Select Target if conditions are met. (Condition)
- when /Select_If: (?'condition'.+)/i
- # Get Match Information
- m = Regexp.last_match
- # Process Target Selection Condition
- @ai_targets.select! {|t| eval(m[:condition])}
- # Select Random Target (Min Random value)
- when /Select_Random[:]?(?'min'\s\d+)?/i
- # Get Match Information
- m = Regexp.last_match
- # Get Random AI Targets
- @ai_targets = [@ai_targets.sample([m[:min].to_i, 1].max)].flatten
- # Select Targets that are targeting the user with their action
- when /Select_Targeting_User/i
- # Get Match Information
- m = Regexp.last_match
- # Get Random AI Targets
- @ai_targets.select! {|t| t.targeting_battler?(battler)}
- end
- end
- end
- #==============================================================================
- # ** Game_Battler
- #------------------------------------------------------------------------------
- # A battler class with methods for sprites and actions added. This class
- # is used as a super class of the Game_Actor class and Game_Enemy class.
- #==============================================================================
- class Game_Battler < Game_BattlerBase
- #--------------------------------------------------------------------------
- # * Get Battler Note Text
- #--------------------------------------------------------------------------
- def note ; return actor.note if actor? ; return enemy.note if enemy? ; '' end
- #--------------------------------------------------------------------------
- # * Get Battler ID
- #--------------------------------------------------------------------------
- def id ; actor.id if actor? ; enemy.enemy_id if enemy? end
- #--------------------------------------------------------------------------
- # * Get Battler Battle Actions
- #--------------------------------------------------------------------------
- def battle_actions
- return enemy.actions if enemy?
- []
- end
- #--------------------------------------------------------------------------
- # * Get Custom Skill AI Array
- # skill_id : ID of skill to check
- #--------------------------------------------------------------------------
- def custom_skill_ai(skill_id)
- # Match text to Get Custom AI for Skill Use
- note[/\<Skill_Use_AI: [#{skill_id}]+\>(.+?)<\/[^>]+>/im]
- # Return Match Stripped and Separated into individual lines
- return $1.nil? ? [] : $1.strip.split(/\r\n/)
- end
- #--------------------------------------------------------------------------
- # * Get All Custom Skill AI Array
- #--------------------------------------------------------------------------
- def all_custom_skill_ai
- # Create Actions Array
- actions = []
- # Scan Notes for Skill Use AI Actions
- note.scan(/\<Skill_Use_AI: (\d+)\>(.+?)<\/[^>]+>/im) {|id, tags|
- # Strip and Remove Empty lines from tags
- tags = tags.strip.split(/\r\n/).delete_if {|s| s.empty?}
- # Add Skill ID and Tags to actions array
- actions << [id.to_i, tags]
- }
- # Return Actions Array
- return actions
- end
- #--------------------------------------------------------------------------
- # * Determine if Targeting Battler
- #--------------------------------------------------------------------------
- def targeting_battler?(battler)
- # Return false if Current Action is nil
- return false if current_action.nil?
- # Check if Targeting battler
- return current_action.make_targets.compact.include?(battler)
- end
- end
- #==============================================================================
- # ** Game_Action
- #------------------------------------------------------------------------------
- # This class handles battle actions. This class is used within the
- # Game_Battler class.
- #==============================================================================
- class Game_Action
- #--------------------------------------------------------------------------
- # * Public Instance Variables
- #--------------------------------------------------------------------------
- attr_accessor :custom_action_ai_targets # Custom AI Targets Array
- #--------------------------------------------------------------------------
- # * Alias Listings
- #--------------------------------------------------------------------------
- alias tds_custom_action_ai_game_action_clear clear
- alias tds_custom_action_ai_game_action_make_targets make_targets
- #--------------------------------------------------------------------------
- # * Clear
- #--------------------------------------------------------------------------
- def clear(*args, &block)
- # Run Original Method
- tds_custom_action_ai_game_action_clear(*args, &block)
- # Clear Custom Action AI Targets Array
- @custom_action_ai_targets = []
- end
- #--------------------------------------------------------------------------
- # * Create Target Array
- #--------------------------------------------------------------------------
- def make_targets(*args, &block)
- # Delete Custom Targets if dead and item is not for dead friend
- @custom_action_ai_targets.delete_if {|t| t.dead? and !item.for_dead_friend?}
- # Return Custom Action AI Targets If Custom Action AI Targets Array is not empty
- return @custom_action_ai_targets if !@custom_action_ai_targets.empty?
- # Run Original Method
- tds_custom_action_ai_game_action_make_targets(*args, &block)
- end
- end
复制代码 |
|