Merge branch 'newBranch' into 'master'

Add feature request

See merge request core-developers/forge!2179
This commit is contained in:
Hans Mackowiak
2019-09-27 12:16:07 +00:00
9 changed files with 60 additions and 0 deletions

View File

@@ -3659,6 +3659,8 @@ public class Card extends GameEntity implements Comparable<Card> {
if (updateView) { if (updateView) {
updateKeywords(); updateKeywords();
if (isToken())
game.fireEvent(new GameEventTokenStateUpdate(this));
} }
} }
@@ -3713,6 +3715,8 @@ public class Card extends GameEntity implements Comparable<Card> {
KeywordsChange change = changedCardKeywords.remove(timestamp); KeywordsChange change = changedCardKeywords.remove(timestamp);
if (change != null && updateView) { if (change != null && updateView) {
updateKeywords(); updateKeywords();
if (isToken())
game.fireEvent(new GameEventTokenStateUpdate(this));
} }
return change; return change;
} }
@@ -5460,6 +5464,14 @@ public class Card extends GameEntity implements Comparable<Card> {
} }
return hexproofKey; return hexproofKey;
} }
public String getKeywordKey() {
List<String> ability = new ArrayList<>();
for (final KeywordInterface inst : getKeywords()) {
ability.add(inst.getOriginal());
}
Collections.sort(ability);
return String.join(",", ability);
}
public Zone getZone() { public Zone getZone() {
return currentZone; return currentZone;
} }

View File

@@ -1017,6 +1017,7 @@ public class CardView extends GameEntityView {
foilIndexOverride = index0; foilIndexOverride = index0;
} }
public String getKeywordKey() { return get(TrackableProperty.KeywordKey); }
public String getProtectionKey() { return get(TrackableProperty.ProtectionKey); } public String getProtectionKey() { return get(TrackableProperty.ProtectionKey); }
public String getHexproofKey() { return get(TrackableProperty.HexproofKey); } public String getHexproofKey() { return get(TrackableProperty.HexproofKey); }
public boolean hasDeathtouch() { return get(TrackableProperty.HasDeathtouch); } public boolean hasDeathtouch() { return get(TrackableProperty.HasDeathtouch); }
@@ -1076,6 +1077,8 @@ public class CardView extends GameEntityView {
set(TrackableProperty.ProtectionKey, c.getProtectionKey()); set(TrackableProperty.ProtectionKey, c.getProtectionKey());
//set hexproofKeys for Icons //set hexproofKeys for Icons
set(TrackableProperty.HexproofKey, c.getHexproofKey()); set(TrackableProperty.HexproofKey, c.getHexproofKey());
//keywordkey
set(TrackableProperty.KeywordKey, c.getKeywordKey());
} }
public boolean isBasicLand() { public boolean isBasicLand() {

View File

@@ -0,0 +1,24 @@
package forge.game.event;
import forge.game.card.Card;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class GameEventTokenStateUpdate extends GameEvent {
public final Collection<Card> cards;
public GameEventTokenStateUpdate(Card affected) {
cards = Arrays.asList(affected);
}
public GameEventTokenStateUpdate(List<Card> affected) {
cards = affected;
}
@Override
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
}

View File

@@ -37,6 +37,7 @@ public interface IGameEventVisitor<T> {
T visit(GameEventPlayerPoisoned event); T visit(GameEventPlayerPoisoned event);
T visit(GameEventPlayerPriority event); T visit(GameEventPlayerPriority event);
T visit(GameEventPlayerStatsChanged event); T visit(GameEventPlayerStatsChanged event);
T visit(GameEventTokenStateUpdate event);
T visit(GameEventScry event); T visit(GameEventScry event);
T visit(GameEventShuffle event); T visit(GameEventShuffle event);
T visit(GameEventSpellAbilityCast gameEventSpellAbilityCast); T visit(GameEventSpellAbilityCast gameEventSpellAbilityCast);
@@ -83,6 +84,7 @@ public interface IGameEventVisitor<T> {
public T visit(GameEventPlayerPoisoned event) { return null; } public T visit(GameEventPlayerPoisoned event) { return null; }
public T visit(GameEventPlayerPriority event) { return null; } public T visit(GameEventPlayerPriority event) { return null; }
public T visit(GameEventPlayerStatsChanged event) { return null; } public T visit(GameEventPlayerStatsChanged event) { return null; }
public T visit(GameEventTokenStateUpdate event) { return null; }
public T visit(GameEventScry event) { return null; } public T visit(GameEventScry event) { return null; }
public T visit(GameEventShuffle event) { return null; } public T visit(GameEventShuffle event) { return null; }
public T visit(GameEventSpellResolved event) { return null; } public T visit(GameEventSpellResolved event) { return null; }

View File

@@ -189,6 +189,8 @@ public class PhaseHandler implements java.io.Serializable {
final List<Card> lands = CardLists.filter(playerTurn.getLandsInPlay(), Presets.UNTAPPED); final List<Card> lands = CardLists.filter(playerTurn.getLandsInPlay(), Presets.UNTAPPED);
playerTurn.setNumPowerSurgeLands(lands.size()); playerTurn.setNumPowerSurgeLands(lands.size());
} }
//update tokens
game.fireEvent(new GameEventTokenStateUpdate(playerTurn.getTokensInPlay()));
game.fireEvent(new GameEventTurnPhase(playerTurn, phase, phaseType)); game.fireEvent(new GameEventTurnPhase(playerTurn, phase, phaseType));
} }

View File

@@ -2362,6 +2362,13 @@ public class Player extends GameEntity implements Comparable<Player> {
return CardLists.filter(getCardsIn(ZoneType.Battlefield), Presets.CREATURES); return CardLists.filter(getCardsIn(ZoneType.Battlefield), Presets.CREATURES);
} }
/**
* use to get a list of tokens in play for a given player.
*/
public CardCollection getTokensInPlay() {
return CardLists.filter(getCardsIn(ZoneType.Battlefield), Presets.TOKEN);
}
/** /**
* use to get a list of all lands a given player has on the battlefield. * use to get a list of all lands a given player has on the battlefield.
*/ */

View File

@@ -82,6 +82,7 @@ public enum TrackableProperty {
ChangedColorWords(TrackableTypes.StringMapType), ChangedColorWords(TrackableTypes.StringMapType),
ChangedTypes(TrackableTypes.StringMapType), ChangedTypes(TrackableTypes.StringMapType),
KeywordKey(TrackableTypes.StringType),
HasDeathtouch(TrackableTypes.BooleanType), HasDeathtouch(TrackableTypes.BooleanType),
HasDefender(TrackableTypes.BooleanType), HasDefender(TrackableTypes.BooleanType),
HasDoubleStrike(TrackableTypes.BooleanType), HasDoubleStrike(TrackableTypes.BooleanType),

View File

@@ -110,6 +110,9 @@ public class VField extends FContainer {
if (!c.hasCardAttachments() && if (!c.hasCardAttachments() &&
cardName.equals(c.getCurrentState().getName()) && cardName.equals(c.getCurrentState().getName()) &&
card.hasSameCounters(c) && card.hasSameCounters(c) &&
card.getCurrentState().getKeywordKey().equals(c.getCurrentState().getKeywordKey()) &&
card.isTapped() == c.isTapped() && // don't stack tapped tokens on untapped tokens
card.isSick() == c.isSick() && //don't stack sick tokens on non sick
card.isToken() == c.isToken()) { //don't stack tokens on top of non-tokens card.isToken() == c.isToken()) { //don't stack tokens on top of non-tokens
CardAreaPanel cPanel = CardAreaPanel.get(c); CardAreaPanel cPanel = CardAreaPanel.get(c);
while (cPanel.getNextPanelInStack() != null) { while (cPanel.getNextPanelInStack() != null) {

View File

@@ -357,6 +357,12 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
return processCards(cards, cardsRefreshDetails); return processCards(cards, cardsRefreshDetails);
} }
@Override
public Void visit(final GameEventTokenStateUpdate event) {
processCards(event.cards, cardsRefreshDetails);
return processCards(event.cards, cardsUpdate);
}
@Override @Override
public Void visit(final GameEventShuffle event) { public Void visit(final GameEventShuffle event) {
//pfps the change to the library has already been performed by a setCards call //pfps the change to the library has already been performed by a setCards call