refactored Player.setLife() to include source, some more changes

This commit is contained in:
Evan Kranzler 2018-04-18 21:14:05 -04:00
parent 2205db105f
commit 3c2a8ee17d
41 changed files with 120 additions and 133 deletions

View file

@ -113,7 +113,7 @@ class AliFromCairoReplacementEffect extends ReplacementEffectImpl {
game.fireEvent(event);
if (controller != null) {
controller.setLife(1, game);
controller.setLife(1, game, source);
}
return true;

View file

@ -97,7 +97,7 @@ class ArbiterOfKnollridgeEffect extends OneShotEffect {
for (UUID pid : playerList) {
Player p = game.getPlayer(pid);
if (p != null) {
p.setLife(maxLife, game);
p.setLife(maxLife, game, source);
}
}
return true;

View file

@ -107,8 +107,8 @@ class AxisOfMortalityEffect extends OneShotEffect {
return false;
}
player1.setLife(lifePlayer2, game);
player2.setLife(lifePlayer1, game);
player1.setLife(lifePlayer2, game, source);
player2.setLife(lifePlayer1, game, source);
return true;
}
return false;

View file

@ -107,8 +107,8 @@ class DarthTyranusEffect extends OneShotEffect {
Player player1 = game.getPlayer(targetPointer.getTargets(game, source).get(0));
Player player2 = game.getPlayer(targetPointer.getTargets(game, source).get(1));
if (player1 != null && player2 != null) {
player1.setLife(5, game);
player1.setLife(30, game);
player1.setLife(5, game, source);
player1.setLife(30, game, source);
return true;
}
return false;

View file

@ -94,7 +94,7 @@ class ElderscaleWurmSetLifeEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
if (player != null && player.getLife() < 7) {
player.setLife(7, game);
player.setLife(7, game, source);
}
return true;

View file

@ -116,7 +116,7 @@ class EternityVesselEffect2 extends OneShotEffect {
Permanent vessel = game.getPermanent(source.getSourceId());
Player controller = game.getPlayer(source.getControllerId());
if (vessel != null && controller != null) {
controller.setLife(vessel.getCounters(game).getCount(CounterType.CHARGE), game);
controller.setLife(vessel.getCounters(game).getCount(CounterType.CHARGE), game, source);
return true;
}
return false;

View file

@ -107,7 +107,7 @@ class EvraHalcyonWitnessEffect extends OneShotEffect {
if (life > amount && !player.isCanLoseLife()) {
return false;
}
player.setLife(amount, game);
player.setLife(amount, game, source);
game.addEffect(new SetPowerToughnessSourceEffect(life, Integer.MIN_VALUE, Duration.Custom, SubLayer.SetPT_7b), source);
return true;
}

View file

@ -104,7 +104,7 @@ class ExquisiteArchangelEffect extends ReplacementEffectImpl {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (player != null && sourcePermanent != null) {
new ExileSourceEffect().apply(game, source);
player.setLife(game.getLife(), game);
player.setLife(game.getLife(), game, source);
return true;
}
return false;

View file

@ -34,25 +34,16 @@ import mage.MageObject;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.GainLifeControllerTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.SimpleTriggeredAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.Card;
import mage.cards.GainAbilitySpellsEffect;
import mage.cards.a.AgelessEntityEffect;
import mage.cards.s.SpiritualFocusDrawCardEffect;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.FilterObject;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.ColorPredicate;
@ -107,6 +98,7 @@ class FiresongAndSunspeakerTriggeredAbility extends TriggeredAbilityImpl {
public FiresongAndSunspeakerTriggeredAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(3), false);
this.addTarget(new TargetCreatureOrPlayer());
}
public FiresongAndSunspeakerTriggeredAbility(final FiresongAndSunspeakerTriggeredAbility ability) {
@ -124,7 +116,7 @@ class FiresongAndSunspeakerTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean applies(GameEvent event, Game game) {
public boolean checkTrigger(GameEvent event, Game game) {
MageObject object = game.getObject(event.getSourceId());
if (object != null && object instanceof Spell) {
if (object.getColor(game).equals(ObjectColor.WHITE)
@ -170,26 +162,6 @@ class GainAbilitySpellsEffect extends ContinuousEffectImpl {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (player != null && permanent != null) {
for (Card card : game.getExile().getAllCards(game)) {
if (card.getOwnerId().equals(source.getControllerId()) && filter.match(card, game)) {
game.getState().addOtherAbility(card, ability);
}
}
for (Card card : player.getLibrary().getCards(game)) {
if (filter.match(card, game)) {
game.getState().addOtherAbility(card, ability);
}
}
for (Card card : player.getHand().getCards(game)) {
if (filter.match(card, game)) {
game.getState().addOtherAbility(card, ability);
}
}
for (Card card : player.getGraveyard().getCards(game)) {
if (filter.match(card, game)) {
game.getState().addOtherAbility(card, ability);
}
}
for (StackObject stackObject : game.getStack()) {
if (stackObject.getControllerId().equals(source.getControllerId())) {
Card card = game.getCard(stackObject.getSourceId());

View file

@ -45,7 +45,7 @@ import mage.target.common.TargetOpponent;
public class GameOfChaos extends CardImpl {
public GameOfChaos(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{R}{R}{R}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}{R}{R}");
// Flip a coin.
// If you win the flip, you gain 1 life and target opponent loses 1 life, and you decide whether to flip again.
@ -66,51 +66,52 @@ public class GameOfChaos extends CardImpl {
}
class GameOfChaosEffect extends OneShotEffect {
public GameOfChaosEffect() {
super(Outcome.Detriment);
this.staticText = "Flip a coin. If you win the flip, you gain 1 life and target opponent loses 1 life, and you decide whether to flip again. If you lose the flip, you lose 1 life and that opponent gains 1 life, and that player decides whether to flip again. Double the life stakes with each flip.";
}
public GameOfChaosEffect(final GameOfChaosEffect effect) {
super(effect);
}
@Override
public GameOfChaosEffect copy() {
return new GameOfChaosEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId());
Player targetOpponent = game.getPlayer(getTargetPointer().getFirst(game, source));
if (you != null && targetOpponent != null) {
boolean continueFlipping = true;
boolean youWonFlip = you.flipCoin(game); // controller flips first
boolean youWonLastFlip = false; // tracks if you won the flip last, negation of it means opponent won last
int lifeAmount = 1; // starts stakes with 1 life
while (continueFlipping) {
while (continueFlipping) {
if (youWonFlip) { // flipper of coin wins, flipper gain 1 and non-flipper loses 1
handleLifeChangesFromFlip(game, you, targetOpponent, lifeAmount);
handleLifeChangesFromFlip(game, you, targetOpponent, lifeAmount, source);
if (!cannotContinueFlipping(you, targetOpponent)) {
continueFlipping = you.chooseUse(outcome, "You gained " + lifeAmount + " life! Flip again for double the life stakes?", source, game);
youWonLastFlip = true;
}
} else { // non-flipper wins, flipper lose 1 and non-flipper gains 1
handleLifeChangesFromFlip(game, targetOpponent, you, lifeAmount);
handleLifeChangesFromFlip(game, targetOpponent, you, lifeAmount, source);
if (!cannotContinueFlipping(you, targetOpponent)) {
continueFlipping = targetOpponent.chooseUse(outcome, "You gained " + lifeAmount + " life! Flip again for double the life stakes?", source, game);
youWonLastFlip = false;
}
}
if (cannotContinueFlipping(you, targetOpponent))
if (cannotContinueFlipping(you, targetOpponent)) {
continueFlipping = false;
}
if (continueFlipping) {
lifeAmount *= 2; // double the life each time
youWonFlip = youWonLastFlip ? you.flipCoin(game) : !targetOpponent.flipCoin(game); // negate the opponent's results for proper evaluation of if you won in next iteration
@ -121,13 +122,13 @@ class GameOfChaosEffect extends OneShotEffect {
}
return false;
}
private void handleLifeChangesFromFlip(Game game, Player playerGainingLife, Player playerLosingLife, int lifeAmount) {
private void handleLifeChangesFromFlip(Game game, Player playerGainingLife, Player playerLosingLife, int lifeAmount, Ability source) {
playerGainingLife.gainLife(lifeAmount, game, source);
playerLosingLife.loseLife(lifeAmount, game, false);
}
private boolean cannotContinueFlipping(Player you, Player opponent) {
return (!you.canRespond() || !opponent.canRespond() || (you.canLoseByZeroOrLessLife() && you.getLife() <= 0) || (opponent.canLoseByZeroOrLessLife() && opponent.getLife() <= 0));
return (!you.canRespond() || !opponent.canRespond() || (you.canLoseByZeroOrLessLife() && you.getLife() <= 0) || (opponent.canLoseByZeroOrLessLife() && opponent.getLife() <= 0));
}
}
}

View file

@ -113,7 +113,7 @@ class LichsMirrorEffect extends ReplacementEffectImpl {
player.drawCards(7, game);
player.setLife(20, game);
player.setLife(20, game, source);
}
return true;
}

View file

@ -90,7 +90,7 @@ class MagisterSphinxEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(source.getFirstTarget());
if (targetPlayer != null) {
targetPlayer.setLife(10, game);
targetPlayer.setLife(10, game, source);
return true;
}
return false;

View file

@ -150,7 +150,7 @@ class MasterOfCrueltiesEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player defendingPlayer = game.getPlayer(game.getCombat().getDefenderId(source.getSourceId()));
if (defendingPlayer != null) {
defendingPlayer.setLife(1, game);
defendingPlayer.setLife(1, game, source);
return true;
}
return false;

View file

@ -87,7 +87,7 @@ class OketrasLastMercyEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
controller.setLife(game.getLife(), game);
controller.setLife(game.getLife(), game, source);
return true;
}
return false;

View file

@ -105,8 +105,8 @@ class PsychicTransferEffect extends OneShotEffect
return false;
}
sourcePlayer.setLife(lifePlayer2, game);
targetPlayer.setLife(lifePlayer1, game);
sourcePlayer.setLife(lifePlayer2, game, source);
targetPlayer.setLife(lifePlayer1, game, source);
return true;
}
return false;

View file

@ -84,7 +84,7 @@ class RepayInKindEffect extends OneShotEffect {
}
for (Player playerId : game.getPlayers().values()) {
if (playerId != null) {
playerId.setLife(lowestLife, game);
playerId.setLife(lowestLife, game, source);
}
}
return true;

View file

@ -93,7 +93,7 @@ class ResoluteArchangelEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
controller.setLife(game.getLife(), game);
controller.setLife(game.getLife(), game, source);
return true;
}
return false;

View file

@ -110,7 +110,7 @@ class ReverseTheSandsEffect extends OneShotEffect {
if (index > 0) {
String lifeString = selectedChoice.substring(0, index);
int life = Integer.parseInt(lifeString);
player.setLife(life, game);
player.setLife(life, game, source);
choices.remove(selectedChoice);
game.informPlayers(new StringBuilder("Player ").append(player.getLogName()).append(" life set to ").append(life).toString());
}

View file

@ -147,7 +147,7 @@ class ShamanOfForgottenWaysEffect extends OneShotEffect {
Player player = game.getPlayer(playerId);
if (player != null){
int numberCreatures = game.getBattlefield().getAllActivePermanents(filter, playerId, game).size();
player.setLife(numberCreatures, game);
player.setLife(numberCreatures, game, source);
}
}
return true;

View file

@ -102,7 +102,7 @@ class SorinMarkovEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(targetPointer.getFirst(game, source));
if (player != null) {
player.setLife(10, game);
player.setLife(10, game, source);
return true;
}
return false;

View file

@ -109,8 +109,8 @@ class SoulConduitEffect extends OneShotEffect {
return false;
}
player1.setLife(lifePlayer2, game);
player2.setLife(lifePlayer1, game);
player1.setLife(lifePlayer2, game, source);
player2.setLife(lifePlayer1, game, source);
return true;
}
return false;

View file

@ -73,7 +73,7 @@ public class SoulfireGrandMaster extends CardImpl {
}
public SoulfireGrandMaster(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.MONK);
this.power = new MageInt(2);
@ -130,26 +130,6 @@ class GainAbilitySpellsEffect extends ContinuousEffectImpl {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (player != null && permanent != null) {
for (Card card : game.getExile().getAllCards(game)) {
if (card.getOwnerId().equals(source.getControllerId()) && filter.match(card, game)) {
game.getState().addOtherAbility(card, ability);
}
}
for (Card card : player.getLibrary().getCards(game)) {
if (filter.match(card, game)) {
game.getState().addOtherAbility(card, ability);
}
}
for (Card card : player.getHand().getCards(game)) {
if (filter.match(card, game)) {
game.getState().addOtherAbility(card, ability);
}
}
for (Card card : player.getGraveyard().getCards(game)) {
if (filter.match(card, game)) {
game.getState().addOtherAbility(card, ability);
}
}
for (StackObject stackObject : game.getStack()) {
if (stackObject.getControllerId().equals(source.getControllerId())) {
Card card = game.getCard(stackObject.getSourceId());
@ -225,7 +205,8 @@ class SoulfireGrandMasterCastFromHandReplacementEffect extends ReplacementEffect
public boolean applies(GameEvent event, Ability source, Game game) {
//Something hit the stack from the hand, see if its a spell with this ability.
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if (spellId == null && // because this effect works only once, spellId has to be null here
if (spellId == null
&& // because this effect works only once, spellId has to be null here
zEvent.getFromZone() == Zone.HAND
&& zEvent.getToZone() == Zone.STACK
&& event.getPlayerId().equals(source.getControllerId())) {

View file

@ -160,7 +160,7 @@ class TorgaarFamineIncarnateEffect extends OneShotEffect {
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
if (targetPlayer != null) {
int startingLifeTotal = game.getLife();
targetPlayer.setLife(startingLifeTotal / 2, game);
targetPlayer.setLife(startingLifeTotal / 2, game, source);
}
return true;
}

View file

@ -84,7 +84,7 @@ class TouchOfTheEternalEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
int permanentsInPlay = game.getBattlefield().countAll(filter, source.getControllerId(), game);
if (player != null) {
player.setLife(permanentsInPlay, game);
player.setLife(permanentsInPlay, game, source);
return true;
}
return false;

View file

@ -104,7 +104,7 @@ class TreeOfPerditionEffect extends OneShotEffect {
if (life > amount && !opponent.isCanLoseLife()) {
return false;
}
opponent.setLife(amount, game);
opponent.setLife(amount, game, source);
perm.getToughness().modifyBaseValue(life);
// game.addEffect(new SetPowerToughnessSourceEffect(Integer.MIN_VALUE, life, Duration.Custom, SubLayer.SetPT_7b), source);
return true;

View file

@ -104,7 +104,7 @@ class TreeOfRedemptionEffect extends OneShotEffect {
if (life > amount && !player.isCanLoseLife()) {
return false;
}
player.setLife(amount, game);
player.setLife(amount, game, source);
game.addEffect(new SetPowerToughnessSourceEffect(Integer.MIN_VALUE, life, Duration.Custom, SubLayer.SetPT_7b), source);
return true;
}

View file

@ -129,7 +129,7 @@ class VraskaRelicSeekerLifeTotalEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(targetPointer.getFirst(game, source));
if (player != null) {
player.setLife(1, game);
player.setLife(1, game, source);
return true;
}
return false;

View file

@ -101,7 +101,7 @@ class WorldfireEffect extends OneShotEffect {
c.moveToExile(null, null, source.getSourceId(), game);
}
}
player.setLife(1, game);
player.setLife(1, game, source);
}
}
return true;

View file

@ -1,5 +1,6 @@
package org.mage.test.cards.single.vis;
import java.util.UUID;
import mage.game.permanent.Permanent;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@ -19,7 +20,7 @@ public class BroodOfCockroachesTest extends CardTestPlayerBase {
@Test
public void should_display_correct_text() {
String expectedText = "When {this} dies, at the beginning of the next end step, you lose 1 life and return Brood of Cockroaches to your hand.";
String expectedText = "When {this} dies, at the beginning of the next end step, you lose 1 life and return Brood of Cockroaches to your hand.";
playerA_casts_Brood_of_Cockroaches_at_precombat_main_phase();
@ -33,7 +34,7 @@ public class BroodOfCockroachesTest extends CardTestPlayerBase {
@Test
public void should_reduce_life_of_playerA_by_1_at_the_beginning_of_the_next_end_step() {
playerA.setLife(ANY_LIFE_TOTAL, currentGame);
playerA.setLife(ANY_LIFE_TOTAL, currentGame, UUID.randomUUID());
playerA_casts_Brood_of_Cockroaches_at_precombat_main_phase();
@ -47,7 +48,7 @@ public class BroodOfCockroachesTest extends CardTestPlayerBase {
@Test
public void should_not_reduce_life_of_playerA_by_1_at_post_combat_main_step() {
playerA.setLife(ANY_LIFE_TOTAL, currentGame);
playerA.setLife(ANY_LIFE_TOTAL, currentGame, UUID.randomUUID());
playerA_casts_Brood_of_Cockroaches_at_precombat_main_phase();
@ -56,12 +57,12 @@ public class BroodOfCockroachesTest extends CardTestPlayerBase {
setStopAt(TURN_1, PRECOMBAT_MAIN);
execute();
assertLife(playerA, ANY_LIFE_TOTAL );
assertLife(playerA, ANY_LIFE_TOTAL);
}
@Test
public void should_return_Brood_of_Cockroaches_to_playerA_hand_end_of_turn() {
playerA.setLife(ANY_LIFE_TOTAL, currentGame);
playerA.setLife(ANY_LIFE_TOTAL, currentGame, UUID.randomUUID());
playerA_casts_Brood_of_Cockroaches_at_precombat_main_phase();
@ -75,7 +76,7 @@ public class BroodOfCockroachesTest extends CardTestPlayerBase {
@Test
public void should_not_return_Brood_of_Cockroaches_to_playerA_at_post_combat_step() {
playerA.setLife(ANY_LIFE_TOTAL, currentGame);
playerA.setLife(ANY_LIFE_TOTAL, currentGame, UUID.randomUUID());
playerA_casts_Brood_of_Cockroaches_at_precombat_main_phase();
@ -87,7 +88,6 @@ public class BroodOfCockroachesTest extends CardTestPlayerBase {
assertHandCount(playerA, BROOD_OF_COCKROACHES, 0);
}
private void brood_of_cockroaches_diesat_precombat_main_phase() {
addCard(BATTLEFIELD, playerB, "Mountain", 1);
addCard(HAND, playerB, SHOCK, 1);
@ -100,5 +100,4 @@ public class BroodOfCockroachesTest extends CardTestPlayerBase {
castSpell(TURN_1, PRECOMBAT_MAIN, playerA, BROOD_OF_COCKROACHES);
}
}

View file

@ -1547,8 +1547,13 @@ public class TestPlayer implements Player {
}
@Override
public void setLife(int life, Game game) {
computerPlayer.setLife(life, game);
public void setLife(int life, Game game, UUID sourceId) {
computerPlayer.setLife(life, game, sourceId);
}
@Override
public void setLife(int life, Game game, Ability source) {
computerPlayer.setLife(life, game, source);
}
@Override
@ -1593,7 +1598,12 @@ public class TestPlayer implements Player {
@Override
public int gainLife(int amount, Game game, Ability source) {
return computerPlayer.gainLife(amount, game);
return computerPlayer.gainLife(amount, game, source);
}
@Override
public int gainLife(int amount, Game game, UUID sourceId) {
return computerPlayer.gainLife(amount, game, sourceId);
}
@Override

View file

@ -140,7 +140,12 @@ public class PlayerStub implements Player {
}
@Override
public void setLife(int life, Game game) {
public void setLife(int life, Game game, Ability source) {
}
@Override
public void setLife(int life, Game game, UUID sourceId) {
}
@ -154,6 +159,11 @@ public class PlayerStub implements Player {
return 0;
}
@Override
public int gainLife(int amount, Game game, UUID sourceId) {
return 0;
}
@Override
public int damage(int damage, UUID sourceId, Game game, boolean combatDamage, boolean preventable) {
return 0;

View file

@ -67,7 +67,7 @@ public class GainLifeOpponentCost extends CostImpl {
if (controller.chooseTarget(Outcome.Detriment, target, ability, game)) {
Player opponent = game.getPlayer(target.getFirstTarget());
if (opponent != null) {
opponent.gainLife(amount, game, source);
opponent.gainLife(amount, game, sourceId);
paid = true;
}

View file

@ -78,7 +78,7 @@ public class GainLifePlayersCost extends CostImpl {
if (!playerId.equals(controllerId)) {
Player player = game.getPlayer(playerId);
if (player != null) {
player.gainLife(amount, game, source);
player.gainLife(amount, game, sourceId);
}
}
}

View file

@ -77,8 +77,8 @@ public class ExchangeLifeTargetEffect extends OneShotEffect {
return false;
}
controller.setLife(lifePlayer, game);
player.setLife(lifeController, game);
controller.setLife(lifePlayer, game, source);
player.setLife(lifeController, game, source);
return true;
}
return false;

View file

@ -62,7 +62,7 @@ public class SetPlayerLifeAllEffect extends OneShotEffect {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
player.setLife(amount.calculate(game, source, this), game);
player.setLife(amount.calculate(game, source, this), game, source);
}
}
break;
@ -70,7 +70,7 @@ public class SetPlayerLifeAllEffect extends OneShotEffect {
for (UUID playerId : game.getOpponents(controller.getId())) {
Player player = game.getPlayer(playerId);
if (player != null) {
player.setLife(amount.calculate(game, source, this), game);
player.setLife(amount.calculate(game, source, this), game, source);
}
}
break;

View file

@ -45,7 +45,7 @@ public class SetPlayerLifeSourceEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
player.setLife(amount.calculate(game, source, this), game);
player.setLife(amount.calculate(game, source, this), game, source);
return true;
}
return false;

View file

@ -67,7 +67,7 @@ public class SetPlayerLifeTargetEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(targetPointer.getFirst(game, source));
if (player != null) {
player.setLife(amount.calculate(game, source, this), game);
player.setLife(amount.calculate(game, source, this), game, source);
return true;
}
return false;

View file

@ -1565,14 +1565,14 @@ public abstract class GameImpl implements Game, Serializable {
}
state.addCommandObject(newPlane);
informPlayers("You have planeswalked to " + newPlane.getLogName());
// Fire off the planeswalked event
GameEvent event = new GameEvent(GameEvent.EventType.PLANESWALK, newPlane.getId(), null, newPlane.getId(), 0, true);
if (!replaceEvent(event)) {
GameEvent ge = new GameEvent(GameEvent.EventType.PLANESWALKED, newPlane.getId(), null, newPlane.getId(), 0, true);
fireEvent(ge);
}
return true;
}
@ -2821,7 +2821,7 @@ public abstract class GameImpl implements Game, Serializable {
if (s.length == 2) {
try {
Integer amount = Integer.parseInt(s[1]);
player.setLife(amount, this);
player.setLife(amount, this, ownerId);
logger.info("Setting player's life: ");
} catch (NumberFormatException e) {
logger.fatal("error setting life", e);

View file

@ -785,7 +785,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
if (source != null && sourceAbilities != null) {
if (sourceAbilities.containsKey(LifelinkAbility.getInstance().getId())) {
Player player = game.getPlayer(sourceControllerId);
player.gainLife(damageDone, game, source);
player.gainLife(damageDone, game, sourceId);
}
if (sourceAbilities.containsKey(DeathtouchAbility.getInstance().getId())) {
deathtouched = true;
@ -946,8 +946,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
}
}
if (abilities.containsKey(HexproofFromBlackAbility.getInstance().getId()) ) {
if (abilities.containsKey(HexproofFromBlackAbility.getInstance().getId())) {
if (game.getPlayer(this.getControllerId()).hasOpponent(sourceControllerId, game)
&& !game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, sourceControllerId, game)
&& source.getColor(game).isBlack()) {
@ -955,7 +954,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
}
}
if (abilities.containsKey(HexproofFromWhiteAbility.getInstance().getId()) ) {
if (abilities.containsKey(HexproofFromWhiteAbility.getInstance().getId())) {
if (game.getPlayer(this.getControllerId()).hasOpponent(sourceControllerId, game)
&& !game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, sourceControllerId, game)
&& source.getColor(game).isWhite()) {

View file

@ -112,7 +112,9 @@ public interface Player extends MageItem, Copyable<Player> {
void initLife(int life);
void setLife(int life, Game game);
void setLife(int life, Game game, Ability source);
void setLife(int life, Game game, UUID sourceId);
/**
*
@ -125,6 +127,8 @@ public interface Player extends MageItem, Copyable<Player> {
int gainLife(int amount, Game game, Ability source);
int gainLife(int amount, Game game, UUID sourceId);
int damage(int damage, UUID sourceId, Game game, boolean combatDamage, boolean preventable);
int damage(int damage, UUID sourceId, Game game, boolean combatDamage, boolean preventable, List<UUID> appliedEffects);
@ -427,6 +431,7 @@ public interface Player extends MageItem, Copyable<Player> {
PlanarDieRoll rollPlanarDie(Game game);
PlanarDieRoll rollPlanarDie(Game game, ArrayList<UUID> appliedEffects);
PlanarDieRoll rollPlanarDie(Game game, ArrayList<UUID> appliedEffects, int numberChaosSides, int numberPlanarSides);
@Deprecated

View file

@ -31,6 +31,7 @@ import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import static jdk.nashorn.internal.objects.NativeRegExp.source;
import mage.ConditionalMana;
import mage.MageObject;
import mage.Mana;
@ -439,7 +440,7 @@ public abstract class PlayerImpl implements Player, Serializable {
this.canLoseLife = true;
this.topCardRevealed = false;
this.payManaMode = false;
this.setLife(game.getLife(), game);
this.setLife(game.getLife(), game, UUID.randomUUID());
this.setReachedNextTurnAfterLeaving(false);
this.castSourceIdWithAlternateMana = null;
@ -1741,10 +1742,15 @@ public abstract class PlayerImpl implements Player, Serializable {
}
@Override
public void setLife(int life, Game game) {
public void setLife(int life, Game game, Ability source) {
setLife(life, game, source.getSourceId());
}
@Override
public void setLife(int life, Game game, UUID sourceId) {
// rule 118.5
if (life > this.life) {
gainLife(life - this.life, game, source);
gainLife(life - this.life, game, sourceId);
} else if (life < this.life) {
loseLife(this.life - life, game, false);
}
@ -1808,6 +1814,10 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public int gainLife(int amount, Game game, Ability source) {
return gainLife(amount, game, source.getSourceId());
}
public int gainLife(int amount, Game game, UUID sourceId) {
if (!canGainLife || amount == 0) {
return 0;
}
@ -1820,7 +1830,7 @@ public abstract class PlayerImpl implements Player, Serializable {
if (!game.isSimulation()) {
game.informPlayers(this.getLogName() + " gains " + event.getAmount() + " life");
}
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.GAINED_LIFE, playerId, source.getSourceId(), playerId, event.getAmount()));
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.GAINED_LIFE, playerId, sourceId, playerId, event.getAmount()));
return event.getAmount();
}
return 0;
@ -1879,7 +1889,7 @@ public abstract class PlayerImpl implements Player, Serializable {
}
if (sourceAbilities != null && sourceAbilities.containsKey(LifelinkAbility.getInstance().getId())) {
Player player = game.getPlayer(sourceControllerId);
player.gainLife(actualDamage, game, source);
player.gainLife(actualDamage, game, sourceId);
}
// Unstable ability - Earl of Squirrel
if (sourceAbilities != null && sourceAbilities.containsKey(SquirrellinkAbility.getInstance().getId())) {