mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
- The AI can now use spellAbilities giving shroud to creatures to protect them from spellAbilities on the stack.
This commit is contained in:
@@ -1929,11 +1929,11 @@ public class ComputerUtil {
|
||||
*/
|
||||
public static boolean containsUsefulKeyword(final ArrayList<String> keywords, final Card card) {
|
||||
for (final String keyword : keywords) {
|
||||
if (ComputerUtil.isUsefulKeyword(keyword, card)) {
|
||||
return true;
|
||||
if (!ComputerUtil.isUsefulKeyword(keyword, card)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1978,9 +1978,6 @@ public class ComputerUtil {
|
||||
if (ph.isPlayerTurn(human) || !CombatUtil.canAttack(card) || !CombatUtil.canBeBlocked(card)) {
|
||||
return false;
|
||||
}
|
||||
} else if (keyword.endsWith("Shroud")) {
|
||||
// TODO: check stack for spells and abilities
|
||||
return false;
|
||||
} else if (keyword.startsWith("Rampage")) {
|
||||
if (ph.isPlayerTurn(human) || !CombatUtil.canAttack(card) || !CombatUtil.canBeBlocked(card)
|
||||
|| (AllZoneUtil.getCreaturesInPlay(human).size() < 2)) {
|
||||
|
||||
@@ -2272,8 +2272,10 @@ public class AbilityFactory {
|
||||
ArrayList<Object> objects = new ArrayList<Object>();
|
||||
final ArrayList<Object> threatened = new ArrayList<Object>();
|
||||
String saviourApi = "";
|
||||
HashMap<String, String> saviourParams = null;
|
||||
if (saviourAf != null) {
|
||||
saviourApi = saviourAf.getAPI();
|
||||
saviourParams = saviourAf.getMapParams();
|
||||
}
|
||||
|
||||
if (topStack == null) {
|
||||
@@ -2299,7 +2301,7 @@ public class AbilityFactory {
|
||||
final String threatApi = topAf.getAPI();
|
||||
final HashMap<String, String> threatParams = topAf.getMapParams();
|
||||
|
||||
// Lethal Damage => prevent damage/regeneration/bounce
|
||||
// Lethal Damage => prevent damage/regeneration/bounce/shroud
|
||||
if (threatApi.equals("DealDamage") || threatApi.equals("DamageAll")) {
|
||||
// If PredictDamage is >= Lethal Damage
|
||||
final int dmg = AbilityFactory.calculateAmount(topStack.getSourceCard(),
|
||||
@@ -2323,6 +2325,13 @@ public class AbilityFactory {
|
||||
continue;
|
||||
}
|
||||
|
||||
// give Shroud to targeted creatures
|
||||
if (saviourApi.equals("Pump") && tgt == null && saviourParams.containsKey("KW")
|
||||
&& (saviourParams.get("KW").endsWith("Shroud")
|
||||
|| saviourParams.get("KW").endsWith("Hexproof"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't bounce or blink a permanent that the human
|
||||
// player owns or is a token
|
||||
if (saviourApi.equals("ChangeZone") && (c.getOwner().isHuman() || c.isToken())) {
|
||||
@@ -2345,10 +2354,10 @@ public class AbilityFactory {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Destroy => regeneration/bounce
|
||||
// Destroy => regeneration/bounce/shroud
|
||||
else if ((threatApi.equals("Destroy") || threatApi.equals("DestroyAll"))
|
||||
&& ((saviourApi.equals("Regenerate") && !threatParams.containsKey("NoRegen")) || saviourApi
|
||||
.equals("ChangeZone"))) {
|
||||
.equals("ChangeZone") || saviourApi.equals("Pump"))) {
|
||||
for (final Object o : objects) {
|
||||
if (o instanceof Card) {
|
||||
final Card c = (Card) o;
|
||||
@@ -2362,6 +2371,13 @@ public class AbilityFactory {
|
||||
continue;
|
||||
}
|
||||
|
||||
// give Shroud to targeted creatures
|
||||
if (saviourApi.equals("Pump") && tgt == null && saviourParams.containsKey("KW")
|
||||
&& (saviourParams.get("KW").endsWith("Shroud")
|
||||
|| saviourParams.get("KW").endsWith("Hexproof"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't bounce or blink a permanent that the human
|
||||
// player owns or is a token
|
||||
if (saviourApi.equals("ChangeZone") && (c.getOwner().isHuman() || c.isToken())) {
|
||||
@@ -2376,13 +2392,21 @@ public class AbilityFactory {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Exiling => bounce
|
||||
// Exiling => bounce/shroud
|
||||
else if ((threatApi.equals("ChangeZone") || threatApi.equals("ChangeZoneAll"))
|
||||
&& saviourApi.equals("ChangeZone") && threatParams.containsKey("Destination")
|
||||
&& (saviourApi.equals("ChangeZone") || saviourApi.equals("Pump"))
|
||||
&& threatParams.containsKey("Destination")
|
||||
&& threatParams.get("Destination").equals("Exile")) {
|
||||
for (final Object o : objects) {
|
||||
if (o instanceof Card) {
|
||||
final Card c = (Card) o;
|
||||
// give Shroud to targeted creatures
|
||||
if (saviourApi.equals("Pump") && tgt == null && saviourParams.containsKey("KW")
|
||||
&& (saviourParams.get("KW").endsWith("Shroud")
|
||||
|| saviourParams.get("KW").endsWith("Hexproof"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't bounce or blink a permanent that the human
|
||||
// player owns or is a token
|
||||
if (saviourApi.equals("ChangeZone") && (c.getOwner().isHuman() || c.isToken())) {
|
||||
|
||||
@@ -278,6 +278,11 @@ public class AbilityFactoryPump {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((keywords.contains("Shroud") || keywords.contains("Hexproof"))
|
||||
&& AbilityFactory.predictThreatenedObjects(sa.getAbilityFactory()).contains(this)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// will the creature attack (only relevant for sorcery speed)?
|
||||
if (CardFactoryUtil.doesCreatureAttackAI(c)
|
||||
&& AllZone.getPhaseHandler().isBefore(Constant.Phase.COMBAT_DECLARE_ATTACKERS)
|
||||
@@ -372,15 +377,16 @@ public class AbilityFactoryPump {
|
||||
} // getCurseCreatures()
|
||||
|
||||
private boolean containsCombatRelevantKeyword(final ArrayList<String> keywords) {
|
||||
boolean flag = false;
|
||||
for (final String keyword : keywords) {
|
||||
// since most keywords are combat relevant check for those that are
|
||||
// not
|
||||
if (!keyword.equals("HIDDEN This card doesn't untap during your next untap step.")) {
|
||||
flag = true;
|
||||
if (keyword.equals("HIDDEN This card doesn't untap during your next untap step.")
|
||||
|| keyword.endsWith("Shroud") || keyword.endsWith("Hexproof")) {
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return flag;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -426,11 +432,9 @@ public class AbilityFactoryPump {
|
||||
return false;
|
||||
}
|
||||
} else if (AllZone.getStack().size() > 0) {
|
||||
// TODO: pump something only if the top thing on the stack will kill
|
||||
// it via damage
|
||||
// or if top thing on stack will pump it/enchant it and I want to
|
||||
// kill it
|
||||
return false;
|
||||
if (!this.keywords.contains("Shroud") && !this.keywords.contains("Hexproof")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
final int activations = restrict.getNumberTurnActivations();
|
||||
@@ -479,21 +483,12 @@ public class AbilityFactoryPump {
|
||||
return false;
|
||||
}
|
||||
|
||||
final boolean givesKws = !this.keywords.get(0).equals("none");
|
||||
String[] kwPump = { "none" };
|
||||
if (givesKws) {
|
||||
kwPump = this.keywords.toArray(new String[this.keywords.size()]);
|
||||
}
|
||||
final String[] keywords = kwPump;
|
||||
|
||||
// when this happens we need to expand AI to consider if its ok for
|
||||
// everything?
|
||||
for (final Card card : cards) {
|
||||
final Random r = MyRandom.getRandom();
|
||||
|
||||
// Don't add duplicate keywords
|
||||
final boolean hKW = card.hasAnyKeyword(keywords);
|
||||
if (givesKws && hKW) {
|
||||
if (!ComputerUtil.containsUsefulKeyword(this.keywords, card)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -501,18 +496,14 @@ public class AbilityFactoryPump {
|
||||
if (card.getController().isComputer()) {
|
||||
return false;
|
||||
}
|
||||
if (!ComputerUtil.containsUsefulKeyword(this.keywords, card)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (r.nextFloat() <= Math.pow(.6667, activations));
|
||||
}
|
||||
if (((card.getNetDefense() + defense) > 0) && (!card.hasAnyKeyword(this.keywords))) {
|
||||
if (card.hasSickness() && this.keywords.contains("Haste")) {
|
||||
return true;
|
||||
} else if (card.hasSickness() ^ this.keywords.contains("Haste")) {
|
||||
return false;
|
||||
} else if (this.hostCard.equals(card)) {
|
||||
if ((keywords.contains("Shroud") || keywords.contains("Hexproof"))
|
||||
&& AbilityFactory.predictThreatenedObjects(sa.getAbilityFactory()).contains(card)) {
|
||||
return (r.nextFloat() <= Math.pow(.6667, activations));
|
||||
} else if (this.hostCard.equals(card) && !this.keywords.contains("Haste")) {
|
||||
if (r.nextFloat() <= Math.pow(.6667, activations)) {
|
||||
return CardFactoryUtil.doesCreatureAttackAI(card) && !sa.getPayCosts().getTap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user