mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +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;
|
||||
|
||||
public class AiCostDecision extends CostDecisionMakerBase {
|
||||
private final SpellAbility ability;
|
||||
private final Card source;
|
||||
|
||||
private final CardCollection discarded;
|
||||
private final CardCollection tapped;
|
||||
|
||||
public AiCostDecision(Player ai0, SpellAbility sa, final boolean effect) {
|
||||
super(ai0, effect);
|
||||
ability = sa;
|
||||
source = ability.getHostCard();
|
||||
super(ai0, effect, sa, sa.getHostCard());
|
||||
|
||||
discarded = new CardCollection();
|
||||
tapped = new CardCollection();
|
||||
|
||||
@@ -26,7 +26,7 @@ public class CharmAi extends SpellAbilityAi {
|
||||
@Override
|
||||
protected boolean checkApiLogic(Player ai, SpellAbility sa) {
|
||||
final Card source = sa.getHostCard();
|
||||
List<AbilitySub> choices = CharmEffect.makePossibleOptions(sa, false);
|
||||
List<AbilitySub> choices = CharmEffect.makePossibleOptions(sa);
|
||||
|
||||
final int num;
|
||||
final int min;
|
||||
|
||||
@@ -943,7 +943,6 @@ public class Game {
|
||||
public GameStage getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(GameStage value) {
|
||||
age = value;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import forge.util.collect.FCollection;
|
||||
|
||||
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();
|
||||
List<String> restriction = null;
|
||||
|
||||
@@ -30,7 +30,7 @@ public class CharmEffect extends SpellAbilityEffect {
|
||||
|
||||
List<AbilitySub> choices = Lists.newArrayList(sa.getAdditionalAbilityList("Choices"));
|
||||
|
||||
if (!forDesc) {
|
||||
if (source.getZone() != null) {
|
||||
List<AbilitySub> toRemove = Lists.newArrayList();
|
||||
for (AbilitySub ch : choices) {
|
||||
// 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) {
|
||||
Card source = sa.getHostCard();
|
||||
|
||||
List<AbilitySub> list = CharmEffect.makePossibleOptions(sa, true);
|
||||
List<AbilitySub> list = CharmEffect.makePossibleOptions(sa);
|
||||
final int num;
|
||||
boolean additionalDesc = sa.hasParam("AdditionalDescription");
|
||||
boolean optional = sa.hasParam("Optional");
|
||||
@@ -169,7 +169,7 @@ public class CharmEffect extends SpellAbilityEffect {
|
||||
//this resets all previous choices
|
||||
sa.setSubAbility(null);
|
||||
|
||||
List<AbilitySub> choices = makePossibleOptions(sa, false);
|
||||
List<AbilitySub> choices = makePossibleOptions(sa);
|
||||
|
||||
// Entwine does use all Choices
|
||||
if (sa.isEntwine()) {
|
||||
|
||||
@@ -176,7 +176,6 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
||||
final Player activator = sa.getActivatingPlayer();
|
||||
final PlayerController pc = activator.getController();
|
||||
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 eachExistingCounter = sa.hasParam("EachExistingCounter");
|
||||
@@ -453,10 +452,6 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
||||
}
|
||||
counterAmount = sa.usesTargeting() && sa.isDividedAsYouChoose() ? sa.getDividedValue(gameCard)
|
||||
: counterAmount;
|
||||
if (max != -1) {
|
||||
counterAmount = Math.max(Math.min(max - gameCard.getCounters(counterType), counterAmount),
|
||||
0);
|
||||
}
|
||||
if (sa.hasParam("UpTo")) {
|
||||
int min = AbilityUtils.calculateAmount(card, sa.getParamOrDefault("UpToMin", "0"), sa);
|
||||
Map<String, Object> params = Maps.newHashMap();
|
||||
|
||||
@@ -526,7 +526,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
if (state == CardStateName.FaceDown) {
|
||||
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;
|
||||
@@ -1427,6 +1427,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
@Override
|
||||
public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table, Map<AbilityKey, Object> params) {
|
||||
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)) {
|
||||
// As per rule 107.1b
|
||||
return;
|
||||
@@ -7115,8 +7119,12 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
|
||||
public void resetChosenModeTurn() {
|
||||
boolean updateView = !chosenModesTurn.isEmpty() || !chosenModesTurnStatic.isEmpty();
|
||||
chosenModesTurn.clear();
|
||||
chosenModesTurnStatic.clear();
|
||||
if (updateView) {
|
||||
updateAbilityTextForView();
|
||||
}
|
||||
}
|
||||
|
||||
public int getPlaneswalkerAbilityActivated() {
|
||||
|
||||
@@ -984,11 +984,24 @@ public class CardProperty {
|
||||
if (card.getTurnInZone() <= sourceController.getLastTurnNr()) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("ThisTurnEntered")) {
|
||||
} else if (property.startsWith("ThisTurnEntered")) {
|
||||
// only check if it entered the Zone this turn
|
||||
if (card.getTurnInZone() != game.getPhaseHandler().getTurn()) {
|
||||
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")) {
|
||||
// only check if it entered the Zone this turn
|
||||
if (card.getTurnInZone() == game.getPhaseHandler().getTurn()) {
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
package forge.game.cost;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
|
||||
public abstract class CostDecisionMakerBase implements ICostVisitor<PaymentDecision> {
|
||||
|
||||
protected final Player player;
|
||||
protected final SpellAbility ability;
|
||||
protected final Card source;
|
||||
private boolean effect;
|
||||
public CostDecisionMakerBase(Player player0, boolean effect0) {
|
||||
|
||||
public CostDecisionMakerBase(Player player0, boolean effect0, SpellAbility ability0, Card source0) {
|
||||
player = player0;
|
||||
effect = effect0;
|
||||
ability = ability0;
|
||||
source = source0;
|
||||
}
|
||||
|
||||
public Player getPlayer() { return player; }
|
||||
public abstract boolean paysRightAfterDecision();
|
||||
public boolean isEffect() {
|
||||
|
||||
@@ -22,7 +22,9 @@ public class GameEventCardStatsChanged extends GameEvent {
|
||||
|
||||
public GameEventCardStatsChanged(Card affected, boolean isTransform) {
|
||||
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) {
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.tommyettinger</groupId>
|
||||
<artifactId>textratypist</artifactId>
|
||||
<version>0.7.9</version>
|
||||
<version>0.8.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<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.TextureAtlas;
|
||||
import com.badlogic.gdx.scenes.scene2d.Action;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.Group;
|
||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
|
||||
@@ -55,6 +56,7 @@ public class ArenaScene extends UIScene implements IAfterMatch {
|
||||
final Sprite edgeM;
|
||||
final Sprite edgeWin;
|
||||
final Sprite edgeWinM;
|
||||
boolean enable = true;
|
||||
boolean arenaStarted = false;
|
||||
|
||||
private ArenaScene() {
|
||||
@@ -76,6 +78,8 @@ public class ArenaScene extends UIScene implements IAfterMatch {
|
||||
|
||||
goldLabel = ui.findActor("gold");
|
||||
ui.onButtonPress("done", () -> {
|
||||
if (!enable)
|
||||
return;
|
||||
if (!arenaStarted)
|
||||
ArenaScene.this.done();
|
||||
else
|
||||
@@ -107,6 +111,8 @@ public class ArenaScene extends UIScene implements IAfterMatch {
|
||||
}
|
||||
|
||||
private void startButton() {
|
||||
if (!enable)
|
||||
return;
|
||||
if (roundsWon == 0) {
|
||||
Dialog startDialog = prepareDialog(Forge.getLocalizer().getMessage("lblStart"), ButtonYes | ButtonNo, () -> startArena());
|
||||
startDialog.text("Do you want to go into the Arena?");
|
||||
@@ -119,6 +125,7 @@ public class ArenaScene extends UIScene implements IAfterMatch {
|
||||
int roundsWon = 0;
|
||||
|
||||
private void startArena() {
|
||||
enable = false;
|
||||
goldLabel.setVisible(false);
|
||||
arenaStarted = true;
|
||||
startButton.setText("[%80]" + Forge.getLocalizer().getMessage("lblContinue"));
|
||||
@@ -132,6 +139,7 @@ public class ArenaScene extends UIScene implements IAfterMatch {
|
||||
|
||||
@Override
|
||||
public void setWinner(boolean winner) {
|
||||
enable = false;
|
||||
Array<ArenaRecord> winners = new Array<>();
|
||||
Array<EnemySprite> winnersEnemies = new Array<>();
|
||||
for (int i = 0; i < fighters.size - 2; i += 2) {
|
||||
@@ -189,7 +197,15 @@ public class ArenaScene extends UIScene implements IAfterMatch {
|
||||
}
|
||||
if (Forge.isLandscapeMode()) {
|
||||
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.Texture;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Action;
|
||||
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.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Button;
|
||||
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.ui.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
@@ -48,20 +42,11 @@ public class GameHUD extends Stage {
|
||||
|
||||
static public GameHUD instance;
|
||||
private final GameStage gameStage;
|
||||
private final Image avatar;
|
||||
private final Image miniMapPlayer;
|
||||
private final TextraLabel lifePoints;
|
||||
private final TextraLabel money;
|
||||
private final TextraLabel shards;
|
||||
private final Image avatar, miniMapPlayer;
|
||||
private final TextraLabel lifePoints, money, shards, keys;
|
||||
private final Image miniMap, gamehud, mapborder, avatarborder, blank;
|
||||
private final InputEvent eventTouchDown;
|
||||
private final InputEvent eventTouchUp;
|
||||
private final TextraButton deckActor;
|
||||
private final TextraButton openMapActor;
|
||||
private final TextraButton menuActor;
|
||||
private final TextraButton statsActor;
|
||||
private final TextraButton inventoryActor;
|
||||
private final TextraButton exitToWorldMapActor;
|
||||
private final InputEvent eventTouchDown, eventTouchUp;
|
||||
private final TextraButton deckActor, openMapActor, menuActor, statsActor, inventoryActor, exitToWorldMapActor;
|
||||
public final UIActor ui;
|
||||
private final Touchpad touchpad;
|
||||
private final Console console;
|
||||
@@ -73,8 +58,10 @@ public class GameHUD extends Stage {
|
||||
private final Dialog dialog;
|
||||
private boolean dialogOnlyInput;
|
||||
private final Array<TextraButton> dialogButtonMap = new Array<>();
|
||||
private final Array<String> questKeys = new Array<>();
|
||||
private String lifepointsTextColor = "";
|
||||
TextraButton selectedKey;
|
||||
private TextraButton selectedKey;
|
||||
private final ScrollPane scrollPane;
|
||||
|
||||
private GameHUD(GameStage gameStage) {
|
||||
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");
|
||||
money.setText("[%95][+Gold] ");
|
||||
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().onShardsChange(() -> shards.setText("[%95][+Shards] " + AdventurePlayer.current().getShards()));
|
||||
|
||||
@@ -291,6 +283,7 @@ public class GameHUD extends Stage {
|
||||
Pixmap miniMapToolTipPixmap;
|
||||
|
||||
public void enter() {
|
||||
questKeys.clear();
|
||||
if (miniMapTexture != null)
|
||||
miniMapTexture.dispose();
|
||||
miniMapTexture = new Texture(WorldSave.getCurrentSave().getWorld().getBiomeImage());
|
||||
@@ -304,6 +297,28 @@ public class GameHUD extends Stage {
|
||||
miniMap.setDrawable(new TextureRegionDrawable(miniMapTexture));
|
||||
avatar.setDrawable(new TextureRegionDrawable(Current.player().avatar()));
|
||||
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) {
|
||||
deckActor.setColor(Color.RED);
|
||||
} else {
|
||||
|
||||
@@ -306,7 +306,7 @@ public class MapStage extends GameStage {
|
||||
dialog.getContentTable().add(group).height(100).width(100).center();
|
||||
dialog.getContentTable().add().row();
|
||||
} 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.setAlignment(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.math.Matrix4;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.github.tommyettinger.textra.TextraLabel;
|
||||
|
||||
/*
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
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...
|
||||
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
|
||||
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) {
|
||||
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
|
||||
{
|
||||
if(GuiBase.isAndroid())
|
||||
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);
|
||||
Sprite item = atlas.createSprite(reward.type.toString());
|
||||
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);
|
||||
image = new Texture(drawingMap);
|
||||
|
||||
@@ -339,8 +339,10 @@ public class Assets implements Disposable {
|
||||
textrafonts = new ObjectMap<>();
|
||||
if (!textrafonts.containsKey("textrafont")) {
|
||||
Font font = new Font(bitmapFont, 0f, 2f, 0f, 0f);
|
||||
font.addAtlas(item_atlas, 0f, 0f, 0f);
|
||||
font.addAtlas(pixelmana_atlas, 0f, -12f, 0f);
|
||||
font.addAtlas(item_atlas, 0f, 4f, 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;
|
||||
textrafonts.put("textrafont", font);
|
||||
}
|
||||
@@ -352,7 +354,7 @@ public class Assets implements Disposable {
|
||||
textrafonts = new ObjectMap<>();
|
||||
if (!textrafonts.containsKey("keysfont")) {
|
||||
Font font = new Font(bitmapFont);
|
||||
font.addAtlas(keys_atlas);
|
||||
font.addAtlas(keys_atlas, 0f, 4f, 0f);
|
||||
font.integerPosition = false;
|
||||
textrafonts.put("keysfont", font);
|
||||
}
|
||||
@@ -364,7 +366,7 @@ public class Assets implements Disposable {
|
||||
textrafonts = new ObjectMap<>();
|
||||
if (!textrafonts.containsKey(name)) {
|
||||
Font font = new Font(bitmapFont);
|
||||
font.addAtlas(items_atlas);
|
||||
font.addAtlas(items_atlas, 0f, 4f, 0f);
|
||||
font.integerPosition = false;
|
||||
textrafonts.put(name, font);
|
||||
}
|
||||
|
||||
@@ -239,7 +239,10 @@ public class SplashScreen extends FContainer {
|
||||
}
|
||||
|
||||
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();
|
||||
g.setAlphaComposite(percentage);
|
||||
if (openAdventure) {
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:no cost
|
||||
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$ 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.
|
||||
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.
|
||||
|
||||
@@ -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: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: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:DBChangeZone:DB$ ChangeZone | ChangeType$ Creature | ChangeNum$ 1 | Hidden$ True | Origin$ Graveyard | AtRandom$ True | Destination$ 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 | 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: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
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:Xira's Boss Effect
|
||||
ManaCost:no cost
|
||||
Colors:black,green,red
|
||||
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.
|
||||
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.
|
||||
|
||||
@@ -5,7 +5,7 @@ Types:Creature Insect
|
||||
PT:0/2
|
||||
K:Defender
|
||||
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.
|
||||
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.
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
<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="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>
|
||||
<property name="teleport" value="maps/map/tibalt_f1.tmx"/>
|
||||
<property name="teleportObjectId" value="114"/>
|
||||
@@ -144,10 +144,5 @@
|
||||
</object>
|
||||
<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="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>
|
||||
</map>
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
<property name="waypoints" value="183,181,182,181"/>
|
||||
</properties>
|
||||
</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>
|
||||
<property name="teleport" value="maps/map/tibalt_f2.tmx"/>
|
||||
</properties>
|
||||
|
||||
@@ -260,6 +260,15 @@ thinwindow
|
||||
orig: 16, 16
|
||||
offset: 0, 0
|
||||
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
|
||||
rotate: false
|
||||
xy: 293, 375
|
||||
|
||||
@@ -166,6 +166,26 @@
|
||||
"playMode": 2,
|
||||
"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": {
|
||||
"region": "pressed",
|
||||
"horizontalStretchAreas": [ 3, 10 ],
|
||||
@@ -443,6 +463,9 @@
|
||||
"gold": {
|
||||
"background": "9patch4"
|
||||
},
|
||||
"transluscent": {
|
||||
"background": "transwindow10Patch"
|
||||
},
|
||||
"nobg": {
|
||||
"background": "transparent"
|
||||
}
|
||||
@@ -549,6 +572,11 @@
|
||||
"background": "paper10Patch",
|
||||
"titleFont": "default"
|
||||
},
|
||||
"transluscent": {
|
||||
"parent": "default",
|
||||
"background": "transwindow10Patch",
|
||||
"titleFont": "default"
|
||||
},
|
||||
"gold": {
|
||||
"background": "TenPatchGold",
|
||||
"titleFont": "default"
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "exittoworldmap",
|
||||
"style":"menu",
|
||||
"text": "[%125][+ExitToWorldMap]",
|
||||
"text": "[%120][+ExitToWorldMap]",
|
||||
"binding": "ExitToWorldMap",
|
||||
"width": 48,
|
||||
"height": 36,
|
||||
@@ -97,7 +97,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "deck",
|
||||
"style":"menu",
|
||||
"text": "[%125][+Deck]",
|
||||
"text": "[%120][+Deck]",
|
||||
"binding": "Deck",
|
||||
"width": 48,
|
||||
"height": 36,
|
||||
@@ -108,7 +108,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "inventory",
|
||||
"style":"menu",
|
||||
"text": "[%125][+Item]",
|
||||
"text": "[%120][+Item]",
|
||||
"binding": "Inventory",
|
||||
"width": 48,
|
||||
"height": 36,
|
||||
@@ -120,7 +120,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "statistic",
|
||||
"style":"menu",
|
||||
"text": "[%125][+Status]",
|
||||
"text": "[%120][+Status]",
|
||||
"binding": "Status",
|
||||
"width": 48,
|
||||
"height": 36,
|
||||
@@ -131,7 +131,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "menu",
|
||||
"style":"menu",
|
||||
"text": "[%125][+Menu]",
|
||||
"text": "[%120][+Menu]",
|
||||
"binding": "Menu",
|
||||
"width": 48,
|
||||
"height": 36,
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "deck",
|
||||
"style":"menu",
|
||||
"text": "[%125][+Deck]",
|
||||
"text": "[%120][+Deck]",
|
||||
"binding": "Deck",
|
||||
"width": 64,
|
||||
"height": 36,
|
||||
@@ -97,7 +97,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "inventory",
|
||||
"style":"menu",
|
||||
"text": "[%125][+Item]",
|
||||
"text": "[%120][+Item]",
|
||||
"binding": "Inventory",
|
||||
"width": 64,
|
||||
"height": 36,
|
||||
@@ -109,7 +109,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "statistic",
|
||||
"style":"menu",
|
||||
"text": "[%125][+Status]",
|
||||
"text": "[%120][+Status]",
|
||||
"binding": "Status",
|
||||
"width": 64,
|
||||
"height": 36,
|
||||
@@ -120,7 +120,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "menu",
|
||||
"style":"menu",
|
||||
"text": "[%125][+Menu]",
|
||||
"text": "[%120][+Menu]",
|
||||
"binding": "Menu",
|
||||
"width": 64,
|
||||
"height": 36,
|
||||
@@ -141,7 +141,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "exittoworldmap",
|
||||
"style":"menu",
|
||||
"text": "[%125][+ExitToWorldMap]",
|
||||
"text": "[%120][+ExitToWorldMap]",
|
||||
"binding": "ExitToWorldMap",
|
||||
"width": 64,
|
||||
"height": 32,
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "deck",
|
||||
"style":"menu",
|
||||
"text": "[%125][+Deck]",
|
||||
"text": "[%120][+Deck]",
|
||||
"binding": "Deck",
|
||||
"width": 64,
|
||||
"height": 32,
|
||||
@@ -96,7 +96,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "inventory",
|
||||
"style":"menu",
|
||||
"text": "[%125][+Item]",
|
||||
"text": "[%120][+Item]",
|
||||
"binding": "Inventory",
|
||||
"width": 64,
|
||||
"height": 32,
|
||||
@@ -108,7 +108,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "statistic",
|
||||
"style":"menu",
|
||||
"text": "[%125][+Status]",
|
||||
"text": "[%120][+Status]",
|
||||
"binding": "Status",
|
||||
"width": 64,
|
||||
"height": 32,
|
||||
@@ -119,7 +119,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "menu",
|
||||
"style":"menu",
|
||||
"text": "[%125][+Menu]",
|
||||
"text": "[%120][+Menu]",
|
||||
"binding": "Menu",
|
||||
"width": 64,
|
||||
"height": 32,
|
||||
@@ -140,7 +140,7 @@
|
||||
"type": "TextButton",
|
||||
"name": "exittoworldmap",
|
||||
"style":"menu",
|
||||
"text": "[%125][+ExitToWorldMap]",
|
||||
"text": "[%120][+ExitToWorldMap]",
|
||||
"binding": "ExitToWorldMap",
|
||||
"width": 64,
|
||||
"height": 32,
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
{
|
||||
"type": "TextButton",
|
||||
"name": "toggleAward",
|
||||
"text": "[%125][+AWARD]",
|
||||
"text": "[%120][+AWARD]",
|
||||
"width": 30,
|
||||
"height": 30,
|
||||
"x": 315,
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
{
|
||||
"type": "TextButton",
|
||||
"name": "toggleAward",
|
||||
"text": "[%125][+AWARD]",
|
||||
"text": "[%120][+AWARD]",
|
||||
"width": 30,
|
||||
"height": 30,
|
||||
"x": 5,
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:Cruel Grimnarch
|
||||
ManaCost:5 B
|
||||
Types:Creature Phyrexian Cleric
|
||||
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.
|
||||
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
|
||||
|
||||
@@ -3,6 +3,6 @@ ManaCost:U U B B
|
||||
Types:Legendary Creature Shapeshifter
|
||||
PT:3/3
|
||||
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
|
||||
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
|
||||
K:etbCounter:DREAM:7
|
||||
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$ PreventDamage | Cost$ SubCounter<1/DREAM> | Defined$ Self | Amount$ 1 | SpellDescription$ Prevent the next 1 damage that would be dealt to CARDNAME 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.
|
||||
A:AB$ Mana | Cost$ SubCounter<1/DREAM/NICKNAME> | Produced$ C | SpellDescription$ Add {C}.
|
||||
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 NICKNAME started the turn untapped, put a dream counter on it.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ DREAM | CounterNum$ 1
|
||||
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.
|
||||
|
||||
@@ -5,7 +5,7 @@ PT:3/4
|
||||
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.
|
||||
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
|
||||
DeckHints:Name$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
|
||||
PT:1/2
|
||||
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
|
||||
DeckHas:Ability$Counters
|
||||
DeckHints:Type$Aura
|
||||
|
||||
@@ -12,6 +12,7 @@ ScryfallCode=MOM
|
||||
67 C Moment of Truth @Rovina Cai
|
||||
94 R Breach the Multiverse @Liiga Smilshkalne
|
||||
134 M Chandra, Hope's Beacon @Kieran Yanner
|
||||
217 M Wrenn and Realmbreaker @Cristi Balanescu
|
||||
222 R Drana and Linvala @Raluca Marinescu
|
||||
225 R Ghalta and Mavren @Zezhou Chen
|
||||
249 R Omnath, Locus of All @Bryan Sola
|
||||
@@ -33,7 +34,9 @@ ScryfallCode=MOM
|
||||
313 R Omnath, Locus of All @Jessica Rossier
|
||||
316 M Thalia and The Gitrog Monster @Sami Makkonen
|
||||
317 R Yargle and Multani @Lisa Heidhoff
|
||||
320 M Archangel Elspeth @Denys Tsiperko
|
||||
321 M Chandra, Hope's Beacon @Randy Vargas
|
||||
322 M Wrenn and Realmbreaker @Jehan Choo
|
||||
339 M Jin-Gitaxias @Julian Kok Joon Wen
|
||||
352 R Faerie Mastermind @Joshua Raphael
|
||||
358 R Breach the Multiverse @Liiga Smilshkalne
|
||||
|
||||
@@ -896,6 +896,12 @@ ScryfallCode=SLD
|
||||
1234 R Azusa, Lost but Seeking @Tsubonari
|
||||
1235 R Teysa Karlov @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
|
||||
1244 M Sorin, Imperious Bloodlord @Showichi Furumi
|
||||
1245 M Sarkhan, Dragonsoul @Miyuki Aramaki
|
||||
|
||||
@@ -11,7 +11,7 @@ ScryfallCode=SCH
|
||||
3 R Dark Confidant @Livia Prima
|
||||
4 R Spell Pierce @Andrew Mar
|
||||
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
|
||||
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 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 SETLOOKUP_DIR = RES_DIR + "setlookup" + PATH_SEPARATOR;
|
||||
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 SOUND_DIR = RES_DIR + "sound" + 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 EFFECTS_DIR = RES_DIR + "effects" + 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 {
|
||||
private final PlayerControllerHuman controller;
|
||||
private final SpellAbility ability;
|
||||
private final Card source;
|
||||
private String orString = null;
|
||||
private boolean mandatory;
|
||||
|
||||
public HumanCostDecision(final PlayerControllerHuman controller, final Player p, final SpellAbility sa, final boolean effect, final Card source) {
|
||||
this(controller, p, sa, effect, source, null);
|
||||
public HumanCostDecision(final PlayerControllerHuman controller, final Player p, final SpellAbility sa, final boolean effect) {
|
||||
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) {
|
||||
super(p, effect);
|
||||
super(p, effect, sa, source);
|
||||
this.controller = controller;
|
||||
ability = sa;
|
||||
mandatory = sa.getPayCosts().isMandatory();
|
||||
this.source = source;
|
||||
this.orString = orString;
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ public class HumanPlaySpellAbility {
|
||||
&& ability.canCastTiming(human)
|
||||
&& ability.checkRestrictions(human)
|
||||
&& 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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user