mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 10:40:06 -08:00
[TLA] Implement Fire Nation Attacks
This commit is contained in:
parent
b552c850f4
commit
e93d95d7a0
7 changed files with 180 additions and 7 deletions
36
Mage.Sets/src/mage/cards/f/FireNationAttacks.java
Normal file
36
Mage.Sets/src/mage/cards/f/FireNationAttacks.java
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
package mage.cards.f;
|
||||||
|
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
|
import mage.abilities.keyword.FlashbackAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.game.permanent.token.SoldierFirebendingToken;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class FireNationAttacks extends CardImpl {
|
||||||
|
|
||||||
|
public FireNationAttacks(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}");
|
||||||
|
|
||||||
|
// Create two 2/2 red Soldier creature tokens with firebending 1.
|
||||||
|
this.getSpellAbility().addEffect(new CreateTokenEffect(new SoldierFirebendingToken(), 2));
|
||||||
|
|
||||||
|
// Flashback {8}{R}
|
||||||
|
this.addAbility(new FlashbackAbility(this, new ManaCostsImpl<>("{8}{R}")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private FireNationAttacks(final FireNationAttacks card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FireNationAttacks copy() {
|
||||||
|
return new FireNationAttacks(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,6 +23,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet {
|
||||||
|
|
||||||
cards.add(new SetCardInfo("Avatar Enthusiasts", 11, Rarity.COMMON, mage.cards.a.AvatarEnthusiasts.class));
|
cards.add(new SetCardInfo("Avatar Enthusiasts", 11, Rarity.COMMON, mage.cards.a.AvatarEnthusiasts.class));
|
||||||
cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class));
|
cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class));
|
||||||
|
cards.add(new SetCardInfo("Fire Nation Attacks", 133, Rarity.UNCOMMON, mage.cards.f.FireNationAttacks.class));
|
||||||
cards.add(new SetCardInfo("Katara, the Fearless", 230, Rarity.RARE, mage.cards.k.KataraTheFearless.class));
|
cards.add(new SetCardInfo("Katara, the Fearless", 230, Rarity.RARE, mage.cards.k.KataraTheFearless.class));
|
||||||
cards.add(new SetCardInfo("Sokka's Haiku", 71, Rarity.UNCOMMON, mage.cards.s.SokkasHaiku.class));
|
cards.add(new SetCardInfo("Sokka's Haiku", 71, Rarity.UNCOMMON, mage.cards.s.SokkasHaiku.class));
|
||||||
cards.add(new SetCardInfo("Southern Air Temple", 36, Rarity.UNCOMMON, mage.cards.s.SouthernAirTemple.class));
|
cards.add(new SetCardInfo("Southern Air Temple", 36, Rarity.UNCOMMON, mage.cards.s.SouthernAirTemple.class));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
package mage.abilities.keyword;
|
||||||
|
|
||||||
|
import mage.Mana;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.AttacksTriggeredAbility;
|
||||||
|
import mage.abilities.dynamicvalue.DynamicValue;
|
||||||
|
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.players.Player;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public class FirebendingAbility extends AttacksTriggeredAbility {
|
||||||
|
|
||||||
|
private final DynamicValue amount;
|
||||||
|
|
||||||
|
public FirebendingAbility(int amount) {
|
||||||
|
this(StaticValue.get(amount));
|
||||||
|
}
|
||||||
|
|
||||||
|
public FirebendingAbility(DynamicValue amount) {
|
||||||
|
super(new FirebendingAbilityEffect(amount));
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FirebendingAbility(final FirebendingAbility ability) {
|
||||||
|
super(ability);
|
||||||
|
this.amount = ability.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FirebendingAbility copy() {
|
||||||
|
return new FirebendingAbility(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRule() {
|
||||||
|
if (amount instanceof StaticValue) {
|
||||||
|
return "firebending " + amount +
|
||||||
|
" <i>(Whenever this creature attacks, add " +
|
||||||
|
String.join("", Collections.nCopies(((StaticValue) amount).getValue(), "{R}")) +
|
||||||
|
". This mana lasts until end of combat.)</i>";
|
||||||
|
}
|
||||||
|
return "firebending X, where X is " + amount.getMessage() +
|
||||||
|
". <i>(Whenever this creature attacks, add X {R}. This mana lasts until end of combat.)</i>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FirebendingAbilityEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
private final DynamicValue amount;
|
||||||
|
|
||||||
|
FirebendingAbilityEffect(DynamicValue amount) {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FirebendingAbilityEffect(final FirebendingAbilityEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
this.amount = effect.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FirebendingAbilityEffect copy() {
|
||||||
|
return new FirebendingAbilityEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
|
if (player == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int amount = Math.max(this.amount.calculate(game, source, this), 0);
|
||||||
|
if (amount > 0) {
|
||||||
|
player.getManaPool().addMana(Mana.RedMana(amount), game, source, Duration.EndOfCombat);
|
||||||
|
}
|
||||||
|
game.fireEvent(GameEvent.getEvent(
|
||||||
|
GameEvent.EventType.FIREBENDED, source.getSourceId(),
|
||||||
|
source, source.getControllerId(), amount
|
||||||
|
));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -696,6 +696,7 @@ public class GameEvent implements Serializable {
|
||||||
*/
|
*/
|
||||||
PAY_SACRIFICE_COST,
|
PAY_SACRIFICE_COST,
|
||||||
EARTHBENDED,
|
EARTHBENDED,
|
||||||
|
FIREBENDED,
|
||||||
// custom events - must store some unique data to track
|
// custom events - must store some unique data to track
|
||||||
CUSTOM_EVENT;
|
CUSTOM_EVENT;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package mage.game.permanent.token;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.keyword.FirebendingAbility;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class SoldierFirebendingToken extends TokenImpl {
|
||||||
|
|
||||||
|
public SoldierFirebendingToken() {
|
||||||
|
super("Soldier Token", "2/2 red Soldier creature token with firebending 1");
|
||||||
|
cardType.add(CardType.CREATURE);
|
||||||
|
color.setRed(true);
|
||||||
|
subtype.add(SubType.SOLDIER);
|
||||||
|
power = new MageInt(2);
|
||||||
|
toughness = new MageInt(2);
|
||||||
|
this.addAbility(new FirebendingAbility(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private SoldierFirebendingToken(final SoldierFirebendingToken token) {
|
||||||
|
super(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SoldierFirebendingToken copy() {
|
||||||
|
return new SoldierFirebendingToken(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ import mage.abilities.costs.Cost;
|
||||||
import mage.abilities.effects.mana.ManaEffect;
|
import mage.abilities.effects.mana.ManaEffect;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.ManaType;
|
import mage.constants.ManaType;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
import mage.constants.TurnPhase;
|
import mage.constants.TurnPhase;
|
||||||
import mage.filter.Filter;
|
import mage.filter.Filter;
|
||||||
import mage.filter.FilterMana;
|
import mage.filter.FilterMana;
|
||||||
|
|
@ -302,10 +303,18 @@ public class ManaPool implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private int emptyItem(ManaPoolItem item, Emptiable toEmpty, Game game, ManaType manaType) {
|
private int emptyItem(ManaPoolItem item, Emptiable toEmpty, Game game, ManaType manaType) {
|
||||||
if (item.getDuration() == Duration.EndOfTurn
|
switch (item.getDuration()) {
|
||||||
&& game.getTurnPhaseType() != TurnPhase.END) {
|
case EndOfTurn:
|
||||||
|
if (game.getTurnPhaseType() != TurnPhase.END) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case EndOfCombat:
|
||||||
|
if (game.getTurnPhaseType() != TurnPhase.COMBAT
|
||||||
|
|| game.getTurnStepType() != PhaseStep.END_COMBAT) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (manaBecomesBlack) {
|
if (manaBecomesBlack) {
|
||||||
int amount = toEmpty.get(manaType);
|
int amount = toEmpty.get(manaType);
|
||||||
toEmpty.clear(manaType);
|
toEmpty.clear(manaType);
|
||||||
|
|
@ -366,6 +375,10 @@ public class ManaPool implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMana(Mana manaToAdd, Game game, Ability source, boolean dontLoseUntilEOT) {
|
public void addMana(Mana manaToAdd, Game game, Ability source, boolean dontLoseUntilEOT) {
|
||||||
|
addMana(manaToAdd, game, source, dontLoseUntilEOT ? Duration.EndOfTurn : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMana(Mana manaToAdd, Game game, Ability source, Duration duration) {
|
||||||
if (manaToAdd != null) {
|
if (manaToAdd != null) {
|
||||||
Mana mana = manaToAdd.copy();
|
Mana mana = manaToAdd.copy();
|
||||||
if (!game.replaceEvent(new ManaEvent(EventType.ADD_MANA, source.getId(), source, playerId, mana))) {
|
if (!game.replaceEvent(new ManaEvent(EventType.ADD_MANA, source.getId(), source, playerId, mana))) {
|
||||||
|
|
@ -376,8 +389,8 @@ public class ManaPool implements Serializable {
|
||||||
source.getSourceObject(game),
|
source.getSourceObject(game),
|
||||||
conditionalMana.getManaProducerOriginalId() != null ? conditionalMana.getManaProducerOriginalId() : source.getOriginalId()
|
conditionalMana.getManaProducerOriginalId() != null ? conditionalMana.getManaProducerOriginalId() : source.getOriginalId()
|
||||||
);
|
);
|
||||||
if (dontLoseUntilEOT) {
|
if (duration != null) {
|
||||||
item.setDuration(Duration.EndOfTurn);
|
item.setDuration(duration);
|
||||||
}
|
}
|
||||||
this.manaItems.add(item);
|
this.manaItems.add(item);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -392,8 +405,8 @@ public class ManaPool implements Serializable {
|
||||||
source.getOriginalId(),
|
source.getOriginalId(),
|
||||||
mana.getFlag()
|
mana.getFlag()
|
||||||
);
|
);
|
||||||
if (dontLoseUntilEOT) {
|
if (duration != null) {
|
||||||
item.setDuration(Duration.EndOfTurn);
|
item.setDuration(duration);
|
||||||
}
|
}
|
||||||
this.manaItems.add(item);
|
this.manaItems.add(item);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ Exploit|new|
|
||||||
Extort|new|
|
Extort|new|
|
||||||
Fabricate|number|
|
Fabricate|number|
|
||||||
Fear|instance|
|
Fear|instance|
|
||||||
|
Firebending|number|
|
||||||
First strike|instance|
|
First strike|instance|
|
||||||
Flanking|new|
|
Flanking|new|
|
||||||
Flash|instance|
|
Flash|instance|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue