mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
- Adding the three "Opponent Chooses" modal spells from Alliances. If the Human casts one, the AI will currently choose the "least harmful" fork of the mode for now, this is a static "decision".
This commit is contained in:
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -3469,6 +3469,7 @@ res/cardsfolder/f/fastbond.txt svneol=native#text/plain
|
||||
res/cardsfolder/f/fatal_attraction.txt svneol=native#text/plain
|
||||
res/cardsfolder/f/fatal_blow.txt svneol=native#text/plain
|
||||
res/cardsfolder/f/fatal_frenzy.txt svneol=native#text/plain
|
||||
res/cardsfolder/f/fatal_lore.txt -text
|
||||
res/cardsfolder/f/fatal_mutation.txt svneol=native#text/plain
|
||||
res/cardsfolder/f/fatestitcher.txt svneol=native#text/plain
|
||||
res/cardsfolder/f/fathom_mage.txt -text
|
||||
@@ -5975,6 +5976,7 @@ res/cardsfolder/l/liability.txt svneol=native#text/plain
|
||||
res/cardsfolder/l/liberate.txt svneol=native#text/plain
|
||||
res/cardsfolder/l/liberated_dwarf.txt svneol=native#text/plain
|
||||
res/cardsfolder/l/library_of_alexandria.txt svneol=native#text/plain
|
||||
res/cardsfolder/l/library_of_lat_nam.txt -text
|
||||
res/cardsfolder/l/library_of_leng.txt -text
|
||||
res/cardsfolder/l/lich.txt svneol=native#text/plain
|
||||
res/cardsfolder/l/lich_lord_of_unx.txt svneol=native#text/plain
|
||||
@@ -6684,6 +6686,7 @@ res/cardsfolder/m/mischievous_poltergeist.txt svneol=native#text/plain
|
||||
res/cardsfolder/m/mischievous_quanar.txt -text
|
||||
res/cardsfolder/m/misers_cage.txt svneol=native#text/plain
|
||||
res/cardsfolder/m/misery_charm.txt svneol=native#text/plain
|
||||
res/cardsfolder/m/misfortune.txt -text
|
||||
res/cardsfolder/m/misfortunes_gain.txt svneol=native#text/plain
|
||||
res/cardsfolder/m/misguided_rage.txt svneol=native#text/plain
|
||||
res/cardsfolder/m/mishra.txt -text
|
||||
|
||||
11
res/cardsfolder/f/fatal_lore.txt
Normal file
11
res/cardsfolder/f/fatal_lore.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
Name:Fatal Lore
|
||||
ManaCost:2 B B
|
||||
Types:Sorcery
|
||||
A:SP$ Charm | Cost$ 2 B B | Chooser$ Opponent | Choices$ DrawThree,DestroyAndDraw | SpellDescription$ An opponent chooses one - You draw three cards; or you destroy up to two target creatures that opponent controls and that player draws up to three cards. Those creatures can't be regenerated.
|
||||
SVar:DrawThree:DB$ Draw | NumCards$ 3 | Defined$ You | SpellDescription$ You draw three cards.
|
||||
SVar:DestroyAndDraw:DB$ Destroy | ValidTgts$ Creature.ChosenCtrl | TgtPrompt$ Select target creature | TargetMin$ 0 | TargetMax$ 2 | NoRegen$ True | SpellDescription$ You destroy up to two target creatures that opponent controls and that player draws up to three cards. Those creatures can't be regenerated. | SubAbility$ ChooserDraws
|
||||
SVar:ChooserDraws:DB$ Draw | NumCards$ 3 | Defined$ ChosenPlayer
|
||||
SVar:RemAIDeck:True
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/fatal_lore.jpg
|
||||
SetInfo:ALL|Rare|http://magiccards.info/scans/en/ai/7.jpg
|
||||
Oracle:An opponent chooses one - You draw three cards; or you destroy up to two target creatures that opponent controls and that player draws up to three cards. Those creatures can't be regenerated.
|
||||
11
res/cardsfolder/l/library_of_lat_nam.txt
Normal file
11
res/cardsfolder/l/library_of_lat_nam.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
Name:Library of Lat-Nam
|
||||
ManaCost:4 U
|
||||
Types:Sorcery
|
||||
A:SP$ Charm | Cost$ 4 U | Chooser$ Opponent | Choices$ SlowDraw,Tutor | SpellDescription$ An opponent chooses one - You draw three cards at the beginning of the next turn's upkeep; or you search your library for a card, put that card into your hand, then shuffle your library.
|
||||
SVar:SlowDraw:DB$ Draw | NumCards$ 3 | Defined$ You | NextUpkeep$ True | SpellDescription$ You draw three cards at the beginning of the next turn's upkeep
|
||||
SVar:Tutor:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Card | ChangeNum$ 1 | Mandatory$ True | SpellDescription$ You search your library for a card, put that card into your hand, then shuffle your library.
|
||||
SVar:RemAIDeck:True
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/library_of_lat_nam.jpg
|
||||
SetInfo:6ED|Rare|http://magiccards.info/scans/en/6e/78.jpg
|
||||
SetInfo:ALL|Rare|http://magiccards.info/scans/en/ai/47.jpg
|
||||
Oracle:An opponent chooses one - You draw three cards at the beginning of the next turn's upkeep; or you search your library for a card, put that card into your hand, then shuffle your library.
|
||||
13
res/cardsfolder/m/misfortune.txt
Normal file
13
res/cardsfolder/m/misfortune.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
Name:Misfortune
|
||||
ManaCost:1 B R G
|
||||
Types:Sorcery
|
||||
A:SP$ Charm | Cost$ 1 B R G | Chooser$ Opponent | Choices$ Fortune,Misfortune | SpellDescription$ An opponent chooses one - You put a +1/+1 counter on each creature you control and gain 4 life; or you put a -1/-1 counter on each creature that player controls and Misfortune deals 4 damage to him or her.
|
||||
SVar:Fortune:DB$ PutCounterAll | ValidCards$ Creature.YouCtrl | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBGainLife | SpellDescription$ Put a +1/+1 counter on each creature you control. You gain 4 life. | SubAbility$ DBGainLife
|
||||
SVar:DBGainLife:DB$ GainLife | LifeAmount$ 4
|
||||
SVar:Misfortune:DB$ PutCounterAll | ValidCards$ Creature.ChosenCtrl | CounterType$ M1M1 | CounterNum$ 1 | SubAbility$ DBLoseLife | SpellDescription$ you put a -1/-1 counter on each creature that player controls and Misfortune deals 4 damage to him or her. | SubAbility$ DBDamage
|
||||
SVar:DBDamage:DB$ DealDamage | Defined$ ChosenPlayer | NumDmg$ 4
|
||||
SVar:ChooserDraws:DB$ Draw | NumCards$ 3 | Defined$ ChosenPlayer
|
||||
SVar:RemAIDeck:True
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/misfortune.jpg
|
||||
SetInfo:ALL|Rare|http://magiccards.info/scans/en/ai/194.jpg
|
||||
Oracle:An opponent chooses one - You put a +1/+1 counter on each creature you control and gain 4 life; or you put a -1/-1 counter on each creature that player controls and Misfortune deals 4 damage to him or her.
|
||||
@@ -4,11 +4,12 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.ability.effects.CharmEffect;
|
||||
import org.apache.commons.lang.math.RandomUtils;
|
||||
import forge.card.ability.SpellAbilityAi;import forge.card.ability.effects.CharmEffect;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
public class CharmAi extends SpellAbilityAi {
|
||||
@@ -22,7 +23,7 @@ public class CharmAi extends SpellAbilityAi {
|
||||
boolean timingRight = sa.isTrigger(); //is there a reason to play the charm now?
|
||||
|
||||
List<AbilitySub> chooseFrom = CharmEffect.makePossibleOptions(sa);
|
||||
List<AbilitySub> chosenList = chooseOptionsAi(ai, timingRight, chooseFrom, num, min);
|
||||
List<AbilitySub> chosenList = chooseOptionsAi(ai, timingRight, chooseFrom, num, min, false);
|
||||
|
||||
if (chosenList == null || chosenList.isEmpty()) {
|
||||
return false;
|
||||
@@ -32,9 +33,17 @@ public class CharmAi extends SpellAbilityAi {
|
||||
return r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
|
||||
}
|
||||
|
||||
public static List<AbilitySub> chooseOptionsAi(final AIPlayer ai, boolean playNow, List<AbilitySub> choices, int num, int min) {
|
||||
public static List<AbilitySub> chooseOptionsAi(final AIPlayer ai, boolean playNow, List<AbilitySub> choices, int num, int min, boolean opponentChoser) {
|
||||
List<AbilitySub> chosenList = new ArrayList<AbilitySub>();
|
||||
|
||||
if (opponentChoser) {
|
||||
// This branch is for "An Opponent chooses" Charm spells from Alliances
|
||||
// Current just choose the first available spell, which seem generally less disastrous for the AI.
|
||||
//return choices.subList(0, 1);
|
||||
return choices.subList(1, choices.size());
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
AbilitySub thisPick = null;
|
||||
for (SpellAbility sub : choices) {
|
||||
@@ -57,4 +66,9 @@ public class CharmAi extends SpellAbilityAi {
|
||||
}
|
||||
return chosenList.size() >= min ? chosenList : null;
|
||||
}
|
||||
|
||||
public static Player determineOpponentChooser(AIPlayer ai, SpellAbility sa, List<Player> opponents) {
|
||||
return opponents.get(RandomUtils.nextInt(opponents.size()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,17 +50,37 @@ public class CharmEffect extends SpellAbilityEffect {
|
||||
final List<AbilitySub> choices = makePossibleOptions(sa);
|
||||
|
||||
List<AbilitySub> chosen = null;
|
||||
|
||||
Card source = sa.getSourceCard();
|
||||
Player activator = sa.getActivatingPlayer();
|
||||
if (activator.isHuman()) {
|
||||
Player chooser = sa.getActivatingPlayer();
|
||||
|
||||
if (sa.hasParam("Chooser")) {
|
||||
// Three modal cards require you to choose a player to make the modal choice'
|
||||
// Two of these also reference the chosen player during the spell effect
|
||||
String choose = sa.getParam("Chooser");
|
||||
List<Player> opponents = activator.getOpponents();
|
||||
int numOpps = opponents.size();
|
||||
if (numOpps == 1) {
|
||||
chooser = opponents.get(0);
|
||||
} else {
|
||||
if (activator.isComputer()) {
|
||||
chooser = CharmAi.determineOpponentChooser((AIPlayer)activator, sa, opponents);
|
||||
} else {
|
||||
chooser = GuiChoose.one("Choose an opponent", opponents);
|
||||
}
|
||||
}
|
||||
source.setChosenPlayer(chooser);
|
||||
}
|
||||
|
||||
if (chooser.isHuman()) {
|
||||
String modeTitle = String.format("%s activated %s - Choose a mode", activator, source);
|
||||
chosen = new ArrayList<AbilitySub>();
|
||||
for (int i = 0; i < num; i++) {
|
||||
AbilitySub a;
|
||||
if (i < min) {
|
||||
a = GuiChoose.one("Choose a mode", choices);
|
||||
a = GuiChoose.one(modeTitle, choices);
|
||||
} else {
|
||||
a = GuiChoose.oneOrNone("Choose a mode", choices);
|
||||
a = GuiChoose.oneOrNone(modeTitle, choices);
|
||||
}
|
||||
if (null == a) {
|
||||
break;
|
||||
@@ -70,7 +90,7 @@ public class CharmEffect extends SpellAbilityEffect {
|
||||
chosen.add(a);
|
||||
}
|
||||
} else {
|
||||
chosen = CharmAi.chooseOptionsAi((AIPlayer)activator, sa.isTrigger(), choices, num, min);
|
||||
chosen = CharmAi.chooseOptionsAi((AIPlayer)chooser, sa.isTrigger(), choices, num, min, !chooser.equals(activator));
|
||||
}
|
||||
|
||||
chainAbilities(sa, chosen);
|
||||
|
||||
Reference in New Issue
Block a user