mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
Merge pull request #3944 from Northmoc/bamboozle
bamboozling_beeble.txt and centaur_of_attention.txt and Support
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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"),
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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),
|
||||||
|
|||||||
@@ -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)),
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
12
forge-gui/res/cardsfolder/b/bamboozling_beeble.txt
Normal file
12
forge-gui/res/cardsfolder/b/bamboozling_beeble.txt
Normal 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.
|
||||||
@@ -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
|
||||||
|
|||||||
11
forge-gui/res/cardsfolder/c/centaur_of_attention.txt
Normal file
11
forge-gui/res/cardsfolder/c/centaur_of_attention.txt
Normal 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.
|
||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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=エコーコストを支払います
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user