[PIP] and [WHO] card implementations (#12482)

* Last Night Together

* Nanogene Conversion

* Return the Past

* Rose, Cutthroat Raider

* Diamond City

* Fix Apostrophe

* Various fixes

* Replace Diamond City and Celebration Watchers

* LastNightTogether improvements, add hint to ReturnThePast

* Add AttackedThisTurnOpponentsCount hint, ignore new failing Celebration test

* Review fixes, also create ValueConditionHint for value hints with a conditional threshold

* Comments improvements

* Requested changes to make ValueConditionHint extend ConditionHint

* single super call in ValueConditionHint constructor
This commit is contained in:
ssk97 2024-06-25 20:22:45 -07:00 committed by GitHub
parent e367aeae25
commit 2daa2b8820
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 657 additions and 75 deletions

View file

@ -3,22 +3,26 @@ package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.abilities.hint.ConditionHint;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueConditionHint;
import mage.game.Game;
import mage.watchers.common.CelebrationWatcher;
import mage.game.permanent.Permanent;
import mage.watchers.common.PermanentsEnteredBattlefieldWatcher;
import java.util.List;
/**
* @author Susucr
*/
public enum CelebrationCondition implements Condition {
instance;
private static final Hint hint = new ConditionHint(instance, "You had two or more nonland permanents enter this turn");
private static final Hint hint = new ValueConditionHint(CelebrationNonlandsThatEnteredThisTurnCount.instance, instance);
@Override
public boolean apply(Game game, Ability source) {
CelebrationWatcher watcher = game.getState().getWatcher(CelebrationWatcher.class);
return watcher != null && watcher.celebrationActive(source.getControllerId());
return CelebrationNonlandsThatEnteredThisTurnCount.instance.calculate(game, source, null) >= 2;
}
@Override
@ -30,3 +34,29 @@ public enum CelebrationCondition implements Condition {
return hint;
}
}
enum CelebrationNonlandsThatEnteredThisTurnCount implements DynamicValue {
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
PermanentsEnteredBattlefieldWatcher watcher = game.getState().getWatcher(PermanentsEnteredBattlefieldWatcher.class);
if (watcher != null) {
List<Permanent> list = watcher.getThisTurnEnteringPermanents(sourceAbility.getControllerId());
return (int) list.stream().filter(x -> !x.isLand(game)).count();
}
return 0;
}
@Override
public DynamicValue copy() {
return instance;
}
@Override
public String getMessage() {
return "nonland permanents that entered under your control this turn";
}
}

View file

@ -4,6 +4,8 @@ package mage.abilities.dynamicvalue.common;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint;
import mage.game.Game;
import mage.watchers.common.PlayersAttackedThisTurnWatcher;
@ -14,6 +16,7 @@ import mage.watchers.common.PlayersAttackedThisTurnWatcher;
*/
public enum AttackedThisTurnOpponentsCount implements DynamicValue {
instance;
private static final Hint hint = new ValueHint("the number of opponents you attacked this turn", instance);
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@ -38,4 +41,8 @@ public enum AttackedThisTurnOpponentsCount implements DynamicValue {
public String getMessage() {
return "the number of opponents you attacked this turn";
}
public static Hint getHint() {
return hint;
}
}

View file

@ -0,0 +1,38 @@
package mage.abilities.hint;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.game.Game;
/**
* @author notgreat
*/
public class ValueConditionHint extends ConditionHint {
private final DynamicValue value;
public ValueConditionHint(DynamicValue value, Condition condition) {
this(condition.toString(), value, condition);
}
public ValueConditionHint(String name, DynamicValue value, Condition condition) {
super(condition, name);
this.value = value;
}
private ValueConditionHint(final ValueConditionHint hint) {
super(hint);
this.value = hint.value.copy();
}
@Override
public String getText(Game game, Ability ability) {
return super.getText(game, ability) + " (current: " + value.calculate(game, ability, null) + ")";
}
@Override
public ValueConditionHint copy() {
return new ValueConditionHint(this);
}
}

View file

@ -1,47 +0,0 @@
package mage.watchers.common;
import mage.constants.WatcherScope;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.util.CardUtil;
import mage.watchers.Watcher;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* @author Susucr
*/
public class CelebrationWatcher extends Watcher {
// playerId -> number of nonland permanents entered the battlefield this turn under that player's control.
private final Map<UUID, Integer> celebrationCounts = new HashMap<>();
public CelebrationWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.ENTERS_THE_BATTLEFIELD) {
return;
}
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && !permanent.isLand(game)) {
celebrationCounts.compute(permanent.getControllerId(), CardUtil::setOrIncrementValue);
}
}
public boolean celebrationActive(UUID playerId) {
return celebrationCounts.getOrDefault(playerId, 0) >= 2;
}
@Override
public void reset() {
super.reset();
celebrationCounts.clear();
}
}