mirror of
https://github.com/magefree/mage.git
synced 2025-12-26 05:22:02 -08:00
Fixed handling and initialization of Fixedtarget object. Fixing a problem of ReturnToBattlefieldUnderYourControlTargetEffect that caused objects to return taht already left the zone they should be moved from.
This commit is contained in:
parent
148fd0e6ae
commit
f45c5cedeb
16 changed files with 398 additions and 209 deletions
|
|
@ -1,16 +1,16 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
|
|
@ -20,18 +20,16 @@
|
|||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.constants.Outcome;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
|
@ -69,8 +67,7 @@ public class AttachEffect extends OneShotEffect {
|
|||
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (permanent != null) {
|
||||
return permanent.addAttachment(source.getSourceId(), game);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||
if (player != null) {
|
||||
return player.addAttachment(source.getSourceId(), game);
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
|
|
@ -20,26 +20,22 @@
|
|||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
|
|
@ -49,14 +45,15 @@ import mage.util.CardUtil;
|
|||
public class ReturnToBattlefieldUnderYourControlTargetEffect extends OneShotEffect {
|
||||
|
||||
private boolean fromExileZone;
|
||||
|
||||
|
||||
public ReturnToBattlefieldUnderYourControlTargetEffect() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param fromExileZone - the card will only be returned if it's still in the source object specific exile zone
|
||||
*
|
||||
* @param fromExileZone - the card will only be returned if it's still in
|
||||
* the source object specific exile zone
|
||||
*/
|
||||
public ReturnToBattlefieldUnderYourControlTargetEffect(boolean fromExileZone) {
|
||||
super(Outcome.Benefit);
|
||||
|
|
@ -77,29 +74,18 @@ public class ReturnToBattlefieldUnderYourControlTargetEffect extends OneShotEffe
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
Card card = null;
|
||||
if (controller != null) {
|
||||
Card card = null;
|
||||
if (fromExileZone) {
|
||||
UUID exilZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
|
||||
if (exilZoneId != null) {
|
||||
ExileZone exileZone = game.getExile().getExileZone(exilZoneId);
|
||||
if (exileZone != null && getTargetPointer().getFirst(game, source) != null) {
|
||||
card = exileZone.get(getTargetPointer().getFirst(game, source), game);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
UUID cardId = targetPointer.getFirst(game, source);
|
||||
if(targetPointer instanceof FixedTarget) {
|
||||
UUID fixedTargetCardId = ((FixedTarget) targetPointer).getTarget();
|
||||
//Moved zones from battlefield to graveyard
|
||||
if(fixedTargetCardId != null && cardId == null) {
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(fixedTargetCardId);
|
||||
if(permanent != null) {
|
||||
cardId = fixedTargetCardId;
|
||||
}
|
||||
}
|
||||
}
|
||||
card = game.getCard(cardId);
|
||||
card = game.getCard(getTargetPointer().getFirst(game, source));
|
||||
}
|
||||
if (card != null) {
|
||||
Zone currentZone = game.getState().getZone(card.getId());
|
||||
|
|
|
|||
|
|
@ -1401,6 +1401,9 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
} else {
|
||||
TriggeredAbility newAbility = ability.copy();
|
||||
newAbility.newId();
|
||||
for (Effect effect : newAbility.getEffects()) {
|
||||
effect.getTargetPointer().init(this, newAbility);
|
||||
}
|
||||
state.addTriggeredAbility(newAbility);
|
||||
}
|
||||
}
|
||||
|
|
@ -1409,7 +1412,9 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
public UUID addDelayedTriggeredAbility(DelayedTriggeredAbility delayedAbility) {
|
||||
DelayedTriggeredAbility newAbility = delayedAbility.copy();
|
||||
newAbility.newId();
|
||||
newAbility.init(this);
|
||||
// ability.init is called as the ability triggeres not now.
|
||||
// If a FixedTarget pointer is already set from the effect setting up this delayed ability
|
||||
// it has to be already initialized so it won't be overwitten as the ability triggers
|
||||
state.addDelayedTriggeredAbility(newAbility);
|
||||
return newAbility.getId();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,52 @@
|
|||
package mage.target.targetpointer;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.cards.Card;
|
||||
import mage.game.Game;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.cards.Card;
|
||||
import mage.game.Game;
|
||||
|
||||
public class FixedTarget implements TargetPointer {
|
||||
private final UUID target;
|
||||
|
||||
private final UUID targetId;
|
||||
private int zoneChangeCounter;
|
||||
private boolean initialized;
|
||||
|
||||
public FixedTarget(UUID target) {
|
||||
this.target = target;
|
||||
this.targetId = target;
|
||||
this.initialized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this if you already want to fix the target object to the known zone
|
||||
* now (otherwise the zone will be set if the ability triggers or not at
|
||||
* all) If not initialized, the object of the current zone then will be
|
||||
* used.
|
||||
*
|
||||
* @param targetId
|
||||
* @param zoneChangeCounter
|
||||
*/
|
||||
public FixedTarget(UUID targetId, int zoneChangeCounter) {
|
||||
this.targetId = targetId;
|
||||
this.initialized = true;
|
||||
this.zoneChangeCounter = zoneChangeCounter;
|
||||
}
|
||||
|
||||
public FixedTarget(final FixedTarget fixedTarget) {
|
||||
this.target = fixedTarget.target;
|
||||
this.targetId = fixedTarget.targetId;
|
||||
this.zoneChangeCounter = fixedTarget.zoneChangeCounter;
|
||||
this.initialized = fixedTarget.initialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Game game, Ability source) {
|
||||
Card card = game.getCard(target);
|
||||
if (card != null) {
|
||||
this.zoneChangeCounter = card.getZoneChangeCounter(game);
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
Card card = game.getCard(targetId);
|
||||
if (card != null) {
|
||||
this.zoneChangeCounter = card.getZoneChangeCounter(game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -33,14 +54,14 @@ public class FixedTarget implements TargetPointer {
|
|||
public List<UUID> getTargets(Game game, Ability source) {
|
||||
// check target not changed zone
|
||||
if (this.zoneChangeCounter > 0) { // will be zero if not defined in init
|
||||
Card card = game.getCard(target);
|
||||
Card card = game.getCard(targetId);
|
||||
if (card != null && card.getZoneChangeCounter(game) != this.zoneChangeCounter) {
|
||||
return new ArrayList<>(); // return empty
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<UUID> list = new ArrayList<>(1);
|
||||
list.add(target);
|
||||
list.add(targetId);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
|
@ -48,26 +69,26 @@ public class FixedTarget implements TargetPointer {
|
|||
public UUID getFirst(Game game, Ability source) {
|
||||
// check target not changed zone
|
||||
if (this.zoneChangeCounter > 0) { // will be zero if not defined in init
|
||||
Card card = game.getCard(target);
|
||||
Card card = game.getCard(targetId);
|
||||
if (card != null && card.getZoneChangeCounter(game) != this.zoneChangeCounter) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
return targetId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetPointer copy() {
|
||||
return new FixedTarget(this);
|
||||
}
|
||||
|
||||
|
||||
public UUID getTarget() {
|
||||
return target;
|
||||
return targetId;
|
||||
}
|
||||
|
||||
public int getZoneChangeCounter() {
|
||||
return zoneChangeCounter;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue