goldbox.strength¶
Party strength: the number random encounters are sized from.
PARTYSTRENGTH is ECL opcode $1D, implemented at DUNGEON $1BE8. Twelve of
the thirty area scripts call it, and in every one of those the value becomes –
after a divide, and sometimes a random reduction – the count operand of
LOADMON: literally how many monsters are placed in the fight. The slums use
(strength / 3) * 2.
Nothing stores it. The routine walks the eight roster slots on every call and
writes only to the ECL variable its operand names, which is why this module
recomputes rather than reads a byte. See docs/114-party-strength.md.
The biased fields are used as stored, not as decoded. The THAC0 and armour
class fields hold 60 - value, and the routine subtracts its own constant from
the byte: 39 from THAC0, 60 from armour class. RosterBlock.thac0 would hand
back the number on the character sheet, which is the wrong end of the encoding
for arithmetic the game does in the stored space.
No Qt and no transport: from_bytes takes the two blocks a save file or a live
read both produce, and read_live takes anything with a read(address, length).
Module Attributes
Roster |
|
wounds do not shrink a Pool of Radiance encounter, though Curse of the Azure Bonds' version of the same routine reads current and they do there. |
|
What the routine subtracts from each biased field. |
|
the 16-bit sum, divided once at the end. |
Functions
|
From the two blocks the game keeps the party in. |
|
From decoded saves. |
|
From a running game, through anything with |
Classes
One roster slot's share of the sum, term by term. |
|
What |
- class goldbox.strength.Contribution[source]¶
Bases:
objectOne roster slot’s share of the sum, term by term.
The breakdown is the useful part: a total of 130 says nothing about what to change, and “MALCYON 27” beside “BRUTUS 26” says the wizard is pulling as hard as the fighter.
- __init__(slot, name, thac0_term, hp_term, armour_term, cleric_term, magic_user_term, thac0_field=0, armour_field=0, level=0, wrapped=False)¶
- goldbox.strength.DIVISOR = 10¶
the 16-bit sum, divided once at the end. CoAB divides per character instead, so with six characters this is systematically the larger by up to 5.
- Type:
$1C51
- class goldbox.strength.PartyStrength[source]¶
Bases:
objectWhat
PARTYSTRENGTHwould return right now, and where it came from.- __init__(parts)¶
- Parameters:
parts (tuple[goldbox.strength.Contribution, ...])
- Return type:
None
- parts: tuple[goldbox.strength.Contribution, ...]¶
- goldbox.strength.RECORD_HP_MAX = 118¶
wounds do not shrink a Pool of Radiance encounter, though Curse of the Azure Bonds’ version of the same routine reads current and they do there.
- Type:
Record offsets. Hit points maximum, not current
- goldbox.strength.ROSTER_STATUS = 0¶
Roster
+0x00, the byte the routine tests before it does anything else: zero for an empty slot, bit 7 for a dead one ($01->$84was seen going in on death).$1BF6 BEQ / BMI– a dead character stops counting, so a party that loses somebody meets smaller encounters until it raises them.
- goldbox.strength.THAC0_OFFSET = 39¶
What the routine subtracts from each biased field. THAC0’s subtraction at
$1C01has no underflow guard; armour class’s at$1C16has one (BCC), which is why only the second has a floor here.
- goldbox.strength.from_bytes(save0_bytes, roster_bytes)[source]¶
From the two blocks the game keeps the party in.
save0_bytesis$4900-$64FF– aSAVEDGAME0payload, or the live read of the same range – androster_bytesthe roster page at$8300. Both are whatautomap/live.pyalready reads on every poll.- Parameters:
- Return type:
- goldbox.strength.from_saves(save0, save1)[source]¶
From decoded saves.
save1may be aSaveGame1or the roster bytes.- Parameters:
save0 (goldbox.savegame.SaveGame0)
- Return type: