mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
- Convert Master of the Wild Hunt to script
This commit is contained in:
@@ -4,5 +4,12 @@ Types:Creature Human Shaman
|
||||
PT:3/3
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ At the beginning of your upkeep, put a 2/2 green Wolf creature token onto the battlefield.
|
||||
SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Wolf | TokenTypes$ Creature,Wolf | TokenOwner$ You | TokenColors$ Green | TokenPower$ 2 | TokenToughness$ 2
|
||||
A:AB$ DealDamage | Cost$ T | SubAbility$ TapWolves | ValidTgts$ Creature | NumDmg$ 0 | AILogic$ WildHunt | SpellDescription$ Tap all untapped Wolf creatures you control. Each Wolf tapped this way deals damage equal to its power to target creature. That creature deals damage equal to its power divided as its controller chooses among any number of those Wolves. | StackDescription$ Tap all untapped Wolf creatures you control. Each Wolf tapped this way deals damage equal to its power to {c:Targeted}. That creature deals damage equal to its power divided as its controller chooses among any number of those Wolves.
|
||||
SVar:TapWolves:DB$ TapAll | ValidCards$ Creature.Wolf+YouCtrl+untapped | RememberTapped$ True | SubAbility$ WildHuntDamage | StackDescription$ None
|
||||
SVar:WildHuntDamage:DB$ RepeatEach | RepeatSubAbility$ WolfStrike | UseImprinted$ True | RepeatCards$ Card.IsRemembered | SubAbility$ HuntedDamage | StackDescription$ None
|
||||
SVar:WolfStrike:DB$ DealDamage | DamageSource$ Imprinted | NumDmg$ X | References$ X | Defined$ ParentTarget | StackDescription$ None
|
||||
SVar:HuntedDamage:DB$ DealDamage | DamageSource$ ParentTarget | NumDmg$ Y | References$ Y | DividerOnResolution$ ParentTargetedController | Defined$ Remembered | StackDescription$ None
|
||||
SVar:X:Imprinted$CardPower
|
||||
SVar:Y:Targeted$CardPower
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/master_of_the_wild_hunt.jpg
|
||||
Oracle:At the beginning of your upkeep, put a 2/2 green Wolf creature token onto the battlefield.\n{T}: Tap all untapped Wolf creatures you control. Each Wolf tapped this way deals damage equal to its power to target creature. That creature deals damage equal to its power divided as its controller chooses among any number of those Wolves.
|
||||
@@ -744,6 +744,22 @@ public class AbilityUtils {
|
||||
Iterables.addAll(players, saTargeting.getTargets().getTargetPlayers());
|
||||
players.add(sa.getActivatingPlayer());
|
||||
}
|
||||
} else if (defined.equals("ParentTargetedController")) {
|
||||
final List<Card> list = getDefinedCards(card, "ParentTarget", sa);
|
||||
final List<SpellAbility> sas = AbilityUtils.getDefinedSpellAbilities(card, "Targeted", sa);
|
||||
|
||||
for (final Card c : list) {
|
||||
final Player p = c.getController();
|
||||
if (!players.contains(p)) {
|
||||
players.add(p);
|
||||
}
|
||||
}
|
||||
for (final SpellAbility s : sas) {
|
||||
final Player p = s.getActivatingPlayer();
|
||||
if (!players.contains(p)) {
|
||||
players.add(p);
|
||||
}
|
||||
}
|
||||
} else if (defined.equals("Remembered")) {
|
||||
for (final Object rem : card.getRemembered()) {
|
||||
if (rem instanceof Player) {
|
||||
|
||||
@@ -4,10 +4,12 @@ import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.ITargetable;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
@@ -25,6 +27,7 @@ import forge.game.phase.PhaseHandler;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
public class DamageDealAi extends DamageAiBase {
|
||||
@@ -60,8 +63,14 @@ public class DamageDealAi extends DamageAiBase {
|
||||
dmg = ComputerUtilMana.determineLeftoverMana(sa, ai);
|
||||
source.setSVar("PayX", Integer.toString(dmg));
|
||||
}
|
||||
if ("DiscardLands".equals(sa.getParam("AILogic"))) {
|
||||
String logic = sa.getParam("AILogic");
|
||||
|
||||
if ("DiscardLands".equals(logic)) {
|
||||
dmg = 2;
|
||||
} else if ("WildHunt".equals(logic)) {
|
||||
// This dummy ability will just deal 0 damage, but holds the logic for the AI for Master of Wild Hunt
|
||||
List<Card> wolves = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), "Creature.Wolf+untapped+YouCtrl+Other", ai, source);
|
||||
dmg = Aggregates.sum(wolves, CardPredicates.Accessors.fnGetNetAttack);
|
||||
}
|
||||
|
||||
if (dmg <= 0) {
|
||||
@@ -499,5 +508,4 @@ public class DamageDealAi extends DamageAiBase {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package forge.card.ability.effects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardUtil;
|
||||
@@ -72,6 +75,7 @@ public class DamageDealEffect extends SpellAbilityEffect {
|
||||
final boolean noPrevention = sa.hasParam("NoPrevention");
|
||||
final boolean combatDmg = sa.hasParam("CombatDamage");
|
||||
final boolean removeDamage = sa.hasParam("Remove");
|
||||
final boolean divideOnResolution = sa.hasParam("DividerOnResolution");
|
||||
|
||||
List<ITargetable> tgts = getTargets(sa);
|
||||
|
||||
@@ -110,6 +114,31 @@ public class DamageDealEffect extends SpellAbilityEffect {
|
||||
}
|
||||
final Card source = definedSources.get(0);
|
||||
|
||||
if (divideOnResolution) {
|
||||
// Dividing Damage up to multiple targets using combat damage box
|
||||
// Currently only used for Master of the Wild Hutn
|
||||
List<Player> players = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("DividerOnResolution"), sa);
|
||||
if (players.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Card> assigneeCards = new ArrayList<Card>();
|
||||
// Do we have a way of doing this in a better fashion?
|
||||
for(ITargetable obj : tgts) {
|
||||
if (obj instanceof Card) {
|
||||
assigneeCards.add((Card)obj);
|
||||
}
|
||||
}
|
||||
|
||||
Player assigningPlayer = players.get(0);
|
||||
Map<Card, Integer> map = assigningPlayer.getController().assignCombatDamage(source, assigneeCards, dmg, null, true);
|
||||
for (Entry<Card, Integer> dt : map.entrySet()) {
|
||||
dt.getKey().addDamage(dt.getValue(), source);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (final Object o : tgts) {
|
||||
dmg = (sa.usesTargeting() && sa.hasParam("DividedAsYouChoose")) ? sa.getTargetRestrictions().getDividedValue(o) : dmg;
|
||||
if (o instanceof Card) {
|
||||
@@ -158,5 +187,4 @@ public class DamageDealEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -130,162 +130,6 @@ public class CardFactoryCreatures {
|
||||
card.addSpellAbility(ability1);
|
||||
}
|
||||
|
||||
private static void getCard_MasterOfTheWildHunt(final Card card) {
|
||||
final Cost abCost = new Cost("T", true);
|
||||
final TargetRestrictions abTgt = new TargetRestrictions("Target a creature to Hunt", new String[]{"Creature"}, "1", "1");
|
||||
class MasterOfTheWildHuntAbility extends AbilityActivated {
|
||||
public MasterOfTheWildHuntAbility(final Card ca, final Cost co, final TargetRestrictions t) {
|
||||
super(ca, co, t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbilityActivated getCopy() {
|
||||
return new MasterOfTheWildHuntAbility(getSourceCard(),
|
||||
getPayCosts(), new TargetRestrictions(getTargetRestrictions()));
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 35050145102566898L;
|
||||
private final Predicate<Card> untappedCreature = Predicates.and(CardPredicates.Presets.UNTAPPED, CardPredicates.Presets.CREATURES);
|
||||
|
||||
@Override
|
||||
public boolean canPlayAI() {
|
||||
List<Card> wolves = CardLists.getType(getActivatingPlayer().getCardsIn(ZoneType.Battlefield), "Wolf");
|
||||
Iterable<Card> untappedWolves = Iterables.filter(wolves, untappedCreature);
|
||||
|
||||
final int totalPower = Aggregates.sum(untappedWolves, CardPredicates.Accessors.fnGetNetAttack);
|
||||
if (totalPower == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Card> targetables = new ArrayList<Card>(getActivatingPlayer().getOpponent().getCardsIn(ZoneType.Battlefield));
|
||||
|
||||
targetables = CardLists.filter(CardLists.getTargetableCards(targetables, this), new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.isCreature() && (c.getNetDefense() <= totalPower);
|
||||
}
|
||||
});
|
||||
|
||||
if (targetables.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.resetTargets();
|
||||
this.setTargetCard(ComputerUtilCard.getBestCreatureAI(targetables));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolve() {
|
||||
List<Card> wolves = CardLists.getType(card.getController().getCardsIn(ZoneType.Battlefield), "Wolf");
|
||||
wolves = CardLists.filter(wolves, untappedCreature);
|
||||
|
||||
final Card target = this.getTargetCard();
|
||||
|
||||
if (wolves.isEmpty() || !target.canBeTargetedBy(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final Card c : wolves) {
|
||||
c.tap();
|
||||
target.addDamage(c.getNetAttack(), c);
|
||||
}
|
||||
|
||||
if (target.getController().isHuman()) { // Human choose spread damage
|
||||
final Predicate<Card> stillInPlay = new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c){
|
||||
return c.isInPlay();
|
||||
}
|
||||
};
|
||||
final int netAttack = target.getNetAttack();
|
||||
|
||||
for (int points = netAttack; points > 0; points--) {
|
||||
if (!Iterables.any(wolves, stillInPlay)) break;
|
||||
InputSelectCards inp = new InputSelectCardsFromList(1,1,wolves);
|
||||
inp.setMessage(String.format("Select target wolf to damage for %s (%d point%s to allocate)",
|
||||
target, points, points > 1? "s": ""));
|
||||
Singletons.getControl().getInputQueue().setInputAndWait(inp);
|
||||
inp.getSelected().get(0).addDamage(1, target);
|
||||
}
|
||||
} else { // AI Choose spread Damage
|
||||
final List<Card> damageableWolves = CardLists.filter(wolves, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return (ComputerUtilCombat.predictDamageTo(c, target.getNetAttack(), target, false) > 0);
|
||||
}
|
||||
});
|
||||
|
||||
if (damageableWolves.size() == 0) {
|
||||
// can't damage
|
||||
// anything
|
||||
return;
|
||||
}
|
||||
|
||||
List<Card> wolvesLeft = CardLists.filter(damageableWolves, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return !c.hasKeyword("Indestructible");
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < target.getNetAttack(); i++) {
|
||||
wolvesLeft = CardLists.filter(wolvesLeft, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return (ComputerUtilCombat.getDamageToKill(c) > 0)
|
||||
&& ((ComputerUtilCombat.getDamageToKill(c) <= target.getNetAttack()) || target
|
||||
.hasKeyword("Deathtouch"));
|
||||
}
|
||||
});
|
||||
|
||||
// Kill Wolves that can be killed first
|
||||
if (wolvesLeft.size() > 0) {
|
||||
final Card best = ComputerUtilCard.getBestCreatureAI(wolvesLeft);
|
||||
best.addDamage(1, target);
|
||||
if ((ComputerUtilCombat.getDamageToKill(best) <= 0) || target.hasKeyword("Deathtouch")) {
|
||||
wolvesLeft.remove(best);
|
||||
}
|
||||
} else {
|
||||
// Add -1/-1s to Random Indestructibles
|
||||
if (target.hasKeyword("Infect") || target.hasKeyword("Wither")) {
|
||||
final List<Card> indestructibles = CardLists.filter(damageableWolves, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.hasKeyword("Indestructible");
|
||||
}
|
||||
});
|
||||
CardLists.shuffle(indestructibles);
|
||||
indestructibles.get(0).addDamage(1, target);
|
||||
}
|
||||
|
||||
// Then just add Damage randomnly
|
||||
|
||||
else {
|
||||
CardLists.shuffle(damageableWolves);
|
||||
wolves.get(0).addDamage(1, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // resolve()
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("Tap: Tap all untapped Wolf creatures you control. ");
|
||||
sb.append("Each Wolf tapped this way deals damage equal to its ");
|
||||
sb.append("power to target creature. That creature deals damage ");
|
||||
sb.append("equal to its power divided as its controller ");
|
||||
sb.append("chooses among any number of those Wolves.");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
final AbilityActivated ability = new MasterOfTheWildHuntAbility(card, abCost, abTgt);
|
||||
card.addSpellAbility(ability);
|
||||
}
|
||||
|
||||
private static void getCard_SurturedGhoul(final Card card) {
|
||||
final Command intoPlay = new Command() {
|
||||
private static final long serialVersionUID = -75234586897814L;
|
||||
@@ -390,8 +234,6 @@ public class CardFactoryCreatures {
|
||||
|
||||
if (cardName.equals("Sphinx of Jwar Isle")) {
|
||||
getCard_SphinxJwar(card);
|
||||
} else if (cardName.equals("Master of the Wild Hunt")) {
|
||||
getCard_MasterOfTheWildHunt(card);
|
||||
} else if (cardName.equals("Sutured Ghoul")) {
|
||||
getCard_SurturedGhoul(card);
|
||||
} else if (cardName.equals("Phyrexian Dreadnought")) {
|
||||
|
||||
Reference in New Issue
Block a user