mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 21:29:17 -08:00
Fixing aura token creation (#10858)
* rework aura token creation * add missing copy constructor * add message for token if unable to be created * add a few extra role tests
This commit is contained in:
parent
93cfb86a0f
commit
b892562b95
9 changed files with 148 additions and 63 deletions
|
|
@ -42,6 +42,7 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
|||
private final CardType additionalCardType;
|
||||
private SubType additionalSubType;
|
||||
private final UUID attackedPlayer;
|
||||
private UUID attachedTo = null;
|
||||
private final boolean attacking;
|
||||
private boolean becomesArtifact;
|
||||
private ObjectColor color;
|
||||
|
|
@ -134,6 +135,7 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
|||
this.additionalCardType = effect.additionalCardType;
|
||||
this.additionalSubType = effect.additionalSubType;
|
||||
this.attackedPlayer = effect.attackedPlayer;
|
||||
this.attachedTo = effect.attachedTo;
|
||||
this.attacking = effect.attacking;
|
||||
this.becomesArtifact = effect.becomesArtifact;
|
||||
this.color = effect.color;
|
||||
|
|
@ -264,7 +266,7 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
|
||||
token.putOntoBattlefield(number, game, source, playerId == null ? source.getControllerId() : playerId, tapped, attacking, attackedPlayer);
|
||||
token.putOntoBattlefield(number, game, source, playerId == null ? source.getControllerId() : playerId, tapped, attacking, attackedPlayer, attachedTo);
|
||||
for (UUID tokenId : token.getLastAddedTokenIds()) { // by cards like Doubling Season multiple tokens can be added to the battlefield
|
||||
Permanent tokenPermanent = game.getPermanent(tokenId);
|
||||
if (tokenPermanent != null) {
|
||||
|
|
@ -386,6 +388,11 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
|||
return this;
|
||||
}
|
||||
|
||||
public CreateTokenCopyTargetEffect setAttachedTo(UUID attachedTo) {
|
||||
this.attachedTo = attachedTo;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void sacrificeTokensCreatedAtNextEndStep(Game game, Ability source) {
|
||||
this.removeTokensCreatedAtEndOf(game, source, PhaseStep.END_TURN, false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import mage.game.Game;
|
|||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.*;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
|
|
@ -39,15 +38,7 @@ public enum RoleType {
|
|||
|
||||
public Token createToken(Permanent permanent, Game game, Ability source) {
|
||||
Token token = supplier.get();
|
||||
token.putOntoBattlefield(1, game, source);
|
||||
for (UUID tokenId : token.getLastAddedTokenIds()) {
|
||||
Permanent aura = game.getPermanent(tokenId);
|
||||
if (aura == null || !aura.hasSubtype(SubType.AURA, game)) {
|
||||
continue;
|
||||
}
|
||||
aura.getAbilities().get(0).getTargets().get(0).add(permanent.getId(), game);
|
||||
aura.getAbilities().get(0).getEffects().get(0).apply(game, aura.getAbilities().get(0));
|
||||
}
|
||||
token.putOntoBattlefield(1, game, source, source.getControllerId(), false, false, null, permanent.getId());
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,9 @@ public interface Token extends MageObject {
|
|||
|
||||
boolean putOntoBattlefield(int amount, Game game, Ability source, UUID controllerId, boolean tapped, boolean attacking, UUID attackedPlayer);
|
||||
|
||||
boolean putOntoBattlefield(int amount, Game game, Ability source, UUID controllerId, boolean tapped, boolean attacking, UUID attackedPlayer, boolean created);
|
||||
boolean putOntoBattlefield(int amount, Game game, Ability source, UUID controllerId, boolean tapped, boolean attacking, UUID attackedPlayer, UUID attachedTo);
|
||||
|
||||
boolean putOntoBattlefield(int amount, Game game, Ability source, UUID controllerId, boolean tapped, boolean attacking, UUID attackedPlayer, UUID attachedTo, boolean created);
|
||||
|
||||
void setPower(int power);
|
||||
|
||||
|
|
|
|||
|
|
@ -197,11 +197,16 @@ public abstract class TokenImpl extends MageObjectImpl implements Token {
|
|||
|
||||
@Override
|
||||
public boolean putOntoBattlefield(int amount, Game game, Ability source, UUID controllerId, boolean tapped, boolean attacking, UUID attackedPlayer) {
|
||||
return putOntoBattlefield(amount, game, source, controllerId, tapped, attacking, attackedPlayer, true);
|
||||
return putOntoBattlefield(amount, game, source, controllerId, tapped, attacking, attackedPlayer, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putOntoBattlefield(int amount, Game game, Ability source, UUID controllerId, boolean tapped, boolean attacking, UUID attackedPlayer, boolean created) {
|
||||
public boolean putOntoBattlefield(int amount, Game game, Ability source, UUID controllerId, boolean tapped, boolean attacking, UUID attackedPlayer, UUID attachedTo) {
|
||||
return putOntoBattlefield(amount, game, source, controllerId, tapped, attacking, attackedPlayer, attachedTo, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putOntoBattlefield(int amount, Game game, Ability source, UUID controllerId, boolean tapped, boolean attacking, UUID attackedPlayer, UUID attachedTo, boolean created) {
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (controller == null) {
|
||||
return false;
|
||||
|
|
@ -233,7 +238,7 @@ public abstract class TokenImpl extends MageObjectImpl implements Token {
|
|||
it.remove();
|
||||
}
|
||||
}
|
||||
putOntoBattlefieldHelper(event, game, source, tapped, attacking, attackedPlayer, created);
|
||||
putOntoBattlefieldHelper(event, game, source, tapped, attacking, attackedPlayer, attachedTo, created);
|
||||
event.getTokens()
|
||||
.keySet()
|
||||
.stream()
|
||||
|
|
@ -247,7 +252,7 @@ public abstract class TokenImpl extends MageObjectImpl implements Token {
|
|||
return false;
|
||||
}
|
||||
|
||||
private static void putOntoBattlefieldHelper(CreateTokenEvent event, Game game, Ability source, boolean tapped, boolean attacking, UUID attackedPlayer, boolean created) {
|
||||
private static void putOntoBattlefieldHelper(CreateTokenEvent event, Game game, Ability source, boolean tapped, boolean attacking, UUID attackedPlayer, UUID attachedTo, boolean created) {
|
||||
Player controller = game.getPlayer(event.getPlayerId());
|
||||
if (controller == null) {
|
||||
return;
|
||||
|
|
@ -258,6 +263,18 @@ public abstract class TokenImpl extends MageObjectImpl implements Token {
|
|||
Token token = entry.getKey();
|
||||
int amount = entry.getValue();
|
||||
|
||||
// check if token needs to be attached to something
|
||||
Permanent permanentAttachedTo;
|
||||
if (attachedTo != null) {
|
||||
permanentAttachedTo = game.getPermanent(attachedTo);
|
||||
if (permanentAttachedTo == null || permanentAttachedTo.cantBeAttachedBy(token, source, game, true)) {
|
||||
game.informPlayers(token.getName() + " will not be created as it cannot be attached to the chosen permanent");
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
permanentAttachedTo = null;
|
||||
}
|
||||
|
||||
// choose token's set code due source
|
||||
TokenInfo tokenInfo = TokenImpl.generateTokenInfo((TokenImpl) token, game, source == null ? null : source.getSourceId());
|
||||
token.setExpansionSetCode(tokenInfo.getSetCode());
|
||||
|
|
@ -317,7 +334,7 @@ public abstract class TokenImpl extends MageObjectImpl implements Token {
|
|||
// if token was created (not a spell copy) handle auras coming into the battlefield
|
||||
// code blindly copied from CopyPermanentEffect
|
||||
// TODO: clean this up -- half the comments make no sense in the context of creating a token
|
||||
if (created && permanent.getSubtype().contains(SubType.AURA)) {
|
||||
if (created && permanent.getSubtype().contains(SubType.AURA) && attachedTo == null) {
|
||||
Outcome auraOutcome = Outcome.BoostCreature;
|
||||
Target auraTarget = null;
|
||||
|
||||
|
|
@ -375,6 +392,15 @@ public abstract class TokenImpl extends MageObjectImpl implements Token {
|
|||
}
|
||||
// end of aura code : just remove this line if everything works out well
|
||||
|
||||
if (permanentAttachedTo != null) {
|
||||
if (permanent.hasSubtype(SubType.AURA, game)) {
|
||||
permanent.getAbilities().get(0).getTargets().get(0).add(permanentAttachedTo.getId(), game);
|
||||
permanent.getAbilities().get(0).getEffects().get(0).apply(game, permanent.getAbilities().get(0));
|
||||
} else {
|
||||
permanentAttachedTo.addAttachment(permanent.getId(), source, game);
|
||||
}
|
||||
}
|
||||
|
||||
// must attack
|
||||
if (attacking && game.getCombat() != null && game.getActivePlayerId().equals(permanent.getControllerId())) {
|
||||
game.getCombat().addAttackingCreature(permanent.getId(), game, attackedPlayer);
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ public class Spell extends StackObjectImpl implements Card {
|
|||
if (isCopy()) {
|
||||
Token token = CopyTokenFunction.createTokenCopy(card, game, this);
|
||||
// The token that a resolving copy of a spell becomes isn’t said to have been “created.” (2020-09-25)
|
||||
if (token.putOntoBattlefield(1, game, ability, getControllerId(), false, false, null, false)) {
|
||||
if (token.putOntoBattlefield(1, game, ability, getControllerId(), false, false, null, null, false)) {
|
||||
permId = token.getLastAddedTokenIds().stream().findFirst().orElse(null);
|
||||
flag = true;
|
||||
} else {
|
||||
|
|
@ -381,7 +381,7 @@ public class Spell extends StackObjectImpl implements Card {
|
|||
} else if (isCopy()) {
|
||||
Token token = CopyTokenFunction.createTokenCopy(card, game, this);
|
||||
// The token that a resolving copy of a spell becomes isn’t said to have been “created.” (2020-09-25)
|
||||
token.putOntoBattlefield(1, game, ability, getControllerId(), false, false, null, false);
|
||||
token.putOntoBattlefield(1, game, ability, getControllerId(), false, false, null, null, false);
|
||||
return true;
|
||||
} else {
|
||||
return controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue