Skip to content

Commit 25b7d6e

Browse files
committed
refactor: arena exit clean up actions
- create PlayerExitedArenaEvent - on arena exit remove AllowShopScreenComponent (players only need the shop in-game) - move check for condition changes that trigger a phase change into LASSystem - switch player to white team instead of removing LASTeam component - trigger arena exit clean up actions for disconnecting clients before they are disconnected (requires MovingBlocks/Terasology#5077)
1 parent 171b29a commit 25b7d6e

File tree

5 files changed

+82
-34
lines changed

5 files changed

+82
-34
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2022 The Terasology Foundation
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package org.terasology.module.lightandshadow.events;
5+
6+
import org.terasology.engine.entitySystem.entity.EntityRef;
7+
import org.terasology.gestalt.entitysystem.event.Event;
8+
9+
public class PlayerExitedArenaEvent implements Event {
10+
private final EntityRef player;
11+
12+
public PlayerExitedArenaEvent(EntityRef player) {
13+
this.player = player;
14+
}
15+
16+
public EntityRef getPlayer() {
17+
return player;
18+
}
19+
}

src/main/java/org/terasology/module/lightandshadow/systems/ClientShopSystem.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.terasology.input.ButtonState;
2121
import org.terasology.module.inventory.input.InventoryButton;
2222
import org.terasology.module.lightandshadow.LASUtils;
23+
import org.terasology.module.lightandshadow.events.PlayerExitedArenaEvent;
2324
import org.terasology.module.lightandshadow.phases.OnPreGamePhaseStartedEvent;
2425
import org.terasology.notifications.events.ExpireNotificationEvent;
2526
import org.terasology.notifications.events.ShowNotificationEvent;
@@ -43,6 +44,11 @@ public void onPregameStart(OnPreGamePhaseStartedEvent event, EntityRef entity) {
4344
entity.upsertComponent(AllowShopScreenComponent.class, c -> c.orElse(new AllowShopScreenComponent()));
4445
}
4546

47+
@ReceiveEvent
48+
public void onArenaExit(PlayerExitedArenaEvent event, EntityRef entity) {
49+
entity.removeComponent(AllowShopScreenComponent.class);
50+
}
51+
4652
/**
4753
* Handles the button event if in-game shop is enabled.
4854
* Needs to have a higher priority than {@link MarketUiClientSystem#onToggleInventory(InventoryButton, EntityRef)}

src/main/java/org/terasology/module/lightandshadow/systems/LASSystem.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
package org.terasology.module.lightandshadow.systems;
44

55
import org.joml.Vector3f;
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
68
import org.terasology.economy.components.CurrencyStorageComponent;
79
import org.terasology.economy.events.WalletUpdatedEvent;
810
import org.terasology.engine.entitySystem.entity.EntityRef;
@@ -12,13 +14,18 @@
1214
import org.terasology.engine.entitySystem.systems.RegisterSystem;
1315
import org.terasology.engine.logic.characters.CharacterTeleportEvent;
1416
import org.terasology.engine.logic.players.event.OnPlayerSpawnedEvent;
17+
import org.terasology.engine.network.ClientComponent;
1518
import org.terasology.engine.registry.In;
1619
import org.terasology.engine.world.sun.CelestialSystem;
1720
import org.terasology.gestalt.entitysystem.event.ReceiveEvent;
1821
import org.terasology.module.inventory.components.InventoryComponent;
1922
import org.terasology.module.inventory.events.RemoveItemAction;
2023
import org.terasology.module.inventory.systems.InventoryManager;
2124
import org.terasology.module.lightandshadow.LASUtils;
25+
import org.terasology.module.lightandshadow.events.PlayerExitedArenaEvent;
26+
import org.terasology.module.lightandshadow.phases.Phase;
27+
import org.terasology.module.lightandshadow.phases.SwitchToPhaseEvent;
28+
import org.terasology.module.lightandshadow.phases.authority.PhaseSystem;
2229

2330
@RegisterSystem
2431
public class LASSystem extends BaseComponentSystem {
@@ -28,6 +35,12 @@ public class LASSystem extends BaseComponentSystem {
2835
private CelestialSystem celestialSystem;
2936
@In
3037
private GameEntitySystem gameEntitySystem;
38+
@In
39+
private PhaseSystem phaseSystem;
40+
@In
41+
private TeamSystem teamSystem;
42+
43+
private static final Logger logger = LoggerFactory.getLogger(LASSystem.class);
3144

3245
/**
3346
* Gives an empty inventory to a player in the lobby to prevent fight's in the lobby and gives the player some funds.
@@ -45,6 +58,28 @@ public void onPlayerSpawn(OnPlayerSpawnedEvent event, EntityRef player, Inventor
4558
player.send(new CharacterTeleportEvent(new Vector3f(LASUtils.FLOATING_PLATFORM_POSITION).add(0, 1, 0)));
4659
}
4760

61+
/**
62+
* Follow-up actions necessary when a player leaves the arena, either by porting back to the platform
63+
* or by disconnecting from the server.
64+
* These action are required to verify the current game state and update the phase accordingly if necessary.
65+
*/
66+
@ReceiveEvent
67+
public void onArenaExit(PlayerExitedArenaEvent event, EntityRef player) {
68+
// if in game phase: verify that game start condition still met
69+
Phase currentPhase = phaseSystem.getCurrentPhase();
70+
if ((currentPhase == Phase.IN_GAME || currentPhase == Phase.COUNTDOWN) && !teamSystem.isMinSizeTeams()) {
71+
logger.debug("Starting condition no longer met, switching from phase {} to PRE_GAME", currentPhase);
72+
gameEntitySystem.getGameEntity().send(new SwitchToPhaseEvent(Phase.PRE_GAME));
73+
}
74+
75+
// if the player teleporting was the last one still in the arena
76+
// switch back to idle phase
77+
if (teamSystem.getTeamSize(LASUtils.BLACK_TEAM) == 0 && teamSystem.getTeamSize(LASUtils.RED_TEAM) == 0) {
78+
logger.debug("No players left in arena, switching to IDLE phase");
79+
gameEntitySystem.getGameEntity().send(new SwitchToPhaseEvent(Phase.IDLE));
80+
}
81+
}
82+
4883
@Override
4984
public void initialise() {
5085
if (!celestialSystem.isSunHalted()) {

src/main/java/org/terasology/module/lightandshadow/systems/TeamSystem.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import org.slf4j.LoggerFactory;
88
import org.terasology.engine.entitySystem.entity.EntityRef;
99
import org.terasology.engine.entitySystem.entity.lifecycleEvents.OnChangedComponent;
10+
import org.terasology.engine.entitySystem.event.EventPriority;
11+
import org.terasology.engine.entitySystem.event.Priority;
1012
import org.terasology.engine.entitySystem.systems.BaseComponentSystem;
1113
import org.terasology.engine.entitySystem.systems.RegisterMode;
1214
import org.terasology.engine.entitySystem.systems.RegisterSystem;
@@ -18,6 +20,7 @@
1820
import org.terasology.module.lightandshadow.LASUtils;
1921
import org.terasology.module.lightandshadow.components.LASConfigComponent;
2022
import org.terasology.module.lightandshadow.components.LASTeamStatsComponent;
23+
import org.terasology.module.lightandshadow.events.PlayerExitedArenaEvent;
2124

2225
@RegisterSystem(RegisterMode.AUTHORITY)
2326
@Share(value = TeamSystem.class)
@@ -34,6 +37,16 @@ public void onTeamChange(OnChangedComponent event, EntityRef entity) {
3437
entity.getComponent(LASTeamComponent.class).team);
3538
}
3639

40+
@Priority(EventPriority.PRIORITY_HIGH)
41+
@ReceiveEvent(components = LASTeamComponent.class)
42+
public void onArenaExit(PlayerExitedArenaEvent event, EntityRef player) {
43+
// players exiting the arena (e.g. by teleporting to platform or disconnecting from the game)
44+
// should be removed from the playing teams
45+
LASTeamComponent lasTeamComponent = player.getComponent(LASTeamComponent.class);
46+
lasTeamComponent.team = LASUtils.WHITE_TEAM;
47+
player.addOrSaveComponent(lasTeamComponent);
48+
}
49+
3750
public boolean isBalancedTeams(String targetTeam) {
3851
gameEntitySystem.updateTeamStats();
3952
EntityRef gameEntity = gameEntitySystem.getGameEntity();

src/main/java/org/terasology/module/lightandshadow/systems/TeleporterSystem.java

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import org.terasology.engine.logic.permission.PermissionManager;
2121
import org.terasology.engine.logic.players.SetDirectionEvent;
2222
import org.terasology.engine.network.ClientComponent;
23-
import org.terasology.engine.network.events.DisconnectedEvent;
23+
import org.terasology.engine.network.events.BeforeDisconnectEvent;
2424
import org.terasology.engine.registry.In;
2525
import org.terasology.engine.utilities.Assets;
2626
import org.terasology.gestalt.entitysystem.event.Event;
@@ -31,6 +31,7 @@
3131
import org.terasology.module.inventory.events.RequestInventoryEvent;
3232
import org.terasology.module.lightandshadow.LASUtils;
3333
import org.terasology.module.lightandshadow.components.LASConfigComponent;
34+
import org.terasology.module.lightandshadow.events.PlayerExitedArenaEvent;
3435
import org.terasology.module.lightandshadow.events.TimerEvent;
3536
import org.terasology.module.lightandshadow.phases.Phase;
3637
import org.terasology.module.lightandshadow.phases.SwitchToPhaseEvent;
@@ -40,8 +41,8 @@
4041
import java.util.function.Supplier;
4142

4243
/**
43-
* Teleports players to play arena once they chose their team.
44-
* It also sends events to change players skins and hud based on team they have chosen.
44+
* Teleports players to play arena once they chose their team. It also sends events to change players skins and hud based on team they have
45+
* chosen.
4546
*
4647
* @see ClientSkinSystem
4748
*/
@@ -64,9 +65,8 @@ public class TeleporterSystem extends BaseComponentSystem {
6465
private final Random random = new Random();
6566

6667
/**
67-
* Depending on which teleporter the player chooses, they are set to that team
68-
* and teleported to that base
69-
* Assumption: there are two teleporters, one for the red, one for the black team
68+
* Depending on which teleporter the player chooses, they are set to that team and teleported to that base Assumption: there are two
69+
* teleporters, one for the red, one for the black team
7070
*
7171
* @param event
7272
* @param entity
@@ -127,44 +127,19 @@ public String teleportToPlatform(@Sender EntityRef sender) {
127127
LASTeamComponent senderTeam = clientComp.character.getComponent(LASTeamComponent.class);
128128
if (senderTeam != null && (senderTeam.team.equals(LASUtils.RED_TEAM) || senderTeam.team.equals(LASUtils.BLACK_TEAM))) {
129129
// spectators (white team) are not relevant for arena exit actions
130-
performArenaExitActions(clientComp);
130+
clientComp.character.send(new PlayerExitedArenaEvent(sender));
131131
}
132132
clientComp.character.send(new CharacterTeleportEvent(new Vector3f(LASUtils.FLOATING_PLATFORM_POSITION).add(0, 1, 0)));
133133
return "Teleporting you to the platform.";
134134
}
135135

136136
@ReceiveEvent(components = ClientComponent.class)
137-
public void onPlayerDisconnect(DisconnectedEvent event, EntityRef entity) {
137+
public void onPlayerDisconnect(BeforeDisconnectEvent event, EntityRef entity) {
138138
ClientComponent clientComp = entity.getComponent(ClientComponent.class);
139139
LASTeamComponent senderTeam = clientComp.character.getComponent(LASTeamComponent.class);
140140
if (senderTeam != null && (senderTeam.team.equals(LASUtils.RED_TEAM) || senderTeam.team.equals(LASUtils.BLACK_TEAM))) {
141141
// spectators (white team) are not relevant for arena exit actions
142-
performArenaExitActions(clientComp);
143-
}
144-
}
145-
146-
/**
147-
* Follow-up actions necessary when a player leaves the arena, either by porting back to the platform
148-
* or by disconnecting from the server.
149-
* These action are required to verify the current game state and update the phase accordingly if necessary.
150-
*/
151-
private void performArenaExitActions(ClientComponent clientComp) {
152-
// players teleporting back to platform should be removed from the playing teams
153-
// white team (spectator) members are allowed to teleport without losing their team
154-
clientComp.character.removeComponent(LASTeamComponent.class);
155-
156-
// if in game phase: verify that game start condition still met
157-
Phase currentPhase = phaseSystem.getCurrentPhase();
158-
if ((currentPhase == Phase.IN_GAME || currentPhase == Phase.COUNTDOWN) && !teamSystem.isMinSizeTeams()) {
159-
logger.debug("Starting condition no longer met, switching from phase {} to PRE_GAME", currentPhase);
160-
gameEntitySystem.getGameEntity().send(new SwitchToPhaseEvent(Phase.PRE_GAME));
161-
}
162-
163-
// if the player teleporting was the last one still in the arena
164-
// switch back to idle phase
165-
if (teamSystem.getTeamSize(LASUtils.BLACK_TEAM) == 0 && teamSystem.getTeamSize(LASUtils.RED_TEAM) == 0) {
166-
logger.debug("No players left in arena, switching to IDLE phase");
167-
gameEntitySystem.getGameEntity().send(new SwitchToPhaseEvent(Phase.IDLE));
142+
teleportToPlatform(entity);
168143
}
169144
}
170145
}

0 commit comments

Comments
 (0)