mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
- Move changed card colors to the Card rather than CardState
- Fix Kusari-Gama
This commit is contained in:
@@ -262,7 +262,6 @@ public class GameAction {
|
||||
}
|
||||
|
||||
if (!c.isToken() && !toBattlefield) {
|
||||
copied.getCurrentState().resetCardColor();
|
||||
copied.clearDevoured();
|
||||
copied.clearDelved();
|
||||
}
|
||||
|
||||
@@ -120,8 +120,9 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
private final Map<Player, CardPlayOption> mayPlay = Maps.newTreeMap();
|
||||
|
||||
// changes by AF animate and continuous static effects - timestamp is the key of maps
|
||||
private Map<Long, CardChangedType> changedCardTypes = new ConcurrentSkipListMap<Long, CardChangedType>();
|
||||
private Map<Long, KeywordsChange> changedCardKeywords = new ConcurrentSkipListMap<Long, KeywordsChange>();
|
||||
private final Map<Long, CardChangedType> changedCardTypes = new ConcurrentSkipListMap<Long, CardChangedType>();
|
||||
private final Map<Long, KeywordsChange> changedCardKeywords = new ConcurrentSkipListMap<Long, KeywordsChange>();
|
||||
private final SortedMap<Long, CardColor> changedCardColors = new ConcurrentSkipListMap<Long, CardColor>();
|
||||
|
||||
// changes that say "replace each instance of one [color,type] by another - timestamp is the key of maps
|
||||
private final CardChangedWords changedTextColors = new CardChangedWords();
|
||||
@@ -739,7 +740,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
return colorsPaid;
|
||||
}
|
||||
public final void setColorsPaid(final byte s) {
|
||||
colorsPaid = s; // TODO: Append colors instead of replacing
|
||||
colorsPaid |= s;
|
||||
}
|
||||
|
||||
public final int getXManaCostPaid() {
|
||||
@@ -1080,29 +1081,6 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
return currentState.getManaCost();
|
||||
}
|
||||
|
||||
public final void addColor(final String s, final boolean addToColors, final long timestamp) {
|
||||
currentState.addColor(s, addToColors, timestamp);
|
||||
}
|
||||
|
||||
public final void removeColor(final long timestamp) {
|
||||
currentState.removeColor(timestamp);
|
||||
}
|
||||
|
||||
public final void setColor(final byte color) {
|
||||
currentState.setColor(new CardColor(color));
|
||||
}
|
||||
public final void setColor(final String color) {
|
||||
currentState.setColor(new CardColor(color));
|
||||
}
|
||||
|
||||
public final ColorSet determineColor() {
|
||||
if (isImmutable()) {
|
||||
return ColorSet.getNullColor();
|
||||
}
|
||||
|
||||
return currentState.determineColor();
|
||||
}
|
||||
|
||||
public final Player getChosenPlayer() {
|
||||
return chosenPlayer;
|
||||
}
|
||||
@@ -2449,6 +2427,41 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
currentState.getView().updateType(currentState);
|
||||
}
|
||||
|
||||
public final void addColor(final String s, final boolean addToColors, final long timestamp) {
|
||||
changedCardColors.put(timestamp, new CardColor(s, addToColors, timestamp));
|
||||
currentState.getView().updateColors(this);
|
||||
}
|
||||
|
||||
public final void removeColor(final long timestampIn) {
|
||||
final CardColor removeCol = changedCardColors.remove(timestampIn);
|
||||
|
||||
if (removeCol != null) {
|
||||
currentState.getView().updateColors(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final void setColor(final String color) {
|
||||
currentState.setColor(color);
|
||||
currentState.getView().updateColors(this);
|
||||
}
|
||||
public final void setColor(final byte color) {
|
||||
currentState.setColor(color);
|
||||
currentState.getView().updateColors(this);
|
||||
}
|
||||
|
||||
public final ColorSet determineColor() {
|
||||
final Iterable<CardColor> colorList = changedCardColors.values();
|
||||
byte colors = currentState.getColor();
|
||||
for (final CardColor cc : colorList) {
|
||||
if (cc.isAdditional()) {
|
||||
colors |= cc.getColorMask();
|
||||
} else {
|
||||
colors = cc.getColorMask();
|
||||
}
|
||||
}
|
||||
return ColorSet.fromMask(colors);
|
||||
}
|
||||
|
||||
// values that are printed on card
|
||||
public final int getBaseLoyalty() {
|
||||
return baseLoyalty;
|
||||
@@ -3687,6 +3700,11 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
if (!getOwner().isValid(valid, sourceController, source)) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.startsWith("ControlledBy")) {
|
||||
final String valid = property.substring(13);
|
||||
if (!getController().isValid(valid, sourceController, source)) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.startsWith("OwnerDoesntControl")) {
|
||||
if (getOwner().equals(getController())) {
|
||||
return false;
|
||||
@@ -5588,6 +5606,8 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
runParams.put("DamageTarget", this);
|
||||
runParams.put("DamageAmount", damageToAdd);
|
||||
runParams.put("IsCombatDamage", isCombat);
|
||||
// Defending player at the time the damage was dealt
|
||||
runParams.put("DefendingPlayer", game.getCombat() != null ? game.getCombat().getDefendingPlayerRelatedTo(source) : null);
|
||||
getGame().getTriggerHandler().runTrigger(TriggerType.DamageDone, runParams, false);
|
||||
|
||||
GameEventCardDamaged.DamageType damageType = DamageType.Normal;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
package forge.game.card;
|
||||
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.card.mana.ManaCostParser;
|
||||
|
||||
@@ -45,23 +44,10 @@ public class CardColor {
|
||||
return this.timestamp;
|
||||
}
|
||||
|
||||
CardColor(final String colors) {
|
||||
this(colors, false, 0L);
|
||||
}
|
||||
CardColor(final String colors, final boolean addToColors, final long timestamp) {
|
||||
final ManaCost mc = new ManaCost(new ManaCostParser(colors));
|
||||
this.colorMask = mc.getColorProfile();
|
||||
this.additional = addToColors;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
CardColor(final byte mask) {
|
||||
this.colorMask = mask;
|
||||
this.additional = false;
|
||||
this.timestamp = 0;
|
||||
}
|
||||
|
||||
public final ColorSet toColorSet() {
|
||||
return ColorSet.fromMask(colorMask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,21 +20,19 @@ package forge.game.card;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.CardRarity;
|
||||
import forge.card.CardType;
|
||||
import forge.card.CardTypeView;
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.card.mana.ManaCostParser;
|
||||
import forge.game.card.CardView.CardStateView;
|
||||
import forge.game.replacement.ReplacementEffect;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
@@ -47,7 +45,7 @@ public class CardState {
|
||||
private String name = "";
|
||||
private CardType type = new CardType();
|
||||
private ManaCost manaCost = ManaCost.NO_COST;
|
||||
private final SortedMap<Long, CardColor> cardColor = Maps.newTreeMap();
|
||||
private byte color = MagicColor.COLORLESS;
|
||||
private int basePower = 0;
|
||||
private int baseToughness = 0;
|
||||
private List<String> intrinsicKeywords = new ArrayList<String>();
|
||||
@@ -118,52 +116,17 @@ public class CardState {
|
||||
view.updateManaCost(this);
|
||||
}
|
||||
|
||||
public final void addColor(final CardColor color) {
|
||||
cardColor.put(color.getTimestamp(), color);
|
||||
getView().updateColors(this);
|
||||
public final byte getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public final void addColor(final String s, final boolean addToColors, final long timestamp) {
|
||||
addColor(new CardColor(s, addToColors, timestamp));
|
||||
public final void setColor(final String color) {
|
||||
final ManaCostParser parser = new ManaCostParser(color);
|
||||
final ManaCost cost = new ManaCost(parser);
|
||||
setColor(cost.getColorProfile());
|
||||
}
|
||||
|
||||
public final void removeColor(final long timestampIn) {
|
||||
final CardColor removeCol = cardColor.remove(timestampIn);
|
||||
|
||||
if (removeCol != null) {
|
||||
getView().updateColors(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final void setColor(final CardColor color) {
|
||||
setColor(ImmutableMap.of(color.getTimestamp(), color));
|
||||
}
|
||||
private final void setColor(final Map<Long, CardColor> cardColor0) {
|
||||
cardColor.clear();
|
||||
cardColor.putAll(cardColor0);
|
||||
view.updateColors(this);
|
||||
}
|
||||
public final void resetCardColor() {
|
||||
if (cardColor.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final Long firstKey = cardColor.firstKey();
|
||||
final CardColor first = cardColor.get(firstKey);
|
||||
cardColor.clear();
|
||||
cardColor.put(firstKey, first);
|
||||
view.updateColors(this);
|
||||
}
|
||||
public final ColorSet determineColor() {
|
||||
final Iterable<CardColor> colorList = cardColor.values();
|
||||
byte colors = 0;
|
||||
for (final CardColor cc : colorList) {
|
||||
if (cc.isAdditional()) {
|
||||
colors |= cc.getColorMask();
|
||||
} else {
|
||||
colors = cc.getColorMask();
|
||||
}
|
||||
}
|
||||
return ColorSet.fromMask(colors);
|
||||
public final void setColor(final byte color) {
|
||||
this.color = color;
|
||||
view.updateColors(card);
|
||||
}
|
||||
|
||||
public final int getBasePower() {
|
||||
@@ -389,7 +352,7 @@ public class CardState {
|
||||
setName(source.getName());
|
||||
setType(source.type);
|
||||
setManaCost(source.getManaCost());
|
||||
setColor(source.cardColor);
|
||||
setColor(source.getColor());
|
||||
setBasePower(source.getBasePower());
|
||||
setBaseToughness(source.getBaseToughness());
|
||||
intrinsicKeywords = new ArrayList<String>(source.intrinsicKeywords);
|
||||
|
||||
@@ -770,7 +770,7 @@ public class CardView extends GameEntityView {
|
||||
set(TrackableProperty.Colors, c.determineColor());
|
||||
}
|
||||
void updateColors(CardState c) {
|
||||
set(TrackableProperty.Colors, c.determineColor());
|
||||
set(TrackableProperty.Colors, c.getColor());
|
||||
}
|
||||
|
||||
public String getImageKey(PlayerView viewer) {
|
||||
|
||||
@@ -532,6 +532,8 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
runParams.put("DamageTarget", this);
|
||||
runParams.put("DamageAmount", amount);
|
||||
runParams.put("IsCombatDamage", isCombat);
|
||||
// Defending player at the time the damage was dealt
|
||||
runParams.put("DefendingPlayer", game.getCombat() != null ? game.getCombat().getDefendingPlayerRelatedTo(source) : null);
|
||||
game.getTriggerHandler().runTrigger(TriggerType.DamageDone, runParams, false);
|
||||
|
||||
game.fireEvent(new GameEventPlayerDamaged(this, source, amount, isCombat, infect));
|
||||
|
||||
@@ -104,5 +104,7 @@ public class TriggerDamageDone extends Trigger {
|
||||
sa.setTriggeringObject("Source", this.getRunParams().get("DamageSource"));
|
||||
sa.setTriggeringObject("Target", this.getRunParams().get("DamageTarget"));
|
||||
sa.setTriggeringObject("DamageAmount", this.getRunParams().get("DamageAmount"));
|
||||
// This parameter is here because LKI information related to combat doesn't work properly
|
||||
sa.setTriggeringObject("DefendingPlayer", this.getRunParams().get("DefendingPlayer"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,9 @@ K:Equip 3
|
||||
S:Mode$ Continuous | Affected$ Card.EquippedBy | AddAbility$ GamaPump | Description$ Equipped creature has "{2}: This creature gets +1/+0 until end of turn."
|
||||
SVar:GamaPump:AB$ Pump | Cost$ 2 | NumAtt$ +1 | SpellDescription$ CARDNAME gets +1/+0 until end of turn.
|
||||
T:Mode$ DamageDone | ValidSource$ Card.EquippedBy | ValidTarget$ Creature.blocking | Execute$ KusariPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever equipped creature deals damage to a blocking creature, CARDNAME deals that much damage to each other creature defending player controls.
|
||||
SVar:KusariPump:DB$ Pump | Defined$ TriggeredTarget | RememberObjects$ TriggeredTarget | SubAbility$ GamaDamage
|
||||
SVar:GamaDamage:DB$ DamageAll | NumDmg$ X | References$ X | ValidCards$ Creature.DefenderCtrl+IsNotRemembered | SubAbility$ CleanUp
|
||||
SVar:KusariPump:DB$ Pump | Defined$ Self | RememberObjects$ TriggeredTarget | SubAbility$ KusariPump2
|
||||
SVar:KusariPump2:DB$ Pump | Defined$ Self | RememberObjects$ TriggeredDefendingPlayer | SubAbility$ GamaDamage
|
||||
SVar:GamaDamage:DB$ DamageAll | NumDmg$ X | References$ X | ValidCards$ Creature.IsNotRemembered+ControlledBy Player.IsRemembered | SubAbility$ CleanUp
|
||||
SVar:CleanUp:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:TriggerCount$DamageAmount
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/kusari_gama.jpg
|
||||
|
||||
Reference in New Issue
Block a user