mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
Merge 253c31f2ab into 520c3a36e5
This commit is contained in:
commit
205e202cb3
4 changed files with 174 additions and 1 deletions
97
Mage.Sets/src/mage/cards/h/HourglassOfTheLost.java
Normal file
97
Mage.Sets/src/mage/cards/h/HourglassOfTheLost.java
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
package mage.cards.h;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.*;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||
import mage.abilities.dynamicvalue.common.GetXValue;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.abilities.mana.WhiteManaAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.ComparisonType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
import mage.filter.common.FilterNonlandCard;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.ManaValuePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author grimreap124
|
||||
*/
|
||||
public final class HourglassOfTheLost extends CardImpl {
|
||||
|
||||
|
||||
public HourglassOfTheLost(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{W}");
|
||||
|
||||
// {T}: Add {W}. Put a time counter on Hourglass of the Lost.
|
||||
Ability ability = new WhiteManaAbility();
|
||||
ability.addEffect(new AddCountersSourceEffect(CounterType.TIME.createInstance()));
|
||||
this.addAbility(ability);
|
||||
// {T}, Remove X time counters from Hourglass of the Lost and exile it: Return each nonland permanent card with mana value X from your graveyard to the battlefield. Activate only as a sorcery.
|
||||
Ability returnAbility = new ActivateAsSorceryActivatedAbility(new HourglassOfTheLostEffect(), null);
|
||||
returnAbility.addCost(new TapSourceCost());
|
||||
returnAbility.addCost(new RemoveVariableCountersSourceCost(CounterType.TIME));
|
||||
returnAbility.addCost(new ExileSourceCost().setText("and exile it"));
|
||||
this.addAbility(returnAbility);
|
||||
}
|
||||
|
||||
private HourglassOfTheLost(final HourglassOfTheLost card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HourglassOfTheLost copy() {
|
||||
return new HourglassOfTheLost(this);
|
||||
}
|
||||
}
|
||||
|
||||
class HourglassOfTheLostEffect extends OneShotEffect {
|
||||
|
||||
HourglassOfTheLostEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Return each nonland permanent card with mana value X from your graveyard to the battlefield.";
|
||||
}
|
||||
|
||||
private HourglassOfTheLostEffect(final HourglassOfTheLostEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HourglassOfTheLostEffect copy() {
|
||||
return new HourglassOfTheLostEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
FilterCard filter = new FilterNonlandCard();
|
||||
int xValue = CardUtil.getSourceCostsTag(game, source, "X", 0);
|
||||
game.informPlayers(xValue + " Time counters removed");
|
||||
filter.add(new ManaValuePredicate(ComparisonType.EQUAL_TO, xValue));
|
||||
return controller.moveCards(controller.getGraveyard().getCards(filter, game), Zone.BATTLEFIELD, source, game);
|
||||
}
|
||||
game.informPlayers("controller is null");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -157,6 +157,7 @@ public final class ModernHorizons3Commander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Hideous Taskmaster", 57, Rarity.RARE, mage.cards.h.HideousTaskmaster.class));
|
||||
cards.add(new SetCardInfo("Horizon of Progress", 78, Rarity.RARE, mage.cards.h.HorizonOfProgress.class));
|
||||
cards.add(new SetCardInfo("Hour of Promise", 232, Rarity.RARE, mage.cards.h.HourOfPromise.class));
|
||||
cards.add(new SetCardInfo("Hourglass of the Lost", 40, Rarity.RARE, mage.cards.h.HourglassOfTheLost.class));
|
||||
cards.add(new SetCardInfo("Hydra Broodmaster", 233, Rarity.RARE, mage.cards.h.HydraBroodmaster.class));
|
||||
cards.add(new SetCardInfo("Hydroid Krasis", 266, Rarity.RARE, mage.cards.h.HydroidKrasis.class));
|
||||
cards.add(new SetCardInfo("Idol of Oblivion", 297, Rarity.UNCOMMON, mage.cards.i.IdolOfOblivion.class));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
package org.mage.test.cards.single.m3c;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public class HourglassOfTheLostTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* {@link mage.cards.h.HourglassOfTheLost HourglassOfTheLost} {2}{U}
|
||||
*/
|
||||
private static final String hourglass = "Hourglass of the Lost";
|
||||
|
||||
@Test
|
||||
public void test_Simple() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, hourglass);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Birds of Paradise"); // Mana value 1
|
||||
addCard(Zone.GRAVEYARD, playerA, "+2 Mace"); // Mana value 2
|
||||
|
||||
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {W}");
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
assertCounterCount(playerA, hourglass, CounterType.TIME,1);
|
||||
assertExileCount(playerA, 0);
|
||||
assertGraveyardCount(playerA, 2);
|
||||
|
||||
setChoiceAmount(playerA, 1); // Remove 1 counter
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}, Remove X"); // Return all with mana value 1
|
||||
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
|
||||
|
||||
execute();
|
||||
assertExileCount(playerA, 1);
|
||||
assertGraveyardCount(playerA, 1); // +2 Mace still in graveyard
|
||||
assertPermanentCount(playerA, "Birds of Paradise", 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -644,7 +644,12 @@ public abstract class AbilityImpl implements Ability {
|
|||
if (!(variableCost instanceof VariableManaCost) && !((Cost) variableCost).isPaid()) {
|
||||
int xValue = variableCost.announceXValue(this, game);
|
||||
Cost fixedCost = variableCost.getFixedCostsFromAnnouncedValue(xValue);
|
||||
int index = getCosts().indexOf(variableCost);
|
||||
if (index == -1) {
|
||||
addCost(fixedCost);
|
||||
} else {
|
||||
addCost(fixedCost, index + 1);
|
||||
}
|
||||
// set the xcosts to paid
|
||||
variableCost.setAmount(xValue, xValue, false);
|
||||
((Cost) variableCost).setPaid();
|
||||
|
|
@ -1076,6 +1081,31 @@ public abstract class AbilityImpl implements Ability {
|
|||
}
|
||||
}
|
||||
|
||||
public void addCost(Cost cost, int index) {
|
||||
if (cost == null) {
|
||||
return;
|
||||
}
|
||||
if (cost instanceof Costs) {
|
||||
// as list of costs
|
||||
Costs<Cost> list = (Costs<Cost>) cost;
|
||||
for (Cost single : list) {
|
||||
addCost(single, index);
|
||||
}
|
||||
} else {
|
||||
// as single cost
|
||||
if (cost instanceof ManaCost) {
|
||||
manaCosts.add((ManaCost) cost);
|
||||
manaCostsToPay.add((ManaCost) cost);
|
||||
} else {
|
||||
if (index > costs.size()) {
|
||||
costs.add(cost);
|
||||
} else {
|
||||
costs.add(index, cost);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addManaCostsToPay(ManaCost manaCost) {
|
||||
if (manaCost == null) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue