- updates and fixes to damage prevention.

- Added the keyword Absorb.
- More AI improvements to handle damage prevention.
- Added Lymph Sliver.
This commit is contained in:
jendave
2011-08-06 11:11:39 +00:00
parent c2672ca4d0
commit e173f949e6
7 changed files with 101 additions and 88 deletions

1
.gitattributes vendored
View File

@@ -2761,6 +2761,7 @@ res/cardsfolder/lure.txt -text svneol=native#text/plain
res/cardsfolder/lurking_informant.txt -text svneol=native#text/plain
res/cardsfolder/lurking_nightstalker.txt -text svneol=native#text/plain
res/cardsfolder/lux_cannon.txt -text svneol=native#text/plain
res/cardsfolder/lymph_sliver.txt -text svneol=native#text/plain
res/cardsfolder/lynx.txt -text svneol=native#text/plain
res/cardsfolder/lys_alana_huntmaster.txt -text svneol=native#text/plain
res/cardsfolder/ma_chao_western_warrior.txt -text svneol=native#text/plain

View File

@@ -0,0 +1,9 @@
Name:Lymph Sliver
ManaCost:4 W
Types:Creature Sliver
Text:no text
PT:3/3
K:stPumpAll:Creature.Sliver:0/0/Absorb 1:no Condition:All Sliver creatures have absorb 1. (If a source would deal damage to a Sliver, prevent 1 of that damage.)
SVar:Rarity:Common
SVar:Picture:http://www.wizards.com/global/images/magic/general/lymph_sliver.jpg
End

View File

