mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 10:18:01 +00:00
AF: Combat refactored (17800 get!)
This commit is contained in:
9
.gitattributes
vendored
9
.gitattributes
vendored
@@ -12466,7 +12466,6 @@ src/main/java/forge/card/abilityfactory/AbilityFactoryCharm.java svneol=native#t
|
||||
src/main/java/forge/card/abilityfactory/AbilityFactoryClash.java svneol=native#text/plain
|
||||
src/main/java/forge/card/abilityfactory/AbilityFactoryCleanup.java svneol=native#text/plain
|
||||
src/main/java/forge/card/abilityfactory/AbilityFactoryClone.java -text
|
||||
src/main/java/forge/card/abilityfactory/AbilityFactoryCombat.java svneol=native#text/plain
|
||||
src/main/java/forge/card/abilityfactory/AbilityFactoryCopy.java svneol=native#text/plain
|
||||
src/main/java/forge/card/abilityfactory/AbilityFactoryDealDamage.java svneol=native#text/plain
|
||||
src/main/java/forge/card/abilityfactory/AbilityFactoryDelayedTrigger.java svneol=native#text/plain
|
||||
@@ -12511,17 +12510,21 @@ src/main/java/forge/card/abilityfactory/ai/DrainManaAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/DrawAi.java svneol=native#text/plain
|
||||
src/main/java/forge/card/abilityfactory/ai/EffectAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/EndTurnAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/FogAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/LifeExchangeAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/LifeGainAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/LifeLoseAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/LifeSetAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/MillAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/MustAttackAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/MustBlockAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/PlayAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/PoisonAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/ProtectAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/ProtectAllAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/RegenerateAi.java svneol=native#text/plain
|
||||
src/main/java/forge/card/abilityfactory/ai/RegenerateAllAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/RemoveFromCombatAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/ShuffleAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/ai/TokenAi.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/AddTurnEffect.java -text
|
||||
@@ -12551,18 +12554,22 @@ src/main/java/forge/card/abilityfactory/effects/DrainManaEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/DrawEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/EffectEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/EndTurnEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/FogEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/HelperAnimate.java svneol=native#text/plain
|
||||
src/main/java/forge/card/abilityfactory/effects/LifeExchangeEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/LifeGainEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/LifeLoseEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/LifeSetEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/MillEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/MustAttackEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/MustBlockEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/PlayEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/PoisonEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/ProtectAllEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/ProtectEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/RegenerateAllEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/RegenerateEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/RemoveFromCombatEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/ShuffleEffect.java -text
|
||||
src/main/java/forge/card/abilityfactory/effects/TokenEffect.java svneol=native#text/plain
|
||||
src/main/java/forge/card/abilityfactory/package-info.java svneol=native#text/plain
|
||||
|
||||
@@ -729,13 +729,8 @@ public class AbilityFactory {
|
||||
}
|
||||
|
||||
else if (this.api.equals("Fog")) {
|
||||
if (this.isAb) {
|
||||
spellAbility = AbilityFactoryCombat.createAbilityFog(this);
|
||||
} else if (this.isSp) {
|
||||
spellAbility = AbilityFactoryCombat.createSpellFog(this);
|
||||
} else if (this.isDb) {
|
||||
spellAbility = AbilityFactoryCombat.createDrawbackFog(this);
|
||||
}
|
||||
ai = new FogAi();
|
||||
se = new FogEffect();
|
||||
}
|
||||
|
||||
else if (this.api.equals("GainControl")) {
|
||||
@@ -809,23 +804,13 @@ public class AbilityFactory {
|
||||
}
|
||||
|
||||
else if (this.api.equals("MustAttack")) {
|
||||
if (this.isAb) {
|
||||
spellAbility = AbilityFactoryCombat.createAbilityMustAttack(this);
|
||||
} else if (this.isSp) {
|
||||
spellAbility = AbilityFactoryCombat.createSpellMustAttack(this);
|
||||
} else if (this.isDb) {
|
||||
spellAbility = AbilityFactoryCombat.createDrawbackMustAttack(this);
|
||||
}
|
||||
ai = new MustAttackAi();
|
||||
se = new MustAttackEffect();
|
||||
}
|
||||
|
||||
else if (this.api.equals("MustBlock")) {
|
||||
if (this.isAb) {
|
||||
spellAbility = AbilityFactoryCombat.createAbilityMustBlock(this);
|
||||
} else if (this.isSp) {
|
||||
spellAbility = AbilityFactoryCombat.createSpellMustBlock(this);
|
||||
} else if (this.isDb) {
|
||||
spellAbility = AbilityFactoryCombat.createDrawbackMustBlock(this);
|
||||
}
|
||||
ai = new MustBlockAi();
|
||||
se = new MustBlockEffect();
|
||||
}
|
||||
|
||||
else if (this.api.equals("NameCard")) {
|
||||
@@ -943,13 +928,8 @@ public class AbilityFactory {
|
||||
}
|
||||
|
||||
else if (this.api.equals("RemoveFromCombat")) {
|
||||
if (this.isAb) {
|
||||
spellAbility = AbilityFactoryCombat.createAbilityRemoveFromCombat(this);
|
||||
} else if (this.isSp) {
|
||||
spellAbility = AbilityFactoryCombat.createSpellRemoveFromCombat(this);
|
||||
} else if (this.isDb) {
|
||||
spellAbility = AbilityFactoryCombat.createDrawbackRemoveFromCombat(this);
|
||||
}
|
||||
ai = new RemoveFromCombatAi();
|
||||
se = new RemoveFromCombatEffect();
|
||||
}
|
||||
|
||||
else if (this.api.equals("Repeat")) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,10 +18,12 @@ public abstract class SpellAiLogic {
|
||||
return doTriggerAINoCost(aiPlayer, params, sa, mandatory);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused") // 'unused' parameters are used by overloads
|
||||
public boolean doTriggerAINoCost(final Player aiPlayer, final Map<String, String> params, final SpellAbility sa, final boolean mandatory) {
|
||||
return canPlayAI(aiPlayer, params, sa);
|
||||
}
|
||||
|
||||
// consider safe
|
||||
@SuppressWarnings("unused") // 'unused' parameters are used by overloads
|
||||
public boolean chkAIDrawback(final Map<String, String> params, final SpellAbility sa, final Player aiPlayer) { return true; }
|
||||
}
|
||||
110
src/main/java/forge/card/abilityfactory/ai/FogAi.java
Normal file
110
src/main/java/forge/card/abilityfactory/ai/FogAi.java
Normal file
@@ -0,0 +1,110 @@
|
||||
package forge.card.abilityfactory.ai;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.card.abilityfactory.SpellAiLogic;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.phase.CombatUtil;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
|
||||
public class FogAi extends SpellAiLogic {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.card.abilityfactory.SpellAiLogic#canPlayAI(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility)
|
||||
*/
|
||||
@Override
|
||||
public boolean canPlayAI(Player ai, Map<String, String> params, SpellAbility sa) {
|
||||
// AI should only activate this during Human's Declare Blockers phase
|
||||
if (Singletons.getModel().getGame().getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) {
|
||||
return false;
|
||||
}
|
||||
if (!Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only cast when Stack is empty, so Human uses spells/abilities first
|
||||
if (!Singletons.getModel().getGame().getStack().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't cast it, if the effect is already in place
|
||||
if (Singletons.getModel().getGame().getPhaseHandler().isPreventCombatDamageThisTurn()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final AbilitySub subAb = sa.getSubAbility();
|
||||
if (subAb != null) {
|
||||
if (!subAb.chkAIDrawback()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Cast it if life is in danger
|
||||
return CombatUtil.lifeInDanger(ai, Singletons.getModel().getGame().getCombat());
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* fogPlayDrawbackAI.
|
||||
* </p>
|
||||
*
|
||||
* @param af
|
||||
* a {@link forge.card.abilityfactory.AbilityFactory} object.
|
||||
* @param sa
|
||||
* a {@link forge.card.spellability.SpellAbility} object.
|
||||
* @return a boolean.
|
||||
*/
|
||||
@Override
|
||||
public boolean chkAIDrawback(java.util.Map<String,String> params, SpellAbility sa, Player ai) {
|
||||
// AI should only activate this during Human's turn
|
||||
boolean chance;
|
||||
|
||||
// should really check if other player is attacking this player
|
||||
if (ai.isHostileTo(Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn())) {
|
||||
chance = Singletons.getModel().getGame().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_FIRST_STRIKE_DAMAGE);
|
||||
} else {
|
||||
chance = Singletons.getModel().getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DAMAGE);
|
||||
}
|
||||
|
||||
final AbilitySub subAb = sa.getSubAbility();
|
||||
if (subAb != null) {
|
||||
chance &= subAb.chkAIDrawback();
|
||||
}
|
||||
|
||||
return chance;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* fogDoTriggerAI.
|
||||
* </p>
|
||||
*
|
||||
* @param af
|
||||
* a {@link forge.card.abilityfactory.AbilityFactory} object.
|
||||
* @param sa
|
||||
* a {@link forge.card.spellability.SpellAbility} object.
|
||||
* @param mandatory
|
||||
* a boolean.
|
||||
* @return a boolean.
|
||||
*/
|
||||
@Override
|
||||
public boolean doTriggerAINoCost(Player aiPlayer, java.util.Map<String,String> params, SpellAbility sa, boolean mandatory) {
|
||||
boolean chance;
|
||||
if (Singletons.getModel().getGame().getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer().getOpponent())) {
|
||||
chance = Singletons.getModel().getGame().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_FIRST_STRIKE_DAMAGE);
|
||||
} else {
|
||||
chance = Singletons.getModel().getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DAMAGE);
|
||||
}
|
||||
|
||||
// check SubAbilities DoTrigger?
|
||||
final AbilitySub abSub = sa.getSubAbility();
|
||||
if (abSub != null) {
|
||||
return chance && abSub.doTrigger(mandatory);
|
||||
}
|
||||
|
||||
return chance;
|
||||
}
|
||||
}
|
||||
44
src/main/java/forge/card/abilityfactory/ai/MustAttackAi.java
Normal file
44
src/main/java/forge/card/abilityfactory/ai/MustAttackAi.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package forge.card.abilityfactory.ai;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import forge.card.abilityfactory.SpellAiLogic;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.player.Player;
|
||||
|
||||
public class MustAttackAi extends SpellAiLogic {
|
||||
|
||||
@Override
|
||||
public boolean canPlayAI(Player aiPlayer, java.util.Map<String,String> params, SpellAbility sa) {
|
||||
// disabled for the AI for now. Only for Gideon Jura at this time.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean chkAIDrawback(java.util.Map<String,String> params, SpellAbility sa, Player aiPlayer) {
|
||||
// AI should only activate this during Human's turn
|
||||
// TODO - implement AI
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.card.abilityfactory.SpellAiLogic#doTriggerAINoCost(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility, boolean)
|
||||
*/
|
||||
@Override
|
||||
public boolean doTriggerAINoCost(Player aiPlayer, Map<String, String> params, SpellAbility sa, boolean mandatory) {
|
||||
|
||||
boolean chance;
|
||||
|
||||
// TODO - implement AI
|
||||
chance = false;
|
||||
|
||||
// check SubAbilities DoTrigger?
|
||||
final AbilitySub abSub = sa.getSubAbility();
|
||||
if (abSub != null) {
|
||||
return chance && abSub.doTrigger(mandatory);
|
||||
}
|
||||
|
||||
return chance;
|
||||
}
|
||||
}
|
||||
109
src/main/java/forge/card/abilityfactory/ai/MustBlockAi.java
Normal file
109
src/main/java/forge/card/abilityfactory/ai/MustBlockAi.java
Normal file
@@ -0,0 +1,109 @@
|
||||
package forge.card.abilityfactory.ai;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.Singletons;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.abilityfactory.SpellAiLogic;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.phase.CombatUtil;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
public class MustBlockAi extends SpellAiLogic {
|
||||
|
||||
@Override
|
||||
public boolean canPlayAI(Player aiPlayer, java.util.Map<String,String> params, SpellAbility sa) {
|
||||
// disabled for the AI until he/she can make decisions about who to make
|
||||
// block
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean chkAIDrawback(java.util.Map<String,String> params, SpellAbility sa, Player aiPlayer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doTriggerAINoCost(Player ai, java.util.Map<String,String> params, SpellAbility sa, boolean mandatory) {
|
||||
final Card source = sa.getSourceCard();
|
||||
final Target abTgt = sa.getTarget();
|
||||
|
||||
// only use on creatures that can attack
|
||||
if (!Singletons.getModel().getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Card attacker = null;
|
||||
if (params.containsKey("DefinedAttacker")) {
|
||||
final ArrayList<Card> cards = AbilityFactory.getDefinedCards(sa.getSourceCard(),
|
||||
params.get("DefinedAttacker"), sa);
|
||||
if (cards.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
attacker = cards.get(0);
|
||||
}
|
||||
|
||||
if (attacker == null) {
|
||||
attacker = source;
|
||||
}
|
||||
|
||||
final Card definedAttacker = attacker;
|
||||
|
||||
boolean chance = false;
|
||||
|
||||
if (abTgt != null) {
|
||||
List<Card> list = CardLists.filter(ai.getOpponent().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES);
|
||||
list = CardLists.getTargetableCards(list, sa);
|
||||
list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source);
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
boolean tapped = c.isTapped();
|
||||
c.setTapped(false);
|
||||
if (!CombatUtil.canBlock(definedAttacker, c)) {
|
||||
return false;
|
||||
}
|
||||
if (CombatUtil.canDestroyAttacker(definedAttacker, c, null, false)) {
|
||||
return false;
|
||||
}
|
||||
if (!CombatUtil.canDestroyBlocker(c, definedAttacker, null, false)) {
|
||||
return false;
|
||||
}
|
||||
c.setTapped(tapped);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (list.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
final Card blocker = CardFactoryUtil.getBestCreatureAI(list);
|
||||
if (blocker == null) {
|
||||
return false;
|
||||
}
|
||||
abTgt.addTarget(blocker);
|
||||
chance = true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check SubAbilities DoTrigger?
|
||||
final AbilitySub abSub = sa.getSubAbility();
|
||||
if (abSub != null) {
|
||||
return chance && abSub.doTrigger(mandatory);
|
||||
}
|
||||
|
||||
return chance;
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@
|
||||
package forge.card.abilityfactory.ai;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import forge.Card;
|
||||
@@ -31,9 +30,7 @@ import forge.card.abilityfactory.SpellAiLogic;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.cost.CostUtil;
|
||||
import forge.card.spellability.AbilityActivated;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.Spell;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.phase.CombatUtil;
|
||||
|
||||
@@ -15,7 +15,6 @@ import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.phase.CombatUtil;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.ComputerUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
@@ -107,14 +106,10 @@ public class RegenerateAllAi extends SpellAiLogic {
|
||||
* a boolean.
|
||||
* @return a boolean.
|
||||
*/
|
||||
private static boolean regenerateAllDoTriggerAI(final Player ai, final AbilityFactory af, final SpellAbility sa,
|
||||
final boolean mandatory) {
|
||||
@Override
|
||||
public boolean doTriggerAINoCost(Player aiPlayer, java.util.Map<String,String> params, SpellAbility sa, boolean mandatory) {
|
||||
boolean chance = true;
|
||||
|
||||
if (!ComputerUtil.canPayCost(sa, ai)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final AbilitySub subAb = sa.getSubAbility();
|
||||
if (subAb != null) {
|
||||
chance &= subAb.doTrigger(mandatory);
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package forge.card.abilityfactory.ai;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import forge.card.abilityfactory.SpellAiLogic;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.player.Player;
|
||||
|
||||
public class RemoveFromCombatAi extends SpellAiLogic {
|
||||
|
||||
@Override
|
||||
public boolean canPlayAI(Player aiPlayer, java.util.Map<String,String> params, SpellAbility sa) {
|
||||
// disabled for the AI for now. Only for Gideon Jura at this time.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean chkAIDrawback(java.util.Map<String,String> params, SpellAbility sa, Player aiPlayer) {
|
||||
// AI should only activate this during Human's turn
|
||||
|
||||
// TODO - implement AI
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.card.abilityfactory.SpellAiLogic#doTriggerAINoCost(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility, boolean)
|
||||
*/
|
||||
@Override
|
||||
public boolean doTriggerAINoCost(Player aiPlayer, Map<String, String> params, SpellAbility sa, boolean mandatory) {
|
||||
boolean chance;
|
||||
|
||||
// TODO - implement AI
|
||||
chance = false;
|
||||
|
||||
// check SubAbilities DoTrigger?
|
||||
final AbilitySub abSub = sa.getSubAbility();
|
||||
if (abSub != null) {
|
||||
return chance && abSub.doTrigger(mandatory);
|
||||
}
|
||||
|
||||
return chance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package forge.card.abilityfactory.effects;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.card.abilityfactory.SpellEffect;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
|
||||
public class FogEffect extends SpellEffect {
|
||||
|
||||
|
||||
@Override
|
||||
public String getStackDescription(java.util.Map<String,String> params, SpellAbility sa) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (!(sa instanceof AbilitySub)) {
|
||||
sb.append(sa.getSourceCard().getName()).append(" - ");
|
||||
} else {
|
||||
sb.append(" ");
|
||||
}
|
||||
|
||||
sb.append(sa.getSourceCard().getController());
|
||||
sb.append(" prevents all combat damage this turn.");
|
||||
|
||||
final AbilitySub abSub = sa.getSubAbility();
|
||||
if (abSub != null) {
|
||||
sb.append(abSub.getStackDescription());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void resolve(java.util.Map<String,String> params, SpellAbility sa) {
|
||||
// Expand Fog keyword here depending on what we need out of it.
|
||||
Singletons.getModel().getGame().getPhaseHandler().setPreventCombatDamageThisTurn(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package forge.card.abilityfactory.effects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
import forge.Card;
|
||||
import forge.GameEntity;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.abilityfactory.SpellEffect;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.player.Player;
|
||||
|
||||
public class MustAttackEffect extends SpellEffect {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.card.abilityfactory.SpellEffect#getStackDescription(java.util.Map, forge.card.spellability.SpellAbility)
|
||||
*/
|
||||
@Override
|
||||
public String getStackDescription(Map<String, String> params, SpellAbility sa) {
|
||||
final Card host = sa.getSourceCard();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (sa instanceof AbilitySub) {
|
||||
sb.append(" ");
|
||||
} else {
|
||||
sb.append(sa.getSourceCard()).append(" - ");
|
||||
}
|
||||
|
||||
// end standard pre-
|
||||
|
||||
ArrayList<Player> tgtPlayers;
|
||||
|
||||
final Target tgt = sa.getTarget();
|
||||
if (tgt != null) {
|
||||
tgtPlayers = tgt.getTargetPlayers();
|
||||
} else {
|
||||
tgtPlayers = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), params.get("Defined"), sa);
|
||||
}
|
||||
|
||||
String defender = null;
|
||||
if (params.get("Defender").equals("Self")) {
|
||||
defender = host.toString();
|
||||
} else {
|
||||
// TODO - if more needs arise in the future
|
||||
}
|
||||
|
||||
for (final Player player : tgtPlayers) {
|
||||
sb.append("Creatures ").append(player).append(" controls attack ");
|
||||
sb.append(defender).append(" during his or her next turn.");
|
||||
}
|
||||
|
||||
// begin standard post-
|
||||
final AbilitySub abSub = sa.getSubAbility();
|
||||
if (abSub != null) {
|
||||
sb.append(abSub.getStackDescription());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolve(java.util.Map<String,String> params, SpellAbility sa) {
|
||||
ArrayList<Player> tgtPlayers;
|
||||
|
||||
final Target tgt = sa.getTarget();
|
||||
if ((tgt != null) && !params.containsKey("Defined")) {
|
||||
tgtPlayers = tgt.getTargetPlayers();
|
||||
} else {
|
||||
tgtPlayers = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), params.get("Defined"), sa);
|
||||
}
|
||||
|
||||
for (final Player p : tgtPlayers) {
|
||||
if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
||||
GameEntity entity;
|
||||
if (params.get("Defender").equals("Self")) {
|
||||
entity = sa.getSourceCard();
|
||||
} else {
|
||||
entity = p.getOpponent();
|
||||
}
|
||||
// System.out.println("Setting mustAttackEntity to: "+entity);
|
||||
p.setMustAttackEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
} // mustAttackResolve()
|
||||
|
||||
// **************************************************************
|
||||
// ********************* RemoveFromCombat ***********************
|
||||
// **************************************************************
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package forge.card.abilityfactory.effects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import forge.Card;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.abilityfactory.SpellEffect;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
|
||||
public class MustBlockEffect extends SpellEffect {
|
||||
|
||||
@Override
|
||||
public void resolve(java.util.Map<String,String> params, SpellAbility sa) {
|
||||
final Card host = sa.getSourceCard();
|
||||
|
||||
ArrayList<Card> tgtCards;
|
||||
|
||||
final Target tgt = sa.getTarget();
|
||||
if (tgt != null) {
|
||||
tgtCards = tgt.getTargetCards();
|
||||
} else {
|
||||
tgtCards = AbilityFactory.getDefinedCards(sa.getSourceCard(), params.get("Defined"), sa);
|
||||
}
|
||||
|
||||
ArrayList<Card> cards;
|
||||
if (params.containsKey("DefinedAttacker")) {
|
||||
cards = AbilityFactory.getDefinedCards(sa.getSourceCard(), params.get("DefinedAttacker"), sa);
|
||||
} else {
|
||||
cards = new ArrayList<Card>();
|
||||
cards.add(host);
|
||||
}
|
||||
|
||||
for (final Card c : tgtCards) {
|
||||
if ((tgt == null) || c.canBeTargetedBy(sa)) {
|
||||
final Card attacker = cards.get(0);
|
||||
c.addMustBlockCard(attacker);
|
||||
System.out.println(c + " is adding " + attacker + " to mustBlockCards: " + c.getMustBlockCards());
|
||||
}
|
||||
}
|
||||
|
||||
} // mustBlockResolve()
|
||||
|
||||
@Override
|
||||
public String getStackDescription(java.util.Map<String,String> params, SpellAbility sa) {
|
||||
final Card host = sa.getSourceCard();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (sa instanceof AbilitySub) {
|
||||
sb.append(" ");
|
||||
} else {
|
||||
sb.append(sa.getSourceCard()).append(" - ");
|
||||
}
|
||||
|
||||
// end standard pre-
|
||||
|
||||
ArrayList<Card> tgtCards;
|
||||
|
||||
final Target tgt = sa.getTarget();
|
||||
if (tgt != null) {
|
||||
tgtCards = tgt.getTargetCards();
|
||||
} else {
|
||||
tgtCards = AbilityFactory.getDefinedCards(sa.getSourceCard(), params.get("Defined"), sa);
|
||||
}
|
||||
|
||||
String attacker = null;
|
||||
if (params.containsKey("DefinedAttacker")) {
|
||||
final ArrayList<Card> cards = AbilityFactory.getDefinedCards(sa.getSourceCard(),
|
||||
params.get("DefinedAttacker"), sa);
|
||||
attacker = cards.get(0).toString();
|
||||
} else {
|
||||
attacker = host.toString();
|
||||
}
|
||||
|
||||
for (final Card c : tgtCards) {
|
||||
sb.append(c).append(" must block ").append(attacker).append(" if able.");
|
||||
}
|
||||
|
||||
// begin standard post-
|
||||
final AbilitySub abSub = sa.getSubAbility();
|
||||
if (abSub != null) {
|
||||
sb.append(abSub.getStackDescription());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
} // end class AbilityFactory_Combat
|
||||
@@ -6,7 +6,6 @@ import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.Command;
|
||||
import forge.Singletons;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.abilityfactory.SpellEffect;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package forge.card.abilityfactory.effects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import forge.Card;
|
||||
import forge.Singletons;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.abilityfactory.SpellEffect;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
|
||||
public class RemoveFromCombatEffect extends SpellEffect {
|
||||
|
||||
@Override
|
||||
public String getStackDescription(java.util.Map<String,String> params, SpellAbility sa) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (sa instanceof AbilitySub) {
|
||||
sb.append(" ");
|
||||
} else {
|
||||
sb.append(sa.getSourceCard()).append(" - ");
|
||||
}
|
||||
|
||||
// end standard pre-
|
||||
|
||||
ArrayList<Card> tgtCards;
|
||||
|
||||
final Target tgt = sa.getTarget();
|
||||
if (tgt != null) {
|
||||
tgtCards = tgt.getTargetCards();
|
||||
} else {
|
||||
tgtCards = AbilityFactory.getDefinedCards(sa.getSourceCard(), params.get("Defined"), sa);
|
||||
}
|
||||
|
||||
sb.append("Remove ");
|
||||
|
||||
for (final Card c : tgtCards) {
|
||||
sb.append(c);
|
||||
}
|
||||
|
||||
sb.append(" from combat.");
|
||||
|
||||
// begin standard post-
|
||||
final AbilitySub abSub = sa.getSubAbility();
|
||||
if (abSub != null) {
|
||||
sb.append(abSub.getStackDescription());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolve(java.util.Map<String,String> params, SpellAbility sa) {
|
||||
|
||||
ArrayList<Card> tgtCards;
|
||||
|
||||
final Target tgt = sa.getTarget();
|
||||
if ((tgt != null) && !params.containsKey("Defined")) {
|
||||
tgtCards = tgt.getTargetCards();
|
||||
} else {
|
||||
tgtCards = AbilityFactory.getDefinedCards(sa.getSourceCard(), params.get("Defined"), sa);
|
||||
}
|
||||
|
||||
for (final Card c : tgtCards) {
|
||||
if ((tgt == null) || c.canBeTargetedBy(sa)) {
|
||||
Singletons.getModel().getGame().getCombat().removeFromCombat(c);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1042,7 +1042,7 @@ public class CombatUtil {
|
||||
* a {@link forge.game.phase.Combat} object.
|
||||
* @return a int.
|
||||
*/
|
||||
public static int poisonIfUnblocked(final Card attacker, final Player attacked, final Combat combat) {
|
||||
public static int poisonIfUnblocked(final Card attacker, final Player attacked) {
|
||||
int damage = attacker.getNetCombatDamage();
|
||||
int poison = 0;
|
||||
damage += CombatUtil.predictPowerBonusOfAttacker(attacker, null, null);
|
||||
@@ -1093,7 +1093,7 @@ public class CombatUtil {
|
||||
public static int sumPoisonIfUnblocked(final List<Card> attackers, final Player attacked) {
|
||||
int sum = 0;
|
||||
for (final Card attacker : attackers) {
|
||||
sum += CombatUtil.poisonIfUnblocked(attacker, attacked, null);
|
||||
sum += CombatUtil.poisonIfUnblocked(attacker, attacked);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ public class ComputerUtilAttack {
|
||||
if (CombatUtil.damageIfUnblocked(attacker, opp, combat) > 0) {
|
||||
return true;
|
||||
}
|
||||
if (CombatUtil.poisonIfUnblocked(attacker, opp, combat) > 0) {
|
||||
if (CombatUtil.poisonIfUnblocked(attacker, opp) > 0) {
|
||||
return true;
|
||||
}
|
||||
if (this.attackers.size() == 1 && attacker.hasKeyword("Exalted")) {
|
||||
@@ -341,7 +341,7 @@ public class ComputerUtilAttack {
|
||||
continue;
|
||||
}
|
||||
totalAttack += CombatUtil.damageIfUnblocked(attacker, ai, null);
|
||||
totalPoison += CombatUtil.poisonIfUnblocked(attacker, ai, null);
|
||||
totalPoison += CombatUtil.poisonIfUnblocked(attacker, ai);
|
||||
}
|
||||
|
||||
if (ai.getLife() <= totalAttack
|
||||
|
||||
@@ -2887,5 +2887,17 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param playerTurn
|
||||
* @return
|
||||
*/
|
||||
public boolean isHostileTo(Player other) {
|
||||
if ( other.equals(getOpponent()) )
|
||||
return true;
|
||||
|
||||
return other.getType() != this.getType();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user