-
Notifications
You must be signed in to change notification settings - Fork 5
/
DeathResolutionGameController.java
137 lines (122 loc) · 4.38 KB
/
DeathResolutionGameController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package core.server.game.controllers.mechanics;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import cards.Card;
import cards.equipments.Equipment;
import commands.client.game.RequestRescueGameClientCommand;
import core.player.PlayerCompleteServer;
import core.player.Role;
import core.server.game.BattleLog;
import core.server.game.GameInternal;
import core.server.game.controllers.AbstractGameController;
import core.server.game.controllers.GameControllerStage;
import exceptions.server.game.GameFlowInterruptedException;
import exceptions.server.game.InvalidPlayerCommandException;
import utils.DelayedStackItem;
public class DeathResolutionGameController
extends AbstractGameController<DeathResolutionGameController.DeathResolutionStage> {
public static enum DeathResolutionStage implements GameControllerStage<DeathResolutionStage> {
RESCUE_INQUIRY,
DEATH,
GAME_END_CHECK,
AFTER_DEATH_SETTLEMENT,
END;
}
private final PlayerCompleteServer dyingPlayer;
private PlayerCompleteServer currentRescuer;
private boolean roundEnded;
public DeathResolutionGameController(PlayerCompleteServer dyingPlayer, PlayerCompleteServer currentPlayer) {
this.dyingPlayer = dyingPlayer;
this.currentRescuer = currentPlayer;
this.roundEnded = false;
}
@Override
protected void handleStage(GameInternal game, DeathResolutionStage stage) throws GameFlowInterruptedException {
switch (stage) {
case RESCUE_INQUIRY:
if (!dyingPlayer.isDying()) {
// if player is no longer dying, end
this.setStage(DeathResolutionStage.END);
return;
}
if (roundEnded) {
// round finished but player is still dying, so kill the player
this.nextStage();
return;
}
throw new GameFlowInterruptedException(new RequestRescueGameClientCommand(currentRescuer, dyingPlayer));
case DEATH:
this.nextStage();
try {
Set<Card> disposedCards = new HashSet<>();
// Dead player discards all cards on hand
// TODO move to GameController
dyingPlayer.discardCards(dyingPlayer.getCardsOnHand());
// Dead player discards all equipments
for (Equipment equipment : dyingPlayer.getEquipments()) {
dyingPlayer.unequip(equipment.getEquipmentType());
disposedCards.add(equipment);
}
// Dead player discards all delayed items
for (DelayedStackItem item : dyingPlayer.getDelayedQueue()) {
dyingPlayer.removeDelayed(item.type);
disposedCards.add(item.delayed);
}
game.log(BattleLog.playerADidXToCards(dyingPlayer, "discarded", disposedCards));
dyingPlayer.kill();
game.log(BattleLog.playerADidX(dyingPlayer, "died"));
game.pushGameController(new RecycleCardsGameController(dyingPlayer, disposedCards));
} catch (InvalidPlayerCommandException e) {
e.printStackTrace();
}
break;
case GAME_END_CHECK:
// Game ends when Emperor dies (Rebel or Usurper wins)
if (dyingPlayer.getRole() == Role.EMPEROR) {
if (game.getNumberOfPlayersAlive() >= 2) {
// Rebel wins if Emperor is not the last one to die
game.end(List.of(Role.REBEL));
} else {
// Usurper (or Rebel, if only 2 players) wins if Emperor is the last one to die
game.end(List.of(game.getPlayersAlive().get(0).getRole()));
}
throw new GameFlowInterruptedException();
}
// Game ends when there's no Rebel or Usurper left (Emperor & Loyalist wins)
if (!game.getPlayersAlive().stream().anyMatch(p -> p.getRole() == Role.USURPER || p.getRole() == Role.REBEL)) {
game.end(List.of(Role.EMPEROR, Role.LOYALIST));
throw new GameFlowInterruptedException();
}
this.nextStage();
break;
case AFTER_DEATH_SETTLEMENT:
this.nextStage();
// TODO resolve after death settlement
break;
case END:
break;
}
}
@Override
protected DeathResolutionStage getInitialStage() {
return DeathResolutionStage.RESCUE_INQUIRY;
}
public void onRescueReaction(GameInternal game, boolean rescued) {
if (rescued) {
game.pushGameController(new HealGameController(currentRescuer, dyingPlayer));
} else {
// ask the next player if they would rescue
currentRescuer = game.getNextPlayerAlive(currentRescuer);
if (currentRescuer == game.getCurrentPlayer()) {
roundEnded = true;
}
}
}
public PlayerCompleteServer getCurrentRescuer() {
return currentRescuer;
}
public PlayerCompleteServer getDyingPlayer() {
return dyingPlayer;
}
}