mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
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:
@@ -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)) {
|
||||||
|
|||||||
@@ -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")) {
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user