-
Notifications
You must be signed in to change notification settings - Fork 99
/
FlierActionPhase.java
97 lines (84 loc) · 3.24 KB
/
FlierActionPhase.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
package com.jcloisterzone.game.phase;
import com.jcloisterzone.action.MeepleAction;
import com.jcloisterzone.board.Location;
import com.jcloisterzone.board.Position;
import com.jcloisterzone.board.Tile;
import com.jcloisterzone.board.pointer.FeaturePointer;
import com.jcloisterzone.event.SelectActionEvent;
import com.jcloisterzone.feature.Cloister;
import com.jcloisterzone.feature.Completable;
import com.jcloisterzone.feature.Feature;
import com.jcloisterzone.feature.visitor.IsCompleted;
import com.jcloisterzone.figure.Follower;
import com.jcloisterzone.figure.Meeple;
import com.jcloisterzone.figure.Phantom;
import com.jcloisterzone.game.Game;
import com.jcloisterzone.game.capability.FlierCapability;
public class FlierActionPhase extends Phase {
private final FlierCapability flierCap;
public FlierActionPhase(Game game) {
super(game);
flierCap = game.getCapability(FlierCapability.class);
}
@Override
public void enter() {
int distance = flierCap.getFlierDistance();
Tile origin = game.getCurrentTile();
Location direction = origin.getFlier().rotateCW(origin.getRotation());
Position pos = game.getCurrentTile().getPosition();
for (int i = 0; i < distance; i++) {
pos = pos.add(direction);
}
Tile target = getBoard().get(pos);
Class<? extends Meeple> meepleType = flierCap.getMeepleType();
Follower follower = (Follower) getActivePlayer().getMeepleFromSupply(meepleType);
if (target == null || !game.isDeployAllowed(target, meepleType)) {
next();
return;
}
MeepleAction action = new MeepleAction(meepleType);
for (Feature f : target.getFeatures()) {
if (!(f instanceof Completable)) continue;
if (f instanceof Cloister) {
Cloister cloister = (Cloister) f;
if (cloister.isMonastery()) {
action.add(new FeaturePointer(pos, Location.ABBOT));
}
}
if (f.walk(new IsCompleted())) continue;
if (follower.isDeploymentAllowed(f).result) {
action.add(new FeaturePointer(pos, f.getLocation()));
}
}
if (action.isEmpty()) {
next();
return;
}
game.post(new SelectActionEvent(getActivePlayer(), action, false));
}
@Override
public void notifyRansomPaid() {
enter(); //recompute available actions
}
@Override
public void next() {
boolean isPhantom = Phantom.class.equals(flierCap.getMeepleType());
flierCap.setFlierDistance(null, 0); //resets meepleType
if (isPhantom) {
PhantomPhase pp = game.getPhases().getInstance(PhantomPhase.class);
super.next(pp.getDefaultNext());
} else {
super.next();
}
}
@Override
public void deployMeeple(Position p, Location loc, Class<? extends Meeple> meepleType) {
if (!meepleType.equals(flierCap.getMeepleType())) {
throw new IllegalArgumentException("Invalid meeple type.");
}
Meeple m = getActivePlayer().getMeepleFromSupply(meepleType);
Tile tile = getBoard().get(p);
m.deploy(tile, loc);
next();
}
}