Entry 223
Mutation's party AI
Filescrates/piney-battle/src/party_ai.rscrates/piney-battle/src/affect.rscrates/piney-battle/src/event.rscrates/piney-battle/src/kite.rscrates/piney-battle/src/tables.rscrates/piney-world/src/combat/chat.rstools/volume.pytools/test_battle_party_ai_rs.pytools/test_battle_rs.py
tools/test_battle_party_ai_rs.py passes all 75 of its checks on
Mutation: Infection's 73 and two for functions Mutation adds. Infection
still passes all of its own. The rework of piney_battle::party_ai took
five commits. Each Mutation rule sits behind self.t.volume, so
Infection's code paths are as they were.
ccAI's new fields
- +0x24, the attack command's target (
Ai::cmd_attack_target).ChatCommandcopiestargetCCmdinto it when it accepts command 11.ChatCommandExecute(11) andReconnoiter(strategy 4) follow it ([Ctx::attack_cmd_target]).targetCCmdstays at +0x20 and still takes every request's target. Worklog 221 and commit 975c083 put the new int at +0x20;RequestChatCmd's store shows it is +0x24.volume.ai_atnow moves Infection's offsets from +0x24 on. - +0x9a and +0x9c, the biggest recent hit and the biggest hit
(
hit_recent,hit_max). BothInfluencefunctions pass each hit to an unnamed function (gcmn 0x005c1a60,Ai::note_hit). It caps the hit at half the member's maxHP and raises both fields. A party member's hit is recorded even when it is down; Kite's only when he is up. The rule emitsEvent::NoteHit, which the field's chat pass applies.ChatCommandclears both at a win. Kite'sReadSysMsg2clears the recent one andbattleFlag.
On later volumes the harness appends the three fields to AI_LAYOUT,
and the probe reads and writes them after the message entry.
Modes, strategies and swayed members
- Mode 4 is new: hold. Infection's modes 4-6 become 5-7 (
mode_of,Ctx::mode_no,Ctx::inf_mode). A held member acts unless a boss is in (CheckBossEntry(1)). - Strategy 6 is a standing hold.
- Most requests turn it back into 3 first.
- The spells command (14) makes a standing 3 (or 0 or 2 while the strategy is 3) into 6.
- In battle, command 14 with strategy 6 stops the member and holds it.
- A refused command turns 6 back into 3, with
skillMask4 andselfFlag.
- Charmed or confused members.
Reconnoitersearches for a foe first.SearchTargettakes Kite's target only on the same side.SearchTargetNearhas no range limit for the party.- In a field, a member closing in for a commanded skill drops the command and fights.
- A member in battle mode that loses its target stops, in a dungeon too.
Healing and cures
- The heal line is a rate (
CheckNeedHealingandCheckHealPartytake a float, asfptosi(maxHP * rate / 100)). - Notes are due sooner. Heal, cure, revive and buff notes are due in
30 frames on the member's first action, then in 1 (
plan_delay). - Items before skills.
HealPlzNormalModeandHealPlzBattleModeask a new function (0x005c1ae0,Ctx::item_first) whether items come first.- It answers -1 when the member cannot act, and 1 when it stands alone
(0x005c8300,
Ctx::live_members). - It also answers 1 when every other member is unable, or when every other member is in danger: HP at most its recent hit, or a tenth of its maxHP.
HealSPC,ResurrectSPCand bothCureOnlyfunctions take the answer.
- Poison and curse. The normal mode's poison cure is a new function
(0x005ac400,
Ctx::cure_poison_curse_spc). It also cures curse (skill 162). - Battle-mode order. Paralysis and sleep are cured before the heal.
ChatCommandHealPlz.- A member that has acted looks every tenth frame.
- A held member heals too.
- The member must be free to use a skill or an item.
- Out of battle the strategy comes back only once no one is below full HP.
ReadSysMsg, kinds 2-0xb (Ctx::read_use_later).- A use is skipped unless the patient needs it. A revive needs one down (2-4). Any other use needs one alive; a heal also needs one below full HP, and a cure needs the condition.
- Item uses announce nothing here (
UseItemremarks instead). - After a buff or debuff use only a debuff command (17) is done.
- Kind 0xc and broadcasts 23 and 24 do nothing.
Buffs and debuffs
- The planners take a check argument: 0 plans; 1 reports; 2 reports on the SP alone. They also keep a candidate list (global 0x774730).
ChatCommandBuffPlzandChatCommandDeBuffPlz(Ctx::chat_command_plz_later).- They look every 35th count, a held member too, and only when it is free to use a skill or an item.
- Out of battle, with nothing planned, the member goes back to its
strategy only if a check finds no one to help. The checks are
0x005c2060 and 0x005c1cc0 (
Ctx::plz_check). - For buffs, no buff for the member may be on the bus or delivered in the last 37 frames (0x005b42c0).
- It then says
OnlyBufforOnlyDebuff.
ChatCommandFulfilCheck.- The buff and debuff commands are refused with that remark when the check finds no one and none is on its way (0x005b4020, 0x005b4170).
- The heal command is taken in battle even when no one needs a heal.
- The arts-and-spells command (0) accepts attack-spell items.
Commands
RequestChatCmdwrites the target totargetCCmdas Infection does. The arts commands (0, 13) keep a standing strategy 1 or 4.ChatCommandhas no "same command again" path. Every new command goes throughChatCommandFulfilCheck.ChatCommandExecute.- Commands 5 and 99 take
targetCCmdonce and clear it. - The Sprite Ocarina's last use says
UseLastIteminstead ofUseOcarina.
- Commands 5 and 99 take
Fixes on the way
piney_battle::tables.TableshelddebuffTableIndexandbuffTableIndexas[i16; 18], andtry_into().unwrap_or_default()turned Mutation's 21 rows into zeros. They are slices now. The other fixed-size tablesexpecttheir size, and a test loads all four volumes.- The harness's bus. Random messages of kind 6 now carry a skill id,
and kind 7 an item code. The game read an item code as a skill and ran
off RAM in
ccSkillCheckType. - The harness's entry field. It is found by name (
AI_AT["entry"]), no longer as the list's last field.
The game's windowed history walk (0x005b42c0) never moves past a delivered item use whose item casts nothing; the port passes it over instead of hanging. Ctx::item_first reads a member without an AI as having no recent hit. The game reads through that null pointer. Who sends message kind 0xc and broadcasts 23 and 24 is unread. The fellow, kite, event, navi and spawn harnesses have not been rerun on Mutation since this work.