mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
Add deterministic ability gain to PermanentImpl.addAbility
This commit is contained in:
parent
82d03b46e3
commit
e20e648a87
5 changed files with 141 additions and 1 deletions
|
|
@ -0,0 +1,104 @@
|
||||||
|
package org.mage.test.cards.single.mat;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jimga150
|
||||||
|
*/
|
||||||
|
public class TyvarTheBellicoseTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link mage.cards.t.TyvarTheBellicose}
|
||||||
|
* Tyvar the Bellicose
|
||||||
|
* {2}{B}{G}
|
||||||
|
* Legendary Creature — Elf Warrior
|
||||||
|
* Whenever one or more Elves you control attack, they gain deathtouch until end of turn.
|
||||||
|
* Each creature you control has “Whenever a mana ability of this creature resolves, put a number of +1/+1
|
||||||
|
* counters on it equal to the amount of mana this creature produced. This ability triggers only once each turn.”
|
||||||
|
* 5/4
|
||||||
|
*/
|
||||||
|
private static final String tyvar = "Tyvar the Bellicose";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link mage.cards.e.EnduringVitality}
|
||||||
|
* <p>
|
||||||
|
* Creatures you control have “{T}: Add one mana of any color.”
|
||||||
|
* 3/3
|
||||||
|
*/
|
||||||
|
private static final String enduringvitality = "Enduring Vitality";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link mage.cards.l.LlanowarElves}
|
||||||
|
* <p>
|
||||||
|
* {T}: Add {G}.
|
||||||
|
* 1/1
|
||||||
|
*/
|
||||||
|
private static final String llanowarelves = "Llanowar Elves";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link mage.cards.a.AkkiDrillmaster}
|
||||||
|
* <p>
|
||||||
|
* {T}: Target creature gains haste until end of turn.
|
||||||
|
* 2/2
|
||||||
|
*/
|
||||||
|
private static final String akkidrillmaster = "Akki Drillmaster";
|
||||||
|
|
||||||
|
private static final String memnite = "Memnite"; // vanilla 1/1
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPrintedAbility() {
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, llanowarelves);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, tyvar);
|
||||||
|
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPowerToughness(playerA, llanowarelves, 2, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNonManaAbility() {
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, akkidrillmaster);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, tyvar);
|
||||||
|
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}");
|
||||||
|
addTarget(playerA, tyvar);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPowerToughness(playerA, akkidrillmaster, 2, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGainedAbility() {
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, enduringvitality);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, memnite);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, tyvar);
|
||||||
|
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}");
|
||||||
|
setChoice(playerA, "Green");
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}");
|
||||||
|
setChoice(playerA, "Green");
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}");
|
||||||
|
setChoice(playerA, "Green");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPowerToughness(playerA, enduringvitality, 4, 4);
|
||||||
|
assertPowerToughness(playerA, memnite, 2, 2);
|
||||||
|
assertPowerToughness(playerA, tyvar, 6, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -38,6 +38,11 @@ public interface Ability extends Controllable, Serializable {
|
||||||
*/
|
*/
|
||||||
void newId();
|
void newId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns a new {@link java.util.UUID} based on the input String. Will always generate the same UUID from a given String.
|
||||||
|
*/
|
||||||
|
void newDeterministicId(String string);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assigns a new {@link java.util.UUID}
|
* Assigns a new {@link java.util.UUID}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,18 @@ public abstract class AbilityImpl implements Ability {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void newDeterministicId(String string) {
|
||||||
|
if (!(this instanceof MageSingleton)) {
|
||||||
|
this.id = UUID.nameUUIDFromBytes(string.getBytes());
|
||||||
|
}
|
||||||
|
getEffects().newId();
|
||||||
|
|
||||||
|
for (Ability sub : getSubAbilities()) {
|
||||||
|
sub.newId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void newOriginalId() {
|
public void newOriginalId() {
|
||||||
this.id = UUID.randomUUID();
|
this.id = UUID.randomUUID();
|
||||||
|
|
|
||||||
|
|
@ -444,7 +444,19 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
||||||
// other abilities -- any amount of instances
|
// other abilities -- any amount of instances
|
||||||
if (!abilities.containsKey(ability.getId())) {
|
if (!abilities.containsKey(ability.getId())) {
|
||||||
Ability copyAbility = ability.copy();
|
Ability copyAbility = ability.copy();
|
||||||
copyAbility.newId(); // needed so that source can get an ability multiple times (e.g. Raging Ravine)
|
|
||||||
|
// needed so that source can get an ability multiple times (e.g. Raging Ravine)
|
||||||
|
// Generate deterministically from sourceId, ability ID, and Permanent's ID
|
||||||
|
// so that future calls to addAbility will always give the resulting ability the same ID
|
||||||
|
String seedString = getId().toString();
|
||||||
|
if (sourceId != null) {
|
||||||
|
seedString += sourceId.toString();
|
||||||
|
}
|
||||||
|
if (ability.getId() != null) {
|
||||||
|
seedString += ability.getId().toString();
|
||||||
|
}
|
||||||
|
copyAbility.newDeterministicId(seedString);
|
||||||
|
|
||||||
copyAbility.setControllerId(controllerId);
|
copyAbility.setControllerId(controllerId);
|
||||||
copyAbility.setSourceId(objectId);
|
copyAbility.setSourceId(objectId);
|
||||||
// triggered abilities must be added to the state().triggers
|
// triggered abilities must be added to the state().triggers
|
||||||
|
|
|
||||||
|
|
@ -488,6 +488,13 @@ public class StackAbility extends StackObjectImpl implements Ability {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void newDeterministicId(String string) {
|
||||||
|
if (!(this instanceof MageSingleton)) {
|
||||||
|
this.ability.newDeterministicId(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void newOriginalId() {
|
public void newOriginalId() {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue