mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
Vote: replace hidden keywords with timestamped properties
This commit is contained in:
committed by
Michael Kamensky
parent
d35a2cdead
commit
33d83dc0c5
@@ -2323,7 +2323,7 @@ public class ComputerUtil {
|
|||||||
return chosen;
|
return chosen;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object vote(Player ai, List<Object> options, SpellAbility sa, Multimap<Object, Player> votes) {
|
public static Object vote(Player ai, List<Object> options, SpellAbility sa, Multimap<Object, Player> votes, Player forPlayer) {
|
||||||
final Card source = sa.getHostCard();
|
final Card source = sa.getHostCard();
|
||||||
final Player controller = source.getController();
|
final Player controller = source.getController();
|
||||||
final Game game = controller.getGame();
|
final Game game = controller.getGame();
|
||||||
|
|||||||
@@ -513,8 +513,8 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes) {
|
public Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes, Player forPlayer) {
|
||||||
return ComputerUtil.vote(player, options, sa, votes);
|
return ComputerUtil.vote(player, options, sa, votes, forPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -46,6 +46,12 @@ public class VoteAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int chooseNumber(Player player, SpellAbility sa, int min, int max, Map<String, Object> params) {
|
public int chooseNumber(Player player, SpellAbility sa, int min, int max, Map<String, Object> params) {
|
||||||
|
if (params.containsKey("Voter")) {
|
||||||
|
Player p = (Player)params.get("Voter");
|
||||||
|
if (p.isOpponentOf(player)) {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (sa.getActivatingPlayer().isOpponentOf(player)) {
|
if (sa.getActivatingPlayer().isOpponentOf(player)) {
|
||||||
return min;
|
return min;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -914,4 +914,17 @@ public class Game {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Player getControlVote() {
|
||||||
|
Player result = null;
|
||||||
|
long maxValue = 0;
|
||||||
|
for (Player p : getPlayers()) {
|
||||||
|
Long v = p.getHighestControlVote();
|
||||||
|
if (v != null && v > maxValue) {
|
||||||
|
maxValue = v;
|
||||||
|
result = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,7 +177,6 @@ public class StaticEffect {
|
|||||||
final CardCollectionView remove() {
|
final CardCollectionView remove() {
|
||||||
final CardCollectionView affectedCards = getAffectedCards();
|
final CardCollectionView affectedCards = getAffectedCards();
|
||||||
final List<Player> affectedPlayers = getAffectedPlayers();
|
final List<Player> affectedPlayers = getAffectedPlayers();
|
||||||
//final Map<String, String> params = getParams();
|
|
||||||
|
|
||||||
String changeColorWordsTo = null;
|
String changeColorWordsTo = null;
|
||||||
|
|
||||||
@@ -245,6 +244,10 @@ public class StaticEffect {
|
|||||||
|
|
||||||
p.removeMaxLandPlays(getTimestamp());
|
p.removeMaxLandPlays(getTimestamp());
|
||||||
p.removeMaxLandPlaysInfinite(getTimestamp());
|
p.removeMaxLandPlaysInfinite(getTimestamp());
|
||||||
|
|
||||||
|
p.removeControlVote(getTimestamp());
|
||||||
|
p.removeAdditionalVote(getTimestamp());
|
||||||
|
p.removeAdditionalOptionalVote(getTimestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
// modify the affected card
|
// modify the affected card
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package forge.game.ability.effects;
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -9,9 +10,9 @@ import forge.game.ability.AbilityKey;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.google.common.collect.ArrayListMultimap;
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.ListMultimap;
|
import com.google.common.collect.ListMultimap;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.ability.AbilityFactory;
|
import forge.game.ability.AbilityFactory;
|
||||||
@@ -19,10 +20,7 @@ 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.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
import forge.game.card.CardPredicates;
|
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.player.PlayerCollection;
|
|
||||||
import forge.game.player.PlayerPredicates;
|
|
||||||
import forge.game.spellability.AbilitySub;
|
import forge.game.spellability.AbilitySub;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.trigger.TriggerType;
|
import forge.game.trigger.TriggerType;
|
||||||
@@ -67,33 +65,29 @@ public class VoteEffect extends SpellAbilityEffect {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// starting with the activator
|
|
||||||
int pSize = tgtPlayers.size();
|
|
||||||
Player activator = sa.getActivatingPlayer();
|
Player activator = sa.getActivatingPlayer();
|
||||||
while (tgtPlayers.contains(activator) && !activator.equals(Iterables.getFirst(tgtPlayers, null))) {
|
|
||||||
tgtPlayers.add(pSize - 1, tgtPlayers.remove(0));
|
// starting with the activator
|
||||||
|
int aidx = tgtPlayers.indexOf(activator);
|
||||||
|
if (aidx != -1) {
|
||||||
|
Collections.rotate(tgtPlayers, -aidx);
|
||||||
}
|
}
|
||||||
|
|
||||||
ListMultimap<Object, Player> votes = ArrayListMultimap.create();
|
ListMultimap<Object, Player> votes = ArrayListMultimap.create();
|
||||||
|
|
||||||
Player voter = null;
|
Player voter = game.getControlVote();
|
||||||
|
|
||||||
PlayerCollection voters = game.getPlayers().filter(PlayerPredicates.hasKeyword("You choose how each player votes this turn."));
|
|
||||||
|
|
||||||
if (voters.size() > 1) {
|
|
||||||
List<Card> illusions = CardLists.filter(voters.getCardsIn(ZoneType.Command), CardPredicates.nameEquals("Illusion of Choice Effect"));
|
|
||||||
voter = Collections.max(illusions, CardPredicates.compareByTimestamp()).getController();
|
|
||||||
} else if (voters.size() == 1) {
|
|
||||||
voter = voters.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final Player p : tgtPlayers) {
|
for (final Player p : tgtPlayers) {
|
||||||
int voteAmount = p.getKeywords().getAmount("You get an additional vote.") + 1;
|
int voteAmount = p.getAdditionalVotesAmount() + 1;
|
||||||
int optionalVotes = p.getKeywords().getAmount("You may vote an additional time.");
|
int optionalVotes = p.getAdditionalOptionalVotesAmount();
|
||||||
voteAmount += p.getController().chooseNumber(sa, Localizer.getInstance().getMessage("lblHowManyAdditionalVotesDoYouWant"), 0, optionalVotes);
|
|
||||||
Player realVoter = voter == null ? p : voter;
|
Player realVoter = voter == null ? p : voter;
|
||||||
|
|
||||||
|
Map<String, Object> params = Maps.newHashMap();
|
||||||
|
params.put("Voter", realVoter);
|
||||||
|
voteAmount += p.getController().chooseNumber(sa, Localizer.getInstance().getMessage("lblHowManyAdditionalVotesDoYouWant"), 0, optionalVotes, params);
|
||||||
|
|
||||||
for (int i = 0; i < voteAmount; i++) {
|
for (int i = 0; i < voteAmount; i++) {
|
||||||
Object result = realVoter.getController().vote(sa, host + Localizer.getInstance().getMessage("lblVote") + ":", voteType, votes);
|
Object result = realVoter.getController().vote(sa, host + Localizer.getInstance().getMessage("lblVote") + ":", voteType, votes, p);
|
||||||
|
|
||||||
votes.put(result, p);
|
votes.put(result, p);
|
||||||
host.getGame().getAction().nofityOfValue(sa, p, result + "\r\n" + Localizer.getInstance().getMessage("lblCurrentVote") + ":" + votes, p);
|
host.getGame().getAction().nofityOfValue(sa, p, result + "\r\n" + Localizer.getInstance().getMessage("lblCurrentVote") + ":" + votes, p);
|
||||||
@@ -104,34 +98,49 @@ public class VoteEffect extends SpellAbilityEffect {
|
|||||||
runParams.put(AbilityKey.AllVotes, votes);
|
runParams.put(AbilityKey.AllVotes, votes);
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.Vote, runParams, false);
|
game.getTriggerHandler().runTrigger(TriggerType.Vote, runParams, false);
|
||||||
|
|
||||||
List<String> subAbs = Lists.newArrayList();
|
if (sa.hasParam("EachVote")) {
|
||||||
final List<Object> mostVotes = getMostVotes(votes);
|
for (Map.Entry<Object, Collection<Player>> e : votes.asMap().entrySet()) {
|
||||||
if (sa.hasParam("Tied") && mostVotes.size() > 1) {
|
final SpellAbility action = AbilityFactory.getAbility(host, sa.getParam("Vote" + e.getKey().toString()));
|
||||||
subAbs.add(sa.getParam("Tied"));
|
|
||||||
} else if (sa.hasParam("VoteSubAbility")) {
|
|
||||||
for (final Object o : mostVotes) {
|
|
||||||
host.addRemembered(o);
|
|
||||||
}
|
|
||||||
subAbs.add(sa.getParam("VoteSubAbility"));
|
|
||||||
} else {
|
|
||||||
for (Object type : mostVotes) {
|
|
||||||
subAbs.add(sa.getParam("Vote" + type.toString()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sa.hasParam("StoreVoteNum")) {
|
|
||||||
for (final Object type : voteType) {
|
|
||||||
host.setSVar("VoteNum" + type, "Number$" + votes.get(type).size());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (final String subAb : subAbs) {
|
|
||||||
final SpellAbility action = AbilityFactory.getAbility(host.getSVar(subAb), host);
|
|
||||||
action.setActivatingPlayer(sa.getActivatingPlayer());
|
action.setActivatingPlayer(sa.getActivatingPlayer());
|
||||||
((AbilitySub) action).setParent(sa);
|
((AbilitySub) action).setParent(sa);
|
||||||
AbilityUtils.resolve(action);
|
|
||||||
|
for (Player p : e.getValue()) {
|
||||||
|
host.addRemembered(p);
|
||||||
|
AbilityUtils.resolve(action);
|
||||||
|
host.removeRemembered(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
List<String> subAbs = Lists.newArrayList();
|
||||||
|
final List<Object> mostVotes = getMostVotes(votes);
|
||||||
|
if (sa.hasParam("Tied") && mostVotes.size() > 1) {
|
||||||
|
subAbs.add(sa.getParam("Tied"));
|
||||||
|
} else if (sa.hasParam("VoteSubAbility")) {
|
||||||
|
for (final Object o : mostVotes) {
|
||||||
|
host.addRemembered(o);
|
||||||
|
}
|
||||||
|
subAbs.add(sa.getParam("VoteSubAbility"));
|
||||||
|
} else {
|
||||||
|
for (Object type : mostVotes) {
|
||||||
|
subAbs.add(sa.getParam("Vote" + type.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sa.hasParam("StoreVoteNum")) {
|
||||||
|
for (final Object type : voteType) {
|
||||||
|
host.setSVar("VoteNum" + type, "Number$" + votes.get(type).size());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (final String subAb : subAbs) {
|
||||||
|
final SpellAbility action = AbilityFactory.getAbility(host, subAb);
|
||||||
|
action.setActivatingPlayer(sa.getActivatingPlayer());
|
||||||
|
((AbilitySub) action).setParent(sa);
|
||||||
|
AbilityUtils.resolve(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sa.hasParam("VoteSubAbility")) {
|
||||||
|
host.clearRemembered();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (sa.hasParam("VoteSubAbility")) {
|
|
||||||
host.clearRemembered();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3938,7 +3938,9 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
keywordsGrantedByTextChanges.add(newKw);
|
keywordsGrantedByTextChanges.add(newKw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addChangedCardKeywordsInternal(addKeywords, removeKeywords, false, false, timestamp, true);
|
if (!addKeywords.isEmpty() || !removeKeywords.isEmpty()) {
|
||||||
|
addChangedCardKeywordsInternal(addKeywords, removeKeywords, false, false, timestamp, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateKeywordsOnRemoveChangedText(final KeywordsChange k) {
|
private void updateKeywordsOnRemoveChangedText(final KeywordsChange k) {
|
||||||
|
|||||||
@@ -162,6 +162,10 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
private Card blessingEffect = null;
|
private Card blessingEffect = null;
|
||||||
private Card keywordEffect = null;
|
private Card keywordEffect = null;
|
||||||
|
|
||||||
|
private Map<Long, Integer> additionalVotes = Maps.newHashMap();
|
||||||
|
private Map<Long, Integer> additionalOptionalVotes = Maps.newHashMap();
|
||||||
|
private SortedSet<Long> controlVotes = Sets.newTreeSet();
|
||||||
|
|
||||||
private final AchievementTracker achievementTracker = new AchievementTracker();
|
private final AchievementTracker achievementTracker = new AchievementTracker();
|
||||||
private final PlayerView view;
|
private final PlayerView view;
|
||||||
|
|
||||||
@@ -3067,4 +3071,86 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
this.updateZoneForView(com);
|
this.updateZoneForView(com);
|
||||||
return keywordEffect;
|
return keywordEffect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addAdditionalVote(long timestamp, int value) {
|
||||||
|
additionalVotes.put(timestamp, value);
|
||||||
|
getView().updateAdditionalVote(this);
|
||||||
|
getGame().fireEvent(new GameEventPlayerStatsChanged(this, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeAdditionalVote(long timestamp) {
|
||||||
|
if (additionalVotes.remove(timestamp) != null) {
|
||||||
|
getView().updateAdditionalVote(this);
|
||||||
|
getGame().fireEvent(new GameEventPlayerStatsChanged(this, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAdditionalVotesAmount() {
|
||||||
|
int value = 0;
|
||||||
|
for (Integer i : additionalVotes.values()) {
|
||||||
|
value += i;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAdditionalOptionalVote(long timestamp, int value) {
|
||||||
|
additionalOptionalVotes.put(timestamp, value);
|
||||||
|
getView().updateOptionalAdditionalVote(this);
|
||||||
|
getGame().fireEvent(new GameEventPlayerStatsChanged(this, false));
|
||||||
|
}
|
||||||
|
public void removeAdditionalOptionalVote(long timestamp) {
|
||||||
|
if (additionalOptionalVotes.remove(timestamp) != null) {
|
||||||
|
getView().updateOptionalAdditionalVote(this);
|
||||||
|
getGame().fireEvent(new GameEventPlayerStatsChanged(this, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAdditionalOptionalVotesAmount() {
|
||||||
|
int value = 0;
|
||||||
|
for (Integer i : additionalOptionalVotes.values()) {
|
||||||
|
value += i;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addControlVote(long timestamp) {
|
||||||
|
if (controlVotes.add(timestamp)) {
|
||||||
|
updateControlVote();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public boolean removeControlVote(long timestamp) {
|
||||||
|
if (controlVotes.remove(timestamp)) {
|
||||||
|
updateControlVote();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateControlVote() {
|
||||||
|
// need to update all players because it can't know
|
||||||
|
Player control = getGame().getControlVote();
|
||||||
|
for (Player pl : getGame().getPlayers()) {
|
||||||
|
pl.getView().updateControlVote(pl.equals(control));
|
||||||
|
getGame().fireEvent(new GameEventPlayerStatsChanged(pl, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Long> getControlVote() {
|
||||||
|
return controlVotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setControlVote(Set<Long> value) {
|
||||||
|
controlVotes.clear();
|
||||||
|
controlVotes.addAll(value);
|
||||||
|
updateControlVote();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getHighestControlVote() {
|
||||||
|
if (controlVotes.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return controlVotes.last();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ public abstract class PlayerController {
|
|||||||
return chooseSomeType(kindOfType, sa, validTypes, invalidTypes, false);
|
return chooseSomeType(kindOfType, sa, validTypes, invalidTypes, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes);
|
public abstract Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes, Player forPlayer);
|
||||||
public abstract boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, String question);
|
public abstract boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, String question);
|
||||||
|
|
||||||
public abstract CardCollectionView getCardsToMulligan(Player firstPlayer);
|
public abstract CardCollectionView getCardsToMulligan(Player firstPlayer);
|
||||||
|
|||||||
@@ -271,6 +271,27 @@ public class PlayerView extends GameEntityView {
|
|||||||
set(TrackableProperty.NumDrawnThisTurn, p.getNumDrawnThisTurn());
|
set(TrackableProperty.NumDrawnThisTurn, p.getNumDrawnThisTurn());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getAdditionalVote() {
|
||||||
|
return get(TrackableProperty.AdditionalVote);
|
||||||
|
}
|
||||||
|
public void updateAdditionalVote(Player p) {
|
||||||
|
set(TrackableProperty.AdditionalVote, p.getAdditionalVotesAmount());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOptionalAdditionalVote() {
|
||||||
|
return get(TrackableProperty.OptionalAdditionalVote);
|
||||||
|
}
|
||||||
|
public void updateOptionalAdditionalVote(Player p) {
|
||||||
|
set(TrackableProperty.OptionalAdditionalVote, p.getAdditionalOptionalVotesAmount());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getControlVote() {
|
||||||
|
return get(TrackableProperty.ControlVotes);
|
||||||
|
}
|
||||||
|
public void updateControlVote(boolean val) {
|
||||||
|
set(TrackableProperty.ControlVotes, val);
|
||||||
|
}
|
||||||
|
|
||||||
public ImmutableMultiset<String> getKeywords() {
|
public ImmutableMultiset<String> getKeywords() {
|
||||||
return get(TrackableProperty.Keywords);
|
return get(TrackableProperty.Keywords);
|
||||||
}
|
}
|
||||||
@@ -497,6 +518,19 @@ public class PlayerView extends GameEntityView {
|
|||||||
details.add(Localizer.getInstance().getMessage("lblCardDrawnThisTurnHas", String.valueOf(getNumDrawnThisTurn())));
|
details.add(Localizer.getInstance().getMessage("lblCardDrawnThisTurnHas", String.valueOf(getNumDrawnThisTurn())));
|
||||||
details.add(Localizer.getInstance().getMessage("lblDamagepreventionHas", String.valueOf(getPreventNextDamage())));
|
details.add(Localizer.getInstance().getMessage("lblDamagepreventionHas", String.valueOf(getPreventNextDamage())));
|
||||||
|
|
||||||
|
int v = getAdditionalVote();
|
||||||
|
if (v > 0) {
|
||||||
|
details.add(Localizer.getInstance().getMessage("lblAdditionalVotes", String.valueOf(v)));
|
||||||
|
}
|
||||||
|
v = getOptionalAdditionalVote();
|
||||||
|
if (v > 0) {
|
||||||
|
details.add(Localizer.getInstance().getMessage("lblOptionalAdditionalVotes", String.valueOf(v)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getControlVote()) {
|
||||||
|
details.add(Localizer.getInstance().getMessage("lblControlsVote"));
|
||||||
|
}
|
||||||
|
|
||||||
if (getIsExtraTurn()) {
|
if (getIsExtraTurn()) {
|
||||||
details.add(Localizer.getInstance().getMessage("lblIsExtraTurn"));
|
details.add(Localizer.getInstance().getMessage("lblIsExtraTurn"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,15 +181,9 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
|||||||
layers.add(StaticAbilityLayer.MODIFYPT);
|
layers.add(StaticAbilityLayer.MODIFYPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasParam("AddHiddenKeyword")) {
|
if (hasParam("AddHiddenKeyword")
|
||||||
layers.add(StaticAbilityLayer.RULES);
|
|| hasParam("IgnoreEffectCost") || hasParam("Goad") || hasParam("CanBlockAny") || hasParam("CanBlockAmount")
|
||||||
}
|
|| hasParam("AdjustLandPlays") || hasParam("ControlVote") || hasParam("AdditionalVote") || hasParam("AdditionalOptionalVote")) {
|
||||||
|
|
||||||
if (hasParam("IgnoreEffectCost") || hasParam("Goad") || hasParam("CanBlockAny") || hasParam("CanBlockAmount")) {
|
|
||||||
layers.add(StaticAbilityLayer.RULES);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasParam("AdjustLandPlays")) {
|
|
||||||
layers.add(StaticAbilityLayer.RULES);
|
layers.add(StaticAbilityLayer.RULES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -513,6 +513,20 @@ public final class StaticAbilityContinuous {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params.containsKey("ControlVote")) {
|
||||||
|
p.addControlVote(se.getTimestamp());
|
||||||
|
}
|
||||||
|
if (params.containsKey("AdditionalVote")) {
|
||||||
|
String mhs = params.get("AdditionalVote");
|
||||||
|
int add = AbilityUtils.calculateAmount(hostCard, mhs, stAb);
|
||||||
|
p.addAdditionalVote(se.getTimestamp(), add);
|
||||||
|
}
|
||||||
|
if (params.containsKey("AdditionalOptionalVote")) {
|
||||||
|
String mhs = params.get("AdditionalOptionalVote");
|
||||||
|
int add = AbilityUtils.calculateAmount(hostCard, mhs, stAb);
|
||||||
|
p.addAdditionalOptionalVote(se.getTimestamp(), add);
|
||||||
|
}
|
||||||
|
|
||||||
if (params.containsKey("RaiseMaxHandSize")) {
|
if (params.containsKey("RaiseMaxHandSize")) {
|
||||||
String rmhs = params.get("RaiseMaxHandSize");
|
String rmhs = params.get("RaiseMaxHandSize");
|
||||||
int rmax = AbilityUtils.calculateAmount(hostCard, rmhs, stAb);
|
int rmax = AbilityUtils.calculateAmount(hostCard, rmhs, stAb);
|
||||||
|
|||||||
@@ -134,6 +134,9 @@ public enum TrackableProperty {
|
|||||||
HasUnlimitedLandPlay(TrackableTypes.BooleanType),
|
HasUnlimitedLandPlay(TrackableTypes.BooleanType),
|
||||||
NumLandThisTurn(TrackableTypes.IntegerType),
|
NumLandThisTurn(TrackableTypes.IntegerType),
|
||||||
NumDrawnThisTurn(TrackableTypes.IntegerType),
|
NumDrawnThisTurn(TrackableTypes.IntegerType),
|
||||||
|
AdditionalVote(TrackableTypes.IntegerType),
|
||||||
|
OptionalAdditionalVote(TrackableTypes.IntegerType),
|
||||||
|
ControlVotes(TrackableTypes.BooleanType),
|
||||||
Keywords(TrackableTypes.KeywordCollectionViewType, FreezeMode.IgnoresFreeze),
|
Keywords(TrackableTypes.KeywordCollectionViewType, FreezeMode.IgnoresFreeze),
|
||||||
Commander(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
Commander(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
CommanderCast(TrackableTypes.IntegerMapType),
|
CommanderCast(TrackableTypes.IntegerMapType),
|
||||||
|
|||||||
@@ -486,7 +486,7 @@ public class PlayerControllerForTests extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes) {
|
public Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes, Player forPlayer) {
|
||||||
return chooseItem(options);
|
return chooseItem(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ Name:Ballot Broker
|
|||||||
ManaCost:2 W
|
ManaCost:2 W
|
||||||
Types:Creature Human Advisor
|
Types:Creature Human Advisor
|
||||||
PT:2/3
|
PT:2/3
|
||||||
S:Mode$ Continuous | Affected$ You | AddKeyword$ You may vote an additional time. | Description$ While voting, you may vote an additional time. (The votes can be for different choices or for the same choice.)
|
S:Mode$ Continuous | Affected$ You | AdditionalOptionalVote$ 1 | Description$ While voting, you may vote an additional time. (The votes can be for different choices or for the same choice.)
|
||||||
Oracle:While voting, you may vote an additional time. (The votes can be for different choices or for the same choice.)
|
Oracle:While voting, you may vote an additional time. (The votes can be for different choices or for the same choice.)
|
||||||
@@ -2,6 +2,6 @@ Name:Brago's Representative
|
|||||||
ManaCost:2 W
|
ManaCost:2 W
|
||||||
Types:Creature Human Advisor
|
Types:Creature Human Advisor
|
||||||
PT:1/4
|
PT:1/4
|
||||||
S:Mode$ Continuous | Affected$ You | AddKeyword$ You get an additional vote. | Description$ While voting, you get an additional vote. (The votes can be for different choices or for the same choice.)
|
S:Mode$ Continuous | Affected$ You | AdditionalVote$ 1 | Description$ While voting, you get an additional vote. (The votes can be for different choices or for the same choice.)
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/bragos_representative.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/bragos_representative.jpg
|
||||||
Oracle:While voting, you get an additional vote. (The votes can be for different choices or for the same choice.)
|
Oracle:While voting, you get an additional vote. (The votes can be for different choices or for the same choice.)
|
||||||
|
|||||||
9
forge-gui/res/cardsfolder/e/expropriate.txt
Normal file
9
forge-gui/res/cardsfolder/e/expropriate.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Name:Expropriate
|
||||||
|
ManaCost:7 U U
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ Vote | Cost$ 7 U U | Defined$ Player | VoteType$ Time,Money | VoteTime$ DBTime | VoteMoney$ DBMoney | EachVote$ True | SubAbility$ DBChange | SpellDescription$ Council’s dilemma — Starting with you, each player votes for time or money. For each time vote, take an extra turn after this one. For each money vote, choose a permanent owned by the voter and gain control of it. Exile Expropriate.
|
||||||
|
SVar:DBTime:DB$ AddTurn | Defined$ You | NumTurns$ 1
|
||||||
|
SVar:DBMoney:DB$ ChooseCard | Defined$ You | Choices$ Permanent.RememberedPlayerOwn | SubAbility$ DBControl
|
||||||
|
SVar:DBControl:DB$ GainControl | Defined$ ChosenCard | NewController$ You
|
||||||
|
SVar:DBChange:DB$ ChangeZone | Origin$ Stack | Destination$ Exile | StackDescription$ None
|
||||||
|
Oracle:Council’s dilemma — Starting with you, each player votes for time or money. For each time vote, take an extra turn after this one. For each money vote, choose a permanent owned by the voter and gain control of it. Exile Expropriate.
|
||||||
@@ -3,6 +3,6 @@ ManaCost:U
|
|||||||
Types:Instant
|
Types:Instant
|
||||||
A:SP$ Effect | Cost$ U | Name$ Illusion of Choice Effect | StaticAbilities$ STVoter | SubAbility$ DBDraw | SpellDescription$ You choose how each player votes this turn. Draw a card.
|
A:SP$ Effect | Cost$ U | Name$ Illusion of Choice Effect | StaticAbilities$ STVoter | SubAbility$ DBDraw | SpellDescription$ You choose how each player votes this turn. Draw a card.
|
||||||
SVar:DBDraw:DB$ Draw | NumCards$ 1
|
SVar:DBDraw:DB$ Draw | NumCards$ 1
|
||||||
SVar:STVoter:Mode$ Continuous | EffectZone$ Command | Affected$ You | AddKeyword$ You choose how each player votes this turn. | Description$ You choose how each player votes this turn.
|
SVar:STVoter:Mode$ Continuous | EffectZone$ Command | Affected$ You | ControlVote$ True | Description$ You choose how each player votes this turn.
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
Oracle:You choose how each player votes this turn. Draw a card.
|
Oracle:You choose how each player votes this turn. Draw a card.
|
||||||
@@ -2010,6 +2010,9 @@ lblDamagepreventionHas=Damage prevention: {0}
|
|||||||
lblIsExtraTurn=Extra Turn: Yes
|
lblIsExtraTurn=Extra Turn: Yes
|
||||||
lblExtraTurnCountHas=Extra Turn Count: {0}
|
lblExtraTurnCountHas=Extra Turn Count: {0}
|
||||||
lblAntedHas=Ante''d: {0}
|
lblAntedHas=Ante''d: {0}
|
||||||
|
lblAdditionalVotes=You get {0} additional votes.
|
||||||
|
lblOptionalAdditionalVotes=You may vote {0} additional times.
|
||||||
|
lblControlsVote=You choose how each player votes.
|
||||||
#VStack.java
|
#VStack.java
|
||||||
lblAlwaysYes=Always Yes
|
lblAlwaysYes=Always Yes
|
||||||
lblAlwaysNo=Always No
|
lblAlwaysNo=Always No
|
||||||
|
|||||||
@@ -1181,7 +1181,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
|
|
||||||
@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) {
|
final ListMultimap<Object, Player> votes, Player forPlayer) {
|
||||||
return getGui().one(prompt, options);
|
return getGui().one(prompt, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user