Merge pull request #3944 from Northmoc/bamboozle

bamboozling_beeble.txt and centaur_of_attention.txt and Support
This commit is contained in:
kevlahnota
2023-10-26 16:55:47 +08:00
committed by GitHub
27 changed files with 257 additions and 29 deletions

View File

@@ -588,6 +588,12 @@ public class PlayerControllerAi extends PlayerController {
return Aggregates.random(rolls); return Aggregates.random(rolls);
} }
@Override
public Integer chooseRollToIgnore(List<Integer> rolls) {
//TODO create AI logic for this
return Aggregates.random(rolls);
}
@Override @Override
public boolean mulliganKeepHand(Player firstPlayer, int cardsToReturn) { public boolean mulliganKeepHand(Player firstPlayer, int cardsToReturn) {
return !ComputerUtil.wantMulligan(player, cardsToReturn); return !ComputerUtil.wantMulligan(player, cardsToReturn);

View File

@@ -73,6 +73,7 @@ public enum AbilityKey {
Fizzle("Fizzle"), Fizzle("Fizzle"),
FoundSearchingLibrary("FoundSearchingLibrary"), FoundSearchingLibrary("FoundSearchingLibrary"),
Ignore("Ignore"), Ignore("Ignore"),
IgnoreChosen("IgnoreChosen"),
IsCombat("IsCombat"), // TODO confirm that this and IsCombatDamage can be merged IsCombat("IsCombat"), // TODO confirm that this and IsCombatDamage can be merged
IsCombatDamage("IsCombatDamage"), IsCombatDamage("IsCombatDamage"),
IsDamage("IsDamage"), IsDamage("IsDamage"),

View File

@@ -2625,6 +2625,25 @@ public class AbilityUtils {
return doXMath(game.getStack().getMaxDistinctSources(), expr, c, ctb); return doXMath(game.getStack().getMaxDistinctSources(), expr, c, ctb);
} }
if (sq[0].equals("MaxSameStoredRolls")) {
int max = 0;
List<Integer> rolls = c.getStoredRolls();
if (rolls != null) {
int lastNum = 0;
for (Integer roll : rolls) {
if (roll.equals(lastNum)) {
continue; // no need to count instances of the same roll multiple times
}
int tally = Collections.frequency(rolls, roll);
if (tally > max) {
max = tally;
}
lastNum = roll;
}
}
return doXMath(max, expr, c, ctb);
}
//Count$Random.<Min>.<Max> //Count$Random.<Min>.<Max>
if (sq[0].equals("Random")) { if (sq[0].equals("Random")) {
int min = calculateAmount(c, sq[1], ctb); int min = calculateAmount(c, sq[1], ctb);

View File

@@ -3,6 +3,7 @@ package forge.game.ability.effects;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.google.common.collect.Maps;
import forge.game.GameObject; import forge.game.GameObject;
import forge.game.PlanarDice; import forge.game.PlanarDice;
import forge.game.ability.AbilityKey; import forge.game.ability.AbilityKey;
@@ -13,7 +14,6 @@ import forge.game.player.Player;
import forge.game.replacement.ReplacementResult; import forge.game.replacement.ReplacementResult;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
public class ReplaceEffect extends SpellAbilityEffect { public class ReplaceEffect extends SpellAbilityEffect {
@Override @Override
@@ -44,6 +44,12 @@ public class ReplaceEffect extends SpellAbilityEffect {
} }
} else if ("PlanarDice".equals(type)) { } else if ("PlanarDice".equals(type)) {
params.put(varName, PlanarDice.smartValueOf(varValue)); params.put(varName, PlanarDice.smartValueOf(varValue));
} else if ("Map".equals(type)) {
Map<Player, Integer> m = Maps.newHashMap();
for (Player key : AbilityUtils.getDefinedPlayers(card, sa.getParam("VarKey"), sa)) {
m.put(key, AbilityUtils.calculateAmount(card, varValue, sa));
}
params.put(varName, m);
} else { } else {
params.put(varName, AbilityUtils.calculateAmount(card, varValue, sa)); params.put(varName, AbilityUtils.calculateAmount(card, varValue, sa));
} }

View File

@@ -1,22 +1,22 @@
package forge.game.ability.effects; package forge.game.ability.effects;
import java.util.*;
import forge.game.event.GameEventRollDie;
import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import forge.game.ability.AbilityKey; import forge.game.ability.AbilityKey;
import forge.game.ability.AbilityUtils; import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect; import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.event.GameEventRollDie;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerCollection; import forge.game.player.PlayerCollection;
import forge.game.replacement.ReplacementType;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.trigger.TriggerType; import forge.game.trigger.TriggerType;
import forge.util.Localizer; import forge.util.Localizer;
import forge.util.MyRandom; import forge.util.MyRandom;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
public class RollDiceEffect extends SpellAbilityEffect { public class RollDiceEffect extends SpellAbilityEffect {
@@ -37,11 +37,6 @@ public class RollDiceEffect extends SpellAbilityEffect {
return sb.toString(); return sb.toString();
} }
private static int getRollAdvange(final Player player) {
String str = "If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll.";
return player.getKeywords().getAmount(str);
}
/* (non-Javadoc) /* (non-Javadoc)
* @see forge.card.abilityfactory.SpellEffect#getStackDescription(java.util.Map, forge.card.spellability.SpellAbility) * @see forge.card.abilityfactory.SpellEffect#getStackDescription(java.util.Map, forge.card.spellability.SpellAbility)
*/ */
@@ -68,11 +63,27 @@ public class RollDiceEffect extends SpellAbilityEffect {
return rollDiceForPlayer(sa, player, amount, sides, 0, 0, null); return rollDiceForPlayer(sa, player, amount, sides, 0, 0, null);
} }
private static int rollDiceForPlayer(SpellAbility sa, Player player, int amount, int sides, int ignore, int modifier, List<Integer> rollsResult) { private static int rollDiceForPlayer(SpellAbility sa, Player player, int amount, int sides, int ignore, int modifier, List<Integer> rollsResult) {
Map<Player, Integer> ignoreChosenMap = Maps.newHashMap();
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(player);
repParams.put(AbilityKey.Number, amount);
repParams.put(AbilityKey.Ignore, ignore);
repParams.put(AbilityKey.IgnoreChosen, ignoreChosenMap);
switch (player.getGame().getReplacementHandler().run(ReplacementType.RollDice, repParams)) {
case NotReplaced:
break;
case Updated: {
amount = (int) repParams.get(AbilityKey.Number);
ignore = (int) repParams.get(AbilityKey.Ignore);
ignoreChosenMap = (Map<Player, Integer>) repParams.get(AbilityKey.IgnoreChosen);
break;
}
}
if (amount == 0) { if (amount == 0) {
return 0; return 0;
} }
int advantage = getRollAdvange(player);
amount += advantage;
int total = 0; int total = 0;
List<Integer> naturalRolls = (rollsResult == null ? new ArrayList<>() : rollsResult); List<Integer> naturalRolls = (rollsResult == null ? new ArrayList<>() : rollsResult);
@@ -85,21 +96,38 @@ public class RollDiceEffect extends SpellAbilityEffect {
total += roll; total += roll;
} }
if (amount > 0) {
String message = Localizer.getInstance().getMessage("lblPlayerRolledResult", player, StringUtils.join(naturalRolls, ", "));
player.getGame().getAction().notifyOfValue(sa, player, message, null);
}
naturalRolls.sort(null); naturalRolls.sort(null);
List<Integer> ignored = new ArrayList<>();
// Ignore lowest rolls // Ignore lowest rolls
advantage += ignore; if (ignore > 0) {
if (advantage > 0) { for (int i = ignore - 1; i >= 0; --i) {
for (int i = advantage - 1; i >= 0; --i) {
total -= naturalRolls.get(i); total -= naturalRolls.get(i);
ignored.add(naturalRolls.get(i));
naturalRolls.remove(i); naturalRolls.remove(i);
} }
} }
// Player chooses to ignore rolls
for (Player chooser : ignoreChosenMap.keySet()) {
for (int ig = 0; ig < ignoreChosenMap.get(chooser); ig++) {
Integer ign = chooser.getController().chooseRollToIgnore(naturalRolls);
total -= ign;
ignored.add(ign);
naturalRolls.remove(ign);
}
}
//Notify of results
if (amount > 0) {
StringBuilder sb = new StringBuilder();
sb.append(Localizer.getInstance().getMessage("lblPlayerRolledResult", player,
StringUtils.join(naturalRolls, ", ")));
if (!ignored.isEmpty()) {
sb.append("\r\n").append(Localizer.getInstance().getMessage("lblIgnoredRolls",
StringUtils.join(ignored, ", ")));
}
player.getGame().getAction().notifyOfValue(sa, player, sb.toString(), null);
}
List<Integer> rolls = Lists.newArrayList(); List<Integer> rolls = Lists.newArrayList();
int oddResults = 0; int oddResults = 0;
@@ -177,6 +205,9 @@ public class RollDiceEffect extends SpellAbilityEffect {
List<Integer> rolls = new ArrayList<>(); List<Integer> rolls = new ArrayList<>();
int total = rollDiceForPlayer(sa, player, amount, sides, ignore, modifier, rolls); int total = rollDiceForPlayer(sa, player, amount, sides, ignore, modifier, rolls);
if (sa.hasParam("StoreResults")) {
host.addStoredRolls(rolls);
}
if (sa.hasParam("ResultSVar")) { if (sa.hasParam("ResultSVar")) {
sa.setSVar(sa.getParam("ResultSVar"), Integer.toString(total)); sa.setSVar(sa.getParam("ResultSVar"), Integer.toString(total));
} }
@@ -235,8 +266,12 @@ public class RollDiceEffect extends SpellAbilityEffect {
List<Integer> results = new ArrayList<>(playersToRoll.size()); List<Integer> results = new ArrayList<>(playersToRoll.size());
for (Player player : playersToRoll) { for (Player player : playersToRoll) {
int result = rollDice(sa, player, amount, sides); if (sa.hasParam("RerollResults")) {
results.add(result); rerollDice(sa, host, player, sides);
} else {
int result = rollDice(sa, player, amount, sides);
results.add(result);
}
} }
if (rememberHighest) { if (rememberHighest) {
int highest = 0; int highest = 0;
@@ -252,4 +287,22 @@ public class RollDiceEffect extends SpellAbilityEffect {
} }
} }
} }
private void rerollDice(SpellAbility sa, Card host, Player roller, int sides) {
List<Integer> toReroll = Lists.newArrayList();
for (Integer storedResult : host.getStoredRolls()) {
if (roller.getController().confirmAction(sa, null,
Localizer.getInstance().getMessage("lblRerollResult", storedResult), null)) {
toReroll.add(storedResult);
}
}
Map<Integer, Integer> replaceMap = Maps.newHashMap();
for (Integer old : toReroll) {
int newRoll = rollDice(sa, roller, 1, sides);
replaceMap.put(old, newRoll);
}
host.replaceStoredRoll(replaceMap);
}
} }

View File

@@ -189,6 +189,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
private final Set<Object> rememberedObjects = Sets.newLinkedHashSet(); private final Set<Object> rememberedObjects = Sets.newLinkedHashSet();
private Map<Player, String> flipResult; private Map<Player, String> flipResult;
private List<Integer> storedRolls;
private final Map<Card, Integer> assignedDamageMap = Maps.newTreeMap(); private final Map<Card, Integer> assignedDamageMap = Maps.newTreeMap();
@@ -1279,6 +1280,33 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
} }
} }
public final List<Integer> getStoredRolls() {
return storedRolls;
}
public final List<String> getStoredRollsForView() {
List<String> forView = new ArrayList<>();
for (Integer i : storedRolls) {
forView.add(String.valueOf(i));
}
return forView;
}
public final void addStoredRolls(final List<Integer> results) {
if (storedRolls == null) {
storedRolls = Lists.newArrayList();
}
storedRolls.addAll(results);
storedRolls.sort(null);
view.updateStoredRolls(this);
}
public final void replaceStoredRoll(final Map<Integer, Integer> replaceMap) {
for (Integer oldValue : replaceMap.keySet()) {
storedRolls.remove(oldValue);
storedRolls.add(replaceMap.get(oldValue));
}
storedRolls.sort(null);
view.updateStoredRolls(this);
}
public final String getFlipResult(final Player flipper) { public final String getFlipResult(final Player flipper) {
if (flipResult == null) { if (flipResult == null) {
return null; return null;

View File

@@ -388,6 +388,13 @@ public class CardView extends GameEntityView {
set(TrackableProperty.ChosenNumber, c.getChosenNumber().toString()); set(TrackableProperty.ChosenNumber, c.getChosenNumber().toString());
} }
public List<String> getStoredRolls() {
return get(TrackableProperty.StoredRolls);
}
void updateStoredRolls(Card c) {
set(TrackableProperty.StoredRolls, c.getStoredRollsForView());
}
public List<String> getChosenColors() { public List<String> getChosenColors() {
return get(TrackableProperty.ChosenColors); return get(TrackableProperty.ChosenColors);
} }

View File

@@ -188,6 +188,7 @@ public abstract class PlayerController {
} }
public abstract PlanarDice choosePDRollToIgnore(List<PlanarDice> rolls); public abstract PlanarDice choosePDRollToIgnore(List<PlanarDice> rolls);
public abstract Integer chooseRollToIgnore(List<Integer> rolls);
public abstract Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes, Player forPlayer); public abstract Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes, Player forPlayer);

