Card: add CounterKeywordEffects

This commit is contained in:
Hans Mackowiak
2025-04-11 07:13:12 +02:00
parent 8328866645
commit fba791d685

View File

@@ -64,6 +64,7 @@ import org.apache.commons.lang3.tuple.Triple;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.stream.Collectors;
import static java.lang.Math.max; import static java.lang.Math.max;
@@ -169,6 +170,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
private final Multimap<Long, Keyword> cantHaveKeywords = MultimapBuilder.hashKeys().hashSetValues().build(); private final Multimap<Long, Keyword> cantHaveKeywords = MultimapBuilder.hashKeys().hashSetValues().build();
private final Map<CounterType, Long> counterTypeTimestamps = Maps.newHashMap(); private final Map<CounterType, Long> counterTypeTimestamps = Maps.newHashMap();
private final Map<CounterType, Card> counterTypeKeywordEffects = Maps.newHashMap();
private final Map<Long, Integer> canBlockAdditional = Maps.newTreeMap(); private final Map<Long, Integer> canBlockAdditional = Maps.newTreeMap();
private final Set<Long> canBlockAny = Sets.newHashSet(); private final Set<Long> canBlockAny = Sets.newHashSet();
@@ -1793,7 +1795,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
view.updateCounters(this); view.updateCounters(this);
} }
if (newValue <= 0) { if (newValue <= 0) {
removeCounterTimestamp(counterType); removeCounterTimestamp(counterType, false);
} else if (addCounterTimestamp(counterType, false)) { } else if (addCounterTimestamp(counterType, false)) {
updateKeywords(); updateKeywords();
} }
@@ -1802,12 +1804,52 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
} }
} }
public boolean addCounterTimestamp(CounterType counterType) { public Card getCounterEffect(CounterType counterType, long timestamp) {
return addCounterTimestamp(counterType, true); Card result = counterTypeKeywordEffects.get(counterType);
int num = 1;
if (!Keyword.smartValueOf(counterType.toString().split(":")[0]).isMultipleRedundant()) {
num = getCounters(counterType);
}
String keywords = Collections.nCopies(num, counterType.toString()).stream().collect(Collectors.joining(" & "));
if (result == null) {
result = SpellAbilityEffect.createEffect(castSA, this, this.getController(), counterType.toString(), this.getImageKey(), timestamp);
result.setRenderForUI(false);
result.addRemembered(this);
String s = "Mode$ Continuous | AffectedDefined$ Remembered | AddKeyword$ " + keywords;
StaticAbility stAb = result.addStaticAbility(s);
stAb.setActiveZone(EnumSet.of(ZoneType.Command));
// TODO add for zone changes, not just Battlefield?
if (isInPlay()) {
GameCommand until = SpellAbilityEffect.exileEffectCommand(getGame(), result);
addLeavesPlayCommand(until);
} else {
SpellAbilityEffect.addForgetOnMovedTrigger(this, getZone().getZoneType().toString());
}
getGame().getAction().moveToCommand(result, null);
counterTypeKeywordEffects.put(counterType, result);
}
// update timestamp
result.setGameTimestamp(timestamp);
// update amount
for (StaticAbility stAb : result.getStaticAbilities()) {
stAb.getMapParams().put("AddKeyword", keywords);
}
return result;
} }
public boolean addCounterTimestamp(CounterType counterType, boolean updateView) { public boolean addCounterTimestamp(CounterType counterType, boolean updateView) {
if (counterType.is(CounterEnumType.MANABOND)) { if (counterType.is(CounterEnumType.MANABOND)) {
removeCounterTimestamp(counterType); removeCounterTimestamp(counterType, updateView);
long timestamp = game.getNextTimestamp(); long timestamp = game.getNextTimestamp();
counterTypeTimestamps.put(counterType, timestamp); counterTypeTimestamps.put(counterType, timestamp);
@@ -1827,28 +1869,25 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
if (!counterType.isKeywordCounter()) { if (!counterType.isKeywordCounter()) {
return false; return false;
} }
removeCounterTimestamp(counterType);
long timestamp = game.getNextTimestamp(); long timestamp = game.getNextTimestamp();
getCounterEffect(counterType, timestamp);
counterTypeTimestamps.put(counterType, timestamp); counterTypeTimestamps.put(counterType, timestamp);
int num = 1;
if (!Keyword.smartValueOf(counterType.toString().split(":")[0]).isMultipleRedundant()) {
num = getCounters(counterType);
}
addChangedCardKeywords(Collections.nCopies(num, counterType.toString()), null, false, timestamp, null, updateView);
return true; return true;
} }
public boolean removeCounterTimestamp(CounterType counterType) {
return removeCounterTimestamp(counterType, true);
}
public boolean removeCounterTimestamp(CounterType counterType, boolean updateView) { public boolean removeCounterTimestamp(CounterType counterType, boolean updateView) {
Long old = counterTypeTimestamps.remove(counterType); Long old = counterTypeTimestamps.remove(counterType);
if (old != null) { if (old != null) {
removeChangedCardTypes(old, 0, updateView); removeChangedCardTypes(old, 0, updateView);
removeChangedCardTraits(old, 0); removeChangedCardTraits(old, 0);
removeChangedCardKeywords(old, 0, updateView); }
if (!counterType.isKeywordCounter()) {
Card effect = counterTypeKeywordEffects.remove(counterType);
if (effect != null) {
getGame().getAction().exileEffect(effect);
}
} }
return old != null; return old != null;
} }