Card: combine PT boost into one Map using timestamp

This commit is contained in:
Hans Mackowiak
2019-09-01 05:39:09 +00:00
committed by Michael Kamensky
parent 5381d6c1dc
commit c04ccdaf7c
9 changed files with 54 additions and 166 deletions

View File

@@ -1601,8 +1601,8 @@ public class ComputerUtilCard {
} }
pumped.addNewPT(c.getCurrentPower(), c.getCurrentToughness(), timestamp); pumped.addNewPT(c.getCurrentPower(), c.getCurrentToughness(), timestamp);
pumped.addTempPowerBoost(c.getTempPowerBoost() + power + berserkPower); pumped.setPTBoost(c.getPTBoostMap());
pumped.addTempToughnessBoost(c.getTempToughnessBoost() + toughness); pumped.addPTBoost(power + berserkPower, toughness, timestamp);
pumped.addChangedCardKeywords(kws, null, false, false, timestamp); pumped.addChangedCardKeywords(kws, null, false, false, timestamp);
Set<CounterType> types = c.getCounters().keySet(); Set<CounterType> types = c.getCounters().keySet();
for(CounterType ct : types) { for(CounterType ct : types) {
@@ -1648,6 +1648,8 @@ public class ComputerUtilCard {
} }
list.add(vCard); // account for the static abilities that may be present on the card itself list.add(vCard); // account for the static abilities that may be present on the card itself
for (final Card c : list) { for (final Card c : list) {
// remove old boost that might be copied
vCard.removePTBoost(c.getTimestamp());
for (final StaticAbility stAb : c.getStaticAbilities()) { for (final StaticAbility stAb : c.getStaticAbilities()) {
final Map<String, String> params = stAb.getMapParams(); final Map<String, String> params = stAb.getMapParams();
if (!params.get("Mode").equals("Continuous")) { if (!params.get("Mode").equals("Continuous")) {
@@ -1663,26 +1665,25 @@ public class ComputerUtilCard {
if (!vCard.isValid(valid, c.getController(), c, null)) { if (!vCard.isValid(valid, c.getController(), c, null)) {
continue; continue;
} }
int att = 0;
if (params.containsKey("AddPower")) { if (params.containsKey("AddPower")) {
String addP = params.get("AddPower"); String addP = params.get("AddPower");
int att = 0;
if (addP.equals("AffectedX")) { if (addP.equals("AffectedX")) {
att = CardFactoryUtil.xCount(vCard, AbilityUtils.getSVar(stAb, addP)); att = CardFactoryUtil.xCount(vCard, AbilityUtils.getSVar(stAb, addP));
} else { } else {
att = AbilityUtils.calculateAmount(c, addP, stAb); att = AbilityUtils.calculateAmount(c, addP, stAb);
} }
vCard.addTempPowerBoost(att);
} }
int def = 0;
if (params.containsKey("AddToughness")) { if (params.containsKey("AddToughness")) {
String addT = params.get("AddToughness"); String addT = params.get("AddToughness");
int def = 0;
if (addT.equals("AffectedY")) { if (addT.equals("AffectedY")) {
def = CardFactoryUtil.xCount(vCard, AbilityUtils.getSVar(stAb, addT)); def = CardFactoryUtil.xCount(vCard, AbilityUtils.getSVar(stAb, addT));
} else { } else {
def = AbilityUtils.calculateAmount(c, addT, stAb); def = AbilityUtils.calculateAmount(c, addT, stAb);
} }
vCard.addTempToughnessBoost(def);
} }
vCard.addPTBoost(att, def, c.getTimestamp());
} }
} }
} }

View File

@@ -277,10 +277,7 @@ public class GameCopier {
// TODO: Copy the full list with timestamps. // TODO: Copy the full list with timestamps.
newCard.addNewPT(setPower, setToughness, newGame.getNextTimestamp()); newCard.addNewPT(setPower, setToughness, newGame.getNextTimestamp());
} }
newCard.addTempPowerBoost(c.getTempPowerBoost()); newCard.setPTBoost(c.getPTBoostMap());
newCard.setSemiPermanentPowerBoost(c.getSemiPermanentPowerBoost());
newCard.addTempToughnessBoost(c.getTempToughnessBoost());
newCard.setSemiPermanentToughnessBoost(c.getSemiPermanentToughnessBoost());
newCard.setDamage(c.getDamage()); newCard.setDamage(c.getDamage());
newCard.setChangedCardTypes(c.getChangedCardTypesMap()); newCard.setChangedCardTypes(c.getChangedCardTypesMap());

View File

@@ -161,17 +161,6 @@ public class GameStateEvaluator {
} }
return super.addValue(value, text); return super.addValue(value, text);
} }
@Override
protected int getEffectivePower(final Card c) {
Card.StatBreakdown breakdown = c.getNetCombatDamageBreakdown();
return breakdown.getTotal() - breakdown.tempBoost;
}
@Override
protected int getEffectiveToughness(final Card c) {
Card.StatBreakdown breakdown = c.getNetToughnessBreakdown();
return breakdown.getTotal() - breakdown.tempBoost;
}
} }
public static class Score { public static class Score {

View File

@@ -53,7 +53,6 @@ public class StaticEffect {
private int xValue = 0; private int xValue = 0;
private int yValue = 0; private int yValue = 0;
private long timestamp = -1; private long timestamp = -1;
private Map<Card, Integer> xValueMap = Maps.newTreeMap();
private String chosenType; private String chosenType;
private Map<String, String> mapParams = Maps.newTreeMap(); private Map<String, String> mapParams = Maps.newTreeMap();
@@ -95,7 +94,6 @@ public class StaticEffect {
copy.xValue = this.xValue; copy.xValue = this.xValue;
copy.yValue = this.yValue; copy.yValue = this.yValue;
copy.timestamp = this.timestamp; copy.timestamp = this.timestamp;
copy.xValueMap = this.xValueMap;
copy.chosenType = this.chosenType; copy.chosenType = this.chosenType;
copy.mapParams = this.mapParams; copy.mapParams = this.mapParams;
copy.overwriteTypes = this.overwriteTypes; copy.overwriteTypes = this.overwriteTypes;
@@ -740,29 +738,6 @@ public class StaticEffect {
return this.yValue; return this.yValue;
} }
/**
* Store xValue relative to a specific card.
* @param affectedCard the card affected
* @param xValue the xValue
*/
public final void addXMapValue(final Card affectedCard, final Integer xValue) {
if (this.xValueMap.containsKey(affectedCard)) {
if (!this.xValueMap.get(affectedCard).equals(xValue)) {
this.xValueMap.remove(affectedCard);
}
}
this.xValueMap.put(affectedCard, xValue);
}
/**
* Get the xValue for specific card.
* @param affectedCard the affected card
* @return an int.
*/
public int getXMapValue(Card affectedCard) {
return this.xValueMap.get(affectedCard);
}
/** /**
* setParams. TODO Write javadoc for this method. * setParams. TODO Write javadoc for this method.
* *
@@ -813,10 +788,6 @@ public class StaticEffect {
String changeColorWordsTo = null; String changeColorWordsTo = null;
int powerBonus = 0;
String addP = "";
int toughnessBonus = 0;
String addT = "";
int keywordMultiplier = 1; int keywordMultiplier = 1;
boolean setPT = false; boolean setPT = false;
String[] addHiddenKeywords = null; String[] addHiddenKeywords = null;
@@ -834,28 +805,6 @@ public class StaticEffect {
setPT = true; setPT = true;
} }
if (params.containsKey("AddPower")) {
addP = params.get("AddPower");
if (addP.matches("[0-9][0-9]?")) {
powerBonus = Integer.valueOf(addP);
} else if (addP.equals("AffectedX")) {
// gets calculated at runtime
} else {
powerBonus = getXValue();
}
}
if (params.containsKey("AddToughness")) {
addT = params.get("AddToughness");
if (addT.matches("[0-9][0-9]?")) {
toughnessBonus = Integer.valueOf(addT);
} else if (addT.equals("AffectedX")) {
// gets calculated at runtime
} else {
toughnessBonus = getYValue();
}
}
if (params.containsKey("KeywordMultiplier")) { if (params.containsKey("KeywordMultiplier")) {
String multiplier = params.get("KeywordMultiplier"); String multiplier = params.get("KeywordMultiplier");
if (multiplier.equals("X")) { if (multiplier.equals("X")) {
@@ -934,15 +883,9 @@ public class StaticEffect {
} }
// remove P/T bonus // remove P/T bonus
if (addP.startsWith("AffectedX")) { affectedCard.removePTBoost(getTimestamp());
powerBonus = getXMapValue(affectedCard);
}
if (addT.startsWith("AffectedX")) {
toughnessBonus = getXMapValue(affectedCard);
}
// the view is updated in GameAction#checkStaticAbilities to avoid flickering // the view is updated in GameAction#checkStaticAbilities to avoid flickering
affectedCard.addSemiPermanentPowerBoost(powerBonus * -1, false);
affectedCard.addSemiPermanentToughnessBoost(toughnessBonus * -1, false);
// remove keywords // remove keywords
// TODO regular keywords currently don't try to use keyword multiplier // TODO regular keywords currently don't try to use keyword multiplier

View File

@@ -49,8 +49,7 @@ public class PumpAllEffect extends SpellAbilityEffect {
continue; continue;
} }
tgtC.addTempPowerBoost(a); tgtC.addPTBoost(a, d, timestamp);
tgtC.addTempToughnessBoost(d);
tgtC.addChangedCardKeywords(kws, null, false, false, timestamp); tgtC.addChangedCardKeywords(kws, null, false, false, timestamp);
for (String kw : hiddenkws) { for (String kw : hiddenkws) {
@@ -68,8 +67,7 @@ public class PumpAllEffect extends SpellAbilityEffect {
@Override @Override
public void run() { public void run() {
tgtC.addTempPowerBoost(-1 * a); tgtC.removePTBoost(timestamp);
tgtC.addTempToughnessBoost(-1 * d);
tgtC.removeChangedCardKeywords(timestamp); tgtC.removeChangedCardKeywords(timestamp);
for (String kw : hiddenkws) { for (String kw : hiddenkws) {

View File

@@ -55,8 +55,7 @@ public class PumpEffect extends SpellAbilityEffect {
} }
} }
gameCard.addTempPowerBoost(a); gameCard.addPTBoost(a, d,timestamp);
gameCard.addTempToughnessBoost(d);
gameCard.addChangedCardKeywords(kws, Lists.<String>newArrayList(), false, false, timestamp); gameCard.addChangedCardKeywords(kws, Lists.<String>newArrayList(), false, false, timestamp);
if (redrawPT) { if (redrawPT) {
gameCard.updatePowerToughnessForView(); gameCard.updatePowerToughnessForView();
@@ -73,23 +72,18 @@ public class PumpEffect extends SpellAbilityEffect {
@Override @Override
public void run() { public void run() {
gameCard.addTempPowerBoost(-1 * a); gameCard.removePTBoost(timestamp);
gameCard.addTempToughnessBoost(-1 * d);
if (keywords.size() > 0) { if (keywords.size() > 0) {
boolean redrawPT = false;
for (String kw : keywords) { for (String kw : keywords) {
redrawPT |= kw.contains("CARDNAME's power and toughness are switched");
if (kw.startsWith("HIDDEN")) { if (kw.startsWith("HIDDEN")) {
gameCard.removeHiddenExtrinsicKeyword(kw); gameCard.removeHiddenExtrinsicKeyword(kw);
if (redrawPT) {
gameCard.updatePowerToughnessForView();
}
} }
} }
gameCard.removeChangedCardKeywords(timestamp); gameCard.removeChangedCardKeywords(timestamp);
} }
gameCard.updatePowerToughnessForView();
game.fireEvent(new GameEventCardStatsChanged(gameCard)); game.fireEvent(new GameEventCardStatsChanged(gameCard));
} }

View File

@@ -195,6 +195,8 @@ public class Card extends GameEntity implements Comparable<Card> {
// stack of set power/toughness // stack of set power/toughness
private Map<Long, Pair<Integer,Integer>> newPT = Maps.newTreeMap(); private Map<Long, Pair<Integer,Integer>> newPT = Maps.newTreeMap();
private Map<Long, Pair<Integer,Integer>> newPTCharacterDefining = Maps.newTreeMap(); private Map<Long, Pair<Integer,Integer>> newPTCharacterDefining = Maps.newTreeMap();
private Map<Long, Pair<Integer,Integer>> boostPT = Maps.newTreeMap();
private String basePowerString = null; private String basePowerString = null;
private String baseToughnessString = null; private String baseToughnessString = null;
private String oracleText = ""; private String oracleText = "";
@@ -208,12 +210,6 @@ public class Card extends GameEntity implements Comparable<Card> {
private int turnInZone; private int turnInZone;
private int tempPowerBoost = 0;
private int tempToughnessBoost = 0;
private int semiPermanentPowerBoost = 0;
private int semiPermanentToughnessBoost = 0;
private int xManaCostPaid = 0; private int xManaCostPaid = 0;
private Map<String, Integer> xManaCostPaidByColor; private Map<String, Integer> xManaCostPaidByColor;
@@ -3343,7 +3339,7 @@ public class Card extends GameEntity implements Comparable<Card> {
} }
public final StatBreakdown getUnswitchedPowerBreakdown() { public final StatBreakdown getUnswitchedPowerBreakdown() {
return new StatBreakdown(getCurrentPower(), getTempPowerBoost(), getSemiPermanentPowerBoost(), getPowerBonusFromCounters()); return new StatBreakdown(getCurrentPower(), getTempPowerBoost(), getPowerBonusFromCounters());
} }
public final int getUnswitchedPower() { public final int getUnswitchedPower() {
return getUnswitchedPowerBreakdown().getTotal(); return getUnswitchedPowerBreakdown().getTotal();
@@ -3380,31 +3376,28 @@ public class Card extends GameEntity implements Comparable<Card> {
public static class StatBreakdown { public static class StatBreakdown {
public final int currentValue; public final int currentValue;
public final int tempBoost; public final int tempBoost;
public final int semiPermanentBoost;
public final int bonusFromCounters; public final int bonusFromCounters;
public StatBreakdown() { public StatBreakdown() {
this.currentValue = 0; this.currentValue = 0;
this.tempBoost = 0; this.tempBoost = 0;
this.semiPermanentBoost = 0;
this.bonusFromCounters = 0; this.bonusFromCounters = 0;
} }
public StatBreakdown(int currentValue, int tempBoost, int semiPermanentBoost, int bonusFromCounters){ public StatBreakdown(int currentValue, int tempBoost, int bonusFromCounters){
this.currentValue = currentValue; this.currentValue = currentValue;
this.tempBoost = tempBoost; this.tempBoost = tempBoost;
this.semiPermanentBoost = semiPermanentBoost;
this.bonusFromCounters = bonusFromCounters; this.bonusFromCounters = bonusFromCounters;
} }
public int getTotal() { public int getTotal() {
return currentValue + tempBoost + semiPermanentBoost + bonusFromCounters; return currentValue + tempBoost + bonusFromCounters;
} }
@Override @Override
public String toString() { public String toString() {
return TextUtil.concatWithSpace("c:"+String.valueOf(currentValue),"tb:"+String.valueOf(tempBoost), "spb:"+String.valueOf(semiPermanentBoost),"bfc:"+String.valueOf(bonusFromCounters)); return TextUtil.concatWithSpace("c:"+String.valueOf(currentValue),"tb:"+String.valueOf(tempBoost),"bfc:"+String.valueOf(bonusFromCounters));
} }
} }
public final StatBreakdown getUnswitchedToughnessBreakdown() { public final StatBreakdown getUnswitchedToughnessBreakdown() {
return new StatBreakdown(getCurrentToughness(), getTempToughnessBoost(), getSemiPermanentToughnessBoost(), getToughnessBonusFromCounters()); return new StatBreakdown(getCurrentToughness(), getTempToughnessBoost(), getToughnessBonusFromCounters());
} }
public final int getUnswitchedToughness() { public final int getUnswitchedToughness() {
return getUnswitchedToughnessBreakdown().getTotal(); return getUnswitchedToughnessBreakdown().getTotal();
@@ -3465,60 +3458,42 @@ public class Card extends GameEntity implements Comparable<Card> {
// for cards like Giant Growth, etc. // for cards like Giant Growth, etc.
public final int getTempPowerBoost() { public final int getTempPowerBoost() {
return tempPowerBoost; int result = 0;
for (Pair<Integer, Integer> pair : boostPT.values()) {
if (pair.getLeft() != null) {
result += pair.getLeft();
}
}
return result;
} }
public final int getTempToughnessBoost() { public final int getTempToughnessBoost() {
return tempToughnessBoost; int result = 0;
for (Pair<Integer, Integer> pair : boostPT.values()) {
if (pair.getRight() != null) {
result += pair.getRight();
}
}
return result;
} }
public final void addTempPowerBoost(final int n) { public void addPTBoost(final Integer power, final Integer toughness, final long timestamp) {
if (n == 0) { return; } boostPT.put(timestamp, Pair.of(power, toughness));
tempPowerBoost += n;
currentState.getView().updatePower(this);
} }
public final void addTempToughnessBoost(final int n) { public void removePTBoost(final long timestamp) {
if (n == 0) { return; } boostPT.remove(timestamp);
tempToughnessBoost += n;
currentState.getView().updateToughness(this);
} }
// for cards like Glorious Anthem, etc. public Map<Long, Pair<Integer, Integer>> getPTBoostMap() {
public final int getSemiPermanentPowerBoost() { return ImmutableMap.copyOf(boostPT);
return semiPermanentPowerBoost;
} }
public final int getSemiPermanentToughnessBoost() { public void setPTBoost(Map<Long, Pair<Integer, Integer>> map) {
return semiPermanentToughnessBoost; this.boostPT.clear();
for (Map.Entry<Long, Pair<Integer,Integer>> e : map.entrySet()) {
this.boostPT.put(e.getKey(), Pair.of(e.getValue().getLeft(), e.getValue().getRight()));
} }
public final void addSemiPermanentPowerBoost(final int n, final boolean updateViewImmediately) {
if (n == 0) { return; }
semiPermanentPowerBoost += n;
if (updateViewImmediately) {
currentState.getView().updatePower(this);
}
}
public final void addSemiPermanentToughnessBoost(final int n, final boolean updateViewImmediately) {
if (n == 0) { return; }
semiPermanentToughnessBoost += n;
if (updateViewImmediately) {
currentState.getView().updateToughness(this);
}
}
public final void setSemiPermanentPowerBoost(final int n) {
if (semiPermanentPowerBoost == n) { return; }
semiPermanentPowerBoost = n;
currentState.getView().updatePower(this);
}
public final void setSemiPermanentToughnessBoost(final int n) {
if (semiPermanentToughnessBoost == n) { return; }
semiPermanentToughnessBoost = n;
currentState.getView().updateToughness(this);
} }
public final boolean isUntapped() { public final boolean isUntapped() {

View File

@@ -251,8 +251,8 @@ public final class CardUtil {
} }
// lock in the current P/T without bonus from counters // lock in the current P/T without bonus from counters
newCopy.setBasePower(in.getCurrentPower() + in.getTempPowerBoost() + in.getSemiPermanentPowerBoost()); newCopy.setBasePower(in.getCurrentPower() + in.getTempPowerBoost());
newCopy.setBaseToughness(in.getCurrentToughness() + in.getTempToughnessBoost() + in.getSemiPermanentToughnessBoost()); newCopy.setBaseToughness(in.getCurrentToughness() + in.getTempToughnessBoost());
newCopy.setCounters(Maps.newEnumMap(in.getCounters())); newCopy.setCounters(Maps.newEnumMap(in.getCounters()));

View File

@@ -179,17 +179,11 @@ public final class StaticAbilityContinuous {
if (layer == StaticAbilityLayer.MODIFYPT && params.containsKey("AddPower")) { if (layer == StaticAbilityLayer.MODIFYPT && params.containsKey("AddPower")) {
addP = params.get("AddPower"); addP = params.get("AddPower");
powerBonus = AbilityUtils.calculateAmount(hostCard, addP, stAb, true); powerBonus = AbilityUtils.calculateAmount(hostCard, addP, stAb, true);
if (!StringUtils.isNumeric(addP) && !addP.equals("AffectedX")) {
se.setXValue(powerBonus);
}
} }
if (layer == StaticAbilityLayer.MODIFYPT && params.containsKey("AddToughness")) { if (layer == StaticAbilityLayer.MODIFYPT && params.containsKey("AddToughness")) {
addT = params.get("AddToughness"); addT = params.get("AddToughness");
toughnessBonus = AbilityUtils.calculateAmount(hostCard, addT, stAb, true); toughnessBonus = AbilityUtils.calculateAmount(hostCard, addT, stAb, true);
if (!StringUtils.isNumeric(addT) && !addT.equals("AffectedX")) {
se.setYValue(toughnessBonus);
}
} }
if (params.containsKey("KeywordMultiplier")) { if (params.containsKey("KeywordMultiplier")) {
@@ -547,14 +541,11 @@ public final class StaticAbilityContinuous {
if (layer == StaticAbilityLayer.MODIFYPT) { if (layer == StaticAbilityLayer.MODIFYPT) {
if (addP.startsWith("AffectedX")) { if (addP.startsWith("AffectedX")) {
powerBonus = CardFactoryUtil.xCount(affectedCard, AbilityUtils.getSVar(stAb, addP)); powerBonus = CardFactoryUtil.xCount(affectedCard, AbilityUtils.getSVar(stAb, addP));
se.addXMapValue(affectedCard, powerBonus);
} }
if (addT.startsWith("AffectedX")) { if (addT.startsWith("AffectedX")) {
toughnessBonus = CardFactoryUtil.xCount(affectedCard, AbilityUtils.getSVar(stAb, addT)); toughnessBonus = CardFactoryUtil.xCount(affectedCard, AbilityUtils.getSVar(stAb, addT));
se.addXMapValue(affectedCard, toughnessBonus);
} }
affectedCard.addSemiPermanentPowerBoost(powerBonus, false); affectedCard.addPTBoost(powerBonus, toughnessBonus, se.getTimestamp());
affectedCard.addSemiPermanentToughnessBoost(toughnessBonus, false);
} }
// add keywords // add keywords