mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
Commit stage 1 of large game view refactoring
This commit is contained in:
11
.gitattributes
vendored
11
.gitattributes
vendored
@@ -271,6 +271,7 @@ forge-game/src/main/java/forge/game/GameAction.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/GameActionUtil.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/GameEndReason.java -text
|
||||
forge-game/src/main/java/forge/game/GameEntity.java -text
|
||||
forge-game/src/main/java/forge/game/GameEntityView.java -text
|
||||
forge-game/src/main/java/forge/game/GameFormat.java -text
|
||||
forge-game/src/main/java/forge/game/GameLog.java -text
|
||||
forge-game/src/main/java/forge/game/GameLogEntry.java -text
|
||||
@@ -281,6 +282,7 @@ forge-game/src/main/java/forge/game/GameOutcome.java -text
|
||||
forge-game/src/main/java/forge/game/GameRules.java -text
|
||||
forge-game/src/main/java/forge/game/GameStage.java -text
|
||||
forge-game/src/main/java/forge/game/GameType.java -text
|
||||
forge-game/src/main/java/forge/game/GameView.java -text
|
||||
forge-game/src/main/java/forge/game/GlobalRuleChange.java -text
|
||||
forge-game/src/main/java/forge/game/IHasGameType.java -text
|
||||
forge-game/src/main/java/forge/game/IIdentifiable.java -text
|
||||
@@ -441,12 +443,14 @@ forge-game/src/main/java/forge/game/card/CardPredicates.java svneol=native#text/
|
||||
forge-game/src/main/java/forge/game/card/CardShields.java -text
|
||||
forge-game/src/main/java/forge/game/card/CardType.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/card/CardUtil.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/card/CardView.java -text
|
||||
forge-game/src/main/java/forge/game/card/CounterType.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/card/package-info.java -text
|
||||
forge-game/src/main/java/forge/game/combat/AttackingBand.java -text
|
||||
forge-game/src/main/java/forge/game/combat/Combat.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/combat/CombatLki.java -text
|
||||
forge-game/src/main/java/forge/game/combat/CombatUtil.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/combat/CombatView.java -text
|
||||
forge-game/src/main/java/forge/game/cost/Cost.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/cost/CostAddMana.java -text
|
||||
forge-game/src/main/java/forge/game/cost/CostChooseCreatureType.java -text
|
||||
@@ -550,6 +554,7 @@ forge-game/src/main/java/forge/game/player/PlayerActionConfirmMode.java -text
|
||||
forge-game/src/main/java/forge/game/player/PlayerController.java -text
|
||||
forge-game/src/main/java/forge/game/player/PlayerOutcome.java -text
|
||||
forge-game/src/main/java/forge/game/player/PlayerStatistics.java -text
|
||||
forge-game/src/main/java/forge/game/player/PlayerView.java -text
|
||||
forge-game/src/main/java/forge/game/player/RegisteredPlayer.java -text
|
||||
forge-game/src/main/java/forge/game/player/package-info.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java -text
|
||||
@@ -585,7 +590,9 @@ forge-game/src/main/java/forge/game/spellability/SpellAbilityCondition.java svne
|
||||
forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/spellability/SpellAbilityStackInstance.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/spellability/SpellAbilityVariables.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/spellability/SpellAbilityView.java -text
|
||||
forge-game/src/main/java/forge/game/spellability/SpellPermanent.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/spellability/StackItemView.java -text
|
||||
forge-game/src/main/java/forge/game/spellability/TargetChoices.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/spellability/TargetRestrictions.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/spellability/package-info.java svneol=native#text/plain
|
||||
@@ -663,6 +670,10 @@ forge-game/src/main/java/forge/game/zone/PlayerZoneBattlefield.java svneol=nativ
|
||||
forge-game/src/main/java/forge/game/zone/Zone.java -text
|
||||
forge-game/src/main/java/forge/game/zone/ZoneType.java -text
|
||||
forge-game/src/main/java/forge/game/zone/package-info.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/trackable/TrackableCollection.java -text
|
||||
forge-game/src/main/java/forge/trackable/TrackableIndex.java -text
|
||||
forge-game/src/main/java/forge/trackable/TrackableObject.java -text
|
||||
forge-game/src/main/java/forge/trackable/TrackableProperty.java -text
|
||||
forge-game/src/main/java/forge/util/Expressions.java -text
|
||||
forge-game/src/main/java/forge/util/MessageUtil.java -text
|
||||
forge-gui-android/.classpath -text
|
||||
|
||||
@@ -27,7 +27,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
@@ -1147,11 +1146,14 @@ public class AiController {
|
||||
List<Card> list = player.getCardsIn(ZoneType.Battlefield);
|
||||
list = CardLists.filter(list, CardPredicates.Presets.PLANEWALKERS);
|
||||
|
||||
List<String> type = card.getType();
|
||||
final String subtype = type.get(type.size() - 1);
|
||||
final List<Card> cl = CardLists.getType(list, subtype);
|
||||
if (!cl.isEmpty()) {
|
||||
return AiPlayDecision.WouldDestroyOtherPlaneswalker;
|
||||
for (String type : card.getType()) { //determine planewalker subtype
|
||||
if (!type.equals("Planeswalker")) {
|
||||
final List<Card> cl = CardLists.getType(list, type);
|
||||
if (!cl.isEmpty()) {
|
||||
return AiPlayDecision.WouldDestroyOtherPlaneswalker;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (card.isType("World")) {
|
||||
|
||||
@@ -172,7 +172,7 @@ public class AiCostDecision extends CostDecisionMakerBase implements ICostVisito
|
||||
}
|
||||
List<SpellAbility> chosen = new ArrayList<SpellAbility>();
|
||||
for (SpellAbilityStackInstance si :source.getGame().getStack()) {
|
||||
SpellAbility sp = si.getSpellAbility().getRootAbility();
|
||||
SpellAbility sp = si.getSpellAbility(true).getRootAbility();
|
||||
if (si.getSourceCard().isValid(cost.getType().split(";"), source.getController(), source)) {
|
||||
chosen.add(sp);
|
||||
}
|
||||
|
||||
@@ -1196,7 +1196,7 @@ public class ComputerUtil {
|
||||
for (StaticAbility stAb : c.getStaticAbilities()) {
|
||||
Map<String, String> params = stAb.getMapParams();
|
||||
if ("Continuous".equals(params.get("Mode")) && params.containsKey("AddKeyword")
|
||||
&& params.get("AddKeyword").contains("Haste") && c.getEquippingCard() == null) {
|
||||
&& params.get("AddKeyword").contains("Haste") && c.getEquipping() == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1376,7 +1376,7 @@ public class ComputerUtil {
|
||||
}
|
||||
|
||||
// already regenerated
|
||||
if (!c.getShield().isEmpty()) {
|
||||
if (c.getShieldCount() > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1431,13 +1431,13 @@ public class ComputerUtil {
|
||||
if (o instanceof Card) {
|
||||
final Card c = (Card) o;
|
||||
final boolean canRemove = (c.getNetDefense() <= dmg)
|
||||
|| (!c.hasKeyword("Indestructible") && c.getShield().isEmpty() && (dmg >= ComputerUtilCombat.getDamageToKill(c)));
|
||||
|| (!c.hasKeyword("Indestructible") && c.getShieldCount() == 0 && (dmg >= ComputerUtilCombat.getDamageToKill(c)));
|
||||
if (!canRemove) {
|
||||
continue;
|
||||
}
|
||||
if (saviourApi == ApiType.Pump || saviourApi == ApiType.PumpAll ) {
|
||||
final boolean cantSave = c.getNetDefense() + defense <= dmg
|
||||
|| (!c.hasKeyword("Indestructible") && c.getShield().isEmpty() && !grantIndestructible
|
||||
|| (!c.hasKeyword("Indestructible") && c.getShieldCount() == 0 && !grantIndestructible
|
||||
&& (dmg >= defense + ComputerUtilCombat.getDamageToKill(c)));
|
||||
if (cantSave && (tgt == null || !grantShroud)) {
|
||||
continue;
|
||||
@@ -1473,7 +1473,7 @@ public class ComputerUtil {
|
||||
}
|
||||
|
||||
// already regenerated
|
||||
if (!c.getShield().isEmpty()) {
|
||||
if (c.getShieldCount() > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -784,9 +784,7 @@ public class ComputerUtilCard {
|
||||
final Map<String, Integer> map = new HashMap<String, Integer>();
|
||||
|
||||
for (final Card c : list) {
|
||||
final ArrayList<String> typeList = c.getType();
|
||||
|
||||
for (final String var : typeList) {
|
||||
for (final String var : c.getType()) {
|
||||
if (CardType.isACreatureType(var)) {
|
||||
if (!map.containsKey(var)) {
|
||||
map.put(var, 1);
|
||||
@@ -987,7 +985,7 @@ public class ComputerUtilCard {
|
||||
Combat currCombat = game.getCombat();
|
||||
if (currCombat != null && !currCombat.getAllBlockers().isEmpty() && currCombat.getAllBlockers().contains(c)) {
|
||||
for (Card attacker : currCombat.getAttackersBlockedBy(c)) {
|
||||
if (attacker.getShield().isEmpty() && ComputerUtilCombat.attackerWouldBeDestroyed(ai, attacker, currCombat)) {
|
||||
if (attacker.getShieldCount() == 0 && ComputerUtilCombat.attackerWouldBeDestroyed(ai, attacker, currCombat)) {
|
||||
List<Card> blockers = currCombat.getBlockers(attacker);
|
||||
ComputerUtilCard.sortByEvaluateCreature(blockers);
|
||||
Combat combat = new Combat(ai);
|
||||
|
||||
@@ -1978,7 +1978,7 @@ public class ComputerUtilCombat {
|
||||
final boolean noPrevention) {
|
||||
final int killDamage = ComputerUtilCombat.getDamageToKill(c);
|
||||
|
||||
if (c.hasKeyword("Indestructible") || !c.getShield().isEmpty()) {
|
||||
if (c.hasKeyword("Indestructible") || c.getShieldCount() > 0) {
|
||||
if (!(source.hasKeyword("Wither") || source.hasKeyword("Infect"))) {
|
||||
return maxDamage + 1;
|
||||
}
|
||||
|
||||
@@ -1118,7 +1118,7 @@ public class ComputerUtilMana {
|
||||
&& replacementEffect.zonesCheck(game.getZoneOf(crd))) {
|
||||
String repType = crd.getSVar(replacementEffect.getMapParams().get("ManaReplacement"));
|
||||
if (repType.contains("Chosen")) {
|
||||
repType = repType.replace("Chosen", MagicColor.toShortString(crd.getChosenColor().get(0)));
|
||||
repType = repType.replace("Chosen", MagicColor.toShortString(crd.getChosenColors().get(0)));
|
||||
}
|
||||
mp.setManaReplaceType(repType);
|
||||
}
|
||||
|
||||
@@ -634,7 +634,7 @@ public class PlayerControllerAi extends PlayerController {
|
||||
String choice = choices.get(0);
|
||||
if (game.stack.size() > 1) {
|
||||
for (SpellAbilityStackInstance si : game.getStack()) {
|
||||
SpellAbility spell = si.getSpellAbility();
|
||||
SpellAbility spell = si.getSpellAbility(true);
|
||||
if (sa != spell) {
|
||||
String s = ProtectAi.toProtectFrom(spell.getHostCard(), sa);
|
||||
if (s != null) {
|
||||
@@ -786,7 +786,7 @@ public class PlayerControllerAi extends PlayerController {
|
||||
|
||||
@Override
|
||||
public CardShields chooseRegenerationShield(Card c) {
|
||||
return Iterables.getFirst(c.getShield(), null);
|
||||
return Iterables.getFirst(c.getShields(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -326,7 +326,7 @@ public class AnimateAi extends SpellAbilityAi {
|
||||
final String colors = sa.getParam("Colors");
|
||||
if (colors.equals("ChosenColor")) {
|
||||
|
||||
tmpDesc = CardUtil.getShortColorsString(source.getChosenColor());
|
||||
tmpDesc = CardUtil.getShortColorsString(source.getChosenColors());
|
||||
} else {
|
||||
tmpDesc = CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(colors.split(","))));
|
||||
}
|
||||
|
||||
@@ -678,7 +678,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
|
||||
//don't equip a worse creature
|
||||
if (card.isEquipping()) {
|
||||
Card oldTarget = card.getEquipping().get(0);
|
||||
Card oldTarget = card.getEquipping();
|
||||
if (ComputerUtilCard.evaluateCreature(oldTarget) > ComputerUtilCard.evaluateCreature(newTarget)) {
|
||||
return false;
|
||||
}
|
||||
@@ -990,7 +990,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
return null;
|
||||
}
|
||||
// Don't fortify if already fortifying
|
||||
if (attachSource.getFortifyingCard() != null && attachSource.getFortifyingCard().getController() == aiPlayer) {
|
||||
if (attachSource.getFortifying() != null && attachSource.getFortifying().getController() == aiPlayer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1019,14 +1019,14 @@ public class AttachAi extends SpellAbilityAi {
|
||||
|
||||
AiController aic = ((PlayerControllerAi)aiPlayer.getController()).getAi();
|
||||
if (c != null && attachSource.getType().contains("Equipment")
|
||||
&& attachSource.getEquippingCard() != null
|
||||
&& attachSource.getEquippingCard().getController() == aiPlayer) {
|
||||
if (c.equals(attachSource.getEquippingCard())) {
|
||||
&& attachSource.isEquipping()
|
||||
&& attachSource.getEquipping().getController() == aiPlayer) {
|
||||
if (c.equals(attachSource.getEquipping())) {
|
||||
// Do not equip if equipping the same card already
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean uselessCreature = isUselessCreature(aiPlayer, attachSource.getEquippingCard());
|
||||
boolean uselessCreature = isUselessCreature(aiPlayer, attachSource.getEquipping());
|
||||
|
||||
if (aic.getProperty(AiProps.MOVE_EQUIPMENT_TO_BETTER_CREATURES).equals("never")) {
|
||||
// Do not equip other creatures if the AI profile does not allow moving equipment around
|
||||
@@ -1330,9 +1330,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
return true;
|
||||
}
|
||||
|
||||
ArrayList<String> cardTypes = sa.getHostCard().getType();
|
||||
|
||||
if (cardTypes.contains("Equipment") && isUselessCreature(ai, c)) {
|
||||
if (sa.getHostCard().getType().contains("Equipment") && isUselessCreature(ai, c)) {
|
||||
// useless to equip a creature that can't attack or block.
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -736,7 +736,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
for (Card attacker : attackers) {
|
||||
List<Card> blockers = currCombat.getBlockers(attacker);
|
||||
// Save my attacker by bouncing a blocker
|
||||
if (attacker.getController().equals(ai) && attacker.getShield().isEmpty()
|
||||
if (attacker.getController().equals(ai) && attacker.getShieldCount() == 0
|
||||
&& ComputerUtilCombat.attackerWouldBeDestroyed(ai, attacker, currCombat)
|
||||
&& !currCombat.getBlockers(attacker).isEmpty()) {
|
||||
ComputerUtilCard.sortByEvaluateCreature(blockers);
|
||||
@@ -799,7 +799,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
ComputerUtilCard.sortByEvaluateCreature(combatants);
|
||||
|
||||
for (final Card c : combatants) {
|
||||
if (c.getShield().isEmpty() && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat) && c.getOwner() == ai && !c.isToken()) {
|
||||
if (c.getShieldCount() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat) && c.getOwner() == ai && !c.isToken()) {
|
||||
sa.getTargets().add(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ public class ChooseSourceAi extends SpellAbilityAi {
|
||||
private Card chooseCardOnStack(SpellAbility sa, Player ai, Game game) {
|
||||
for (SpellAbilityStackInstance si : game.getStack()) {
|
||||
final Card source = si.getSourceCard();
|
||||
final SpellAbility abilityOnStack = si.getSpellAbility();
|
||||
final SpellAbility abilityOnStack = si.getSpellAbility(true);
|
||||
|
||||
if (sa.hasParam("Choices") && !abilityOnStack.getHostCard().isValid(sa.getParam("Choices"), ai, sa.getHostCard())) {
|
||||
continue;
|
||||
|
||||
@@ -287,7 +287,7 @@ public class DamageDealAi extends DamageAiBase {
|
||||
}
|
||||
final int assignedDamage = ComputerUtilCombat.getEnoughDamageToKill(humanCreature, dmg, source, false, noPrevention);
|
||||
if (assignedDamage <= dmg
|
||||
&& humanCreature.getShield().isEmpty() && !ComputerUtil.canRegenerate(humanCreature.getController(), humanCreature)) {
|
||||
&& humanCreature.getShieldCount() == 0 && !ComputerUtil.canRegenerate(humanCreature.getController(), humanCreature)) {
|
||||
tcs.add(humanCreature);
|
||||
tgt.addDividedAllocation(humanCreature, assignedDamage);
|
||||
lastTgt = humanCreature;
|
||||
|
||||
@@ -113,7 +113,7 @@ public class DestroyAi extends SpellAbilityAi {
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return (c.getShield().isEmpty() && !ComputerUtil.canRegenerate(ai, c));
|
||||
return (c.getShieldCount() == 0 && !ComputerUtil.canRegenerate(ai, c));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -237,7 +237,7 @@ public class DestroyAi extends SpellAbilityAi {
|
||||
preferred = CardLists.filter(preferred, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.getShield().isEmpty();
|
||||
return c.getShieldCount() == 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -118,10 +118,11 @@ public class EffectAi extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
boolean threatened = false;
|
||||
for (final SpellAbilityStackInstance stackSA : game.getStack()) {
|
||||
if (!stackSA.isSpell()) { continue; }
|
||||
if (stackSA.getSpellAbility().getApi() == ApiType.DealDamage) {
|
||||
final SpellAbility saTargeting = stackSA.getSpellAbility().getSATargetingPlayer();
|
||||
for (final SpellAbilityStackInstance stackInst : game.getStack()) {
|
||||
if (!stackInst.isSpell()) { continue; }
|
||||
SpellAbility stackSpellAbility = stackInst.getSpellAbility(true);
|
||||
if (stackSpellAbility.getApi() == ApiType.DealDamage) {
|
||||
final SpellAbility saTargeting = stackSpellAbility.getSATargetingPlayer();
|
||||
if (saTargeting != null && Iterables.contains(saTargeting.getTargets().getTargetPlayers(), ai)) {
|
||||
threatened = true;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ public class FightAi extends SpellAbilityAi {
|
||||
return true;
|
||||
}
|
||||
if (opponent.hasProtectionFrom(fighter) || !opponent.canBeDestroyed()
|
||||
|| !opponent.getShield().isEmpty() || ComputerUtil.canRegenerate(opponent.getController(), opponent)) {
|
||||
|| opponent.getShieldCount() > 0 || ComputerUtil.canRegenerate(opponent.getController(), opponent)) {
|
||||
return false;
|
||||
}
|
||||
if (fighter.hasKeyword("Deathtouch") || ComputerUtilCombat.getDamageToKill(opponent) <= fighter.getNetAttack() + pumpAttack) {
|
||||
|
||||
@@ -138,7 +138,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
} else if (keyword.endsWith("CARDNAME can't be regenerated.")) {
|
||||
if (!card.getShield().isEmpty()) {
|
||||
if (card.getShieldCount() > 0) {
|
||||
return true;
|
||||
}
|
||||
if (card.hasKeyword("If CARDNAME would be destroyed, regenerate it.") && combat != null
|
||||
|
||||
@@ -99,7 +99,7 @@ public class RegenerateAi extends SpellAbilityAi {
|
||||
boolean flag = false;
|
||||
|
||||
for (final Card c : list) {
|
||||
if (c.getShield().isEmpty()) {
|
||||
if (c.getShieldCount() == 0) {
|
||||
flag |= ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat);
|
||||
}
|
||||
}
|
||||
@@ -128,7 +128,7 @@ public class RegenerateAi extends SpellAbilityAi {
|
||||
final List<Card> threatenedTargets = new ArrayList<Card>();
|
||||
|
||||
for (final Card c : targetables) {
|
||||
if (objects.contains(c) && c.getShield().isEmpty() && !ComputerUtil.canRegenerate(ai, c)) {
|
||||
if (objects.contains(c) && c.getShieldCount() == 0 && !ComputerUtil.canRegenerate(ai, c)) {
|
||||
threatenedTargets.add(c);
|
||||
}
|
||||
}
|
||||
@@ -144,7 +144,7 @@ public class RegenerateAi extends SpellAbilityAi {
|
||||
ComputerUtilCard.sortByEvaluateCreature(combatants);
|
||||
|
||||
for (final Card c : combatants) {
|
||||
if (c.getShield().isEmpty() && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat)) {
|
||||
if (c.getShieldCount() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat)) {
|
||||
sa.getTargets().add(c);
|
||||
chance = true;
|
||||
break;
|
||||
@@ -200,7 +200,7 @@ public class RegenerateAi extends SpellAbilityAi {
|
||||
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
|
||||
Combat combat = game.getCombat();
|
||||
for (final Card c : combatants) {
|
||||
if (c.getShield().isEmpty() && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat)) {
|
||||
if (c.getShieldCount() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat)) {
|
||||
sa.getTargets().add(c);
|
||||
return true;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ public class RegenerateAi extends SpellAbilityAi {
|
||||
// choose my best X without regen
|
||||
if (CardLists.getNotType(compTargetables, "Creature").isEmpty()) {
|
||||
for (final Card c : combatants) {
|
||||
if (c.getShield().isEmpty()) {
|
||||
if (c.getShieldCount() == 0) {
|
||||
sa.getTargets().add(c);
|
||||
return true;
|
||||
}
|
||||
@@ -223,7 +223,7 @@ public class RegenerateAi extends SpellAbilityAi {
|
||||
} else {
|
||||
CardLists.sortByCmcDesc(compTargetables);
|
||||
for (final Card c : compTargetables) {
|
||||
if (c.getShield().isEmpty()) {
|
||||
if (c.getShieldCount() == 0) {
|
||||
sa.getTargets().add(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ public class RegenerateAllAi extends SpellAbilityAi {
|
||||
final List<GameObject> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
|
||||
|
||||
for (final Card c : list) {
|
||||
if (objects.contains(c) && c.getShield().isEmpty()) {
|
||||
if (objects.contains(c) && c.getShieldCount() == 0) {
|
||||
numSaved++;
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ public class RegenerateAllAi extends SpellAbilityAi {
|
||||
final List<Card> combatants = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
||||
final Combat combat = game.getCombat();
|
||||
for (final Card c : combatants) {
|
||||
if (c.getShield().isEmpty() && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat)) {
|
||||
if (c.getShieldCount() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat)) {
|
||||
numSaved++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ public class TokenAi extends SpellAbilityAi {
|
||||
for (int i = 0; i < substitutedColors.length; i++) {
|
||||
if (substitutedColors[i].equals("ChosenColor")) {
|
||||
// this currently only supports 1 chosen color
|
||||
substitutedColors[i] = host.getChosenColor().get(0);
|
||||
substitutedColors[i] = host.getChosenColors().get(0);
|
||||
}
|
||||
}
|
||||
String colorDesc = "";
|
||||
|
||||
@@ -83,7 +83,7 @@ public class UnattachAllAi extends SpellAbilityAi {
|
||||
|
||||
//don't equip a worse creature
|
||||
if (card.isEquipping()) {
|
||||
Card oldTarget = card.getEquipping().get(0);
|
||||
Card oldTarget = card.getEquipping();
|
||||
if (ComputerUtilCard.evaluateCreature(oldTarget) > ComputerUtilCard.evaluateCreature(newTarget)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -100,6 +100,8 @@ public class Game implements IGameStateObject {
|
||||
private GameOutcome outcome;
|
||||
private boolean disableAutoYields;
|
||||
|
||||
private final GameView view = new GameView();
|
||||
|
||||
@Override
|
||||
public void loadState(GameStateDeserializer gsd) {
|
||||
gsd.readObject(rules);
|
||||
@@ -202,6 +204,10 @@ public class Game implements IGameStateObject {
|
||||
subscribeToEvents(gameLog.getEventVisitor());
|
||||
}
|
||||
|
||||
public GameView getView() {
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the players who are still fighting to win, in turn order.
|
||||
*
|
||||
|
||||
@@ -354,14 +354,14 @@ public class GameAction {
|
||||
}
|
||||
// equipment moving off battlefield
|
||||
if (copied.isEquipping()) {
|
||||
final Card equippedCreature = copied.getEquipping().get(0);
|
||||
final Card equippedCreature = copied.getEquipping();
|
||||
if (equippedCreature.isInPlay()) {
|
||||
copied.unEquipCard(equippedCreature);
|
||||
}
|
||||
}
|
||||
// fortifications moving off battlefield
|
||||
if (copied.isFortifying()) {
|
||||
final Card fortifiedLand = copied.getFortifying().get(0);
|
||||
final Card fortifiedLand = copied.getFortifying();
|
||||
if (fortifiedLand.isInPlay()) {
|
||||
copied.unFortifyCard(fortifiedLand);
|
||||
}
|
||||
@@ -1040,7 +1040,7 @@ public class GameAction {
|
||||
} // if isFortified()
|
||||
|
||||
if (c.isEquipping()) {
|
||||
final Card equippedCreature = c.getEquipping().get(0);
|
||||
final Card equippedCreature = c.getEquipping();
|
||||
if (!equippedCreature.isCreature() || !equippedCreature.isInPlay()
|
||||
|| !equippedCreature.canBeEquippedBy(c)
|
||||
|| (equippedCreature.isPhasedOut() && !c.isPhasedOut())
|
||||
@@ -1056,7 +1056,7 @@ public class GameAction {
|
||||
} // if isEquipping()
|
||||
|
||||
if (c.isFortifying()) {
|
||||
final Card fortifiedLand = c.getFortifying().get(0);
|
||||
final Card fortifiedLand = c.getFortifying();
|
||||
if (!fortifiedLand.isLand() || !fortifiedLand.isInPlay()
|
||||
|| (fortifiedLand.isPhasedOut() && !c.isPhasedOut())) {
|
||||
c.unFortifyCard(fortifiedLand);
|
||||
@@ -1071,11 +1071,6 @@ public class GameAction {
|
||||
return checkAgain;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param c
|
||||
* @return
|
||||
*/
|
||||
private boolean stateBasedAction704_5r(Card c) {
|
||||
boolean checkAgain = false;
|
||||
int plusOneCounters = c.getCounters(CounterType.P1P1);
|
||||
@@ -1334,7 +1329,7 @@ public class GameAction {
|
||||
}
|
||||
|
||||
if (c.canBeShielded() && (!c.isCreature() || c.getNetDefense() > 0)
|
||||
&& (!c.getShield().isEmpty() || c.hasKeyword("If CARDNAME would be destroyed, regenerate it."))) {
|
||||
&& (c.getShieldCount() > 0 || c.hasKeyword("If CARDNAME would be destroyed, regenerate it."))) {
|
||||
c.subtractShield(c.getController().getController().chooseRegenerationShield(c));
|
||||
c.setDamage(0);
|
||||
c.tap();
|
||||
@@ -1483,7 +1478,7 @@ public class GameAction {
|
||||
final Card persistCard = newCard;
|
||||
String effect = String.format("AB$ ChangeZone | Cost$ 0 | Defined$ CardUID_%d" +
|
||||
" | Origin$ Graveyard | Destination$ Battlefield | WithCounters$ M1M1_1",
|
||||
persistCard.getUniqueNumber());
|
||||
persistCard.getId());
|
||||
SpellAbility persistAb = AbilityFactory.getAbility(effect, c);
|
||||
persistAb.setTrigger(true);
|
||||
persistAb.setStackDescription(newCard.getName() + " - Returning from Persist");
|
||||
@@ -1497,7 +1492,7 @@ public class GameAction {
|
||||
final Card undyingCard = newCard;
|
||||
String effect = String.format("AB$ ChangeZone | Cost$ 0 | Defined$ CardUID_%d |" +
|
||||
" Origin$ Graveyard | Destination$ Battlefield | WithCounters$ P1P1_1",
|
||||
undyingCard.getUniqueNumber());
|
||||
undyingCard.getId());
|
||||
SpellAbility undyingAb = AbilityFactory.getAbility(effect, c);
|
||||
undyingAb.setTrigger(true);
|
||||
undyingAb.setStackDescription(newCard.getName() + " - Returning from Undying");
|
||||
|
||||
@@ -438,4 +438,5 @@ public abstract class GameEntity extends GameObject {
|
||||
}
|
||||
|
||||
public abstract Game getGame();
|
||||
public abstract GameEntityView<?> getView();
|
||||
}
|
||||
|
||||
22
forge-game/src/main/java/forge/game/GameEntityView.java
Normal file
22
forge-game/src/main/java/forge/game/GameEntityView.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package forge.game;
|
||||
|
||||
import forge.trackable.TrackableObject;
|
||||
|
||||
public abstract class GameEntityView<E extends Enum<E>> extends TrackableObject<E> {
|
||||
public static GameEntityView<?> get(GameEntity e) {
|
||||
return e == null ? null : e.getView();
|
||||
}
|
||||
|
||||
protected GameEntityView(int id0, Class<E> propEnum0) {
|
||||
super(id0, propEnum0);
|
||||
}
|
||||
|
||||
protected abstract E preventNextDamageProp();
|
||||
|
||||
public int getPreventNextDamage() {
|
||||
return get(preventNextDamageProp());
|
||||
}
|
||||
void updatePreventNextDamage(GameEntity e) {
|
||||
set(preventNextDamageProp(), e.getPreventNextDamageTotalShields());
|
||||
}
|
||||
}
|
||||
50
forge-game/src/main/java/forge/game/GameView.java
Normal file
50
forge-game/src/main/java/forge/game/GameView.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package forge.game;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.combat.AttackingBand;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.combat.CombatView;
|
||||
import forge.game.player.PlayerView;
|
||||
import forge.game.spellability.SpellAbilityView;
|
||||
import forge.game.spellability.StackItemView;
|
||||
import forge.trackable.TrackableIndex;
|
||||
|
||||
public class GameView {
|
||||
private final TrackableIndex<CardView> cards = new TrackableIndex<CardView>();
|
||||
private final TrackableIndex<PlayerView> players = new TrackableIndex<PlayerView>();
|
||||
private final TrackableIndex<SpellAbilityView> spellAbilities = new TrackableIndex<SpellAbilityView>();
|
||||
private final TrackableIndex<StackItemView> stackItems = new TrackableIndex<StackItemView>();
|
||||
private CombatView combatView;
|
||||
|
||||
public GameView() {
|
||||
|
||||
}
|
||||
|
||||
public CombatView getCombatView() {
|
||||
return combatView;
|
||||
}
|
||||
|
||||
public void refreshCombat(Game game) {
|
||||
final Combat combat = game.getCombat();
|
||||
if (combat == null) {
|
||||
combatView = null;
|
||||
return;
|
||||
}
|
||||
|
||||
combatView = new CombatView();
|
||||
for (final AttackingBand b : combat.getAttackingBands()) {
|
||||
if (b == null) continue;
|
||||
final GameEntity defender = combat.getDefenderByAttacker(b);
|
||||
final List<Card> blockers = combat.getBlockers(b);
|
||||
final boolean isBlocked = b.isBlocked() == Boolean.TRUE;
|
||||
combatView.addAttackingBand(
|
||||
CardView.getCollection(b.getAttackers()),
|
||||
GameEntityView.get(defender),
|
||||
isBlocked ? CardView.getCollection(blockers) : null,
|
||||
CardView.getCollection(blockers));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,7 +146,7 @@ public class StaticEffects implements IGameStateObject {
|
||||
if (params.containsKey("AddColor")) {
|
||||
final String colors = params.get("AddColor");
|
||||
if (colors.equals("ChosenColor")) {
|
||||
addColors = CardUtil.getShortColorsString(se.getSource().getChosenColor());
|
||||
addColors = CardUtil.getShortColorsString(se.getSource().getChosenColors());
|
||||
} else {
|
||||
addColors = CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(colors.split(" & "))));
|
||||
}
|
||||
@@ -155,7 +155,7 @@ public class StaticEffects implements IGameStateObject {
|
||||
if (params.containsKey("SetColor")) {
|
||||
final String colors = params.get("SetColor");
|
||||
if (colors.equals("ChosenColor")) {
|
||||
addColors = CardUtil.getShortColorsString(se.getSource().getChosenColor());
|
||||
addColors = CardUtil.getShortColorsString(se.getSource().getChosenColors());
|
||||
} else {
|
||||
addColors = CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(colors.split(" & "))));
|
||||
}
|
||||
|
||||
@@ -89,19 +89,16 @@ public class AbilityUtils {
|
||||
if (defined.equals("Self")) {
|
||||
c = hostCard;
|
||||
}
|
||||
|
||||
else if (defined.equals("OriginalHost")) {
|
||||
c = sa.getRootAbility().getOriginalHost();
|
||||
}
|
||||
|
||||
else if (defined.equals("EffectSource")) {
|
||||
if (hostCard.isType("Effect")) {
|
||||
c = AbilityUtils.findEffectRoot(hostCard);
|
||||
}
|
||||
}
|
||||
|
||||
else if (defined.equals("Equipped")) {
|
||||
c = hostCard.getEquippingCard();
|
||||
c = hostCard.getEquipping();
|
||||
}
|
||||
|
||||
else if (defined.equals("Enchanted")) {
|
||||
@@ -112,7 +109,6 @@ public class AbilityUtils {
|
||||
c = sa.getRootAbility().getPaidList("Sacrificed").get(0).getEnchantingCard();
|
||||
}
|
||||
}
|
||||
|
||||
else if (defined.endsWith("OfLibrary")) {
|
||||
final List<Card> lib = hostCard.getController().getCardsIn(ZoneType.Library);
|
||||
if (lib.size() > 0) { // TopOfLibrary or BottomOfLibrary
|
||||
@@ -121,22 +117,26 @@ public class AbilityUtils {
|
||||
// we don't want this to fall through and return the "Self"
|
||||
return cards;
|
||||
}
|
||||
} else if (defined.equals("Targeted")) {
|
||||
}
|
||||
else if (defined.equals("Targeted")) {
|
||||
final SpellAbility saTargeting = sa.getSATargetingCard();
|
||||
if (saTargeting != null) {
|
||||
Iterables.addAll(cards, saTargeting.getTargets().getTargetCards());
|
||||
}
|
||||
} else if (defined.equals("ThisTargetedCard")) { // do not add parent targeted
|
||||
}
|
||||
else if (defined.equals("ThisTargetedCard")) { // do not add parent targeted
|
||||
if (sa != null && sa.getTargets() != null) {
|
||||
Iterables.addAll(cards, sa.getTargets().getTargetCards());
|
||||
}
|
||||
} else if (defined.equals("ParentTarget")) {
|
||||
}
|
||||
else if (defined.equals("ParentTarget")) {
|
||||
final SpellAbility parent = sa.getParentTargetingCard();
|
||||
if (parent != null) {
|
||||
Iterables.addAll(cards, parent.getTargets().getTargetCards());
|
||||
}
|
||||
|
||||
} else if (defined.startsWith("Triggered") && (sa != null)) {
|
||||
}
|
||||
else if (defined.startsWith("Triggered") && (sa != null)) {
|
||||
final SpellAbility root = sa.getRootAbility();
|
||||
if (defined.contains("LKICopy")) { //TriggeredCardLKICopy
|
||||
final Object crd = root.getTriggeringObject(defined.substring(9, 13));
|
||||
@@ -154,7 +154,8 @@ public class AbilityUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (defined.startsWith("Replaced") && (sa != null)) {
|
||||
}
|
||||
else if (defined.startsWith("Replaced") && (sa != null)) {
|
||||
final SpellAbility root = sa.getRootAbility();
|
||||
final Object crd = root.getReplacingObject(defined.substring(8));
|
||||
if (crd instanceof Card) {
|
||||
@@ -164,7 +165,8 @@ public class AbilityUtils {
|
||||
cards.add(cardItem);
|
||||
}
|
||||
}
|
||||
} else if (defined.equals("Remembered")) {
|
||||
}
|
||||
else if (defined.equals("Remembered")) {
|
||||
if (hostCard.getRemembered().isEmpty()) {
|
||||
final Card newCard = game.getCardState(hostCard);
|
||||
for (final Object o : newCard.getRemembered()) {
|
||||
@@ -179,7 +181,8 @@ public class AbilityUtils {
|
||||
cards.add(game.getCardState((Card) o));
|
||||
}
|
||||
}
|
||||
} else if (defined.equals("DirectRemembered")) {
|
||||
}
|
||||
else if (defined.equals("DirectRemembered")) {
|
||||
if (hostCard.getRemembered().isEmpty()) {
|
||||
final Card newCard = game.getCardState(hostCard);
|
||||
for (final Object o : newCard.getRemembered()) {
|
||||
@@ -194,7 +197,8 @@ public class AbilityUtils {
|
||||
cards.add((Card) o);
|
||||
}
|
||||
}
|
||||
} else if (defined.equals("DelayTriggerRemembered")) {
|
||||
}
|
||||
else if (defined.equals("DelayTriggerRemembered")) {
|
||||
if (sa.getRootAbility().isTrigger()) {
|
||||
for (Object o : sa.getRootAbility().getTriggerRemembered()) {
|
||||
if (o instanceof Card) {
|
||||
@@ -202,20 +206,24 @@ public class AbilityUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (defined.equals("FirstRemembered")) {
|
||||
}
|
||||
else if (defined.equals("FirstRemembered")) {
|
||||
Object o = Iterables.getFirst(hostCard.getRemembered(), null);
|
||||
if (o != null && o instanceof Card) {
|
||||
cards.add(game.getCardState((Card) o));
|
||||
}
|
||||
} else if (defined.equals("Clones")) {
|
||||
}
|
||||
else if (defined.equals("Clones")) {
|
||||
for (final Card clone : hostCard.getClones()) {
|
||||
cards.add(game.getCardState(clone));
|
||||
}
|
||||
} else if (defined.equals("Imprinted")) {
|
||||
}
|
||||
else if (defined.equals("Imprinted")) {
|
||||
for (final Card imprint : hostCard.getImprinted()) {
|
||||
cards.add(game.getCardState(imprint));
|
||||
}
|
||||
} else if (defined.startsWith("ThisTurnEntered")) {
|
||||
}
|
||||
else if (defined.startsWith("ThisTurnEntered")) {
|
||||
final String[] workingCopy = defined.split("_");
|
||||
ZoneType destination, origin;
|
||||
String validFilter;
|
||||
@@ -231,7 +239,8 @@ public class AbilityUtils {
|
||||
for (final Card cl : CardUtil.getThisTurnEntered(destination, origin, validFilter, hostCard)) {
|
||||
cards.add(game.getCardState(cl));
|
||||
}
|
||||
} else if (defined.equals("ChosenCard")) {
|
||||
}
|
||||
else if (defined.equals("ChosenCard")) {
|
||||
for (final Card chosen : hostCard.getChosenCard()) {
|
||||
cards.add(game.getCardState(chosen));
|
||||
}
|
||||
@@ -239,11 +248,12 @@ public class AbilityUtils {
|
||||
else if (defined.startsWith("CardUID_")) {
|
||||
String idString = defined.substring(8);
|
||||
for (final Card cardByID : game.getCardsInGame()) {
|
||||
if (cardByID.getUniqueNumber() == Integer.valueOf(idString)) {
|
||||
if (cardByID.getId() == Integer.valueOf(idString)) {
|
||||
cards.add(game.getCardState(cardByID));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
List<Card> list = null;
|
||||
if (defined.startsWith("SacrificedCards")) {
|
||||
list = sa.getRootAbility().getPaidList("SacrificedCards");
|
||||
@@ -251,50 +261,42 @@ public class AbilityUtils {
|
||||
else if (defined.startsWith("Sacrificed")) {
|
||||
list = sa.getRootAbility().getPaidList("Sacrificed");
|
||||
}
|
||||
|
||||
else if (defined.startsWith("DiscardedCards")) {
|
||||
list = sa.getRootAbility().getPaidList("DiscardedCards");
|
||||
}
|
||||
else if (defined.startsWith("Discarded")) {
|
||||
list = sa.getRootAbility().getPaidList("Discarded");
|
||||
}
|
||||
|
||||
else if (defined.startsWith("ExiledCards")) {
|
||||
list = sa.getRootAbility().getPaidList("ExiledCards");
|
||||
}
|
||||
else if (defined.startsWith("Exiled")) {
|
||||
list = sa.getRootAbility().getPaidList("Exiled");
|
||||
}
|
||||
|
||||
else if (defined.startsWith("TappedCards")) {
|
||||
list = sa.getRootAbility().getPaidList("TappedCards");
|
||||
}
|
||||
else if (defined.startsWith("Tapped")) {
|
||||
list = sa.getRootAbility().getPaidList("Tapped");
|
||||
}
|
||||
|
||||
else if (defined.startsWith("UntappedCards")) {
|
||||
list = sa.getRootAbility().getPaidList("UntappedCards");
|
||||
}
|
||||
else if (defined.startsWith("Untapped")) {
|
||||
list = sa.getRootAbility().getPaidList("Untapped");
|
||||
}
|
||||
|
||||
else if (defined.startsWith("Valid ")) {
|
||||
String validDefined = defined.substring("Valid ".length());
|
||||
list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), validDefined.split(","), hostCard.getController(), hostCard);
|
||||
}
|
||||
|
||||
else if (defined.startsWith("ValidHand ")) {
|
||||
String validDefined = defined.substring("ValidHand ".length());
|
||||
list = CardLists.getValidCards(game.getCardsIn(ZoneType.Hand), validDefined.split(","), hostCard.getController(), hostCard);
|
||||
}
|
||||
|
||||
else if (defined.startsWith("ValidAll ")) {
|
||||
String validDefined = defined.substring("ValidAll ".length());
|
||||
list = CardLists.getValidCards(game.getCardsInGame(), validDefined.split(","), hostCard.getController(), hostCard);
|
||||
}
|
||||
|
||||
else {
|
||||
return cards;
|
||||
}
|
||||
@@ -307,7 +309,6 @@ public class AbilityUtils {
|
||||
if (c != null) {
|
||||
cards.add(c);
|
||||
}
|
||||
|
||||
return cards;
|
||||
}
|
||||
|
||||
@@ -1151,7 +1152,7 @@ public class AbilityUtils {
|
||||
for (SpellAbility targetSpell : saTargeting.getTargets().getTargetSpells()) {
|
||||
SpellAbilityStackInstance stackInstance = game.getStack().getInstanceFromSpellAbility(targetSpell);
|
||||
if (stackInstance != null) {
|
||||
SpellAbility instanceSA = stackInstance.getSpellAbility();
|
||||
SpellAbility instanceSA = stackInstance.getSpellAbility(true);
|
||||
if (instanceSA != null) {
|
||||
sas.add(instanceSA);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
||||
if (sa.hasParam("Colors")) {
|
||||
final String colors = sa.getParam("Colors");
|
||||
if (colors.equals("ChosenColor")) {
|
||||
tmpDesc = CardUtil.getShortColorsString(host.getChosenColor());
|
||||
tmpDesc = CardUtil.getShortColorsString(host.getChosenColors());
|
||||
} else {
|
||||
tmpDesc = CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(colors.split(","))));
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ public class AnimateEffect extends AnimateEffectBase {
|
||||
final String colors = sa.getParam("Colors");
|
||||
if (colors.equals("ChosenColor")) {
|
||||
|
||||
tmpDesc = CardUtil.getShortColorsString(source.getChosenColor());
|
||||
tmpDesc = CardUtil.getShortColorsString(source.getChosenColors());
|
||||
} else {
|
||||
tmpDesc = CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(colors.split(","))));
|
||||
}
|
||||
|
||||
@@ -50,21 +50,21 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
|
||||
// Redirect rules read 'you MAY choose new targets' ... okay!
|
||||
// TODO: Don't even ask to change targets, if the SA and subs don't actually have targets
|
||||
boolean isOptional = sa.hasParam("Optional");
|
||||
if( isOptional && !chooser.getController().confirmAction(sa, null, "Do you want to change targets of " + tgtSA.getHostCard() + "?"))
|
||||
if (isOptional && !chooser.getController().confirmAction(sa, null, "Do you want to change targets of " + tgtSA.getHostCard() + "?")) {
|
||||
continue;
|
||||
|
||||
if( changesOneTarget ) {
|
||||
}
|
||||
if (changesOneTarget) {
|
||||
// 1. choose a target of target spell
|
||||
List<Pair<SpellAbilityStackInstance, GameObject>> allTargets = new ArrayList<>();
|
||||
while(changingTgtSI != null) {
|
||||
SpellAbility changedSa = changingTgtSI.getSpellAbility();
|
||||
if(changedSa.usesTargeting()) {
|
||||
SpellAbility changedSa = changingTgtSI.getSpellAbility(true);
|
||||
if (changedSa.usesTargeting()) {
|
||||
for(GameObject it : changedSa.getTargets().getTargets())
|
||||
allTargets.add(ImmutablePair.of(changingTgtSI, it));
|
||||
}
|
||||
changingTgtSI = changingTgtSI.getSubInstance();
|
||||
}
|
||||
if( allTargets.isEmpty() ) {
|
||||
if (allTargets.isEmpty()) {
|
||||
// is it an error or not?
|
||||
System.err.println("Player managed to target a spell without targets with Spellskite's ability.");
|
||||
return;
|
||||
@@ -80,28 +80,33 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
|
||||
replaceIn.updateTarget(newTargetBlock);
|
||||
// 3. test if updated choices would be correct.
|
||||
GameObject newTarget = Iterables.getFirst(getDefinedCardsOrTargeted(sa), null);
|
||||
if(replaceIn.getSpellAbility().canTarget(newTarget)) {
|
||||
if (replaceIn.getSpellAbility(true).canTarget(newTarget)) {
|
||||
newTargetBlock.add(newTarget);
|
||||
replaceIn.updateTarget(newTargetBlock);
|
||||
} else
|
||||
}
|
||||
else {
|
||||
replaceIn.updateTarget(oldTargetBlock);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(changingTgtSI != null) {
|
||||
SpellAbility changingTgtSA = changingTgtSI.getSpellAbility();
|
||||
SpellAbility changingTgtSA = changingTgtSI.getSpellAbility(true);
|
||||
if (sa.hasParam("RandomTarget")){
|
||||
changingTgtSA.resetTargets();
|
||||
List<GameEntity> candidates = changingTgtSA.getTargetRestrictions().getAllCandidates(changingTgtSA, true);
|
||||
GameEntity choice = Aggregates.random(candidates);
|
||||
changingTgtSA.getTargets().add(choice);
|
||||
changingTgtSI.updateTarget(changingTgtSA.getTargets());
|
||||
} else if (sa.hasParam("DefinedMagnet")){
|
||||
}
|
||||
else if (sa.hasParam("DefinedMagnet")){
|
||||
GameObject newTarget = Iterables.getFirst(getDefinedCardsOrTargeted(sa, "DefinedMagnet"), null);
|
||||
if(changingTgtSA.canTarget(newTarget)) {
|
||||
if (changingTgtSA.canTarget(newTarget)) {
|
||||
changingTgtSA.resetTargets();
|
||||
changingTgtSA.getTargets().add(newTarget);
|
||||
changingTgtSI.updateTarget(changingTgtSA.getTargets());
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Update targets, with a potential new target
|
||||
TargetChoices newTarget = sa.getActivatingPlayer().getController().chooseNewTargetsFor(changingTgtSA);
|
||||
if (null != newTarget) {
|
||||
|
||||
@@ -471,14 +471,14 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
tgtC.enchantEntity(attachedTo);
|
||||
} else if (tgtC.isEquipment()) { //Equipment
|
||||
if (tgtC.isEquipping()) {
|
||||
final Card oldEquiped = tgtC.getEquippingCard();
|
||||
final Card oldEquiped = tgtC.getEquipping();
|
||||
if ( null != oldEquiped )
|
||||
tgtC.unEquipCard(oldEquiped);
|
||||
}
|
||||
tgtC.equipCard(attachedTo);
|
||||
} else { // fortification
|
||||
if (tgtC.isFortifying()) {
|
||||
final Card oldFortified = tgtC.getFortifyingCard();
|
||||
final Card oldFortified = tgtC.getFortifying();
|
||||
if( oldFortified != null )
|
||||
tgtC.unFortifyCard(oldFortified);
|
||||
}
|
||||
@@ -856,7 +856,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
}
|
||||
else if (c.isEquipment()) { //Equipment
|
||||
if (c.isEquipping()) {
|
||||
final Card oldEquiped = c.getEquippingCard();
|
||||
final Card oldEquiped = c.getEquipping();
|
||||
if ( null != oldEquiped )
|
||||
c.unEquipCard(oldEquiped);
|
||||
}
|
||||
@@ -864,7 +864,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
}
|
||||
else {
|
||||
if (c.isFortifying()) {
|
||||
final Card oldFortified = c.getFortifyingCard();
|
||||
final Card oldFortified = c.getFortifying();
|
||||
if ( null != oldFortified )
|
||||
c.unFortifyCard(oldFortified);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class ChooseColorEffect extends SpellAbilityEffect {
|
||||
if (chosenColors.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
card.setChosenColor(chosenColors);
|
||||
card.setChosenColors(chosenColors);
|
||||
p.getGame().getAction().nofityOfValue(sa, card, p.getName() + " picked " + Lang.joinHomogenous(chosenColors), p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,8 +61,9 @@ public class ChooseSourceEffect extends SpellAbilityEffect {
|
||||
stackSources.add(stackinst.getSourceCard());
|
||||
}
|
||||
// Get the list of cards that are referenced by effects on the stack
|
||||
if (null != stackinst.getSpellAbility().getTriggeringObjects()) {
|
||||
for (Object c : stackinst.getSpellAbility().getTriggeringObjects().values()) {
|
||||
SpellAbility siSpellAbility = stackinst.getSpellAbility(true);
|
||||
if (siSpellAbility.getTriggeringObjects() != null) {
|
||||
for (Object c : siSpellAbility.getTriggeringObjects().values()) {
|
||||
if (c instanceof Card) {
|
||||
if (!stackSources.contains((Card) c)) {
|
||||
referencedSources.add((Card) c);
|
||||
@@ -70,12 +71,12 @@ public class ChooseSourceEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (null != stackinst.getSpellAbility().getTargetCard()) {
|
||||
referencedSources.add(stackinst.getSpellAbility().getTargetCard());
|
||||
if (siSpellAbility.getTargetCard() != null) {
|
||||
referencedSources.add(siSpellAbility.getTargetCard());
|
||||
}
|
||||
// TODO: is this necessary?
|
||||
if (null != stackinst.getSpellAbility().getReplacingObjects()) {
|
||||
for (Object c : stackinst.getSpellAbility().getReplacingObjects().values()) {
|
||||
if (siSpellAbility.getReplacingObjects() != null) {
|
||||
for (Object c : siSpellAbility.getReplacingObjects().values()) {
|
||||
if (c instanceof Card) {
|
||||
if (!stackSources.contains((Card) c)) {
|
||||
referencedSources.add((Card) c);
|
||||
@@ -85,7 +86,6 @@ public class ChooseSourceEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (sa.hasParam("Choices")) {
|
||||
permanentSources = CardLists.getValidCards(permanentSources, sa.getParam("Choices"), host.getController(), host);
|
||||
|
||||
|
||||
@@ -106,12 +106,12 @@ public class CloneEffect extends SpellAbilityEffect {
|
||||
tgtCard.clearStates(CardCharacteristicName.Cloner);
|
||||
}
|
||||
// add "Cloner" state to clone
|
||||
tgtCard.addAlternateState(CardCharacteristicName.Cloner);
|
||||
tgtCard.addAlternateState(CardCharacteristicName.Cloner, false);
|
||||
tgtCard.switchStates(CardCharacteristicName.Original, CardCharacteristicName.Cloner);
|
||||
tgtCard.setState(CardCharacteristicName.Original);
|
||||
} else {
|
||||
//copy Original state to Cloned
|
||||
tgtCard.addAlternateState(CardCharacteristicName.Cloned);
|
||||
tgtCard.addAlternateState(CardCharacteristicName.Cloned, false);
|
||||
tgtCard.switchStates(CardCharacteristicName.Original, CardCharacteristicName.Cloned);
|
||||
if (tgtCard.isFlipCard()) {
|
||||
tgtCard.setState(CardCharacteristicName.Original);
|
||||
@@ -285,7 +285,7 @@ public class CloneEffect extends SpellAbilityEffect {
|
||||
if (sa.hasParam("Colors")) {
|
||||
final String colors = sa.getParam("Colors");
|
||||
if (colors.equals("ChosenColor")) {
|
||||
shortColors = CardUtil.getShortColorsString(tgtCard.getChosenColor());
|
||||
shortColors = CardUtil.getShortColorsString(tgtCard.getChosenColors());
|
||||
} else {
|
||||
shortColors = CardUtil.getShortColorsString(Arrays.asList(colors.split(",")));
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class ControlGainEffect extends SpellAbilityEffect {
|
||||
for (final Card c : getDefinedCards(sa)) {
|
||||
sb.append(" ");
|
||||
if (c.isFaceDown()) {
|
||||
sb.append("Face-down creature (").append(c.getUniqueNumber()).append(')');
|
||||
sb.append("Face-down creature (").append(c.getId()).append(')');
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class CounterEffect extends SpellAbilityEffect {
|
||||
if (sa.hasParam("AllType")) {
|
||||
sas = new ArrayList<SpellAbility>();
|
||||
for (SpellAbilityStackInstance si : game.getStack()) {
|
||||
SpellAbility spell = si.getSpellAbility();
|
||||
SpellAbility spell = si.getSpellAbility(true);
|
||||
if (sa.getParam("AllType").equals("Spell") && !spell.isSpell()) {
|
||||
continue;
|
||||
}
|
||||
@@ -71,7 +71,7 @@ public class CounterEffect extends SpellAbilityEffect {
|
||||
if (sa.hasParam("AllType")) {
|
||||
sas = new ArrayList<SpellAbility>();
|
||||
for (SpellAbilityStackInstance si : game.getStack()) {
|
||||
SpellAbility spell = si.getSpellAbility();
|
||||
SpellAbility spell = si.getSpellAbility(true);
|
||||
if (sa.getParam("AllType").equals("Spell") && !spell.isSpell()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ public class DamagePreventEffect extends SpellAbilityEffect {
|
||||
effTgts = AbilityUtils.getDefinedObjects(host, sa.getParam("ShieldEffectTarget"), sa);
|
||||
for (final Object effTgt : effTgts) {
|
||||
if (effTgt instanceof Card) {
|
||||
effTgtString = String.valueOf(((Card) effTgt).getUniqueNumber());
|
||||
effTgtString = String.valueOf(((Card) effTgt).getId());
|
||||
effectMap.put("ShieldEffectTarget", "CardUID_" + effTgtString);
|
||||
} else if (effTgt instanceof Player) {
|
||||
effTgtString = ((Player) effTgt).getName();
|
||||
@@ -131,7 +131,7 @@ public class DamagePreventEffect extends SpellAbilityEffect {
|
||||
effTgts = AbilityUtils.getDefinedObjects(host, sa.getParam("ShieldEffectTarget"), sa);
|
||||
for (final Object effTgt : effTgts) {
|
||||
if (effTgt instanceof Card) {
|
||||
effTgtString = String.valueOf(((Card) effTgt).getUniqueNumber());
|
||||
effTgtString = String.valueOf(((Card) effTgt).getId());
|
||||
effectMap.put("ShieldEffectTarget", "CardUID_" + effTgtString);
|
||||
} else if (effTgt instanceof Player) {
|
||||
effTgtString = ((Player) effTgt).getName();
|
||||
|
||||
@@ -32,7 +32,7 @@ public class DestroyEffect extends SpellAbilityEffect {
|
||||
while (it.hasNext()) {
|
||||
final Card tgtC = it.next();
|
||||
if (tgtC.isFaceDown()) {
|
||||
sb.append("Morph ").append("(").append(tgtC.getUniqueNumber()).append(")");
|
||||
sb.append("Morph ").append("(").append(tgtC.getId()).append(")");
|
||||
} else {
|
||||
sb.append(tgtC);
|
||||
}
|
||||
|
||||
@@ -189,8 +189,8 @@ public class EffectEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
// Set Chosen Color(s)
|
||||
if (!hostCard.getChosenColor().isEmpty()) {
|
||||
eff.setChosenColor(hostCard.getChosenColor());
|
||||
if (!hostCard.getChosenColors().isEmpty()) {
|
||||
eff.setChosenColors(hostCard.getChosenColors());
|
||||
}
|
||||
|
||||
// Set Chosen name
|
||||
|
||||
@@ -75,7 +75,7 @@ public class PlayLandVariantEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
String imageFileName = game.getRules().canCloneUseTargetsImage ? source.getImageKey() : random.getImageKey();
|
||||
source.addAlternateState(CardCharacteristicName.Cloner);
|
||||
source.addAlternateState(CardCharacteristicName.Cloner, false);
|
||||
source.switchStates(CardCharacteristicName.Original, CardCharacteristicName.Cloner);
|
||||
source.setState(CardCharacteristicName.Original);
|
||||
CardCharacteristicName stateToCopy = random.getCurState();
|
||||
|
||||
@@ -56,7 +56,7 @@ public class ProtectAllEffect extends SpellAbilityEffect {
|
||||
game.getAction().nofityOfValue(sa, choser, Lang.joinHomogenous(gains), choser);
|
||||
} else {
|
||||
if (sa.getParam("Gains").equals("ChosenColor")) {
|
||||
for (final String color : host.getChosenColor()) {
|
||||
for (final String color : host.getChosenColors()) {
|
||||
gains.add(color.toLowerCase());
|
||||
}
|
||||
} else if (sa.getParam("Gains").equals("TargetedCardColor")) {
|
||||
|
||||
@@ -114,7 +114,7 @@ public class ProtectEffect extends SpellAbilityEffect {
|
||||
game.getAction().nofityOfValue(sa, choser, Lang.joinHomogenous(gains), choser);
|
||||
} else {
|
||||
if (sa.getParam("Gains").equals("ChosenColor")) {
|
||||
for (final String color : host.getChosenColor()) {
|
||||
for (final String color : host.getChosenColors()) {
|
||||
gains.add(color.toLowerCase());
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -209,7 +209,7 @@ public class PumpEffect extends SpellAbilityEffect {
|
||||
if (defined.equals("ChosenType")) {
|
||||
replaced = host.getChosenType();
|
||||
} else if (defined.equals("CardUIDSource")) {
|
||||
replaced = "CardUID_" + String.valueOf(host.getUniqueNumber());
|
||||
replaced = "CardUID_" + String.valueOf(host.getId());
|
||||
}
|
||||
for (int i = 0; i < keywords.size(); i++) {
|
||||
keywords.set(i, keywords.get(i).replaceAll(defined, replaced));
|
||||
|
||||
@@ -73,7 +73,7 @@ public class RegenerateEffect extends SpellAbilityEffect {
|
||||
} else if (sa.hasParam("ReplaceCardUID")) { // Debt of Loyalty
|
||||
String def = sa.getParam("ReplaceCardUID");
|
||||
List<Card> replaced = AbilityUtils.getDefinedCards(sourceCard, def, sa);
|
||||
abString = abString.replace(def, replaced.isEmpty() ? "" : Integer.toString(replaced.get(0).getUniqueNumber()));
|
||||
abString = abString.replace(def, replaced.isEmpty() ? "" : Integer.toString(replaced.get(0).getId()));
|
||||
}
|
||||
triggerSA = AbilityFactory.getAbility(abString, sourceCard);
|
||||
triggerSA.setActivatingPlayer(sa.getActivatingPlayer());
|
||||
|
||||
@@ -28,7 +28,7 @@ public class SetStateEffect extends SpellAbilityEffect {
|
||||
while (it.hasNext()) {
|
||||
final Card tgtC = it.next();
|
||||
if (tgtC.isFaceDown()) {
|
||||
sb.append("Morph ").append("(").append(tgtC.getUniqueNumber()).append(")");
|
||||
sb.append("Morph ").append("(").append(tgtC.getId()).append(")");
|
||||
} else {
|
||||
sb.append(tgtC);
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ public class TokenEffect extends SpellAbilityEffect {
|
||||
for (int i = 0; i < substitutedColors.length; i++) {
|
||||
if (substitutedColors[i].equals("ChosenColor")) {
|
||||
// this currently only supports 1 chosen color
|
||||
substitutedColors[i] = host.getChosenColor().get(0);
|
||||
substitutedColors[i] = host.getChosenColors().get(0);
|
||||
}
|
||||
}
|
||||
String colorDesc = "";
|
||||
|
||||
@@ -24,11 +24,11 @@ public class UnattachAllEffect extends SpellAbilityEffect {
|
||||
//AbilityFactoryAttach.handleUnattachAura(cardToUnattach, c, gainControl);
|
||||
} else if (cardToUnattach.isEquipment()) {
|
||||
if (cardToUnattach.isEquipping() && c.getEquippedBy().contains(cardToUnattach)) {
|
||||
cardToUnattach.unEquipCard(cardToUnattach.getEquipping().get(0));
|
||||
cardToUnattach.unEquipCard(cardToUnattach.getEquipping());
|
||||
}
|
||||
} else if (cardToUnattach.isFortification()) {
|
||||
if (cardToUnattach.isFortifying() && c.getFortifiedBy().contains(cardToUnattach)) {
|
||||
cardToUnattach.unFortifyCard(cardToUnattach.getFortifying().get(0));
|
||||
cardToUnattach.unFortifyCard(cardToUnattach.getFortifying());
|
||||
}
|
||||
}
|
||||
} else if (o instanceof Player) {
|
||||
|
||||
@@ -33,11 +33,11 @@ public class UnattachEffect extends SpellAbilityEffect {
|
||||
//AbilityFactoryAttach.handleUnattachAura(cardToUnattach, c, gainControl);
|
||||
} else if (cardToUnattach.isEquipment()) {
|
||||
if (cardToUnattach.isEquipping()) {
|
||||
cardToUnattach.unEquipCard(cardToUnattach.getEquipping().get(0));
|
||||
cardToUnattach.unEquipCard(cardToUnattach.getEquipping());
|
||||
}
|
||||
} else if (cardToUnattach.isFortification()) {
|
||||
if (cardToUnattach.isFortifying()) {
|
||||
cardToUnattach.unFortifyCard(cardToUnattach.getFortifying().get(0));
|
||||
cardToUnattach.unFortifyCard(cardToUnattach.getFortifying());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,8 +31,10 @@ import forge.game.trigger.Trigger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
@@ -40,7 +42,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||
*/
|
||||
public class CardCharacteristics {
|
||||
private String name = "";
|
||||
private List<String> type = new CopyOnWriteArrayList<String>();
|
||||
private Set<String> type = new CopyOnWriteArraySet<String>();
|
||||
private ManaCost manaCost = ManaCost.NO_COST;
|
||||
private List<CardColor> cardColor = new ArrayList<CardColor>();
|
||||
private String oracleText = "";
|
||||
@@ -84,7 +86,7 @@ public class CardCharacteristics {
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public final List<String> getType() {
|
||||
public final Set<String> getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
@@ -438,7 +440,7 @@ public class CardCharacteristics {
|
||||
// String name : just copy reference
|
||||
this.name = source.getName();
|
||||
// ArrayList<String> type : list of String objects so use copy constructor
|
||||
this.type = new CopyOnWriteArrayList<String>(source.getType());
|
||||
this.type = new CopyOnWriteArraySet<String>(source.getType());
|
||||
// CardManaCost manaCost : not sure if a deep copy is needed
|
||||
this.manaCost = source.getManaCost();
|
||||
// ArrayList<CardColor> cardColor : not sure if a deep copy is needed
|
||||
|
||||
@@ -75,9 +75,9 @@ public class CardFactory {
|
||||
Card out;
|
||||
if (!(in.isToken() || in.getCopiedPermanent() != null)) {
|
||||
out = assignNewId ? getCard(in.getPaperCard(), in.getOwner())
|
||||
: getCard(in.getPaperCard(), in.getOwner(), in.getUniqueNumber());
|
||||
: getCard(in.getPaperCard(), in.getOwner(), in.getId());
|
||||
} else { // token
|
||||
out = assignNewId ? new Card(in.getGame().nextCardId(), in.getPaperCard()) : new Card(in.getUniqueNumber(), in.getPaperCard());
|
||||
out = assignNewId ? new Card(in.getGame().nextCardId(), in.getPaperCard()) : new Card(in.getId(), in.getPaperCard());
|
||||
out = CardFactory.copyStats(in, in.getController());
|
||||
out.setToken(true);
|
||||
|
||||
@@ -148,7 +148,7 @@ public class CardFactory {
|
||||
String tmp = "";
|
||||
final String newColor = sourceSA.getParam("CopyIsColor");
|
||||
if (newColor.equals("ChosenColor")) {
|
||||
tmp = CardUtil.getShortColorsString(source.getChosenColor());
|
||||
tmp = CardUtil.getShortColorsString(source.getChosenColors());
|
||||
} else {
|
||||
tmp = CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(newColor.split(","))));
|
||||
}
|
||||
@@ -356,20 +356,19 @@ public class CardFactory {
|
||||
}
|
||||
|
||||
private static Card readCard(final CardRules rules, final IPaperCard paperCard, int cardId) {
|
||||
|
||||
final Card card = new Card(cardId, paperCard);
|
||||
|
||||
// 1. The states we may have:
|
||||
CardSplitType st = rules.getSplitType();
|
||||
if ( st == CardSplitType.Split) {
|
||||
card.addAlternateState(CardCharacteristicName.LeftSplit);
|
||||
if (st == CardSplitType.Split) {
|
||||
card.addAlternateState(CardCharacteristicName.LeftSplit, false);
|
||||
card.setState(CardCharacteristicName.LeftSplit);
|
||||
}
|
||||
|
||||
readCardFace(card, rules.getMainPart());
|
||||
|
||||
if ( st != CardSplitType.None) {
|
||||
card.addAlternateState(st.getChangedStateName());
|
||||
if (st != CardSplitType.None) {
|
||||
card.addAlternateState(st.getChangedStateName(), false);
|
||||
card.setState(st.getChangedStateName());
|
||||
readCardFace(card, rules.getOtherPart());
|
||||
}
|
||||
@@ -570,7 +569,7 @@ public class CardFactory {
|
||||
|
||||
// get CardCharacteristics for desired state
|
||||
if (!to.getStates().contains(toState)) {
|
||||
to.addAlternateState(toState);
|
||||
to.addAlternateState(toState, true);
|
||||
}
|
||||
final CardCharacteristics toCharacteristics = to.getState(toState),
|
||||
fromCharacteristics = from.getState(fromState);
|
||||
@@ -590,7 +589,7 @@ public class CardFactory {
|
||||
final CardCharacteristics fromCharacteristics = from.getState(fromState);
|
||||
final CardCharacteristicName oldToState = to.getCurState();
|
||||
if (!to.getStates().contains(toState)) {
|
||||
to.addAlternateState(toState);
|
||||
to.addAlternateState(toState, false);
|
||||
}
|
||||
|
||||
to.setState(toState);
|
||||
@@ -688,7 +687,7 @@ public class CardFactory {
|
||||
t.setTriggeringObjects(trig);
|
||||
trig.setTriggerRemembered(t.getTriggerRemembered());
|
||||
if (t.getStoredTriggeredObjects() != null) {
|
||||
trig.setAllTriggeringObjects(t.getStoredTriggeredObjects());
|
||||
trig.setTriggeringObjects(t.getStoredTriggeredObjects());
|
||||
}
|
||||
|
||||
trig.setActivatingPlayer(sa.getActivatingPlayer());
|
||||
|
||||
@@ -1159,7 +1159,7 @@ public class CardFactoryUtil {
|
||||
ZoneType sourceZone = sq[0].contains("ChromaInGrave") ? ZoneType.Graveyard : ZoneType.Battlefield;
|
||||
String colorName = sq[1];
|
||||
if (colorName.contains("Chosen")) {
|
||||
colorName = MagicColor.toShortString(c.getChosenColor().get(0));
|
||||
colorName = MagicColor.toShortString(c.getChosenColors().get(0));
|
||||
}
|
||||
final List<Card> cards;
|
||||
if (sq[0].contains("ChromaSource")) { // Runs Chroma for passed in Source card
|
||||
@@ -1250,7 +1250,7 @@ public class CardFactoryUtil {
|
||||
if (sq[0].contains("CardManaCost")) {
|
||||
Card ce;
|
||||
if (sq[0].contains("Equipped") && c.isEquipping()) {
|
||||
ce = c.getEquipping().get(0);
|
||||
ce = c.getEquipping();
|
||||
}
|
||||
else if (sq[0].contains("Remembered")) {
|
||||
ce = (Card) c.getRemembered().get(0);
|
||||
@@ -2027,7 +2027,7 @@ public class CardFactoryUtil {
|
||||
final int magnitude = Integer.parseInt(s);
|
||||
|
||||
String description = String.format("Bushido %d (When this blocks or becomes blocked, it gets +%d/+%d until end of turn).", magnitude, magnitude, magnitude);
|
||||
String regularPart = String.format("AB$ Pump | Cost$ 0 | Defined$ CardUID_%d | NumAtt$ +%d | NumDef$ +%d | StackDescription$ %s", c.getUniqueNumber(), magnitude, magnitude, description);
|
||||
String regularPart = String.format("AB$ Pump | Cost$ 0 | Defined$ CardUID_%d | NumAtt$ +%d | NumDef$ +%d | StackDescription$ %s", c.getId(), magnitude, magnitude, description);
|
||||
|
||||
SpellAbility ability = AbilityFactory.getAbility(regularPart, c);
|
||||
ability.setDescription(ability.getStackDescription());
|
||||
|
||||
@@ -213,14 +213,13 @@ public final class CardUtil {
|
||||
* @return a copy of C with LastKnownInfo stuff retained.
|
||||
*/
|
||||
public static Card getLKICopy(final Card in) {
|
||||
|
||||
final Card newCopy = new Card(in.getUniqueNumber(), in.getPaperCard());
|
||||
final Card newCopy = new Card(in.getId(), in.getPaperCard());
|
||||
newCopy.setCurSetCode(in.getCurSetCode());
|
||||
newCopy.setOwner(in.getOwner());
|
||||
newCopy.setController(in.getController(), 0);
|
||||
newCopy.getCharacteristics().copyFrom(in.getState(in.getCurState()));
|
||||
if (in.isCloned()) {
|
||||
newCopy.addAlternateState(CardCharacteristicName.Cloner);
|
||||
newCopy.addAlternateState(CardCharacteristicName.Cloner, false);
|
||||
}
|
||||
newCopy.setType(new ArrayList<String>(in.getType()));
|
||||
newCopy.setToken(in.isToken());
|
||||
@@ -245,9 +244,9 @@ public final class CardUtil {
|
||||
newCopy.getDamageHistory().setCreatureGotBlockedThisTurn(in.getDamageHistory().getCreatureGotBlockedThisTurn());
|
||||
newCopy.setEnchanting(in.getEnchanting());
|
||||
newCopy.setEnchantedBy(new ArrayList<Card> (in.getEnchantedBy()));
|
||||
newCopy.setEquipping(new ArrayList<Card> (in.getEquipping()));
|
||||
newCopy.setEquipping(in.getEquipping());
|
||||
newCopy.setEquippedBy(new ArrayList<Card> (in.getEquippedBy()));
|
||||
newCopy.setFortifying(new ArrayList<Card> (in.getFortifying()));
|
||||
newCopy.setFortifying(in.getFortifying());
|
||||
newCopy.setFortifiedBy(new ArrayList<Card> (in.getFortifiedBy()));
|
||||
newCopy.setClones(in.getClones());
|
||||
newCopy.setHaunting(in.getHaunting());
|
||||
|
||||
625
forge-game/src/main/java/forge/game/card/CardView.java
Normal file
625
forge-game/src/main/java/forge/game/card/CardView.java
Normal file
@@ -0,0 +1,625 @@
|
||||
package forge.game.card;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.card.CardCharacteristicName;
|
||||
import forge.card.CardRarity;
|
||||
import forge.card.CardType;
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.game.GameEntityView;
|
||||
import forge.game.player.PlayerView;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.trackable.TrackableCollection;
|
||||
import forge.trackable.TrackableObject;
|
||||
import forge.trackable.TrackableProperty.CardProp;
|
||||
import forge.trackable.TrackableProperty.CardStateProp;
|
||||
|
||||
|
||||
public class CardView extends GameEntityView<CardProp> {
|
||||
public static CardView get(Card c) {
|
||||
return c == null ? null : c.getView();
|
||||
}
|
||||
|
||||
public static TrackableCollection<CardView> getCollection(Iterable<Card> cards) {
|
||||
if (cards == null) {
|
||||
return null;
|
||||
}
|
||||
TrackableCollection<CardView> collection = new TrackableCollection<CardView>();
|
||||
for (Card c : cards) {
|
||||
collection.add(c.getView());
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
public CardView(int id0) {
|
||||
super(id0, CardProp.class);
|
||||
set(CardProp.Original, new CardStateView(id0));
|
||||
}
|
||||
|
||||
public PlayerView getOwner() {
|
||||
return get(CardProp.Owner);
|
||||
}
|
||||
void updateOwner(Card c) {
|
||||
set(CardProp.Owner, PlayerView.get(c.getOwner()));
|
||||
}
|
||||
|
||||
public PlayerView getController() {
|
||||
return get(CardProp.Controller);
|
||||
}
|
||||
void updateController(Card c) {
|
||||
set(CardProp.Owner, PlayerView.get(c.getController()));
|
||||
}
|
||||
|
||||
public ZoneType getZone() {
|
||||
return get(CardProp.Zone);
|
||||
}
|
||||
void updateZone(Card c) {
|
||||
set(CardProp.Zone, c.getZone() == null ? null : c.getZone().getZoneType());
|
||||
}
|
||||
|
||||
public boolean isCloned() {
|
||||
return get(CardProp.Cloned);
|
||||
}
|
||||
|
||||
public boolean isFaceDown() {
|
||||
return get(CardProp.FaceDown);
|
||||
}
|
||||
|
||||
public boolean isFlipCard() {
|
||||
return get(CardProp.FlipCard);
|
||||
}
|
||||
|
||||
public boolean isFlipped() {
|
||||
return get(CardProp.Flipped);
|
||||
}
|
||||
|
||||
public boolean isSplitCard() {
|
||||
return get(CardProp.SplitCard);
|
||||
}
|
||||
|
||||
public boolean isTransformed() {
|
||||
return get(CardProp.Transformed);
|
||||
}
|
||||
|
||||
public String getSetCode() {
|
||||
return get(CardProp.SetCode);
|
||||
}
|
||||
void updateSetCode(Card c) {
|
||||
set(CardProp.SetCode, c.getCurSetCode());
|
||||
}
|
||||
|
||||
public CardRarity getRarity() {
|
||||
return get(CardProp.Rarity);
|
||||
}
|
||||
void updateRarity(Card c) {
|
||||
set(CardProp.Rarity, c.getRarity());
|
||||
}
|
||||
|
||||
public boolean isAttacking() {
|
||||
return get(CardProp.Attacking);
|
||||
}
|
||||
void updateAttacking(Card c) {
|
||||
set(CardProp.Attacking, c.getGame().getCombat().isAttacking(c));
|
||||
}
|
||||
|
||||
public boolean isBlocking() {
|
||||
return get(CardProp.Blocking);
|
||||
}
|
||||
void updateBlocking(Card c) {
|
||||
set(CardProp.Blocking, c.getGame().getCombat().isBlocking(c));
|
||||
}
|
||||
|
||||
public boolean isPhasedOut() {
|
||||
return get(CardProp.PhasedOut);
|
||||
}
|
||||
void updatePhasedOut(Card c) {
|
||||
set(CardProp.PhasedOut, c.isPhasedOut());
|
||||
}
|
||||
|
||||
public boolean isFirstTurnControlled() {
|
||||
return get(CardProp.Sickness);
|
||||
}
|
||||
public boolean hasSickness() {
|
||||
return isFirstTurnControlled() && !getOriginal().hasHaste();
|
||||
}
|
||||
public boolean isSick() {
|
||||
return getZone() == ZoneType.Battlefield && hasSickness();
|
||||
}
|
||||
void updateSickness(Card c) {
|
||||
set(CardProp.Sickness, c.isInPlay() && c.isSick());
|
||||
}
|
||||
|
||||
public boolean isTapped() {
|
||||
return get(CardProp.Tapped);
|
||||
}
|
||||
void updateTapped(Card c) {
|
||||
set(CardProp.Tapped, c.isTapped());
|
||||
}
|
||||
|
||||
public boolean isToken() {
|
||||
return get(CardProp.Token);
|
||||
}
|
||||
void updateToken(Card c) {
|
||||
set(CardProp.Token, c.isToken());
|
||||
}
|
||||
|
||||
public Map<CounterType, Integer> getCounters() {
|
||||
return get(CardProp.Counters);
|
||||
}
|
||||
void updateCounters(Card c) {
|
||||
set(CardProp.Counters, c.getCounters());
|
||||
}
|
||||
|
||||
public int getDamage() {
|
||||
return get(CardProp.Damage);
|
||||
}
|
||||
void updateDamage(Card c) {
|
||||
set(CardProp.Damage, c.getDamage());
|
||||
}
|
||||
|
||||
public int getAssignedDamage() {
|
||||
return get(CardProp.AssignedDamage);
|
||||
}
|
||||
void updateAssignedDamage(Card c) {
|
||||
set(CardProp.AssignedDamage, c.getTotalAssignedDamage());
|
||||
}
|
||||
|
||||
public int getLethalDamage() {
|
||||
return getOriginal().getToughness() - getDamage() - getAssignedDamage();
|
||||
}
|
||||
|
||||
public int getShieldCount() {
|
||||
return get(CardProp.ShieldCount);
|
||||
}
|
||||
void updateShieldCount(Card c) {
|
||||
set(CardProp.ShieldCount, c.getShieldCount());
|
||||
}
|
||||
|
||||
public String getChosenType() {
|
||||
return get(CardProp.ChosenType);
|
||||
}
|
||||
void updateChosenType(Card c) {
|
||||
set(CardProp.ChosenType, c.getChosenType());
|
||||
}
|
||||
|
||||
public List<String> getChosenColors() {
|
||||
return get(CardProp.ChosenColors);
|
||||
}
|
||||
void updateChosenColors(Card c) {
|
||||
set(CardProp.ChosenColors, c.getChosenColors());
|
||||
}
|
||||
|
||||
public PlayerView getChosenPlayer() {
|
||||
return get(CardProp.ChosenPlayer);
|
||||
}
|
||||
void updateChosenPlayer(Card c) {
|
||||
set(CardProp.ChosenPlayer, c.getChosenPlayer());
|
||||
}
|
||||
|
||||
public String getNamedCard() {
|
||||
return get(CardProp.NamedCard);
|
||||
}
|
||||
void updateNamedCard(Card c) {
|
||||
set(CardProp.NamedCard, c.getNamedCard());
|
||||
}
|
||||
|
||||
public CardView getEquipping() {
|
||||
return get(CardProp.Equipping);
|
||||
}
|
||||
void updateEquipping(Card c) {
|
||||
set(CardProp.Equipping, CardView.get(c.getEquipping()));
|
||||
}
|
||||
|
||||
public Iterable<CardView> getEquippedBy() {
|
||||
return get(CardProp.EquippedBy);
|
||||
}
|
||||
void updateEquippedBy(Card c) {
|
||||
set(CardProp.EquippedBy, CardView.getCollection(c.getEquippedBy()));
|
||||
}
|
||||
|
||||
public boolean isEquipped() {
|
||||
return getEquippedBy() != null;
|
||||
}
|
||||
|
||||
public GameEntityView<?> getEnchanting() {
|
||||
return get(CardProp.Enchanting);
|
||||
}
|
||||
void updateEnchanting(Card c) {
|
||||
set(CardProp.Owner, GameEntityView.get(c.getEnchanting()));
|
||||
}
|
||||
|
||||
public CardView getEnchantingCard() {
|
||||
GameEntityView<?> enchanting = getEnchanting();
|
||||
if (enchanting instanceof CardView) {
|
||||
return (CardView) enchanting;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public PlayerView getEnchantingPlayer() {
|
||||
GameEntityView<?> enchanting = getEnchanting();
|
||||
if (enchanting instanceof PlayerView) {
|
||||
return (PlayerView) enchanting;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Iterable<CardView> getEnchantedBy() {
|
||||
return get(CardProp.EnchantedBy);
|
||||
}
|
||||
void updateEnchantedBy(Card c) {
|
||||
set(CardProp.EnchantedBy, CardView.getCollection(c.getEnchantedBy()));
|
||||
}
|
||||
|
||||
public boolean isEnchanted() {
|
||||
return getEnchantedBy() != null;
|
||||
}
|
||||
|
||||
public CardView getFortifying() {
|
||||
return get(CardProp.Fortifying);
|
||||
}
|
||||
void updateFortifying(Card c) {
|
||||
set(CardProp.Fortifying, c.getFortifying());
|
||||
}
|
||||
|
||||
public Iterable<CardView> getFortifiedBy() {
|
||||
return get(CardProp.FortifiedBy);
|
||||
}
|
||||
void updateFortifiedBy(Card c) {
|
||||
set(CardProp.FortifiedBy, CardView.getCollection(c.getFortifiedBy()));
|
||||
}
|
||||
|
||||
public boolean isFortified() {
|
||||
return getFortifiedBy() != null;
|
||||
}
|
||||
|
||||
public Iterable<CardView> getGainControlTargets() {
|
||||
return get(CardProp.GainControlTargets);
|
||||
}
|
||||
void updateGainControlTargets(Card c) {
|
||||
set(CardProp.GainControlTargets, CardView.getCollection(c.getGainControlTargets()));
|
||||
}
|
||||
|
||||
public CardView getCloneOrigin() {
|
||||
return get(CardProp.CloneOrigin);
|
||||
}
|
||||
void updateCloneOrigin(Card c) {
|
||||
set(CardProp.CloneOrigin, CardView.get(c.getCloneOrigin()));
|
||||
}
|
||||
|
||||
public Iterable<CardView> getImprinted() {
|
||||
return get(CardProp.Imprinted);
|
||||
}
|
||||
void updateImprinted(Card c) {
|
||||
set(CardProp.Imprinted, CardView.getCollection(c.getImprinted()));
|
||||
}
|
||||
|
||||
public Iterable<CardView> getHauntedBy() {
|
||||
return get(CardProp.HauntedBy);
|
||||
}
|
||||
void updateHauntedBy(Card c) {
|
||||
set(CardProp.HauntedBy, CardView.getCollection(c.getHauntedBy()));
|
||||
}
|
||||
|
||||
public CardView getHaunting() {
|
||||
return get(CardProp.Haunting);
|
||||
}
|
||||
void updateHaunting(Card c) {
|
||||
set(CardProp.Haunting, CardView.get(c.getHaunting()));
|
||||
}
|
||||
|
||||
public Iterable<CardView> getMustBlock() {
|
||||
return get(CardProp.MustBlock);
|
||||
}
|
||||
void updateHaunting(CardView haunting) {
|
||||
set(CardProp.MustBlock, haunting);
|
||||
}
|
||||
|
||||
public CardView getPairedWith() {
|
||||
return get(CardProp.PairedWith);
|
||||
}
|
||||
void updatePairedWith(Card c) {
|
||||
set(CardProp.PairedWith, CardView.get(c.getPairedWith()));
|
||||
}
|
||||
|
||||
public CardStateView getOriginal() {
|
||||
return get(CardProp.Original);
|
||||
}
|
||||
|
||||
public CardStateView getAlternate() {
|
||||
return get(CardProp.Alternate);
|
||||
}
|
||||
|
||||
public CardStateView getState(final boolean alternate0) {
|
||||
return alternate0 ? getAlternate() : getOriginal();
|
||||
}
|
||||
void updateState(Card c, boolean fromCurStateChange) {
|
||||
boolean isDoubleFaced = c.isDoubleFaced();
|
||||
boolean isFaceDown = c.isFaceDown();
|
||||
boolean isFlipCard = c.isFlipCard();
|
||||
boolean isFlipped = c.getCurState() == CardCharacteristicName.Flipped;
|
||||
boolean isSplitCard = c.isSplitCard();
|
||||
boolean isTransformed = c.getCurState() == CardCharacteristicName.Transformed;
|
||||
boolean hasAltState = isDoubleFaced || isFlipCard || isSplitCard || (isFaceDown/* && mayShowCardFace*/);
|
||||
|
||||
set(CardProp.Alternate, hasAltState ? new CardStateView(getId()) : null);
|
||||
set(CardProp.Cloned, c.isCloned());
|
||||
set(CardProp.FaceDown, isFaceDown);
|
||||
set(CardProp.SplitCard, isSplitCard);
|
||||
set(CardProp.FlipCard, isFlipCard);
|
||||
|
||||
if (fromCurStateChange) {
|
||||
set(CardProp.Flipped, isFlipped);
|
||||
set(CardProp.Transformed, isTransformed);
|
||||
updateRarity(c); //rarity and set based on current state
|
||||
updateSetCode(c);
|
||||
}
|
||||
|
||||
if (isSplitCard) {
|
||||
final CardCharacteristicName orig, alt;
|
||||
if (c.getCurState() == CardCharacteristicName.RightSplit) {
|
||||
// If right half on stack, place it first
|
||||
orig = CardCharacteristicName.RightSplit;
|
||||
alt = CardCharacteristicName.LeftSplit;
|
||||
}
|
||||
else {
|
||||
orig = CardCharacteristicName.LeftSplit;
|
||||
alt = CardCharacteristicName.RightSplit;
|
||||
}
|
||||
updateState(c, getOriginal(), orig);
|
||||
updateState(c, getAlternate(), alt);
|
||||
return;
|
||||
}
|
||||
|
||||
final CardStateView origView = getOriginal();
|
||||
origView.updateName(c);
|
||||
origView.updateColors(c);
|
||||
origView.updateImageKey(c);
|
||||
origView.updateType(c);
|
||||
origView.updateManaCost(c);
|
||||
origView.updatePower(c);
|
||||
origView.updateToughness(c);
|
||||
origView.updateLoyalty(c);
|
||||
origView.updateText(c);
|
||||
origView.updateChangedColorWords(c);
|
||||
origView.updateChangedTypes(c);
|
||||
origView.updateManaCost(c);
|
||||
origView.updateKeywords(c);
|
||||
origView.updateFoilIndex(c);
|
||||
|
||||
if (hasAltState) {
|
||||
if (isFlipCard && !isFlipped) {
|
||||
updateState(c, getAlternate(), CardCharacteristicName.Flipped);
|
||||
}
|
||||
else if (isDoubleFaced && !isTransformed) {
|
||||
updateState(c, getAlternate(), CardCharacteristicName.Transformed);
|
||||
}
|
||||
else {
|
||||
updateState(c, getAlternate(), CardCharacteristicName.Original);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void updateState(Card c, CardStateView view, CardCharacteristicName state) {
|
||||
final CardCharacteristics chars = c.getState(state);
|
||||
view.updateName(chars);
|
||||
view.updateColors(chars);
|
||||
view.updateImageKey(chars);
|
||||
view.updateType(chars);
|
||||
view.updateManaCost(chars);
|
||||
view.updatePower(chars);
|
||||
view.updateToughness(chars);
|
||||
view.updateLoyalty(chars);
|
||||
view.updateText(chars);
|
||||
view.updateFoilIndex(chars);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (getId() <= 0) { //if fake card, just return name
|
||||
return getOriginal().getName();
|
||||
}
|
||||
|
||||
/*if (!mayBeShown) {
|
||||
return "(Unknown card)";
|
||||
}*/
|
||||
|
||||
if (StringUtils.isEmpty(getOriginal().getName())) {
|
||||
CardStateView alternate = getAlternate();
|
||||
if (alternate != null) {
|
||||
return "Face-down card (" + getAlternate().getName() + ")";
|
||||
}
|
||||
return "(" + getId() + ")";
|
||||
}
|
||||
return getOriginal().getName() + " (" + getId() + ")";
|
||||
}
|
||||
|
||||
public String determineName(final CardStateView state) {
|
||||
if (state == getOriginal()) {
|
||||
return toString();
|
||||
}
|
||||
return getAlternate().getName() + " (" + getId() + ")";
|
||||
}
|
||||
|
||||
public class CardStateView extends TrackableObject<CardStateProp> {
|
||||
public CardStateView(int id0) {
|
||||
super(id0, CardStateProp.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getCard().determineName(this);
|
||||
}
|
||||
|
||||
public CardView getCard() {
|
||||
return CardView.this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return get(CardStateProp.Name);
|
||||
}
|
||||
void updateName(Card c) {
|
||||
set(CardStateProp.Name, c.getName());
|
||||
}
|
||||
void updateName(CardCharacteristics c) {
|
||||
set(CardStateProp.Name, c.getName());
|
||||
}
|
||||
|
||||
public ColorSet getColors() {
|
||||
return get(CardStateProp.Colors);
|
||||
}
|
||||
void updateColors(Card c) {
|
||||
set(CardStateProp.Colors, c.determineColor());
|
||||
}
|
||||
void updateColors(CardCharacteristics c) {
|
||||
set(CardStateProp.Colors, c.determineColor());
|
||||
}
|
||||
|
||||
public String getImageKey() {
|
||||
return get(CardStateProp.ImageKey);
|
||||
}
|
||||
void updateImageKey(Card c) {
|
||||
set(CardStateProp.ImageKey, c.getImageKey());
|
||||
}
|
||||
void updateImageKey(CardCharacteristics c) {
|
||||
set(CardStateProp.ImageKey, c.getImageKey());
|
||||
}
|
||||
|
||||
public Set<String> getType() {
|
||||
return get(CardStateProp.Type);
|
||||
}
|
||||
void updateType(Card c) {
|
||||
set(CardStateProp.Type, c.getType());
|
||||
}
|
||||
void updateType(CardCharacteristics c) {
|
||||
set(CardStateProp.Type, c.getType());
|
||||
}
|
||||
|
||||
public ManaCost getManaCost() {
|
||||
return get(CardStateProp.ManaCost);
|
||||
}
|
||||
void updateManaCost(Card c) {
|
||||
set(CardStateProp.ManaCost, c.getManaCost());
|
||||
}
|
||||
void updateManaCost(CardCharacteristics c) {
|
||||
set(CardStateProp.ManaCost, c.getManaCost());
|
||||
}
|
||||
|
||||
public int getPower() {
|
||||
return get(CardStateProp.Power);
|
||||
}
|
||||
void updatePower(Card c) {
|
||||
set(CardStateProp.Power, c.getNetAttack());
|
||||
}
|
||||
void updatePower(CardCharacteristics c) {
|
||||
set(CardStateProp.Power, c.getBaseAttack());
|
||||
}
|
||||
|
||||
public int getToughness() {
|
||||
return get(CardStateProp.Toughness);
|
||||
}
|
||||
void updateToughness(Card c) {
|
||||
set(CardStateProp.Toughness, c.getNetDefense());
|
||||
}
|
||||
void updateToughness(CardCharacteristics c) {
|
||||
set(CardStateProp.Toughness, c.getBaseDefense());
|
||||
}
|
||||
|
||||
public int getLoyalty() {
|
||||
return get(CardStateProp.Loyalty);
|
||||
}
|
||||
void updateLoyalty(Card c) {
|
||||
set(CardStateProp.Loyalty, c.getCurrentLoyalty());
|
||||
}
|
||||
void updateLoyalty(CardCharacteristics c) {
|
||||
set(CardStateProp.Loyalty, 0); // Q why is loyalty not a property of CardCharacteristic? A: because no alt states have a base loyalty (only candidate is Garruk Relentless).
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return get(CardStateProp.Text);
|
||||
}
|
||||
void updateText(Card c) {
|
||||
set(CardStateProp.Text, c.getText());
|
||||
}
|
||||
void updateText(CardCharacteristics c) {
|
||||
set(CardStateProp.Text, c.getOracleText());
|
||||
}
|
||||
|
||||
public int getFoilIndex() {
|
||||
return get(CardStateProp.FoilIndex);
|
||||
}
|
||||
void updateFoilIndex(Card c) {
|
||||
set(CardStateProp.FoilIndex, c.getCharacteristics().getFoil());
|
||||
}
|
||||
void updateFoilIndex(CardCharacteristics c) {
|
||||
set(CardStateProp.FoilIndex, c.getFoil());
|
||||
}
|
||||
|
||||
public Map<String, String> getChangedColorWords() {
|
||||
return get(CardStateProp.ChangedColorWords);
|
||||
}
|
||||
void updateChangedColorWords(Card c) {
|
||||
set(CardStateProp.ChangedColorWords, c.getChangedTextColorWords());
|
||||
}
|
||||
|
||||
public Map<String, String> getChangedTypes() {
|
||||
return get(CardStateProp.ChangedTypes);
|
||||
}
|
||||
void updateChangedTypes(Card c) {
|
||||
set(CardStateProp.ChangedTypes, c.getChangedTextTypeWords());
|
||||
}
|
||||
|
||||
public boolean hasDeathtouch() {
|
||||
return get(CardStateProp.HasDeathtouch);
|
||||
}
|
||||
public boolean hasHaste() {
|
||||
return get(CardStateProp.HasHaste);
|
||||
}
|
||||
public boolean hasInfect() {
|
||||
return get(CardStateProp.HasInfect);
|
||||
}
|
||||
public boolean hasStorm() {
|
||||
return get(CardStateProp.HasStorm);
|
||||
}
|
||||
public boolean hasTrample() {
|
||||
return get(CardStateProp.HasTrample);
|
||||
}
|
||||
void updateKeywords(Card c) {
|
||||
set(CardStateProp.HasDeathtouch, c.hasKeyword("Deathtouch"));
|
||||
set(CardStateProp.HasHaste, c.hasKeyword("Haste"));
|
||||
set(CardStateProp.HasInfect, c.hasKeyword("Infect"));
|
||||
set(CardStateProp.HasStorm, c.hasKeyword("Storm"));
|
||||
set(CardStateProp.HasTrample, c.hasKeyword("Trample"));
|
||||
}
|
||||
|
||||
public boolean isBasicLand() {
|
||||
return isLand() && Iterables.any(getType(), Predicates.in(CardType.getBasicTypes()));
|
||||
}
|
||||
public boolean isCreature() {
|
||||
return getType().contains("Creature");
|
||||
}
|
||||
public boolean isLand() {
|
||||
return getType().contains("Land");
|
||||
}
|
||||
public boolean isPlane() {
|
||||
return getType().contains("Plane");
|
||||
}
|
||||
public boolean isPhenomenon() {
|
||||
return getType().contains("Phenomenon");
|
||||
}
|
||||
public boolean isPlaneswalker() {
|
||||
return getType().contains("Planeswalker");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CardProp preventNextDamageProp() {
|
||||
return CardProp.PreventNextDamage;
|
||||
}
|
||||
}
|
||||
@@ -278,9 +278,9 @@ public class Combat {
|
||||
if (source.isAura()) {
|
||||
attacker = source.getEnchantingCard();
|
||||
} else if (source.isEquipment()) {
|
||||
attacker = source.getEquippingCard();
|
||||
attacker = source.getEquipping();
|
||||
} else if (source.isFortification()) {
|
||||
attacker = source.getFortifyingCard();
|
||||
attacker = source.getFortifying();
|
||||
}
|
||||
|
||||
// return the corresponding defender
|
||||
|
||||
@@ -634,7 +634,7 @@ public class CombatUtil {
|
||||
final String parse = blocker.getKeyword().get(keywordPosition).toString();
|
||||
if (parse.startsWith("CantBlockCardUID")) {
|
||||
final String[] k = parse.split("_", 2);
|
||||
if (attacker.getUniqueNumber() == Integer.parseInt(k[1])) {
|
||||
if (attacker.getId() == Integer.parseInt(k[1])) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
@@ -999,7 +999,7 @@ public class CombatUtil {
|
||||
|
||||
// Rule 702.23b: If a creature has multiple instances of flanking, each triggers separately.
|
||||
for( int i = 0; i < flankingMagnitude; i++ ) {
|
||||
String effect = String.format("AB$ Pump | Cost$ 0 | Defined$ CardUID_%d | NumAtt$ -1 | NumDef$ -1 | ", blocker.getUniqueNumber());
|
||||
String effect = String.format("AB$ Pump | Cost$ 0 | Defined$ CardUID_%d | NumAtt$ -1 | NumDef$ -1 | ", blocker.getId());
|
||||
String desc = String.format("StackDescription$ Flanking (The blocking %s gets -1/-1 until end of turn)", blocker.getName());
|
||||
|
||||
SpellAbility ability = AbilityFactory.getAbility(effect + desc, attacker);
|
||||
@@ -1031,7 +1031,7 @@ public class CombatUtil {
|
||||
private static void executeRampageAbility(final Game game, final Card c, final int magnitude, final int numBlockers) {
|
||||
// numBlockers starts with 1 since it is for every creature beyond the first
|
||||
for (int i = 1; i < numBlockers; i++) {
|
||||
String effect = "AB$ Pump | Cost$ 0 | " + c.getUniqueNumber() + " | NumAtt$ " + magnitude + " | NumDef$ " + magnitude + " | ";
|
||||
String effect = "AB$ Pump | Cost$ 0 | " + c.getId() + " | NumAtt$ " + magnitude + " | NumDef$ " + magnitude + " | ";
|
||||
String desc = "StackDescription$ Rampage " + magnitude + " (Whenever CARDNAME becomes blocked, it gets +" + magnitude + "/+"
|
||||
+ magnitude + " until end of turn for each creature blocking it beyond the first.)";
|
||||
|
||||
|
||||
150
forge-game/src/main/java/forge/game/combat/CombatView.java
Normal file
150
forge-game/src/main/java/forge/game/combat/CombatView.java
Normal file
@@ -0,0 +1,150 @@
|
||||
package forge.game.combat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import forge.game.GameEntityView;
|
||||
import forge.game.card.CardView;
|
||||
import forge.trackable.TrackableObject;
|
||||
import forge.trackable.TrackableProperty.CombatProp;
|
||||
|
||||
|
||||
public class CombatView extends TrackableObject<CombatProp> {
|
||||
public CombatView() {
|
||||
super(-1, CombatProp.class); //ID not needed
|
||||
}
|
||||
private Map<CardView, GameEntityView<?>> getAttackersWithDefenders() {
|
||||
return get(CombatProp.AttackersWithDefenders);
|
||||
}
|
||||
private Map<CardView, Iterable<CardView>> getAttackersWithBlockers() {
|
||||
return get(CombatProp.AttackersWithBlockers);
|
||||
}
|
||||
private Map<Iterable<CardView>, GameEntityView<?>> getBandsWithDefenders() {
|
||||
return get(CombatProp.BandsWithDefenders);
|
||||
}
|
||||
private Map<Iterable<CardView>, Iterable<CardView>> getBandsWithBlockers() {
|
||||
return get(CombatProp.BandsWithBlockers);
|
||||
}
|
||||
private Map<CardView, Iterable<CardView>> getAttackersWithPlannedBlockers() {
|
||||
return get(CombatProp.AttackersWithPlannedBlockers);
|
||||
}
|
||||
private Map<Iterable<CardView>, Iterable<CardView>> getBandsWithPlannedBlockers() {
|
||||
return get(CombatProp.BandsWithPlannedBlockers);
|
||||
}
|
||||
|
||||
public int getNumAttackers() {
|
||||
return getAttackersWithDefenders().size();
|
||||
}
|
||||
|
||||
public boolean isAttacking(final CardView card) {
|
||||
return getAttackersWithDefenders().containsKey(card);
|
||||
}
|
||||
|
||||
public Iterable<CardView> getAttackers() {
|
||||
return getAttackersWithDefenders().keySet();
|
||||
}
|
||||
|
||||
public Iterable<GameEntityView<?>> getDefenders() {
|
||||
return Sets.newHashSet(getAttackersWithDefenders().values());
|
||||
}
|
||||
|
||||
public GameEntityView<?> getDefender(final CardView attacker) {
|
||||
return getAttackersWithDefenders().get(attacker);
|
||||
}
|
||||
|
||||
public boolean isBlocking(final CardView card) {
|
||||
for (final Iterable<CardView> blockers : getAttackersWithBlockers().values()) {
|
||||
if (blockers == null) {
|
||||
continue;
|
||||
}
|
||||
if (Iterables.contains(blockers, card)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param attacker
|
||||
* @return the blockers associated with an attacker, or {@code null} if the
|
||||
* attacker is unblocked.
|
||||
*/
|
||||
public Iterable<CardView> getBlockers(final CardView attacker) {
|
||||
return getAttackersWithBlockers().get(attacker);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param attacker
|
||||
* @return the blockers associated with an attacker, or {@code null} if the
|
||||
* attacker is unblocked (planning stage, for targeting overlay).
|
||||
*/
|
||||
public Iterable<CardView> getPlannedBlockers(final CardView attacker) {
|
||||
return getAttackersWithPlannedBlockers().get(attacker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an {@link Iterable} of the blockers of the specified band, or
|
||||
* {@code null} if that band is unblocked.
|
||||
*
|
||||
* @param attackingBand
|
||||
* an {@link Iterable} representing an attacking band.
|
||||
* @return an {@link Iterable} of {@link CardView} objects, or {@code null}.
|
||||
*/
|
||||
public Iterable<CardView> getBlockers(final Iterable<CardView> attackingBand) {
|
||||
return getBandsWithBlockers().get(attackingBand);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an {@link Iterable} of the blockers of the specified band, or
|
||||
* {@code null} if that band is unblocked (planning stage, for targeting overlay).
|
||||
*
|
||||
* @param attackingBand
|
||||
* an {@link Iterable} representing an attacking band.
|
||||
* @return an {@link Iterable} of {@link CardView} objects, or {@code null}.
|
||||
*/
|
||||
public Iterable<CardView> getPlannedBlockers(final Iterable<CardView> attackingBand) {
|
||||
return getBandsWithPlannedBlockers().get(attackingBand);
|
||||
}
|
||||
|
||||
public Iterable<CardView> getAttackersOf(final GameEntityView<?> defender) {
|
||||
ArrayList<CardView> views = new ArrayList<CardView>();
|
||||
for (Entry<CardView, GameEntityView<?>> entry : getAttackersWithDefenders().entrySet()) {
|
||||
if (entry.getValue().equals(defender)) {
|
||||
views.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
return views;
|
||||
}
|
||||
public Iterable<Iterable<CardView>> getAttackingBandsOf(final GameEntityView<?> defender) {
|
||||
ArrayList<Iterable<CardView>> views = new ArrayList<Iterable<CardView>>();
|
||||
for (Entry<Iterable<CardView>, GameEntityView<?>> entry : getBandsWithDefenders().entrySet()) {
|
||||
if (entry.getValue().equals(defender)) {
|
||||
views.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
return views;
|
||||
}
|
||||
|
||||
public void addAttackingBand(final Iterable<CardView> attackingBand, final GameEntityView<?> defender, final Iterable<CardView> blockers, final Iterable<CardView> plannedBlockers) {
|
||||
final List<CardView> attackingBandCopy = Lists.newArrayList(attackingBand),
|
||||
blockersCopy, plannedBlockersCopy;
|
||||
|
||||
blockersCopy = blockers == null ? null : Lists.newArrayList(blockers);
|
||||
plannedBlockersCopy = plannedBlockers == null ? null : Lists.newArrayList(plannedBlockers);
|
||||
|
||||
for (final CardView attacker : attackingBandCopy) {
|
||||
this.getAttackersWithDefenders().put(attacker, defender);
|
||||
this.getAttackersWithBlockers().put(attacker, blockersCopy);
|
||||
this.getAttackersWithPlannedBlockers().put(attacker, plannedBlockersCopy);
|
||||
}
|
||||
this.getBandsWithDefenders().put(attackingBandCopy, defender);
|
||||
this.getBandsWithBlockers().put(attackingBandCopy, blockersCopy);
|
||||
this.getBandsWithPlannedBlockers().put(attackingBandCopy, plannedBlockersCopy);
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@ public class CostUnattach extends CostPartWithList {
|
||||
*/
|
||||
@Override
|
||||
protected Card doPayment(SpellAbility ability, Card targetCard) {
|
||||
targetCard.unEquipCard(targetCard.getEquipping().get(0));
|
||||
targetCard.unEquipCard(targetCard.getEquipping());
|
||||
return targetCard;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ public class GameStateSerializer {
|
||||
public void write(Card card) {
|
||||
if (card == null) { return; }
|
||||
|
||||
int key = card.getUniqueNumber();
|
||||
int key = card.getId();
|
||||
cards.put(key, card);
|
||||
write(key); //only write info for each card once at end of file
|
||||
}
|
||||
|
||||
@@ -518,7 +518,7 @@ public class PhaseHandler implements java.io.Serializable, IGameStateObject {
|
||||
int exaltedMagnitude = card.getKeywordAmount("Exalted");
|
||||
|
||||
for (int i = 0; i < exaltedMagnitude; i++) {
|
||||
String abScript = String.format("AB$ Pump | Cost$ 0 | Defined$ CardUID_%d | NumAtt$ +1 | NumDef$ +1 | StackDescription$ Exalted for attacker {c:CardUID_%d} (Whenever a creature you control attacks alone, that creature gets +1/+1 until end of turn).", attacker.getUniqueNumber(), attacker.getUniqueNumber());
|
||||
String abScript = String.format("AB$ Pump | Cost$ 0 | Defined$ CardUID_%d | NumAtt$ +1 | NumDef$ +1 | StackDescription$ Exalted for attacker {c:CardUID_%d} (Whenever a creature you control attacks alone, that creature gets +1/+1 until end of turn).", attacker.getId(), attacker.getId());
|
||||
SpellAbility ability = AbilityFactory.getAbility(abScript, card);
|
||||
ability.setActivatingPlayer(card.getController());
|
||||
ability.setDescription(ability.getStackDescription());
|
||||
|
||||
@@ -257,11 +257,11 @@ public class Untap extends Phase {
|
||||
continue;
|
||||
}
|
||||
} else if (c.isEquipment() && c.isEquipping()) {
|
||||
if (list.contains(c.getEquippingCard())) {
|
||||
if (list.contains(c.getEquipping())) {
|
||||
continue;
|
||||
}
|
||||
} else if (c.isFortification() && c.isFortifying()) {
|
||||
if (list.contains(c.getFortifyingCard())) {
|
||||
if (list.contains(c.getFortifying())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
207
forge-game/src/main/java/forge/game/player/PlayerView.java
Normal file
207
forge-game/src/main/java/forge/game/player/PlayerView.java
Normal file
@@ -0,0 +1,207 @@
|
||||
package forge.game.player;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.card.MagicColor;
|
||||
import forge.game.GameEntityView;
|
||||
import forge.game.card.CardFactoryUtil;
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.zone.PlayerZone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.trackable.TrackableCollection;
|
||||
import forge.trackable.TrackableProperty.PlayerProp;
|
||||
|
||||
|
||||
public class PlayerView extends GameEntityView<PlayerProp> {
|
||||
public static PlayerView get(Player p) {
|
||||
return p == null ? null : p.getView();
|
||||
}
|
||||
|
||||
public static TrackableCollection<PlayerView> getCollection(Iterable<Player> players) {
|
||||
if (players == null) {
|
||||
return null;
|
||||
}
|
||||
TrackableCollection<PlayerView> collection = new TrackableCollection<PlayerView>();
|
||||
for (Player p : players) {
|
||||
collection.add(p.getView());
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
public PlayerView(int id0) {
|
||||
super(id0, PlayerProp.class);
|
||||
|
||||
set(PlayerProp.Mana, Maps.newHashMapWithExpectedSize(MagicColor.NUMBER_OR_COLORS + 1));
|
||||
}
|
||||
|
||||
public LobbyPlayer getLobbyPlayer() {
|
||||
return get(PlayerProp.LobbyPlayer);
|
||||
}
|
||||
void updateLobbyPlayer(Player p) {
|
||||
set(PlayerProp.LobbyPlayer, p.getLobbyPlayer());
|
||||
}
|
||||
|
||||
public Iterable<PlayerView> getOpponents() {
|
||||
return get(PlayerProp.Opponents);
|
||||
}
|
||||
private TrackableCollection<PlayerView> getOpponentCollection() {
|
||||
return get(PlayerProp.Opponents);
|
||||
}
|
||||
|
||||
public boolean isOpponentOf(final PlayerView other) {
|
||||
return getOpponentCollection().contains(other);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return getLobbyPlayer().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
public int getLife() {
|
||||
return get(PlayerProp.Life);
|
||||
}
|
||||
void updateLife(Player p) {
|
||||
set(PlayerProp.Life, p.getLife());
|
||||
}
|
||||
|
||||
public int getPoisonCounters() {
|
||||
return get(PlayerProp.PoisonCounters);
|
||||
}
|
||||
void updatePoisonCounters(Player p) {
|
||||
set(PlayerProp.PoisonCounters, p.getPoisonCounters());
|
||||
}
|
||||
|
||||
public int getMaxHandSize() {
|
||||
return get(PlayerProp.MaxHandSize);
|
||||
}
|
||||
void updateMaxHandSize(Player p) {
|
||||
set(PlayerProp.MaxHandSize, p.getMaxHandSize());
|
||||
}
|
||||
|
||||
public boolean hasUnlimitedHandSize() {
|
||||
return get(PlayerProp.HasUnlimitedHandSize);
|
||||
}
|
||||
void updateUnlimitedHandSize(Player p) {
|
||||
set(PlayerProp.HasUnlimitedHandSize, p.isUnlimitedHandSize());
|
||||
}
|
||||
|
||||
public int getNumDrawnThisTurn() {
|
||||
return get(PlayerProp.NumDrawnThisTurn);
|
||||
}
|
||||
void updateNumDrawnThisTurn(Player p) {
|
||||
set(PlayerProp.NumDrawnThisTurn, p.getNumDrawnThisTurn());
|
||||
}
|
||||
|
||||
public Iterable<String> getKeywords() {
|
||||
return get(PlayerProp.Keywords);
|
||||
}
|
||||
void updateKeywords(Player p) {
|
||||
set(PlayerProp.Keywords, p.getKeywords());
|
||||
}
|
||||
|
||||
public String getCommanderInfo() {
|
||||
return get(PlayerProp.CommanderInfo);
|
||||
}
|
||||
void updateCommanderInfo(Player p) {
|
||||
set(PlayerProp.CommanderInfo, CardFactoryUtil.getCommanderInfo(p).trim().replace("\r\n", "; "));
|
||||
}
|
||||
|
||||
public Iterable<CardView> getAnte() {
|
||||
return get(PlayerProp.Ante);
|
||||
}
|
||||
|
||||
public Iterable<CardView> getBattlefield() {
|
||||
return get(PlayerProp.Battlefield);
|
||||
}
|
||||
|
||||
public Iterable<CardView> getCommand() {
|
||||
return get(PlayerProp.Command);
|
||||
}
|
||||
|
||||
public Iterable<CardView> getExile() {
|
||||
return get(PlayerProp.Exile);
|
||||
}
|
||||
|
||||
public Iterable<CardView> getFlashback() {
|
||||
return get(PlayerProp.Flashback);
|
||||
}
|
||||
|
||||
public Iterable<CardView> getGraveyard() {
|
||||
return get(PlayerProp.Graveyard);
|
||||
}
|
||||
|
||||
public Iterable<CardView> getHand() {
|
||||
return get(PlayerProp.Hand);
|
||||
}
|
||||
|
||||
public Iterable<CardView> getLibrary() {
|
||||
return get(PlayerProp.Library);
|
||||
}
|
||||
|
||||
public Iterable<CardView> getCards(final ZoneType zone) {
|
||||
PlayerProp prop = getZoneProp(zone);
|
||||
if (prop != null) {
|
||||
return get(prop);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private PlayerProp getZoneProp(final ZoneType zone) {
|
||||
switch (zone) {
|
||||
case Ante:
|
||||
return PlayerProp.Ante;
|
||||
case Battlefield:
|
||||
return PlayerProp.Battlefield;
|
||||
case Command:
|
||||
return PlayerProp.Command;
|
||||
case Exile:
|
||||
return PlayerProp.Exile;
|
||||
case Graveyard:
|
||||
return PlayerProp.Graveyard;
|
||||
case Hand:
|
||||
return PlayerProp.Hand;
|
||||
case Library:
|
||||
return PlayerProp.Library;
|
||||
default:
|
||||
return null; //other zones not represented
|
||||
}
|
||||
}
|
||||
void updateZone(PlayerZone zone) {
|
||||
PlayerProp prop = getZoneProp(zone.getZoneType());
|
||||
if (prop == null) { return; }
|
||||
set(prop, CardView.getCollection(zone.getCards()));
|
||||
}
|
||||
|
||||
private Map<Byte, Integer> getMana() {
|
||||
return get(PlayerProp.Mana);
|
||||
}
|
||||
void updateMana(Player p) {
|
||||
boolean changed = false;
|
||||
Map<Byte, Integer> mana = getMana();
|
||||
for (byte b : MagicColor.WUBRGC) {
|
||||
int value = p.getManaPool().getAmountOfColor(b);
|
||||
if (mana.put(b, value) != value) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
flagAsChanged(PlayerProp.Mana);
|
||||
}
|
||||
}
|
||||
|
||||
public int getMana(final byte color) {
|
||||
Integer count = getMana().get(color);
|
||||
return count != null ? count.intValue() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PlayerProp preventNextDamageProp() {
|
||||
return PlayerProp.PreventNextDamage;
|
||||
}
|
||||
}
|
||||
@@ -233,8 +233,8 @@ public class ReplacementHandler implements IGameStateObject {
|
||||
// Replaced mana type
|
||||
final Card repHost = replacementEffect.getHostCard();
|
||||
String repType = repHost.getSVar(mapParams.get("ManaReplacement"));
|
||||
if (repType.contains("Chosen") && !repHost.getChosenColor().isEmpty()) {
|
||||
repType = repType.replace("Chosen", MagicColor.toShortString(repHost.getChosenColor().get(0)));
|
||||
if (repType.contains("Chosen") && !repHost.getChosenColors().isEmpty()) {
|
||||
repType = repType.replace("Chosen", MagicColor.toShortString(repHost.getChosenColors().get(0)));
|
||||
}
|
||||
manaAb.getManaPart().setManaReplaceType(repType);
|
||||
manaAb.getManaPart().produceMana(rep, player1, manaAb);
|
||||
|
||||
@@ -341,9 +341,9 @@ public class AbilityManaPart implements java.io.Serializable {
|
||||
*/
|
||||
public final String mana() {
|
||||
if (this.getOrigProduced().contains("Chosen")) {
|
||||
if (this.getSourceCard() != null && !this.getSourceCard().getChosenColor().isEmpty()) {
|
||||
if (this.getSourceCard() != null && !this.getSourceCard().getChosenColors().isEmpty()) {
|
||||
return MagicColor.toShortString(this.getSourceCard()
|
||||
.getChosenColor().get(0));
|
||||
.getChosenColors().get(0));
|
||||
}
|
||||
}
|
||||
return this.getOrigProduced();
|
||||
@@ -473,7 +473,7 @@ public class AbilityManaPart implements java.io.Serializable {
|
||||
}
|
||||
|
||||
if (this.getOrigProduced().contains("Chosen") && sourceCard != null ) {
|
||||
List<String> chosenCol = this.getSourceCard().getChosenColor();
|
||||
List<String> chosenCol = this.getSourceCard().getChosenColors();
|
||||
if ( !chosenCol.isEmpty() && MagicColor.toShortString(chosenCol.get(0)).contains(s)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -275,7 +275,7 @@ public class SpellAbilityCondition extends SpellAbilityVariables {
|
||||
}
|
||||
|
||||
if (this.getColorToCheck() != null) {
|
||||
if (!sa.getHostCard().getChosenColor().contains(this.getColorToCheck())) {
|
||||
if (!sa.getHostCard().getChosenColors().contains(this.getColorToCheck())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,7 +302,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
|
||||
}
|
||||
|
||||
if (this.getColorToCheck() != null) {
|
||||
if (!sa.getHostCard().getChosenColor().contains(this.getColorToCheck())) {
|
||||
if (!sa.getHostCard().getChosenColors().contains(this.getColorToCheck())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,10 +51,10 @@ public class SpellAbilityStackInstance implements IIdentifiable {
|
||||
// Coming off the Stack would work similarly, except it would just add the
|
||||
// full active SI instead of each of the parts
|
||||
|
||||
private int id;
|
||||
private SpellAbility ability = null;
|
||||
private final int id;
|
||||
private final SpellAbility ability;
|
||||
|
||||
private SpellAbilityStackInstance subInstance = null;
|
||||
private final SpellAbilityStackInstance subInstance;
|
||||
private Player activator;
|
||||
|
||||
// When going to a SubAbility that SA has a Instance Choice object
|
||||
@@ -73,67 +73,58 @@ public class SpellAbilityStackInstance implements IIdentifiable {
|
||||
private int xManaPaid = 0;
|
||||
|
||||
// Other Paid things
|
||||
private HashMap<String, List<Card>> paidHash = new HashMap<String, List<Card>>();
|
||||
private final HashMap<String, List<Card>> paidHash;
|
||||
|
||||
// Additional info
|
||||
// is Kicked, is Buyback
|
||||
|
||||
// Triggers
|
||||
private HashMap<String, Object> triggeringObjects = new HashMap<String, Object>();
|
||||
private List<Object> triggerRemembered = new ArrayList<Object>();
|
||||
private final HashMap<String, Object> triggeringObjects;
|
||||
private final List<Object> triggerRemembered;
|
||||
|
||||
private final HashMap<String, String> storedSVars = new HashMap<String, String>();
|
||||
|
||||
private final List<ZoneType> zonesToOpen;
|
||||
private final Map<Player, Object> playersWithValidTargets;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Constructor for SpellAbility_StackInstance.
|
||||
* </p>
|
||||
*
|
||||
* @param sa
|
||||
* a {@link forge.game.spellability.SpellAbility} object.
|
||||
*/
|
||||
private final StackItemView view;
|
||||
|
||||
public SpellAbilityStackInstance(final SpellAbility sa) {
|
||||
// Base SA info
|
||||
this.id = nextId();
|
||||
this.ability = sa;
|
||||
this.stackDescription = this.ability.getStackDescription();
|
||||
this.activator = sa.getActivatingPlayer();
|
||||
id = nextId();
|
||||
ability = sa;
|
||||
stackDescription = sa.getStackDescription();
|
||||
activator = sa.getActivatingPlayer();
|
||||
|
||||
// Payment info
|
||||
this.paidHash = this.ability.getPaidHash();
|
||||
this.ability.resetPaidHash();
|
||||
this.splicedCards = sa.getSplicedCards();
|
||||
paidHash = ability.getPaidHash();
|
||||
ability.resetPaidHash();
|
||||
splicedCards = sa.getSplicedCards();
|
||||
|
||||
// TODO getXManaCostPaid should be on the SA, not the Card
|
||||
this.xManaPaid = sa.getHostCard().getXManaCostPaid();
|
||||
xManaPaid = sa.getHostCard().getXManaCostPaid();
|
||||
|
||||
// Triggering info
|
||||
this.triggeringObjects = sa.getTriggeringObjects();
|
||||
this.triggerRemembered = sa.getTriggerRemembered();
|
||||
triggeringObjects = sa.getTriggeringObjects();
|
||||
triggerRemembered = sa.getTriggerRemembered();
|
||||
|
||||
final AbilitySub subAb = this.ability.getSubAbility();
|
||||
if (subAb != null) {
|
||||
this.subInstance = new SpellAbilityStackInstance(subAb);
|
||||
}
|
||||
subInstance = ability.getSubAbility() == null ? null : new SpellAbilityStackInstance(ability.getSubAbility());
|
||||
|
||||
// Targeting info -- 29/06/11 Moved to after taking care of SubAbilities
|
||||
// because otherwise AF_DealDamage SubAbilities that use Defined$
|
||||
// Targeted breaks (since it's parents target is reset)
|
||||
if (sa.usesTargeting()) {
|
||||
this.tc = ability.getTargets();
|
||||
this.ability.resetTargets();
|
||||
tc = ability.getTargets();
|
||||
ability.resetTargets();
|
||||
}
|
||||
|
||||
final Card source = this.ability.getHostCard();
|
||||
final Card source = ability.getHostCard();
|
||||
|
||||
// Store SVars and Clear
|
||||
for (final String store : Card.getStorableSVars()) {
|
||||
final String value = source.getSVar(store);
|
||||
if (value.length() > 0) {
|
||||
this.storedSVars.put(store, value);
|
||||
storedSVars.put(store, value);
|
||||
source.setSVar(store, "");
|
||||
}
|
||||
}
|
||||
@@ -156,154 +147,107 @@ public class SpellAbilityStackInstance implements IIdentifiable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view = new StackItemView(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.id;
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getSpellAbility.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link forge.game.spellability.SpellAbility} object.
|
||||
*/
|
||||
public final SpellAbility getSpellAbility() {
|
||||
this.ability.resetTargets();
|
||||
this.ability.setTargets(tc);
|
||||
this.ability.setActivatingPlayer(activator);
|
||||
//TODO: See if refresh actually needed for most places this is being called
|
||||
// Perhaps lets move the refresh logic to a separate function called only when necessary
|
||||
public final SpellAbility getSpellAbility(boolean refresh) {
|
||||
if (refresh) {
|
||||
ability.resetTargets();
|
||||
ability.setTargets(tc);
|
||||
ability.setActivatingPlayer(activator);
|
||||
|
||||
// Saved sub-SA needs to be reset on the way out
|
||||
if (this.subInstance != null) {
|
||||
this.ability.setSubAbility((AbilitySub) this.subInstance.getSpellAbility());
|
||||
}
|
||||
// Saved sub-SA needs to be reset on the way out
|
||||
if (subInstance != null) {
|
||||
ability.setSubAbility((AbilitySub) subInstance.getSpellAbility(true));
|
||||
}
|
||||
|
||||
// Set Cost specific things here
|
||||
this.ability.resetPaidHash();
|
||||
this.ability.setPaidHash(this.paidHash);
|
||||
this.ability.setSplicedCards(splicedCards);
|
||||
this.ability.getHostCard().setXManaCostPaid(this.xManaPaid);
|
||||
// Set Cost specific things here
|
||||
ability.resetPaidHash();
|
||||
ability.setPaidHash(paidHash);
|
||||
ability.setSplicedCards(splicedCards);
|
||||
ability.getHostCard().setXManaCostPaid(xManaPaid);
|
||||
|
||||
// Triggered
|
||||
this.ability.setAllTriggeringObjects(this.triggeringObjects);
|
||||
this.ability.setTriggerRemembered(this.triggerRemembered);
|
||||
// Triggered
|
||||
ability.setTriggeringObjects(triggeringObjects);
|
||||
ability.setTriggerRemembered(triggerRemembered);
|
||||
|
||||
// Add SVars back in
|
||||
final Card source = this.ability.getHostCard();
|
||||
for (final String store : this.storedSVars.keySet()) {
|
||||
final String value = this.storedSVars.get(store);
|
||||
if (value.length() > 0) {
|
||||
source.setSVar(store, value);
|
||||
// Add SVars back in
|
||||
final Card source = ability.getHostCard();
|
||||
for (final String store : storedSVars.keySet()) {
|
||||
final String value = storedSVars.get(store);
|
||||
if (value.length() > 0) {
|
||||
source.setSVar(store, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.ability;
|
||||
return ability;
|
||||
}
|
||||
|
||||
// A bit of SA shared abilities to restrict conflicts
|
||||
/**
|
||||
* <p>
|
||||
* Getter for the field <code>stackDescription</code>.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public final String getStackDescription() {
|
||||
return this.stackDescription;
|
||||
return stackDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getHostCard.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link forge.game.card.Card} object.
|
||||
*/
|
||||
public final Card getSourceCard() {
|
||||
return this.ability.getHostCard();
|
||||
return ability.getHostCard();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* isSpell.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public final boolean isSpell() {
|
||||
return this.ability.isSpell();
|
||||
return ability.isSpell();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* isAbility.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public final boolean isAbility() {
|
||||
return this.ability.isAbility();
|
||||
return ability.isAbility();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* isTrigger.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public final boolean isTrigger() {
|
||||
return this.ability.isTrigger();
|
||||
return ability.isTrigger();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* isStateTrigger.
|
||||
* </p>
|
||||
*
|
||||
* @param id
|
||||
* a int.
|
||||
* @return a boolean.
|
||||
*/
|
||||
public final boolean isStateTrigger(final int id) {
|
||||
return this.ability.getSourceTrigger() == id;
|
||||
return ability.getSourceTrigger() == id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is optional trigger.
|
||||
*
|
||||
* @return true, if is optional trigger
|
||||
*/
|
||||
public final boolean isOptionalTrigger() {
|
||||
return this.ability.isOptionalTrigger();
|
||||
return ability.isOptionalTrigger();
|
||||
}
|
||||
|
||||
public final SpellAbilityStackInstance getSubInstance() {
|
||||
return this.subInstance;
|
||||
return subInstance;
|
||||
}
|
||||
|
||||
public final TargetChoices getTargetChoices() {
|
||||
return this.tc;
|
||||
return tc;
|
||||
}
|
||||
|
||||
public final List<ZoneType> getZonesToOpen() {
|
||||
return this.zonesToOpen;
|
||||
return zonesToOpen;
|
||||
}
|
||||
|
||||
public final Map<Player, Object> getPlayersWithValidTargets() {
|
||||
return this.playersWithValidTargets;
|
||||
return playersWithValidTargets;
|
||||
}
|
||||
|
||||
public void updateTarget(TargetChoices target) {
|
||||
if (target != null) {
|
||||
this.tc = target;
|
||||
this.ability.setTargets(tc);
|
||||
this.stackDescription = this.ability.getStackDescription();
|
||||
tc = target;
|
||||
ability.setTargets(tc);
|
||||
stackDescription = ability.getStackDescription();
|
||||
view.updateTargetCards(this);
|
||||
view.updateTargetPlayers(this);
|
||||
view.updateText(this);
|
||||
|
||||
// Run BecomesTargetTrigger
|
||||
HashMap<String, Object> runParams = new HashMap<String, Object>();
|
||||
runParams.put("SourceSA", this.ability);
|
||||
runParams.put("SourceSA", ability);
|
||||
HashSet<Object> distinctObjects = new HashSet<Object>();
|
||||
for (final Object tgt : target.getTargets()) {
|
||||
if (distinctObjects.contains(tgt)) {
|
||||
@@ -315,7 +259,7 @@ public class SpellAbilityStackInstance implements IIdentifiable {
|
||||
((Card) tgt).setBecameTargetThisTurn(true);
|
||||
}
|
||||
runParams.put("Target", tgt);
|
||||
this.getSourceCard().getGame().getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
|
||||
getSourceCard().getGame().getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,12 +291,18 @@ public class SpellAbilityStackInstance implements IIdentifiable {
|
||||
return activator;
|
||||
}
|
||||
|
||||
public void setActivator(Player activator) {
|
||||
this.activator = activator;
|
||||
public void setActivator(Player activator0) {
|
||||
if (activator == activator0) { return; }
|
||||
activator = activator0;
|
||||
view.updateActivator(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s->%s", getSourceCard(), stackDescription);
|
||||
return String.format("%s->%s", getSourceCard(), getStackDescription());
|
||||
}
|
||||
|
||||
public StackItemView getView() {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package forge.game.spellability;
|
||||
|
||||
import forge.game.card.CardView;
|
||||
import forge.trackable.TrackableObject;
|
||||
import forge.trackable.TrackableProperty.SpellAbilityProp;
|
||||
|
||||
|
||||
public class SpellAbilityView extends TrackableObject<SpellAbilityProp> {
|
||||
SpellAbilityView(SpellAbility sa) {
|
||||
super(sa.getId(), SpellAbilityProp.class);
|
||||
updateHostCard(sa);
|
||||
updateDescription(sa);
|
||||
updateCanPlay(sa);
|
||||
updatePromptIfOnlyPossibleAbility(sa);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getDescription();
|
||||
}
|
||||
|
||||
public CardView getHostCard() {
|
||||
return get(SpellAbilityProp.HostCard);
|
||||
}
|
||||
void updateHostCard(SpellAbility sa) {
|
||||
set(SpellAbilityProp.HostCard, CardView.get(sa.getHostCard()));
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return get(SpellAbilityProp.Description);
|
||||
}
|
||||
void updateDescription(SpellAbility sa) {
|
||||
set(SpellAbilityProp.Description, sa.toUnsuppressedString());
|
||||
}
|
||||
|
||||
public boolean canPlay() {
|
||||
return get(SpellAbilityProp.CanPlay);
|
||||
}
|
||||
void updateCanPlay(SpellAbility sa) {
|
||||
set(SpellAbilityProp.CanPlay, sa.canPlay());
|
||||
}
|
||||
|
||||
public boolean promptIfOnlyPossibleAbility() {
|
||||
return get(SpellAbilityProp.PromptIfOnlyPossibleAbility);
|
||||
}
|
||||
void updatePromptIfOnlyPossibleAbility(SpellAbility sa) {
|
||||
set(SpellAbilityProp.PromptIfOnlyPossibleAbility, sa.promptIfOnlyPossibleAbility());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package forge.game.spellability;
|
||||
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.player.PlayerView;
|
||||
import forge.trackable.TrackableObject;
|
||||
import forge.trackable.TrackableProperty.StackItemProp;
|
||||
|
||||
|
||||
public class StackItemView extends TrackableObject<StackItemProp> {
|
||||
public StackItemView(SpellAbilityStackInstance si) {
|
||||
super(si.getId(), StackItemProp.class);
|
||||
updateKey(si);
|
||||
updateSourceTrigger(si);
|
||||
updateText(si);
|
||||
updateSourceCard(si);
|
||||
updateActivator(si);
|
||||
updateTargetCards(si);
|
||||
updateTargetPlayers(si);
|
||||
updateAbility(si);
|
||||
updateOptionalTrigger(si);
|
||||
updateSubInstance(si);
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return get(StackItemProp.Key);
|
||||
}
|
||||
void updateKey(SpellAbilityStackInstance si) {
|
||||
set(StackItemProp.Key, si.getSpellAbility(false).toUnsuppressedString());
|
||||
}
|
||||
|
||||
public int getSourceTrigger() {
|
||||
return get(StackItemProp.SourceTrigger);
|
||||
}
|
||||
void updateSourceTrigger(SpellAbilityStackInstance si) {
|
||||
set(StackItemProp.SourceTrigger, si.getSpellAbility(false).getSourceTrigger());
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return get(StackItemProp.Text);
|
||||
}
|
||||
void updateText(SpellAbilityStackInstance si) {
|
||||
set(StackItemProp.Text, si.getStackDescription());
|
||||
}
|
||||
|
||||
public CardView getSourceCard() {
|
||||
return get(StackItemProp.SourceCard);
|
||||
}
|
||||
void updateSourceCard(SpellAbilityStackInstance si) {
|
||||
set(StackItemProp.SourceCard, si.getSourceCard());
|
||||
}
|
||||
|
||||
public PlayerView getActivator() {
|
||||
return get(StackItemProp.Activator);
|
||||
}
|
||||
void updateActivator(SpellAbilityStackInstance si) {
|
||||
set(StackItemProp.Activator, PlayerView.get(si.getActivator()));
|
||||
}
|
||||
|
||||
public Iterable<CardView> getTargetCards() {
|
||||
return get(StackItemProp.TargetCards);
|
||||
}
|
||||
void updateTargetCards(SpellAbilityStackInstance si) {
|
||||
set(StackItemProp.TargetCards, CardView.getCollection(si.getTargetChoices().getTargetCards()));
|
||||
}
|
||||
|
||||
public Iterable<PlayerView> getTargetPlayers() {
|
||||
return get(StackItemProp.TargetPlayers);
|
||||
}
|
||||
void updateTargetPlayers(SpellAbilityStackInstance si) {
|
||||
set(StackItemProp.TargetPlayers, PlayerView.getCollection(si.getTargetChoices().getTargetPlayers()));
|
||||
}
|
||||
|
||||
public boolean isAbility() {
|
||||
return get(StackItemProp.Ability);
|
||||
}
|
||||
void updateAbility(SpellAbilityStackInstance si) {
|
||||
set(StackItemProp.Ability, si.isAbility());
|
||||
}
|
||||
|
||||
public boolean isOptionalTrigger() {
|
||||
return get(StackItemProp.OptionalTrigger);
|
||||
}
|
||||
void updateOptionalTrigger(SpellAbilityStackInstance si) {
|
||||
set(StackItemProp.OptionalTrigger, si.isOptionalTrigger());
|
||||
}
|
||||
|
||||
public StackItemView getSubInstance() {
|
||||
return get(StackItemProp.SubInstance);
|
||||
}
|
||||
void updateSubInstance(SpellAbilityStackInstance si) {
|
||||
set(StackItemProp.SubInstance, si.getSubInstance() == null ? null : new StackItemView(si.getSubInstance()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getText();
|
||||
}
|
||||
}
|
||||
@@ -159,7 +159,7 @@ public class StaticAbilityContinuous {
|
||||
|
||||
if (params.containsKey("AddKeyword")) {
|
||||
addKeywords = params.get("AddKeyword").split(" & ");
|
||||
final List<String> chosencolors = hostCard.getChosenColor();
|
||||
final List<String> chosencolors = hostCard.getChosenColors();
|
||||
for (final String color : chosencolors) {
|
||||
for (int w = 0; w < addKeywords.length; w++) {
|
||||
addKeywords[w] = addKeywords[w].replaceAll("ChosenColor", color.substring(0, 1).toUpperCase().concat(color.substring(1, color.length())));
|
||||
@@ -170,7 +170,7 @@ public class StaticAbilityContinuous {
|
||||
addKeywords[w] = addKeywords[w].replaceAll("ChosenType", chosenType);
|
||||
}
|
||||
final String chosenName = hostCard.getNamedCard();
|
||||
final String hostCardUID = Integer.toString(hostCard.getUniqueNumber()); // Protection with "doesn't remove" effect
|
||||
final String hostCardUID = Integer.toString(hostCard.getId()); // Protection with "doesn't remove" effect
|
||||
for (int w = 0; w < addKeywords.length; w++) {
|
||||
if (addKeywords[w].startsWith("Protection:")) {
|
||||
addKeywords[w] = addKeywords[w].replaceAll("ChosenName", "Card.named" + chosenName).replace("HostCardUID", hostCardUID);
|
||||
@@ -223,7 +223,7 @@ public class StaticAbilityContinuous {
|
||||
addTypes[0] = chosenType;
|
||||
se.setChosenType(chosenType);
|
||||
} else if (addTypes[0].equals("ImprintedCreatureType")) {
|
||||
final ArrayList<String> imprint = hostCard.getImprinted().get(0).getType();
|
||||
final Set<String> imprint = hostCard.getImprinted().get(0).getType();
|
||||
ArrayList<String> imprinted = new ArrayList<String>();
|
||||
for (String t : imprint) {
|
||||
if (CardType.isACreatureType(t) || t.equals("AllCreatureTypes")) {
|
||||
@@ -262,7 +262,7 @@ public class StaticAbilityContinuous {
|
||||
if (params.containsKey("AddColor")) {
|
||||
final String colors = params.get("AddColor");
|
||||
if (colors.equals("ChosenColor")) {
|
||||
addColors = CardUtil.getShortColorsString(hostCard.getChosenColor());
|
||||
addColors = CardUtil.getShortColorsString(hostCard.getChosenColors());
|
||||
} else {
|
||||
addColors = CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(colors.split(
|
||||
" & "))));
|
||||
@@ -272,7 +272,7 @@ public class StaticAbilityContinuous {
|
||||
if (params.containsKey("SetColor")) {
|
||||
final String colors = params.get("SetColor");
|
||||
if (colors.equals("ChosenColor")) {
|
||||
addColors = CardUtil.getShortColorsString(hostCard.getChosenColor());
|
||||
addColors = CardUtil.getShortColorsString(hostCard.getChosenColors());
|
||||
} else {
|
||||
addColors = CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(
|
||||
colors.split(" & "))));
|
||||
@@ -381,8 +381,8 @@ public class StaticAbilityContinuous {
|
||||
if (changeColorWordsTo != null) {
|
||||
final byte color;
|
||||
if (changeColorWordsTo.equals("ChosenColor")) {
|
||||
if (hostCard.getChosenColor().size() > 0) {
|
||||
color = MagicColor.fromName(hostCard.getChosenColor().get(0));
|
||||
if (hostCard.getChosenColors().size() > 0) {
|
||||
color = MagicColor.fromName(hostCard.getChosenColors().get(0));
|
||||
} else {
|
||||
color = 0;
|
||||
}
|
||||
@@ -653,7 +653,7 @@ public class StaticAbilityContinuous {
|
||||
} else if (params.get("Affected").contains("EnchantedBy")) {
|
||||
affectedCards = Lists.newArrayList(hostCard.getEnchantingCard());
|
||||
} else if (params.get("Affected").contains("EquippedBy")) {
|
||||
affectedCards = Lists.newArrayList(hostCard.getEquippingCard());
|
||||
affectedCards = Lists.newArrayList(hostCard.getEquipping());
|
||||
} else if (params.get("Affected").equals("EffectSource")) {
|
||||
affectedCards = new ArrayList<Card>(AbilityUtils.getDefinedCards(hostCard, params.get("Affected"), null));
|
||||
return affectedCards;
|
||||
|
||||
@@ -190,7 +190,7 @@ public class TriggerHandler implements IGameStateObject {
|
||||
|
||||
while(itr.hasNext()) {
|
||||
t = (Trigger)itr.next();
|
||||
if (c.getUniqueNumber() == t.getHostCard().getUniqueNumber() && t.isIntrinsic()) {
|
||||
if (c.getId() == t.getHostCard().getId() && t.isIntrinsic()) {
|
||||
toBeRemoved.add(t);
|
||||
}
|
||||
}
|
||||
@@ -420,7 +420,7 @@ public class TriggerHandler implements IGameStateObject {
|
||||
Card host = regtrig.getHostCard();
|
||||
Card trigCard = regtrig.getRunParams().containsKey("Card") ? (Card)regtrig.getRunParams().get("Card") : null;
|
||||
|
||||
if (trigCard != null && (host.getUniqueNumber() == trigCard.getUniqueNumber())) {
|
||||
if (trigCard != null && (host.getId() == trigCard.getId())) {
|
||||
host = trigCard;
|
||||
} else {
|
||||
host = game.getCardState(regtrig.getHostCard());
|
||||
@@ -445,7 +445,7 @@ public class TriggerHandler implements IGameStateObject {
|
||||
regtrig.setTriggeringObjects(sa);
|
||||
sa.setTriggerRemembered(regtrig.getTriggerRemembered());
|
||||
if (regtrig.getStoredTriggeredObjects() != null) {
|
||||
sa.setAllTriggeringObjects(regtrig.getStoredTriggeredObjects());
|
||||
sa.setTriggeringObjects(regtrig.getStoredTriggeredObjects());
|
||||
}
|
||||
if (sa.getActivatingPlayer() == null) { // overriding delayed trigger should have set activator
|
||||
sa.setActivatingPlayer(host.getController());
|
||||
|
||||
@@ -95,7 +95,7 @@ public class TriggerSpellAbilityCast extends Trigger {
|
||||
}
|
||||
|
||||
if (this.mapParams.containsKey("ValidActivatingPlayer")) {
|
||||
if (si == null || !matchesValid(si.getSpellAbility().getActivatingPlayer(), this.mapParams.get("ValidActivatingPlayer")
|
||||
if (si == null || !matchesValid(si.getSpellAbility(true).getActivatingPlayer(), this.mapParams.get("ValidActivatingPlayer")
|
||||
.split(","), this.getHostCard())) {
|
||||
return false;
|
||||
}
|
||||
@@ -103,7 +103,7 @@ public class TriggerSpellAbilityCast extends Trigger {
|
||||
String compare = this.mapParams.get("ActivatorThisTurnCast");
|
||||
List<Card> thisTurnCast = CardUtil.getThisTurnCast(this.mapParams.containsKey("ValidCard") ? this.mapParams.get("ValidCard") : "Card",
|
||||
this.getHostCard());
|
||||
thisTurnCast = CardLists.filterControlledBy(thisTurnCast, si.getSpellAbility().getActivatingPlayer());
|
||||
thisTurnCast = CardLists.filterControlledBy(thisTurnCast, si.getSpellAbility(true).getActivatingPlayer());
|
||||
int left = thisTurnCast.size();
|
||||
int right = Integer.parseInt(compare.substring(2));
|
||||
if (!Expressions.compare(left, compare, right)) {
|
||||
@@ -121,7 +121,7 @@ public class TriggerSpellAbilityCast extends Trigger {
|
||||
if (this.mapParams.containsKey("TargetsValid")) {
|
||||
SpellAbility sa = spellAbility;
|
||||
if (si != null) {
|
||||
sa = si.getSpellAbility();
|
||||
sa = si.getSpellAbility(true);
|
||||
}
|
||||
|
||||
boolean validTgtFound = false;
|
||||
@@ -211,7 +211,7 @@ public class TriggerSpellAbilityCast extends Trigger {
|
||||
final SpellAbilityStackInstance si = sa.getHostCard().getGame().getStack().getInstanceFromSpellAbility(castSA);
|
||||
sa.setTriggeringObject("Card", castSA.getHostCard());
|
||||
sa.setTriggeringObject("SpellAbility", castSA);
|
||||
sa.setTriggeringObject("SpellAbilityTargetingCards", (si != null ? si.getSpellAbility() : castSA).getTargets().getTargetCards());
|
||||
sa.setTriggeringObject("SpellAbilityTargetingCards", (si != null ? si.getSpellAbility(true) : castSA).getTargets().getTargetCards());
|
||||
sa.setTriggeringObject("Player", this.getRunParams().get("Player"));
|
||||
sa.setTriggeringObject("Activator", this.getRunParams().get("Activator"));
|
||||
sa.setTriggeringObject("CurrentStormCount", this.getRunParams().get("CurrentStormCount"));
|
||||
|
||||
@@ -93,7 +93,7 @@ public class TriggerTapsForMana extends Trigger {
|
||||
}
|
||||
String produced = (String) prod;
|
||||
if ("ChosenColor".equals(mapParams.get("Produced"))) {
|
||||
List<String> colors = this.getHostCard().getChosenColor();
|
||||
List<String> colors = this.getHostCard().getChosenColors();
|
||||
if (colors.isEmpty() || !produced.contains(MagicColor.toShortString(colors.get(0)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class WrappedAbility extends Ability implements ISpellAbility {
|
||||
boolean mandatory = false;
|
||||
|
||||
public WrappedAbility(final Trigger regTrig, final SpellAbility sa0, final Player decider0) {
|
||||
super(regTrig.getHostCard(), ManaCost.ZERO);
|
||||
super(sa0.getHostCard(), ManaCost.ZERO);
|
||||
regtrig = regTrig;
|
||||
sa = sa0;
|
||||
decider = decider0;
|
||||
@@ -41,7 +41,6 @@ public class WrappedAbility extends Ability implements ISpellAbility {
|
||||
return sa;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isWrapper() {
|
||||
return true;
|
||||
@@ -109,8 +108,8 @@ public class WrappedAbility extends Ability implements ISpellAbility {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAllTriggeringObjects(final HashMap<String, Object> triggeredObjects) {
|
||||
sa.setAllTriggeringObjects(triggeredObjects);
|
||||
public void setTriggeringObjects(final HashMap<String, Object> triggeredObjects) {
|
||||
sa.setTriggeringObjects(triggeredObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -178,11 +177,6 @@ public class WrappedAbility extends Ability implements ISpellAbility {
|
||||
return sa.getRestrictions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Card getHostCard() {
|
||||
return sa.getHostCard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStackDescription() {
|
||||
final StringBuilder sb = new StringBuilder(regtrig.toString());
|
||||
|
||||
@@ -191,7 +191,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
|
||||
// Add all Frozen Abilities onto the stack
|
||||
while (!this.frozenStack.isEmpty()) {
|
||||
final SpellAbility sa = this.frozenStack.pop().getSpellAbility();
|
||||
final SpellAbility sa = this.frozenStack.pop().getSpellAbility(true);
|
||||
this.add(sa);
|
||||
}
|
||||
// Add all waiting triggers onto the stack
|
||||
@@ -427,15 +427,15 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
runParams.put("Cost", sp.getPayCosts());
|
||||
runParams.put("Player", sp.getHostCard().getController());
|
||||
runParams.put("Activator", sp.getActivatingPlayer());
|
||||
runParams.put("CastSA", si.getSpellAbility());
|
||||
runParams.put("CastSACMC", si.getSpellAbility().getHostCard().getCMC());
|
||||
runParams.put("CastSA", si.getSpellAbility(true));
|
||||
runParams.put("CastSACMC", si.getSpellAbility(true).getHostCard().getCMC());
|
||||
runParams.put("CurrentStormCount", game.getStack().getCardsCastThisTurn().size());
|
||||
game.getTriggerHandler().runTrigger(TriggerType.SpellAbilityCast, runParams, true);
|
||||
|
||||
// Run SpellCast triggers
|
||||
if (sp.isSpell()) {
|
||||
game.getTriggerHandler().runTrigger(TriggerType.SpellCast, runParams, true);
|
||||
this.executeCastCommand(si.getSpellAbility().getHostCard());
|
||||
this.executeCastCommand(si.getSpellAbility(true).getHostCard());
|
||||
}
|
||||
|
||||
// Run AbilityCast triggers
|
||||
@@ -458,7 +458,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
runParams = new HashMap<String, Object>();
|
||||
SpellAbility s = sp;
|
||||
if (si != null) {
|
||||
s = si.getSpellAbility();
|
||||
s = si.getSpellAbility(true);
|
||||
}
|
||||
runParams.put("SourceSA", s);
|
||||
HashSet<Object> distinctObjects = new HashSet<Object>();
|
||||
@@ -780,13 +780,13 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
}
|
||||
|
||||
public final SpellAbility peekAbility() {
|
||||
return this.stack.peekFirst().getSpellAbility();
|
||||
return this.stack.peekFirst().getSpellAbility(true);
|
||||
}
|
||||
|
||||
public final void remove(final SpellAbilityStackInstance si) {
|
||||
this.stack.remove(si);
|
||||
this.frozenStack.remove(si);
|
||||
game.fireEvent(new GameEventSpellRemovedFromStack(si.getSpellAbility()));
|
||||
game.fireEvent(new GameEventSpellRemovedFromStack(si.getSpellAbility(true)));
|
||||
}
|
||||
|
||||
public final SpellAbilityStackInstance getInstanceFromSpellAbility(final SpellAbility sa) {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package forge.trackable;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class TrackableCollection<T extends TrackableObject<?>> extends LinkedHashSet<T> { //use linked hash set so order is maintained
|
||||
public TrackableCollection() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(T item) {
|
||||
//TODO: Track change
|
||||
return super.add(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object item) {
|
||||
//TODO: Track change
|
||||
return super.remove(item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package forge.trackable;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class TrackableIndex<T extends TrackableObject<?>> extends HashMap<Integer, T> {
|
||||
public TrackableIndex() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package forge.trackable;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import forge.game.IIdentifiable;
|
||||
|
||||
//base class for objects that can be tracked and synced between game server and GUI
|
||||
public abstract class TrackableObject<E extends Enum<E>> implements IIdentifiable {
|
||||
private final int id;
|
||||
private final EnumMap<E, Object> props;
|
||||
private final EnumSet<E> changedProps;
|
||||
|
||||
protected TrackableObject(int id0, Class<E> propEnum0) {
|
||||
id = id0;
|
||||
props = new EnumMap<E, Object>(propEnum0);
|
||||
changedProps = EnumSet.noneOf(propEnum0);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> T get(E key) {
|
||||
return (T)props.get(key);
|
||||
}
|
||||
|
||||
protected <T> void set(E key, T value) {
|
||||
if (value == null) {
|
||||
if (props.remove(key) != null) {
|
||||
changedProps.add(key);
|
||||
}
|
||||
}
|
||||
else if (!value.equals(props.put(key, value))) {
|
||||
changedProps.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
//use when updating collection type properties with using set
|
||||
protected void flagAsChanged(E key) {
|
||||
changedProps.add(key);
|
||||
}
|
||||
}
|
||||
118
forge-game/src/main/java/forge/trackable/TrackableProperty.java
Normal file
118
forge-game/src/main/java/forge/trackable/TrackableProperty.java
Normal file
@@ -0,0 +1,118 @@
|
||||
package forge.trackable;
|
||||
|
||||
public class TrackableProperty {
|
||||
public enum CardProp {
|
||||
Owner,
|
||||
Controller,
|
||||
Zone,
|
||||
Cloned,
|
||||
FaceDown,
|
||||
FlipCard,
|
||||
Flipped,
|
||||
SplitCard,
|
||||
Transformed,
|
||||
SetCode,
|
||||
Rarity,
|
||||
Attacking,
|
||||
Blocking,
|
||||
PhasedOut,
|
||||
Sickness,
|
||||
Tapped,
|
||||
Token,
|
||||
Counters,
|
||||
Damage,
|
||||
AssignedDamage,
|
||||
ShieldCount,
|
||||
PreventNextDamage,
|
||||
ChosenType,
|
||||
ChosenColors,
|
||||
ChosenPlayer,
|
||||
NamedCard,
|
||||
Equipping,
|
||||
EquippedBy,
|
||||
Enchanting,
|
||||
EnchantedBy,
|
||||
Fortifying,
|
||||
FortifiedBy,
|
||||
GainControlTargets,
|
||||
CloneOrigin,
|
||||
Imprinted,
|
||||
HauntedBy,
|
||||
Haunting,
|
||||
MustBlock,
|
||||
PairedWith,
|
||||
Original,
|
||||
Alternate
|
||||
}
|
||||
|
||||
public enum CardStateProp {
|
||||
Name,
|
||||
Colors,
|
||||
ImageKey,
|
||||
Type,
|
||||
ManaCost,
|
||||
Power,
|
||||
Toughness,
|
||||
Loyalty,
|
||||
Text,
|
||||
ChangedColorWords,
|
||||
ChangedTypes,
|
||||
HasDeathtouch,
|
||||
HasHaste,
|
||||
HasInfect,
|
||||
HasStorm,
|
||||
HasTrample,
|
||||
FoilIndex
|
||||
}
|
||||
|
||||
public enum PlayerProp {
|
||||
LobbyPlayer,
|
||||
Opponents,
|
||||
Life,
|
||||
PoisonCounters,
|
||||
MaxHandSize,
|
||||
HasUnlimitedHandSize,
|
||||
NumDrawnThisTurn,
|
||||
PreventNextDamage,
|
||||
Keywords,
|
||||
CommanderInfo,
|
||||
Ante,
|
||||
Battlefield,
|
||||
Command,
|
||||
Exile,
|
||||
Flashback,
|
||||
Graveyard,
|
||||
Hand,
|
||||
Library,
|
||||
Mana
|
||||
}
|
||||
|
||||
public enum SpellAbilityProp {
|
||||
HostCard,
|
||||
Description,
|
||||
CanPlay,
|
||||
PromptIfOnlyPossibleAbility
|
||||
}
|
||||
|
||||
public enum StackItemProp {
|
||||
Key,
|
||||
SourceTrigger,
|
||||
Text,
|
||||
SourceCard,
|
||||
Activator,
|
||||
TargetCards,
|
||||
TargetPlayers,
|
||||
SubInstance,
|
||||
Ability,
|
||||
OptionalTrigger
|
||||
}
|
||||
|
||||
public enum CombatProp {
|
||||
AttackersWithDefenders,
|
||||
AttackersWithBlockers,
|
||||
BandsWithDefenders,
|
||||
BandsWithBlockers,
|
||||
AttackersWithPlannedBlockers,
|
||||
BandsWithPlannedBlockers
|
||||
}
|
||||
}
|
||||
@@ -575,7 +575,7 @@ public class PlayerControllerForTests extends PlayerController {
|
||||
|
||||
@Override
|
||||
public CardShields chooseRegenerationShield(Card c) {
|
||||
return Iterables.getFirst(c.getShield(), null);
|
||||
return Iterables.getFirst(c.getShields(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -167,7 +168,7 @@ public class CardDetailUtil {
|
||||
}
|
||||
|
||||
public static String formatCardType(final CardStateView card) {
|
||||
final List<String> list = card.getType();
|
||||
final Set<String> list = card.getType();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
final List<String> superTypes = new ArrayList<String>();
|
||||
|
||||
@@ -82,7 +82,7 @@ public class InputBlock extends InputSyncronizedBase {
|
||||
showMessage("Select another attacker to declare blockers for.");
|
||||
}
|
||||
else {
|
||||
String attackerName = currentAttacker.isFaceDown() ? "Morph" : currentAttacker.getName() + " (" + currentAttacker.getUniqueNumber() + ")";
|
||||
String attackerName = currentAttacker.isFaceDown() ? "Morph" : currentAttacker.getName() + " (" + currentAttacker.getId() + ")";
|
||||
String message = "Select creatures to block " + attackerName + " or select another attacker to declare blockers for.";
|
||||
showMessage(message);
|
||||
}
|
||||
|
||||
@@ -327,7 +327,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
|
||||
for (SpellAbilityStackInstance si : game.getStack()) {
|
||||
final Card stC = si.getSourceCard();
|
||||
final SpellAbility stSA = si.getSpellAbility().getRootAbility();
|
||||
final SpellAbility stSA = si.getSpellAbility(true).getRootAbility();
|
||||
if (stC.isValid(cost.getType().split(";"), ability.getActivatingPlayer(), source) && stSA.isSpell()) {
|
||||
saList.add(stSA);
|
||||
if (stC.isCopiedSpell()) {
|
||||
|
||||
@@ -1275,10 +1275,14 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
|
||||
@Override
|
||||
public CardShields chooseRegenerationShield(Card c) {
|
||||
if (c.getShield().size() < 2) {
|
||||
return Iterables.getFirst(c.getShield(), null);
|
||||
if (c.getShieldCount() < 2) {
|
||||
return Iterables.getFirst(c.getShields(), null);
|
||||
}
|
||||
return SGuiChoose.one(getGui(), "Choose a regeneration shield:", c.getShield());
|
||||
ArrayList<CardShields> shields = new ArrayList<CardShields>();
|
||||
for (CardShields shield : c.getShields()) {
|
||||
shields.add(shield);
|
||||
}
|
||||
return SGuiChoose.one(getGui(), "Choose a regeneration shield:", shields);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -318,7 +318,7 @@ public class TargetSelection {
|
||||
|
||||
final Game game = ability.getActivatingPlayer().getGame();
|
||||
for (final SpellAbilityStackInstance si : game.getStack()) {
|
||||
SpellAbility abilityOnStack = si.getSpellAbility();
|
||||
SpellAbility abilityOnStack = si.getSpellAbility(true);
|
||||
if (ability.equals(abilityOnStack)) {
|
||||
// By peeking at stack item, target is set to its SI state. So set it back before adding targets
|
||||
ability.resetTargets();
|
||||
@@ -346,7 +346,7 @@ public class TargetSelection {
|
||||
return false;
|
||||
}
|
||||
if (madeChoice instanceof StackItemView) {
|
||||
ability.getTargets().add(controller.getStackItem((StackItemView)madeChoice).getSpellAbility());
|
||||
ability.getTargets().add(controller.getStackItem((StackItemView)madeChoice).getSpellAbility(true));
|
||||
} else // 'FINISH TARGETING' chosen
|
||||
bTargetingDone = true;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package forge.view;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -751,7 +752,7 @@ public class CardView extends GameEntityView {
|
||||
private String name;
|
||||
private ColorSet colors;
|
||||
private String imageKey;
|
||||
private List<String> type;
|
||||
private Set<String> type;
|
||||
private ManaCost manaCost;
|
||||
private int power, toughness, loyalty;
|
||||
private String text;
|
||||
@@ -768,7 +769,7 @@ public class CardView extends GameEntityView {
|
||||
this.name = "";
|
||||
this.colors = ColorSet.getNullColor();
|
||||
this.imageKey = ImageKeys.HIDDEN_CARD;
|
||||
this.type = Collections.emptyList();
|
||||
this.type = Collections.emptySet();
|
||||
this.manaCost = ManaCost.NO_COST;
|
||||
this.power = 0;
|
||||
this.toughness = 0;
|
||||
@@ -837,15 +838,15 @@ public class CardView extends GameEntityView {
|
||||
/**
|
||||
* @return the type
|
||||
*/
|
||||
public List<String> getType() {
|
||||
public Set<String> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setType(final List<String> type) {
|
||||
this.type = Collections.unmodifiableList(type);
|
||||
public void setType(final Set<String> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -484,7 +484,7 @@ public abstract class LocalGameView implements IGameView {
|
||||
view.setAttacking(combat != null && combat.isAttacking(c));
|
||||
view.setBlocking(combat != null && combat.isBlocking(c));
|
||||
view.setChosenPlayer(getPlayerView(c.getChosenPlayer(), false));
|
||||
view.setEquipping(getCardView(Iterables.getFirst(c.getEquipping(), null), false));
|
||||
view.setEquipping(getCardView(c.getEquipping(), false));
|
||||
view.setEquippedBy(getCardViews(c.getEquippedBy(), false));
|
||||
view.setEnchantingCard(getCardView(c.getEnchantingCard(), false));
|
||||
view.setEnchantingPlayer(getPlayerView(c.getEnchantingPlayer(), false));
|
||||
|
||||
@@ -27,8 +27,8 @@ public class StackItemView implements IIdentifiable {
|
||||
|
||||
public StackItemView(SpellAbilityStackInstance si, LocalGameView gameView) {
|
||||
id = si.getId();
|
||||
key = si.getSpellAbility().toUnsuppressedString();
|
||||
sourceTrigger = si.getSpellAbility().getSourceTrigger();
|
||||
key = si.getSpellAbility(false).toUnsuppressedString();
|
||||
sourceTrigger = si.getSpellAbility(false).getSourceTrigger();
|
||||
text = si.getStackDescription();
|
||||
source = gameView.getCardView(si.getSourceCard(), true);
|
||||
activatingPlayer = gameView.getPlayerView(si.getActivator(), false);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package forge.view;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
@@ -53,10 +52,10 @@ public final class ViewUtil {
|
||||
view.setCounters(c.getCounters());
|
||||
view.setDamage(c.getDamage());
|
||||
view.setAssignedDamage(c.getTotalAssignedDamage());
|
||||
view.setRegenerationShields(c.getShield().size());
|
||||
view.setRegenerationShields(c.getShieldCount());
|
||||
view.setPreventNextDamage(c.getPreventNextDamageTotalShields());
|
||||
view.setChosenType(c.getChosenType());
|
||||
view.setChosenColors(c.getChosenColor());
|
||||
view.setChosenColors(c.getChosenColors());
|
||||
view.setNamedCard(c.getNamedCard());
|
||||
|
||||
if (c.isSplitCard()) {
|
||||
@@ -78,7 +77,7 @@ public final class ViewUtil {
|
||||
origView.setName(c.getName());
|
||||
origView.setColors(c.determineColor());
|
||||
origView.setImageKey(c.getImageKey() );
|
||||
origView.setType(Collections.unmodifiableList(c.getType()));
|
||||
origView.setType(c.getType());
|
||||
origView.setManaCost(c.getManaCost());
|
||||
origView.setPower(c.getNetAttack());
|
||||
origView.setToughness(c.getNetDefense());
|
||||
@@ -119,7 +118,7 @@ public final class ViewUtil {
|
||||
view.setName(chars.getName());
|
||||
view.setColors(chars.determineColor());
|
||||
view.setImageKey(chars.getImageKey());
|
||||
view.setType(Collections.unmodifiableList(chars.getType()));
|
||||
view.setType(chars.getType());
|
||||
view.setManaCost(chars.getManaCost());
|
||||
view.setPower(chars.getBaseAttack());
|
||||
view.setToughness(chars.getBaseDefense());
|
||||
|
||||
Reference in New Issue
Block a user