@@ -175,9 +175,10 @@ import java.util.Random;
}
private boolean shouldTgtP(int d, final boolean noPrevention) {
int restDamage = d;
if (AllZone.HumanPlayer.preventAllDamageToPlayer(AF.getHostCard(), false)
|| !AllZone.HumanPlayer.canTarget(AF.getHostCard())) return false;
if (!noPrevention)
restDamage = AllZone.HumanPlayer.staticDamagePrevention(restDamage,AF.getHostCard(),false);
PlayerZone compHand = AllZone.getZone(Constant.Zone.Hand, AllZone.ComputerPlayer);
CardList hand = new CardList(compHand.getCards());
@@ -197,10 +198,12 @@ import java.util.Random;
CardList hPlay = new CardList(human.getCards());
hPlay = hPlay.filter(new CardListFilter() {
public boolean addCard(Card c) {
int restDamage = d;
if (!noPrevention)
restDamage = c.staticDamagePrevention(d,AF.getHostCard(),false);
// will include creatures already dealt damage
return c.isCreature() && (c.getKillDamage() <= d)
return c.isCreature() && (c.getKillDamage() <= restDamage)
&& CardFactoryUtil.canTarget(AF.getHostCard(), c)
&& !(c.preventAllDamageToCard(AF.getHostCard(),false) && !noPrevention)
&& !c.getKeyword().contains("Indestructible")
&& !(c.getSVar("SacMe").length() > 0);
}

View File

@@ -2216,11 +2216,11 @@ public class Card extends MyObservable {
}
// This is for keywords with a number like Bushido, Annihilator and Rampage. It returns the total.
public int getKeywordMagnitute(String k) {
public int getKeywordMagnitude(String k) {
int count = 0;
ArrayList<String> keywords = getKeyword();
for(String kw:keywords) {
if(kw.contains(k)) {
if(kw.startsWith(k)) {
String[] parse = kw.split(" ");
String s = parse[1];
count += Integer.parseInt(s);
@@ -2661,10 +2661,8 @@ public class Card extends MyObservable {
return getNetDefense() + preventNextDamage - getDamage();
}
public void setDamage(int n) {
if(this.getKeyword().contains("Prevent all damage that would be dealt to CARDNAME.")) n = 0;
//if(this.getKeyword().contains("Prevent all damage that would be dealt to CARDNAME.")) n = 0;
damage = n;
}
@@ -2761,46 +2759,58 @@ public class Card extends MyObservable {
}
}
public boolean preventAllDamageToCard(Card source, boolean isCombat) {
boolean reduce = false;
//This should be also usable by the AI to forecast an effect (so it must not change the game state)
public int staticDamagePrevention(final int damage, final Card source, final boolean isCombat) {
int restDamage = damage;
if(isCombat) {
reduce = reduce || getKeyword().contains("Prevent all combat damage that would be dealt to and dealt by CARDNAME.");
reduce = reduce || getKeyword().contains("Prevent all combat damage that would be dealt to CARDNAME.");
reduce = reduce || source.getKeyword().contains("Prevent all combat damage that would be dealt to and dealt by CARDNAME.");
reduce = reduce || source.getKeyword().contains("Prevent all combat damage that would be dealt by CARDNAME.");
if(getKeyword().contains("Prevent all combat damage that would be dealt to and dealt by CARDNAME."))return 0;
if(getKeyword().contains("Prevent all combat damage that would be dealt to CARDNAME."))return 0;
if(source.getKeyword().contains("Prevent all combat damage that would be dealt to and dealt by CARDNAME."))return 0;
if(source.getKeyword().contains("Prevent all combat damage that would be dealt by CARDNAME."))return 0;
}
if(getKeyword().contains("Prevent all damage that would be dealt to CARDNAME."))return 0;
if(getKeyword().contains("Prevent all damage that would be dealt to and dealt by CARDNAME."))return 0;
if(source.getKeyword().contains("Prevent all damage that would be dealt to and dealt by CARDNAME."))return 0;
if(source.getKeyword().contains("Prevent all damage that would be dealt by CARDNAME."))return 0;
if(hasStartOfKeyword("Absorb")) {
int absorbed = this.getKeywordMagnitude("Absorb");
if (restDamage > absorbed) restDamage = restDamage - absorbed;
else return 0;
}
reduce = reduce || getKeyword().contains("Prevent all damage that would be dealt to CARDNAME.");
reduce = reduce || getKeyword().contains("Prevent all damage that would be dealt to and dealt by CARDNAME.");
reduce = reduce || source.getKeyword().contains("Prevent all damage that would be dealt to and dealt by CARDNAME.");
reduce = reduce || source.getKeyword().contains("Prevent all damage that would be dealt by CARDNAME.");
//more specific prevents here:
reduce = reduce || (getKeyword().contains("Prevent all damage that would be dealt to CARDNAME by artifact creatures.")
&& source.isCreature() && source.isArtifact());
reduce = reduce || (getKeyword().contains("Prevent all damage that would be dealt to CARDNAME by artifacts.")
&& source.isArtifact());
reduce = reduce || (getKeyword().contains("Prevent all damage that would be dealt to CARDNAME by creatures.")
&& source.isCreature());
if((getKeyword().contains("Prevent all damage that would be dealt to CARDNAME by artifact creatures.")
&& source.isCreature() && source.isArtifact()))return 0;
if((getKeyword().contains("Prevent all damage that would be dealt to CARDNAME by artifacts.")
&& source.isArtifact()))return 0;
if((getKeyword().contains("Prevent all damage that would be dealt to CARDNAME by creatures.")
&& source.isCreature()))return 0;
// specific Cards
reduce = reduce || (this.isCreature() && source.isCreature() &&
AllZoneUtil.isCardInPlay("Well-Laid Plans") && source.sharesColorWith(this));
reduce = reduce || (!isCombat && AllZoneUtil.isCardInPlay("Mark of Asylum", getController()));
reduce = reduce || (source.getController() == getController() && AllZoneUtil.isCardInPlay("Light of Sanction", getController()));
return reduce;
if(!isCreature()) { //and not a planeswalker
if((this.isCreature() && source.isCreature() &&
AllZoneUtil.isCardInPlay("Well-Laid Plans") && source.sharesColorWith(this)))return 0;
if((!isCombat && AllZoneUtil.isCardInPlay("Mark of Asylum", getController())))return 0;
if((source.getController().isPlayer(getController()) && AllZoneUtil.isCardInPlay("Light of Sanction", getController())))
return 0;
if (AllZoneUtil.isCardInPlay("Plated Pegasus") && source.isSpell()
&& restDamage > 0) restDamage = restDamage - 1;
} //Creature end
if (AllZoneUtil.isCardInPlay("Energy Storm") && source.isSpell()) return 0;
return restDamage;
}
public int preventDamage(final int damage, Card source, boolean isCombat) {
int restDamage = damage;
if (AllZoneUtil.isCardInPlay("Energy Storm") && source.isSpell()) return 0;
if( preventAllDamageToCard(source, isCombat)) {
return 0;
}
if (AllZoneUtil.isCardInPlay("Plated Pegasus") && source.isSpell()
&& restDamage > 0) restDamage = restDamage - 1;
restDamage = staticDamagePrevention(restDamage, source, isCombat);
if(restDamage >= preventNextDamage) {
restDamage = restDamage - preventNextDamage;

View File

@@ -454,7 +454,7 @@ public class CardFactoryUtil {
//Battle stats increasing keywords
if (c.hasKeyword("Double Strike")) value += power * 15;
value += c.getKeywordMagnitute("Bushido") * 20;
value += c.getKeywordMagnitude("Bushido") * 20;
value += c.getAmountOfKeyword("Flanking") * 20;
//Other good keywords
@@ -465,8 +465,8 @@ public class CardFactoryUtil {
if (c.hasKeyword("Trample")) value += power * 3;
if (c.hasKeyword("Vigilance")) value += power * 5 + toughness * 5;
if (c.hasKeyword("Wither")) value += power * 10;
value += c.getKeywordMagnitute("Rampage");
value += c.getKeywordMagnitute("Annihilator") * 30;
value += c.getKeywordMagnitude("Rampage");
value += c.getKeywordMagnitude("Annihilator") * 30;
if (c.hasKeyword("Changeling")) value += 5;
if (c.hasKeyword("Whenever CARDNAME becomes blocked by a creature, destroy that creature at end of combat") && power > 0) value += 15;
if (c.hasKeyword("Whenever a creature dealt damage by CARDNAME this turn is put into a graveyard, put a +1/+1 counter on CARDNAME.") && power > 0) value += 2;
@@ -4495,19 +4495,6 @@ public class CardFactoryUtil {
return list;
}
public static int getTotalBushidoMagnitude(Card c) {
int count = 0;
ArrayList<String> keywords = c.getKeyword();
for(String kw:keywords) {
if(kw.contains("Bushido")) {
String[] parse = kw.split(" ");
String s = parse[1];
count += Integer.parseInt(s);
}
}
return count;
}
public static ArrayList<Ability> getBushidoEffects(Card c) {
ArrayList<String> keywords = c.getKeyword();
ArrayList<Ability> list = new ArrayList<Ability>();

View File

@@ -471,8 +471,8 @@ public class CombatUtil {
if(!CardFactoryUtil.canDamage(defender, attacker)) return false;
int defBushidoMagnitude = CardFactoryUtil.getTotalBushidoMagnitude(defender);
int attBushidoMagnitude = CardFactoryUtil.getTotalBushidoMagnitude(attacker);
int defBushidoMagnitude = defender.getKeywordMagnitude("Bushido");
int attBushidoMagnitude = attacker.getKeywordMagnitude("Bushido");
int defenderDamage = defender.getNetAttack() - flankingMagnitude + defBushidoMagnitude;
int attackerDamage = attacker.getNetAttack() + attBushidoMagnitude;
@@ -576,8 +576,8 @@ public class CombatUtil {
if(!CardFactoryUtil.canDamage(attacker,defender)) return false;
int defBushidoMagnitude = CardFactoryUtil.getTotalBushidoMagnitude(defender);
int attBushidoMagnitude = CardFactoryUtil.getTotalBushidoMagnitude(attacker);
int defBushidoMagnitude = defender.getKeywordMagnitude("Bushido");
int attBushidoMagnitude = attacker.getKeywordMagnitude("Bushido");
int defenderDamage = defender.getNetAttack() - flankingMagnitude + defBushidoMagnitude;
int attackerDamage = attacker.getNetAttack() + attBushidoMagnitude;

View File

@@ -218,42 +218,22 @@ public abstract class Player extends MyObservable{
GameActionUtil.executePlayerDamageEffects(this, source, damageToDo, false);
}
public boolean preventAllDamageToPlayer(final Card source, final boolean isCombat) {
boolean reduce = false;
//This should be also usable by the AI to forecast an effect (so it must not change the game state)
public int staticDamagePrevention(final int damage, final Card source, final boolean isCombat) {
int restDamage = damage;
if(isCombat) {
reduce = reduce || source.getKeyword().contains("Prevent all combat damage that would be dealt to and dealt by CARDNAME.");
reduce = reduce || source.getKeyword().contains("Prevent all combat damage that would be dealt by CARDNAME.");
if(source.getKeyword().contains("Prevent all combat damage that would be dealt to and dealt by CARDNAME.")) return 0;
if(source.getKeyword().contains("Prevent all combat damage that would be dealt by CARDNAME.")) return 0;
if (AllZoneUtil.isCardInPlay("Purity", this)) return 0;
}
reduce = reduce || source.getKeyword().contains("Prevent all damage that would be dealt to and dealt by CARDNAME.");
reduce = reduce || source.getKeyword().contains("Prevent all damage that would be dealt by CARDNAME.");
//Spirit of Resistance
if(AllZoneUtil.isCardInPlay("Spirit of Resistance", this)) {
if( AllZoneUtil.getPlayerColorInPlay(this, Constant.Color.Black).size() > 0
&& AllZoneUtil.getPlayerColorInPlay(this, Constant.Color.Blue).size() > 0
&& AllZoneUtil.getPlayerColorInPlay(this, Constant.Color.Green).size() > 0
&& AllZoneUtil.getPlayerColorInPlay(this, Constant.Color.Red).size() > 0
&& AllZoneUtil.getPlayerColorInPlay(this, Constant.Color.White).size() > 0) {
reduce = true;
}
}
return reduce;
}
public int preventDamage(final int damage, Card source, boolean isCombat) {
int restDamage = damage;
if(source.getKeyword().contains("Prevent all damage that would be dealt to and dealt by CARDNAME.")) return 0;
if(source.getKeyword().contains("Prevent all damage that would be dealt by CARDNAME.")) return 0;
if (AllZoneUtil.isCardInPlay("Purity", this) && !isCombat) {
gainLife(restDamage,null);
return 0;
}
//specific cards
if (AllZoneUtil.isCardInPlay("Energy Storm") && source.isSpell()) return 0;
if( preventAllDamageToPlayer(source, isCombat)) {
return 0;
}
if (AllZoneUtil.isCardInPlay("Spirit of Resistance", this) && !source.getController().equals(this)
&& restDamage > 0) restDamage = restDamage - 1;
@@ -283,6 +263,29 @@ public abstract class Player extends MyObservable{
else return 0;
}
if (AllZoneUtil.isCardInPlay("Urza's Armor", this) && restDamage > 0) restDamage = restDamage - 1;
if(AllZoneUtil.isCardInPlay("Spirit of Resistance", this)) {
if( AllZoneUtil.getPlayerColorInPlay(this, Constant.Color.Black).size() > 0
&& AllZoneUtil.getPlayerColorInPlay(this, Constant.Color.Blue).size() > 0
&& AllZoneUtil.getPlayerColorInPlay(this, Constant.Color.Green).size() > 0
&& AllZoneUtil.getPlayerColorInPlay(this, Constant.Color.Red).size() > 0
&& AllZoneUtil.getPlayerColorInPlay(this, Constant.Color.White).size() > 0) {
return 0;
}
}
return restDamage;
}
public int preventDamage(final int damage, Card source, boolean isCombat) {
int restDamage = damage;
// Purity has to stay here because it changes the game state
if (AllZoneUtil.isCardInPlay("Purity", this) && !isCombat) {
gainLife(restDamage,null);
return 0;
}
restDamage = staticDamagePrevention(restDamage, source, isCombat);
if(restDamage >= preventNextDamage) {