refactor: improved search in stack

This commit is contained in:
Oleg Agafonov 2025-08-10 02:07:15 +04:00
parent 26adccdfd5
commit 384ce67cc3
20 changed files with 101 additions and 119 deletions

View file

@ -53,11 +53,9 @@ public abstract class SpecialAction extends ActivatedAbilityImpl {
if (isManaAction()) {
// limit play mana abilities by steps
int currentStepOrder = 0;
if (!game.getStack().isEmpty()) {
StackObject stackObject = game.getStack().getFirst();
if (stackObject instanceof Spell) {
currentStepOrder = ((Spell) stackObject).getCurrentActivatingManaAbilitiesStep().getStepOrder();
}
StackObject stackObject = game.getStack().getFirstOrNull();
if (stackObject instanceof Spell) {
currentStepOrder = ((Spell) stackObject).getCurrentActivatingManaAbilitiesStep().getStepOrder();
}
if (currentStepOrder > manaAbility.useOnActivationManaAbilityStep().getStepOrder()) {
return ActivationStatus.getFalse();

View file

@ -31,10 +31,7 @@ public class CycleAllTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.getState().getStack().isEmpty()) {
return false;
}
StackObject item = game.getState().getStack().getFirst();
StackObject item = game.getState().getStack().getFirstOrNull();
return item instanceof StackAbility
&& item.getStackAbility() instanceof CyclingAbility;
}

View file

@ -42,12 +42,11 @@ public class CycleControllerTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.getState().getStack().isEmpty()
|| !event.getPlayerId().equals(this.getControllerId())
if (!event.getPlayerId().equals(this.getControllerId())
|| (event.getSourceId().equals(this.getSourceId()) && excludeSource)) {
return false;
}
StackObject item = game.getState().getStack().getFirst();
StackObject item = game.getState().getStack().getFirstOrNull();
return item instanceof StackAbility
&& item.getStackAbility() instanceof CyclingAbility;
}

View file

@ -18,25 +18,24 @@ public enum SunburstCount implements DynamicValue {
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
int count = 0;
if (!game.getStack().isEmpty()) {
StackObject spell = game.getStack().getFirst();
if (spell instanceof Spell && ((Spell) spell).getSourceId().equals(sourceAbility.getSourceId())) {
Mana mana = ((Spell) spell).getSpellAbility().getManaCostsToPay().getUsedManaToPay();
if (mana.getBlack() > 0) {
count++;
}
if (mana.getBlue() > 0) {
count++;
}
if (mana.getGreen() > 0) {
count++;
}
if (mana.getRed() > 0) {
count++;
}
if (mana.getWhite() > 0) {
count++;
}
StackObject spell = game.getStack().getFirstOrNull();
if (spell instanceof Spell && spell.getSourceId().equals(sourceAbility.getSourceId())) {
Mana mana = ((Spell) spell).getSpellAbility().getManaCostsToPay().getUsedManaToPay();
if (mana.getBlack() > 0) {
count++;
}
if (mana.getBlue() > 0) {
count++;
}
if (mana.getGreen() > 0) {
count++;
}
if (mana.getRed() > 0) {
count++;
}
if (mana.getWhite() > 0) {
count++;
}
}
return count;

View file

@ -513,13 +513,10 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
// If the top card of your library changes while youre casting a spell, playing a land, or activating an ability,
// you cant look at the new top card until you finish doing so. This means that if you cast the top card of
// your library, you cant look at the next one until youre done paying for that spell. (2019-05-03)
if (!game.getStack().isEmpty()) {
StackObject stackObject = game.getStack().getFirst();
return !(stackObject instanceof Spell)
|| !Zone.LIBRARY.equals(((Spell) stackObject).getFromZone())
|| stackObject.getStackAbility().getManaCostsToPay().isPaid(); // mana payment finished
}
return true;
StackObject stackObject = game.getStack().getFirstOrNull();
return !(stackObject instanceof Spell)
|| !Zone.LIBRARY.equals(((Spell) stackObject).getFromZone())
|| stackObject.getStackAbility().getManaCostsToPay().isPaid(); // mana payment finished
}
@Override

View file

@ -44,19 +44,16 @@ public abstract class ActivatedManaAbilityImpl extends ActivatedAbilityImpl impl
public ActivationStatus canActivate(UUID playerId, Game game) {
// check if player is in the process of playing spell costs and they are no longer allowed to use
// activated mana abilities (e.g. because they started to use improvise or convoke)
if (!game.getStack().isEmpty()) {
StackObject stackObject = game.getStack().getFirst();
if (stackObject instanceof Spell) {
switch (((Spell) stackObject).getCurrentActivatingManaAbilitiesStep()) {
case BEFORE:
case NORMAL:
break;
case AFTER:
return ActivationStatus.getFalse();
}
StackObject stackObject = game.getStack().getFirstOrNull();
if (stackObject instanceof Spell) {
switch (((Spell) stackObject).getCurrentActivatingManaAbilitiesStep()) {
case BEFORE:
case NORMAL:
break;
case AFTER:
return ActivationStatus.getFalse();
}
}
return super.canActivate(playerId, game);
}

View file

@ -51,6 +51,16 @@ public class SpellStack extends ArrayDeque<StackObject> {
}
}
@Override
@Deprecated // must use getFirstOrNull instead
public StackObject getFirst() {
return super.getFirst();
}
public StackObject getFirstOrNull() {
return this.isEmpty() ? null : this.getFirst();
}
public boolean remove(StackObject object, Game game) {
for (StackObject spell : this) {
if (spell.getId().equals(object.getId())) {