Entry 103
The party in a field: members join and leave the running fights
Documented in Leaving the town - Kite in a field and its dungeon.
Filescrates/piney-world/src/field_world.rscrates/piney-game/src/area_host.rscrates/piney-game/src/area.rscrates/piney-game/src/session/event11.rscrates/piney-world/examples/world_probe.rstools/test_party_rs.pydocs/engine/field-walk.md
Outside the towns, party_add and party_remove fell to the event host's
default, which does nothing. So did the field UI's AddMember,
DelMember and TransferOut requests. Event 11 hit this first: at the
end of the church its tail runs party_remove 15, and BlackRose stayed in
the party.
What the game does
The same functions run as in Mac Anu (field-game.md):
ccParty::AddMember(gcmn 0x0059ce80): the first slot whosememberIDis -1 getsinviteSpc(id)(0x005a08e0).- For a registered id,
inviteSpcsets the registry'spartyFlagto 1. - If the character is built, its own flag (+0xe0 bits 14-16) changes
too: -2 turns
recallFlagon, -1 clears recall and becomes 1, and 0 becomes 1. - It returns the character pointer. When that is null, the slot's
memberCharis 0,memberIDstays -1 and AddMember returns -1.
- For a registered id,
ccParty::DelMember(0x0059cf60) acts only on slots above 0 whosememberIDis not -1. It setsmemberCharto 0 and callsdisbandSpc(0x005a0f50): the registry's flag becomes 0, and the character becomes -2 with recall off if it was recalled, else -1. ThenmemberIDis -1 andnumgoes down by 1.expulsionSpc(0x005a1070) is justDelMember(CheckMemberID(registry[listNum].id)).
The port
party.rs's Spcs already had all of these for the town.
Party changes. FieldWorld now has party_add, party_remove and
transfer_out. They run these functions over the fights' characters
(with_party, the BattleChars adapter). After a change,
Combat::set_party rebuilds the fights' ccPartyManager from memberID.
A member who leaves drops out of the fights, the panels and the AI's
party. One who joins is back in.
Who calls them.
area_host.rsroutes cases 77 and 78 to them.party_addalso sets the new slot's menu face, as the town's host does.area.rsanswersAddMember,DelMember(slot)(asparty_remove -slot) andTransferOutfor a party handle.
A dismissed leaver. When the fellow task lets a leaver go (partyFlag
-2 and act 14 set exitFlag), the game's ccThFellow02 calls
expulsionSpc and deletes the character. The port now does the same
after each combat frame (fellows_gone):
Spcs::expulsionwith the character's flag, which also frees the registry slot unless it is still a member;- the character dropped from the fights' members and cast.
Checked
- Against the game.
tools/test_party_rs.pyrunsAddMember,DelMemberandexpulsionSpcnatively in eemu, withinviteSpc,disbandSpcandCheckMemberIDbeneath them. It uses 600 random registries and parties and the characters' whole +0xe0 words, with one to five calls each. The world_probe's newpartyrequest runs the same calls onSpcs.- Compared: each return, the registry's ids and flags,
memberChar,memberID,num, and each character'spartyFlagandrecallFlag. - None differ. The adds return slots 1 and 2 and -1, and 235 of the runs change the registry's flags.
- Compared: each return, the registry's ids and flags,
- The session.
event_11_church_ends_with_blackrose_outplays event 11 from the join through the church. It checks:- BlackRose is in the party on the holy ground;
party_remove 15leaves her registry flag 0 and her character's flag -1, with the party without her;- the party the field hands back to the session is without her;
take_unported()is empty.
- The workspace's tests, clippy, fmt and the docs check also pass.
- Adding a stranger. When an unregistered id is added and the registry has room,
inviteSpcbuilds the character at the Chaos Gate (ccGetChgatePosDirc,inviteOffsetTbl). That is not ported: the add does nothing. No event script adds anyone (noparty_addat all), so only the menus could reach it. - The town doesn't take the party back. Mac Anu still starts from its own registry, not the party the field returns (field-walk.md's Unknown). - Only the rules are compared. The fellow task's own frames are not run against the game in a field: when a dismissed leaver's exit happens, and the walk away before it.