mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Merge remote-tracking branch 'upstream/master' into adventureupdatee
This commit is contained in:
@@ -35,16 +35,11 @@ import forge.util.TextUtil;
|
|||||||
import forge.util.collect.FCollectionView;
|
import forge.util.collect.FCollectionView;
|
||||||
|
|
||||||
public class AiCostDecision extends CostDecisionMakerBase {
|
public class AiCostDecision extends CostDecisionMakerBase {
|
||||||
private final SpellAbility ability;
|
|
||||||
private final Card source;
|
|
||||||
|
|
||||||
private final CardCollection discarded;
|
private final CardCollection discarded;
|
||||||
private final CardCollection tapped;
|
private final CardCollection tapped;
|
||||||
|
|
||||||
public AiCostDecision(Player ai0, SpellAbility sa, final boolean effect) {
|
public AiCostDecision(Player ai0, SpellAbility sa, final boolean effect) {
|
||||||
super(ai0, effect);
|
super(ai0, effect, sa, sa.getHostCard());
|
||||||
ability = sa;
|
|
||||||
source = ability.getHostCard();
|
|
||||||
|
|
||||||
discarded = new CardCollection();
|
discarded = new CardCollection();
|
||||||
tapped = new CardCollection();
|
tapped = new CardCollection();
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class CharmAi extends SpellAbilityAi {
|
|||||||
@Override
|
@Override
|
||||||
protected boolean checkApiLogic(Player ai, SpellAbility sa) {
|
protected boolean checkApiLogic(Player ai, SpellAbility sa) {
|
||||||
final Card source = sa.getHostCard();
|
final Card source = sa.getHostCard();
|
||||||
List<AbilitySub> choices = CharmEffect.makePossibleOptions(sa, false);
|
List<AbilitySub> choices = CharmEffect.makePossibleOptions(sa);
|
||||||
|
|
||||||
final int num;
|
final int num;
|
||||||
final int min;
|
final int min;
|
||||||
|
|||||||
@@ -943,7 +943,6 @@ public class Game {
|
|||||||
public GameStage getAge() {
|
public GameStage getAge() {
|
||||||
return age;
|
return age;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAge(GameStage value) {
|
public void setAge(GameStage value) {
|
||||||
age = value;
|
age = value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import forge.util.collect.FCollection;
|
|||||||
|
|
||||||
public class CharmEffect extends SpellAbilityEffect {
|
public class CharmEffect extends SpellAbilityEffect {
|
||||||
|
|
||||||
public static List<AbilitySub> makePossibleOptions(final SpellAbility sa, boolean forDesc) {
|
public static List<AbilitySub> makePossibleOptions(final SpellAbility sa) {
|
||||||
final Card source = sa.getHostCard();
|
final Card source = sa.getHostCard();
|
||||||
List<String> restriction = null;
|
List<String> restriction = null;
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ public class CharmEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
List<AbilitySub> choices = Lists.newArrayList(sa.getAdditionalAbilityList("Choices"));
|
List<AbilitySub> choices = Lists.newArrayList(sa.getAdditionalAbilityList("Choices"));
|
||||||
|
|
||||||
if (!forDesc) {
|
if (source.getZone() != null) {
|
||||||
List<AbilitySub> toRemove = Lists.newArrayList();
|
List<AbilitySub> toRemove = Lists.newArrayList();
|
||||||
for (AbilitySub ch : choices) {
|
for (AbilitySub ch : choices) {
|
||||||
// 603.3c If one of the modes would be illegal, that mode can't be chosen.
|
// 603.3c If one of the modes would be illegal, that mode can't be chosen.
|
||||||
@@ -55,7 +55,7 @@ public class CharmEffect extends SpellAbilityEffect {
|
|||||||
public static String makeFormatedDescription(SpellAbility sa) {
|
public static String makeFormatedDescription(SpellAbility sa) {
|
||||||
Card source = sa.getHostCard();
|
Card source = sa.getHostCard();
|
||||||
|
|
||||||
List<AbilitySub> list = CharmEffect.makePossibleOptions(sa, true);
|
List<AbilitySub> list = CharmEffect.makePossibleOptions(sa);
|
||||||
final int num;
|
final int num;
|
||||||
boolean additionalDesc = sa.hasParam("AdditionalDescription");
|
boolean additionalDesc = sa.hasParam("AdditionalDescription");
|
||||||
boolean optional = sa.hasParam("Optional");
|
boolean optional = sa.hasParam("Optional");
|
||||||
@@ -169,7 +169,7 @@ public class CharmEffect extends SpellAbilityEffect {
|
|||||||
//this resets all previous choices
|
//this resets all previous choices
|
||||||
sa.setSubAbility(null);
|
sa.setSubAbility(null);
|
||||||
|
|
||||||
List<AbilitySub> choices = makePossibleOptions(sa, false);
|
List<AbilitySub> choices = makePossibleOptions(sa);
|
||||||
|
|
||||||
// Entwine does use all Choices
|
// Entwine does use all Choices
|
||||||
if (sa.isEntwine()) {
|
if (sa.isEntwine()) {
|
||||||
|
|||||||
@@ -176,7 +176,6 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
|||||||
final Player activator = sa.getActivatingPlayer();
|
final Player activator = sa.getActivatingPlayer();
|
||||||
final PlayerController pc = activator.getController();
|
final PlayerController pc = activator.getController();
|
||||||
final boolean etbcounter = sa.hasParam("ETB");
|
final boolean etbcounter = sa.hasParam("ETB");
|
||||||
final int max = sa.hasParam("MaxFromEffect") ? Integer.parseInt(sa.getParam("MaxFromEffect")) : -1;
|
|
||||||
|
|
||||||
boolean existingCounter = sa.hasParam("CounterType") && sa.getParam("CounterType").equals("ExistingCounter");
|
boolean existingCounter = sa.hasParam("CounterType") && sa.getParam("CounterType").equals("ExistingCounter");
|
||||||
boolean eachExistingCounter = sa.hasParam("EachExistingCounter");
|
boolean eachExistingCounter = sa.hasParam("EachExistingCounter");
|
||||||
@@ -453,10 +452,6 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
counterAmount = sa.usesTargeting() && sa.isDividedAsYouChoose() ? sa.getDividedValue(gameCard)
|
counterAmount = sa.usesTargeting() && sa.isDividedAsYouChoose() ? sa.getDividedValue(gameCard)
|
||||||
: counterAmount;
|
: counterAmount;
|
||||||
if (max != -1) {
|
|
||||||
counterAmount = Math.max(Math.min(max - gameCard.getCounters(counterType), counterAmount),
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
if (sa.hasParam("UpTo")) {
|
if (sa.hasParam("UpTo")) {
|
||||||
int min = AbilityUtils.calculateAmount(card, sa.getParamOrDefault("UpToMin", "0"), sa);
|
int min = AbilityUtils.calculateAmount(card, sa.getParamOrDefault("UpToMin", "0"), sa);
|
||||||
Map<String, Object> params = Maps.newHashMap();
|
Map<String, Object> params = Maps.newHashMap();
|
||||||
|
|||||||
@@ -526,7 +526,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
if (state == CardStateName.FaceDown) {
|
if (state == CardStateName.FaceDown) {
|
||||||
view.updateHiddenId(game.nextHiddenCardId());
|
view.updateHiddenId(game.nextHiddenCardId());
|
||||||
}
|
}
|
||||||
game.fireEvent(new GameEventCardStatsChanged(this, true)); //ensure stats updated for new characteristics
|
game.fireEvent(new GameEventCardStatsChanged(this)); //ensure stats updated for new characteristics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -1427,6 +1427,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
@Override
|
@Override
|
||||||
public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table, Map<AbilityKey, Object> params) {
|
public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table, Map<AbilityKey, Object> params) {
|
||||||
int addAmount = n;
|
int addAmount = n;
|
||||||
|
// Rules say it is only a SBA, but is it checked there too?
|
||||||
|
if (counterType.is(CounterEnumType.DREAM) && hasKeyword("CARDNAME can't have more than seven dream counters on it.")) {
|
||||||
|
addAmount = Math.min(addAmount, 7 - getCounters(CounterEnumType.DREAM));
|
||||||
|
}
|
||||||
if (addAmount <= 0 || !canReceiveCounters(counterType)) {
|
if (addAmount <= 0 || !canReceiveCounters(counterType)) {
|
||||||
// As per rule 107.1b
|
// As per rule 107.1b
|
||||||
return;
|
return;
|
||||||
@@ -7115,8 +7119,12 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void resetChosenModeTurn() {
|
public void resetChosenModeTurn() {
|
||||||
|
boolean updateView = !chosenModesTurn.isEmpty() || !chosenModesTurnStatic.isEmpty();
|
||||||
chosenModesTurn.clear();
|
chosenModesTurn.clear();
|
||||||
chosenModesTurnStatic.clear();
|
chosenModesTurnStatic.clear();
|
||||||
|
if (updateView) {
|
||||||
|
updateAbilityTextForView();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPlaneswalkerAbilityActivated() {
|
public int getPlaneswalkerAbilityActivated() {
|
||||||
|
|||||||
@@ -984,11 +984,24 @@ public class CardProperty {
|
|||||||
if (card.getTurnInZone() <= sourceController.getLastTurnNr()) {
|
if (card.getTurnInZone() <= sourceController.getLastTurnNr()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (property.equals("ThisTurnEntered")) {
|
} else if (property.startsWith("ThisTurnEntered")) {
|
||||||
// only check if it entered the Zone this turn
|
// only check if it entered the Zone this turn
|
||||||
if (card.getTurnInZone() != game.getPhaseHandler().getTurn()) {
|
if (card.getTurnInZone() != game.getPhaseHandler().getTurn()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!property.equals("ThisTurnEntered")) { // to confirm specific zones / player
|
||||||
|
final boolean your = property.contains("Your");
|
||||||
|
final ZoneType where = ZoneType.smartValueOf(property.substring(your ? 19 : 15));
|
||||||
|
final Zone z = sourceController.getZone(where);
|
||||||
|
if (!z.getCardsAddedThisTurn(null).contains(card)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (your) { // for corner cases of controlling other player
|
||||||
|
if (!card.getOwner().equals(sourceController)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (property.equals("NotThisTurnEntered")) {
|
} else if (property.equals("NotThisTurnEntered")) {
|
||||||
// only check if it entered the Zone this turn
|
// only check if it entered the Zone this turn
|
||||||
if (card.getTurnInZone() == game.getPhaseHandler().getTurn()) {
|
if (card.getTurnInZone() == game.getPhaseHandler().getTurn()) {
|
||||||
|
|||||||
@@ -1,15 +1,23 @@
|
|||||||
package forge.game.cost;
|
package forge.game.cost;
|
||||||
|
|
||||||
|
import forge.game.card.Card;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
public abstract class CostDecisionMakerBase implements ICostVisitor<PaymentDecision> {
|
public abstract class CostDecisionMakerBase implements ICostVisitor<PaymentDecision> {
|
||||||
|
|
||||||
protected final Player player;
|
protected final Player player;
|
||||||
|
protected final SpellAbility ability;
|
||||||
|
protected final Card source;
|
||||||
private boolean effect;
|
private boolean effect;
|
||||||
public CostDecisionMakerBase(Player player0, boolean effect0) {
|
|
||||||
|
public CostDecisionMakerBase(Player player0, boolean effect0, SpellAbility ability0, Card source0) {
|
||||||
player = player0;
|
player = player0;
|
||||||
effect = effect0;
|
effect = effect0;
|
||||||
|
ability = ability0;
|
||||||
|
source = source0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player getPlayer() { return player; }
|
public Player getPlayer() { return player; }
|
||||||
public abstract boolean paysRightAfterDecision();
|
public abstract boolean paysRightAfterDecision();
|
||||||
public boolean isEffect() {
|
public boolean isEffect() {
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ public class GameEventCardStatsChanged extends GameEvent {
|
|||||||
|
|
||||||
public GameEventCardStatsChanged(Card affected, boolean isTransform) {
|
public GameEventCardStatsChanged(Card affected, boolean isTransform) {
|
||||||
cards = Arrays.asList(affected);
|
cards = Arrays.asList(affected);
|
||||||
transform = isTransform;
|
//the transform should only fire once so the flip effect sound will trigger once every transformation...
|
||||||
|
// disable for now
|
||||||
|
transform = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameEventCardStatsChanged(Collection<Card> affected) {
|
public GameEventCardStatsChanged(Collection<Card> affected) {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.tommyettinger</groupId>
|
<groupId>com.github.tommyettinger</groupId>
|
||||||
<artifactId>textratypist</artifactId>
|
<artifactId>textratypist</artifactId>
|
||||||
<version>0.7.9</version>
|
<version>0.8.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.badlogicgames.gdx-controllers</groupId>
|
<groupId>com.badlogicgames.gdx-controllers</groupId>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package forge.adventure.scene;
|
|||||||
|
|
||||||
import com.badlogic.gdx.graphics.g2d.Sprite;
|
import com.badlogic.gdx.graphics.g2d.Sprite;
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.Action;
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||||
import com.badlogic.gdx.scenes.scene2d.Group;
|
import com.badlogic.gdx.scenes.scene2d.Group;
|
||||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
|
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
|
||||||
@@ -55,6 +56,7 @@ public class ArenaScene extends UIScene implements IAfterMatch {
|
|||||||
final Sprite edgeM;
|
final Sprite edgeM;
|
||||||
final Sprite edgeWin;
|
final Sprite edgeWin;
|
||||||
final Sprite edgeWinM;
|
final Sprite edgeWinM;
|
||||||
|
boolean enable = true;
|
||||||
boolean arenaStarted = false;
|
boolean arenaStarted = false;
|
||||||
|
|
||||||
private ArenaScene() {
|
private ArenaScene() {
|
||||||
@@ -76,6 +78,8 @@ public class ArenaScene extends UIScene implements IAfterMatch {
|
|||||||
|
|
||||||
goldLabel = ui.findActor("gold");
|
goldLabel = ui.findActor("gold");
|
||||||
ui.onButtonPress("done", () -> {
|
ui.onButtonPress("done", () -> {
|
||||||
|
if (!enable)
|
||||||
|
return;
|
||||||
if (!arenaStarted)
|
if (!arenaStarted)
|
||||||
ArenaScene.this.done();
|
ArenaScene.this.done();
|
||||||
else
|
else
|
||||||
@@ -107,6 +111,8 @@ public class ArenaScene extends UIScene implements IAfterMatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startButton() {
|
private void startButton() {
|
||||||
|
if (!enable)
|
||||||
|
return;
|
||||||
if (roundsWon == 0) {
|
if (roundsWon == 0) {
|
||||||
Dialog startDialog = prepareDialog(Forge.getLocalizer().getMessage("lblStart"), ButtonYes | ButtonNo, () -> startArena());
|
Dialog startDialog = prepareDialog(Forge.getLocalizer().getMessage("lblStart"), ButtonYes | ButtonNo, () -> startArena());
|
||||||
startDialog.text("Do you want to go into the Arena?");
|
startDialog.text("Do you want to go into the Arena?");
|
||||||
@@ -119,6 +125,7 @@ public class ArenaScene extends UIScene implements IAfterMatch {
|
|||||||
int roundsWon = 0;
|
int roundsWon = 0;
|
||||||
|
|
||||||
private void startArena() {
|
private void startArena() {
|
||||||
|
enable = false;
|
||||||
goldLabel.setVisible(false);
|
goldLabel.setVisible(false);
|
||||||
arenaStarted = true;
|
arenaStarted = true;
|
||||||
startButton.setText("[%80]" + Forge.getLocalizer().getMessage("lblContinue"));
|
startButton.setText("[%80]" + Forge.getLocalizer().getMessage("lblContinue"));
|
||||||
@@ -132,6 +139,7 @@ public class ArenaScene extends UIScene implements IAfterMatch {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setWinner(boolean winner) {
|
public void setWinner(boolean winner) {
|
||||||
|
enable = false;
|
||||||
Array<ArenaRecord> winners = new Array<>();
|
Array<ArenaRecord> winners = new Array<>();
|
||||||
Array<EnemySprite> winnersEnemies = new Array<>();
|
Array<EnemySprite> winnersEnemies = new Array<>();
|
||||||
for (int i = 0; i < fighters.size - 2; i += 2) {
|
for (int i = 0; i < fighters.size - 2; i += 2) {
|
||||||
@@ -189,7 +197,15 @@ public class ArenaScene extends UIScene implements IAfterMatch {
|
|||||||
}
|
}
|
||||||
if (Forge.isLandscapeMode()) {
|
if (Forge.isLandscapeMode()) {
|
||||||
actor.toFront();
|
actor.toFront();
|
||||||
actor.addAction(Actions.sequence(Actions.moveBy(0f, gridSize * 2f, 1), Actions.moveBy((float) (gridSize * stepsToTheSide * (leftPlayer ? 1 : -1)), 0f, 1)));
|
actor.addAction(Actions.sequence(Actions.moveBy(0f, gridSize * 2f, 1), Actions.moveBy((float) (gridSize * stepsToTheSide * (leftPlayer ? 1 : -1)), 0f, 1), new Action() {
|
||||||
|
@Override
|
||||||
|
public boolean act(float v) {
|
||||||
|
enable = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
enable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,15 +8,9 @@ import com.badlogic.gdx.graphics.Color;
|
|||||||
import com.badlogic.gdx.graphics.Pixmap;
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.scenes.scene2d.Action;
|
import com.badlogic.gdx.scenes.scene2d.*;
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
|
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Button;
|
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Touchpad;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener;
|
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener;
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||||
@@ -48,20 +42,11 @@ public class GameHUD extends Stage {
|
|||||||
|
|
||||||
static public GameHUD instance;
|
static public GameHUD instance;
|
||||||
private final GameStage gameStage;
|
private final GameStage gameStage;
|
||||||
private final Image avatar;
|
private final Image avatar, miniMapPlayer;
|
||||||
private final Image miniMapPlayer;
|
private final TextraLabel lifePoints, money, shards, keys;
|
||||||
private final TextraLabel lifePoints;
|
|
||||||
private final TextraLabel money;
|
|
||||||
private final TextraLabel shards;
|
|
||||||
private final Image miniMap, gamehud, mapborder, avatarborder, blank;
|
private final Image miniMap, gamehud, mapborder, avatarborder, blank;
|
||||||
private final InputEvent eventTouchDown;
|
private final InputEvent eventTouchDown, eventTouchUp;
|
||||||
private final InputEvent eventTouchUp;
|
private final TextraButton deckActor, openMapActor, menuActor, statsActor, inventoryActor, exitToWorldMapActor;
|
||||||
private final TextraButton deckActor;
|
|
||||||
private final TextraButton openMapActor;
|
|
||||||
private final TextraButton menuActor;
|
|
||||||
private final TextraButton statsActor;
|
|
||||||
private final TextraButton inventoryActor;
|
|
||||||
private final TextraButton exitToWorldMapActor;
|
|
||||||
public final UIActor ui;
|
public final UIActor ui;
|
||||||
private final Touchpad touchpad;
|
private final Touchpad touchpad;
|
||||||
private final Console console;
|
private final Console console;
|
||||||
@@ -73,8 +58,10 @@ public class GameHUD extends Stage {
|
|||||||
private final Dialog dialog;
|
private final Dialog dialog;
|
||||||
private boolean dialogOnlyInput;
|
private boolean dialogOnlyInput;
|
||||||
private final Array<TextraButton> dialogButtonMap = new Array<>();
|
private final Array<TextraButton> dialogButtonMap = new Array<>();
|
||||||
|
private final Array<String> questKeys = new Array<>();
|
||||||
private String lifepointsTextColor = "";
|
private String lifepointsTextColor = "";
|
||||||
TextraButton selectedKey;
|
private TextraButton selectedKey;
|
||||||
|
private final ScrollPane scrollPane;
|
||||||
|
|
||||||
private GameHUD(GameStage gameStage) {
|
private GameHUD(GameStage gameStage) {
|
||||||
super(new ScalingViewport(Scaling.stretch, Scene.getIntendedWidth(), Scene.getIntendedHeight()), gameStage.getBatch());
|
super(new ScalingViewport(Scaling.stretch, Scene.getIntendedWidth(), Scene.getIntendedHeight()), gameStage.getBatch());
|
||||||
@@ -137,6 +124,11 @@ public class GameHUD extends Stage {
|
|||||||
shards.setText("[%95][+Shards] 0");
|
shards.setText("[%95][+Shards] 0");
|
||||||
money.setText("[%95][+Gold] ");
|
money.setText("[%95][+Gold] ");
|
||||||
lifePoints.setText("[%95][+Life] 20/20");
|
lifePoints.setText("[%95][+Life] 20/20");
|
||||||
|
keys = Controls.newTextraLabel("");
|
||||||
|
scrollPane = new ScrollPane(keys);
|
||||||
|
scrollPane.setPosition(2, 2);
|
||||||
|
scrollPane.setStyle(Controls.getSkin().get("transluscent", ScrollPane.ScrollPaneStyle.class));
|
||||||
|
addActor(scrollPane);
|
||||||
AdventurePlayer.current().onLifeChange(() -> lifePoints.setText("[%95][+Life]" + lifepointsTextColor + " " + AdventurePlayer.current().getLife() + "/" + AdventurePlayer.current().getMaxLife()));
|
AdventurePlayer.current().onLifeChange(() -> lifePoints.setText("[%95][+Life]" + lifepointsTextColor + " " + AdventurePlayer.current().getLife() + "/" + AdventurePlayer.current().getMaxLife()));
|
||||||
AdventurePlayer.current().onShardsChange(() -> shards.setText("[%95][+Shards] " + AdventurePlayer.current().getShards()));
|
AdventurePlayer.current().onShardsChange(() -> shards.setText("[%95][+Shards] " + AdventurePlayer.current().getShards()));
|
||||||
|
|
||||||
@@ -291,6 +283,7 @@ public class GameHUD extends Stage {
|
|||||||
Pixmap miniMapToolTipPixmap;
|
Pixmap miniMapToolTipPixmap;
|
||||||
|
|
||||||
public void enter() {
|
public void enter() {
|
||||||
|
questKeys.clear();
|
||||||
if (miniMapTexture != null)
|
if (miniMapTexture != null)
|
||||||
miniMapTexture.dispose();
|
miniMapTexture.dispose();
|
||||||
miniMapTexture = new Texture(WorldSave.getCurrentSave().getWorld().getBiomeImage());
|
miniMapTexture = new Texture(WorldSave.getCurrentSave().getWorld().getBiomeImage());
|
||||||
@@ -304,6 +297,28 @@ public class GameHUD extends Stage {
|
|||||||
miniMap.setDrawable(new TextureRegionDrawable(miniMapTexture));
|
miniMap.setDrawable(new TextureRegionDrawable(miniMapTexture));
|
||||||
avatar.setDrawable(new TextureRegionDrawable(Current.player().avatar()));
|
avatar.setDrawable(new TextureRegionDrawable(Current.player().avatar()));
|
||||||
Deck deck = AdventurePlayer.current().getSelectedDeck();
|
Deck deck = AdventurePlayer.current().getSelectedDeck();
|
||||||
|
if (AdventurePlayer.current().hasItem("Red Key"))
|
||||||
|
questKeys.add("[+RedKey]");
|
||||||
|
if (AdventurePlayer.current().hasItem("Green Key"))
|
||||||
|
questKeys.add("[+GreenKey]");
|
||||||
|
if (AdventurePlayer.current().hasItem("Blue Key"))
|
||||||
|
questKeys.add("[+BlueKey]");
|
||||||
|
if (AdventurePlayer.current().hasItem("Black Key"))
|
||||||
|
questKeys.add("[+BlackKey]");
|
||||||
|
if (AdventurePlayer.current().hasItem("White Key"))
|
||||||
|
questKeys.add("[+WhiteKey]");
|
||||||
|
if (AdventurePlayer.current().hasItem("Strange Key"))
|
||||||
|
questKeys.add("[+StrangeKey]");
|
||||||
|
if (!questKeys.isEmpty()) {
|
||||||
|
keys.setText(String.join("\n", questKeys));
|
||||||
|
scrollPane.setSize(keys.getWidth() + 8, keys.getHeight() + 5);
|
||||||
|
scrollPane.layout();
|
||||||
|
keys.layout();
|
||||||
|
scrollPane.getColor().a = opacity;
|
||||||
|
} else {
|
||||||
|
keys.setText("");
|
||||||
|
scrollPane.getColor().a = 0;
|
||||||
|
}
|
||||||
if (deck == null || deck.isEmpty() || deck.getMain().toFlatList().size() < 30) {
|
if (deck == null || deck.isEmpty() || deck.getMain().toFlatList().size() < 30) {
|
||||||
deckActor.setColor(Color.RED);
|
deckActor.setColor(Color.RED);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ public class MapStage extends GameStage {
|
|||||||
dialog.getContentTable().add(group).height(100).width(100).center();
|
dialog.getContentTable().add(group).height(100).width(100).center();
|
||||||
dialog.getContentTable().add().row();
|
dialog.getContentTable().add().row();
|
||||||
} else {
|
} else {
|
||||||
TypingLabel label = Controls.newTypingLabel("[%125]"+Controls.colorIdToTypingString(DeckProxy.getColorIdentity(deck)).toUpperCase()+"\n[%]"+deck.getName());
|
TypingLabel label = Controls.newTypingLabel("[%120]"+Controls.colorIdToTypingString(DeckProxy.getColorIdentity(deck)).toUpperCase()+"\n[%]"+deck.getName());
|
||||||
label.skipToTheEnd();
|
label.skipToTheEnd();
|
||||||
label.setAlignment(Align.center);
|
label.setAlignment(Align.center);
|
||||||
dialog.getContentTable().add(label).align(Align.center);
|
dialog.getContentTable().add(label).align(Align.center);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
|||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
|
||||||
import com.badlogic.gdx.math.Matrix4;
|
import com.badlogic.gdx.math.Matrix4;
|
||||||
import com.badlogic.gdx.utils.Align;
|
import com.badlogic.gdx.utils.Align;
|
||||||
|
import com.github.tommyettinger.textra.TextraLabel;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Class to draw directly on a pixmap
|
Class to draw directly on a pixmap
|
||||||
@@ -26,7 +27,6 @@ public abstract class DrawOnPixmap {
|
|||||||
on.drawPixmap(textureData.consumePixmap(), x, y, from.getRegionX(), from.getRegionY(), from.getRegionWidth(), from.getRegionHeight());
|
on.drawPixmap(textureData.consumePixmap(), x, y, from.getRegionX(), from.getRegionY(), from.getRegionWidth(), from.getRegionHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void drawText(Pixmap drawingMap, String itemText, int x, int y, float width, boolean bigText, Color color) {
|
public static void drawText(Pixmap drawingMap, String itemText, int x, int y, float width, boolean bigText, Color color) {
|
||||||
//used for big numbers on Gold/Life for reward...
|
//used for big numbers on Gold/Life for reward...
|
||||||
BitmapFont font = bigText ? Controls.getBitmapFont("big") : Controls.getBitmapFont("default");
|
BitmapFont font = bigText ? Controls.getBitmapFont("big") : Controls.getBitmapFont("default");
|
||||||
@@ -59,4 +59,37 @@ public abstract class DrawOnPixmap {
|
|||||||
if (bigText) //don't know why this is needed to circumvent bug getting default size for the same pixelfont
|
if (bigText) //don't know why this is needed to circumvent bug getting default size for the same pixelfont
|
||||||
Controls.getBitmapFont("default");
|
Controls.getBitmapFont("default");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void drawText(Pixmap drawingMap, TextraLabel itemText, int modX, int modY) {
|
||||||
|
FrameBuffer frameBuffer = new FrameBuffer(Pixmap.Format.RGB888, drawingMap.getWidth(), drawingMap.getHeight(), false);
|
||||||
|
SpriteBatch batch = new SpriteBatch();
|
||||||
|
|
||||||
|
frameBuffer.begin();
|
||||||
|
|
||||||
|
Gdx.gl.glClearColor(0, 0, 0, 0);
|
||||||
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
Matrix4 matrix = new Matrix4();
|
||||||
|
matrix.setToOrtho2D(0, drawingMap.getHeight(), drawingMap.getWidth(), -drawingMap.getHeight());
|
||||||
|
batch.setProjectionMatrix(matrix);
|
||||||
|
|
||||||
|
batch.begin();
|
||||||
|
//Rendering ends here. Create a new Pixmap to Texture with mipmaps, otherwise will render as full black.
|
||||||
|
Texture texture = new Texture(drawingMap);
|
||||||
|
batch.draw(texture, 0, 0);
|
||||||
|
itemText.setWrap(true);
|
||||||
|
itemText.setAlignment(1);
|
||||||
|
itemText.setWidth(texture.getWidth());
|
||||||
|
itemText.setHeight(texture.getHeight());
|
||||||
|
itemText.setX(itemText.getX()+modX);
|
||||||
|
itemText.setY(itemText.getY()+modY);
|
||||||
|
itemText.draw(batch, 1);
|
||||||
|
batch.end();
|
||||||
|
Pixmap pixmap = Pixmap.createFromFrameBuffer(0, 0, drawingMap.getWidth(), drawingMap.getHeight());
|
||||||
|
drawingMap.drawPixmap(pixmap, 0, 0);
|
||||||
|
frameBuffer.end();
|
||||||
|
texture.dispose();
|
||||||
|
batch.dispose();
|
||||||
|
pixmap.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,13 +44,13 @@ public enum KeyBinding {
|
|||||||
public String getLabelText(boolean pressed) {
|
public String getLabelText(boolean pressed) {
|
||||||
if(Controllers.getCurrent()!=null)
|
if(Controllers.getCurrent()!=null)
|
||||||
{
|
{
|
||||||
return "[%125][+"+controllerPrefix+Input.Keys.toString(bindingController).replace(" Button","")+(pressed?"_pressed]":"]");
|
return "[%120][+"+controllerPrefix+Input.Keys.toString(bindingController).replace(" Button","")+(pressed?"_pressed]":"]");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(GuiBase.isAndroid())
|
if(GuiBase.isAndroid())
|
||||||
return "";
|
return "";
|
||||||
return "[%125][+"+Input.Keys.toString(binding)+(pressed?"_pressed]":"]");
|
return "[%120][+"+Input.Keys.toString(binding)+(pressed?"_pressed]":"]");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -305,7 +305,8 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
|||||||
DrawOnPixmap.draw(drawingMap, backSprite);
|
DrawOnPixmap.draw(drawingMap, backSprite);
|
||||||
Sprite item = atlas.createSprite(reward.type.toString());
|
Sprite item = atlas.createSprite(reward.type.toString());
|
||||||
DrawOnPixmap.draw(drawingMap, (int) ((backSprite.getWidth() / 2f) - item.getWidth() / 2f), (int) ((backSprite.getHeight() / 4f) * 1f), item);
|
DrawOnPixmap.draw(drawingMap, (int) ((backSprite.getWidth() / 2f) - item.getWidth() / 2f), (int) ((backSprite.getHeight() / 4f) * 1f), item);
|
||||||
DrawOnPixmap.drawText(drawingMap, String.valueOf(reward.getCount()), 0, (int) ((backSprite.getHeight() / 4f) * 2f) - 1, backSprite.getWidth(), true, Color.WHITE);
|
//DrawOnPixmap.drawText(drawingMap, String.valueOf(reward.getCount()), 0, (int) ((backSprite.getHeight() / 4f) * 2f) - 1, backSprite.getWidth(), true, Color.WHITE);
|
||||||
|
DrawOnPixmap.drawText(drawingMap, Controls.newTextraLabel("[%200]"+reward.getCount()), 0, -10);
|
||||||
|
|
||||||
setItemTooltips(item, backSprite, atlas);
|
setItemTooltips(item, backSprite, atlas);
|
||||||
image = new Texture(drawingMap);
|
image = new Texture(drawingMap);
|
||||||
|
|||||||
@@ -339,8 +339,10 @@ public class Assets implements Disposable {
|
|||||||
textrafonts = new ObjectMap<>();
|
textrafonts = new ObjectMap<>();
|
||||||
if (!textrafonts.containsKey("textrafont")) {
|
if (!textrafonts.containsKey("textrafont")) {
|
||||||
Font font = new Font(bitmapFont, 0f, 2f, 0f, 0f);
|
Font font = new Font(bitmapFont, 0f, 2f, 0f, 0f);
|
||||||
font.addAtlas(item_atlas, 0f, 0f, 0f);
|
font.addAtlas(item_atlas, 0f, 4f, 0f);
|
||||||
font.addAtlas(pixelmana_atlas, 0f, -12f, 0f);
|
//problematic atlas since some buttons are small, and this is too big for some buttons, need a way to enable
|
||||||
|
//this via property
|
||||||
|
//font.addAtlas(pixelmana_atlas, -90f, 20f, 0f);
|
||||||
font.integerPosition = false;
|
font.integerPosition = false;
|
||||||
textrafonts.put("textrafont", font);
|
textrafonts.put("textrafont", font);
|
||||||
}
|
}
|
||||||
@@ -352,7 +354,7 @@ public class Assets implements Disposable {
|
|||||||
textrafonts = new ObjectMap<>();
|
textrafonts = new ObjectMap<>();
|
||||||
if (!textrafonts.containsKey("keysfont")) {
|
if (!textrafonts.containsKey("keysfont")) {
|
||||||
Font font = new Font(bitmapFont);
|
Font font = new Font(bitmapFont);
|
||||||
font.addAtlas(keys_atlas);
|
font.addAtlas(keys_atlas, 0f, 4f, 0f);
|
||||||
font.integerPosition = false;
|
font.integerPosition = false;
|
||||||
textrafonts.put("keysfont", font);
|
textrafonts.put("keysfont", font);
|
||||||
}
|
}
|
||||||
@@ -364,7 +366,7 @@ public class Assets implements Disposable {
|
|||||||
textrafonts = new ObjectMap<>();
|
textrafonts = new ObjectMap<>();
|
||||||
if (!textrafonts.containsKey(name)) {
|
if (!textrafonts.containsKey(name)) {
|
||||||
Font font = new Font(bitmapFont);
|
Font font = new Font(bitmapFont);
|
||||||
font.addAtlas(items_atlas);
|
font.addAtlas(items_atlas, 0f, 4f, 0f);
|
||||||
font.integerPosition = false;
|
font.integerPosition = false;
|
||||||
textrafonts.put(name, font);
|
textrafonts.put(name, font);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,7 +239,10 @@ public class SplashScreen extends FContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void drawTransition(Graphics g, boolean openAdventure, float percentage) {
|
void drawTransition(Graphics g, boolean openAdventure, float percentage) {
|
||||||
TextureRegion tr = new TextureRegion(Forge.getAssets().fallback_skins().get("title"));
|
Texture t = Forge.getAssets().fallback_skins().get("title");
|
||||||
|
TextureRegion tr = null;
|
||||||
|
if (t != null)
|
||||||
|
tr = new TextureRegion(t);
|
||||||
float oldAlpha = g.getfloatAlphaComposite();
|
float oldAlpha = g.getfloatAlphaComposite();
|
||||||
g.setAlphaComposite(percentage);
|
g.setAlphaComposite(percentage);
|
||||||
if (openAdventure) {
|
if (openAdventure) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ ManaCost:no cost
|
|||||||
Types:Enchantment
|
Types:Enchantment
|
||||||
S:Mode$ Continuous | EffectZone$ Command | Affected$ Card.Self | AffectedZone$ Command | RemoveAllAbilities$ True | IsPresent$ Card.namedGarruk's Boss Effect Phase One | PresentZone$ Command | PresentCompare$ EQ1
|
S:Mode$ Continuous | EffectZone$ Command | Affected$ Card.Self | AffectedZone$ Command | RemoveAllAbilities$ True | IsPresent$ Card.namedGarruk's Boss Effect Phase One | PresentZone$ Command | PresentCompare$ EQ1
|
||||||
S:Mode$ Continuous | EffectZone$ Command | Affected$ Forest.YouCtrl | AddType$ Swamp | Description$ Each Forest you control is a Swamp in addition to its other land types.
|
S:Mode$ Continuous | EffectZone$ Command | Affected$ Forest.YouCtrl | AddType$ Swamp | Description$ Each Forest you control is a Swamp in addition to its other land types.
|
||||||
S:Mode$ Continuous | Affected$ Beast.YouCtrl | AddPower$ 3 | AddToughness 3 | AddKeyword$ Trample & Deathtouch | Description$ Beast creatures you control get +3/+3 and have trample and Deathtouch
|
S:Mode$ Continuous | Affected$ Beast.YouCtrl | AddPower$ 3 | AddToughness$ 3 | AddKeyword$ Trample & Deathtouch | Description$ Beast creatures you control get +3/+3 and have trample and Deathtouch
|
||||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | PresentZone$ Command | Execute$ TrigConjure | TriggerDescription$ At the beginning of your upkeep, conjure a card of Garruk Phase 2's Spellbook into your hand.
|
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | PresentZone$ Command | Execute$ TrigConjure | TriggerDescription$ At the beginning of your upkeep, conjure a card of Garruk Phase 2's Spellbook into your hand.
|
||||||
SVar:TrigConjure:DB$ MakeCard | Conjure$ True | Zone$ Hand | AtRandom$ True | Spellbook$ Garruk; Apex Predator,Garruk; Cursed Huntsman,Garruk Relentless,In Garruk's Wake,Rampaging Baloths,Manglehorn,Elder Gargaroth,Gemrazer,Thragtusk,Sawtusk Demolisher,Avenger of Zendikar,Soul of the Harvest,Kogla; the Titan Ape, Terastodon, Bane of Progress
|
SVar:TrigConjure:DB$ MakeCard | Conjure$ True | Zone$ Hand | AtRandom$ True | Spellbook$ Garruk; Apex Predator,Garruk; Cursed Huntsman,Garruk Relentless,In Garruk's Wake,Rampaging Baloths,Manglehorn,Elder Gargaroth,Gemrazer,Thragtusk,Sawtusk Demolisher,Avenger of Zendikar,Soul of the Harvest,Kogla; the Titan Ape, Terastodon, Bane of Progress
|
||||||
T:Mode$ SpellCast | ValidCard$ Card.nonCreature | ValidActivatingPlayer$ Player.Opponent | Execute$ DBEffect | TriggerZones$ Command | TriggerDescription$ Whenever an opponent casts a noncreature spell,perpetually increase the power and toughness of creatures you control and creature cards in your hand, library, and graveyard by 1.
|
T:Mode$ SpellCast | ValidCard$ Card.nonCreature | ValidActivatingPlayer$ Player.Opponent | Execute$ DBEffect | TriggerZones$ Command | TriggerDescription$ Whenever an opponent casts a noncreature spell,perpetually increase the power and toughness of creatures you control and creature cards in your hand, library, and graveyard by 1.
|
||||||
@@ -13,4 +13,4 @@ SVar:Update:Mode$ ChangesZone | Origin$ Any | Destination$ Any | Static$ True |
|
|||||||
SVar:DBUpdate:DB$ UpdateRemember
|
SVar:DBUpdate:DB$ UpdateRemember
|
||||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigReanimate | TriggerDescription$ At the beginning of your end step, return a random creature card from your graveyard to the battlefield. It gains "If this creature would leave the battlefield, exile it instead".
|
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigReanimate | TriggerDescription$ At the beginning of your end step, return a random creature card from your graveyard to the battlefield. It gains "If this creature would leave the battlefield, exile it instead".
|
||||||
SVar:TrigReanimate:DB$ ChangeZone | ChangeType$ Creature.YouOwn | ChangeNum$ 1 | Hidden$ True | Origin$ Graveyard | AtRandom$ True | Destination$ Battlefield | LeaveBattlefield$ Exile
|
SVar:TrigReanimate:DB$ ChangeZone | ChangeType$ Creature.YouOwn | ChangeNum$ 1 | Hidden$ True | Origin$ Graveyard | AtRandom$ True | Destination$ Battlefield | LeaveBattlefield$ Exile
|
||||||
Oracle:Each Forest you control is a Swamp in addition to its other land types.\nBeast creatures you control get +3/+3 and have trample and Deathtouch\nAt the beginning of your upkeep, conjure a card of Garruk spellbook into your hand.\nWhenever an opponent casts a noncreature spell, perpetually increase the power and toughness of creatures you control and creature cards in your hand, library, and graveyard by 1. At the beginning of your end step, return a random creature card from your graveyard to the battlefield. That creature gains "If this creature would leave the battlefield, exile it instead".
|
Oracle:Each Forest you control is a Swamp in addition to its other land types.\nBeast creatures you control get +3/+3 and have trample and Deathtouch\nAt the beginning of your upkeep, conjure a card of Garruk spellbook into your hand.\nWhenever an opponent casts a noncreature spell, perpetually increase the power and toughness of creatures you control and creature cards in your hand, library, and graveyard by 1. At the beginning of your end step, return a random creature card from your graveyard to the battlefield. That creature gains "If this creature would leave the battlefield, exile it instead".
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ SVar:TrigRollDice:DB$ RollDice | Sides$ 20 | ResultSubAbilities$ 1-5:DBConjureSm
|
|||||||
SVar:DBConjureSmall:DB$ MakeCard | Conjure$ True | AtRandom$ True | Spellbook$ Chained Brute,Big Spender,Devilish Valet,Gibbering Fiend,Hobblefiend,Footlight Fiend,Forge Devil,Festival Crasher,Hulking Devil,Mayhem Devil,Spiteful Prankster,Vexing Devil,Wildfire Devil | Zone$ Battlefield | SpellDescription$ Conjure a random Devil unto the battlefield.
|
SVar:DBConjureSmall:DB$ MakeCard | Conjure$ True | AtRandom$ True | Spellbook$ Chained Brute,Big Spender,Devilish Valet,Gibbering Fiend,Hobblefiend,Footlight Fiend,Forge Devil,Festival Crasher,Hulking Devil,Mayhem Devil,Spiteful Prankster,Vexing Devil,Wildfire Devil | Zone$ Battlefield | SpellDescription$ Conjure a random Devil unto the battlefield.
|
||||||
SVar:DBRandomLoot:DB$ Draw | Defined$ Player | NumCards$ 3 | SubAbility$ DBDiscard3 | SpellDescription$ Each player draws three cards, then discards three cards at random.
|
SVar:DBRandomLoot:DB$ Draw | Defined$ Player | NumCards$ 3 | SubAbility$ DBDiscard3 | SpellDescription$ Each player draws three cards, then discards three cards at random.
|
||||||
SVar:DBDiscard3:DB$ Discard | Defined$ Player | Mode$ Random | NumCards$ 3
|
SVar:DBDiscard3:DB$ Discard | Defined$ Player | Mode$ Random | NumCards$ 3
|
||||||
SVar:DBDamage:DB$ DealDamage | NumDmg$ 7 | ValidTgts$ Creature | TargetsAtRandom$ True | SubAbility$ DBChangeZone | SpellDescription$ Tibalt deals seven damage to a creature chosen at random. Then Tibalt returns a random creature card to the battlefield
|
SVar:DBDamage:DB$ DealDamage | NumDmg$ 7 | ValidTgts$ Creature,Player,Planeswalker | TargetsAtRandom$ True | SubAbility$ DBChangeZone | SpellDescription$ Tibalt deals seven damage to a creature chosen at random. Then Tibalt returns a random creature card to the battlefield
|
||||||
SVar:DBChangeZone:DB$ ChangeZone | ChangeType$ Creature | ChangeNum$ 1 | Hidden$ True | Origin$ Graveyard | AtRandom$ True | Destination$ Battlefield
|
SVar:DBChangeZone:DB$ ChangeZone | ChangeType$ Creature | ChangeNum$ 1 | GainControl$ True | Hidden$ True | Origin$ Graveyard | AtRandom$ True | Destination$ Battlefield
|
||||||
SVar:DBCast:DB$ Play | AnySupportedCard$ Names:Hellion Eruption,Insurrection,Warp World,Shahrazad,Possibility Storm,Scrambleverse | RandomCopied$ True | CopyCard$ True | WithoutManaCost$ True | SpellDescription$ Cast a copy of one of the following cards chosen at random—Hellion Eruption, Insurrection, Warp World, Shahrazad, Possibility Storm, Scrambleverse.
|
SVar:DBCast:DB$ Play | AnySupportedCard$ Names:Hellion Eruption,Insurrection,Warp World,Shahrazad,Possibility Storm,Scrambleverse | RandomCopied$ True | CopyCard$ True | WithoutManaCost$ True | SpellDescription$ Cast a copy of one of the following cards chosen at random—Hellion Eruption, Insurrection, Warp World, Shahrazad, Possibility Storm, Scrambleverse.
|
||||||
SVar:DBWheel:DB$ Discard | Mode$ Hand | Defined$ Player | SubAbility$ DBEachDraw | SpellDescription$ Each player discards their hand, then draws seven cards.
|
SVar:DBWheel:DB$ Discard | Mode$ Hand | Defined$ Player | SubAbility$ DBEachDraw | SpellDescription$ Each player discards their hand, then draws seven cards.
|
||||||
SVar:DBEachDraw:DB$ Draw | Defined$ Player | NumCards$ 7
|
SVar:DBEachDraw:DB$ Draw | Defined$ Player | NumCards$ 7
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Name:Xira's Boss Effect
|
|||||||
ManaCost:no cost
|
ManaCost:no cost
|
||||||
Colors:black,green,red
|
Colors:black,green,red
|
||||||
Types:Enchantment
|
Types:Enchantment
|
||||||
S:Mode$ Continuous | Affected$ Insect.YouCtrl | EffectZone$ Command | AddPower$ 1 | AddToughness 1 | AddKeyword$ Double Team | Description$ Nontoken insects you control have +1/+1 and Double Team.
|
S:Mode$ Continuous | Affected$ Insect.YouCtrl | EffectZone$ Command | AddPower$ 1 | AddToughness$ 1 | AddKeyword$ Double Team | Description$ Nontoken insects you control have +1/+1 and Double Team.
|
||||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | Execute$ PutCounterAll | TriggerDescription$ At the beginning of your upkeep, put an egg counter on each nontoken creature.
|
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | Execute$ PutCounterAll | TriggerDescription$ At the beginning of your upkeep, put an egg counter on each nontoken creature.
|
||||||
SVar:PutCounterAll:DB$ PutCounterAll | ValidCards$ Creature.nonToken | CounterType$ EGG | CounterNum$ 1
|
SVar:PutCounterAll:DB$ PutCounterAll | ValidCards$ Creature.nonToken | CounterType$ EGG | CounterNum$ 1
|
||||||
T:Mode$ ChangesZone | Origin$ Battlefield | TriggerZones$ Command | Destination$ Graveyard | ValidCard$ Creature.counters_GE1_EGG+OppCtrl | Execute$ TrigDraw | TriggerDescription$ Whenever a creature with an egg counter on it dies, draw a card and create X 1/1 black Insect creature token with flying where X is the amount of Egg counters on that creature.
|
T:Mode$ ChangesZone | Origin$ Battlefield | TriggerZones$ Command | Destination$ Graveyard | ValidCard$ Creature.counters_GE1_EGG+OppCtrl | Execute$ TrigDraw | TriggerDescription$ Whenever a creature with an egg counter on it dies, draw a card and create X 1/1 black Insect creature token with flying where X is the amount of Egg counters on that creature.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Types:Creature Insect
|
|||||||
PT:0/2
|
PT:0/2
|
||||||
K:Defender
|
K:Defender
|
||||||
K:Reach
|
K:Reach
|
||||||
S:Mode$ Continuous | Affected$ Insect.YouCtrl+nonToken | EffectZone$ Battlefield | AddPower$ 1 | AddToughness 1 | AddKeyword$ Double Team | Description$ Nontoken Insects you control have +1/+1 and double team.
|
S:Mode$ Continuous | Affected$ Insect.YouCtrl+nonToken | EffectZone$ Battlefield | AddPower$ 1 | AddToughness$ 1 | AddKeyword$ Double Team | Description$ Nontoken Insects you control have +1/+1 and double team.
|
||||||
T:Mode$ DamageDone | ActivationLimit$ 1 | ValidSource$ Card.OppCtrl,Emblem.OppCtrl | ValidTarget$ You | TriggerZones$ Battlefield | Execute$ TrigCounter | TriggerDescription$ When a source an opponent controls deals damage to you for the first time each turn, put an egg counter on CARDNAME.
|
T:Mode$ DamageDone | ActivationLimit$ 1 | ValidSource$ Card.OppCtrl,Emblem.OppCtrl | ValidTarget$ You | TriggerZones$ Battlefield | Execute$ TrigCounter | TriggerDescription$ When a source an opponent controls deals damage to you for the first time each turn, put an egg counter on CARDNAME.
|
||||||
SVar:TrigCounter:DB$ PutCounter | CounterType$ EGG | CounterNum$ 1
|
SVar:TrigCounter:DB$ PutCounter | CounterType$ EGG | CounterNum$ 1
|
||||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME dies, create X 1/1 black Insect tokens for each egg counter on CARDNAME.
|
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME dies, create X 1/1 black Insect tokens for each egg counter on CARDNAME.
|
||||||
|
|||||||
@@ -136,7 +136,7 @@
|
|||||||
<object id="194" template="../obj/collision.tx" x="-16.4079" y="346.105" width="527.5" height="16"/>
|
<object id="194" template="../obj/collision.tx" x="-16.4079" y="346.105" width="527.5" height="16"/>
|
||||||
<object id="195" template="../obj/collision.tx" x="492.342" y="-22.9362" width="16" height="387.083"/>
|
<object id="195" template="../obj/collision.tx" x="492.342" y="-22.9362" width="16" height="387.083"/>
|
||||||
<object id="196" template="../obj/collision.tx" x="-17.6579" y="-19.9362" width="16" height="382.083"/>
|
<object id="196" template="../obj/collision.tx" x="-17.6579" y="-19.9362" width="16" height="382.083"/>
|
||||||
<object id="197" template="../obj/door_up.tx" x="290.342" y="104.105">
|
<object id="197" template="../obj/door_up.tx" x="284.842" y="71.105">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="teleport" value="maps/map/tibalt_f1.tmx"/>
|
<property name="teleport" value="maps/map/tibalt_f1.tmx"/>
|
||||||
<property name="teleportObjectId" value="114"/>
|
<property name="teleportObjectId" value="114"/>
|
||||||
@@ -144,10 +144,5 @@
|
|||||||
</object>
|
</object>
|
||||||
<object id="198" template="../obj/waypoint.tx" x="225.342" y="221.105"/>
|
<object id="198" template="../obj/waypoint.tx" x="225.342" y="221.105"/>
|
||||||
<object id="199" template="../obj/waypoint.tx" x="202.342" y="251.605"/>
|
<object id="199" template="../obj/waypoint.tx" x="202.342" y="251.605"/>
|
||||||
<object id="200" template="../obj/entry_up.tx" x="142.342" y="327.105">
|
|
||||||
<properties>
|
|
||||||
<property name="teleport" value="maps/map/tibalt_f2.tmx"/>
|
|
||||||
</properties>
|
|
||||||
</object>
|
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
|||||||
@@ -93,7 +93,7 @@
|
|||||||
<property name="waypoints" value="183,181,182,181"/>
|
<property name="waypoints" value="183,181,182,181"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="161" template="../obj/entry_up.tx" x="464.012" y="105.236">
|
<object id="161" template="../obj/entry_up.tx" x="460.679" y="88.9027" width="31.6667" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="teleport" value="maps/map/tibalt_f2.tmx"/>
|
<property name="teleport" value="maps/map/tibalt_f2.tmx"/>
|
||||||
</properties>
|
</properties>
|
||||||
|
|||||||
@@ -260,6 +260,15 @@ thinwindow
|
|||||||
orig: 16, 16
|
orig: 16, 16
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
|
transwindow
|
||||||
|
rotate: false
|
||||||
|
xy: 305, 415
|
||||||
|
size: 16, 16
|
||||||
|
split: 2, 2, 2, 2
|
||||||
|
pad: 0, 0, 0, 0
|
||||||
|
orig: 16, 16
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
uncheck
|
uncheck
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 293, 375
|
xy: 293, 375
|
||||||
|
|||||||
@@ -166,6 +166,26 @@
|
|||||||
"playMode": 2,
|
"playMode": 2,
|
||||||
"crushMode": 0
|
"crushMode": 0
|
||||||
},
|
},
|
||||||
|
"transwindow10Patch": {
|
||||||
|
"region": "transwindow",
|
||||||
|
"horizontalStretchAreas": [ 2, 13 ],
|
||||||
|
"verticalStretchAreas": [ 2, 13 ],
|
||||||
|
"tiling": true,
|
||||||
|
"minWidth": 16,
|
||||||
|
"minHeight": 16,
|
||||||
|
"rightWidth": 4,
|
||||||
|
"leftWidth": 4,
|
||||||
|
"bottomHeight": 4,
|
||||||
|
"topHeight": 4,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"offsetXspeed": 0,
|
||||||
|
"offsetYspeed": 0,
|
||||||
|
"frameDuration": 0.03,
|
||||||
|
"regions": [],
|
||||||
|
"playMode": 2,
|
||||||
|
"crushMode": 0
|
||||||
|
},
|
||||||
"pressed10Patch": {
|
"pressed10Patch": {
|
||||||
"region": "pressed",
|
"region": "pressed",
|
||||||
"horizontalStretchAreas": [ 3, 10 ],
|
"horizontalStretchAreas": [ 3, 10 ],
|
||||||
@@ -443,6 +463,9 @@
|
|||||||
"gold": {
|
"gold": {
|
||||||
"background": "9patch4"
|
"background": "9patch4"
|
||||||
},
|
},
|
||||||
|
"transluscent": {
|
||||||
|
"background": "transwindow10Patch"
|
||||||
|
},
|
||||||
"nobg": {
|
"nobg": {
|
||||||
"background": "transparent"
|
"background": "transparent"
|
||||||
}
|
}
|
||||||
@@ -549,6 +572,11 @@
|
|||||||
"background": "paper10Patch",
|
"background": "paper10Patch",
|
||||||
"titleFont": "default"
|
"titleFont": "default"
|
||||||
},
|
},
|
||||||
|
"transluscent": {
|
||||||
|
"parent": "default",
|
||||||
|
"background": "transwindow10Patch",
|
||||||
|
"titleFont": "default"
|
||||||
|
},
|
||||||
"gold": {
|
"gold": {
|
||||||
"background": "TenPatchGold",
|
"background": "TenPatchGold",
|
||||||
"titleFont": "default"
|
"titleFont": "default"
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "exittoworldmap",
|
"name": "exittoworldmap",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+ExitToWorldMap]",
|
"text": "[%120][+ExitToWorldMap]",
|
||||||
"binding": "ExitToWorldMap",
|
"binding": "ExitToWorldMap",
|
||||||
"width": 48,
|
"width": 48,
|
||||||
"height": 36,
|
"height": 36,
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "deck",
|
"name": "deck",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+Deck]",
|
"text": "[%120][+Deck]",
|
||||||
"binding": "Deck",
|
"binding": "Deck",
|
||||||
"width": 48,
|
"width": 48,
|
||||||
"height": 36,
|
"height": 36,
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "inventory",
|
"name": "inventory",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+Item]",
|
"text": "[%120][+Item]",
|
||||||
"binding": "Inventory",
|
"binding": "Inventory",
|
||||||
"width": 48,
|
"width": 48,
|
||||||
"height": 36,
|
"height": 36,
|
||||||
@@ -120,7 +120,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "statistic",
|
"name": "statistic",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+Status]",
|
"text": "[%120][+Status]",
|
||||||
"binding": "Status",
|
"binding": "Status",
|
||||||
"width": 48,
|
"width": 48,
|
||||||
"height": 36,
|
"height": 36,
|
||||||
@@ -131,7 +131,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "menu",
|
"name": "menu",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+Menu]",
|
"text": "[%120][+Menu]",
|
||||||
"binding": "Menu",
|
"binding": "Menu",
|
||||||
"width": 48,
|
"width": 48,
|
||||||
"height": 36,
|
"height": 36,
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "deck",
|
"name": "deck",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+Deck]",
|
"text": "[%120][+Deck]",
|
||||||
"binding": "Deck",
|
"binding": "Deck",
|
||||||
"width": 64,
|
"width": 64,
|
||||||
"height": 36,
|
"height": 36,
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "inventory",
|
"name": "inventory",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+Item]",
|
"text": "[%120][+Item]",
|
||||||
"binding": "Inventory",
|
"binding": "Inventory",
|
||||||
"width": 64,
|
"width": 64,
|
||||||
"height": 36,
|
"height": 36,
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "statistic",
|
"name": "statistic",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+Status]",
|
"text": "[%120][+Status]",
|
||||||
"binding": "Status",
|
"binding": "Status",
|
||||||
"width": 64,
|
"width": 64,
|
||||||
"height": 36,
|
"height": 36,
|
||||||
@@ -120,7 +120,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "menu",
|
"name": "menu",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+Menu]",
|
"text": "[%120][+Menu]",
|
||||||
"binding": "Menu",
|
"binding": "Menu",
|
||||||
"width": 64,
|
"width": 64,
|
||||||
"height": 36,
|
"height": 36,
|
||||||
@@ -141,7 +141,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "exittoworldmap",
|
"name": "exittoworldmap",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+ExitToWorldMap]",
|
"text": "[%120][+ExitToWorldMap]",
|
||||||
"binding": "ExitToWorldMap",
|
"binding": "ExitToWorldMap",
|
||||||
"width": 64,
|
"width": 64,
|
||||||
"height": 32,
|
"height": 32,
|
||||||
|
|||||||
@@ -85,7 +85,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "deck",
|
"name": "deck",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+Deck]",
|
"text": "[%120][+Deck]",
|
||||||
"binding": "Deck",
|
"binding": "Deck",
|
||||||
"width": 64,
|
"width": 64,
|
||||||
"height": 32,
|
"height": 32,
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "inventory",
|
"name": "inventory",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+Item]",
|
"text": "[%120][+Item]",
|
||||||
"binding": "Inventory",
|
"binding": "Inventory",
|
||||||
"width": 64,
|
"width": 64,
|
||||||
"height": 32,
|
"height": 32,
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "statistic",
|
"name": "statistic",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+Status]",
|
"text": "[%120][+Status]",
|
||||||
"binding": "Status",
|
"binding": "Status",
|
||||||
"width": 64,
|
"width": 64,
|
||||||
"height": 32,
|
"height": 32,
|
||||||
@@ -119,7 +119,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "menu",
|
"name": "menu",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+Menu]",
|
"text": "[%120][+Menu]",
|
||||||
"binding": "Menu",
|
"binding": "Menu",
|
||||||
"width": 64,
|
"width": 64,
|
||||||
"height": 32,
|
"height": 32,
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "exittoworldmap",
|
"name": "exittoworldmap",
|
||||||
"style":"menu",
|
"style":"menu",
|
||||||
"text": "[%125][+ExitToWorldMap]",
|
"text": "[%120][+ExitToWorldMap]",
|
||||||
"binding": "ExitToWorldMap",
|
"binding": "ExitToWorldMap",
|
||||||
"width": 64,
|
"width": 64,
|
||||||
"height": 32,
|
"height": 32,
|
||||||
|
|||||||
@@ -130,7 +130,7 @@
|
|||||||
{
|
{
|
||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "toggleAward",
|
"name": "toggleAward",
|
||||||
"text": "[%125][+AWARD]",
|
"text": "[%120][+AWARD]",
|
||||||
"width": 30,
|
"width": 30,
|
||||||
"height": 30,
|
"height": 30,
|
||||||
"x": 315,
|
"x": 315,
|
||||||
|
|||||||
@@ -121,7 +121,7 @@
|
|||||||
{
|
{
|
||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "toggleAward",
|
"name": "toggleAward",
|
||||||
"text": "[%125][+AWARD]",
|
"text": "[%120][+AWARD]",
|
||||||
"width": 30,
|
"width": 30,
|
||||||
"height": 30,
|
"height": 30,
|
||||||
"x": 5,
|
"x": 5,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Name:Cruel Grimnarch
|
|||||||
ManaCost:5 B
|
ManaCost:5 B
|
||||||
Types:Creature Phyrexian Cleric
|
Types:Creature Phyrexian Cleric
|
||||||
PT:5/5
|
PT:5/5
|
||||||
K:Deatchtouch
|
K:Deathtouch
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDiscard | TriggerDescription$ When CARDNAME enters the battlefield, each opponent discards a card. For each opponent who can't, you gain 4 life.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDiscard | TriggerDescription$ When CARDNAME enters the battlefield, each opponent discards a card. For each opponent who can't, you gain 4 life.
|
||||||
SVar:TrigDiscard:DB$ Discard | Mode$ TgtChoose | Defined$ Player.Opponent | NumCards$ 1 | RememberDiscarded$ True | SubAbility$ DBRepeat
|
SVar:TrigDiscard:DB$ Discard | Mode$ TgtChoose | Defined$ Player.Opponent | NumCards$ 1 | RememberDiscarded$ True | SubAbility$ DBRepeat
|
||||||
SVar:DBRepeat:DB$ RepeatEach | RepeatPlayers$ Player.Opponent | RepeatSubAbility$ DBGainLife | SubAbility$ DBCleanup
|
SVar:DBRepeat:DB$ RepeatEach | RepeatPlayers$ Player.Opponent | RepeatSubAbility$ DBGainLife | SubAbility$ DBCleanup
|
||||||
@@ -10,4 +10,4 @@ SVar:DBGainLife:DB$ GainLife | LifeAmount$ 4 | ConditionCheckSVar$ X | Conditio
|
|||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
SVar:X:Remembered$Valid Card.nonLand+RememberedPlayerOwn
|
SVar:X:Remembered$Valid Card.nonLand+RememberedPlayerOwn
|
||||||
DeckHas:Ability$Discard
|
DeckHas:Ability$Discard
|
||||||
Oracle:Deathtouch\nWhen Cruel Grimnarch enters the battlefield, each opponent discards a card. For each opponent who can't, you gain 4 life
|
Oracle:Deathtouch\nWhen Cruel Grimnarch enters the battlefield, each opponent discards a card. For each opponent who can't, you gain 4 life
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ ManaCost:U U B B
|
|||||||
Types:Legendary Creature Shapeshifter
|
Types:Legendary Creature Shapeshifter
|
||||||
PT:3/3
|
PT:3/3
|
||||||
K:Hexproof
|
K:Hexproof
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Graveyard | ValidCard$ Creature.nonToken+OppOwn | TriggerZones$ Battlefield | Execute$ LazavCopy | OptionalDecider$ You | TriggerDescription$ Whenever a creature card is put into an opponent's graveyard from anywhere, you may have Lazav, Dimir Mastermind become a copy of that card, except its name is Lazav, Dimir Mastermind, it's legendary in addition to its other types, and it has hexproof and this ability.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Graveyard | ValidCard$ Creature.nonToken+OppOwn | TriggerZones$ Battlefield | Execute$ LazavCopy | OptionalDecider$ You | TriggerDescription$ Whenever a creature card is put into an opponent's graveyard from anywhere, you may have CARDNAME become a copy of that card, except its name is Lazav, Dimir Mastermind, it's legendary in addition to its other types, and it has hexproof and this ability.
|
||||||
SVar:LazavCopy:DB$ Clone | Defined$ TriggeredCard | NewName$ Lazav, Dimir Mastermind | AddTypes$ Legendary | AddKeywords$ Hexproof | GainThisAbility$ True | Optional$ True | AddSVars$ LazavCopy | AILogic$ IfDefinedCreatureIsBetter
|
SVar:LazavCopy:DB$ Clone | Defined$ TriggeredCard | NewName$ Lazav, Dimir Mastermind | AddTypes$ Legendary | AddKeywords$ Hexproof | GainThisAbility$ True | Optional$ True | AddSVars$ LazavCopy | AILogic$ IfDefinedCreatureIsBetter
|
||||||
Oracle:Hexproof\nWhenever a creature card is put into an opponent's graveyard from anywhere, you may have Lazav, Dimir Mastermind become a copy of that card, except its name is Lazav, Dimir Mastermind, it's legendary in addition to its other types, and it has hexproof and this ability.
|
Oracle:Hexproof\nWhenever a creature card is put into an opponent's graveyard from anywhere, you may have Lazav, Dimir Mastermind become a copy of that card, except its name is Lazav, Dimir Mastermind, it's legendary in addition to its other types, and it has hexproof and this ability.
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ Types:Legendary Creature Human Wizard
|
|||||||
PT:4/1
|
PT:4/1
|
||||||
K:etbCounter:DREAM:7
|
K:etbCounter:DREAM:7
|
||||||
K:CARDNAME can't have more than seven dream counters on it.
|
K:CARDNAME can't have more than seven dream counters on it.
|
||||||
A:AB$ Mana | Cost$ SubCounter<1/DREAM> | Produced$ C | SpellDescription$ Add {C}.
|
A:AB$ Mana | Cost$ SubCounter<1/DREAM/NICKNAME> | Produced$ C | SpellDescription$ Add {C}.
|
||||||
A:AB$ PreventDamage | Cost$ SubCounter<1/DREAM> | Defined$ Self | Amount$ 1 | SpellDescription$ Prevent the next 1 damage that would be dealt to CARDNAME this turn.
|
A:AB$ PreventDamage | Cost$ SubCounter<1/DREAM/NICKNAME> | Defined$ Self | Amount$ 1 | SpellDescription$ Prevent the next 1 damage that would be dealt to NICKNAME this turn.
|
||||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | IsPresent$ Card.Self+startedTheTurnUntapped | TriggerDescription$ At the beginning of your upkeep, if CARDNAME started the turn untapped, put a dream counter on it.
|
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | IsPresent$ Card.Self+startedTheTurnUntapped | TriggerDescription$ At the beginning of your upkeep, if NICKNAME started the turn untapped, put a dream counter on it.
|
||||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ DREAM | CounterNum$ 1
|
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ DREAM | CounterNum$ 1
|
||||||
DeckHas:Ability$Counters
|
DeckHas:Ability$Counters
|
||||||
Oracle:Rasputin Dreamweaver enters the battlefield with seven dream counters on it.\nRemove a dream counter from Rasputin: Add {C}.\nRemove a dream counter from Rasputin: Prevent the next 1 damage that would be dealt to Rasputin this turn.\nAt the beginning of your upkeep, if Rasputin started the turn untapped, put a dream counter on it.\nRasputin can't have more than seven dream counters on it.
|
Oracle:Rasputin Dreamweaver enters the battlefield with seven dream counters on it.\nRemove a dream counter from Rasputin: Add {C}.\nRemove a dream counter from Rasputin: Prevent the next 1 damage that would be dealt to Rasputin this turn.\nAt the beginning of your upkeep, if Rasputin started the turn untapped, put a dream counter on it.\nRasputin can't have more than seven dream counters on it.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ PT:3/4
|
|||||||
K:Reach
|
K:Reach
|
||||||
T:Mode$ ChangesZoneAll | ValidCards$ Land.YouOwn+nonToken | Origin$ Any | Destination$ Graveyard | TriggerZones$ Battlefield | Execute$ TrigLifegain | TriggerDescription$ Whenever one or more land cards are put into your graveyard from anywhere, you gain 2 life.
|
T:Mode$ ChangesZoneAll | ValidCards$ Land.YouOwn+nonToken | Origin$ Any | Destination$ Graveyard | TriggerZones$ Battlefield | Execute$ TrigLifegain | TriggerDescription$ Whenever one or more land cards are put into your graveyard from anywhere, you gain 2 life.
|
||||||
SVar:TrigLifegain:DB$ GainLife | LifeAmount$ 2
|
SVar:TrigLifegain:DB$ GainLife | LifeAmount$ 2
|
||||||
T:Mode$ Phase | Phase$ Upkeep | CheckSVar$ X | SVarCompare$ GE4 | IsPresent$ Card.Self+YouOwn | IsPresent2$ Land.YouCtrl+YouOwn+namedArgoth; Sanctum of Nature | ValidPlayer$ You | Execute$ Meld | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, if you both own and control CARDNAME and a land named Argoth, Sanctum of Nature, exile them, then meld them into Titania, Gaea Incarnate.
|
T:Mode$ Phase | Phase$ Upkeep | CheckSVar$ X | SVarCompare$ GE4 | IsPresent$ Card.Self+YouOwn | IsPresent2$ Land.YouCtrl+YouOwn+namedArgoth; Sanctum of Nature | ValidPlayer$ You | Execute$ Meld | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, if there are four or more land cards in your graveyard and you both own and control CARDNAME and a land named Argoth, Sanctum of Nature, exile them, then meld them into Titania, Gaea Incarnate.
|
||||||
SVar:Meld:DB$ Meld | Name$ Titania, Gaea Incarnate | Primary$ Titania, Voice of Gaea | Secondary$ Argoth, Sanctum of Nature | SecondaryType$ Land
|
SVar:Meld:DB$ Meld | Name$ Titania, Gaea Incarnate | Primary$ Titania, Voice of Gaea | Secondary$ Argoth, Sanctum of Nature | SecondaryType$ Land
|
||||||
DeckHints:Name$Argoth, Sanctum of Nature
|
DeckHints:Name$Argoth, Sanctum of Nature
|
||||||
MeldPair:Argoth, Sanctum of Nature
|
MeldPair:Argoth, Sanctum of Nature
|
||||||
|
|||||||
10
forge-gui/res/cardsfolder/upcoming/archangel_elspeth.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/archangel_elspeth.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Name:Archangel Elspeth
|
||||||
|
ManaCost:2 W W
|
||||||
|
Types:Legendary Planeswalker Elspeth
|
||||||
|
Loyalty:4
|
||||||
|
A:AB$ Token | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | TokenScript$ w_1_1_soldier_lifelink | SpellDescription$ Create a 1/1 white Soldier creature token with lifelink.
|
||||||
|
A:AB$ PutCounter | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | CounterType$ P1P1 | CounterNum$ 2 | ValidTgts$ Creature | SubAbility$ DBAnimate | SpellDescription$ Put two +1/+1 counters on target creature.
|
||||||
|
SVar:DBAnimate:DB$ Animate | Defined$ Targeted | Types$ Angel | Keywords$ Flying | Duration$ Permanent | StackDescription$ SpellDescription | SpellDescription$ It becomes an Angel in addition to its other types and gains flying.
|
||||||
|
A:AB$ ChangeZoneAll | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | Ultimate$ True | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Permanent.nonLand+YouOwn+cmcLE3 | SpellDescription$ Return all nonland permanent cards with mana value 3 or less from your graveyard to the battlefield.
|
||||||
|
DeckHas:Ability$Token|LifeGain|Counters|Graveyard & Type$Soldier|Angel
|
||||||
|
Oracle:[+1]: Create a 1/1 white Soldier creature token with lifelink.\n[-2]: Put two +1/+1 counters on target creature. It becomes an Angel in addition to its other types and gains flying.\n[-6]: Return all nonland permanent cards with mana value 3 or less from your graveyard to the battlefield.
|
||||||
10
forge-gui/res/cardsfolder/upcoming/quicksilver_servitor.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/quicksilver_servitor.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Name:Quicksilver Servitor
|
||||||
|
ManaCost:2 U
|
||||||
|
Types:Creature Phyrexian Cleric
|
||||||
|
PT:3/3
|
||||||
|
K:Ward:2
|
||||||
|
T:Mode$ SpellCast | ValidCard$ Card.ThisTurnEnteredYourHand | ValidActivatingPlayer$ You | Execute$ TrigProliferate | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell from among cards put into your hand this turn, proliferate.
|
||||||
|
SVar:TrigProliferate:DB$ Proliferate
|
||||||
|
DeckHas:Ability$Proliferate
|
||||||
|
DeckNeeds:Ability$Counters
|
||||||
|
Oracle:Ward {2}\nWhenever you cast a spell from among cards put into your hand this turn, proliferate.
|
||||||
@@ -3,7 +3,7 @@ ManaCost:G
|
|||||||
Types:Creature Phyrexian Druid
|
Types:Creature Phyrexian Druid
|
||||||
PT:1/2
|
PT:1/2
|
||||||
K:Toxic:1
|
K:Toxic:1
|
||||||
T:Mode$ BecomesTarget | ValidTarget$ Creature.YouCtrl | ValidSource$ Spell | TriggerZones$ Battlefield | Execute$ TrigPoison | TriggerDescription$ Whenever a creature you control becomes the target of a spell, target opponent gets a poison counter.
|
T:Mode$ BecomesTarget | ValidTarget$ Creature.YouCtrl+inZoneBattlefield | ValidSource$ Spell | TriggerZones$ Battlefield | Execute$ TrigPoison | TriggerDescription$ Whenever a creature you control becomes the target of a spell, target opponent gets a poison counter.
|
||||||
SVar:TrigPoison:DB$ Poison | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | Num$ 1
|
SVar:TrigPoison:DB$ Poison | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | Num$ 1
|
||||||
DeckHas:Ability$Counters
|
DeckHas:Ability$Counters
|
||||||
DeckHints:Type$Aura
|
DeckHints:Type$Aura
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ ScryfallCode=MOM
|
|||||||
67 C Moment of Truth @Rovina Cai
|
67 C Moment of Truth @Rovina Cai
|
||||||
94 R Breach the Multiverse @Liiga Smilshkalne
|
94 R Breach the Multiverse @Liiga Smilshkalne
|
||||||
134 M Chandra, Hope's Beacon @Kieran Yanner
|
134 M Chandra, Hope's Beacon @Kieran Yanner
|
||||||
|
217 M Wrenn and Realmbreaker @Cristi Balanescu
|
||||||
222 R Drana and Linvala @Raluca Marinescu
|
222 R Drana and Linvala @Raluca Marinescu
|
||||||
225 R Ghalta and Mavren @Zezhou Chen
|
225 R Ghalta and Mavren @Zezhou Chen
|
||||||
249 R Omnath, Locus of All @Bryan Sola
|
249 R Omnath, Locus of All @Bryan Sola
|
||||||
@@ -33,7 +34,9 @@ ScryfallCode=MOM
|
|||||||
313 R Omnath, Locus of All @Jessica Rossier
|
313 R Omnath, Locus of All @Jessica Rossier
|
||||||
316 M Thalia and The Gitrog Monster @Sami Makkonen
|
316 M Thalia and The Gitrog Monster @Sami Makkonen
|
||||||
317 R Yargle and Multani @Lisa Heidhoff
|
317 R Yargle and Multani @Lisa Heidhoff
|
||||||
|
320 M Archangel Elspeth @Denys Tsiperko
|
||||||
321 M Chandra, Hope's Beacon @Randy Vargas
|
321 M Chandra, Hope's Beacon @Randy Vargas
|
||||||
|
322 M Wrenn and Realmbreaker @Jehan Choo
|
||||||
339 M Jin-Gitaxias @Julian Kok Joon Wen
|
339 M Jin-Gitaxias @Julian Kok Joon Wen
|
||||||
352 R Faerie Mastermind @Joshua Raphael
|
352 R Faerie Mastermind @Joshua Raphael
|
||||||
358 R Breach the Multiverse @Liiga Smilshkalne
|
358 R Breach the Multiverse @Liiga Smilshkalne
|
||||||
|
|||||||
@@ -896,6 +896,12 @@ ScryfallCode=SLD
|
|||||||
1234 R Azusa, Lost but Seeking @Tsubonari
|
1234 R Azusa, Lost but Seeking @Tsubonari
|
||||||
1235 R Teysa Karlov @Tsubonari
|
1235 R Teysa Karlov @Tsubonari
|
||||||
1236 R Paradise Mantle @Tsubonari
|
1236 R Paradise Mantle @Tsubonari
|
||||||
|
1237 R Xenk, Paladin Unbroken @Tatiana Vetrova & Jason Li
|
||||||
|
1238 R Simon, Wild Magic Sorcerer @Shuangcheng Leng
|
||||||
|
1239 R Forge, Neverwinter Charlatan @Liangliang Zhang
|
||||||
|
1240 R Holga, Relentless Rager @Yang Luo
|
||||||
|
1241 R Doric, Nature's Warden @Oiya Zhang & Liangliang Zhang
|
||||||
|
1242 R Edgin, Larcenous Lutenist @Wenfei Ye
|
||||||
1243 R Ugin, the Ineffable @Sansyu
|
1243 R Ugin, the Ineffable @Sansyu
|
||||||
1244 M Sorin, Imperious Bloodlord @Showichi Furumi
|
1244 M Sorin, Imperious Bloodlord @Showichi Furumi
|
||||||
1245 M Sarkhan, Dragonsoul @Miyuki Aramaki
|
1245 M Sarkhan, Dragonsoul @Miyuki Aramaki
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ ScryfallCode=SCH
|
|||||||
3 R Dark Confidant @Livia Prima
|
3 R Dark Confidant @Livia Prima
|
||||||
4 R Spell Pierce @Andrew Mar
|
4 R Spell Pierce @Andrew Mar
|
||||||
5 R Gilded Goose @Chris Seaman
|
5 R Gilded Goose @Chris Seaman
|
||||||
6 C Omnath, Locus of Creation @John Tedrick
|
6 M Omnath, Locus of Creation @John Tedrick
|
||||||
7 R Annex Sentry @Sam Guay
|
7 R Annex Sentry @Sam Guay
|
||||||
8 R Memory Deluge @Sam Guay
|
8 R Memory Deluge @Sam Guay
|
||||||
9 M Koth, Fire of Resistance @Kieran Yanner
|
9 R Koth, Fire of Resistance @Kieran Yanner
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ public final class ForgeConstants {
|
|||||||
|
|
||||||
public static final String RES_DIR = ASSETS_DIR + "res" + PATH_SEPARATOR;
|
public static final String RES_DIR = ASSETS_DIR + "res" + PATH_SEPARATOR;
|
||||||
public static final String ADVENTURE_DIR = RES_DIR + "adventure" + PATH_SEPARATOR;
|
public static final String ADVENTURE_DIR = RES_DIR + "adventure" + PATH_SEPARATOR;
|
||||||
|
public static final String ADVENTURE_DEFAULT_PLANE_DIR = ADVENTURE_DIR + "Shandalar" + PATH_SEPARATOR;
|
||||||
public static final String LISTS_DIR = RES_DIR + "lists" + PATH_SEPARATOR;
|
public static final String LISTS_DIR = RES_DIR + "lists" + PATH_SEPARATOR;
|
||||||
public static final String SETLOOKUP_DIR = RES_DIR + "setlookup" + PATH_SEPARATOR;
|
public static final String SETLOOKUP_DIR = RES_DIR + "setlookup" + PATH_SEPARATOR;
|
||||||
public static final String KEYWORD_LIST_FILE = LISTS_DIR + "NonStackingKWList.txt";
|
public static final String KEYWORD_LIST_FILE = LISTS_DIR + "NonStackingKWList.txt";
|
||||||
@@ -84,7 +85,7 @@ public final class ForgeConstants {
|
|||||||
public static final String AI_PROFILE_DIR = RES_DIR + "ai" + PATH_SEPARATOR;
|
public static final String AI_PROFILE_DIR = RES_DIR + "ai" + PATH_SEPARATOR;
|
||||||
public static final String SOUND_DIR = RES_DIR + "sound" + PATH_SEPARATOR;
|
public static final String SOUND_DIR = RES_DIR + "sound" + PATH_SEPARATOR;
|
||||||
public static final String MUSIC_DIR = RES_DIR + "music" + PATH_SEPARATOR;
|
public static final String MUSIC_DIR = RES_DIR + "music" + PATH_SEPARATOR;
|
||||||
public static final String ADVENTURE_MUSIC_DIR = ADVENTURE_DIR + "music" + PATH_SEPARATOR;
|
public static final String ADVENTURE_MUSIC_DIR = ADVENTURE_DEFAULT_PLANE_DIR + "music" + PATH_SEPARATOR;
|
||||||
public static final String LANG_DIR = RES_DIR + "languages" + PATH_SEPARATOR;
|
public static final String LANG_DIR = RES_DIR + "languages" + PATH_SEPARATOR;
|
||||||
public static final String EFFECTS_DIR = RES_DIR + "effects" + PATH_SEPARATOR;
|
public static final String EFFECTS_DIR = RES_DIR + "effects" + PATH_SEPARATOR;
|
||||||
public static final String PUZZLE_DIR = RES_DIR + "puzzle" + PATH_SEPARATOR;
|
public static final String PUZZLE_DIR = RES_DIR + "puzzle" + PATH_SEPARATOR;
|
||||||
|
|||||||
@@ -47,20 +47,16 @@ import forge.util.collect.FCollectionView;
|
|||||||
|
|
||||||
public class HumanCostDecision extends CostDecisionMakerBase {
|
public class HumanCostDecision extends CostDecisionMakerBase {
|
||||||
private final PlayerControllerHuman controller;
|
private final PlayerControllerHuman controller;
|
||||||
private final SpellAbility ability;
|
|
||||||
private final Card source;
|
|
||||||
private String orString = null;
|
private String orString = null;
|
||||||
private boolean mandatory;
|
private boolean mandatory;
|
||||||
|
|
||||||
public HumanCostDecision(final PlayerControllerHuman controller, final Player p, final SpellAbility sa, final boolean effect, final Card source) {
|
public HumanCostDecision(final PlayerControllerHuman controller, final Player p, final SpellAbility sa, final boolean effect) {
|
||||||
this(controller, p, sa, effect, source, null);
|
this(controller, p, sa, effect, sa.getHostCard(), null);
|
||||||
}
|
}
|
||||||
public HumanCostDecision(final PlayerControllerHuman controller, final Player p, final SpellAbility sa, final boolean effect, final Card source, final String orString) {
|
public HumanCostDecision(final PlayerControllerHuman controller, final Player p, final SpellAbility sa, final boolean effect, final Card source, final String orString) {
|
||||||
super(p, effect);
|
super(p, effect, sa, source);
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
ability = sa;
|
|
||||||
mandatory = sa.getPayCosts().isMandatory();
|
mandatory = sa.getPayCosts().isMandatory();
|
||||||
this.source = source;
|
|
||||||
this.orString = orString;
|
this.orString = orString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ public class HumanPlaySpellAbility {
|
|||||||
&& ability.canCastTiming(human)
|
&& ability.canCastTiming(human)
|
||||||
&& ability.checkRestrictions(human)
|
&& ability.checkRestrictions(human)
|
||||||
&& ability.isLegalAfterStack()
|
&& ability.isLegalAfterStack()
|
||||||
&& (isFree || payment.payCost(new HumanCostDecision(controller, human, ability, false, ability.getHostCard())));
|
&& (isFree || payment.payCost(new HumanCostDecision(controller, human, ability, false)));
|
||||||
|
|
||||||
game.clearTopLibsCast(ability);
|
game.clearTopLibsCast(ability);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user