Implement offspring mechanic (#12572)

* implement offspring mechanic

* create offspring test
This commit is contained in:
Evan Kranzler 2024-07-12 23:38:29 -04:00 committed by GitHub
parent 6232368162
commit 204f67c5f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 185 additions and 11 deletions

View file

@ -1,26 +1,58 @@
package mage.abilities.keyword;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.StaticAbility;
import mage.abilities.costs.Cost;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.costs.*;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.util.CardUtil;
/**
* @author TheElk801
* TODO: Implement this
*/
public class OffspringAbility extends StaticAbility {
public class OffspringAbility extends StaticAbility implements OptionalAdditionalSourceCosts {
private static final String keywordText = "Offspring";
private static final String reminderText = "You may pay an additional %s as you cast this spell. If you do, when this creature enters, create a 1/1 token copy of it.";
private final String rule;
public static final String OFFSPRING_ACTIVATION_VALUE_KEY = "offspringActivation";
protected OptionalAdditionalCost additionalCost;
public OffspringAbility(String manaString) {
this(new ManaCostsImpl<>(manaString));
}
public OffspringAbility(Cost cost) {
super(Zone.ALL, null);
super(Zone.STACK, null);
this.additionalCost = new OptionalAdditionalCostImpl(
keywordText + ' ' + cost.getText(),
String.format(reminderText, cost.getText()), cost
);
this.additionalCost.setRepeatable(false);
this.rule = additionalCost.getName() + ' ' + additionalCost.getReminderText();
this.setRuleAtTheTop(true);
this.addSubAbility(new ConditionalInterveningIfTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new OffspringEffect()), OffspringCondition.instance,
"When this creature enters, if its offspring cost was paid, create a 1/1 token copy of it."
).setRuleVisible(false));
}
private OffspringAbility(final OffspringAbility ability) {
super(ability);
this.rule = ability.rule;
this.additionalCost = ability.additionalCost.copy();
}
@Override
@ -28,8 +60,73 @@ public class OffspringAbility extends StaticAbility {
return new OffspringAbility(this);
}
@Override
public void addOptionalAdditionalCosts(Ability ability, Game game) {
if (!(ability instanceof SpellAbility)) {
return;
}
Player player = game.getPlayer(ability.getControllerId());
if (player == null) {
return;
}
additionalCost.reset();
if (!additionalCost.canPay(ability, this, ability.getControllerId(), game)
|| !player.chooseUse(Outcome.PutCreatureInPlay, "Pay " + additionalCost.getText(true) + " for offspring?", ability, game)) {
return;
}
additionalCost.activate();
for (Cost cost : ((Costs<Cost>) additionalCost)) {
ability.getCosts().add(cost.copy());
}
ability.setCostsTag(OFFSPRING_ACTIVATION_VALUE_KEY, null);
}
@Override
public String getCastMessageSuffix() {
return additionalCost.getCastSuffixMessage(0);
}
@Override
public String getRule() {
return "Offspring";
return rule;
}
}
class OffspringEffect extends OneShotEffect {
OffspringEffect() {
super(Outcome.Benefit);
}
private OffspringEffect(final OffspringEffect effect) {
super(effect);
}
@Override
public OffspringEffect copy() {
return new OffspringEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = source.getSourcePermanentOrLKI(game);
return permanent != null && new CreateTokenCopyTargetEffect(
null, null, false, 1, false,
false, null, 1, 1, false
).setSavedPermanent(permanent).apply(game, source);
}
}
enum OffspringCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
return CardUtil.checkSourceCostsTagExists(game, source, OffspringAbility.OFFSPRING_ACTIVATION_VALUE_KEY);
}
@Override
public String toString() {
return "Offspring cost was paid";
}
}