- The AI can now use spellAbilities giving shroud to creatures to protect them from spellAbilities on the stack.

This commit is contained in:
Sloth
2012-02-24 14:03:18 +00:00
parent 3132a376ee
commit e72f5f93a0
3 changed files with 50 additions and 38 deletions

View File

@@ -1929,12 +1929,12 @@ 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 true;
}
/**
* Checks if is useful keyword.
@@ -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)) {

View File

@@ -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())) {

View File

@@ -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,12 +432,10 @@ 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
if (!this.keywords.contains("Shroud") && !this.keywords.contains("Hexproof")) {
return false;
}
}
final int activations = restrict.getNumberTurnActivations();
final int sacActivations = restrict.getActivationNumberSacrifice();
@@ -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();
}