Rework drawing cards and associated replacement effects; implement [WHO] River Song (#12700)

* remove unused scoring system code

* add test for Alms Collector replacement effect

* flatten draw cards into single method in PlayerImpl

* remove outdated MageAction framework

* clarify game event for drawing two or more cards

* clarify methods for getting cards from library

* implement [WHO] River Song

* fix error

* adjust library methods

* add lots of test cases for draw replacement effects

* fix #12616

* track cards drawn this way through multi draw replacement as well

* add test for River Song

* remove redundant comment
This commit is contained in:
xenohedron 2024-08-24 01:02:55 -04:00 committed by GitHub
parent 34ae226130
commit 9fcbfdeac6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 645 additions and 345 deletions

View file

@ -11,7 +11,6 @@ import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffects;
import mage.abilities.effects.PreventionEffectData;
import mage.actions.impl.MageAction;
import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.MeldCard;
@ -552,8 +551,6 @@ public interface Game extends MageItem, Serializable, Copyable<Game> {
boolean endTurn(Ability source);
int doAction(Ability source, MageAction action);
//game transaction methods
void saveState(boolean bookmark);

View file

@ -22,7 +22,6 @@ import mage.abilities.effects.keyword.StunCounterEffect;
import mage.abilities.keyword.*;
import mage.abilities.mana.DelayedTriggeredManaAbility;
import mage.abilities.mana.TriggeredManaAbility;
import mage.actions.impl.MageAction;
import mage.cards.*;
import mage.cards.decks.Deck;
import mage.cards.decks.DeckCardInfo;
@ -3772,11 +3771,6 @@ public abstract class GameImpl implements Game {
return true;
}
@Override
public int doAction(Ability source, MageAction action) {
return action.doAction(source, this);
}
@Override
public Date getStartTime() {
if (startTime == null) {

View file

@ -9,6 +9,10 @@ import java.util.UUID;
*/
public class DrawCardEvent extends GameEvent {
private boolean fromBottom = false; // for replacement effects that draw from bottom of library instead
private int cardsDrawn = 0; // for replacement effects to keep track for "cards drawn this way"
public DrawCardEvent(UUID playerId, Ability source, GameEvent originalDrawEvent) {
super(GameEvent.EventType.DRAW_CARD, playerId, null, playerId, 0, false);
@ -22,4 +26,21 @@ public class DrawCardEvent extends GameEvent {
this.addAppliedEffects(originalDrawEvent.getAppliedEffects());
}
}
public void setFromBottom(boolean fromBottom) {
this.fromBottom = fromBottom;
}
public boolean isFromBottom() {
return fromBottom;
}
public void incrementCardsDrawn(int cardsDrawn) {
this.cardsDrawn += cardsDrawn;
}
public int getCardsDrawn() {
return cardsDrawn;
}
}

View file

@ -7,10 +7,12 @@ import java.util.UUID;
/**
* @author JayDi85
*/
public class DrawCardsEvent extends GameEvent {
public class DrawTwoOrMoreCardsEvent extends GameEvent {
public DrawCardsEvent(UUID playerId, Ability source, GameEvent originalDrawEvent, int amount) {
super(GameEvent.EventType.DRAW_CARDS, playerId, null, playerId, amount, false);
private int cardsDrawn = 0; // for replacement effects to keep track for "cards drawn this way"
public DrawTwoOrMoreCardsEvent(UUID playerId, Ability source, GameEvent originalDrawEvent, int amount) {
super(GameEvent.EventType.DRAW_TWO_OR_MORE_CARDS, playerId, null, playerId, amount, false);
// source of draw events must be kept between replacements, example: UnpredictableCycloneTest
this.setSourceId(originalDrawEvent == null
@ -22,4 +24,13 @@ public class DrawCardsEvent extends GameEvent {
this.addAppliedEffects(originalDrawEvent.getAppliedEffects());
}
}
public void incrementCardsDrawn(int cardsDrawn) {
this.cardsDrawn += cardsDrawn;
}
public int getCardsDrawn() {
return cardsDrawn;
}
}

View file

@ -75,7 +75,7 @@ public class GameEvent implements Serializable {
ZONE_CHANGE,
ZONE_CHANGE_GROUP, // between two specific zones only; TODO: rework all usages to ZONE_CHANGE_BATCH instead, see #11895
ZONE_CHANGE_BATCH, // all zone changes that occurred from a single effect
DRAW_CARDS, // event calls for multi draws only (if player draws 2+ cards at once)
DRAW_TWO_OR_MORE_CARDS, // event calls for multi draws only (if player draws 2+ cards at once)
DRAW_CARD, DREW_CARD,
EXPLORE, EXPLORED, // targetId is exploring permanent, playerId is its controller
ECHO_PAID,