Fix ResolvedLimit not accounting for multiple controllers (#4612)

* Fix ResolvedLimit not accounting for multiple controllers

* Fix missing trigger

---------

Co-authored-by: tool4EvEr <tool4EvEr@192.168.0.59>
Co-authored-by: tool4EvEr <tool4EvEr@192.168.0.60>
This commit is contained in:
tool4ever
2024-02-05 05:11:32 +01:00
committed by GitHub
parent f952b75d53
commit b6ba226312
5 changed files with 41 additions and 12 deletions

View File

@@ -1,20 +1,24 @@
package forge.game.card;
import java.util.List;
import org.apache.commons.lang3.ObjectUtils;
import com.google.common.base.Optional;
import com.google.common.collect.ForwardingTable;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Table;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.staticability.StaticAbility;
public class ActivationTable extends ForwardingTable<SpellAbility, Optional<StaticAbility>, Integer> {
Table<SpellAbility, Optional<StaticAbility>, Integer> dataTable = HashBasedTable.create();
public class ActivationTable extends ForwardingTable<SpellAbility, Optional<StaticAbility>, List<Player>> {
Table<SpellAbility, Optional<StaticAbility>, List<Player>> dataTable = HashBasedTable.create();
@Override
protected Table<SpellAbility, Optional<StaticAbility>, Integer> delegate() {
protected Table<SpellAbility, Optional<StaticAbility>, List<Player>> delegate() {
return dataTable;
}
@@ -38,11 +42,20 @@ public class ActivationTable extends ForwardingTable<SpellAbility, Optional<Stat
if (original != null) {
Optional<StaticAbility> st = Optional.fromNullable(root.getGrantorStatic());
delegate().put(original, st, ObjectUtils.defaultIfNull(get(original, st), 0) + 1);
List<Player> activators = get(original, st);
if (activators == null) {
activators = Lists.newArrayList();
}
activators.add(sa.getActivatingPlayer());
delegate().put(original, st, activators);
}
}
public Integer get(SpellAbility sa) {
return getActivators(sa).size();
}
public List<Player> getActivators(SpellAbility sa) {
SpellAbility root = sa.getRootAbility();
SpellAbility original = getOriginal(sa);
Optional<StaticAbility> st = Optional.fromNullable(root.getGrantorStatic());
@@ -50,6 +63,6 @@ public class ActivationTable extends ForwardingTable<SpellAbility, Optional<Stat
if (contains(original, st)) {
return get(original, st);
}
return 0;
return Lists.newArrayList();
}
}

View File

@@ -7576,6 +7576,9 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
public int getAbilityResolvedThisTurn(SpellAbility ability) {
return numberAbilityResolved.get(ability);
}
public List<Player> getAbilityResolvedThisTurnActivators(SpellAbility ability) {
return numberAbilityResolved.getActivators(ability);
}
public void resetAbilityResolvedThisTurn() {
numberAbilityResolved.clear();

View File

@@ -344,17 +344,26 @@ public abstract class Trigger extends TriggerReplacementBase {
}
}
if (hasParam("ResolvedLimit")) {
if (this.getOverridingAbility().getResolvedThisTurn() >= Integer.parseInt(getParam("ResolvedLimit"))) {
return false;
}
}
// host controller will be null when adding card in a simulation game
if (this.getHostCard().getController() == null || (game.getAge() != GameStage.Play && game.getAge() != GameStage.RestartedByKarn) || !meetsCommonRequirements(this.mapParams)) {
return false;
}
if (!checkResolvedLimit(getHostCard().getController())) {
return false;
}
return true;
}
public boolean checkResolvedLimit(Player activator) {
// CR 603.2i
if (hasParam("ResolvedLimit")) {
if (Collections.frequency(getHostCard().getAbilityResolvedThisTurnActivators(getOverridingAbility()), activator)
>= Integer.parseInt(getParam("ResolvedLimit"))) {
return false;
}
}
return true;
}

View File

@@ -467,6 +467,10 @@ public class WrappedAbility extends Ability {
}
}
if (!regtrig.checkResolvedLimit(getActivatingPlayer())) {
return;
}
if (regtrig.hasParam("ResolvingCheck")) {
// rare cases: Hidden Predators (state trigger, but have "Intervening If" to check IsPresent2) etc.
Map<String, String> recheck = Maps.newHashMap();