View File

@@ -0,0 +1,41 @@
package forge.game.replacement;
import forge.game.ability.AbilityKey;
import forge.game.card.Card;
import forge.game.spellability.SpellAbility;
import java.util.Map;
public class ReplaceRollDice extends ReplacementEffect {
/**
* Instantiates a new replace roll planar dice.
*
* @param params the params
* @param host the host
*/
public ReplaceRollDice(final Map<String, String> params, final Card host, final boolean intrinsic) {
super(params, host, intrinsic);
}
/* (non-Javadoc)
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
return true;
}
/* (non-Javadoc)
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.Map, forge.card.spellability.SpellAbility)
*/
@Override
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
sa.setReplacingObject(AbilityKey.Number, runParams.get(AbilityKey.Number));
sa.setReplacingObject(AbilityKey.Ignore, runParams.get(AbilityKey.Ignore));
sa.setReplacingObject(AbilityKey.IgnoreChosen, runParams.get(AbilityKey.IgnoreChosen));
}
}

View File

@@ -39,6 +39,7 @@ public enum ReplacementType {
ProduceMana(ReplaceProduceMana.class), ProduceMana(ReplaceProduceMana.class),
Proliferate(ReplaceProliferate.class), Proliferate(ReplaceProliferate.class),
RemoveCounter(ReplaceRemoveCounter.class), RemoveCounter(ReplaceRemoveCounter.class),
RollDice(ReplaceRollDice.class),
RollPlanarDice(ReplaceRollPlanarDice.class), RollPlanarDice(ReplaceRollPlanarDice.class),
Scry(ReplaceScry.class), Scry(ReplaceScry.class),
SetInMotion(ReplaceSetInMotion.class), SetInMotion(ReplaceSetInMotion.class),

View File

@@ -66,6 +66,7 @@ public enum TrackableProperty {
ChosenColors(TrackableTypes.StringListType), ChosenColors(TrackableTypes.StringListType),
ChosenCards(TrackableTypes.CardViewCollectionType), ChosenCards(TrackableTypes.CardViewCollectionType),
ChosenNumber(TrackableTypes.StringType), ChosenNumber(TrackableTypes.StringType),
StoredRolls(TrackableTypes.StringListType),
ChosenPlayer(TrackableTypes.PlayerViewType), ChosenPlayer(TrackableTypes.PlayerViewType),
ProtectingPlayer(TrackableTypes.PlayerViewType), ProtectingPlayer(TrackableTypes.PlayerViewType),
ChosenDirection(TrackableTypes.EnumType(Direction.class)), ChosenDirection(TrackableTypes.EnumType(Direction.class)),

View File

@@ -495,6 +495,11 @@ public class PlayerControllerForTests extends PlayerController {
return Aggregates.random(rolls); return Aggregates.random(rolls);
} }
@Override
public Integer chooseRollToIgnore(List<Integer> rolls) {
return Aggregates.random(rolls);
}
@Override @Override
public Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes, Player forPlayer) { public Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes, Player forPlayer) {
return chooseItem(options); return chooseItem(options);

View File

@@ -0,0 +1,12 @@
Name:Bamboozling Beeble
ManaCost:U
Types:Creature Beeble
PT:1/1
K:Protection from Robots
A:AB$ Effect | Cost$ 1 T | ValidTgts$ Player | ReplacementEffects$ RigRoll | RememberObjects$ Targeted | ExileOnMoved$ Battlefield | SpellDescription$ The next time target player would roll one or more dice this turn, instead they roll that many dice plus one and you choose one of those rolls to ignore.
SVar:RigRoll:Event$ RollDice | ValidPlayer$ Player.IsRemembered | ReplaceWith$ PlusRoll | Description$ The next time target player would roll one or more dice this turn, instead they roll that many dice plus one and you choose one of those rolls to ignore.
SVar:PlusRoll:DB$ ReplaceEffect | VarName$ Number | VarValue$ ReplaceCount$Number/Plus.1 | SubAbility$ IgnoreRoll
SVar:IgnoreRoll:DB$ ReplaceEffect | VarName$ IgnoreChosen | VarType$ Map | VarKey$ You | VarValue$ 1 | SubAbility$ DBExileEffect
SVar:DBExileEffect:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
AI:RemoveDeck:All
Oracle:Protection from Robots\n{1}, {T}: The next time target player would roll one or more dice this turn, instead they roll that many dice plus one and you choose one of those rolls to ignore.

View File

@@ -1,7 +1,9 @@
Name:Barbarian Class Name:Barbarian Class
ManaCost:R ManaCost:R
Types:Enchantment Class Types:Enchantment Class
S:Mode$ Continuous | Affected$ You | AddKeyword$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll. | Description$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll. R:Event$ RollDice | ActiveZones$ Battlefield | ValidPlayer$ You | ReplaceWith$ PlusRoll | Description$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll.
SVar:PlusRoll:DB$ ReplaceEffect | VarName$ Number | VarValue$ ReplaceCount$Number/Plus.1 | SubAbility$ IgnoreLowest
SVar:IgnoreLowest:DB$ ReplaceEffect | VarName$ Ignore | VarValue$ ReplaceCount$Ignore/Plus.1
K:Class:2:1 R:AddTrigger$ TriggerRoll K:Class:2:1 R:AddTrigger$ TriggerRoll
SVar:TriggerRoll:Mode$ RolledDieOnce | TriggerZones$ Battlefield | ValidPlayer$ You | Execute$ TrigPump | Secondary$ True | TriggerDescription$ Whenever you roll one or more dice, target creature you control gets +2/+0 and gains menace until end of turn. SVar:TriggerRoll:Mode$ RolledDieOnce | TriggerZones$ Battlefield | ValidPlayer$ You | Execute$ TrigPump | Secondary$ True | TriggerDescription$ Whenever you roll one or more dice, target creature you control gets +2/+0 and gains menace until end of turn.
SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.YouCtrl | NumAtt$ 2 | KW$ Menace SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.YouCtrl | NumAtt$ 2 | KW$ Menace

View File

@@ -0,0 +1,11 @@
Name:Centaur of Attention
ManaCost:3 G G
Types:Creature Centaur Performer
PT:3/3
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigRollDice | TriggerDescription$ When CARDNAME enters the battlefield, roll five six-sided dice and store those results on it.
SVar:TrigRollDice:DB$ RollDice | Amount$ 5 | StoreResults$ True
T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | Execute$ TrigReroll | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of combat on your turn, you may reroll any number of CARDNAME's stored results.
SVar:TrigReroll:DB$ RollDice | RerollResults$ True
S:Mode$ Continuous | Affected$ Card.Self | AddPower$ X | AddToughness$ X | Description$ Centaur of Attention gets +X/+X, where X is the greatest number of stored results on it of the same value.
SVar:X:Count$MaxSameStoredRolls
Oracle:When Centaur of Attention enters the battlefield, roll five six-sided dice and store those results on it.\nAt the beginning of combat on your turn, you may reroll any number of Centaur of Attention's stored results.\nCentaur of Attention gets +X/+X, where X is the greatest number of stored results on it of the same value.

View File

@@ -3,5 +3,7 @@ ManaCost:1 U
Types:Creature Faerie Types:Creature Faerie
PT:1/3 PT:1/3
K:Flying K:Flying
S:Mode$ Continuous | Affected$ You | AddKeyword$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll. | Description$ Grant an Advantage — If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll. R:Event$ RollDice | ActiveZones$ Battlefield | ValidPlayer$ You | ReplaceWith$ PlusRoll | Description$ Grant an Advantage — If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll.
SVar:PlusRoll:DB$ ReplaceEffect | VarName$ Number | VarValue$ ReplaceCount$Number/Plus.1 | SubAbility$ IgnoreLowest
SVar:IgnoreLowest:DB$ ReplaceEffect | VarName$ Ignore | VarValue$ ReplaceCount$Ignore/Plus.1
Oracle:Flying\nGrant an Advantage — If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll. Oracle:Flying\nGrant an Advantage — If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll.

View File

@@ -2,7 +2,9 @@ Name:Wyll, Blade of Frontiers
ManaCost:1 R ManaCost:1 R
Types:Legendary Creature Human Warlock Types:Legendary Creature Human Warlock
PT:1/1 PT:1/1
S:Mode$ Continuous | Affected$ You | AddKeyword$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll. | Description$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll. R:Event$ RollDice | ActiveZones$ Battlefield | ValidPlayer$ You | ReplaceWith$ PlusRoll | Description$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll.
SVar:PlusRoll:DB$ ReplaceEffect | VarName$ Number | VarValue$ ReplaceCount$Number/Plus.1 | SubAbility$ IgnoreLowest
SVar:IgnoreLowest:DB$ ReplaceEffect | VarName$ Ignore | VarValue$ ReplaceCount$Ignore/Plus.1
T:Mode$ RolledDieOnce | TriggerZones$ Battlefield | ValidPlayer$ You | Execute$ TrigPut | TriggerDescription$ Whenever you roll one or more dice, put a +1/+1 counter on CARDNAME. T:Mode$ RolledDieOnce | TriggerZones$ Battlefield | ValidPlayer$ You | Execute$ TrigPut | TriggerDescription$ Whenever you roll one or more dice, put a +1/+1 counter on CARDNAME.
SVar:TrigPut:DB$ PutCounter | CounterType$ P1P1 SVar:TrigPut:DB$ PutCounter | CounterType$ P1P1
K:Choose a Background K:Choose a Background

View File

@@ -2054,6 +2054,8 @@ lblDoYouWantRepeatProcessAgain=Möchtest du den Vorgang wiederholen?
lblDoYouWantRevealYourHand=Möchtest du deine Handkarten offen vorzeigen? lblDoYouWantRevealYourHand=Möchtest du deine Handkarten offen vorzeigen?
#RollDiceEffect.java #RollDiceEffect.java
lblPlayerRolledResult={0} würfelt {1} lblPlayerRolledResult={0} würfelt {1}
lblIgnoredRolls=Ignorierte Würfelwürfe: {0}
lblRerollResult={0} neu auswürfeln?
#RollPlanarDiceEffect.java #RollPlanarDiceEffect.java
lblPlanarDiceResult=Ergebnis Weltenwürfel: {0} lblPlanarDiceResult=Ergebnis Weltenwürfel: {0}
#SacrificeEffect.java #SacrificeEffect.java

View File

@@ -2059,6 +2059,8 @@ lblDoYouWantRepeatProcessAgain=Do you want to repeat this process again?
lblDoYouWantRevealYourHand=Do you want to reveal your hand? lblDoYouWantRevealYourHand=Do you want to reveal your hand?
#RollDiceEffect.java #RollDiceEffect.java
lblPlayerRolledResult={0} rolled {1} lblPlayerRolledResult={0} rolled {1}
lblIgnoredRolls=Ignored rolls: {0}
lblRerollResult=Reroll {0}?
#RollPlanarDiceEffect.java #RollPlanarDiceEffect.java
lblPlanarDiceResult=Planar dice result: {0} lblPlanarDiceResult=Planar dice result: {0}
#SacrificeEffect.java #SacrificeEffect.java

View File

@@ -2055,8 +2055,10 @@ lblDoYouWantRepeatProcessAgain=¿Quiere repetir este proceso de nuevo?
lblDoYouWantRevealYourHand=¿Quieres descubrir tu mano? lblDoYouWantRevealYourHand=¿Quieres descubrir tu mano?
#RollDiceEffect.java #RollDiceEffect.java
lblPlayerRolledResult={0} lanzó {1} lblPlayerRolledResult={0} lanzó {1}
lblIgnoredRolls=Dados ignorados: {0}
lblRerollResult=¿Volver a tirar {0}?
#RollPlanarDiceEffect.java #RollPlanarDiceEffect.java
lblPlanarDiceResult=Planar dice result: {0} lblPlanarDiceResult=Resultado de los dados planares: {0}
#SacrificeEffect.java #SacrificeEffect.java
lblDoYouWantPayEcho=¿Quieres pagar Eco lblDoYouWantPayEcho=¿Quieres pagar Eco
lblPayEcho=Pagar Eco lblPayEcho=Pagar Eco

View File

@@ -2059,6 +2059,8 @@ lblDoYouWantRepeatProcessAgain=Voulez-vous répéter ce processus à nouveau ?
lblDoYouWantRevealYourHand=Voulez-vous révéler votre main ? lblDoYouWantRevealYourHand=Voulez-vous révéler votre main ?
#RollDiceEffect.java #RollDiceEffect.java
lblPlayerRolledResult={0} a lancé {1} lblPlayerRolledResult={0} a lancé {1}
lblIgnoredRolls=Rouleaux ignorés: {0}
lblRerollResult=Relancez {0} ?
#RollPlanarDiceEffect.java #RollPlanarDiceEffect.java
lblPlanarDiceResult=Planar dice result: {0} lblPlanarDiceResult=Planar dice result: {0}
#SacrificeEffect.java #SacrificeEffect.java

View File

@@ -2055,6 +2055,8 @@ lblDoYouWantRepeatProcessAgain=Vuoi ripetere nuovamente questo procedimento?
lblDoYouWantRevealYourHand=Vuoi rivelare la tua mano? lblDoYouWantRevealYourHand=Vuoi rivelare la tua mano?
#RollDiceEffect.java #RollDiceEffect.java
lblPlayerRolledResult={0} ha ottenuto {1} col dado lblPlayerRolledResult={0} ha ottenuto {1} col dado
lblIgnoredRolls=Tiri ignorati: {0}
lblRerollResult=Rilanciare {0}?
#RollPlanarDiceEffect.java #RollPlanarDiceEffect.java
lblPlanarDiceResult=Planar dice result: {0} lblPlanarDiceResult=Planar dice result: {0}
#SacrificeEffect.java #SacrificeEffect.java

View File

@@ -2054,8 +2054,10 @@ lblDoYouWantRepeatProcessAgain=この手順をもう一度しますか?
lblDoYouWantRevealYourHand=手札を公開しますか? lblDoYouWantRevealYourHand=手札を公開しますか?
#RollDiceEffect.java #RollDiceEffect.java
lblPlayerRolledResult={0}が {1}をロールしました lblPlayerRolledResult={0}が {1}をロールしました
lblIgnoredRolls=無視されたサイコロロール: {0}
lblRerollResult={0}リロール?
#RollPlanarDiceEffect.java #RollPlanarDiceEffect.java
lblPlanarDiceResult=Planar dice result: {0} lblPlanarDiceResult=平面サイコロの結果:{0}
#SacrificeEffect.java #SacrificeEffect.java
lblDoYouWantPayEcho=エコーコストを支払いますか: lblDoYouWantPayEcho=エコーコストを支払いますか:
lblPayEcho=エコーコストを支払います lblPayEcho=エコーコストを支払います

View File

@@ -2116,6 +2116,8 @@ lblDoYouWantRepeatProcessAgain=Quer repetir este processo novamente?
lblDoYouWantRevealYourHand=Você quer revelar sua mão? lblDoYouWantRevealYourHand=Você quer revelar sua mão?
#RollDiceEffect.java #RollDiceEffect.java
lblPlayerRolledResult={0} tirou {1} lblPlayerRolledResult={0} tirou {1}
lblIgnoredRolls=Rolos ignorados: {0}
lblRerollResult=Rolar {0}?
#RollPlanarDiceEffect.java #RollPlanarDiceEffect.java
lblPlanarDiceResult=Planar dice result: {0} lblPlanarDiceResult=Planar dice result: {0}
#SacrificeEffect.java #SacrificeEffect.java

View File

@@ -2059,6 +2059,8 @@ lblDoYouWantRepeatProcessAgain=你是否想再次重复这个过程?
lblDoYouWantRevealYourHand=你想展示你的手牌吗? lblDoYouWantRevealYourHand=你想展示你的手牌吗?
#RollDiceEffect.java #RollDiceEffect.java
lblPlayerRolledResult={0}掷骰结果为{1} lblPlayerRolledResult={0}掷骰结果为{1}
lblIgnoredRolls=忽略的卷: {0}
lblRerollResult=重滚{0}?
#RollPlanarDiceEffect.java #RollPlanarDiceEffect.java
lblPlanarDiceResult=时空骰子点数: {0} lblPlanarDiceResult=时空骰子点数: {0}
#SacrificeEffect.java #SacrificeEffect.java

View File

@@ -484,6 +484,15 @@ public class CardDetailUtil {
area.append("(chosen number: ").append(card.getChosenNumber()).append(")"); area.append("(chosen number: ").append(card.getChosenNumber()).append(")");
} }
// stored dice results
if (card.getStoredRolls() != null) {
if (area.length() != 0) {
area.append("\n");
}
area.append("(stored dice results: ").append(StringUtils.join(card.getStoredRolls(), ", "));
area.append(")");
}
// chosen player // chosen player
if (card.getChosenPlayer() != null) { if (card.getChosenPlayer() != null) {
if (area.length() != 0) { if (area.length() != 0) {

View File

@@ -1413,6 +1413,11 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
return getGui().one(Localizer.getInstance().getMessage("lblChooseRollIgnore"), rolls); return getGui().one(Localizer.getInstance().getMessage("lblChooseRollIgnore"), rolls);
} }
@Override
public Integer chooseRollToIgnore(List<Integer> rolls) {
return getGui().one(Localizer.getInstance().getMessage("lblChooseRollIgnore"), rolls);
}
@Override @Override
public Object vote(final SpellAbility sa, final String prompt, final List<Object> options, public Object vote(final SpellAbility sa, final String prompt, final List<Object> options,
final ListMultimap<Object, Player> votes, Player forPlayer) { final ListMultimap<Object, Player> votes, Player forPlayer) {