Commit Graph
3283 Commits
Author SHA1 Message Date
MagicBotandClaude Opus 5.5 ef6fe4aa5b Skip rubble when locating a city's warehouse building at load
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 09:21:57 -04:00
MagicBotandClaude Opus 5.5 145bb15232 Skip the warehouse delete when the owner destroys warehouse rubble
city.warehouse is already null after a combat destruction, which threw in
DELETE_WAREHOUSE. If a new warehouse was placed it would have deleted that
one instead, so only a live (rank != -1) warehouse clears city.warehouse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 09:20:21 -04:00
MagicBotandClaude Opus 5.5 e64d64bf18 Keep destroyed warehouse contents in memory so the rubble can be looted
destroyOrDerank nulled city.warehouse on destruction, so the loot click
found no warehouse and returned silently. The destroyed Warehouse is now
held in Warehouse.destroyedWarehouses keyed by the rubble building UUID
until it is looted empty, the rubble is destroyed, or the city places a
new warehouse. Contents are not persisted across a reboot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 09:19:40 -04:00
MagicBotandClaude Opus 5.5 0865a7be74 Log only the JSON error and workorder ID when a workorder fails to load
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 08:24:04 -04:00
MagicBotandClaude Opus 5.5 a079deef8d Log only the JSON error and city UUID when a warehouse fails to load
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 08:23:18 -04:00
MagicBotandClaude Opus 5.5 963130565e Make MB_MINION_SPAWN_TIME a required ConfigManager entry
0 or blank keeps the normal guard/siege minion spawn timers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 08:00:53 -04:00
MagicBotandClaude Opus 5.5 becab380d2 Add optional MB_MINION_SPAWN_TIME override for guard and siege minion spawns
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 07:41:16 -04:00
MagicBotandClaude Opus 5.5 5c78bc7fa5 Skip the shopkeeper rune when applying an NPC rune set
applyRunesForNPC already adds 252620, and most rune sets repeat it, so
NPCs with a set listed the shopkeeper rune twice after the runeSet fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 14:30:18 -04:00
MagicBotandClaude Opus 5.5 4e30a04619 Fix /makeitem looking up the template by string instead of template id
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 14:06:10 -04:00
MagicBotandClaude Opus 5.5 42a1c8a532 Fix Warehouse.loot looking up the template by enum instead of template id
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 14:06:10 -04:00
MagicBotandClaude Opus 5.5 2a2c528981 Fix NPC rune sets storing the set id instead of the rune id
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 14:06:10 -04:00
MagicBotandClaude Opus 5.5 58e0fa32fb Add dev-only DB/JSON parity check at world boot
ParityCheck compares DB-built objects with the cache JSON and logs
table/id/field differences plus a per-table summary. It runs only when
the optional env var MB_PARITY_CHECK=true is set; it is not added to the
ConfigManager enum because init() aborts on any missing enum entry.

First comparator: static_rune_baseclass name vs RUNE obj_name.
No gameplay values change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 13:51:22 -04:00
MagicBotandClaude Opus 5.5 62b4a2a897 Skip cache JSON files whose name is not a 32-bit template id
The client cache holds RUNE/10788957847552 (2512 << 32), which would
overflow Integer.parseInt and abort the rune load. Such files are now
skipped with a warning. The file is not in MBDATA yet, so the
880/2695/4011 counts are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 13:44:45 -04:00
MagicBotandClaude Opus 5.5 d9d1c41d9e Add CObjectIndex lookups over the cache templates
Built at login and world bootstrap after the three parsers load (Task 0.1):
- lookup(id) across ITEM, then DEED, then RUNE
- race (MonsterType) -> creation race rune ids, male and female
- ClassType -> class rune id, DisciplineType -> discipline rune id
- SBStringHash(rune_sub_type) token -> runes
- skill and power name <-> SBStringHash token, from every template field
  that names one

No consumers yet; no values change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 13:33:35 -04:00
MagicBotandClaude Opus 5.5 cb427de440 Add CObjectTemplate marker interface for cache templates
ITEM, DEED and RUNE templates share one id space (JSON-Refactor-Plan D1).
Empty for now; the shared getters come with Task 1.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 13:33:34 -04:00
MagicBotandClaude Opus 5.5 74828c620d Load item cache JSON at login and world server bootstrap
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 09:51:20 -04:00
MagicBotandClaude Opus 5.5 fbd38732dc Add ITEM cache JSON parser
ItemTemplate follows ArcItemTemplate_Load (sb.exe 0x4AABD0): weapon and
armor blocks keyed by item type, sheath and stub blocks, and empty equip
slot masks read as empty sets. Adds SheathSlot and readHashLabel, which
keeps unresolved hashes such as item_skill_used in 195340.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 09:51:20 -04:00
MagicBot 75e10f613f Reporting within parser 2026-10-17 08:46:23 -04:00
MagicBot 783d2d4dc9 Bootstrap count reporting for DEED/RUNE 2026-10-17 08:40:37 -04:00
MagicBot 3870b283d8 Bootstrap count reporting for DEED/RUNE 2026-10-17 08:39:48 -04:00
MagicBotandClaude Opus 5.5 542ae79e2c Load deed and rune cache JSON at login server bootstrap
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 07:49:09 -04:00
MagicBotandClaude Opus 5.5 08d4bc2501 Treat unknown enum values in deed and rune JSON as parse failures
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 07:48:11 -04:00
MagicBotandClaude Opus 5.5 7309159f83 Abort world server startup when any deed or rune file fails to parse
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 07:45:24 -04:00
MagicBotandClaude Opus 5.5 ad476db166 Abort world server startup when deed or rune templates fail to load
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 07:44:42 -04:00
MagicBotandClaude Opus 5.5 a75cbb5cc1 Load deed and rune cache JSON at world server bootstrap
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 07:43:48 -04:00
MagicBotandClaude Opus 5.5 2bee93087d Add static template maps to DeedTemplate and RuneTemplate
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 07:42:00 -04:00
MagicBotandClaude Opus 5.5 99a4a6741a Remove unused StringUtils.hashString and FastMath.hash
Neither matches the client string hash; Hasher.SBStringHash does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 14:52:46 -04:00
MagicBotandClaude Opus 5.5 1ac5a248db Read named grant keys and signed values from new COBJECTS JSON
Grant pair lists now carry name strings ("HLR-021", "Unarmed Combat")
instead of integer hashes, so they are stored as name -> value maps.
Unresolved hashes are kept as their decimal string and logged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 14:46:37 -04:00
MagicBotandClaude Opus 5.5 b56d4ee243 Note lossy power action maps in ItemTemplate
item_user_power_action and item_power_action are keyed by power, so
rune step tables (repeated powers, multiple power_actions entries) are
collapsed to one entry. Nothing reads the rune data today; the new
RuneTemplate keeps the full lists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 20:21:41 -04:00
MagicBotandClaude Opus 5.5 0fb1c078ad Normalize case and punctuation in DamageType.getDamageType
The validity check compared names case-sensitively, so mixed-case
input such as "Fire" or "Crushing" from static_power_failcondition and
static_power_poweraction, and SourceType names in the fortitude check,
all resolved to NONE. Input is now stripped of spaces, commas and
hyphens and upper-cased before lookup, so "Anti-Siege" maps to
ANTISIEGE as well.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 20:18:38 -04:00
MagicBotandClaude Opus 5.5 c14231afb9 Add RuneType enum and DamageType.ANTISIEGE
RuneType covers the rune_type values in the client cache data
(CLASS, DISCIPLINE, RACE, TALENT). ANTISIEGE matches the
combat_attack_resist key in the cache data.

RuneTemplate.rune_type and combat_attack_resist on both cache
templates now use these enums.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 20:16:05 -04:00
MagicBotandClaude Opus 5.5 0d48080e38 Add cache parsers and POJOs for DEED and RUNE templates
New engine.parsers package:
- cache: DeedParser and RuneParser load COBJECTS/DEED and COBJECTS/RUNE
  JSON straight from the data dir, keyed by file id. CacheParserUtil
  holds the shared JSON helpers.
- objects: standalone DeedTemplate and RuneTemplate covering every
  field in the client data, plus shared PowerGrant/UserPowerAction.
- wpak: placeholder for upcoming wpak parsers.

