diff --git a/.idea/dictionaries/aoaaceai.xml b/.idea/dictionaries/aoaaceai.xml
index da391cd..eebe285 100644
--- a/.idea/dictionaries/aoaaceai.xml
+++ b/.idea/dictionaries/aoaaceai.xml
@@ -4,6 +4,7 @@
aclone
bclone
gameboard
+ ownerless
spacezipper
sundar
diff --git a/src/main/java/eod/Player.java b/src/main/java/eod/Player.java
index 9888f88..8185d35 100644
--- a/src/main/java/eod/Player.java
+++ b/src/main/java/eod/Player.java
@@ -11,6 +11,7 @@
import eod.event.*;
import eod.event.relay.EventReceiver;
import eod.event.relay.EventSender;
+import eod.event.relay.StatusHolder;
import eod.exceptions.GameLosingException;
import eod.exceptions.NotSupportedException;
import eod.param.AttackParam;
@@ -83,6 +84,10 @@ public void setIsActing(boolean acting) {
isActingPlayer = acting;
}
+ public boolean isActingPlayer() {
+ return isActingPlayer;
+ }
+
public void handReceive(ArrayList h) {
hand.receive(h);
output.sendReceivedCards(this, h.toArray(new Card[0]));
@@ -105,6 +110,15 @@ public void drawFromDeck(int count) {
output.sendReceivedCards(this, cards);
}
+ public void drawFromDeck(Class extends Card> cardType, int count) {
+ output.sendDrawingCards(this);
+
+ Card[] cards = deck.draw(cardType, count);
+ hand.receive(new ArrayList<>(Arrays.asList(cards)));
+
+ output.sendReceivedCards(this, cards);
+ }
+
public boolean checkCardTypeInHand(Class extends Card> c) {
return hand.containsType(c);
}
@@ -432,6 +446,11 @@ public void unregisterReceiver(EventReceiver receiver) {
receivers.remove(receiver);
}
+ @Override
+ public StatusHolder[] getStatusHolders() {
+ return receivers.stream().filter(receiver -> receiver instanceof StatusHolder).map(receiver -> (StatusHolder) receiver).toArray(StatusHolder[]::new);
+ }
+
@Override
public void send(GameObject sender, Event event) {
receivers.stream()
diff --git a/src/main/java/eod/card/abstraction/summon/AssassinSummon.java b/src/main/java/eod/card/abstraction/summon/AssassinSummon.java
new file mode 100644
index 0000000..6adf27b
--- /dev/null
+++ b/src/main/java/eod/card/abstraction/summon/AssassinSummon.java
@@ -0,0 +1,7 @@
+package eod.card.abstraction.summon;
+
+public abstract class AssassinSummon extends SummonCard{
+ public AssassinSummon(int cost, SummonCardType type) {
+ super(cost, type);
+ }
+}
diff --git a/src/main/java/eod/card/abstraction/summon/BunkerSummon.java b/src/main/java/eod/card/abstraction/summon/BunkerSummon.java
new file mode 100644
index 0000000..6282e73
--- /dev/null
+++ b/src/main/java/eod/card/abstraction/summon/BunkerSummon.java
@@ -0,0 +1,7 @@
+package eod.card.abstraction.summon;
+
+public abstract class BunkerSummon extends SummonCard {
+ public BunkerSummon(int cost, SummonCardType type) {
+ super(cost, type);
+ }
+}
diff --git a/src/main/java/eod/card/abstraction/summon/FighterSummon.java b/src/main/java/eod/card/abstraction/summon/FighterSummon.java
new file mode 100644
index 0000000..aa7d34e
--- /dev/null
+++ b/src/main/java/eod/card/abstraction/summon/FighterSummon.java
@@ -0,0 +1,7 @@
+package eod.card.abstraction.summon;
+
+public abstract class FighterSummon extends SummonCard {
+ public FighterSummon(int cost, SummonCardType type) {
+ super(cost, type);
+ }
+}
diff --git a/src/main/java/eod/card/abstraction/summon/HackerSummon.java b/src/main/java/eod/card/abstraction/summon/HackerSummon.java
new file mode 100644
index 0000000..6b6fd6a
--- /dev/null
+++ b/src/main/java/eod/card/abstraction/summon/HackerSummon.java
@@ -0,0 +1,7 @@
+package eod.card.abstraction.summon;
+
+public abstract class HackerSummon extends SummonCard {
+ public HackerSummon(int cost, SummonCardType type) {
+ super(cost, type);
+ }
+}
diff --git a/src/main/java/eod/card/abstraction/summon/MachineSummon.java b/src/main/java/eod/card/abstraction/summon/MachineSummon.java
new file mode 100644
index 0000000..3070ff0
--- /dev/null
+++ b/src/main/java/eod/card/abstraction/summon/MachineSummon.java
@@ -0,0 +1,7 @@
+package eod.card.abstraction.summon;
+
+public abstract class MachineSummon extends SummonCard {
+ public MachineSummon(int cost, SummonCardType type) {
+ super(cost, type);
+ }
+}
diff --git a/src/main/java/eod/card/abstraction/summon/MedicSummon.java b/src/main/java/eod/card/abstraction/summon/MedicSummon.java
new file mode 100644
index 0000000..304ecd2
--- /dev/null
+++ b/src/main/java/eod/card/abstraction/summon/MedicSummon.java
@@ -0,0 +1,7 @@
+package eod.card.abstraction.summon;
+
+public abstract class MedicSummon extends SummonCard {
+ public MedicSummon(int cost, SummonCardType type) {
+ super(cost, type);
+ }
+}
diff --git a/src/main/java/eod/card/abstraction/summon/SapperSummon.java b/src/main/java/eod/card/abstraction/summon/SapperSummon.java
new file mode 100644
index 0000000..ca29b78
--- /dev/null
+++ b/src/main/java/eod/card/abstraction/summon/SapperSummon.java
@@ -0,0 +1,7 @@
+package eod.card.abstraction.summon;
+
+public abstract class SapperSummon extends SummonCard {
+ public SapperSummon(int cost, SummonCardType type) {
+ super(cost, type);
+ }
+}
diff --git a/src/main/java/eod/card/abstraction/summon/ShooterSummon.java b/src/main/java/eod/card/abstraction/summon/ShooterSummon.java
new file mode 100644
index 0000000..1bb9258
--- /dev/null
+++ b/src/main/java/eod/card/abstraction/summon/ShooterSummon.java
@@ -0,0 +1,7 @@
+package eod.card.abstraction.summon;
+
+public abstract class ShooterSummon extends SummonCard {
+ public ShooterSummon(int cost, SummonCardType type) {
+ super(cost, type);
+ }
+}
diff --git a/src/main/java/eod/card/abstraction/summon/SniperSummon.java b/src/main/java/eod/card/abstraction/summon/SniperSummon.java
new file mode 100644
index 0000000..1af3f07
--- /dev/null
+++ b/src/main/java/eod/card/abstraction/summon/SniperSummon.java
@@ -0,0 +1,7 @@
+package eod.card.abstraction.summon;
+
+public abstract class SniperSummon extends SummonCard {
+ public SniperSummon(int cost, SummonCardType type) {
+ super(cost, type);
+ }
+}
diff --git a/src/main/java/eod/card/collection/Deck.java b/src/main/java/eod/card/collection/Deck.java
index 93d7a89..9c05f7c 100644
--- a/src/main/java/eod/card/collection/Deck.java
+++ b/src/main/java/eod/card/collection/Deck.java
@@ -6,6 +6,7 @@
import eod.snapshots.Snapshotted;
import java.util.*;
+import java.util.stream.Collectors;
public class Deck implements Snapshotted, Iterable, GameObject {
@@ -43,6 +44,27 @@ public Card[] draw(int count) {
}
+ public Card[] draw(Class extends Card> cardType, int count) {
+ // TODO:
+ // Whether or not the drawn card will have the same reference as the card in deck is unknown. testing needed.
+ List canDraw = cards.stream().filter(card -> card.cardTypeEquals(cardType)).collect(Collectors.toList());
+ int n = Math.min(canDraw.size(), count);
+ Random random = new Random();
+
+ Card[] drew = new Card[n];
+
+ for(int i = 0;i < n;i++) {
+ drew[i] = canDraw.remove(random.nextInt(canDraw.size()));
+ cards.remove(drew[i]);
+ }
+
+ if(cards.size() == 0) {
+ throw new GameLosingException("Deck is drained.");
+ }
+
+ return drew;
+ }
+
public void dropCard(Card card) {
for(Card c:cards) {
if(c.cardTypeEquals(card.getClass())) {
diff --git a/src/main/java/eod/card/collection/Hand.java b/src/main/java/eod/card/collection/Hand.java
index 5c48e03..2465e49 100644
--- a/src/main/java/eod/card/collection/Hand.java
+++ b/src/main/java/eod/card/collection/Hand.java
@@ -60,6 +60,9 @@ public boolean containsCard(Card c) {
return hand.contains(c);
}
+ public int size() {
+ return hand.size();
+ }
public Stream stream() {
return hand.stream();
}
diff --git a/src/main/java/eod/card/concrete/normal/TyrantsCommand.java b/src/main/java/eod/card/concrete/normal/TyrantsCommand.java
new file mode 100644
index 0000000..33697c3
--- /dev/null
+++ b/src/main/java/eod/card/concrete/normal/TyrantsCommand.java
@@ -0,0 +1,60 @@
+package eod.card.concrete.normal;
+
+import eod.Party;
+import eod.card.abstraction.Card;
+import eod.card.abstraction.action.NormalCard;
+import eod.effect.Effect;
+import eod.effect.EffectExecutor;
+import eod.warObject.Status;
+import eod.warObject.WarObject;
+import eod.warObject.character.concrete.red.Gangster;
+
+import static eod.effect.EffectFunctions.*;
+import static eod.specifier.WarObjectSpecifier.WarObject;
+import static eod.specifier.condition.Conditions.Being;
+import static eod.specifier.condition.Conditions.OwnedBy;
+
+public class TyrantsCommand extends NormalCard {
+ public TyrantsCommand() {
+ super(4);
+ }
+
+ @Override
+ public void applyEffect(EffectExecutor executor) {
+ WarObject[] gangsters = WarObject(player.getBoard()).which(OwnedBy(player)).which(Being(Gangster.class)).get();
+
+ for(WarObject gangster:gangsters) {
+ executor.tryToExecute(
+ IncreaseAttack(1).to((Gangster) gangster)
+ );
+ executor.tryToExecute(
+ IncreaseHealth(1).to((Gangster) gangster)
+ );
+ }
+
+ executor.tryToExecute(
+ GiveStatus(Status.FURIOUS, Effect.HandlerType.Owner).to(gangsters)
+ );
+
+ for(WarObject gangster:gangsters) {
+ ((Gangster) gangster).attack(executor);
+ }
+ }
+
+ @Override
+ public Card copy() {
+ Card c = new TyrantsCommand();
+ c.setPlayer(player);
+ return c;
+ }
+
+ @Override
+ public String getName() {
+ return "暴君的指揮";
+ }
+
+ @Override
+ public Party getParty() {
+ return Party.RED;
+ }
+}
diff --git a/src/main/java/eod/card/concrete/summon/AssassinsIntermediarySummon.java b/src/main/java/eod/card/concrete/summon/AssassinsIntermediarySummon.java
new file mode 100644
index 0000000..aa29ffb
--- /dev/null
+++ b/src/main/java/eod/card/concrete/summon/AssassinsIntermediarySummon.java
@@ -0,0 +1,38 @@
+package eod.card.concrete.summon;
+
+import eod.Party;
+import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.SummonCard;
+import eod.card.abstraction.summon.SummonCardType;
+import eod.effect.Summon;
+import eod.warObject.character.concrete.transparent.AssassinsIntermediary;
+
+import static eod.effect.EffectFunctions.Summon;
+
+public class AssassinsIntermediarySummon extends SummonCard {
+ public AssassinsIntermediarySummon() {
+ super(2, SummonCardType.NORMAL);
+ }
+
+ @Override
+ public Summon summonEffect() {
+ return Summon(new AssassinsIntermediary(player)).onOnePointOf(player, player.getBaseEmpty());
+ }
+
+ @Override
+ public Card copy() {
+ Card c = new AssassinsIntermediarySummon();
+ c.setPlayer(player);
+ return c;
+ }
+
+ @Override
+ public String getName() {
+ return "召喚 殺手掮客";
+ }
+
+ @Override
+ public Party getParty() {
+ return Party.TRANSPARENT;
+ }
+}
diff --git a/src/main/java/eod/card/concrete/summon/AssaultTeamLeaderSummon.java b/src/main/java/eod/card/concrete/summon/AssaultTeamLeaderSummon.java
index fec682a..0ec2ccf 100644
--- a/src/main/java/eod/card/concrete/summon/AssaultTeamLeaderSummon.java
+++ b/src/main/java/eod/card/concrete/summon/AssaultTeamLeaderSummon.java
@@ -28,7 +28,7 @@ public Card copy() {
@Override
public String getName() {
- return "召喚 特攻隊隊長";
+ return "召喚 特攻隊長";
}
@Override
diff --git a/src/main/java/eod/card/concrete/summon/BloodThirstFighterSummon.java b/src/main/java/eod/card/concrete/summon/BloodThirstFighterSummon.java
index 3f45d3d..31523bf 100644
--- a/src/main/java/eod/card/concrete/summon/BloodThirstFighterSummon.java
+++ b/src/main/java/eod/card/concrete/summon/BloodThirstFighterSummon.java
@@ -2,6 +2,7 @@
import eod.Party;
import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.FighterSummon;
import eod.card.abstraction.summon.SummonCard;
import eod.card.abstraction.summon.SummonCardType;
import eod.effect.Summon;
@@ -12,7 +13,7 @@
import static eod.effect.EffectFunctions.Summon;
-public class BloodThirstFighterSummon extends SummonCard {
+public class BloodThirstFighterSummon extends FighterSummon {
public BloodThirstFighterSummon() {
super(5, SummonCardType.NORMAL);
}
diff --git a/src/main/java/eod/card/concrete/summon/DroneSummon.java b/src/main/java/eod/card/concrete/summon/DroneSummon.java
index 9c4ab24..0328c95 100644
--- a/src/main/java/eod/card/concrete/summon/DroneSummon.java
+++ b/src/main/java/eod/card/concrete/summon/DroneSummon.java
@@ -2,6 +2,7 @@
import eod.Party;
import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.MachineSummon;
import eod.card.abstraction.summon.SummonCard;
import eod.card.abstraction.summon.SummonCardType;
import eod.effect.Summon;
@@ -9,7 +10,7 @@
import static eod.effect.EffectFunctions.Summon;
-public class DroneSummon extends SummonCard {
+public class DroneSummon extends MachineSummon {
public DroneSummon() {
super(3, SummonCardType.TOKEN);
}
diff --git a/src/main/java/eod/card/concrete/summon/ExperiencedWarriorSummon.java b/src/main/java/eod/card/concrete/summon/ExperiencedWarriorSummon.java
index 3999bba..cf368b6 100644
--- a/src/main/java/eod/card/concrete/summon/ExperiencedWarriorSummon.java
+++ b/src/main/java/eod/card/concrete/summon/ExperiencedWarriorSummon.java
@@ -2,6 +2,7 @@
import eod.Party;
import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.FighterSummon;
import eod.card.abstraction.summon.SummonCard;
import eod.card.abstraction.summon.SummonCardType;
import eod.effect.Summon;
@@ -9,7 +10,7 @@
import static eod.effect.EffectFunctions.Summon;
-public class ExperiencedWarriorSummon extends SummonCard {
+public class ExperiencedWarriorSummon extends FighterSummon {
public ExperiencedWarriorSummon() {
super(3, SummonCardType.TOKEN);
}
diff --git a/src/main/java/eod/card/concrete/summon/ExpertOfPoisonSummon.java b/src/main/java/eod/card/concrete/summon/ExpertOfPoisonSummon.java
new file mode 100644
index 0000000..aa2ffe2
--- /dev/null
+++ b/src/main/java/eod/card/concrete/summon/ExpertOfPoisonSummon.java
@@ -0,0 +1,38 @@
+package eod.card.concrete.summon;
+
+import eod.Party;
+import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.SummonCard;
+import eod.card.abstraction.summon.SummonCardType;
+import eod.effect.Summon;
+import eod.warObject.character.concrete.transparent.ExpertOfPoison;
+
+import static eod.effect.EffectFunctions.Summon;
+
+public class ExpertOfPoisonSummon extends SummonCard {
+ public ExpertOfPoisonSummon() {
+ super(5, SummonCardType.NORMAL);
+ }
+
+ @Override
+ public Summon summonEffect() {
+ return Summon(new ExpertOfPoison(player)).onOnePointOf(player, player.getBaseEmpty());
+ }
+
+ @Override
+ public Card copy() {
+ Card c = new ExpertOfPoisonSummon();
+ c.setPlayer(player);
+ return c;
+ }
+
+ @Override
+ public String getName() {
+ return "召喚 毒殺專家";
+ }
+
+ @Override
+ public Party getParty() {
+ return Party.TRANSPARENT;
+ }
+}
diff --git a/src/main/java/eod/card/concrete/summon/FacelessHumanSummon.java b/src/main/java/eod/card/concrete/summon/FacelessHumanSummon.java
new file mode 100644
index 0000000..099527c
--- /dev/null
+++ b/src/main/java/eod/card/concrete/summon/FacelessHumanSummon.java
@@ -0,0 +1,38 @@
+package eod.card.concrete.summon;
+
+import eod.Party;
+import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.SummonCard;
+import eod.card.abstraction.summon.SummonCardType;
+import eod.effect.Summon;
+import eod.warObject.character.concrete.transparent.FacelessHuman;
+
+import static eod.effect.EffectFunctions.Summon;
+
+public class FacelessHumanSummon extends SummonCard {
+ public FacelessHumanSummon() {
+ super(4, SummonCardType.NORMAL);
+ }
+
+ @Override
+ public Summon summonEffect() {
+ return Summon(new FacelessHuman(player)).onOnePointOf(player, player.getBaseEmpty());
+ }
+
+ @Override
+ public Card copy() {
+ Card c = new FacelessHumanSummon();
+ c.setPlayer(player);
+ return c;
+ }
+
+ @Override
+ public String getName() {
+ return "無面的人";
+ }
+
+ @Override
+ public Party getParty() {
+ return Party.TRANSPARENT;
+ }
+}
diff --git a/src/main/java/eod/card/concrete/summon/GangBossSummon.java b/src/main/java/eod/card/concrete/summon/GangBossSummon.java
index e1a1409..b53ab84 100644
--- a/src/main/java/eod/card/concrete/summon/GangBossSummon.java
+++ b/src/main/java/eod/card/concrete/summon/GangBossSummon.java
@@ -2,6 +2,7 @@
import eod.Party;
import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.FighterSummon;
import eod.card.abstraction.summon.SummonCard;
import eod.card.abstraction.summon.SummonCardType;
import eod.effect.Summon;
@@ -9,7 +10,7 @@
import static eod.effect.EffectFunctions.Summon;
-public class GangBossSummon extends SummonCard {
+public class GangBossSummon extends FighterSummon {
public GangBossSummon() {
super(5, SummonCardType.NORMAL);
}
diff --git a/src/main/java/eod/card/concrete/summon/GangsterSummon.java b/src/main/java/eod/card/concrete/summon/GangsterSummon.java
index 92a76b1..7943cca 100644
--- a/src/main/java/eod/card/concrete/summon/GangsterSummon.java
+++ b/src/main/java/eod/card/concrete/summon/GangsterSummon.java
@@ -2,6 +2,7 @@
import eod.Party;
import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.FighterSummon;
import eod.card.abstraction.summon.SummonCard;
import eod.card.abstraction.summon.SummonCardType;
import eod.effect.Summon;
@@ -9,7 +10,7 @@
import static eod.effect.EffectFunctions.Summon;
-public class GangsterSummon extends SummonCard {
+public class GangsterSummon extends FighterSummon {
public GangsterSummon() {
super(1, SummonCardType.TOKEN);
}
diff --git a/src/main/java/eod/card/concrete/summon/GuerrillaShooterSummon.java b/src/main/java/eod/card/concrete/summon/GuerrillaShooterSummon.java
index 70c77af..a26e763 100644
--- a/src/main/java/eod/card/concrete/summon/GuerrillaShooterSummon.java
+++ b/src/main/java/eod/card/concrete/summon/GuerrillaShooterSummon.java
@@ -2,6 +2,7 @@
import eod.Party;
import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.ShooterSummon;
import eod.card.abstraction.summon.SummonCard;
import eod.card.abstraction.summon.SummonCardType;
import eod.effect.Summon;
@@ -12,7 +13,7 @@
import static eod.effect.EffectFunctions.Summon;
-public class GuerrillaShooterSummon extends SummonCard {
+public class GuerrillaShooterSummon extends ShooterSummon {
public GuerrillaShooterSummon() {
super(2, SummonCardType.NORMAL);
}
diff --git a/src/main/java/eod/card/concrete/summon/IntelligenceVendorSummon.java b/src/main/java/eod/card/concrete/summon/IntelligenceVendorSummon.java
new file mode 100644
index 0000000..1adcc5f
--- /dev/null
+++ b/src/main/java/eod/card/concrete/summon/IntelligenceVendorSummon.java
@@ -0,0 +1,38 @@
+package eod.card.concrete.summon;
+
+import eod.Party;
+import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.SummonCard;
+import eod.card.abstraction.summon.SummonCardType;
+import eod.effect.Summon;
+import eod.warObject.character.concrete.transparent.IntelligenceVendor;
+
+import static eod.effect.EffectFunctions.Summon;
+
+public class IntelligenceVendorSummon extends SummonCard {
+ public IntelligenceVendorSummon() {
+ super(3, SummonCardType.NORMAL);
+ }
+
+ @Override
+ public Summon summonEffect() {
+ return Summon(new IntelligenceVendor(player)).onOnePointOf(player, player.getBaseEmpty());
+ }
+
+ @Override
+ public Card copy() {
+ Card c = new IntelligenceVendorSummon();
+ c.setPlayer(player);
+ return c;
+ }
+
+ @Override
+ public String getName() {
+ return "召喚 情報販";
+ }
+
+ @Override
+ public Party getParty() {
+ return Party.TRANSPARENT;
+ }
+}
diff --git a/src/main/java/eod/card/concrete/summon/LeadersGuardSummon.java b/src/main/java/eod/card/concrete/summon/LeadersGuardSummon.java
index f234ea3..fd35f89 100644
--- a/src/main/java/eod/card/concrete/summon/LeadersGuardSummon.java
+++ b/src/main/java/eod/card/concrete/summon/LeadersGuardSummon.java
@@ -2,6 +2,7 @@
import eod.Party;
import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.ShooterSummon;
import eod.card.abstraction.summon.SummonCard;
import eod.card.abstraction.summon.SummonCardType;
import eod.effect.Summon;
@@ -9,7 +10,7 @@
import static eod.effect.EffectFunctions.Summon;
-public class LeadersGuardSummon extends SummonCard {
+public class LeadersGuardSummon extends ShooterSummon {
public LeadersGuardSummon() {
super(3, SummonCardType.NORMAL);
}
diff --git a/src/main/java/eod/card/concrete/summon/MafiaAssassinSummon.java b/src/main/java/eod/card/concrete/summon/MafiaAssassinSummon.java
index 9fad858..eeb67bc 100644
--- a/src/main/java/eod/card/concrete/summon/MafiaAssassinSummon.java
+++ b/src/main/java/eod/card/concrete/summon/MafiaAssassinSummon.java
@@ -2,6 +2,7 @@
import eod.Party;
import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.AssassinSummon;
import eod.card.abstraction.summon.SummonCard;
import eod.card.abstraction.summon.SummonCardType;
import eod.effect.Summon;
@@ -12,7 +13,7 @@
import static eod.effect.EffectFunctions.Summon;
-public class MafiaAssassinSummon extends SummonCard {
+public class MafiaAssassinSummon extends AssassinSummon {
public MafiaAssassinSummon() {
super(3, SummonCardType.NORMAL);
}
diff --git a/src/main/java/eod/card/concrete/summon/OneTimeAssassinSummon.java b/src/main/java/eod/card/concrete/summon/OneTimeAssassinSummon.java
index 2ff68c3..b919137 100644
--- a/src/main/java/eod/card/concrete/summon/OneTimeAssassinSummon.java
+++ b/src/main/java/eod/card/concrete/summon/OneTimeAssassinSummon.java
@@ -2,6 +2,7 @@
import eod.Party;
import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.AssassinSummon;
import eod.card.abstraction.summon.SummonCard;
import eod.card.abstraction.summon.SummonCardType;
import eod.effect.Summon;
@@ -9,7 +10,7 @@
import static eod.effect.EffectFunctions.Summon;
-public class OneTimeAssassinSummon extends SummonCard {
+public class OneTimeAssassinSummon extends AssassinSummon {
// TODO: remove or change the name
public OneTimeAssassinSummon() {
super(2, SummonCardType.NORMAL);
diff --git a/src/main/java/eod/card/concrete/summon/OwnerlessAssassinSummon.java b/src/main/java/eod/card/concrete/summon/OwnerlessAssassinSummon.java
index d98a771..12b30df 100644
--- a/src/main/java/eod/card/concrete/summon/OwnerlessAssassinSummon.java
+++ b/src/main/java/eod/card/concrete/summon/OwnerlessAssassinSummon.java
@@ -2,6 +2,7 @@
import eod.Party;
import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.AssassinSummon;
import eod.card.abstraction.summon.SummonCard;
import eod.card.abstraction.summon.SummonCardType;
import eod.effect.Summon;
@@ -9,7 +10,7 @@
import static eod.effect.EffectFunctions.Summon;
-public class OwnerlessAssassinSummon extends SummonCard {
+public class OwnerlessAssassinSummon extends AssassinSummon {
public OwnerlessAssassinSummon() {
super(2, SummonCardType.NORMAL);
}
diff --git a/src/main/java/eod/card/concrete/summon/RepairmanSummon.java b/src/main/java/eod/card/concrete/summon/RepairmanSummon.java
index 7cdfe34..e1f6b1e 100644
--- a/src/main/java/eod/card/concrete/summon/RepairmanSummon.java
+++ b/src/main/java/eod/card/concrete/summon/RepairmanSummon.java
@@ -2,6 +2,7 @@
import eod.Party;
import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.SapperSummon;
import eod.card.abstraction.summon.SummonCard;
import eod.card.abstraction.summon.SummonCardType;
import eod.effect.Summon;
@@ -9,7 +10,7 @@
import static eod.effect.EffectFunctions.Summon;
-public class RepairmanSummon extends SummonCard {
+public class RepairmanSummon extends SapperSummon {
public RepairmanSummon() {
super(2, SummonCardType.NORMAL);
}
diff --git a/src/main/java/eod/card/concrete/summon/SecureGuardBotSummon.java b/src/main/java/eod/card/concrete/summon/SecureGuardBotSummon.java
index f1e25d1..1056c38 100644
--- a/src/main/java/eod/card/concrete/summon/SecureGuardBotSummon.java
+++ b/src/main/java/eod/card/concrete/summon/SecureGuardBotSummon.java
@@ -2,6 +2,7 @@
import eod.Party;
import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.MachineSummon;
import eod.card.abstraction.summon.SummonCard;
import eod.card.abstraction.summon.SummonCardType;
import eod.effect.Summon;
@@ -9,7 +10,7 @@
import static eod.effect.EffectFunctions.Summon;
-public class SecureGuardBotSummon extends SummonCard {
+public class SecureGuardBotSummon extends MachineSummon {
public SecureGuardBotSummon() {
super(3, SummonCardType.TOKEN);
}
diff --git a/src/main/java/eod/card/concrete/summon/ToughGuySummon.java b/src/main/java/eod/card/concrete/summon/ToughGuySummon.java
index 51b7f5a..0a7e135 100644
--- a/src/main/java/eod/card/concrete/summon/ToughGuySummon.java
+++ b/src/main/java/eod/card/concrete/summon/ToughGuySummon.java
@@ -2,6 +2,7 @@
import eod.Party;
import eod.card.abstraction.Card;
+import eod.card.abstraction.summon.FighterSummon;
import eod.card.abstraction.summon.SummonCard;
import eod.card.abstraction.summon.SummonCardType;
import eod.effect.Summon;
@@ -9,7 +10,7 @@
import static eod.effect.EffectFunctions.Summon;
-public class ToughGuySummon extends SummonCard {
+public class ToughGuySummon extends FighterSummon {
public ToughGuySummon() {
super(6, SummonCardType.NORMAL);
}
diff --git a/src/main/java/eod/event/relay/EventManager.java b/src/main/java/eod/event/relay/EventManager.java
index 14db3e3..b8b31ab 100644
--- a/src/main/java/eod/event/relay/EventManager.java
+++ b/src/main/java/eod/event/relay/EventManager.java
@@ -18,6 +18,11 @@ public void unregisterReceiver(EventReceiver receiver) {
receivers.remove(receiver);
}
+ @Override
+ public StatusHolder[] getStatusHolders() {
+ return receivers.stream().filter(receiver -> receiver instanceof StatusHolder).map(receiver -> (StatusHolder) receiver).toArray(StatusHolder[]::new);
+ }
+
@Override
public void send(GameObject sender, Event event) {
receivers.stream()
diff --git a/src/main/java/eod/event/relay/EventSender.java b/src/main/java/eod/event/relay/EventSender.java
index 4386cec..2bd3c1b 100644
--- a/src/main/java/eod/event/relay/EventSender.java
+++ b/src/main/java/eod/event/relay/EventSender.java
@@ -3,12 +3,12 @@
import eod.GameObject;
import eod.event.Event;
-import java.util.ArrayList;
-
public interface EventSender {
void registerReceiver(EventReceiver receiver);
void unregisterReceiver(EventReceiver receiver);
+ StatusHolder[] getStatusHolders();
+
void send(GameObject sender, Event event);
}
diff --git a/src/main/java/eod/event/relay/StatusHolder.java b/src/main/java/eod/event/relay/StatusHolder.java
new file mode 100644
index 0000000..4693464
--- /dev/null
+++ b/src/main/java/eod/event/relay/StatusHolder.java
@@ -0,0 +1,11 @@
+package eod.event.relay;
+
+import eod.warObject.Status;
+
+import java.util.ArrayList;
+
+public interface StatusHolder extends EventReceiver {
+ // the receiver that holds status for a limited time
+ // It will only remove the status if no other holder is holding its statuses.
+ ArrayList holdingStatus();
+}
diff --git a/src/main/java/eod/warObject/Status.java b/src/main/java/eod/warObject/Status.java
index 38f88d6..17e95a5 100644
--- a/src/main/java/eod/warObject/Status.java
+++ b/src/main/java/eod/warObject/Status.java
@@ -8,5 +8,7 @@ public enum Status {
STABLE,
FURIOUS,
CANT_ATTACK,
- NO_EFFECT
+ NO_EFFECT,
+ POISON,
+ NO_ATTACK
}
diff --git a/src/main/java/eod/warObject/WarObject.java b/src/main/java/eod/warObject/WarObject.java
index c5ea22d..a6d9263 100644
--- a/src/main/java/eod/warObject/WarObject.java
+++ b/src/main/java/eod/warObject/WarObject.java
@@ -9,6 +9,7 @@
import eod.event.StatusAcquiredEvent;
import eod.event.relay.EventReceiver;
import eod.event.relay.EventSender;
+import eod.event.relay.StatusHolder;
import eod.param.PointParam;
import java.awt.*;
@@ -93,6 +94,14 @@ public void unregisterReceiver(EventReceiver receiver) {
receivers.remove(receiver);
}
+ @Override
+ public StatusHolder[] getStatusHolders() {
+ return receivers.stream()
+ .filter(receiver -> receiver instanceof StatusHolder)
+ .map(receiver -> (StatusHolder) receiver)
+ .toArray(StatusHolder[]::new);
+ }
+
@Override
public void send(GameObject sender, Event event) {
receivers.stream()
diff --git a/src/main/java/eod/warObject/character/abstraction/Character.java b/src/main/java/eod/warObject/character/abstraction/Character.java
index 231396c..df4e248 100644
--- a/src/main/java/eod/warObject/character/abstraction/Character.java
+++ b/src/main/java/eod/warObject/character/abstraction/Character.java
@@ -1,12 +1,17 @@
package eod.warObject.character.abstraction;
+import eod.GameObject;
import eod.Gameboard;
import eod.Party;
import eod.Player;
import eod.card.abstraction.summon.SummonCard;
+import eod.effect.Damage;
+import eod.effect.Effect;
import eod.event.AfterObjectDamageEvent;
import eod.event.BeforeObjectDamageEvent;
import eod.effect.EffectExecutor;
+import eod.event.Event;
+import eod.event.RoundStartEvent;
import eod.param.AttackParam;
import eod.param.DamageParam;
import eod.warObject.CanAttack;
@@ -18,6 +23,9 @@
import java.util.ArrayList;
import java.util.Arrays;
+import static eod.effect.EffectFunctions.Damage;
+import static eod.warObject.Status.POISON;
+
public abstract class Character extends WarObject implements Damageable, CanAttack {
protected ArrayList status = new ArrayList<>();
protected int max_hp;
@@ -146,6 +154,11 @@ public void die() {
teardown();
}
+ @Override
+ public int getHp() {
+ return hp;
+ }
+
@Override
public void teardown() {
super.teardown();
@@ -153,8 +166,15 @@ public void teardown() {
}
@Override
- public int getHp() {
- return hp;
+ public void onEventOccurred(GameObject sender, Event event) {
+ super.onEventOccurred(sender, event);
+ if(event instanceof RoundStartEvent) {
+ if(player.isActingPlayer() && hasStatus(POISON)) {
+ player.tryToExecute(
+ Damage(new DamageParam(1), Effect.HandlerType.Owner).on(this)
+ );
+ }
+ }
}
public abstract SummonCard getSummonCard();
diff --git a/src/main/java/eod/warObject/character/concrete/blue/HeavyPolice.java b/src/main/java/eod/warObject/character/concrete/blue/HeavyPolice.java
index cd2a02c..e658e76 100644
--- a/src/main/java/eod/warObject/character/concrete/blue/HeavyPolice.java
+++ b/src/main/java/eod/warObject/character/concrete/blue/HeavyPolice.java
@@ -21,7 +21,7 @@
public class HeavyPolice extends Character {
public HeavyPolice(Player player) {
super(player, 5,5, Party.BLUE);
- new DamageLessThan2();
+ registerReceiver(new DamageLessThan2());
}
@Override
@@ -59,7 +59,6 @@ public class DamageLessThan2 implements EventReceiver {
public DamageLessThan2() {
this.canHandle = new ArrayList<>();
canHandle.add(BeforeObjectDamageEvent.class);
- HeavyPolice.this.registerReceiver(this);
}
@Override
diff --git a/src/main/java/eod/warObject/character/concrete/red/AssaultTeamLeader.java b/src/main/java/eod/warObject/character/concrete/red/AssaultTeamLeader.java
index 6a809c3..5b06d43 100644
--- a/src/main/java/eod/warObject/character/concrete/red/AssaultTeamLeader.java
+++ b/src/main/java/eod/warObject/character/concrete/red/AssaultTeamLeader.java
@@ -24,7 +24,7 @@
public class AssaultTeamLeader extends Character {
public AssaultTeamLeader(Player player) {
super(player, 1, 1, Party.RED);
- new OwnedAbilities();
+ registerReceiver(new OwnedAbilities());
}
@Override
@@ -53,7 +53,7 @@ public SummonCard getSummonCard() {
@Override
public String getName() {
- return "特攻隊隊長";
+ return "特攻隊長";
}
private class OwnedAbilities implements EventReceiver {
@@ -64,7 +64,6 @@ public OwnedAbilities() {
canHandle.add(RoundStartEvent.class);
canHandle.add(ObjectEnterEnemyBaseEvent.class);
canHandle.add(StatusAcquiredEvent.class);
- AssaultTeamLeader.this.registerReceiver(this);
}
diff --git a/src/main/java/eod/warObject/character/concrete/red/BloodThirstFighter.java b/src/main/java/eod/warObject/character/concrete/red/BloodThirstFighter.java
index 28d2d82..499131d 100644
--- a/src/main/java/eod/warObject/character/concrete/red/BloodThirstFighter.java
+++ b/src/main/java/eod/warObject/character/concrete/red/BloodThirstFighter.java
@@ -23,7 +23,7 @@
public class BloodThirstFighter extends Fighter {
public BloodThirstFighter(Player player) {
super(player, 4, 3, Party.RED);
- new OwnedAbilities();
+ registerReceiver(new OwnedAbilities());
}
@Override
@@ -67,7 +67,6 @@ private class OwnedAbilities implements EventReceiver {
public OwnedAbilities() {
canHandle = new ArrayList<>();
canHandle.add(ObjectEnterEvent.class);
- BloodThirstFighter.this.registerReceiver(this);
}
@Override
diff --git a/src/main/java/eod/warObject/character/concrete/red/CrazyBomber.java b/src/main/java/eod/warObject/character/concrete/red/CrazyBomber.java
index 558da54..c355fcf 100644
--- a/src/main/java/eod/warObject/character/concrete/red/CrazyBomber.java
+++ b/src/main/java/eod/warObject/character/concrete/red/CrazyBomber.java
@@ -26,7 +26,7 @@
public class CrazyBomber extends Character {
public CrazyBomber(Player player) {
super(player, 1, 2, Party.RED);
- new OwnedAbilities();
+ registerReceiver(new OwnedAbilities());
}
@Override
@@ -73,7 +73,6 @@ private class OwnedAbilities implements EventReceiver {
public OwnedAbilities() {
canHandle = new ArrayList<>();
canHandle.add(ObjectDeadEvent.class);
- CrazyBomber.this.registerReceiver(this);
}
@Override
diff --git a/src/main/java/eod/warObject/character/concrete/red/LeadersGuard.java b/src/main/java/eod/warObject/character/concrete/red/LeadersGuard.java
index 0b10408..f0e3318 100644
--- a/src/main/java/eod/warObject/character/concrete/red/LeadersGuard.java
+++ b/src/main/java/eod/warObject/character/concrete/red/LeadersGuard.java
@@ -23,7 +23,7 @@
public class LeadersGuard extends Shooter {
public LeadersGuard(Player player) {
super(player, 5, 2, Party.RED);
- new OwnedAbilities();
+ registerReceiver(new OwnedAbilities());
}
@Override
@@ -58,7 +58,6 @@ private class OwnedAbilities implements EventReceiver {
public OwnedAbilities() {
canHandle = new ArrayList<>();
canHandle.add(ObjectMovingEvent.class);
- LeadersGuard.this.registerReceiver(this);
}
@Override
diff --git a/src/main/java/eod/warObject/character/concrete/red/ToughGuy.java b/src/main/java/eod/warObject/character/concrete/red/ToughGuy.java
index b4296ba..c6a925d 100644
--- a/src/main/java/eod/warObject/character/concrete/red/ToughGuy.java
+++ b/src/main/java/eod/warObject/character/concrete/red/ToughGuy.java
@@ -21,7 +21,7 @@
public class ToughGuy extends Fighter {
public ToughGuy(Player player) {
super(player, 6, 3, Party.RED);
- new OwnedAbilities();
+ registerReceiver(new OwnedAbilities());
}
@Override
@@ -59,7 +59,6 @@ private class OwnedAbilities implements EventReceiver {
public OwnedAbilities() {
canHandle = new ArrayList<>();
canHandle.add(AfterObjectDamageEvent.class);
- ToughGuy.this.registerReceiver(this);
}
@Override
diff --git a/src/main/java/eod/warObject/character/concrete/transparent/AssassinsIntermediary.java b/src/main/java/eod/warObject/character/concrete/transparent/AssassinsIntermediary.java
new file mode 100644
index 0000000..b67374a
--- /dev/null
+++ b/src/main/java/eod/warObject/character/concrete/transparent/AssassinsIntermediary.java
@@ -0,0 +1,76 @@
+package eod.warObject.character.concrete.transparent;
+
+import eod.GameObject;
+import eod.Party;
+import eod.Player;
+import eod.card.abstraction.summon.AssassinSummon;
+import eod.card.abstraction.summon.SummonCard;
+import eod.card.concrete.summon.AssassinsIntermediarySummon;
+import eod.event.Event;
+import eod.event.ObjectEnterEvent;
+import eod.event.relay.EventReceiver;
+import eod.param.PointParam;
+import eod.warObject.character.abstraction.Character;
+import eod.warObject.character.abstraction.assaulter.Assassin;
+
+import java.awt.*;
+import java.util.ArrayList;
+
+public class AssassinsIntermediary extends Character {
+ public AssassinsIntermediary(Player player) {
+ super(player, 2, 1, Party.TRANSPARENT);
+ registerReceiver(new OwnedAbilities());
+ }
+
+ @Override
+ public SummonCard getSummonCard() {
+ SummonCard c = new AssassinsIntermediarySummon();
+ c.setPlayer(player);
+ return c;
+ }
+
+ @Override
+ public String getName() {
+ return "殺手掮客";
+ }
+
+ @Override
+ public ArrayList getAttackRange() {
+ PointParam param = new PointParam();
+ param.range = 1;
+ return player.getBoard().get4Ways(position, param);
+ }
+
+ private class OwnedAbilities implements EventReceiver {
+ private ArrayList> canHandle;
+
+
+ public OwnedAbilities() {
+ canHandle = new ArrayList<>();
+ canHandle.add(ObjectEnterEvent.class);
+ }
+
+ @Override
+ public ArrayList> supportedEventTypes() {
+ return canHandle;
+ }
+
+ @Override
+ public void onEventOccurred(GameObject sender, Event event) {
+ if(event instanceof ObjectEnterEvent) {
+ ObjectEnterEvent e = (ObjectEnterEvent) event;
+ if (e.getObject() == AssassinsIntermediary.this) {
+ player.drawFromDeck(AssassinSummon.class, 1);
+ teardown();
+ }
+ }
+ }
+
+ @Override
+ public void teardown() {
+ AssassinsIntermediary.this.unregisterReceiver(this);
+ canHandle.clear();
+ canHandle = null;
+ }
+ }
+}
diff --git a/src/main/java/eod/warObject/character/concrete/transparent/ExpertOfPoison.java b/src/main/java/eod/warObject/character/concrete/transparent/ExpertOfPoison.java
new file mode 100644
index 0000000..ad72a7d
--- /dev/null
+++ b/src/main/java/eod/warObject/character/concrete/transparent/ExpertOfPoison.java
@@ -0,0 +1,57 @@
+package eod.warObject.character.concrete.transparent;
+
+import eod.Gameboard;
+import eod.Party;
+import eod.Player;
+import eod.card.abstraction.summon.SummonCard;
+import eod.card.concrete.summon.ExpertOfPoisonSummon;
+import eod.effect.Effect;
+import eod.effect.EffectExecutor;
+import eod.param.PointParam;
+import eod.warObject.Status;
+import eod.warObject.WarObject;
+import eod.warObject.character.abstraction.Character;
+
+import java.awt.*;
+import java.util.ArrayList;
+
+import static eod.effect.EffectFunctions.GiveStatus;
+
+public class ExpertOfPoison extends Character {
+ public ExpertOfPoison(Player player) {
+ super(player, 2, 2, Party.TRANSPARENT);
+ }
+
+ @Override
+ public SummonCard getSummonCard() {
+ SummonCard c = new ExpertOfPoisonSummon();
+ c.setPlayer(player);
+ return c;
+ }
+
+ @Override
+ public String getName() {
+ return "毒殺專家";
+ }
+
+ @Override
+ public ArrayList getAttackRange() {
+ return player.getBoard().allSpaces(new Point(Gameboard.firstLine, 0), new PointParam());
+ }
+
+ @Override
+ public void attack(EffectExecutor executor) {
+ super.attack(executor);
+ try {
+ Point p = player.selectPosition(getAttackRange());
+ WarObject object = player.getBoard().getObjectOn(p.x, p.y);
+ player.tryToExecute(
+ GiveStatus(Status.POISON, Effect.HandlerType.Rival).to(object)
+ );
+ } catch (IllegalArgumentException e) {
+ System.out.println("The selected position is empty. Skipping.");
+ }
+
+ afterAttack();
+ }
+}
diff --git a/src/main/java/eod/warObject/character/concrete/transparent/FacelessHuman.java b/src/main/java/eod/warObject/character/concrete/transparent/FacelessHuman.java
new file mode 100644
index 0000000..078f5cd
--- /dev/null
+++ b/src/main/java/eod/warObject/character/concrete/transparent/FacelessHuman.java
@@ -0,0 +1,51 @@
+package eod.warObject.character.concrete.transparent;
+
+import eod.Party;
+import eod.Player;
+import eod.card.abstraction.summon.SummonCard;
+import eod.card.concrete.summon.FacelessHumanSummon;
+import eod.effect.EffectExecutor;
+import eod.param.PointParam;
+import eod.warObject.character.abstraction.Character;
+
+import java.awt.*;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+
+import static eod.specifier.WarObjectSpecifier.WarObject;
+
+public class FacelessHuman extends Character {
+ public FacelessHuman(Player player) {
+ super(player, 3, 3, Party.TRANSPARENT);
+ }
+
+ @Override
+ public SummonCard getSummonCard() {
+ SummonCard c = new FacelessHumanSummon();
+ c.setPlayer(player);
+ return c;
+ }
+
+ @Override
+ public ArrayList getAttackRange() {
+ return player.getBoard().allSpaces(new Point(-1, 0), new PointParam());
+ }
+
+ @Override
+ public String getName() {
+ return "無面的人";
+ }
+
+ @Override
+ public void attack(EffectExecutor executor) {
+ super.attack(executor);
+ try {
+ player.transferObjectTo(this, player.selectObject(
+ WarObject(player.getBoard()).get()
+ ).getClass().getConstructor(Player.class).newInstance(player));
+ } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
+ System.out.println(e.getMessage());
+ }
+ }
+ // Todo: finish its abilities
+}
diff --git a/src/main/java/eod/warObject/character/concrete/transparent/IntelligenceVendor.java b/src/main/java/eod/warObject/character/concrete/transparent/IntelligenceVendor.java
new file mode 100644
index 0000000..d25ce32
--- /dev/null
+++ b/src/main/java/eod/warObject/character/concrete/transparent/IntelligenceVendor.java
@@ -0,0 +1,162 @@
+package eod.warObject.character.concrete.transparent;
+
+import eod.GameObject;
+import eod.Party;
+import eod.Player;
+import eod.card.abstraction.summon.SummonCard;
+import eod.card.concrete.summon.IntelligenceVendorSummon;
+import eod.effect.Effect;
+import eod.effect.EffectExecutor;
+import eod.event.Event;
+import eod.event.RoundEndEvent;
+import eod.event.relay.EventReceiver;
+import eod.event.relay.StatusHolder;
+import eod.param.PointParam;
+import eod.warObject.Status;
+import eod.warObject.WarObject;
+import eod.warObject.character.abstraction.Character;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import static eod.effect.EffectFunctions.GiveStatus;
+
+public class IntelligenceVendor extends Character {
+ public IntelligenceVendor(Player player) {
+ super(player, 3, 0, Party.TRANSPARENT);
+ registerReceiver(new OwnedAbilities());
+ }
+
+ @Override
+ public SummonCard getSummonCard() {
+ SummonCard c = new IntelligenceVendorSummon();
+ c.setPlayer(player);
+ return c;
+ }
+
+ @Override
+ public String getName() {
+ return "情報販";
+ }
+
+ @Override
+ public ArrayList getAttackRange() {
+ return player.getBoard().allSpaces(new Point(-1, 0), new PointParam());
+ }
+
+ @Override
+ public void attack(EffectExecutor executor) {
+ super.attack(executor);
+ try {
+ Point p = player.selectPosition(getAttackRange());
+ WarObject object = player.getBoard().getObjectOn(p.x, p.y);
+
+ object.registerReceiver(new AttackEffectLock(object));
+ } catch (IllegalArgumentException e) {
+ System.out.println("There's no object on the selected point. Skipping.");
+ }
+
+ afterAttack();
+ }
+
+
+ private class AttackEffectLock implements StatusHolder {
+
+ private WarObject holder;
+ private ArrayList> canHandle;
+ private ArrayList holdingStatus;
+
+ public AttackEffectLock(WarObject object) {
+ this.holder = object;
+ canHandle = new ArrayList<>();
+ canHandle.add(RoundEndEvent.class);
+
+ holdingStatus = new ArrayList<>();
+ holdingStatus.add(Status.NO_ATTACK);
+ holdingStatus.add(Status.NO_EFFECT);
+
+ holdingStatus.forEach(status -> object.getPlayer().tryToExecute(
+ GiveStatus(status, Effect.HandlerType.Owner).to(object)
+ ));
+ }
+
+ @Override
+ public ArrayList> supportedEventTypes() {
+ return canHandle;
+ }
+
+ @Override
+ public void onEventOccurred(GameObject sender, Event event) {
+ if(event instanceof RoundEndEvent) {
+ RoundEndEvent e = (RoundEndEvent) event;
+ if(e.getEndedRound().getPlayer().isPlayerA() != player.rival().isPlayerA()) {
+ // End of the enemy's round.
+ teardown();
+ }
+ }
+ }
+
+ @Override
+ public void teardown() {
+ holder.unregisterReceiver(this);
+ StatusHolder[] temporaryReceivers = holder.getStatusHolders();
+ holdingStatus.forEach(status -> {
+ if(Arrays.stream(temporaryReceivers)
+ .filter(receiver -> receiver.holdingStatus().contains(status))
+ .toArray().length == 0) {
+ holder.removeStatus(status);
+ }
+ });
+
+ holder = null;
+ holdingStatus.clear();
+ holdingStatus = null;
+ canHandle.clear();
+ canHandle = null;
+ }
+
+ @Override
+ public ArrayList holdingStatus() {
+ return holdingStatus;
+ }
+ }
+
+
+
+ private class OwnedAbilities implements EventReceiver {
+ private ArrayList> canHandle;
+
+ public OwnedAbilities() {
+ canHandle = new ArrayList<>();
+ canHandle.add(RoundEndEvent.class);
+ }
+
+ @Override
+ public ArrayList> supportedEventTypes() {
+ return canHandle;
+ }
+
+ @Override
+ public void onEventOccurred(GameObject sender, Event event) {
+ if(IntelligenceVendor.this.hasStatus(Status.NO_EFFECT)) {
+ return;
+ }
+ if(event instanceof RoundEndEvent) {
+ RoundEndEvent e = (RoundEndEvent) event;
+ if(e.getEndedRound().getPlayer().isPlayerA() == player.isPlayerA()) {
+ if(player.getHand().size() <= 2) {
+ player.drawFromDeck(2);
+ } else {
+ player.drawFromDeck(1);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void teardown() {
+ IntelligenceVendor.this.unregisterReceiver(this);
+ }
+ }
+}
diff --git a/src/main/java/eod/warObject/character/concrete/transparent/OwnerlessAssassin.java b/src/main/java/eod/warObject/character/concrete/transparent/OwnerlessAssassin.java
index a808a8c..9d6fda4 100644
--- a/src/main/java/eod/warObject/character/concrete/transparent/OwnerlessAssassin.java
+++ b/src/main/java/eod/warObject/character/concrete/transparent/OwnerlessAssassin.java
@@ -22,7 +22,7 @@
public class OwnerlessAssassin extends Assassin {
public OwnerlessAssassin(Player player) {
super(player, 2, 4, Party.TRANSPARENT);
- new OwnedAbilities();
+ registerReceiver(new OwnedAbilities());
}
@Override
@@ -58,7 +58,6 @@ private class OwnedAbilities implements EventReceiver {
public OwnedAbilities() {
canHandle = new ArrayList<>();
canHandle.add(RoundStartEvent.class);
- OwnerlessAssassin.this.registerReceiver(this);
}
@Override
diff --git a/src/main/java/eod/warObject/character/concrete/transparent/Spacezipper.java b/src/main/java/eod/warObject/character/concrete/transparent/Spacezipper.java
index d6028c9..cc8159d 100644
--- a/src/main/java/eod/warObject/character/concrete/transparent/Spacezipper.java
+++ b/src/main/java/eod/warObject/character/concrete/transparent/Spacezipper.java
@@ -25,7 +25,7 @@ public class Spacezipper extends Character implements Marker {
public Spacezipper(Player player) {
super(player, 5, 3, Party.TRANSPARENT);
marked = new ArrayList<>();
- new OwnedAbilities();
+ registerReceiver(new OwnedAbilities());
}
@Override
@@ -110,7 +110,6 @@ private class OwnedAbilities implements EventReceiver {
public OwnedAbilities() {
canHandle = new ArrayList<>();
canHandle.add(RoundStartEvent.class);
- Spacezipper.this.registerReceiver(this);
}
@Override
@@ -134,6 +133,7 @@ public void teardown() {
Spacezipper.this.unregisterReceiver(this);
canHandle.clear();
canHandle = null;
+ clearMark();
}
}
}
diff --git a/src/main/java/eod/warObject/leader/red/Sundar.java b/src/main/java/eod/warObject/leader/red/Sundar.java
index b22856d..0219b9e 100644
--- a/src/main/java/eod/warObject/leader/red/Sundar.java
+++ b/src/main/java/eod/warObject/leader/red/Sundar.java
@@ -32,7 +32,7 @@
public class Sundar extends Leader {
public Sundar(Player player) {
super(player, 20, 0, Party.RED);
- canHandle.add(ObjectDeadEvent.class);
+ registerReceiver(new OwnedAbilities());
}
@Override
@@ -89,15 +89,12 @@ private boolean isDeadObjectOwnedByEnemy(WarObject object) {
}
private class OwnedAbilities implements EventReceiver {
- private Sundar holder;
private ArrayList> canHandle;
- public OwnedAbilities(Sundar holder) {
- this.holder = holder;
+ public OwnedAbilities() {
this.canHandle = new ArrayList<>();
canHandle.add(ObjectDeadEvent.class);
- holder.registerReceiver(this);
}
@Override
@@ -121,7 +118,7 @@ public void onEventOccurred(GameObject sender, Event event) {
player.tryToExecute(
Summon(new LittleGhost(player)).on(new Point(x, y))
);
- } else if(object.getPlayer().isPlayerA() == holder.player.isPlayerA() && isGhostOrSundar(attacker) && ((WarObject) attacker).getPlayer().equals(player)){
+ } else if(object.getPlayer().isPlayerA() == Sundar.this.player.isPlayerA() && isGhostOrSundar(attacker) && ((WarObject) attacker).getPlayer().equals(player)){
player.getBoard().summonObject(new GhostOfHatred(player), new Point(x, y));
}
}
@@ -129,8 +126,7 @@ public void onEventOccurred(GameObject sender, Event event) {
@Override
public void teardown() {
- holder.unregisterReceiver(this);
- holder = null;
+ Sundar.this.unregisterReceiver(this);
canHandle.clear();
canHandle = null;
}