Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public String getAbilityDescription() {
}

@Override
protected void appendDetails(final StringBuilder sb) {
sb.append(" ability=\"").append(abilityDescription).append("\"");
public String describe() {
return localize("lblMacroActionActivateAbility", describeEntity(), abilityDescription);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ public class CastSpellAction extends PlayerAction {
public CastSpellAction(GameEntityView cardView) {
super(cardView, "Cast spell");
}

@Override
public String describe() {
return localize("lblMacroActionCastSpell", describeEntity());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public byte getColor() {
}

@Override
protected void appendDetails(final StringBuilder sb) {
sb.append(" color=").append(MagicColor.toShortString(color));
public String describe() {
return localize("lblMacroActionChooseColor", MagicColor.toLongString(color));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package forge.game.player.actions;

import forge.game.GameEntityView;
import forge.game.card.CardView;

public class ConfirmAction extends PlayerAction {
private final boolean confirmed;
Expand All @@ -14,8 +15,19 @@ public boolean isConfirmed() {
return confirmed;
}

public boolean matchesPrompt(final CardView inputCard, final String message) {
final GameEntityView recordedView = getGameEntityView();
if (!(recordedView instanceof CardView recordedCard)) {
return true;
}
return (inputCard != null && recordedCard.getName().equals(inputCard.getName()))
|| (message != null && message.contains(recordedCard.getName()));
}

@Override
protected void appendDetails(final StringBuilder sb) {
sb.append(" confirmed=").append(confirmed);
public String describe() {
final String action = localize(confirmed ? "lblMacroActionConfirm" : "lblMacroActionDecline");
final String entity = describeEntity();
return entity.isEmpty() ? action : localize("lblMacroActionChoiceFor", action, entity);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
package forge.game.player.actions;

public class FinishTargetingAction extends PlayerAction{
public class FinishTargetingAction extends PlayerAction {
public FinishTargetingAction() {
super(null, "Finish game entity");
}

@Override
public boolean isTargetSelectionAction() {
return true;
}

@Override
public String describe() {
return localize("lblMacroActionFinishSelecting");
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package forge.game.player.actions;

import forge.card.MagicColor;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

Expand All @@ -8,15 +11,34 @@ public class ManaComboAction extends PlayerAction {

public ManaComboAction(final Map<Byte, Integer> manaCombo) {
super(null, "Choose mana combination");
this.manaCombo = new LinkedHashMap<>(manaCombo);
this.manaCombo = Collections.unmodifiableMap(new LinkedHashMap<>(manaCombo));
}

public Map<Byte, Integer> getManaCombo() {
return manaCombo;
}

@Override
protected void appendDetails(final StringBuilder sb) {
sb.append(" manaCombo=").append(manaCombo);
public String describe() {
final StringBuilder sb = new StringBuilder();
boolean needComma = false;
for (final Map.Entry<Byte, Integer> entry : manaCombo.entrySet()) {
final int amount = entry.getValue() == null ? 0 : entry.getValue();
if (amount <= 0) {
continue;
}
if (needComma) {
sb.append(", ");
}
sb.append(describeColor(entry.getKey(), amount));
needComma = true;
}
return localize("lblMacroActionChooseManaCombination",
needComma ? sb.toString() : localize("lblMacroNone"));
}

private static String describeColor(final byte color, final int amount) {
final String colorName = MagicColor.toLongString(color);
return localize(amount == 1 ? "lblMacroManaAmount" : "lblMacroManaAmountPlural", amount, colorName);
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
package forge.game.player.actions;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ModeChoiceAction extends PlayerAction {
private final List<String> modeDescriptions;

public ModeChoiceAction(final List<String> modeDescriptions) {
super(null, "Choose mode");
this.modeDescriptions = modeDescriptions;
this.modeDescriptions = Collections.unmodifiableList(new ArrayList<>(modeDescriptions));
}

public List<String> getModeDescriptions() {
return modeDescriptions;
}

@Override
protected void appendDetails(final StringBuilder sb) {
sb.append(" modes=").append(modeDescriptions);
public String describe() {
return localize(modeDescriptions.size() == 1 ? "lblMacroActionChooseMode" : "lblMacroActionChooseModes",
describeList(modeDescriptions));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,58 @@ public boolean wasStackEmpty() {
return stackWasEmpty;
}

public PhaseType getPhase() {
return phase;
public boolean isObsoleteWhen(final boolean stackEmpty) {
return !stackWasEmpty && stackEmpty;
}

public boolean isStaleFor(final PhaseType currentPhase) {
return phase != null && currentPhase != null && phase.isBefore(currentPhase);
}

public boolean canReplay(final boolean currentStackEmpty, final PhaseType currentPhase) {
return stackWasEmpty == currentStackEmpty
&& (phase == null || phase == currentPhase || canAdvanceTowardRecordedCombatPass(currentPhase));
}

public boolean canReplayDuringAttack(final PhaseType currentPhase) {
return phase == null || phase == currentPhase;
}

public boolean isStackPassFor(final PhaseType currentPhase) {
return !stackWasEmpty && phase == currentPhase;
}

public boolean isTrailingMainPhasePassCandidate(final PhaseType currentPhase) {
return stackWasEmpty && phase == PhaseType.MAIN1 && currentPhase == PhaseType.MAIN1;
}

private boolean canAdvanceTowardRecordedCombatPass(final PhaseType currentPhase) {
return stackWasEmpty
&& currentPhase != null
&& phase != null
&& currentPhase.isBefore(phase)
&& isCombatPhase(currentPhase)
&& (isCombatPhase(phase) || phase == PhaseType.MAIN2);
}

private static boolean isCombatPhase(final PhaseType phase) {
return phase.name().startsWith("COMBAT_");
}

@Override
public boolean clearsPostStackOrderWait() {
return true;
}

@Override
public PassPriorityAction asPassPriorityAction() {
return this;
}

@Override
protected void appendDetails(final StringBuilder sb) {
sb.append(" stackWasEmpty=").append(stackWasEmpty);
if (phase != null) {
sb.append(" phase=").append(phase);
}
public String describe() {
final String phaseText = phase == null ? "" : " " + localize("lblMacroActionDuringPhase", phase.nameForUi);
final String stackText = localize(stackWasEmpty ? "lblMacroStackEmpty" : "lblMacroStackNotEmpty");
return localize("lblMacroActionPassPriority", phaseText, stackText);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ public class PayCostAction extends PlayerAction {
public PayCostAction(GameEntityView cardView) {
super(cardView, "Pay cost");
}

@Override
public String describe() {
return localize("lblMacroActionPayCost", describeEntity());
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package forge.game.player.actions;

import forge.card.MagicColor;

public class PayManaFromPoolAction extends PlayerAction {
private final byte colorSelected;

public class PayManaFromPoolAction extends PlayerAction{
private byte colorSelected;
public PayManaFromPoolAction(byte colorCode) {
super(null, "Pay mana");
colorSelected = colorCode;
Expand All @@ -13,7 +15,7 @@ public byte getSelectedColor() {
}

@Override
protected void appendDetails(final StringBuilder sb) {
sb.append(" mana=").append(colorSelected);
public String describe() {
return localize("lblMacroActionPayManaFromPool", MagicColor.toSymbol(colorSelected));
}
}
Original file line number Diff line number Diff line change
@@ -1,39 +1,86 @@
package forge.game.player.actions;

import forge.game.GameEntityView;
import forge.game.player.PlayerController;
import forge.game.card.CardView;
import forge.util.Localizer;

import java.util.List;
import java.util.regex.Pattern;

public abstract class PlayerAction {
protected String name;
protected GameEntityView gameEntityView = null;
private static final Pattern ENTITY_ID_SUFFIX = Pattern.compile(" \\((\\d+)\\)$");
private static final Localizer LOCALIZER = Localizer.getInstance();

private final String name;
private final GameEntityView gameEntityView;

public PlayerAction(GameEntityView cardView) {
gameEntityView = cardView;
name = null;
}

public PlayerAction(final GameEntityView cardView, final String actionName) {
this(cardView);
gameEntityView = cardView;
name = actionName;
}

public void run(PlayerController controller) {
// Turn this abstract soon
// This should try to replicate the recorded macro action
public boolean isSelectionAction() {
return false;
}

public boolean isTargetSelectionAction() {
return isSelectionAction();
}

public boolean clearsPostStackOrderWait() {
return isSelectionAction();
}

public PassPriorityAction asPassPriorityAction() {
return null;
}

public CardView getSelectedCardView() {
return null;
}

public GameEntityView getGameEntityView() {
return gameEntityView;
}

public String describe() {
final StringBuilder sb = new StringBuilder(getClass().getSimpleName());
if (gameEntityView != null) {
sb.append("(").append(gameEntityView).append(")");
final StringBuilder sb = new StringBuilder(name == null ? getClass().getSimpleName() : name);
final String entity = describeEntity();
if (!entity.isEmpty()) {
sb.append(": ").append(entity);
}
appendDetails(sb);
return sb.toString();
}

protected String describeEntity() {
return gameEntityView == null ? "" : describeEntity(gameEntityView);
}

protected static String describeEntity(final GameEntityView entity) {
return entity == null ? "" : ENTITY_ID_SUFFIX.matcher(String.valueOf(entity)).replaceAll(" $1");
}

protected static String describeList(final List<String> values) {
if (values == null || values.isEmpty()) {
return localize("lblMacroNone");
}
final StringBuilder sb = new StringBuilder();
for (final String value : values) {
sb.append('\n').append("- ").append(value);
}
return sb.toString();
}

protected static String localize(final String key, final Object... args) {
return LOCALIZER.getMessage(key, args);
}

protected void appendDetails(final StringBuilder sb) {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ private static List<String> namesOf(final CardCollectionView cards) {
for (final Card card : cards) {
names.add(card.getName());
}
return names;
return Collections.unmodifiableList(names);
}

public List<String> getTopCardNames() {
Expand All @@ -37,8 +37,7 @@ public List<String> getBottomCardNames() {
}

@Override
protected void appendDetails(final StringBuilder sb) {
sb.append(" top=").append(topCardNames);
sb.append(" bottom=").append(bottomCardNames);
public String describe() {
return localize("lblMacroActionScry", describeList(topCardNames), describeList(bottomCardNames));
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
package forge.game.player.actions;

import forge.game.GameEntityView;
import forge.game.card.CardView;

public class SelectCardAction extends PlayerAction{
public class SelectCardAction extends PlayerAction {
public SelectCardAction(GameEntityView cardView) {
super(cardView, "Select card");
}

@Override
public boolean isSelectionAction() {
return true;
}

@Override
public CardView getSelectedCardView() {
return getGameEntityView() instanceof CardView cardView ? cardView : null;
}

@Override
public String describe() {
return localize("lblMacroActionSelectCard", describeEntity());
}
}
Loading