mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Commit stage 1 of large game view refactoring
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user