- 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_kaleidoscope.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/didgeridoo.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.ComputerUtilCard;
import forge.ai.SpellAbilityAi;
import forge.game.ability.AbilityUtils;
import forge.game.card.Card;
import forge.game.card.CardLists;
import forge.game.card.CardPredicates.Presets;
@@ -49,6 +50,11 @@ public class CopyPermanentAi extends SpellAbilityAi {
final TargetRestrictions abTgt = sa.getTargetRestrictions();
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 = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source);
list = CardLists.getTargetableCards(list, sa);
@@ -59,7 +65,6 @@ public class CopyPermanentAi extends SpellAbilityAi {
return !vars.containsKey("RemAIDeck");
}
});
sa.resetTargets();
// target loop
while (sa.getTargets().getNumTargeted() < abTgt.getMaxTargets(sa.getHostCard(), sa)) {
if (list.isEmpty()) {

View File

@@ -7,6 +7,7 @@ import forge.ai.ComputerUtilCard;
import forge.ai.ComputerUtilCost;
import forge.ai.SpellAbilityAi;
import forge.game.ability.AbilityUtils;
import forge.game.ability.ApiType;
import forge.game.card.Card;
import forge.game.card.CardLists;
import forge.game.card.CounterType;
@@ -44,6 +45,7 @@ public class DestroyAi extends SpellAbilityAi {
final TargetRestrictions abTgt = sa.getTargetRestrictions();
final Card source = sa.getHostCard();
final boolean noRegen = sa.hasParam("NoRegen");
final String logic = sa.getParam("AILogic");
List<Card> list;
if (abCost != null) {
@@ -66,6 +68,10 @@ public class DestroyAi extends SpellAbilityAi {
// Targeting
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 = CardLists.getTargetableCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), sa);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source);
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 (CardLists.getNotType(list, "Creature").isEmpty()) {
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()) {
choice = ComputerUtilCard.getBestLandAI(list);
} else {
@@ -162,14 +174,12 @@ public class DestroyAi extends SpellAbilityAi {
} else {
if (sa.hasParam("Defined")) {
list = new ArrayList<Card>(AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa));
if (sa.hasParam("AILogic")) {
String logic = sa.getParam("AILogic");
if ("WillSkipTurn".equals(logic) && !sa.getHostCard().getController().equals(ai)
&& (ai.getCreaturesInPlay().size() >= ai.getOpponent().getCreaturesInPlay().size() || ai.getLife() > 5)) {
// Basic ai logic for Lethal Vapors
return true;
}
if ("WillSkipTurn".equals(logic) && !sa.getHostCard().getController().equals(ai)
&& (ai.getCreaturesInPlay().size() >= ai.getOpponent().getCreaturesInPlay().size() || ai.getLife() > 5)) {
// Basic ai logic for Lethal Vapors
return true;
}
if (list.isEmpty()
|| !CardLists.filterControlledBy(list, ai).isEmpty()
|| CardLists.getNotKeyword(list, "Indestructible").isEmpty()) {
@@ -251,7 +261,13 @@ public class DestroyAi extends SpellAbilityAi {
} else {
Card c;
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 {
c = ComputerUtilCard.getCheapestPermanentAI(list, sa, false);
}

View File

@@ -258,6 +258,9 @@ public final class AbilityFactory {
if (mapParams.containsKey("TargetsWithRelatedProperty")) {
abTgt.setRelatedProperty(mapParams.get("TargetsWithRelatedProperty"));
}
if (mapParams.containsKey("TargetingPlayer")) {
abTgt.setMandatory(true);
}
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("\n");
}
if (!sa.getUniqueTargets().isEmpty()) {
sb.append("Parent Targeted:");
sb.append(sa.getUniqueTargets()).append("\n");
}
sb.append(sa.getHostCard() + " - " + tgt.getVTSelection());
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 java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
@@ -139,9 +140,16 @@ public class HumanPlaySpellAbility {
TargetRestrictions tgt = currentAbility.getTargetRestrictions();
if (tgt != null && tgt.doesTarget()) {
clearTargets(currentAbility);
Player targetingPlayer = ability.hasParam("TargetingPlayer") ?
AbilityUtils.getDefinedPlayers(source, ability.getParam("TargetingPlayer"), currentAbility).get(0) : ability.getActivatingPlayer();
Player targetingPlayer;
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))
return false;
}