mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
Merge pull request #4277 from Northmoc/WHO-trap
WHO: the_toymakers_trap.txt + support
This commit is contained in:
@@ -1877,6 +1877,8 @@ public class AiController {
|
|||||||
} else {
|
} else {
|
||||||
return options.get(0);
|
return options.get(0);
|
||||||
}
|
}
|
||||||
|
case ChooseNumber:
|
||||||
|
return Aggregates.random(options);
|
||||||
default:
|
default:
|
||||||
return options.get(0);
|
return options.get(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public final class AbilityFactory {
|
|||||||
public static final List<String> additionalAbilityKeys = Lists.newArrayList(
|
public static final List<String> additionalAbilityKeys = Lists.newArrayList(
|
||||||
"WinSubAbility", "OtherwiseSubAbility", // Clash
|
"WinSubAbility", "OtherwiseSubAbility", // Clash
|
||||||
"BidSubAbility", // BidLifeEffect
|
"BidSubAbility", // BidLifeEffect
|
||||||
"ChooseNumberSubAbility", "Lowest", "Highest", "NotLowest", // ChooseNumber
|
"ChooseNumberSubAbility", "Lowest", "Highest", "NotLowest", "GuessCorrect", "GuessWrong", // ChooseNumber
|
||||||
"HeadsSubAbility", "TailsSubAbility", "LoseSubAbility", // FlipCoin
|
"HeadsSubAbility", "TailsSubAbility", "LoseSubAbility", // FlipCoin
|
||||||
"TrueSubAbility", "FalseSubAbility", // Branch
|
"TrueSubAbility", "FalseSubAbility", // Branch
|
||||||
"ChosenPile", "UnchosenPile", // MultiplePiles & TwoPiles
|
"ChosenPile", "UnchosenPile", // MultiplePiles & TwoPiles
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.game.ability.effects;
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@@ -15,6 +16,9 @@ import forge.game.spellability.SpellAbility;
|
|||||||
import forge.util.Lang;
|
import forge.util.Lang;
|
||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
import forge.util.MyRandom;
|
import forge.util.MyRandom;
|
||||||
|
import forge.util.collect.FCollectionView;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
public class ChooseNumberEffect extends SpellAbilityEffect {
|
public class ChooseNumberEffect extends SpellAbilityEffect {
|
||||||
|
|
||||||
@@ -47,11 +51,17 @@ public class ChooseNumberEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
final Map<Player, Integer> chooseMap = Maps.newHashMap();
|
final Map<Player, Integer> chooseMap = Maps.newHashMap();
|
||||||
|
|
||||||
|
// defined guesser must try to guess the chosen - currently only on "The Toymaker's Trap"
|
||||||
|
boolean guessedCorrect = false;
|
||||||
|
Pair<Player, Integer> guessPair = null;
|
||||||
|
// may need future work to ensure chooser and guesser get same choices even in absence of RemoveChoices param
|
||||||
|
List<Integer> choices = new ArrayList<>();
|
||||||
|
|
||||||
for (final Player p : getTargetPlayers(sa)) {
|
for (final Player p : getTargetPlayers(sa)) {
|
||||||
if (!p.isInGame()) {
|
if (!p.isInGame()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int chosen;
|
Integer chosen;
|
||||||
if (random) {
|
if (random) {
|
||||||
chosen = MyRandom.getRandom().nextInt((max - min) + 1) + min;
|
chosen = MyRandom.getRandom().nextInt((max - min) + 1) + min;
|
||||||
//TODO more useful notify for RepeatEach -> ChooseNumber with random
|
//TODO more useful notify for RepeatEach -> ChooseNumber with random
|
||||||
@@ -61,6 +71,16 @@ public class ChooseNumberEffect extends SpellAbilityEffect {
|
|||||||
if (anyNumber) {
|
if (anyNumber) {
|
||||||
Integer value = p.getController().announceRequirements(sa, title);
|
Integer value = p.getController().announceRequirements(sa, title);
|
||||||
chosen = value == null ? 0 : value;
|
chosen = value == null ? 0 : value;
|
||||||
|
} else if (sa.hasParam("RemoveChoices")) {
|
||||||
|
// currently we always remove remembered numbers, so the value is not really used yet
|
||||||
|
for (int i = min; i <= max; i++) {
|
||||||
|
choices.add(i);
|
||||||
|
}
|
||||||
|
for (Object o : card.getRemembered()) {
|
||||||
|
if (o instanceof Integer) choices.remove((Integer) o);
|
||||||
|
}
|
||||||
|
if (choices.isEmpty()) continue;
|
||||||
|
chosen = p.getController().chooseNumber(sa, title, choices, null);
|
||||||
} else {
|
} else {
|
||||||
chosen = p.getController().chooseNumber(sa, title, min, max);
|
chosen = p.getController().chooseNumber(sa, title, min, max);
|
||||||
}
|
}
|
||||||
@@ -72,15 +92,35 @@ public class ChooseNumberEffect extends SpellAbilityEffect {
|
|||||||
card.setChosenNumber(chosen);
|
card.setChosenNumber(chosen);
|
||||||
}
|
}
|
||||||
if (sa.hasParam("Notify")) {
|
if (sa.hasParam("Notify")) {
|
||||||
p.getGame().getAction().notifyOfValue(sa, card, Localizer.getInstance().getMessage("lblPlayerPickedChosen", p.getName(), chosen), p);
|
p.getGame().getAction().notifyOfValue(sa, card, Localizer.getInstance().
|
||||||
|
getMessage("lblPlayerPickedChosen", p.getName(), chosen), p);
|
||||||
|
}
|
||||||
|
if (sa.hasParam("Guesser") && chosen != null) { // if nothing was chosen, there is nothing to guess
|
||||||
|
final FCollectionView<Player> gChoices =
|
||||||
|
AbilityUtils.getDefinedPlayers(card, sa.getParam("Guesser"), sa);
|
||||||
|
final Player guesser = choices.isEmpty() ? null : p.getController().
|
||||||
|
chooseSingleEntityForEffect(gChoices, sa, Localizer.getInstance().getMessage("lblChoosePlayer"),
|
||||||
|
false, null);
|
||||||
|
if (guesser != null) {
|
||||||
|
guessPair = Pair.of(guesser, guesser.getController().chooseNumber(sa,
|
||||||
|
Localizer.getInstance().getMessage("lblChooseNumber"), choices, null));
|
||||||
|
// if more complicated effects require this in the future it may be worth a unique message
|
||||||
|
if (chooseMap.containsValue(guessPair.getValue())) guessedCorrect = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (secretlyChoose) {
|
}
|
||||||
|
|
||||||
|
if (secretlyChoose && !chooseMap.isEmpty()) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
List<Player> highestNum = Lists.newArrayList();
|
List<Player> highestNum = Lists.newArrayList();
|
||||||
List<Player> lowestNum = Lists.newArrayList();
|
List<Player> lowestNum = Lists.newArrayList();
|
||||||
int highest = 0;
|
int highest = 0;
|
||||||
int lowest = Integer.MAX_VALUE;
|
int lowest = Integer.MAX_VALUE;
|
||||||
|
if (guessPair != null) {
|
||||||
|
sb.append(Localizer.getInstance().getMessage("lblPlayerGuessedNum", guessPair.getKey().getName(),
|
||||||
|
String.valueOf(guessPair.getValue())));
|
||||||
|
sb.append("\r\n");
|
||||||
|
}
|
||||||
for (Entry<Player, Integer> ev : chooseMap.entrySet()) {
|
for (Entry<Player, Integer> ev : chooseMap.entrySet()) {
|
||||||
int num = ev.getValue();
|
int num = ev.getValue();
|
||||||
Player player = ev.getKey();
|
Player player = ev.getKey();
|
||||||
@@ -153,7 +193,24 @@ public class ChooseNumberEffect extends SpellAbilityEffect {
|
|||||||
card.addRemembered(highestNum);
|
card.addRemembered(highestNum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sa.hasParam("GuessCorrect") && guessedCorrect) { // correct guess doesn't use any chosen num yet
|
||||||
|
SpellAbility sub = sa.getAdditionalAbility("GuessCorrect");
|
||||||
|
AbilityUtils.resolve(sub);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sa.hasParam("GuessWrong") && guessPair != null && !guessedCorrect) {
|
||||||
|
SpellAbility sub = sa.getAdditionalAbility("GuessWrong");
|
||||||
|
// wrong currently uses the guess, not the chosen
|
||||||
|
card.setChosenNumber(guessPair.getValue());
|
||||||
|
card.addRemembered(guessPair.getKey());
|
||||||
|
AbilityUtils.resolve(sub);
|
||||||
|
card.clearChosenNumber();
|
||||||
|
card.removeRemembered(guessPair.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sa.hasParam("RememberChosen")) card.addRemembered(chooseMap.values());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1830,6 +1830,11 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
view.updateChosenNumber(this);
|
view.updateChosenNumber(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void clearChosenNumber() {
|
||||||
|
chosenNumber = null;
|
||||||
|
view.clearChosenNumber();
|
||||||
|
}
|
||||||
|
|
||||||
public final Card getExiledWith() {
|
public final Card getExiledWith() {
|
||||||
return exiledWith;
|
return exiledWith;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -387,6 +387,9 @@ public class CardView extends GameEntityView {
|
|||||||
void updateChosenNumber(Card c) {
|
void updateChosenNumber(Card c) {
|
||||||
set(TrackableProperty.ChosenNumber, c.getChosenNumber().toString());
|
set(TrackableProperty.ChosenNumber, c.getChosenNumber().toString());
|
||||||
}
|
}
|
||||||
|
void clearChosenNumber() {
|
||||||
|
set(TrackableProperty.ChosenNumber, "");
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getStoredRolls() {
|
public List<String> getStoredRolls() {
|
||||||
return get(TrackableProperty.StoredRolls);
|
return get(TrackableProperty.StoredRolls);
|
||||||
|
|||||||
12
forge-gui/res/cardsfolder/upcoming/the_toymakers_trap.txt
Normal file
12
forge-gui/res/cardsfolder/upcoming/the_toymakers_trap.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Name:The Toymaker's Trap
|
||||||
|
ManaCost:2 B
|
||||||
|
Types:Enchantment
|
||||||
|
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigChooseNumber | TriggerDescription$ At the beginning of your upkeep, secretly choose a number between 1 and 5 that hasn't been chosen. If you do, an opponent guesses which number you chose, then you reveal the number you chose. If they guessed wrong, they lose life equal to the number they guessed and you draw a card. If they guessed right, sacrifice The Toymaker's Trap.
|
||||||
|
SVar:TrigChooseNumber:DB$ ChooseNumber | SecretlyChoose$ True | Min$ 1 | Max$ 5 | RemoveChoices$ Remembered | Guesser$ Opponent | GuessWrong$ DBLoseLife | GuessCorrect$ DBSac | RememberChosen$ True | SubAbility$ DBCleanup
|
||||||
|
SVar:DBLoseLife:DB$ LoseLife | Defined$ RememberedPlayer | LifeAmount$ Count$ChosenNumber | SubAbility$ DBDraw
|
||||||
|
SVar:DBDraw:DB$ Draw
|
||||||
|
SVar:DBSac:DB$ Sacrifice
|
||||||
|
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | Static$ True | ValidCard$ Card.Self | Execute$ DBCleanup
|
||||||
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
|
DeckHas:Ability$Sacrifice
|
||||||
|
Oracle:At the beginning of your upkeep, secretly choose a number between 1 and 5 that hasn't been chosen. If you do, an opponent guesses which number you chose, then you reveal the number you chose. If they guessed wrong, they lose life equal to the number they guessed and you draw a card. If they guessed right, sacrifice The Toymaker's Trap.
|
||||||
@@ -1907,6 +1907,7 @@ lblChooseOne=Wähle eines
|
|||||||
#ChooseNumberEffect.java
|
#ChooseNumberEffect.java
|
||||||
lblChooseNumber=Wähle eine Zahl
|
lblChooseNumber=Wähle eine Zahl
|
||||||
lblPlayerChoseNum={0} wähle {1}
|
lblPlayerChoseNum={0} wähle {1}
|
||||||
|
lblPlayerGuessedNum={0} hat {1} erraten
|
||||||
#ChoosePlayerEffect.java
|
#ChoosePlayerEffect.java
|
||||||
lblChoosePlayer=Wähle einen Spieler
|
lblChoosePlayer=Wähle einen Spieler
|
||||||
#ChooseSourceEffect.java
|
#ChooseSourceEffect.java
|
||||||
|
|||||||
@@ -1912,6 +1912,7 @@ lblChooseOne=Choose one
|
|||||||
#ChooseNumberEffect.java
|
#ChooseNumberEffect.java
|
||||||
lblChooseNumber=Choose a number
|
lblChooseNumber=Choose a number
|
||||||
lblPlayerChoseNum={0} chose {1}
|
lblPlayerChoseNum={0} chose {1}
|
||||||
|
lblPlayerGuessedNum={0} guessed {1}
|
||||||
#ChoosePlayerEffect.java
|
#ChoosePlayerEffect.java
|
||||||
lblChoosePlayer=Choose a player
|
lblChoosePlayer=Choose a player
|
||||||
#ChooseSourceEffect.java
|
#ChooseSourceEffect.java
|
||||||
|
|||||||
@@ -1908,6 +1908,7 @@ lblChooseOne=Elige uno
|
|||||||
#ChooseNumberEffect.java
|
#ChooseNumberEffect.java
|
||||||
lblChooseNumber=Elige un número
|
lblChooseNumber=Elige un número
|
||||||
lblPlayerChoseNum={0} eligió {1}
|
lblPlayerChoseNum={0} eligió {1}
|
||||||
|
lblPlayerGuessedNum={0} adivinó {1}
|
||||||
#ChoosePlayerEffect.java
|
#ChoosePlayerEffect.java
|
||||||
lblChoosePlayer=Elige un jugador
|
lblChoosePlayer=Elige un jugador
|
||||||
#ChooseSourceEffect.java
|
#ChooseSourceEffect.java
|
||||||
|
|||||||
@@ -1878,7 +1878,7 @@ lblLookingCardIn=Regarder les cartes dans
|
|||||||
lblDoYouWantPlayCard=Voulez-vous jouer à {0} ?
|
lblDoYouWantPlayCard=Voulez-vous jouer à {0} ?
|
||||||
lblDoYouWantPlayCardTransformed=Voulez-vous jouer à {0} transformée?
|
lblDoYouWantPlayCardTransformed=Voulez-vous jouer à {0} transformée?
|
||||||
lblSelectCardFromPlayerZone=Sélectionnez une carte de {0} {1}
|
lblSelectCardFromPlayerZone=Sélectionnez une carte de {0} {1}
|
||||||
lblSelectUpToNumCardFromPlayerZone=S\u00e9lectionnez jusqu''\u00e0 {0} cartes de {1} {2}
|
lblSelectUpToNumCardFromPlayerZone=Sélectionnez jusqu''à {0} cartes de {1} {2}
|
||||||
lblSelectCardsFromPlayerZone=Sélectionner les cartes de {0} {1}
|
lblSelectCardsFromPlayerZone=Sélectionner les cartes de {0} {1}
|
||||||
lblCancelSearchUpToSelectNumCards=Annuler la recherche ? Jusqu''à {0} carte(s) supplémentaire(s) peuvent être sélectionnées.
|
lblCancelSearchUpToSelectNumCards=Annuler la recherche ? Jusqu''à {0} carte(s) supplémentaire(s) peuvent être sélectionnées.
|
||||||
#ChangeZoneAllEffect.java
|
#ChangeZoneAllEffect.java
|
||||||
@@ -1911,6 +1911,7 @@ lblChooseOne=Choisissez-en un
|
|||||||
#ChooseNumberEffect.java
|
#ChooseNumberEffect.java
|
||||||
lblChooseNumber=Choisissez un nombre
|
lblChooseNumber=Choisissez un nombre
|
||||||
lblPlayerChoseNum={0} a choisi {1}
|
lblPlayerChoseNum={0} a choisi {1}
|
||||||
|
lblPlayerGuessedNum={0} deviné {1}
|
||||||
#ChoosePlayerEffect.java
|
#ChoosePlayerEffect.java
|
||||||
lblChoosePlayer=Choisir un joueur
|
lblChoosePlayer=Choisir un joueur
|
||||||
#ChooseSourceEffect.java
|
#ChooseSourceEffect.java
|
||||||
|
|||||||
@@ -1908,6 +1908,7 @@ lblChooseOne=Scegli uno
|
|||||||
#ChooseNumberEffect.java
|
#ChooseNumberEffect.java
|
||||||
lblChooseNumber=Scegli un numero
|
lblChooseNumber=Scegli un numero
|
||||||
lblPlayerChoseNum={0} ha scelto {1}
|
lblPlayerChoseNum={0} ha scelto {1}
|
||||||
|
lblPlayerGuessedNum={0} ha indovinato {1}
|
||||||
#ChoosePlayerEffect.java
|
#ChoosePlayerEffect.java
|
||||||
lblChoosePlayer=Scegli un giocatore
|
lblChoosePlayer=Scegli un giocatore
|
||||||
#ChooseSourceEffect.java
|
#ChooseSourceEffect.java
|
||||||
|
|||||||
@@ -1907,6 +1907,7 @@ lblChooseOne=以下から 1つを選ぶ
|
|||||||
#ChooseNumberEffect.java
|
#ChooseNumberEffect.java
|
||||||
lblChooseNumber=数字を 1つ選ぶ
|
lblChooseNumber=数字を 1つ選ぶ
|
||||||
lblPlayerChoseNum={0}が {1}を選んだ
|
lblPlayerChoseNum={0}が {1}を選んだ
|
||||||
|
lblPlayerGuessedNum={0}は {1}を推測しました
|
||||||
#ChoosePlayerEffect.java
|
#ChoosePlayerEffect.java
|
||||||
lblChoosePlayer=プレイヤーを選ぶ
|
lblChoosePlayer=プレイヤーを選ぶ
|
||||||
#ChooseSourceEffect.java
|
#ChooseSourceEffect.java
|
||||||
|
|||||||
@@ -1969,6 +1969,7 @@ lblChooseOne=Escolha um
|
|||||||
#ChooseNumberEffect.java
|
#ChooseNumberEffect.java
|
||||||
lblChooseNumber=Escolha um número
|
lblChooseNumber=Escolha um número
|
||||||
lblPlayerChoseNum={0} escolheu {1}
|
lblPlayerChoseNum={0} escolheu {1}
|
||||||
|
lblPlayerGuessedNum={0} adivinhou {1}
|
||||||
#ChoosePlayerEffect.java
|
#ChoosePlayerEffect.java
|
||||||
lblChoosePlayer=Escolha um jogador
|
lblChoosePlayer=Escolha um jogador
|
||||||
#ChooseSourceEffect.java
|
#ChooseSourceEffect.java
|
||||||
|
|||||||
@@ -1912,6 +1912,7 @@ lblChooseOne=选择一个
|
|||||||
#ChooseNumberEffect.java
|
#ChooseNumberEffect.java
|
||||||
lblChooseNumber=选择一个数
|
lblChooseNumber=选择一个数
|
||||||
lblPlayerChoseNum={0}已选择{1}
|
lblPlayerChoseNum={0}已选择{1}
|
||||||
|
lblPlayerGuessedNum={0}猜了{1}
|
||||||
#ChoosePlayerEffect.java
|
#ChoosePlayerEffect.java
|
||||||
lblChoosePlayer=选择一个牌手
|
lblChoosePlayer=选择一个牌手
|
||||||
#ChooseSourceEffect.java
|
#ChooseSourceEffect.java
|
||||||
|
|||||||
Reference in New Issue
Block a user