- Added Diaochan, Artful Beauty

This commit is contained in:
swordshine
2014-03-05 05:08:04 +00:00
parent 34c2d37b46
commit cd45fd824d
7 changed files with 57 additions and 13 deletions

1
.gitattributes vendored
View File

@@ -3495,6 +3495,7 @@ forge-gui/res/cardsfolder/d/diamond_faerie.txt svneol=native#text/plain
forge-gui/res/cardsfolder/d/diamond_faerie_avatar.txt -text forge-gui/res/cardsfolder/d/diamond_faerie_avatar.txt -text
forge-gui/res/cardsfolder/d/diamond_kaleidoscope.txt svneol=native#text/plain forge-gui/res/cardsfolder/d/diamond_kaleidoscope.txt svneol=native#text/plain
forge-gui/res/cardsfolder/d/diamond_valley.txt svneol=native#text/plain forge-gui/res/cardsfolder/d/diamond_valley.txt svneol=native#text/plain
forge-gui/res/cardsfolder/d/diaochan_artful_beauty.txt -text
forge-gui/res/cardsfolder/d/dichotomancy.txt -text forge-gui/res/cardsfolder/d/dichotomancy.txt -text
forge-gui/res/cardsfolder/d/didgeridoo.txt svneol=native#text/plain forge-gui/res/cardsfolder/d/didgeridoo.txt svneol=native#text/plain
forge-gui/res/cardsfolder/d/diligent_farmhand.txt svneol=native#text/plain forge-gui/res/cardsfolder/d/diligent_farmhand.txt svneol=native#text/plain

View File

@@ -4,6 +4,7 @@ import com.google.common.base.Predicate;
import forge.ai.ComputerUtil; import forge.ai.ComputerUtil;
import forge.ai.ComputerUtilCard; import forge.ai.ComputerUtilCard;
import forge.ai.SpellAbilityAi; import forge.ai.SpellAbilityAi;
import forge.game.ability.AbilityUtils;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardLists; import forge.game.card.CardLists;
import forge.game.card.CardPredicates.Presets; import forge.game.card.CardPredicates.Presets;
@@ -49,6 +50,11 @@ public class CopyPermanentAi extends SpellAbilityAi {
final TargetRestrictions abTgt = sa.getTargetRestrictions(); final TargetRestrictions abTgt = sa.getTargetRestrictions();
if (abTgt != null) { if (abTgt != null) {
sa.resetTargets();
if (sa.hasParam("TargetingPlayer")) {
Player targetingPlayer = AbilityUtils.getDefinedPlayers(source, sa.getParam("TargetingPlayer"), sa).get(0);
return targetingPlayer.getController().chooseTargetsFor(sa);
}
List<Card> list = aiPlayer.getGame().getCardsIn(ZoneType.Battlefield); List<Card> list = aiPlayer.getGame().getCardsIn(ZoneType.Battlefield);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source); list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source);
list = CardLists.getTargetableCards(list, sa); list = CardLists.getTargetableCards(list, sa);
@@ -59,7 +65,6 @@ public class CopyPermanentAi extends SpellAbilityAi {
return !vars.containsKey("RemAIDeck"); return !vars.containsKey("RemAIDeck");
} }
}); });
sa.resetTargets();
// target loop // target loop
while (sa.getTargets().getNumTargeted() < abTgt.getMaxTargets(sa.getHostCard(), sa)) { while (sa.getTargets().getNumTargeted() < abTgt.getMaxTargets(sa.getHostCard(), sa)) {
if (list.isEmpty()) { if (list.isEmpty()) {

View File

@@ -7,6 +7,7 @@ import forge.ai.ComputerUtilCard;
import forge.ai.ComputerUtilCost; import forge.ai.ComputerUtilCost;
import forge.ai.SpellAbilityAi; import forge.ai.SpellAbilityAi;
import forge.game.ability.AbilityUtils; import forge.game.ability.AbilityUtils;
import forge.game.ability.ApiType;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardLists; import forge.game.card.CardLists;
import forge.game.card.CounterType; import forge.game.card.CounterType;
@@ -44,6 +45,7 @@ public class DestroyAi extends SpellAbilityAi {
final TargetRestrictions abTgt = sa.getTargetRestrictions(); final TargetRestrictions abTgt = sa.getTargetRestrictions();
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
final boolean noRegen = sa.hasParam("NoRegen"); final boolean noRegen = sa.hasParam("NoRegen");
final String logic = sa.getParam("AILogic");
List<Card> list; List<Card> list;
if (abCost != null) { if (abCost != null) {
@@ -66,6 +68,10 @@ public class DestroyAi extends SpellAbilityAi {
// Targeting // Targeting
if (abTgt != null) { if (abTgt != null) {
sa.resetTargets(); sa.resetTargets();
if (sa.hasParam("TargetingPlayer")) {
Player targetingPlayer = AbilityUtils.getDefinedPlayers(source, sa.getParam("TargetingPlayer"), sa).get(0);
return targetingPlayer.getController().chooseTargetsFor(sa);
}
list = CardLists.getTargetableCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), sa); list = CardLists.getTargetableCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), sa);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source); list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source);
if (sa.hasParam("AITgts")) { if (sa.hasParam("AITgts")) {
@@ -129,6 +135,12 @@ public class DestroyAi extends SpellAbilityAi {
// If the targets are only of one type, take the best // If the targets are only of one type, take the best
if (CardLists.getNotType(list, "Creature").isEmpty()) { if (CardLists.getNotType(list, "Creature").isEmpty()) {
choice = ComputerUtilCard.getBestCreatureAI(list); choice = ComputerUtilCard.getBestCreatureAI(list);
if ("OppDestroyYours".equals(logic)) {
Card aiBest = ComputerUtilCard.getBestCreatureAI(ai.getCreaturesInPlay());
if (ComputerUtilCard.evaluateCreature(aiBest) > ComputerUtilCard.evaluateCreature(choice) - 40) {
return false;
}
}
} else if (CardLists.getNotType(list, "Land").isEmpty()) { } else if (CardLists.getNotType(list, "Land").isEmpty()) {
choice = ComputerUtilCard.getBestLandAI(list); choice = ComputerUtilCard.getBestLandAI(list);
} else { } else {
@@ -162,14 +174,12 @@ public class DestroyAi extends SpellAbilityAi {
} else { } else {
if (sa.hasParam("Defined")) { if (sa.hasParam("Defined")) {
list = new ArrayList<Card>(AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa)); list = new ArrayList<Card>(AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa));
if (sa.hasParam("AILogic")) { if ("WillSkipTurn".equals(logic) && !sa.getHostCard().getController().equals(ai)
String logic = sa.getParam("AILogic"); && (ai.getCreaturesInPlay().size() >= ai.getOpponent().getCreaturesInPlay().size() || ai.getLife() > 5)) {
if ("WillSkipTurn".equals(logic) && !sa.getHostCard().getController().equals(ai) // Basic ai logic for Lethal Vapors
&& (ai.getCreaturesInPlay().size() >= ai.getOpponent().getCreaturesInPlay().size() || ai.getLife() > 5)) { return true;
// Basic ai logic for Lethal Vapors
return true;
}
} }
if (list.isEmpty() if (list.isEmpty()
|| !CardLists.filterControlledBy(list, ai).isEmpty() || !CardLists.filterControlledBy(list, ai).isEmpty()
|| CardLists.getNotKeyword(list, "Indestructible").isEmpty()) { || CardLists.getNotKeyword(list, "Indestructible").isEmpty()) {
@@ -251,7 +261,13 @@ public class DestroyAi extends SpellAbilityAi {
} else { } else {
Card c; Card c;
if (CardLists.getNotType(list, "Creature").isEmpty()) { if (CardLists.getNotType(list, "Creature").isEmpty()) {
c = ComputerUtilCard.getWorstCreatureAI(list); if (!sa.getUniqueTargets().isEmpty() && sa.getParent().getApi() == ApiType.Destroy
&& sa.getUniqueTargets().get(0) instanceof Card) {
// basic ai for Diaochan
c = (Card) sa.getUniqueTargets().get(0);
} else {
c = ComputerUtilCard.getWorstCreatureAI(list);
}
} else { } else {
c = ComputerUtilCard.getCheapestPermanentAI(list, sa, false); c = ComputerUtilCard.getCheapestPermanentAI(list, sa, false);
} }

View File

@@ -258,6 +258,9 @@ public final class AbilityFactory {
if (mapParams.containsKey("TargetsWithRelatedProperty")) { if (mapParams.containsKey("TargetsWithRelatedProperty")) {
abTgt.setRelatedProperty(mapParams.get("TargetsWithRelatedProperty")); abTgt.setRelatedProperty(mapParams.get("TargetsWithRelatedProperty"));
} }
if (mapParams.containsKey("TargetingPlayer")) {
abTgt.setMandatory(true);
}
return abTgt; return abTgt;
} }

View File

@@ -0,0 +1,8 @@
Name:Diaochan, Artful Beauty
ManaCost:3 R
Types:Legendary Creature Human Advisor
PT:1/1
A:AB$ Destroy | Cost$ T | ValidTgts$ Creature | SubAbility$ DBDestroy | AILogic$ OppDestroyYours | PlayerTurn$ True | ActivationPhases$ Upkeep->BeginCombat | SpellDescription$ Destroy target creature of your choice, then destroy target creature of an opponent's choice. Activate this ability only during your turn, before attackers are declared.
SVar:DBDestroy:DB$ Destroy | ValidTgts$ Creature | TargetingPlayer$ Opponent
SVar:Picture:http://www.wizards.com/global/images/magic/general/diaochan_artful_beauty.jpg
Oracle:{T}: Destroy target creature of your choice, then destroy target creature of an opponent's choice. Activate this ability only during your turn, before attackers are declared.

View File

@@ -61,7 +61,10 @@ public final class InputSelectTargets extends InputSyncronizedBase {
sb.append(" (").append(o.getValue()).append(" times)"); sb.append(" (").append(o.getValue()).append(" times)");
sb.append("\n"); sb.append("\n");
} }
if (!sa.getUniqueTargets().isEmpty()) {
sb.append("Parent Targeted:");
sb.append(sa.getUniqueTargets()).append("\n");
}
sb.append(sa.getHostCard() + " - " + tgt.getVTSelection()); sb.append(sa.getHostCard() + " - " + tgt.getVTSelection());
int maxTargets = tgt.getMaxTargets(sa.getHostCard(), sa); int maxTargets = tgt.getMaxTargets(sa.getHostCard(), sa);

View File

@@ -39,6 +39,7 @@ import forge.game.zone.Zone;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@@ -139,8 +140,15 @@ public class HumanPlaySpellAbility {
TargetRestrictions tgt = currentAbility.getTargetRestrictions(); TargetRestrictions tgt = currentAbility.getTargetRestrictions();
if (tgt != null && tgt.doesTarget()) { if (tgt != null && tgt.doesTarget()) {
clearTargets(currentAbility); clearTargets(currentAbility);
Player targetingPlayer = ability.hasParam("TargetingPlayer") ? Player targetingPlayer;
AbilityUtils.getDefinedPlayers(source, ability.getParam("TargetingPlayer"), currentAbility).get(0) : ability.getActivatingPlayer(); if (currentAbility.hasParam("TargetingPlayer")) {
List<Player> candidates = AbilityUtils.getDefinedPlayers(source, currentAbility.getParam("TargetingPlayer"), currentAbility);
// activator chooses targeting player
targetingPlayer = ability.getActivatingPlayer().getController().chooseSingleEntityForEffect(
candidates, currentAbility, "Choose the targeting player");
} else {
targetingPlayer = ability.getActivatingPlayer();
}
if (!targetingPlayer.getController().chooseTargetsFor(currentAbility)) if (!targetingPlayer.getController().chooseTargetsFor(currentAbility))
return false; return false;