Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #===============================================================================
- # * [ACE] Basic AI Module for Falcao's Pearl ABS Liquid v3
- #===============================================================================
- # * Made by: Sixth (www.rpgmakervxace.net, www.forums.rpgmakerweb.com)
- # * Version: 1.2
- # * Updated: 02/09/2015
- # * Requires: Falcao's Pearl ABS Liquid v3
- #-------------------------------------------------------------------------------
- # * < Change Log >
- #-------------------------------------------------------------------------------
- # * Version 1.0 (01/08/2015)
- # - Initial release.
- # * Version 1.1 (05/08/2015)
- # - Added situational tool group settings.
- # These can not be used by the enemy if the conditions for them do not match.
- # You can check for:
- # ~ HP rates.
- # ~ States inflicted.
- # ~ States not inflicted.
- # ~ Distance from another character (2 types).
- # ~ Switches.
- # ~ Variables.
- # With these, you can check if any enemy on the screen matches the
- # condition(s) required or not.
- # - Added forced "targeting scope" options.
- # This will let the enemy heal the most wounded allies automatically, or
- # will use cure only on poisoned enemies, for example.
- # - Combine these two new features, and make highly intelligent healer enemies,
- # or make enemies enrage when their partners are close to death (or dead)!
- # These are just examples, use your imagination to make better AI for your
- # enemies!
- # * Version 1.2 (02/09/2015)
- # - Added some conditional movement script calls.
- # You can now have a bit more control over how your enemy moves and when.
- #-------------------------------------------------------------------------------
- # * < Description >
- #-------------------------------------------------------------------------------
- # * By default, the random tool usage script calls Falcao provided are not very
- # flexible. It simply selects a random tool from a pool you specify. It can
- # not be used to define actual chance of usage for the tools, so if you would
- # like to add 3 skills, for example, 1 weak, 1 mid and 1 very strong one, it
- # is highly possible that the enemy will use a lot of very strong tools in a
- # row, which is not something that a developer wants normally, right?
- # * With this script, you can set the chance of usage for each tool you add to
- # the random pool, so you can limit a very strong tool to be only used 5% of
- # the times, for example.
- # * You can also set up HP thresholds for your random tools. For example, you
- # can remove a skill like "Heal" from the random pool if the enemy is above
- # 50% HP, and let the enemy only cast it if it's HP is below 50%.
- # Effectively, this is the same function what Falcao provided with the HP
- # threshold switch notes for enemies, but this one is more flexible and
- # requires no switch usage at all!
- # * You can even set up a mixed group, meaning mix weapon and skill tools too
- # in the random pool with the mixed group settings!
- # * From v.1.1, you are not limited to check the user's HP only!
- # Check for any enemy's HP or states inflicted on the screen!
- # Check if the player or any other enemy is in a specified range from the user!
- # * Add situational tools depending on other enemies' HP, states, distance!
- # * Activate a whole new group of tools for the enemy with a switch or variable!
- # * Basic AI for your enemies! Basic is better than no AI at all, riight? :D
- #-------------------------------------------------------------------------------
- # * < Script Calls>
- #-------------------------------------------------------------------------------
- # * All script calls are used within the Move Route event command!
- # * To make an enemy use a random tool from your tool group settings, simply use
- # the following script calls:
- #
- # adv_rand_w(group_id) <-- For weapon tools.
- # adv_rand_a(group_id) <-- For armor tools.
- # adv_rand_s(group_id) <-- For skill tools.
- # adv_rand_i(group_id) <-- For item tools.
- #
- # adv_tool_group(group_id) <-- For mixed tool types.
- #
- # Replace 'group_id' with a key you used in your tool group settings.
- #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # * To make an enemy use situational tools, use the following script call:
- #
- # epic_tool_group(adv_group_id,[group_data])
- #
- # The 'adv_group_id' is the key of the situational tool list you want to use.
- #
- # The '[group_data]' is an array, and that will be the regular tool list of
- # the enemy. You can set up any tool group for it from the 'Weapons', 'Armors',
- # 'Skills', 'Items' or 'Mixed' settings in the script.
- # Here is how it looks like:
- # [:type,group_id]
- # Replace :type with one of these: :weapon, :armor, :skill, :item or :mix.
- # These will decide the type of the tool group settings.
- # :weapon will read a group from the 'Weapons' settings, and so on.
- # The group_id is the key of the tool group you want to use.
- # For example: [:skill,2], [:mix,1], etc.
- # If you omit this, than the enemy will not use any tool if no situational
- # tool passed it's condition/chance checks. It will simply stay idle.
- #
- # Example:
- #
- # epic_tool_group(1,[:skill,3])
- #
- # This will make the enemy first check the tools used in the situational group
- # with the key of 1. If no tools can be used from that group (so the
- # conditions for them do not match or all of them failed the chance check),
- # it will select a tool from the 'Skills' tool groups (the HP thresholds and
- # chance settings from that will still apply), specifically, from the group
- # with the key of 3 in the settings.
- #
- # epic_tool_group(4)
- #
- # This will make the enemy check the tools from the situational group with the
- # key of 4. If no tool can be used (conditions are not met or chance check
- # failed) from the group, the enemy will not use any tool, it will just wait
- # one round. You should put at least one 'wait' move command before or after
- # this script call if this is the only thing you put in the enemy's auto-move
- # command list. That will make sure that you won't have any performance issues
- # (I tested, and I got no issues, even without any 'wait' command, but it's
- # better to be safe than sorry, right? :P).
- #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # * To add some distance conditions to the movement of the enemies, you can use
- # the following script call:
- #
- # custom_move_route(:type,range,target)
- #
- # You have 3 options for the :type setting:
- # 1. :close_in = This will make the enemy approach the target if the target is
- # not yet within the specified range. If it is in range, it
- # will not move closer.
- # 2. :stay_in_range = This will make the enemy stay in the specified range.
- # If the enemy is closer than the range specified, it will
- # move away from the target, if the enemy is farther than
- # the range, it will move closer.
- # 3. :get_away = This will make the enemy move away from the target if it is
- # closer than the range specified.
- #
- # The 'range' is the sum distance from the target on the X and Y axis.
- # It is measured in tiles.
- #
- # The 'target' is a valid character object. That can be:
- # $game_player # <-- For the player.
- # $game_map.events[ID] # <-- For any events on the map.
- # $game_followers[ID] # <-- For any followers on the map. This is not tested!
- # If you omit the target argument, $game_player is used by default.
- #
- # Examples:
- #
- # custom_move_route(:close_in,5)
- # This makes the event where the script call is used move toward the player
- # if the distance between them is more than 5 tiles. If it is less or equal,
- # the event will not move.
- #
- # custom_move_route(:stay_in_range,3,$game_map.events[2])
- # This makes the event where the script call is used move toward the other
- # event (with ID 2) when the distance between them is more than 3 tiles, and
- # will make the event move away from the other one if the distance is less
- # than 3 tiles. If the distance is equal 3 tiles, the event will not move.
- #
- # custom_move_route(:get_away,4)
- # This makes the event where the script call is used move away from the player
- # if the distance between them is less than 4 tiles. If the distance is more
- # or equal 4 tiles, the event will not move.
- #-------------------------------------------------------------------------------
- # * < Note-tags >
- #-------------------------------------------------------------------------------
- # * To make a healing or state curing situational tool work correctly, you must
- # tag them with the following note-tags:
- #
- # ~ For healing tools:
- # Tool Enemy Heal = true
- # This will automatically set the enemy with the lowest HP rate to be the
- # target of this tool. The scope of the tool must be set to "One Ally" in the
- # database, or else this function will NOT work!
- #
- # ~ For state curing tools:
- # Tool Enemy State = state_id1, state_id2, ... state_idN
- # This will automatically set the first enemy found with any of the states
- # listed inflicted to be the target of the tool.
- # Replace the 'state_ids' with the state IDs you want to be cured on the target.
- # You can add as many as you want.
- # The scope of the tool must be set to "One Ally" ("or One Ally (Dead)" in the
- # case of death state removal, aka state ID 1) in the database, or else this
- # function will NOT work!
- #
- # You only need to set these note-tags if you want the enemy to target
- # intelligently, instead of blowing off healing and curing tools on random
- # enemies. Even if you don't set these tags, the enemies will still use the
- # selected situational tool, but they will simply select a target randomly.
- # Needless to say that if your tool's scope is "All Ally" or an enemy related,
- # you don't really need these new "targeting scopes".
- #-------------------------------------------------------------------------------
- # * < Installation >
- #-------------------------------------------------------------------------------
- # * Place this script below all of Falcao's ABS scripts but above Main!
- #-------------------------------------------------------------------------------
- # * < Compatibility Info >
- #-------------------------------------------------------------------------------
- # * No known incompatibilities.
- #-------------------------------------------------------------------------------
- # * < Known Issues >
- #-------------------------------------------------------------------------------
- # * No known issues.
- #-------------------------------------------------------------------------------
- # * < Terms of Use >
- #-------------------------------------------------------------------------------
- # * Free to use for whatever purposes you want.
- # * Credit me (Sixth) in your game, pretty please! :P
- # * Posting modified versions of this script is allowed as long as you notice me
- # about it with a link to it!
- #===============================================================================
- $imported = {} if $imported.nil?
- $imported["SixthFalcaoABSBasicAI"] = true
- #===============================================================================
- # Settings:
- #===============================================================================
- module AdvRandTool
- #-----------------------------------------------------------------------------
- # Single Tool Group Settings
- #-----------------------------------------------------------------------------
- # These settings are good only if you don't plan on mixing weapon and skill
- # tools in your group settings, for example.
- # So, you can only use one type of tool in these settings.
- # If you don't need mixed groups, than use these settings instead of the
- # mixed one, because this one is a bit faster (the difference is not
- # noticeable for human eyes, but still).
- #
- # Format:
- #
- # group_id => {
- # hp_rate => {
- # tool_id => [chance_min,chance_max],
- # tool_id => [chance_min,chance_max],
- # # <-- You can add more tool settings here!
- # },
- # # <-- You can add more HP rate threshold settings here!
- # },
- # # <-- You can add more group settings here!
- #
- # group_id = The key used in the script calls, just an identifier.
- # I used numbers in my game, but you can use strings and symbols
- # too if you want. Do not make duplicates!
- # hp_rate = HP rate threshold. Goes from lower to higher thresholds.
- # If the enemy got equal or lower HP rate than this number, the tool
- # group will be selected. 1 means 1%, 20 means 20%, and so on.
- # tool_id = The ID of the weapon/armor/skill/item to use.
- # [chance_min,chance_max] = Specify a range for the probability calculations.
- # Valid numbers: from 0 to 99.
- # Example: [0,21] means 22%, 22 numbers total from 0 to 21.
- # It is inclusive, so 0 and 21 counts too!
- # Adding higher numbers than 99 will mean nothing!
- #
- # Current formula:
- # Checks for HP rates, selects the proper tool group based on HP.
- # A random number is generated between 0 and 99. If the number is between the
- # chance range of a tool, that tool will be selected.
- #
- # Example setting explanation:
- # You can see one example in the Skills settings.
- # The group_id I used is a number, a simple 1. This will be used in the script
- # call. The script call would look like: adv_rand_s(1) .
- # I set up a threshold for 25% HP or below and one 100% or below. The latter
- # needs to be set up for every group! Every other thresholds are optional.
- # You can add as many thresholds as you want.
- # In the 25% HP threshold group, I added in a self-heal tool (ID 187), which
- # will be used 78% of the times (22 to 99, meaning 78 numbers total), and a
- # regular attack tool (ID 192), which will be used 22% of the times (0 to 21,
- # meaning 22 numbers total).
- # This means that if the random number generated is 65, for example, the
- # "Heal" skill will be used. If the random number is 32, the "Heal" skill will
- # be used again. If the number is 15, the enemy will attack. And so on...
- # Effectively, when the enemy heals itself above 25% HP, it will switch to
- # the 100% threshold tool group, and stops healing itself automatically,
- # almost like an intelligent being. :P
- #
- # But healing AI is not the only thing you can do with this.
- # You can make the enemy use stronger skills if they are below 30% HP,
- # for example, or you can even switch it up, and make the enemy use stronger
- # skills when they are close to full HP, instead of being almost dead.
- #
- # NOTE:
- # If you miss some numbers from the chance setting, the enemies will randomly
- # "do" nothing too! The more numbers you miss, the bigger the chance of them
- # just waiting instead of acting (using a tool).
- #-----------------------------------------------------------------------------
- Weapons = {
- # Add your weapon tool group settings here.
- }
- Armors = {
- # Add your armor tool group settings here.
- }
- Skills = {
- 1 => { # Skill tool group setting 1.
- 25 => { 187 => [22,99], 192 => [0,21] },
- 100 => { 192 => [9,99], 196 => [0,8] },
- },
- 2 => { # Skill tool group setting 2.
- 100 => { 193 => [0,99] },
- },
- 3 => { # Skill tool group setting 3.
- 30 => { 187 => [36,99], 193 => [12,35], 214 => [0,11] },
- 100 => { 193 => [40,99], 214 => [0,39] },
- },
- 4 => { # Skill tool group setting 4.
- 30 => { 187 => [36,99], 184 => [12,35], 172 => [0,11] },
- 100 => { 172 => [40,99], 186 => [0,39] },
- },
- # Add more skill tool group settings here.
- }
- Items = {
- # Add your item tool group settings here.
- }
- #-----------------------------------------------------------------------------
- # Mixed Tool Group Settings
- #-----------------------------------------------------------------------------
- # If you need to mix weapon tools with skill tools, or item tools with skills,
- # and so on, you can set a mixed group up for it here.
- # The format is almost the same, but instead of simply adding the tool IDs,
- # you will use an array at that place to define the type of the tool and
- # it's ID.
- #
- # The types are symbols and they are:
- # :weapon, :armor, :skill, :item
- # It is pretty obvious what these mean, right? :P
- # So, it looks like this: [:type,ID] => [chance_min,chance_max],
- #
- # In the example here, I use the same HP thresholds settings like in the
- # skill group example, but now instead of a normal skill attack, I use a
- # weapon tool instead. This means the enemy will use "Heal" 78% of times, and
- # will use the weapon with the ID of 2 the rest of the times when it's HP is
- # below 25%. If it is above, it will use a regular skill attack all the time.
- # The script call for this would look like this: adv_tool_group(1) .
- #-----------------------------------------------------------------------------
- Mixed = {
- 1 => {
- 25 => { [:skill,187] => [22,99], [:weapon,2] => [0,21] },
- 100 => { [:skill,193] => [0,99] },
- },
- 2 => {
- 25 => { [:skill,187] => [22,99], [:weapon,7] => [0,21] },
- 100 => { [:weapon,38] => [0,99] },
- },
- # Add more mixed tool group settings here.
- }
- #-----------------------------------------------------------------------------
- # Situational Tool Group Settings
- #-----------------------------------------------------------------------------
- # This is where you can set up some real AI involved thinking for your enemies.
- # Every tool must have a condition set up here. The conditions will decide
- # whether the enemy will use the tool or not.
- # In other words, these are tools which will only be used when they are needed
- # or if they are enabled.
- # Great for making thinking healer enemies, for example.
- # Another epic usage is to make enraged enemies when their partners get low HP.
- # And yet another is making some complicated puzzles with the help of tools!
- #
- # Format:
- #
- # group_id => {
- # [type,ID] => {
- # :conditions => {
- # :hp => [:check_target,rate,check_type],
- # :state => [:check_target,[state_ids],check_type],
- # :nostate => [:check_target,[state_ids],check_type],
- # :distance => [:check_target,[x,y],[check_typeX,check_typeY],"check_mode"],
- # :distance2 => [:check_target,distance,"check_type"],
- # :switch => [[switch_ids],true/false,check_type],
- # :variable => [[var_id,value,check_type],...],
- # },
- # :chance => value,
- # },
- # # Add more tool settings here!
- # },
- # # Add more group settings here!
- #
- #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # Basic data explanation:
- #
- # These must be present for all of your tools you set up here!
- #
- # group_id = Same as for the basic group settings.
- # This is an identifier/key which can be anything from numbers to
- # strings, and even symbols. I used numbers in my game.
- # Must be a unique key, so no duplicates!
- # This is what you will use in your script calls.
- #
- # type = The type of the tool. You have 2 groups of settings here:
- # Use :weapon, :armor, :skill or :item if you want to set conditions
- # for single tools.
- # Use "weapon", "armor", "skill", "item" or "mix" if you want to set
- # a condition for a whole group of tools.
- # So, symbols for single tools, strings for groups!
- #
- # ID = The database ID of the tool (if you use a symbol for the type)
- # or the tool group key (if you use a string for the type).
- #
- # :chance = The chance of the tool being used.
- # Enter a number between 1 and 100 for the value.
- # 1 = 1%, 30 = 30%, 100 = 100%
- #
- # Note that even if the condition is matched, it is not 100% that the enemy
- # will use that tool, unless you set the :chance for it to 100!
- #
- # Also, these tools or groups are higher priority on the tool selection list.
- # The system will first check these settings.
- # If the condition is true, and the usage chance check is passed, a tool from
- # this list will be used instead of the tools from the regular tool group list.
- # If the condition check returns false, or the chance check is false, it
- # proceeds to select a tool from the regular tool group list.
- #
- # Now, let's start with the available condition check types!
- #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # Condition Type 1 (HP rate checks):
- #
- # :hp => [:check_target,rate,"check_type"],
- #
- # :check_target = 3 target type can be specified for this condition:
- # 1. :self = Will only check the condition on the user itself.
- # 2. :player = Will only check the condition on the player.
- # 3. :any = Will check the condition on any visible enemies on the screen.
- # Even if only one enemy matches the condition, the tool can be used.
- #
- # rate = The HP rate to check for. Takes float numbers, meaning:
- # 0.1 = 10%, 0.3 = 30%, 0.5 = 50%, 1.0 = 100%, and so on.
- #
- # "check_type" = The type of comparison used for the condition.
- # It can be: ">", ">=", "=", "<", "<=" or "!=".
- # These are strings, so use the quotation marks!
- # It's obvious what they mean (hint: basic math :P).
- #
- # Examples:
- #
- # :hp => [:player,0.3,"<="],
- # A tool with this setup will only be used if the player is NOT above 30% HP.
- #
- # :hp => [:any,0.5,"<"],
- # A tool with this setup will only be used if there is at least one enemy on
- # the visible screen with less than 50% HP. I sense thinking healer enemies!
- #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # Condition Type 2 (State inflicted checks):
- #
- # :state => [:check_target,[state_ids],"check_type"],
- #
- # :check_target = Same as for the HP rate condition type.
- #
- # [state_ids] = This is an array containing the IDs of the states you want to
- # check for. You can enter as many IDs as you want.
- #
- # "check_type" = The type of the check used. You have 2 options here:
- # 1. "any" = This means that even if only one state from the list is
- # inflicted on the check target(s), the tool can be used.
- # 2. "all" = This means that ALL of the entered states must be inflicted on
- # the check target(s) in order for this tool to be used.
- #
- # Examples:
- #
- # :state => [:any,[1],"all"],
- # This means that if any enemy on the screen got the state with ID 1 inflicted
- # (in other words, if any enemy is dead), the tool can be used.
- # Since there is only one state to be checked, it doesn't really matter what
- # type of check you use, both "any" and "all" should work.
- #
- # :state => [:any,[2,3,4,5,6],"any"],
- # This means that if any enemy on the screen got any of the states listed
- # inflicted, the tool can be used. A great way to make a healer enemy cure all
- # these nasty negative states from an ally!
- #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # Condition Type 3 (State NOT inflicted checks):
- #
- # :nostate => [:check_target,[state_ids],"check_type"],
- #
- # The format is exactly the same as for the state inflicted checks, but this
- # time, it will check if the state is NOT inflicted.
- #
- # Examples:
- #
- # :nostate => [:player,[2],"all"],
- # This tool will only be used if the player do NOT have the state with ID of 2
- # inflicted already. It's "Poison" by default, so if the enemy already poisoned
- # the player, it won't use this tool, until the poison wears off or cured.
- #
- # :nostate => [:self,[6],"any"],
- # If the user already got the state with ID of 6 inflicted on it, this tool
- # will NOT be used. Possible uses include an "Enrage" tool, which is executed
- # only when there is a dead enemy on the screen and only if the "Enrage" state
- # is NOT present yet. Or if the enemy got the "Regen" status already, it won't
- # re-cast it, until it wears off.
- #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # Condition Type 4 (Distance checks - Type 1):
- #
- # :distance => [:check_target,[x,y],["check_typeX","check_typeY"],"check_mode"],
- #
- # :check_target = 2 target type can be specified for this condition:
- # 1. :player = Will only check the condition on the player.
- # 2. :any = Will check the condition on any visible enemies on the screen.
- # Even if only one enemy matches the condition, the tool can be used.
- #
- # [x,y] = The distance to check for. Measured in tiles.
- # You can use a different number for X and Y if you want.
- #
- # "check_typeX" = The type of comparison used for the condition.
- # "check_typeY" "check_typeX" is for the X distance condition, while
- # "check_typeY" is for the Y distance condition.
- # These can be: ">", ">=", "=", "<", "<=" or "!=" .
- # Don't forget that they must be put into an array!
- #
- # "check_mode" = The mode of the comparison. You have two options to use:
- # "any" = If you use this mode, than it's enough if only 1 of
- # the distance checks return true, it can be either
- # the X distance or Y distance.
- # "both" = If you use this mode, both the X and Y checks must
- # be true to use this tool.
- #
- # Examples:
- #
- # :distance => [:player,[2,2],["<=","<="],"both"],
- # The enemy will only use this tool if the player is not further than 2 tiles
- # from it in both the X and Y axis. For example, a plant which can't move will
- # only use this tool if the player is in range, like a "Pollen Attack". But
- # if the player is not close enough, it switches to use another tool.
- # This is the difference between this condition and the regular enemy sensor
- # settings for this ABS. The sensor only let's you add one distance condition,
- # while with this, you can add as many as you want, and you are not limited
- # to "closer than" checks (you can use "further than" checks too, for example).
- #
- # :distance => [:any,[5,3],[">","<"],"any"],
- # The enemy will only use this tool if any other enemy is further than 5 tiles
- # from it on the X axis, OR closer than 3 tiles on the Y axis. Only one check
- # needs to be true, not both!
- # This can be used to create cool puzzles if you combine some other elements
- # of this ABS and add some eventing to it, for example.
- #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # Condition Type 5 (Distance checks - Type 2):
- #
- # :distance2 => [:check_target,distance,"check_type"],
- #
- # :check_target = The same like at the previous distance condition check type.
- #
- # distance = The total distance from the target to check for. This means the
- # sum of the distance on the X and Y axis.
- #
- # "check_type" = The type of comparison used for the condition.
- # It can be: ">", ">=", "=", "<", "<=" or "!=".
- # These are strings, so use the quotation marks!
- #
- # Examples:
- #
- # :distance2 => [:player,3,"<="],
- # The enemy will only use this tool, if the player is in 3 tiles range. This
- # means that if the player is 1 tile away on the X axis, and 2 tiles away on
- # the Y axis, or 1 tile away on the X axis and 2 tiles away on the Y axis,
- # so, if the total distance on both the X and Y axis is not more than 3, the
- # tool can be used, otherwise it will be disabled.
- # You can use this to create 2 different type of tool sets for your enemies,
- # one for close combat, and another one for ranged combat, for example.
- #
- # :distance2 => [:any,3,">"],
- # The enemy will only use this tool if there is at least 1 other enemy 3 tiles
- # away from it. This interesting check can be used to make some chained tools.
- # Add this tool for more enemies, and if the player let them separate, they
- # all can use a powerful skill. Just an example, but it can be used for many
- # more things, if you have some imagination.
- #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # Condition Type 6 (Switch checks):
- #
- # :switch => [[switch_ids],true/false,"check_type"],
- #
- # [switch_ids] = The IDs of the switches you want to check for.
- # You can add as many as you want.
- #
- # true/false = The state of the switch(es) you want to check.
- # To check if a switch is turned ON, you should use true,
- # otherwise use false.
- #
- # "check_type" = The type of the check used. You have 2 options here:
- # 1. "any" = This means that even if only one switch from the list matches
- # the state you checked for, the tool can be used.
- # 2. "all" = This means that ALL of the entered switches must match the
- # state you checked for in order for this tool to be used.
- #
- # Examples:
- #
- # :switch => [[12,14],true,"all"],
- # This tool can only be used by the enemy if both switch 12 and 14 are turned
- # ON. It is great for changing the behaviour of your enemies after some major
- # events in your story-line.
- #
- # :switch => [[13,15,35,34],true,"any"],
- # This tool can be used by the enemy as soon as one of those switches is
- # turned ON. In case you are designing a non-linear game, and you find
- # yourself turning on different switches for different paths, but still want
- # your enemies to get stronger after any major events, you can use the switch
- # conditions like this, for example.
- #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # Condition Type 7 (Variable checks):
- #
- # :variable => [[var_id,value,"check_type"],...],
- #
- # var_id = The ID of the variable you want to check for.
- #
- # value = The value to check for.
- #
- # "check_type" = The type of comparison used for the condition.
- # It can be: ">", ">=", "=", "<", "<=" or "!=".
- # These are strings, so use the quotation marks!
- #
- # Note that all of these are put into an array! You can add more of these
- # arrays to check for multiple variables at the same time too!
- #
- # Examples:
- #
- # :variable => [[2,15,">="],[4,100,"<"]],
- # This tool can only be used by the enemy if the value of variable 2 is higher
- # than or equal 15, AND if the value of variable 4 is lower than 100.
- # Can be used for puzzle making or for changing enemy behaviours depending on
- # these variables.
- #
- # :variable => [[24,"Code Word","="]],
- # This tool can only be used by the enemy if the "value" of variable 24 is a
- # string, specifically the words "Code Word". Yeah, you can check for stored
- # texts too, but you can only use the "=" or "!=" check types for these, or
- # else your game will crash! Good for word puzzles, password checks, etc.
- #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # And this is it for now.
- # Combine these condition checks however you want!
- # You can add multiple different types of conditions for your tools too, but
- # make sure that you do NOT use duplicates! So, only one HP condition check,
- # or only one state condition check, etc!
- #
- # For example:
- #
- # :conditions => {
- # :hp => [:any,0.25,"<"],
- # :state => [:self,[12],"any"],
- # :switch => [[45,84,74],true,"all"],
- # },
- #
- # This tool can only be used by the enemy if:
- # 1. Any enemy on the screen got less than 25% HP.
- # 2. The user got the state with ID 12 inflicted on him/her/itself.
- # 3. The switches 45, 84 and 74 are all turned ON.
- # If any of the conditions do not match, the tool can NOT be used!
- #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # NOTE:
- # In order for some of these tools to work, you must set up an extra note-tag
- # for them! These are the tools with :any type HP rate conditions, and the
- # ones with :any type state inflicted conditions. To make the user target the
- # correct allies, you must set the provided new note-tags for these tools.
- # You can read more on that in the note-tag explanation at the script's header.
- # You only need these note-tags if the tool's scope is "One Ally" (or
- # "One Ally (Dead)" in the case of death state) to make sure that the enemy
- # using the tool will target the intended target instead of just randomly
- # using the tool on allies.
- #-----------------------------------------------------------------------------
- Advanced = {
- 1 => {
- [:skill,211] => { # Revive
- :conditions => {
- :state => [:any,[1],"any"], # If dead
- },
- :chance => 60, # 60% chance of casting
- },
- [:skill,209] => { # Heal
- :conditions => {
- :hp => [:any,0.5,"<="], # If HP <= 50%
- },
- :chance => 40, # 40% chance of casting
- },
- [:skill,210] => { # Poison Cure
- :conditions => {
- :state => [:any,[27],"any"], # If poisoned
- },
- :chance => 40, # 40% chance of casting
- },
- },
- 2 => {
- [:skill,212] => { # Enrage
- :conditions => {
- :state => [:any,[1],"any"], # If dead
- :nostate => [:self,[56],"any"], # If no Enrage state
- },
- :chance => 100, # 100% chance of casting
- },
- },
- 3 => {
- [:skill,213] => { # Plant Pollen
- :conditions => {
- :distance => [:player,[2,2],["<=","<="],"both"], # If player is in 2 tiles range
- },
- :chance => 60, # 60% chance of casting
- },
- },
- 4 => {
- ["skill",4] => { # Skill tool group 4 ("ranged combat tools")
- :conditions => {
- :distance2 => [:player,3,">"], # If player is further than 3 tiles total
- },
- :chance => 100, # 100% chance
- },
- ["mix",2] => { # Mixed tool group 2 ("close combat tools")
- :conditions => {
- :distance2 => [:player,3,"<="], # If player is in 3 tiles range total
- },
- :chance => 100, # 100% chance
- },
- },
- # Add more situational tool group settings here.
- }
- end
- #===============================================================================
- # End of Settings! Editing anything below may lead to... you know it, right?
- #===============================================================================
- class Game_CharacterBase
- def custom_move_route(type,range,target=$game_player)
- dist = eval_distance(target).sum
- case type
- when :close_in
- if case_comparison(">",dist,range)
- move_toward_character(target)
- end
- when :stay_in_range
- if case_comparison(">",dist,range)
- move_toward_character(target)
- elsif case_comparison("<",dist,range)
- move_away_from_character(target)
- end
- when :get_away
- if case_comparison("<",dist,range)
- move_away_from_character(target)
- end
- end
- end
- def epic_tool_group(adv_group_id,group_data=nil)
- AdvRandTool::Advanced[adv_group_id].each do |tool_inf,data|
- if check_tool_conditions(data[:conditions]) == true
- if data[:chance] >= rand(100)
- return unless tool_can_use?
- p "#{self.battler.name} (Ev ID: #{self.id}) using #{tool_inf[0]} #{tool_inf[1]}!"
- case tool_inf[0]
- when Symbol
- proc_mixed_tool(tool_inf[0],tool_inf[1])
- when String
- new_data = [tool_inf[0].to_sym,tool_inf[1]]
- use_correct_group(new_data)
- end
- return
- end
- end
- end
- use_correct_group(group_data) if !group_data.nil?
- end
- def use_correct_group(group_data)
- case group_data[0]
- when :weapon
- adv_rand_w(group_data[1])
- when :armor
- adv_rand_a(group_data[1])
- when :skill
- adv_rand_s(group_data[1])
- when :item
- adv_rand_i(group_data[1])
- when :mix
- adv_tool_group(group_data[1])
- end
- end
- def proc_mixed_tool(type,id)
- case type
- when :weapon
- process_tool_action($data_weapons[id])
- when :armor
- process_tool_action($data_armors[id])
- when :skill
- process_tool_action($data_skills[id])
- when :item
- process_tool_action($data_items[id])
- end
- end
- def check_tool_conditions(conditions)
- conditions.each do |type,dt|
- case type
- when :distance
- case dt[0]
- when :player
- dist = eval_distance($game_player)
- p dist
- case dt[3]
- when "any"
- if case_comparison(dt[2][0],dist[0],dt[1][0]) == false &&
- case_comparison(dt[2][1],dist[1],dt[1][1]) == false
- return false
- end
- when "both"
- if case_comparison(dt[2][0],dist[0],dt[1][0]) == false ||
- case_comparison(dt[2][1],dist[1],dt[1][1]) == false
- return false
- end
- end
- when :any
- cond = false
- $game_map.event_enemies.each do |event|
- if event.on_battle_screen? && !event.erased && !event.killed
- dist = eval_distance(event)
- case dt[3]
- when "any"
- if case_comparison(dt[2][0],dist[0],dt[1][0]) == true ||
- case_comparison(dt[2][1],dist[0],dt[1][1]) == true
- cond = true
- break
- end
- when "both"
- if case_comparison(dt[2][0],dist[0],dt[1][0]) == true &&
- case_comparison(dt[2][1],dist[0],dt[1][1]) == true
- cond = true
- break
- end
- end
- end
- end
- return false if cond == false
- end
- when :distance2
- case dt[0]
- when :player
- dist = eval_distance($game_player).sum
- if case_comparison(dt[2],dist,dt[1]) == false
- return false
- end
- when :any
- cond = false
- $game_map.event_enemies.each do |event|
- if event.on_battle_screen? && !event.erased && !event.killed
- dist = eval_distance(event).sum
- if case_comparison(dt[2],dist,dt[1]) == true
- cond = true
- break
- end
- end
- end
- return false if cond == false
- end
- when :switch
- return false if any_all_switch_check(dt[2],dt[0],dt[1]) == false
- when :variable
- cond = true
- dt.each do |var_inf|
- if case_comparison(var_inf[2], $game_variables[var_inf[0]], var_inf[1]) == false
- cond = false
- break
- end
- end
- return false if cond == false
- when :hp
- case dt[0]
- when :self
- return false if case_comparison(dt[2],self.battler.hp_rate,dt[1]) == false
- when :any
- cond = false
- $game_map.event_enemies.each do |event|
- if event.on_battle_screen? && !event.erased && !event.killed
- cond = true if case_comparison(dt[2],event.battler.hp_rate,dt[1]) == true
- break if cond == true
- end
- end
- return false if cond == false
- when :player
- return false if case_comparison(dt[2],$game_player.battler.hp_rate,dt[1]) == false
- end
- when :state
- case dt[0]
- when :self
- return false unless any_all_type_check(dt[2],self,dt[1]) == true
- when :any
- cond = false
- $game_map.event_enemies.each do |event|
- if event.on_battle_screen? && ((!event.erased && !event.killed) || dt[1].include?(1))
- cond = true if any_all_type_check(dt[2],event,dt[1]) == true
- break if cond == true
- end
- end
- return false if cond == false
- when :player
- return false unless any_all_type_check(dt[2],$game_player,dt[1]) == true
- end
- when :nostate
- case dt[0]
- when :self
- return false if any_all_type_check(dt[2],self,dt[1]) == true
- when :any
- cond = true
- $game_map.event_enemies.each do |event|
- if event.on_battle_screen? && ((!event.erased && !event.killed) || dt[1].include?(1))
- cond = false if any_all_type_check(dt[2],event,dt[1]) == true
- break if cond == false
- end
- end
- return false if cond == false
- when :player
- return false if any_all_type_check(dt[2],$game_player,dt[1]) == true
- end
- end
- end
- return true
- end
- def any_all_switch_check(type,switches,state)
- case type
- when "any"
- return switches.any? {|switch| $game_switches[switch] == state }
- when "all"
- return switches.all? {|switch| $game_switches[switch] == state }
- else
- return false
- end
- end
- def any_all_type_check(type,target,reqs)
- case type
- when "any"
- return reqs.any? {|req| target.battler.state?(req) }
- when "all"
- return reqs.all? {|req| target.battler.state?(req) }
- else
- return false
- end
- end
- def case_comparison(type, data, req)
- case type
- when ">"
- return data > req
- when ">="
- return data >= req
- when "==", "="
- return data == req
- when "<"
- return data < req
- when "<="
- return data <= req
- when "!="
- return data != req
- else
- return false
- end
- end
- def adv_tool_group(group_id)
- sel = 0; tool_type = :none
- random_num = rand(100)
- AdvRandTool::Mixed[group_id].each do |hprt,data|
- next unless battler.hp_rate*100 <= hprt
- data.each do |tool_inf,chance|
- if random_num.between?(*chance)
- sel = tool_inf[1]
- tool_type = tool_inf[0]
- p "#{self.battler.name} (Ev ID: #{self.id}) using #{tool_inf[0]} #{tool_inf[1]}!"
- break
- end
- end
- break if sel != 0
- end
- return unless tool_can_use?
- proc_mixed_tool(tool_type,sel)
- end
- def adv_rand_w(group_id)
- sel = 0
- random_num = rand(100)
- AdvRandTool::Weapons[group_id].each do |hprt,data|
- next unless battler.hp_rate*100 <= hprt
- data.each do |weapon_id,chance|
- if random_num.between?(*chance)
- sel = weapon_id
- p "#{self.battler.name} (Ev ID: #{self.id}) using weapon #{sel}!"
- break
- end
- end
- break if sel != 0
- end
- return unless tool_can_use?
- process_tool_action($data_weapons[sel])
- end
- def adv_rand_a(group_id)
- sel = 0
- random_num = rand(100)
- AdvRandTool::Armors[group_id].each do |hprt,data|
- next unless battler.hp_rate*100 <= hprt
- data.each do |armor_id,chance|
- if random_num.between?(*chance)
- sel = armor_id
- p "#{self.battler.name} (Ev ID: #{self.id}) using armor #{sel}!"
- break
- end
- end
- break if sel != 0
- end
- return unless tool_can_use?
- process_tool_action($data_armors[sel])
- end
- def adv_rand_s(group_id)
- sel = 0
- random_num = rand(100)
- AdvRandTool::Skills[group_id].each do |hprt,data|
- next unless battler.hp_rate*100 <= hprt
- data.each do |skill_id,chance|
- if random_num.between?(*chance)
- sel = skill_id
- p "#{self.battler.name} (Ev ID: #{self.id}) using skill #{sel}!"
- break
- end
- end
- break if sel != 0
- end
- return unless tool_can_use?
- process_tool_action($data_skills[sel])
- end
- def adv_rand_i(group_id)
- sel = 0
- random_num = rand(100)
- AdvRandTool::Items[group_id].each do |hprt,data|
- next unless battler.hp_rate*100 <= hprt
- data.each do |item_id,chance|
- if random_num.between?(*chance)
- sel = item_id
- p "#{self.battler.name} (Ev ID: #{self.id}) using item #{sel}!"
- break
- end
- end
- break if sel != 0
- end
- return unless tool_can_use?
- process_tool_action($data_items[sel])
- end
- end
- class RPG::BaseItem
- def enemy_heal
- @note =~ /Tool Enemy Heal = (.*)/i ? $1.sub("\r","") : ""
- end
- def enemy_state
- states = []
- if @note =~ /Tool Enemy State = (\d+(?:\s*,\s*\d+)*)/i
- $1.scan(/\d+/).each { |id| states << id.to_i }
- end
- return states
- end
- end
- class Projectile < Game_Character
- alias adv_ai_part1100 set_targeting
- def set_targeting
- adv_ai_part1100
- if @item.enemy_heal == "true" and @user.battler.is_a?(Game_Enemy)
- target = $game_map.event_enemies.min_by {|event|
- (!event.on_battle_screen? || event.erased || event.killed) ? 2.0 : event.battler.hp_rate }
- target = @user if target.nil?
- @user.targeting = [true, nil, target]
- @target_effect = [@user.targeting[0], @user.targeting[2]]
- @user.turn_toward_character(target)
- end
- if @item.enemy_state != [] and @user.battler.is_a?(Game_Enemy)
- target = $game_map.event_enemies.find {|event|
- if event.on_battle_screen? && ((!event.erased && !event.killed) || @item.enemy_state.include?(1))
- @item.enemy_state.any? {|state_id| event.battler.state?(state_id)}
- else
- false
- end
- }
- target = @user if target.nil?
- @user.targeting = [true, nil, target]
- @target_effect = [@user.targeting[0], @user.targeting[2]]
- @user.turn_toward_character(target)
- end
- end
- alias adv_ai_part1200 apply_effectto_selection
- def apply_effectto_selection
- if @item.enemy_heal == "true" and @user.battler.is_a?(Game_Enemy)
- target = $game_map.event_enemies.min_by {|event|
- (!event.on_battle_screen? || event.erased || event.killed) ? 2.0 : event.battler.hp_rate }
- apply_self_effect(target, true) if !target.nil?
- apply_self_effect(@user, true) if target.nil?
- return
- end
- if @item.enemy_state != [] and @user.battler.is_a?(Game_Enemy)
- target = $game_map.event_enemies.find {|event|
- if event.on_battle_screen? && ((!event.erased && !event.killed) || @item.enemy_state.include?(1))
- @item.enemy_state.any? {|state_id| event.battler.state?(state_id)}
- else
- false
- end
- }
- apply_self_effect(target, true) if !target.nil?
- apply_self_effect(@user, true) if target.nil?
- target.apply_respawn if !target.nil? && target.killed && @item.enemy_state.include?(1)
- return
- end
- adv_ai_part1200
- end
- end
- class Array
- def sum
- a = 0
- for n in 0...size
- a += self[n]
- end
- return a
- end
- end
- #==============================================================================
- # !!END OF SCRIPT - OHH, NOES!!
- #==============================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement