Skip to content

Instantly share code, notes, and snippets.

@AnonymousRandomPerson
Last active September 3, 2021 01:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AnonymousRandomPerson/a2656f25ab0e0d06268e64f215be5187 to your computer and use it in GitHub Desktop.
Save AnonymousRandomPerson/a2656f25ab0e0d06268e64f215be5187 to your computer and use it in GitHub Desktop.
Rescue Team AI raw notes
# All these statuses ignore tactics and Hungry Pal.
if Pokémon is a decoy or cross-eyed:
Move in a random direction.
End.
if Pokémon has blinker:
if Pokémon can move forward:
Move forward.
End.
if roll 50% is success:
Move in a random direction.
else:
Attack.
End.
if Pokémon is a client:
Move in a random direction.
End.
if:
* Pokémon is holding a non-sticky item.
* Pokémon is not avoiding enemies.
* Pokémon is not a decoy.
* Pokémon has Item Master IQ.
if item can be used on self: # Note: item use chance
Roll chance of using item.
if roll is successful:
Eat/Use the item.
End.
if item can be thrown at an ally/enemy: # Note: item use chance
Find all visible, viable targets in throwing range of the item.
# Any allied/enemy Pokémon (respectively) within 10 tiles of the Pokémon.
# If item is thrown straight, only include targets aligned with the Pokémon.
If multiple targets, choose one randomly.
Roll chance of using item.
if roll is successful:
Face the target.
Throw the item.
End.
if Pokémon has Dedicated Traveler:
Try to move.
if cannot move:
Try to attack.
else:
Try to attack.
if cannot attack:
Try to move.
===
Move:
if any of:
* Tactic is "Be patient" and HP < max HP / 2
* Tactic is "Wait there"
* Belly is empty (Hungry Pal)
Don't move.
End.
if Pokémon is avoiding enemies:
Choose closest target Pokémon.
if target is in same room:
if Pokémon is on room exit tile:
Check all tiles around Pokémon, starting with a random tile and going counterclockwise.
If Pokémon can move to any adjacent tile not in the same room, move to that tile.
Else, move in a random direction.
# If Pokémon can cross special terrain, they might cross the terrain rather than following the corridor.
End.
else:
Calculate x/y position differences between target and Pokémon.
Find the room exit furthest away from the target.
if moving towards the furthest exit would move closer to the target:
# Note: Run away room movement
Target the position away from the target in both directions.
else:
Target the room exit furthest away from the target Pokémon.
else if Pokémon are in different rooms or either is in a corridor:
Target the position away from the target in both directions.
else: # i.e., no target
Explore.
if:
* Item is underfoot.
* Item is not for sale.
* Pokémon is not holding an item.
* Pokémon is not avoiding enemies.
* Pokémon is not an escort.
# Won't pick up item if holding one, even if toolbox has space.
Pick up item underfoot.
End.
if wild Pokémon or tactic is "Go the other way", "Go after foes", or "Avoid the first hit":
Choose closest target Pokémon.
if target exists:
Move towards the target Pokémon.
End.
else:
if team Pokémon and tactic is not "Go the other way":
if leader is not a decoy and can be seen:
Move towards the leader's position.
End.
# Wild Pokémon, Go the other way, fallback if leader can't be seen.
# Note: Unused item targeting code
if Pokémon was previously targeting another Pokémon:
Check the target Pokémon's last four turns for any positions that can be seen.
if there is a valid previous position for the target Pokémon:
Target the most recent valid previous position of the target Pokémon.
End.
else:
Explore.
if target is adjacent:
Don't move.
End.
Face target, prioritizing diagonal movement.
if tactic is "Avoid the first hit":
if target is two tiles away:
Don't move.
End.
else:
Move forward.
End.
Move forward.
End.
===
Avoid enemies:
Pokémon will try to avoid enemies under any of the conditions below.
* Pokémon is terrified.
* Tactic is "Get away".
* Tactic is "Avoid trouble" and HP < max HP / 2
* Ability is Run Away and HP < max HP / 2
===
Forward movement checks:
Any forward movement makes the following checks. A Pokémon won't move to a tile if:
* Target tile is inaccessible (special terrain or walls).
* Target tile is an inactive monster house and Pokémon has House Avoider.
* Target tile has trap, Pokémon has Trap Avoider, and any of:
* Trap is visible.
* Pokémon has Eyedrops.
* Target tile is lava and Pokémon has Lava Evader.
If the Pokémon can't move forward, it will try to step around the tile.
Iterate through directions in facing rotation order, starting with facing the target.
* If the Pokémon is running away or turning around, try turning left 45 degrees, right 45, left 90, and right 90 degrees.
* Otherwise, try turning 45 degrees left and right.
if any direction is passable:
Move forward in that direction.
else:
Don't move.
Special case if the following conditions are met:
* Pokémon is on the player's team.
* Target is 2 tiles away.
* Target is diagonally positioned relative to the Pokémon.
* Both tiles when turning left/right 45 degrees are passable.
Instead of facing rotation order, decide to turn left/right based on which moves closer to the target.
# Pokémon can get stuck behind a row of three traps. Although if they are running away, they will step around successfully.
===
Choose closest target Pokémon:
Choose target to run away from based on who is closest to Pokémon: min(max(xDiff, yDiff)).
* Must be in range: same room and/or at most 2 tiles away.
* Ignore allied Pokémon except for decoys.
* Ignore client Pokémon.
* Ignore friendly shopkeepers.
* Ignore invisible opponents.
* Teammates ignore petrified opponents.
* Blinker prevents seeing any target.
* Prioritize decoys.
===
Visible range:
A target Pokémon is visible if it is in the same room and/or at most 2 tiles away.
Some statuses prevent a target Pokémon from being seen:
* Pokémon has blinker.
* Target Pokémon is invisible.
===
Run away room movement:
Since this only checks if moving would move closer to the target, not whether moving would keep it the same distance away, this can result in counterintuitive behavior, especially visible when directly next to the target. Changing this to check for moving closer or the same distance away fixes this odd behavior.
In assembly, change 0x0807b890 to 0x5dd.
===
Explore:
if Pokémon is in a corridor:
if Pokémon is at a junction:
# At junctions, randomly choose which way to go.
# Note: Explore junction movement
Move in a random direction.
End.
if Pokémon is mobile:
# E.g., Mobile Scarf, Super Mobile, Ghost types.
# Every few turns (at least 3, 5 on average), randomly choose a new direction to move in.
Generate a number [0,100) and increment the mobile junction timer.
if mobile junction timer >= 200:
Move in a random direction.
Set mobile junction timer back to 0.
End.
# At non-junctions, move forward according to the path.
Move in the first traversable direction using facing rotation order.
* Exclude the direction opposite of the current facing direction.
else: # in room
if room has no exits:
Move in a random direction.
else:
if Pokémon is already targeting a room exit:
Keep targeting room exit.
else if room has one exit:
Turn around.
else # room has multiple exits
# Note: Picking random exit
Target a random room exit that's not the exit the Pokémon is standing on.
===
Explore junction movement:
A junction is defined as any tile traversable in a T or + shape.
If the Pokémon can cross special terrain, they will go in a random direction if the terrain makes the tile look like a junction, though not if the special terrain surrounds the tile.
At non-junction turns, if a Pokémon can cross special terrain, they will veer off the path and continue moving forward.
===
Picking random exit:
The Pokémon tries to pick a random exit up to 10 times. If the Pokémon chooses the exit that it's standing on 10 times in a row (1/n^10 chance with n-exit room), it will turn around even if there is another exit.
===
Facing rotation order:
In degrees, facing rotation order is 0, left 45, right 45, left 90, right 90, left 135, right 135.
===
Attack:
if Pokémon is avoiding enemies or tactic is "Keep your distance":
End.
if Pokémon is confused:
Roll a 30% chance.
if roll is not successful:
End.
if Pokémon has PP Checker, filter out unusable moves:
* Moves with 0 PP.
* Linked moves with 1 PP.
* If Pokémon is taunted, non-offensive moves.
* If Pokémon is encored, all moves except the last used move.
if Pokémon has Exclusive Move-User, filter out the regular attack.
Iterate through usable moves (including inner linked moves):
# Include Struggle if no usable moves.
if move targets in front (including cut corners, 2-ahead, and line):
Iterate through directions in facing rotation order:
Iterate through each tile in front based on move range:
# 1 for in front or cut corners.
# 2 for 2-ahead.
# 10 for line range.
if direction has an enemy Pokémon in front and is not blocked by walls (or corners if move can't cut them):
if Pokémon has Course Checker, move has line range, and a wall or another Pokémon obstructs the target:
Skip move.
Weight move/direction for target.
# Note: Move weighting.
if a move/direction combo is usable:
Find the move/direction combo with maximum weight.
* If there is a tie, randomly choose one of the move/direction combos with max weight.
Move weight is max weight among move/direction combos.
else:
Move weight is 0.
else if move targets room:
Iterate through all visible Pokémon:
Weight move for target.
# Note: Move weighting.
else if move targets floor:
Iterate through all Pokémon:
Weight move for target.
# Note: Move weighting.
else if move is a self-heal:
Weight move for target.
# Note: Move weighting.
if Pokémon has Weak-Type Picker:
Use calculated move weight.
else:
Use move's default weight.
Randomly choose a move via weighted random.
Face a target for the move; if there are multiple targets, pick the one with the highest weight.
* If there are no targets for the move, don't attack.
===
Unused item targeting code:
There is unused code for targeting items. This code is conditional on the Pokémon being the team leader; it will never be run because the leader is player-controlled, not AI-controlled.
If an item is within visible range, target the item's position. The item search is conducted starting at the top-left of the visible range, scanning horizontally; the first item found is targeted.
This logic doesn't check if the Pokémon is holding an item, so the Pokémon will get stuck on an item when already holding one.
===
Item use chance:
Different items have different conditions for being used. If an item can be consumed or thrown, the Pokémon has a chance of using the item.
Used on self/thrown at ally:
Oran Berry/Sitrus Berry
Target has <= 25% HP (50%, thrown)
User has <= 25% HP and next to an opponent (100%, self).
User has <= 25% HP and not next to an opponent (50%, self).
Pecha Berry
Target is poisoned/badly poisoned and next to an opponent (100%, self/thrown).
Target is poisoned/badly poisoned and not next to an opponent (50%, self/thrown).
Status healing:
Conditional on item having effect (self/thrown).
Heal Seed: (80%)
Rawst Berry: (50%)
Chesto Berry (5%)
Boosting:
Conditional on item having effect (self/thrown).
Apple/Big Apple/Huge Apple: < 10 belly (100%).
Protein/Iron/Calcium/Zinc: Respective stat is < 250 (100%).
Joy Seed: Level 98 or lower (80%).
Eyedrop Seed/Quick Seed/Cheri Berry
Ignore if the Pokémon will not benefit from the status.
* Eyedrop Seed: Has Goggle Specs or already has Eyedrops status.
* Quick Seed: Is at quadruple speed.
* Cheri Berry: Is not paralyzed.
Target is next to an opponent (80%, self/thrown).
Target is not next to an opponent (self/thrown).
* 30% for Cheri Berry.
* 5% otherwise.
Max Elixir
Iterate through the Pokémon's moves. To get the weight, add 30% for every move with 0 PP, and 6% for every move that is not at max PP (self/thrown).
Life Seed
User is next to an opponent (10%, self).
User is not next to an opponent (100%, self).
Rollcall Orb
User is wild Pokémon (20%, self).
Ginseng
# Unused
Target exists (80%, self/thrown).
Warp Seed
# Unused
Ally has < 20 HP (50%, thrown).
User has < 20 HP and is next to an opponent (100%, self).
User has < 20 HP and is not next to an opponent (50%, self).
Thrown at opponent:
Target exists.
* Stackable thrown items (Iron Thorn, Gravelerock, etc.) (70%)
* Whiff Specs/No-Aim Scope (50%)
* Patsy Band (40%)
* Grimy Food (30%)
Conditional on item having effect:
Doom Seed: Level 2 or above (80%).
Diet Ribbon/Hunger Seed: Non-empty belly (50%).
Allure/Blast/Blinker/Sleep/Stun/Totter/Warp Seed
Ignore if target already has respective status. Unconditional for Blast/Warp Seed.
# Sleep Seed can be thrown even if target is sleepless.
Target is next to an ally (80%, thrown).
Target is not next to an ally (thrown).
* 30% for Blast Seed.
* 15% for Totter Seed.
* 5% otherwise.
===
Status Checker:
Many moves have custom checks for whether they can be used when Status Checker is enabled.
Self status move:
User does not have the status caused by the move.
* Bide/Revenge (redundant)
* Charge
* Conversion 2
* Counter/Pursuit
* Destiny Bond
* Detect/Protect
* Doom Desire/Future Sight
* Endure
* Grudge
* Light Screen
* Lock-On/Mind Reader
* Magic Coat
* Mirror Coat
* Mist
* Mud Sport
* Rage
* Reflect
* Safeguard
* Snatch
* Transform
* Water Sport
* (Invisify/Invisify Orb)
Target status move:
Target doesn't have the status applied by the move.
* Attract
* Block/Mean Look/Spider Web
* Confuse Ray/Flatter/Supersonic/Swagger/Sweet Kiss/Teeter Dance/(Totter/Totter Orb)
* Curse (Ghost)
* Disable/Glare/Stun Spore/Thunder Wave
* Grasswhistle/Hypnosis/Lovely Kiss/Sing/Sleep Powder/Spore
* Imprison
* Leech Seed
* Perish Song
* Smokescreen
* Taunt
* Toxic
* Uproar
* Will-O-Wisp
* Wrap
Self stat boost move:
User's stat stage is not maxed (+10 or quadruple speed) for the stat raised by the move.
* Howl/Meditate/Sharpen/Swords Dance
* Acid Armor/Barrier/Defense Curl/Harden/Iron Defense/Withdraw
* Growth/Tail Glow
* Amnesia
* Double Team/Minimize
* Agility
Self multi-stat boost move:
User's stat stages are not maxed (+10 or quadruple speed) for any stat raised by the move.
* Bulk Up
* Calm Mind
* Cosmic Power
* Curse (non-Ghost)
* Dragon Dance
Target stat lower move (slightly):
Target's stat stage is not at minimum (-10 or slow speed) for the stat lowered by the move.
* Featherdance/Growl
* Leer/Tail Whip
* Fake Tears/Metal Sound
* Flash/Kinesis/Sand-Attack
* Cotton Spore/Scary Face/String Shot
Target stat lower move (sharply):
Target's stat stage is sharply lowered less than 3 times.
* Charm
* Screech
Target multi-stat lower move (slightly):
Target's stat stage is not at minimum (-10 or slow speed) for any stat lowered by the move.
* Tickle
Target multi-stat lower move (sharply):
Target's stat stage is sharply lowered less than 3 times for any stat lowered by the move.
* Memento
Weather move:
Weather is not already the weather caused by the move.
# Holding a Weather Band causes the weather to always be treated as clear; This causes a Pokémon to repeatedly use a weather move even if the weather is already up and Status Checker is enabled.
* Hail
* Rain Dance
* Sandstorm
* Sunny Day
Position-changing move:
Floor is not a special area (e.g., boss battle).
* Beat Up
* Memento
* Roar/Whirlwind
* Teleport
* Vital Throw
* (Blowback/Blowback Orb)
* (Hurl/Hurl Orb)
* (Stay Away/Stayaway Orb)
* (Switcher/Switcher Orb)
* (Warp/Warp Orb)
HP-healing move:
Target has 25% HP or less.
* Milk Drink
* Morning Sun/Moonlight
* Recover/Slack Off
* Softboiled
* Synthesis
Aromatherapy/Heal Bell/Refresh
Target has a negative status to heal.
Belly Drum
User's Attack is not maxed and belly is not empty.
Camouflage
User's type is not the type Camouflage would give for the dungeon.
Dig/Dive
User is on a tile where the move is usable.
Dream Eater
Target is asleep.
Encore
Target has used a move and is not already encored.
Endeavor/Pain Split
Target has more HP than user.
False Swipe/Super Fang
Target has more than 1 HP.
Follow Me/Substitute/(Decoy Maker/Decoy Orb)
Floor has no active decoy.
Foresight/Odor Sleuth
Target is a Ghost type and not exposed, or target's evasion is boosted.
Haze
Target has no lowered stats.
Helping Hand
User can see a teammate with non-maxed Attack or Special Attack.
Ingrain
User is not already ingrained and has < half HP (rounded down).
Knock Off
Target has a held item.
Mimic/Sketch
Target has used a move.
Nightmare
Target does not have a nightmare.
Poison Gas/Poisonpowder
Target is not poisoned or badly poisoned.
Psych Up
Target has any stat stage higher than user's.
Rest
User has quarter HP or less (rounded down) or has a negative status.
Role Play
User's and target's first Abilities don't match.
Spikes
Trap can be laid on the user's tile.
# If the user is on a trap, doesn't check if the trap is already a Spikes trap. Can lead to the user uselessly turning a Spikes trap into another Spikes trap.
Spit Up
User has Stockpile.
Spite
Target's last-used move has PP.
Stockpile
User's Stockpile count is not maxed (3).
Swallow
User has less than full health and has Stockpile.
Torment
Target has used a move and doesn't have a disabled move.
Trick
User and target both have held items.
Wish
User is not a wild Pokémon and Wish isn't already active.
Yawn
Target is not yawning or sleeping.
(Cleanse/Cleanse Orb)
User's held item is sticky.
(Takeaway/Mug Orb)
User has no held item.
(Trap Buster/Trapbust Orb)
User is standing on a trap.
===
Move weighting:
# Note: Status Checker
If Pokémon has Status Checker and Status Checker rejects the move, skip the move.
If the Pokémon is charged:
* Charge has weight 0.
* Regular attack has weight 0.
* Electric moves have their default weight.
* All other moves have weight 1.
If the Pokémon has Weak-Type Picker, use move target weight directly.
Regular attack:
Weight depends on the number of other usable moves.
0: 100
1: 20
2: 30
3: 40
4: 50
All other moves have default weights from 10-30 that are used if the Pokémon doesn't have Weak-Type Picker.
If a move has multiple possible targets and the Pokémon has a target-selection IQ skill, use an intermediate weighting system to choose a target.
* Moves targeting self/allies have a weight of 2.
* Blinker causes all moves to have a weight of 99.
Exp. Go-Getter:
Weight is the target's exp. yield.
Efficiency Expert:
Weight is 244 - target HP. If the target's HP is exactly 244, weight is 1.
Weak-Type Picker:
Regular attack weight is 2; skip all other checks.
If the target is immune to the move due to Ability, weight is 1 (Flash Fire, Levitate, Volt Absorb, Water Absorb).
If the move is weakened by Thick Fat, sunny weather, Mud Sport, or Water Sport, return 3.
If the move is resisted by the target, weight is 3.
* This includes if the target's primary type resists the move, even if the secondary type cancels out the resistance (e.g., Grass-type move against Steel/Rock type).
If the move is not resisted by the target, start with 1 (neutral), 2 (x2 weakness), or 4 (x4 weakness).
Multiply weight by 2 for each additional boost due to STAB, Blaze/Overgrow/Swarm/Torrent, Charge or sunny weather.
* Rain is not included in this check.
Add 3 to weight.
Cap weight at a maximum of 6.
===
Recalculating actions:
When a Pokémon chooses not to attack or move, or if it tries to move and is blocked by another Pokémon, it will retry the decision process for moving/attacking up to three times. This handles the case where team members are lined up out of order when following the leader (e.g., team member #3 is before team member #2), ensuring that they continue to follow a straight line.
Having to recalculate an action causes some odd effects for the Pokémon:
* If the Pokémon has a ranged move that can hit an enemy, that move has a higher chance of being used than normal. This is because the Pokémon has multiple chances to randomly select the move.
* Dedicated Traveler doesn't properly prioritize movement when the Pokémon is able to attack.
Enemies do not recalculate their actions, so there are instances where the back Pokémon in a line of enemies will pause for a turn because its move was calculated before the Pokémon in front of it.
===
Kecleon attacking enemies:
If Kecleon is damaged by an attack (e.g., Explosion or Explosion trap), he will begin moving like an enemy and targeting the player's team. However, if an enemy attacked him, he will attack enemies back, despite moving towards the player's team.
===
Wild Pokémon IQ:
Wild Pokémon always have these IQ skills:
* Item Catcher
* PP Checker
* Status Checker
They may have these IQ skills if certain conditions are met:
* Item Master: Level 16+
* Self-Curer: Bosses
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment