- Statue HP overridden to 100k at spawn (MaximumHealthOverride) for the test phase - no DB change.
- Guards made fully stationary by overriding their definition's IntelligenceTypeName to
NullMonsterIntelligence at runtime (no wander, no chase); no DB change.
- Statue/guard in-game names rebranded to 'TvT Statue' / 'TvT Guard' (runtime designation override).
- Bosses: 306/309/357/459 spawn once at (55,42)/(32,42)/(31,59)/(56,58) after 3 total statues broken.
- Guards/bosses spawn in a walkable BOX (retry) instead of a fixed point; several statue-guard
offsets landed on non-walkable terrain and silently failed, leaving statues unbreakable.
- Guard-alive gate uses the ACTUAL spawned count so a statue can always reach 0 -> breakable.
- HeykelSavasiStartPlugIn.OnStartedAsync force-disposes a lingering finished context so GM /starths
restarts the event immediately (no server restart).
- Statue-break + join messages translated to English.
A forced start (e.g. /starths) was blocked for the whole TaskDuration after a
run even though the event had already ended, so re-starting needed a server
restart. ForceStart now skips the 'previous event still running' guard;
scheduled auto-starts still respect it.
SendOpenedNotificationsAsync only looped per full minute, so a <1min entrance
(e.g. a 30s test window) sent no golden 'event opened' notification. Now sends
one up front when TotalMinutes==0. >=1min windows unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Instead of a fixed lane, each statue (and its 4 guards) now spawns at a random
walkable coordinate anywhere on the map; breaking one reveals the next at a new
random spot, so players must search for it. Falls back to the fixed positions.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- HeykelSavasiContext.IsItemAllowedToEquip disallows wings/capes during
Playing only (so entry is never rejected for wearing wings); auto-unequips
any equipped wing/cape into a free inventory slot in OnGameStartAsync.
- New S2C packet HeykelSavasiHudState (C1, code FB, length 11) carrying
phase, team, counts, statue progress and remaining seconds, plus its view
plugin/interface, broadcast once per second across registration/prep/
battle and one-shot on join/statue-break/game-end.
#1: block all player-vs-player damage while State != Playing (registration/
prep), keep same-team friendly-fire off during battle. Prevents pre-battle
kills (which also caused deaths to route to Lorencia instead of a base).
#3: remove a player from their team on OnObjectRemovedFromMapAsync (real
leave to another map), not on same-map death-respawn, so team counts stay
accurate and re-joining works.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GetTeamSpawnGate matched gates by exact X1/Y1 anchors, which threw
'Sequence contains no matching element' when the DB gate coords drifted a
tile from the code anchors. Now selects the two spawn gates by Y-order
(red=top, blue=bottom) so it works regardless of exact coordinates.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
AddHeykelSavasiEventUpdateSeason6 (version 100): adds map 92 + terrain,
statue/guard monsters, red/blue base gates, event NPC 560 in Lorencia, and
the mini-game definition to an EXISTING config via the admin Updates page
(no DB wipe). Reuses HeykelSavasiMap/HeykelSavasiInitializer; idempotent.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Embed Terrain93.att (server map No 92 -> loads Terrain93); map Number 90->92.
- Real walkable coords from the LoL arena diamond (center lane x=42):
Red base (42,10) top tip, Blue base (42,92) bottom tip; 7 statues per team along x=42.
- Client World93 + Object93 deployed to PC client separately.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A player could destroy their own team's Heykel Savasi statue: the win-condition
attribution (OnDestructibleDied) trusts geometry alone (attacker = Opponent of
defender), and the old friendly-fire guard only covered Player targets, not
Destructible statues. Block same-team damage at the NPC damage intake instead
so only the enemy team can ever land a hit on a statue.
Adds HeykelSavasiContext runtime logic for Task 4.2: per-team statue
break progress/winner tracking (extracted into a pure, testable
StatueProgressState), OnDestructibleDied wiring against the base
MiniGameContext's existing Destructible->Died auto-subscription, and
SpawnStatueAsync which spawns the next statue (561) + 4 guards (580)
via the map initializer using placeholder line-of-statues coordinates.
OnGameStartAsync now spawns each team's first statue after the warp.
Adds the HeykelSavasiTeam enum (None/Red/Blue) and the HeykelSavasiContext
skeleton (subclass of MiniGameContext) with team registration
(AssignTeam/GetTeam/PlayersOf/TeamCount) and a join-balance rule
(|Red-Blue| <= 2 after the prospective join), exposed as a pure static
IsJoinAllowed for fast unit testing without constructing the full context.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds HeykelSavasiMap (BaseMapInitializer, Number=90/World91) as an empty
terrain-only skeleton and registers it in GameMapsInitializer. Statue/guard
monster definitions and spawns are added by later Heykel Savasi tasks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Six high-tier imported wings, one per class line: Wizard (242, Soul Master),
Magic (243, Duel Master), Elf (244, High Elf), Summoner (245, Dimension Master),
Warrior Cape (246, Lord Emperor + Fist Master) and Knight (247, Blade Master).
Each: base defense + defense-per-level, 3rd Wing Options, damage increase and
fast flight. Applied via update v99 (AddWarriorWingsUpdateSeason6), reusing the
shared "3rd Wing Options" option set to avoid Guid collisions.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Switch from the basic CreateWing overload to the full one: base
defense 65/60, defense-per-level, wing options (HP recover / phys
damage / defense), damage increase, fast flight. Level req 100.
Same pattern as Arkania: terrain resources Terrain84-87.att, map
initializer classes, registration, and update-plugin (v97) that
creates each map + spawn gate + /move warp AND assigns it to the
game server configuration so it is hosted. Also fix the Arkania
update-plugin to assign the game server config (was missing).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Client tried to load World84 for map 83; MU client world index is
server map number + 1 (Lorencia 0 -> World1). Arkania client assets
are World83, so the server map number is 82 and the terrain resource
is Terrain83.att (number+1).
MoveHomeAsync wrote PositionX/PositionY/CurrentMap/Rotation on the character
record directly, which is a partial copy of Player.PlaceAtGateAsync: it placed
the player but skipped removing him from the map and telling the client.
Player.Position is backed by those very fields, so the coordinates jumped on the
server while the client never got a map change. The client then interpolated a
walk to the new spot and the character visibly slid across the map after a reset.
WarpToAsync does the same placement plus the map removal and the map change
notification, and it handles respawning on the same map. It is the path every
other caller uses (duel room, gate NPCs, mini games, castle siege portal).
The existing tests all ran with MoveHome = false, which is why this path was
never covered. The new test pins the notification: it fails on the old code
because MapChangeAsync is never invoked.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two new weapons placed at free item slots so they never collide with
standard Season 6 items. The client name DB (Item_eng.bmd) is the source
of tooltip name/stats, so only free slots are usable for custom items.
Both seed paths are covered:
- Fresh DB: Weapons.Initialize() calls the new CreateImperialWeapons050().
- Existing DB: AddImperialWeapons050UpdateSeason6 (UpdateVersion 95),
applied from the AdminPanel Updates page, with an idempotency guard.
Imperial Sword is a Magic Gladiator weapon (copy of 0/28), Imperial Staff
is a Wizard weapon (copy of 5/31).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>