Skip to content

Castle Siege Crown & Switch Win-Condition Mechanics #726

@sven-n

Description

@sven-n

Summary

Implement the core Castle Siege win condition: the crown capture system. Three players from the same attacking side must simultaneously occupy the crown and both switches for a configured duration to capture the castle.

Prerequisites

Requirements

1. CheckMiddleWinner()In GameLogic/CastleSiege/CastleSiegeCrownMechanics.cs (new file)

Called every tick (every second) during Start state.

Logic:

  1. Get CrownUser, SwitchUsers[0], SwitchUsers[1] from CastleSiegeContext.
  2. All three must be:
    • Non-null.
    • Alive (IsAlive).
    • In a guild (GuildStatus != null).
    • On an attacking side (not None, not Defense).
    • On the same attacking side.
  3. If conditions are not met:
    • If the crown user changed or left, send CrownAccessState.Fail to the previous user.
    • Do not reset accumulated time (capped at CrownHoldTimeSeconds - 1 on fail).
    • Return.
  4. Increment CrownAccumulatedTime by the tick interval (1 second).
  5. Send CrownAccessState.Attempt to the crown user with the current accumulated time.
  6. If CrownAccumulatedTime >= Configuration.CrownHoldTimeSeconds:
    • Send CrownAccessState.Success to the crown user.
    • Call ChangeWinnerGuild().

2. ChangeWinnerGuild() — In the same file

Called when a capture succeeds.

Logic:

  1. Set MiddleOwnerGuildId to the crown user's guild ID.
  2. Swap sides:
    • The capturing guild's side becomes Defense.
    • The previous Defense side becomes the capturing guild's old attack side.
  3. Call SetPlayerJoinSideAsync(killLifeStones: true) to:
    • Re-assign all players to their new sides.
    • Kill all Life Stones.
  4. Respawn all non-defense players to the attack respawn area.
  5. Lock the crown (IsCrownAvailable = false).
  6. Reset CrownAccumulatedTime to zero.
  7. Clear CrownUser and both SwitchUsers.
  8. Broadcast CastleSiegeOwnershipChangeNotification to all players on the CS map.

3. SendSwitchInfo()In GameLogic/CastleSiege/CastleSiegeSwitchMechanics.cs (new file)

Called every second during Start state.

Logic:

  1. For each switch (0 and 1):
    • Send CastleSiegeSwitchInfo packet to all players on the CS map with:
      • Switch ID, state (empty/occupied), occupant's join side, guild name, character name.
  2. Determine crown availability:
    • If both switch users are non-null and on the same attacking side → IsCrownAvailable = true.
    • Otherwise → IsCrownAvailable = false.
  3. Send CastleSiegeCrownStateUpdate to all players with the current lock/unlock state.

4. Crown Access State Broadcasting

When the crown user's state changes, send CrownAccessState packet:

Value Name When
0 Attempt Player is actively pressing, accumulating time
1 Success Capture completed
2 Fail Player was interrupted (killed, left, switch broken)

The packet includes the accumulated time in milliseconds.

5. CheckResult() — Called when Start timer expires

In CastleSiegePlugIn.OnEnterStateAsync(End):

  1. If MiddleOwnerGuildId has a value → that guild is the new castle owner.
  2. If MiddleOwnerGuildId is null → the existing castle owner retains ownership.
  3. If ownership changed:
    • Update CastleSiegeData.OwnerGuildId, IsOccupied = true.
    • Reset tax rates to 0, tribute money to 0 (Phase 10).
  4. Save to database.
  5. Broadcast ownership result.

6. View Interfaces & Remote Views

  • ICastleSiegeCrownStatePlugIn — sends crown lock/unlock state.
  • ICastleSiegeCrownAccessStatePlugIn — sends crown access state (attempt/success/fail) to the crown user.
  • ICastleSiegeSwitchInfoPlugIn — sends switch occupant info.
  • ICastleSiegeOwnershipChangePlugIn — sends ownership change notification.

Files to Create

File Description
GameLogic/CastleSiege/CastleSiegeCrownMechanics.cs CheckMiddleWinner, ChangeWinnerGuild, CheckResult
GameLogic/CastleSiege/CastleSiegeSwitchMechanics.cs SendSwitchInfo, crown availability
GameLogic/Views/CastleSiege/ICastleSiegeCrownStatePlugIn.cs View interface
GameLogic/Views/CastleSiege/ICastleSiegeCrownAccessStatePlugIn.cs View interface
GameLogic/Views/CastleSiege/ICastleSiegeSwitchInfoPlugIn.cs View interface
GameLogic/Views/CastleSiege/ICastleSiegeOwnershipChangePlugIn.cs View interface
GameServer/RemoteView/CastleSiege/CastleSiegeCrownStatePlugIn.cs Remote view
GameServer/RemoteView/CastleSiege/CastleSiegeCrownAccessStatePlugIn.cs Remote view
GameServer/RemoteView/CastleSiege/CastleSiegeSwitchInfoPlugIn.cs Remote view
GameServer/RemoteView/CastleSiege/CastleSiegeOwnershipChangePlugIn.cs Remote view

Acceptance Criteria

  • Crown capture requires all 3 positions (crown + 2 switches) held by the same attacking side.
  • Accumulated time increments only when all 3 conditions are met.
  • Capture occurs when accumulated time reaches CrownHoldTimeSeconds.
  • On capture: sides are swapped, all players re-assigned, Life Stones killed, crown locked.
  • Accumulated time is capped at CrownHoldTimeSeconds - 1 on failure (not reset to 0).
  • Switch info is broadcast every second showing occupant details.
  • Crown lock/unlock state is broadcast based on switch occupancy.
  • At battle end, the final winner is correctly determined.
  • Ownership change triggers tax reset.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions