Start removing logic that depends on a single opponent, as this (naturally) doesn't work in multiplayer games.

'OppLifeTotal' is now removed, and started removing 'OppPoisonCounters'.
This commit is contained in:
elcnesh
2014-06-25 10:07:23 +00:00
parent 4eca4decac
commit 48086b30b7
9 changed files with 52 additions and 16 deletions

View File

@@ -392,8 +392,13 @@ public class DamageDealAi extends DamageAiBase {
} }
continue; continue;
} }
} else if ("OppAtTenLife".equals(sa.getParam("AILogic"))) {
for (final Player p : ai.getOpponents()) {
if (sa.canTarget(p) && p.getLife() == 10 && tcs.getNumTargeted() < tgt.getMaxTargets(source, sa)) {
tcs.add(p);
}
}
} }
// TODO: Improve Damage, we shouldn't just target the player just // TODO: Improve Damage, we shouldn't just target the player just
// because we can // because we can
else if (sa.canTarget(enemy)) { else if (sa.canTarget(enemy)) {

View File

@@ -961,7 +961,17 @@ public class CardFactoryUtil {
if (sq[0].contains("YourLifeTotal")) return doXMath(cc.getLife(), m, c); if (sq[0].contains("YourLifeTotal")) return doXMath(cc.getLife(), m, c);
if (sq[0].contains("OppLifeTotal")) return doXMath(ccOpp.getLife(), m, c); if (sq[0].contains("OppGreatestLifeTotal")) return doXMath(cc.getOpponentsGreatestLifeTotal(), m, c);
if (sq[0].contains("OppsAtLifeTotal")) {
final int lifeTotal = xCount(c, sq[1]);
int number = 0;
for (final Player opp : cc.getOpponents()) {
if (opp.getLife() == lifeTotal) {
number++;
}
}
return doXMath(number, m, c);
}
// Count$TargetedLifeTotal (targeted player's life total) // Count$TargetedLifeTotal (targeted player's life total)
if (sq[0].contains("TargetedLifeTotal")) { if (sq[0].contains("TargetedLifeTotal")) {

View File

@@ -301,6 +301,22 @@ public class Player extends GameEntity implements Comparable<Player> {
return result; return result;
} }
/**
* Find the greatest life total amongst this player's opponents.
*
* @return the life total of the opponent with the most life.
*/
public final int getOpponentsGreatestLifeTotal() {
final List<Player> opps = this.getOpponents();
int greatestLifeTotal = Integer.MIN_VALUE;
for (final Player p : opps) {
if (p.getLife() > greatestLifeTotal) {
greatestLifeTotal = p.getLife();
}
}
return greatestLifeTotal;
}
/** /**
* returns allied players. * returns allied players.
* Should keep player relations somewhere in the match structure * Should keep player relations somewhere in the match structure
@@ -2407,6 +2423,10 @@ public class Player extends GameEntity implements Comparable<Player> {
if (this.getLife() != life) { if (this.getLife() != life) {
return false; return false;
} }
} else if (property.equals("IsPoisoned")) {
if (this.getPoisonCounters() <= 0) {
return false;
}
} else if (property.startsWith("withMore")) { } else if (property.startsWith("withMore")) {
final String cardType = property.split("sThan")[0].substring(8); final String cardType = property.split("sThan")[0].substring(8);
final Player controller = "Active".equals(property.split("sThan")[1]) ? game.getPhaseHandler().getPlayerTurn() : sourceController; final Player controller = "Active".equals(property.split("sThan")[1]) ? game.getPhaseHandler().getPlayerTurn() : sourceController;
@@ -2426,7 +2446,7 @@ public class Player extends GameEntity implements Comparable<Player> {
return false; return false;
} }
} else if (property.startsWith("hasMore")) { } else if (property.startsWith("hasMore")) {
final Player controller = "Active".equals(property.split("Than")[1]) ? game.getPhaseHandler().getPlayerTurn() : sourceController; final Player controller = property.contains("Than") && "Active".equals(property.split("Than")[1]) ? game.getPhaseHandler().getPlayerTurn() : sourceController;
if (property.substring(7).startsWith("Life") && this.getLife() <= controller.getLife()) { if (property.substring(7).startsWith("Life") && this.getLife() <= controller.getLife()) {
return false; return false;
} else if (property.substring(7).startsWith("CardsInHand") } else if (property.substring(7).startsWith("CardsInHand")

View File

@@ -79,6 +79,12 @@ public class StaticAbilityCantAttackBlock {
&& defender.equals(hostCard.getGame().getNextPlayerAfter(card.getController(), hostCard.getChosenDirection()))) { && defender.equals(hostCard.getGame().getNextPlayerAfter(card.getController(), hostCard.getChosenDirection()))) {
return false; return false;
} }
if (params.containsKey("UnlessDefender")) {
final String type = params.get("UnlessDefender");
if (defender.hasProperty(type, hostCard.getController(), hostCard)) {
return false;
}
}
return true; return true;
} }

View File

@@ -3,7 +3,6 @@ ManaCost:5 U
Types:Creature Horror Types:Creature Horror
PT:5/5 PT:5/5
K:Infect K:Infect
S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ CARDNAME can't attack. | CheckSVar$ X | SVarCompare$ LE0 | Description$ CARDNAME can't attack unless defending player is poisoned. S:Mode$ CantAttack | ValidCard$ Card.Self | UnlessDefender$ IsPoisoned | Description$ CARDNAME can't attack unless defending player is poisoned.
SVar:X:Count$OppPoisonCounters
SVar:Picture:http://www.wizards.com/global/images/magic/general/chained_throatseeker.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/chained_throatseeker.jpg
Oracle:Infect (This creature deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.)\nChained Throatseeker can't attack unless defending player is poisoned. Oracle:Infect (This creature deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.)\nChained Throatseeker can't attack unless defending player is poisoned.

View File

@@ -1,9 +1,9 @@
Name:Hidetsugu's Second Rite Name:Hidetsugu's Second Rite
ManaCost:3 R ManaCost:3 R
Types:Instant Types:Instant
A:SP$ DealDamage | Cost$ 3 R | ValidTgts$ Player | TgtPrompt$ Select target player | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ10 | NumDmg$ 10 | References$ X | SpellDescription$ If target player has exactly 10 life, CARDNAME deals 10 damage to that player. A:SP$ DealDamage | Cost$ 3 R | ValidTgts$ Player | TgtPrompt$ Select target player | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ10 | NumDmg$ 10 | References$ X | AILogic$ OppAtTenLife | SpellDescription$ If target player has exactly 10 life, CARDNAME deals 10 damage to that player.
SVar:X:TargetedPlayer$LifeTotal SVar:X:TargetedPlayer$LifeTotal
SVar:Y:Count$OppLifeTotal SVar:Y:Count$OppsAtLifeTotal.10
SVar:NeedsToPlayVar:Y EQ10 SVar:NeedsToPlayVar:Y GE1
SVar:Picture:http://resources.wizards.com/magic/cards/sok/en-us/card88818.jpg SVar:Picture:http://resources.wizards.com/magic/cards/sok/en-us/card88818.jpg
Oracle:If target player has exactly 10 life, Hidetsugu's Second Rite deals 10 damage to that player. Oracle:If target player has exactly 10 life, Hidetsugu's Second Rite deals 10 damage to that player.

View File

@@ -2,8 +2,6 @@ Name:Keeper of the Flame
ManaCost:R R ManaCost:R R
Types:Creature Human Wizard Types:Creature Human Wizard
PT:1/2 PT:1/2
A:AB$ DealDamage | Cost$ R T | ValidTgts$ Opponent | CheckSVar$ X | SVarCompare$ LTY | NumDmg$ 2 | References$ X,Y | SpellDescription$ Choose target opponent who had more life than you did as you activated this ability. CARDNAME deals 2 damage to him or her. A:AB$ DealDamage | Cost$ R T | ValidTgts$ Opponent.hasMoreLife | NumDmg$ 2 | SpellDescription$ Choose target opponent who had more life than you did as you activated this ability. CARDNAME deals 2 damage to him or her.
SVar:X:Count$YourLifeTotal
SVar:Y:Count$OppLifeTotal
SVar:Picture:http://www.wizards.com/global/images/magic/general/keeper_of_the_flame.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/keeper_of_the_flame.jpg
Oracle:{R}, {T}: Choose target opponent who had more life than you did as you activated this ability. Keeper of the Flame deals 2 damage to him or her. Oracle:{R}, {T}: Choose target opponent who had more life than you did as you activated this ability. Keeper of the Flame deals 2 damage to him or her.

View File

@@ -2,9 +2,7 @@ Name:Keeper of the Light
ManaCost:W W ManaCost:W W
Types:Creature Human Wizard Types:Creature Human Wizard
PT:1/2 PT:1/2
A:AB$ Pump | Cost$ W T | ValidTgts$ Opponent | TgtPrompt$ Choose target opponent with more life than you | CheckSVar$ X | SVarCompare$ LTY | SubAbility$ LightKeepersLife | StackDescription$ None | References$ X,Y | SpellDescription$ Choose target opponent who had more life than you did as you activated this ability. You gain 3 life. A:AB$ Pump | Cost$ W T | ValidTgts$ Opponent.hasMoreLife | TgtPrompt$ Choose target opponent with more life than you | SubAbility$ LightKeepersLife | StackDescription$ None | SpellDescription$ Choose target opponent who had more life than you did as you activated this ability. You gain 3 life.
SVar:LightKeepersLife:DB$ GainLife | Defined$ You | LifeAmount$ 3 SVar:LightKeepersLife:DB$ GainLife | Defined$ You | LifeAmount$ 3
SVar:X:Count$YourLifeTotal
SVar:Y:Count$OppLifeTotal
SVar:Picture:http://www.wizards.com/global/images/magic/general/keeper_of_the_light.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/keeper_of_the_light.jpg
Oracle:{W}, {T}: Choose target opponent who had more life than you did as you activated this ability. You gain 3 life. Oracle:{W}, {T}: Choose target opponent who had more life than you did as you activated this ability. You gain 3 life.

View File

@@ -10,7 +10,7 @@ SVar:TrigLoseLife:AB$ LoseLife | Cost$ 0 | ValidTgts$ Player | TgtPrompt$ Choose
SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1 SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1
SVar:X:Count$xPaid SVar:X:Count$xPaid
SVar:Y:Count$YourLifeTotal/Minus.Z SVar:Y:Count$YourLifeTotal/Minus.Z
SVar:Z:Count$OppLifeTotal SVar:Z:Count$OppGreatestLifeTotal
SVar:RemAIDeck:True SVar:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/roiling_horror.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/roiling_horror.jpg
Oracle:Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life.\nSuspend X-{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.)\nWhenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. Oracle:Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life.\nSuspend X- {X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.)\nWhenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life.