Not wired into server startup yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 11:09:41 -04:00
MagicBot 777f7ad89d Merge branch 'subdate3' into magicbox-1.5.2.1 2026-10-15 09:58:34 -04:00
MagicBotandClaude Opus 5.5 40799f96f6 Mark summoned pets with MASK_PET
Summoned pets (not necro pets) now carry MASK_PET, so pet-targeted
AOE powers can find them. The checkForAggro pet scan is held off with
PET_AGGRO_ENABLED until it checks rune enemy lists, filters targets
and keeps pet targets (plan-mask-pet.md steps 2-4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 09:19:36 -04:00
MagicBotandClaude Opus 5.5 5262a602da Keep siege engine target when a new player loads it
InterestManager cleared the combat target of every live mob loaded for
a new player, so a siege engine firing at a wall dropped its target
whenever someone entered load range. Siege engines now keep it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 09:05:24 -04:00
MagicBotandClaude Opus 5.5 5b80614376 Restore regular mob MASK_PET aggro scan
The scan was removed as dead code, but creature runes list Pet in
rune_enemy_monster_types, so monsters are meant to aggro summoned pets.
Restored unchanged; it stays inactive until MASK_PET is set from the
rune data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 09:00:27 -04:00
MagicBotandClaude Opus 5.5 b60f2754f1 Remove siege and pet auto-aggro scans
Guard MASK_SIEGE and regular mob MASK_PET scans were dead code: no mob
ever carries either mask. Removed so they cannot start auto-aggroing
siege engines if the masks are wired up later. Safehold guards no
longer aggro siege engines. Guards still respond to a siege engine
damaging a city building.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:53:57 -04:00
MagicBotandClaude Opus 5.5 89cdf5655d Flag players hostile for damaging siege engines on a city grid
Damaging a siege engine on a city grid adds the attacker (or the owning
player, for pets) to that city's outlaw list, unless they are in the
city's nation or an allied nation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:53:24 -04:00
MagicBotandClaude Opus 5.5 c9208000bb Pull siege engine aggro on damage only
A siege engine switches to whoever damages it, player or pet, even when
it already has a target. Pre-roll melee retaliation, harmful-power
direct aggro (which also fires on misses) and Taunt no longer change a
siege engine's target. The attack timer is untouched, so a switched
engine still waits for its next cycle before firing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:52:56 -04:00
MagicBotandClaude Opus 5.5 531a2d028b Drop siege engine targets only on death or attack range
Siege engines dropped player targets at 100 units, at the 200 unit
drop-aggro range, or when the player was missing from playerAgroMap,
all well inside their 350 attack range. They now hold a character
target until it dies, can't be seen, or leaves getRange().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:52:09 -04:00
MagicBotandClaude Opus 5.5 ca33c5a14c Keep siege engines alive and targeting when released
Owner death, logout or invisibility dismissed a commanded siege engine
by clearing its target and marking it dead. Released engines now revert
to MOBILE in place, stay alive and keep their current target so any
nation member can re-command them with a Rod of Command. Commanding an
engine no longer clears the target of the old or new engine.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:51:38 -04:00
MagicBot 5868530414 mobai aligned with rune data and client. 2026-10-15 07:31:30 -04:00
MagicBotandClaude Opus 5.5 66a731005e Use race rune natural attack damage for unarmed players
Unarmed base damage was a hardcoded 1-3 (TODO). Read it from the race
rune natural attack for the swinging hand (1-4 for all races), then
scale it with the existing formula, matching the client (0x46D200).
Falls back to 1-3 if the rune has no natural attack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 07:24:33 -04:00
MagicBotandClaude Opus 5.5 330db50985 Use rune ATTACK for regular mob ATR
The client (0x466570) gives mobiles their ATR straight from the rune
ATTACK. Read rune_attack from the rune template, falling back to the
mobbase atr when the rune has none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 07:15:26 -04:00
MagicBotandClaude Opus 5.5 12c08c940a Use rune MINDAMAGE/MAXDAMAGE for regular mob damage
The client (ArcMobile, 0x46D200) takes mob damage straight from the rune
MINDAMAGE/MAXDAMAGE with no stat scaling; natural attack damage is only
scaled for non-mobile characters. Read rune_min_damage/rune_max_damage
from the rune template, falling back to the mobbase row when the rune
has none. 2689 of 2770 mobbase rows already match the rune.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 07:13:52 -04:00
MagicBotandClaude Opus 5.5 b21ccdbb4c Use rune natural attack range for unarmed mobs
Unarmed mobs now add their rune natural attack range in processAttack
and use it in getRange. Most melee runes have 0, so they are unchanged;
ranged plant mobs (Gasser, Spitter, Needler, ...) get 150, Shuggra 50.
Natural range is not subject to the unverified 80 clamp.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 07:05:25 -04:00
MagicBotandClaude Opus 5.5 a708a1f0b2 Use rune natural attack range for siege engines
Siege engine range was hardcoded to 300. Read it from the rune natural
attack instead (350 for Trebuchet, Mangonel and Ballista), matching the
client's RecalcMinWeaponRange. Falls back to 300 if the rune has none.
getNaturalAttack now returns the whole entry so speed and range share
the lookup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 07:04:11 -04:00
MagicBotandClaude Opus 5.5 b525a7a3ab Document verified rune natural attack layout
Field layout of rune_naturalattacks confirmed in the client (IDA): it is
the same attack info struct as a weapon, so [0] is WEPSPEED.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 07:01:57 -04:00
MagicBotandClaude Opus 5.5 b690195233 Use race rune natural attack speed for unarmed players
Extend getNaturalAttackSpeed to resolve the rune from the attacker type:
mobbase rune for mobs, race rune for players. Unarmed players now swing
at their race rune speed (20 = 2.0 s per hand) instead of a flat 5000 ms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 06:56:21 -04:00
MagicBotandClaude Opus 5.5 9aa44d4e9a Use rune natural attack speed for unarmed mobs
Unarmed mobs used a flat 5000 ms swing delay. Parse rune_naturalattacks
from the rune template and use its speed (x100 ms) instead, with the
AttackDelay modifier and 1.0 s floor applied as for weapons. Siege
engines now fire every 17.5 s (speed 175); most creatures swing every 3.5 s.
Falls back to 5000 ms when the rune has no natural attack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 06:53:50 -04:00