Merge branch 'Card-Forge:master' into YONE3

This commit is contained in:
Simisays
2023-02-28 22:30:06 +01:00
committed by GitHub
194 changed files with 3227 additions and 566 deletions

View File

@@ -15,7 +15,7 @@ import java.util.Arrays;
public class RewardEdit extends FormPanel {
RewardData currentData;
JComboBox typeField =new JComboBox(new String[] { "card", "gold", "life", "deckCard", "item","mana"});
JComboBox typeField =new JComboBox(new String[] { "card", "gold", "life", "deckCard", "item","shards"});
JSpinner probability = new JSpinner(new SpinnerNumberModel(0f, 0, 1, 0.1f));
JSpinner count = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1));
JSpinner addMaxCount = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1));

View File

@@ -18,6 +18,8 @@
package forge.ai;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import forge.game.staticability.StaticAbility;
@@ -815,13 +817,37 @@ public class AiAttackController {
} else {
if (combat.getAttackConstraints().getRequirements().get(attacker) == null) continue;
// check defenders in order of maximum requirements
for (Pair<GameEntity, Integer> e : combat.getAttackConstraints().getRequirements().get(attacker).getSortedRequirements()) {
List<Pair<GameEntity, Integer>> reqs = combat.getAttackConstraints().getRequirements().get(attacker).getSortedRequirements();
final GameEntity def = defender;
Collections.sort(reqs, new Comparator<Pair<GameEntity, Integer>>() {
@Override
public int compare(Pair<GameEntity, Integer> r1, Pair<GameEntity, Integer> r2) {
if (r1.getValue() == r2.getValue()) {
// try to attack the designated defender
if (r1.getKey().equals(def) && !r2.getKey().equals(def)) {
return -1;
}
if (r2.getKey().equals(def) && !r1.getKey().equals(def)) {
return 1;
}
// otherwise PW
if (r1.getKey() instanceof Card && r2.getKey() instanceof Player) {
return -1;
}
if (r2.getKey() instanceof Card && r1.getKey() instanceof Player) {
return 1;
}
// or weakest player
if (r1.getKey() instanceof Player && r2.getKey() instanceof Player) {
return ((Player) r1.getKey()).getLife() - ((Player) r2.getKey()).getLife();
}
}
return r2.getValue() - r1.getValue();
}
});
for (Pair<GameEntity, Integer> e : reqs) {
if (e.getRight() == 0) continue;
GameEntity mustAttackDefMaybe = e.getLeft();
// Gideon Jura returns LKI
if (mustAttackDefMaybe instanceof Card) {
mustAttackDefMaybe = ai.getGame().getCardState((Card) mustAttackDefMaybe);
}
if (canAttackWrapper(attacker, mustAttackDefMaybe) && CombatUtil.getAttackCost(ai.getGame(), attacker, mustAttackDefMaybe) == null) {
mustAttackDef = mustAttackDefMaybe;
break;

View File

@@ -1741,6 +1741,10 @@ public class ComputerUtil {
continue;
}
if (c.getCounters(CounterEnumType.SHIELD) > 0) {
continue;
}
// already regenerated
if (c.getShieldCount() > 0) {
continue;
@@ -1855,6 +1859,10 @@ public class ComputerUtil {
continue;
}
if (c.getCounters(CounterEnumType.SHIELD) > 0) {
continue;
}
// already regenerated
if (c.getShieldCount() > 0) {
continue;

View File

@@ -1312,7 +1312,6 @@ public class ComputerUtilCard {
final int power, final List<String> keywords) {
return shouldPumpCard(ai, sa, c, toughness, power, keywords, false);
}
public static boolean shouldPumpCard(final Player ai, final SpellAbility sa, final Card c, final int toughness,
final int power, final List<String> keywords, boolean immediately) {
final Game game = ai.getGame();
@@ -1546,35 +1545,37 @@ public class ComputerUtilCard {
|| ("PumpForTrample".equals(sa.getParam("AILogic")))) {
return true;
}
}
// try to determine if pumping a creature for more power will give lethal on board
// considering all unblocked creatures after the blockers are already declared
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS) && pumpedDmg > dmg) {
int totalPowerUnblocked = 0;
for (Card atk : combat.getAttackers()) {
if (combat.isBlocked(atk) && !atk.hasKeyword(Keyword.TRAMPLE)) {
continue;
}
if (atk == c) {
totalPowerUnblocked += pumpedDmg; // this accounts for Trample by now
} else {
totalPowerUnblocked += ComputerUtilCombat.damageIfUnblocked(atk, opp, combat, true);
if (combat.isBlocked(atk)) {
// consider Trample damage properly for a blocked creature
for (Card blk : combat.getBlockers(atk)) {
totalPowerUnblocked -= ComputerUtilCombat.getDamageToKill(blk, false);
// try to determine if pumping a creature for more power will give lethal on board
// considering all unblocked creatures after the blockers are already declared
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
int totalPowerUnblocked = 0;
for (Card atk : combat.getAttackers()) {
if (combat.isBlocked(atk) && !atk.hasKeyword(Keyword.TRAMPLE)) {
continue;
}
if (atk == c) {
totalPowerUnblocked += pumpedDmg; // this accounts for Trample by now
} else {
totalPowerUnblocked += ComputerUtilCombat.damageIfUnblocked(atk, opp, combat, true);
if (combat.isBlocked(atk)) {
// consider Trample damage properly for a blocked creature
for (Card blk : combat.getBlockers(atk)) {
totalPowerUnblocked -= ComputerUtilCombat.getDamageToKill(blk, false);
}
}
}
}
}
if (totalPowerUnblocked >= opp.getLife()) {
return true;
} else if (totalPowerUnblocked > dmg && sa.getHostCard() != null && sa.getHostCard().isInPlay()) {
if (sa.getPayCosts().hasNoManaCost()) {
return true; // always activate abilities which cost no mana and which can increase unblocked damage
if (totalPowerUnblocked >= opp.getLife()) {
return true;
} else if (totalPowerUnblocked > dmg && sa.getHostCard() != null && sa.getHostCard().isInPlay()) {
if (sa.getPayCosts().hasNoManaCost()) {
return true; // always activate abilities which cost no mana and which can increase unblocked damage
}
}
}
}
float value = 1.0f * (pumpedDmg - dmg);
if (c == sa.getHostCard() && power > 0) {
int divisor = sa.getPayCosts().getTotalMana().getCMC();

View File

@@ -128,7 +128,7 @@ public class ComputerUtilCombat {
// || (attacker.hasKeyword(Keyword.FADING) && attacker.getCounters(CounterEnumType.FADE) == 0)
// || attacker.hasSVar("EndOfTurnLeavePlay"));
// The creature won't untap next turn
return !attacker.isTapped() || Untap.canUntap(attacker);
return !attacker.isTapped() || (attacker.getCounters(CounterEnumType.STUN) == 0 && Untap.canUntap(attacker));
}
/**
@@ -1628,9 +1628,8 @@ public class ComputerUtilCombat {
* a {@link forge.game.card.Card} object.
* @return a boolean.
*/
public static boolean combatantCantBeDestroyed(Player ai, final Card combatant) {
// either indestructible or may regenerate
if (combatant.hasKeyword(Keyword.INDESTRUCTIBLE) || ComputerUtil.canRegenerate(ai, combatant)) {
public static boolean combatantCantBeDestroyed(final Player ai, final Card combatant) {
if (combatant.getCounters(CounterEnumType.SHIELD) > 0) {
return true;
}
@@ -1639,6 +1638,11 @@ public class ComputerUtilCombat {
return true;
}
// either indestructible or may regenerate
if (combatant.hasKeyword(Keyword.INDESTRUCTIBLE) || ComputerUtil.canRegenerate(ai, combatant)) {
return true;
}
return false;
}
@@ -2150,7 +2154,7 @@ public class ComputerUtilCombat {
final boolean noPrevention) {
final int killDamage = getDamageToKill(c, false);
if (c.hasKeyword(Keyword.INDESTRUCTIBLE) || c.getShieldCount() > 0) {
if (c.hasKeyword(Keyword.INDESTRUCTIBLE) || c.getCounters(CounterEnumType.SHIELD) > 0 || (c.getShieldCount() > 0 && c.canBeShielded())) {
if (!(source.hasKeyword(Keyword.WITHER) || source.hasKeyword(Keyword.INFECT))) {
return maxDamage + 1;
}
@@ -2488,12 +2492,12 @@ public class ComputerUtilCombat {
return poison;
}
public static GameEntity addAttackerToCombat(SpellAbility sa, Card attacker, FCollection<GameEntity> defenders) {
public static GameEntity addAttackerToCombat(SpellAbility sa, Card attacker, Iterable<? extends GameEntity> defenders) {
Combat combat = sa.getHostCard().getGame().getCombat();
if (combat != null) {
// 1. If the card that spawned the attacker was sent at a planeswalker, attack the same. Consider improving.
GameEntity def = combat.getDefenderByAttacker(sa.getHostCard());
if (def instanceof Card && ((Card)def).isPlaneswalker() && defenders.contains(def)) {
if (def instanceof Card && ((Card)def).isPlaneswalker() && Iterables.contains(defenders, def)) {
return def;
}
// 2. Otherwise, go through the list of options one by one, choose the first one that can't be blocked profitably.

View File

@@ -688,10 +688,6 @@ public class ComputerUtilMana {
ListMultimap<ManaCostShard, SpellAbility> sourcesForShards = getSourcesForShards(cost, sa, ai, test,
checkPlayable, manaSpentToPay, hasConverge, ignoreColor, ignoreType);
if (sourcesForShards == null && !purePhyrexian) {
return false; // no mana abilities to use for paying
}
int testEnergyPool = ai.getCounters(CounterEnumType.ENERGY);
final ManaPool manapool = ai.getManaPool();
ManaCostShard toPay = null;
@@ -712,7 +708,7 @@ public class ComputerUtilMana {
manapool.applyCardMatrix(pay);
for (byte color : ManaAtom.MANATYPES) {
if (manapool.tryPayCostWithColor(color, sa, cost)) {
if (manapool.tryPayCostWithColor(color, sa, cost, manaSpentToPay)) {
found = true;
break;
}
@@ -724,6 +720,11 @@ public class ComputerUtilMana {
if (cost.isPaid()) {
break;
}
if (sourcesForShards == null && !purePhyrexian) {
return false; // no mana abilities to use for paying
}
toPay = getNextShardToPay(cost);
boolean lifeInsteadOfBlack = toPay.isBlack() && ai.hasKeyword("PayLifeInsteadOf:B");
@@ -1323,9 +1324,9 @@ public class ComputerUtilMana {
public static ManaCostBeingPaid calculateManaCost(final SpellAbility sa, final boolean test, final int extraMana) {
Card card = sa.getHostCard();
Zone castFromBackup = null;
if (test && sa.isSpell()) {
if (test && sa.isSpell() && !card.isInZone(ZoneType.Stack)) {
castFromBackup = card.getCastFrom();
sa.getHostCard().setCastFrom(card.getZone() != null ? card.getZone() : null);
card.setCastFrom(card.getZone() != null ? card.getZone() : null);
}
Cost payCosts = CostAdjustment.adjust(sa.getPayCosts(), sa);

View File

@@ -33,7 +33,6 @@ import forge.game.staticability.StaticAbilityMustTarget;
import forge.game.zone.ZoneType;
import forge.util.Aggregates;
import forge.util.MyRandom;
import forge.util.collect.FCollection;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
@@ -1359,12 +1358,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
chance = aic.getIntProperty(AiProps.BLINK_RELOAD_PLANESWALKER_CHANCE);
}
if (MyRandom.percentTrue(chance)) {
Collections.sort(aiPlaneswalkers, new Comparator<Card>() {
@Override
public int compare(final Card a, final Card b) {
return a.getCounters(CounterEnumType.LOYALTY) - b.getCounters(CounterEnumType.LOYALTY);
}
});
Collections.sort(aiPlaneswalkers, CardPredicates.compareByCounterType(CounterEnumType.LOYALTY));
for (Card pw : aiPlaneswalkers) {
int curLoyalty = pw.getCounters(CounterEnumType.LOYALTY);
int freshLoyalty = Integer.valueOf(pw.getCurrentState().getBaseLoyalty());
@@ -1764,7 +1758,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
public Player chooseSinglePlayer(Player ai, SpellAbility sa, Iterable<Player> options, Map<String, Object> params) {
// Called when attaching Aura to player or adding creature to combat
if (params != null && params.containsKey("Attacker")) {
return (Player) ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), new FCollection<GameEntity>(options));
return (Player) ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), options);
}
return AttachAi.attachToPlayerAIPreferences(ai, sa, true, (List<Player>)options);
}
@@ -1772,7 +1766,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
@Override
protected GameEntity chooseSinglePlayerOrPlaneswalker(Player ai, SpellAbility sa, Iterable<GameEntity> options, Map<String, Object> params) {
if (params != null && params.containsKey("Attacker")) {
return ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), new FCollection<GameEntity>(options));
return ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), options);
}
// should not be reached
return super.chooseSinglePlayerOrPlaneswalker(ai, sa, options, params);

View File

@@ -14,6 +14,7 @@ import forge.ai.SpellAbilityAi;
import forge.game.ability.AbilityUtils;
import forge.game.ability.effects.CharmEffect;
import forge.game.card.Card;
import forge.game.keyword.Keyword;
import forge.game.player.Player;
import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility;
@@ -26,7 +27,6 @@ public class CharmAi extends SpellAbilityAi {
protected boolean checkApiLogic(Player ai, SpellAbility sa) {
final Card source = sa.getHostCard();
List<AbilitySub> choices = CharmEffect.makePossibleOptions(sa);
Collections.shuffle(choices);
final int num;
final int min;
@@ -37,6 +37,11 @@ public class CharmAi extends SpellAbilityAi {
min = sa.hasParam("MinCharmNum") ? AbilityUtils.calculateAmount(source, sa.getParam("MinCharmNum"), sa) : num;
}
// only randomize if not all possible together
if (num < choices.size() || source.hasKeyword(Keyword.ESCALATE)) {
Collections.shuffle(choices);
}
boolean timingRight = sa.isTrigger(); //is there a reason to play the charm now?
// Reset the chosen list otherwise it will be locked in forever by earlier calls

View File

@@ -34,7 +34,6 @@ import forge.game.player.PlayerActionConfirmMode;
import forge.game.player.PlayerCollection;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.collect.FCollection;
public class CopyPermanentAi extends SpellAbilityAi {
@Override
@@ -254,7 +253,7 @@ public class CopyPermanentAi extends SpellAbilityAi {
@Override
protected Player chooseSinglePlayer(Player ai, SpellAbility sa, Iterable<Player> options, Map<String, Object> params) {
if (params != null && params.containsKey("Attacker")) {
return (Player) ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), new FCollection<GameEntity>(options));
return (Player) ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), options);
}
final List<Card> cards = new PlayerCollection(options).getCreaturesInPlay();
Card chosen = ComputerUtilCard.getBestCreatureAI(cards);
@@ -264,7 +263,7 @@ public class CopyPermanentAi extends SpellAbilityAi {
@Override
protected GameEntity chooseSinglePlayerOrPlaneswalker(Player ai, SpellAbility sa, Iterable<GameEntity> options, Map<String, Object> params) {
if (params != null && params.containsKey("Attacker")) {
return ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), new FCollection<GameEntity>(options));
return ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), options);
}
// should not be reached
return super.chooseSinglePlayerOrPlaneswalker(ai, sa, options, params);

View File

@@ -45,6 +45,7 @@ import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode;
import forge.game.player.PlayerCollection;
import forge.game.player.PlayerPredicates;
import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.game.trigger.Trigger;
@@ -456,25 +457,24 @@ public class CountersPutAi extends CountersAi {
}
}
if (!ai.getGame().getStack().isEmpty() && !SpellAbilityAi.isSorcerySpeed(sa, ai)) {
// only evaluates case where all tokens are placed on a single target
if (sa.usesTargeting() && sa.getMinTargets() < 2) {
if (ComputerUtilCard.canPumpAgainstRemoval(ai, sa)) {
Card c = sa.getTargetCard();
if (sa.getTargets().size() > 1) {
sa.resetTargets();
sa.getTargets().add(c);
if (sa.usesTargeting()) {
if (!ai.getGame().getStack().isEmpty() && !SpellAbilityAi.isSorcerySpeed(sa, ai)) {
// only evaluates case where all tokens are placed on a single target
if (sa.getMinTargets() < 2) {
if (ComputerUtilCard.canPumpAgainstRemoval(ai, sa)) {
Card c = sa.getTargetCard();
if (sa.getTargets().size() > 1) {
sa.resetTargets();
sa.getTargets().add(c);
}
sa.addDividedAllocation(c, amount);
return true;
} else {
return false;
}
sa.addDividedAllocation(c, amount);
return true;
} else {
return false;
}
}
}
// Targeting
if (sa.usesTargeting()) {
sa.resetTargets();
final boolean sacSelf = ComputerUtilCost.isSacrificeSelfCost(abCost);
@@ -482,7 +482,7 @@ public class CountersPutAi extends CountersAi {
if (sa.isCurse()) {
list = ai.getOpponents().getCardsIn(ZoneType.Battlefield);
} else {
list = new CardCollection(ai.getCardsIn(ZoneType.Battlefield));
list = ComputerUtil.getSafeTargets(ai, sa, ai.getCardsIn(ZoneType.Battlefield));
}
list = CardLists.filter(list, new Predicate<Card>() {
@@ -530,8 +530,7 @@ public class CountersPutAi extends CountersAi {
for (int i = 1; i < amount + 1; i++) {
int left = amount;
for (Card c : list) {
if (ComputerUtilCard.shouldPumpCard(ai, sa, c, i, i,
Lists.newArrayList())) {
if (ComputerUtilCard.shouldPumpCard(ai, sa, c, i, i, Lists.newArrayList())) {
sa.getTargets().add(c);
sa.addDividedAllocation(c, i);
left -= i;
@@ -553,7 +552,7 @@ public class CountersPutAi extends CountersAi {
// target loop
while (sa.canAddMoreTarget()) {
if (list.isEmpty()) {
if (!sa.isTargetNumberValid() || (sa.getTargets().size() == 0)) {
if (!sa.isTargetNumberValid() || sa.getTargets().isEmpty()) {
sa.resetTargets();
return false;
} else {
@@ -567,31 +566,42 @@ public class CountersPutAi extends CountersAi {
} else {
if (type.equals("P1P1") && !SpellAbilityAi.isSorcerySpeed(sa, ai)) {
for (Card c : list) {
if (ComputerUtilCard.shouldPumpCard(ai, sa, c, amount, amount,
Lists.newArrayList())) {
if (ComputerUtilCard.shouldPumpCard(ai, sa, c, amount, amount, Lists.newArrayList())) {
choice = c;
break;
}
}
if (!source.isSpell()) { // does not cost a card
if (choice == null) { // find generic target
if (abCost == null
if (choice == null) {
// try to use as cheap kill
choice = ComputerUtil.getKilledByTargeting(sa, CardLists.getTargetableCards(ai.getOpponents().getCreaturesInPlay(), sa));
}
if (choice == null) {
// find generic target
boolean increasesCharmOutcome = false;
if (sa.getRootAbility().getApi() == ApiType.Charm && source.getStaticAbilities().isEmpty()) {
List<AbilitySub> choices = Lists.newArrayList(sa.getRootAbility().getAdditionalAbilityList("Choices"));
choices.remove(sa);
// check if other choice will already be played
increasesCharmOutcome = !choices.get(0).getTargets().isEmpty();
}
if (!source.isSpell() || increasesCharmOutcome // does not cost a card or can buff charm for no expense
|| ph.getTurn() - source.getTurnInZone() >= source.getGame().getPlayers().size() * 2) {
if (abCost == null || abCost == Cost.Zero
|| (ph.is(PhaseType.END_OF_TURN) && ph.getPlayerTurn().isOpponentOf(ai))) {
// only use at opponent EOT unless it is free
choice = chooseBoonTarget(list, type);
}
}
}
if (ComputerUtilAbility.getAbilitySourceName(sa).equals("Dromoka's Command")) {
choice = chooseBoonTarget(list, type);
}
} else {
choice = chooseBoonTarget(list, type);
}
}
if (choice == null) { // can't find anything left
if (!sa.isTargetNumberValid() || sa.getTargets().size() == 0) {
if (!sa.isTargetNumberValid() || sa.getTargets().isEmpty()) {
sa.resetTargets();
return false;
} else {
@@ -907,7 +917,6 @@ public class CountersPutAi extends CountersAi {
// Didn't want to choose anything?
list.clear();
}
}
}
return true;

View File

@@ -1,6 +1,7 @@
package forge.ai.ability;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import forge.ai.*;
import forge.game.ability.AbilityUtils;
@@ -174,6 +175,8 @@ public class DestroyAi extends SpellAbilityAi {
list = ComputerUtilCard.prioritizeCreaturesWorthRemovingNow(ai, list, false);
}
if (!SpellAbilityAi.playReusable(ai, sa)) {
list = CardLists.filter(list, Predicates.not(CardPredicates.hasCounter(CounterEnumType.SHIELD, 1)));
list = CardLists.filter(list, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
@@ -196,7 +199,7 @@ public class DestroyAi extends SpellAbilityAi {
return false;
}
//Check for undying
return (!c.hasKeyword(Keyword.UNDYING) || c.getCounters(CounterEnumType.P1P1) > 0);
return !c.hasKeyword(Keyword.UNDYING) || c.getCounters(CounterEnumType.P1P1) > 0;
}
});
}
@@ -333,6 +336,7 @@ public class DestroyAi extends SpellAbilityAi {
CardCollection preferred = CardLists.getNotKeyword(list, Keyword.INDESTRUCTIBLE);
preferred = CardLists.filterControlledBy(preferred, ai.getOpponents());
preferred = CardLists.filter(preferred, Predicates.not(CardPredicates.hasCounter(CounterEnumType.SHIELD, 1)));
if (CardLists.getNotType(preferred, "Creature").isEmpty()) {
preferred = ComputerUtilCard.prioritizeCreaturesWorthRemovingNow(ai, preferred, false);
}

View File

@@ -8,6 +8,7 @@ import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.card.CardLists;
import forge.game.card.CardPredicates;
import forge.game.card.CounterEnumType;
import forge.game.combat.Combat;
import forge.game.cost.Cost;
import forge.game.keyword.Keyword;
@@ -21,7 +22,7 @@ public class DestroyAllAi extends SpellAbilityAi {
private static final Predicate<Card> predicate = new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return !(c.hasKeyword(Keyword.INDESTRUCTIBLE) || c.getSVar("SacMe").length() > 0);
return !(c.hasKeyword(Keyword.INDESTRUCTIBLE) || c.getCounters(CounterEnumType.SHIELD) > 0 || c.hasSVar("SacMe"));
}
};

View File

@@ -27,7 +27,6 @@ import forge.game.player.PlayerPredicates;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.TextUtil;
import forge.util.collect.FCollection;
public class DigAi extends SpellAbilityAi {
@@ -190,7 +189,7 @@ public class DigAi extends SpellAbilityAi {
@Override
public Player chooseSinglePlayer(Player ai, SpellAbility sa, Iterable<Player> options, Map<String, Object> params) {
if (params != null && params.containsKey("Attacker")) {
return (Player) ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), new FCollection<GameEntity>(options));
return (Player) ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), options);
}
// an opponent choose a card from
return Iterables.getFirst(options, null);
@@ -199,7 +198,7 @@ public class DigAi extends SpellAbilityAi {
@Override
protected GameEntity chooseSinglePlayerOrPlaneswalker(Player ai, SpellAbility sa, Iterable<GameEntity> options, Map<String, Object> params) {
if (params != null && params.containsKey("Attacker")) {
return ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), new FCollection<GameEntity>(options));
return ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), options);
}
// should not be reached
return super.chooseSinglePlayerOrPlaneswalker(ai, sa, options, params);

View File

@@ -37,7 +37,7 @@ public class PermanentNoncreatureAi extends PermanentAi {
// Check for valid targets before casting
if (host.hasSVar("OblivionRing")) {
SpellAbility effectExile = AbilityFactory.getAbility(host.getSVar("TrigExile"), host);
final ZoneType origin = ZoneType.listValueOf(effectExile.getParam("Origin")).get(0);
final ZoneType origin = ZoneType.listValueOf(effectExile.getParamOrDefault("Origin", "Battlefield")).get(0);
effectExile.setActivatingPlayer(ai, true);
CardCollection targets = CardLists.getTargetableCards(game.getCardsIn(origin), effectExile);
if (sourceName.equals("Suspension Field")

View File

@@ -40,7 +40,6 @@ import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
import forge.util.MyRandom;
import forge.util.collect.FCollection;
/**
* <p>
@@ -321,7 +320,7 @@ public class TokenAi extends SpellAbilityAi {
@Override
protected Player chooseSinglePlayer(Player ai, SpellAbility sa, Iterable<Player> options, Map<String, Object> params) {
if (params != null && params.containsKey("Attacker")) {
return (Player) ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), new FCollection<GameEntity>(options));
return (Player) ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), options);
}
return Iterables.getFirst(options, null);
}
@@ -332,7 +331,7 @@ public class TokenAi extends SpellAbilityAi {
@Override
protected GameEntity chooseSinglePlayerOrPlaneswalker(Player ai, SpellAbility sa, Iterable<GameEntity> options, Map<String, Object> params) {
if (params != null && params.containsKey("Attacker")) {
return ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), new FCollection<GameEntity>(options));
return ComputerUtilCombat.addAttackerToCombat(sa, (Card) params.get("Attacker"), options);
}
// should not be reached
return super.chooseSinglePlayerOrPlaneswalker(ai, sa, options, params);

View File

@@ -188,7 +188,7 @@ public class ForgeScript {
} else if (property.startsWith("XCost")) {
String comparator = property.substring(5, 7);
int y = AbilityUtils.calculateAmount(sa.getHostCard(), property.substring(7), sa);
return Expressions.compare(sa.getXManaCostPaid(), comparator, y);
return Expressions.compare(sa.getXManaCostPaid() == null ? 0 : sa.getXManaCostPaid(), comparator, y);
} else if (property.equals("hasTapCost")) {
Cost cost = sa.getPayCosts();
return cost != null && cost.hasTapCost();

View File

@@ -288,12 +288,12 @@ public class AbilityUtils {
} else {
System.err.println("Warning: couldn't find trigger SA in the chain of SpellAbility " + sa);
}
} else if (defined.equals("FirstRemembered")) {
} else if (defined.equals("RememberedFirst")) {
Object o = hostCard.getFirstRemembered();
if (o instanceof Card) {
cards.add(game.getCardState((Card) o));
}
} else if (defined.equals("LastRemembered")) {
} else if (defined.equals("RememberedLast")) {
Object o = Iterables.getLast(hostCard.getRemembered(), null);
if (o instanceof Card) {
cards.add(game.getCardState((Card) o));

View File

@@ -15,7 +15,6 @@ import com.google.common.collect.Table;
import forge.GameCommand;
import forge.game.Game;
import forge.game.GameEntity;
import forge.game.GameObject;
import forge.game.ability.AbilityKey;
import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect;
@@ -220,11 +219,10 @@ public abstract class TokenEffectBase extends SpellAbilityEffect {
final Card host = sa.getHostCard();
final Game game = host.getGame();
GameObject aTo = Iterables.getFirst(
AbilityUtils.getDefinedObjects(host, sa.getParam("AttachedTo"), sa), null);
GameEntity aTo = Iterables.getFirst(
AbilityUtils.getDefinedEntities(host, sa.getParam("AttachedTo"), sa), null);
if (aTo instanceof GameEntity) {
GameEntity ge = (GameEntity)aTo;
if (aTo != null) {
// check what the token would be on the battlefield
Card lki = CardUtil.getLKICopy(tok);
@@ -237,7 +235,7 @@ public abstract class TokenEffectBase extends SpellAbilityEffect {
boolean canAttach = lki.isAttachment();
if (canAttach && !ge.canBeAttached(lki, sa)) {
if (canAttach && !aTo.canBeAttached(lki, sa)) {
canAttach = false;
}
@@ -253,7 +251,7 @@ public abstract class TokenEffectBase extends SpellAbilityEffect {
return false;
}
tok.attachToEntity(ge, sa);
tok.attachToEntity(aTo, sa);
return true;
}
// not a GameEntity, cant be attach

View File

@@ -2064,7 +2064,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
sbLong.append(TextUtil.fastReplace(keyword, ":", " ")).append("\r\n");
} else if (keyword.startsWith("Morph") || keyword.startsWith("Megamorph")
|| keyword.startsWith("Escape") || keyword.startsWith("Foretell:")
|| keyword.startsWith("Madness:")
|| keyword.startsWith("Madness:")|| keyword.startsWith("Recover")
|| keyword.startsWith("Reconfigure") || keyword.startsWith("Squad")
|| keyword.startsWith("Miracle") || keyword.startsWith("More Than Meets the Eye")
|| keyword.startsWith("Level up")) {
@@ -2072,11 +2072,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
sbLong.append(k[0]);
if (k.length > 1) {
final Cost mCost = new Cost(k[1], true);
if (!mCost.isOnlyManaCost()) {
sbLong.append("");
}
if (mCost.isOnlyManaCost()) {
sbLong.append(" ");
} else {
sbLong.append("");
}
sbLong.append(mCost.toString());
if (!mCost.isOnlyManaCost()) {

View File

@@ -1691,14 +1691,20 @@ public class CardFactoryUtil {
AbilitySub exileSA = (AbilitySub) AbilityFactory.getAbility(exileStr, card);
changeSA.setSubAbility(exileSA);
final Cost cost = new Cost(recoverCost, false);
String costDesc = cost.toSimpleString();
if (!cost.isOnlyManaCost()) {
costDesc = "" + costDesc;
}
String trigObject = card.isCreature() ? "Creature.Other+YouOwn" : "Creature.YouOwn";
String trigArticle = card.isCreature() ? "another" : "a";
String trigStr = "Mode$ ChangesZone | ValidCard$ " + trigObject
+ " | Origin$ Battlefield | Destination$ Graveyard | "
+ "TriggerZones$ Graveyard | Secondary$ True | "
+ "TriggerDescription$ Recover " + recoverCost + " (When " + trigArticle + " creature is "
+ "TriggerDescription$ Recover " + costDesc + " (When " + trigArticle + " creature is "
+ "put into your graveyard from the battlefield, you "
+ "may pay " + recoverCost + ". If you do, return "
+ "may pay " + costDesc + ". If you do, return "
+ "CARDNAME from your graveyard to your hand. Otherwise,"
+ " exile CARDNAME.)";
final Trigger myTrigger = TriggerHandler.parseTrigger(trigStr, card, intrinsic);

View File

@@ -42,6 +42,7 @@ import forge.game.GameEntityCounterTable;
import forge.game.GameLogEntryType;
import forge.game.GameObjectMap;
import forge.game.ability.AbilityKey;
import forge.game.ability.ApiType;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.card.CardCollectionView;
@@ -795,7 +796,7 @@ public class Combat {
assigningPlayer = orderedBlockers.get(0).getController();
}
final SpellAbility emptySA = new SpellAbility.EmptySa(attacker);
final SpellAbility emptySA = new SpellAbility.EmptySa(ApiType.Cleanup, attacker);
boolean assignToPlayer = false;
if (StaticAbilityAssignCombatDamageAsUnblocked.assignCombatDamageAsUnblocked(attacker, false)) {
@@ -846,8 +847,7 @@ public class Combat {
// If the Attacker is unblocked, or it's a trampler and has 0 blockers, deal damage to defender
if (defender instanceof Card && attacker.hasKeyword("Trample:Planeswalker")) {
if (orderedBlockers == null || orderedBlockers.isEmpty()) {
CardCollection cc = new CardCollection();
cc.add((Card)defender);
CardCollection cc = new CardCollection((Card) defender);
orderedBlockers = cc;
} else {
orderedBlockers.add((Card) defender);
@@ -862,7 +862,7 @@ public class Combat {
attackers.remove(attacker);
if (assignCombatDamageToCreature) {
Card chosen = attacker.getController().getController().chooseCardsForEffect(getDefendersCreatures(),
null, Localizer.getInstance().getMessage("lblChooseCreature"), 1, 1, false, null).get(0);
emptySA, Localizer.getInstance().getMessage("lblChooseCreature"), 1, 1, false, null).get(0);
damageMap.put(attacker, chosen, damageDealt);
} else if (trampler || !band.isBlocked()) { // this is called after declare blockers, no worries 'bout nulls in isBlocked
damageMap.put(attacker, defender, damageDealt);

View File

@@ -212,7 +212,7 @@ public class ManaPool extends ManaConversionMatrix implements Iterable<Mana> {
}
}
public boolean tryPayCostWithColor(byte colorCode, SpellAbility saPaidFor, ManaCostBeingPaid manaCost) {
public boolean tryPayCostWithColor(byte colorCode, SpellAbility saPaidFor, ManaCostBeingPaid manaCost, List<Mana> manaSpentToPay) {
Mana manaFound = null;
String restriction = manaCost.getSourceRestriction();
Collection<Mana> cm = floatingMana.get(colorCode);
@@ -231,7 +231,7 @@ public class ManaPool extends ManaConversionMatrix implements Iterable<Mana> {
}
if (manaFound != null && tryPayCostWithMana(saPaidFor, manaCost, manaFound, false)) {
saPaidFor.getPayingMana().add(0, manaFound);
manaSpentToPay.add(0, manaFound);
return true;
}
return false;

View File

@@ -105,7 +105,7 @@ public class Untap extends Phase {
public static final Predicate<Card> CANUNTAP = new Predicate<Card>() {
@Override
public boolean apply(Card c) {
return Untap.canUntap(c);
return canUntap(c);
}
};

View File

@@ -2891,6 +2891,16 @@ public class Player extends GameEntity implements Comparable<Player> {
com.add(conspire);
}
// Adventure Mode items
Iterable<? extends IPaperCard> adventureItemCards = registeredPlayer.getExtraCardsInCommandZone();
if (adventureItemCards != null) {
for (final IPaperCard cp : adventureItemCards) {
Card c = Card.fromPaperCard(cp, this);
com.add(c);
c.setStartsGameInPlay(true);
}
}
for (final Card c : getCardsIn(ZoneType.Library)) {
for (KeywordInterface inst : c.getKeywords()) {
String kw = inst.getOriginal();

View File

@@ -29,6 +29,7 @@ public class RegisteredPlayer {
private int manaShards = 0;
private Iterable<IPaperCard> cardsOnBattlefield = null;
private Iterable<IPaperCard> extraCardsOnBattlefield = null;
private Iterable<IPaperCard> extraCardsInCommandZone = null;
private Iterable<? extends IPaperCard> schemes = null;
private Iterable<PaperCard> planes = null;
private Iterable<PaperCard> conspiracies = null;
@@ -56,6 +57,10 @@ public class RegisteredPlayer {
extraCardsOnBattlefield == null ? EmptyList : extraCardsOnBattlefield);
}
public final Iterable<? extends IPaperCard> getExtraCardsInCommandZone() {
return extraCardsInCommandZone == null ? EmptyList : extraCardsInCommandZone;
}
public final void setStartingLife(int startingLife) {
this.startingLife = startingLife;
}
@@ -86,6 +91,13 @@ public class RegisteredPlayer {
this.extraCardsOnBattlefield = Iterables.concat(this.extraCardsOnBattlefield, extraCardsonTable);
}
public final void addExtraCardsInCommandZone(Iterable<IPaperCard> extraCardsInCommandZone) {
if (this.extraCardsInCommandZone == null)
this.extraCardsInCommandZone = extraCardsInCommandZone;
else
this.extraCardsInCommandZone = Iterables.concat(this.extraCardsInCommandZone, extraCardsInCommandZone);
}
public int getStartingHand() {
return startingHand;
}

View File

@@ -20,7 +20,6 @@ package forge.game.spellability;
import forge.card.mana.ManaCost;
import forge.game.card.Card;
import forge.game.cost.Cost;
import forge.game.player.Player;
/**
* <p>
@@ -51,11 +50,6 @@ public abstract class AbilityStatic extends Ability implements Cloneable {
}
@Override
public boolean canPlay() {
Player player = getActivatingPlayer();
if (player == null) {
player = this.getHostCard().getController();
}
final Card c = this.getHostCard();
return this.getRestrictions().canPlay(c, this);

View File

@@ -126,15 +126,8 @@ public class TriggerSpellAbilityCastOrCopy extends Trigger {
boolean validTgtFound = false;
while (sa != null && !validTgtFound) {
for (final Card tgt : sa.getTargets().getTargetCards()) {
if (matchesValid(tgt, getParam("TargetsValid").split(","))) {
validTgtFound = true;
break;
}
}
for (final Player p : sa.getTargets().getTargetPlayers()) {
if (matchesValid(p, getParam("TargetsValid").split(","))) {
for (final GameEntity ge : sa.getTargets().getTargetEntities()) {
if (matchesValid(ge, getParam("TargetsValid").split(","))) {
validTgtFound = true;
break;
}

View File

@@ -7,6 +7,10 @@ import forge.item.PaperToken;
import forge.model.FModel;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
public class EffectData implements Serializable {
public String name = null; //Effect name. Can be checked for.
@@ -14,6 +18,7 @@ public class EffectData implements Serializable {
public int lifeModifier = 0; //Amount to add to starting Life.
public int changeStartCards = 0; //Amount to add to starting hand size.
public String[] startBattleWithCard; //Cards that start in the Battlefield.
public String[] startBattleWithCardInCommandZone; //Cards that start in the Command Zone of the Battlefield.
//Map only effects.
public boolean colorView = false; //Allows to display enemy colors on the map.
public float moveSpeed = 1.0f; //Change of movement speed. Map only.
@@ -52,13 +57,27 @@ public class EffectData implements Serializable {
return startCards;
}
public String cardNames() {
StringBuilder ret = new StringBuilder();
Array<IPaperCard> array=startBattleWithCards();
for(int i =0;i<array.size;i++) {
ret.append(array.get(i).toString());
if(i!=array.size-1) ret.append(" , ");
public Array<IPaperCard> startBattleWithCardsInCommandZone(){
Array<IPaperCard> startCardsInCommandZone=new Array<>();
if(startBattleWithCardInCommandZone != null) {
for (String name:startBattleWithCardInCommandZone) {
PaperCard C = FModel.getMagicDb().getCommonCards().getCard(name);
if(C != null)
startCardsInCommandZone.add(C);
else {
PaperToken T = FModel.getMagicDb().getAllTokens().getToken(name);
if (T != null) startCardsInCommandZone.add(T);
else System.err.print("Can not find card \"" + name + "\"\n");
}
}
}
return startCardsInCommandZone;
}
public String itemize(Array<IPaperCard> paperCards) {
StringBuilder ret = new StringBuilder();
Map<IPaperCard, Integer> duplicateCountMap = Arrays.stream(paperCards.toArray()).collect(Collectors.toMap(Function.identity(), cards -> 1, Math::addExact));
duplicateCountMap.forEach((key, value) -> ret.append("\n").append(value).append("x ").append(key));
return ret.toString();
}
@@ -69,7 +88,9 @@ public class EffectData implements Serializable {
if(lifeModifier != 0)
description += "[+Life] " + ((lifeModifier > 0) ? "+" : "") + lifeModifier + "\n";
if(startBattleWithCard != null && startBattleWithCard.length != 0)
description+="Cards on battlefield: \n" + cardNames() + "\n";
description+="Battlefield:" + itemize(startBattleWithCards()) + "\n";
if(startBattleWithCardInCommandZone != null && startBattleWithCardInCommandZone.length != 0)
description+="Command:" + itemize(startBattleWithCardsInCommandZone()) + "\n";
if(changeStartCards != 0)
description+="Starting hand: " + changeStartCards + "\n";
if(moveSpeed!=0 && moveSpeed != 1)

View File

@@ -167,14 +167,19 @@ public class DuelScene extends ForgeScene {
int changeStartCards = 0;
int extraManaShards = 0;
Array<IPaperCard> startCards = new Array<>();
Array<IPaperCard> startCardsInCommandZone = new Array<>();
for (EffectData data : effects) {
lifeMod += data.lifeModifier;
changeStartCards += data.changeStartCards;
startCards.addAll(data.startBattleWithCards());
startCardsInCommandZone.addAll(data.startBattleWithCardsInCommandZone());
extraManaShards += data.extraManaShards;
}
player.addExtraCardsOnBattlefield(startCards);
player.addExtraCardsInCommandZone(startCardsInCommandZone);
player.setStartingLife(Math.max(1, lifeMod + player.getStartingLife()));
player.setStartingHand(player.getStartingHand() + changeStartCards);
player.setManaShards((player.getManaShards() + extraManaShards));

View File

@@ -230,6 +230,8 @@ public class InventoryScene extends UIScene {
}
}
itemDescription.setText(data.name+"\n"+data.getDescription());
itemDescription.setWrap(true);
itemDescription.layout();
}

View File

@@ -358,7 +358,7 @@ public class SpellSmithScene extends UIScene {
if (cost_low > -1) totalCost *= 2.5f; //And CMC cost multiplier.
cardPool = StreamSupport.stream(P.spliterator(), false).collect(Collectors.toList());
poolSize.setText(((cardPool.size() > 0 ? "[FOREST]" : "[RED]")) + cardPool.size() + " possible card" + (cardPool.size() != 1 ? "s" : ""));
poolSize.setText(((cardPool.size() > 0 ? "[/][FOREST]" : "[/][RED]")) + cardPool.size() + " possible card" + (cardPool.size() != 1 ? "s" : ""));
currentPrice = (int) totalCost;
currentShardPrice = (int) (totalCost * 0.2f); //Intentionally rounding up via the cast to int
pullUsingGold.setText("Pull: " + currentPrice + "[+gold]");

View File

@@ -0,0 +1,282 @@
package forge.adventure.stage;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.maps.MapGroupLayer;
import com.badlogic.gdx.maps.MapLayer;
import com.badlogic.gdx.maps.MapLayers;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapImageLayer;
import com.badlogic.gdx.maps.tiled.TiledMapTile;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import static com.badlogic.gdx.graphics.g2d.Batch.*;
// https://www.badlogicgames.com/forum/viewtopic.php?t=16368#p74103
// better solution: render to framebuffer and scale that one?
public class OrthogonalTiledMapRendererBleeding extends OrthogonalTiledMapRenderer {
public OrthogonalTiledMapRendererBleeding(TiledMap map, Batch batch) {
super(map, batch);
}
@Override
protected void renderMapLayer(MapLayer layer) {
if (layer.isVisible()) {
if (layer instanceof MapGroupLayer) {
MapLayers childLayers = ((MapGroupLayer) layer).getLayers();
for (int i = 0; i < childLayers.size(); ++i) {
MapLayer childLayer = childLayers.get(i);
if (childLayer.isVisible()) {
this.renderMapLayer(childLayer);
}
}
} else if (layer instanceof TiledMapTileLayer) {
this.renderTileLayer((TiledMapTileLayer) layer);
} else if (layer instanceof TiledMapImageLayer) {
this.renderImageLayer((TiledMapImageLayer) layer);
} else {
this.renderObjects(layer);
}
}
}
@Override
public void renderImageLayer(TiledMapImageLayer layer) {
final Color batchColor = batch.getColor();
final float color = Color.toFloatBits(batchColor.r, batchColor.g, batchColor.b, batchColor.a * layer.getOpacity());
final float[] vertices = this.vertices;
TextureRegion region = layer.getTextureRegion();
if (region == null) {
return;
}
fixBleeding(region);
final float x = layer.getX();
final float y = layer.getY();
final float x1 = x * unitScale;
final float y1 = y * unitScale;
final float x2 = x1 + region.getRegionWidth() * unitScale;
final float y2 = y1 + region.getRegionHeight() * unitScale;
imageBounds.set(x1, y1, x2 - x1, y2 - y1);
if (viewBounds.contains(imageBounds) || viewBounds.overlaps(imageBounds)) {
final float u1 = region.getU();
final float v1 = region.getV2();
final float u2 = region.getU2();
final float v2 = region.getV();
vertices[X1] = x1;
vertices[Y1] = y1;
vertices[C1] = color;
vertices[U1] = u1;
vertices[V1] = v1;
vertices[X2] = x1;
vertices[Y2] = y2;
vertices[C2] = color;
vertices[U2] = u1;
vertices[V2] = v2;
vertices[X3] = x2;
vertices[Y3] = y2;
vertices[C3] = color;
vertices[U3] = u2;
vertices[V3] = v2;
vertices[X4] = x2;
vertices[Y4] = y1;
vertices[C4] = color;
vertices[U4] = u2;
vertices[V4] = v1;
batch.draw(region.getTexture(), vertices, 0, NUM_VERTICES);
}
}
@Override
public void renderTileLayer(TiledMapTileLayer layer) {
final Color batchColor = batch.getColor();
final float color = Color.toFloatBits(batchColor.r, batchColor.g, batchColor.b, batchColor.a * layer.getOpacity());
final int layerWidth = layer.getWidth();
final int layerHeight = layer.getHeight();
final float layerTileWidth = layer.getTileWidth() * unitScale;
final float layerTileHeight = layer.getTileHeight() * unitScale;
final float layerOffsetX = layer.getRenderOffsetX() * unitScale;
// offset in tiled is y down, so we flip it
final float layerOffsetY = -layer.getRenderOffsetY() * unitScale;
final int col1 = Math.max(0, (int) ((viewBounds.x - layerOffsetX) / layerTileWidth));
final int col2 = Math.min(layerWidth,
(int) ((viewBounds.x + viewBounds.width + layerTileWidth - layerOffsetX) / layerTileWidth));
final int row1 = Math.max(0, (int) ((viewBounds.y - layerOffsetY) / layerTileHeight));
final int row2 = Math.min(layerHeight,
(int) ((viewBounds.y + viewBounds.height + layerTileHeight - layerOffsetY) / layerTileHeight));
float y = row2 * layerTileHeight + layerOffsetY;
float xStart = col1 * layerTileWidth + layerOffsetX;
final float[] vertices = this.vertices;
for (int row = row2; row >= row1; row--) {
float x = xStart;
for (int col = col1; col < col2; col++) {
final TiledMapTileLayer.Cell cell = layer.getCell(col, row);
if (cell == null) {
x += layerTileWidth;
continue;
}
final TiledMapTile tile = cell.getTile();
if (tile != null) {
final boolean flipX = cell.getFlipHorizontally();
final boolean flipY = cell.getFlipVertically();
final int rotations = cell.getRotation();
TextureRegion region = tile.getTextureRegion();
fixBleeding(region);
float x1 = x + tile.getOffsetX() * unitScale;
float y1 = y + tile.getOffsetY() * unitScale;
float x2 = x1 + region.getRegionWidth() * unitScale;
float y2 = y1 + region.getRegionHeight() * unitScale;
float u1 = region.getU();
float v1 = region.getV2();
float u2 = region.getU2();
float v2 = region.getV();
vertices[X1] = x1;
vertices[Y1] = y1;
vertices[C1] = color;
vertices[U1] = u1;
vertices[V1] = v1;
vertices[X2] = x1;
vertices[Y2] = y2;
vertices[C2] = color;
vertices[U2] = u1;
vertices[V2] = v2;
vertices[X3] = x2;
vertices[Y3] = y2;
vertices[C3] = color;
vertices[U3] = u2;
vertices[V3] = v2;
vertices[X4] = x2;
vertices[Y4] = y1;
vertices[C4] = color;
vertices[U4] = u2;
vertices[V4] = v1;
if (flipX) {
float temp = vertices[U1];
vertices[U1] = vertices[U3];
vertices[U3] = temp;
temp = vertices[U2];
vertices[U2] = vertices[U4];
vertices[U4] = temp;
}
if (flipY) {
float temp = vertices[V1];
vertices[V1] = vertices[V3];
vertices[V3] = temp;
temp = vertices[V2];
vertices[V2] = vertices[V4];
vertices[V4] = temp;
}
if (rotations != 0) {
switch (rotations) {
case TiledMapTileLayer.Cell.ROTATE_90: {
float tempV = vertices[V1];
vertices[V1] = vertices[V2];
vertices[V2] = vertices[V3];
vertices[V3] = vertices[V4];
vertices[V4] = tempV;
float tempU = vertices[U1];
vertices[U1] = vertices[U2];
vertices[U2] = vertices[U3];
vertices[U3] = vertices[U4];
vertices[U4] = tempU;
break;
}
case TiledMapTileLayer.Cell.ROTATE_180: {
float tempU = vertices[U1];
vertices[U1] = vertices[U3];
vertices[U3] = tempU;
tempU = vertices[U2];
vertices[U2] = vertices[U4];
vertices[U4] = tempU;
float tempV = vertices[V1];
vertices[V1] = vertices[V3];
vertices[V3] = tempV;
tempV = vertices[V2];
vertices[V2] = vertices[V4];
vertices[V4] = tempV;
break;
}
case TiledMapTileLayer.Cell.ROTATE_270: {
float tempV = vertices[V1];
vertices[V1] = vertices[V4];
vertices[V4] = vertices[V3];
vertices[V3] = vertices[V2];
vertices[V2] = tempV;
float tempU = vertices[U1];
vertices[U1] = vertices[U4];
vertices[U4] = vertices[U3];
vertices[U3] = vertices[U2];
vertices[U2] = tempU;
break;
}
}
}
batch.draw(region.getTexture(), vertices, 0, NUM_VERTICES);
}
x += layerTileWidth;
}
y -= layerTileHeight;
}
}
public static void fixBleeding(TextureRegion region) {
float fix = 0.01f;
float x = region.getRegionX();
float y = region.getRegionY();
float width = region.getRegionWidth();
float height = region.getRegionHeight();
float invTexWidth = 1f / region.getTexture().getWidth();
float invTexHeight = 1f / region.getTexture().getHeight();
region.setRegion((x + fix) * invTexWidth, (y + fix) * invTexHeight, (x + width - fix) * invTexWidth, (y + height - fix) * invTexHeight); // Trims Region
}
public void begin() {
beginRender();
}
public void end() {
endRender();
}
@Override
protected void beginRender() {
super.beginRender();
}
@Override
protected void endRender() {
super.endRender();
}
}

View File

@@ -3,39 +3,36 @@ package forge.adventure.stage;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.maps.MapLayer;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
/**
* Custom renderer to render the game stage between the map layers of a tiled map
*/
public class PointOfInterestMapRenderer extends OrthogonalTiledMapRenderer {
public class PointOfInterestMapRenderer extends OrthogonalTiledMapRendererBleeding {
private final MapStage stage;
public PointOfInterestMapRenderer(MapStage stage) {
super(null,stage.getBatch());
super(null, stage.getBatch());
this.stage = stage;
}
@Override
public void render () {
public void render() {
Camera camera = stage.getCamera();
camera.update();
batch.setProjectionMatrix(camera.combined);
beginRender();
for (MapLayer layer : map.getLayers()) {
renderMapLayer(layer);
if(layer==stage.getSpriteLayer())
{
if (layer == stage.getSpriteLayer()) {
stage.draw(batch);
}
}
endRender();
}
public void loadMap(TiledMap map,String sourceMap)
{
stage.loadMap(map,sourceMap);
public void loadMap(TiledMap map, String sourceMap) {
stage.loadMap(map, sourceMap);
super.setMap(map);
}

View File

@@ -447,7 +447,7 @@ public class Controls {
}
else {
currencyAmount = Current.player().getGold();
currencyIcon = "[+Gold]";
currencyIcon = "[+Gold] "; //fix space since gold sprite is wider than a single glyph
Current.player().onGoldChange(() -> update(AdventurePlayer.current().getGold(),true));
}
label.setText(getLabelText(currencyAmount));

View File

@@ -254,7 +254,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
fetcher.fetchImage(reward.getCard().getImageKey(false), this);
if (reward.getCard().hasBackFace()) {
if (!ImageCache.imageKeyFileExists(reward.getCard().getImageKey(true))) {
fetcher.fetchImage(reward.getCard().getImageKey(true), this);
fetcher.fetchImage(reward.getCard().getImageKey(true), null);
}
}
}

View File

@@ -203,6 +203,13 @@ public class CardRenderer {
}
public static FImageComplex getCardArt(IPaperCard pc, boolean backFace) {
//missing papercard due to configchanges default to forgeart
if (pc == null)
return CardImageRenderer.forgeArt;
//token?
if (pc.getRules() == null)
return getCardArt(pc.getImageKey(backFace), false, false, false, false, false, false, false, false, true);
CardType type = pc.getRules().getType();
return getCardArt(pc.getImageKey(backFace), pc.getRules().getSplitType() == CardSplitType.Split,
type.isPlane() || type.isPhenomenon(), pc.getRules().getOracleText().contains("Aftermath"),
@@ -828,7 +835,10 @@ public class CardRenderer {
else
drawManaCost(g, card.getLeftSplitState().getManaCost(), x - padding, y, w + 2 * padding, h, manaSymbolSize);
} else {
drawManaCost(g, card.getCurrentState().getManaCost(), x - padding, y, w + 2 * padding, h, manaSymbolSize);
ManaCost leftManaCost = card.getLeftSplitState().getManaCost();
ManaCost rightManaCost = card.getRightSplitState().getManaCost();
drawManaCost(g, leftManaCost, x - padding, y-(manaSymbolSize/1.5f), w + 2 * padding, h, manaSymbolSize);
drawManaCost(g, rightManaCost, x - padding, y+(manaSymbolSize/1.5f), w + 2 * padding, h, manaSymbolSize);
}
}
} else {

View File

@@ -242,7 +242,7 @@ public class TransitionScreen extends FContainer {
run[0] = true;
FThreads.invokeInEdtNowOrLater(runnable);
}
}, 2.5f);
}, 2f);
} else {
if (run[0])
return;

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 556 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 654 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 502 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 689 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@@ -1,8 +1,7 @@
Name:Cursed Treasure
ManaCost:no cost
Types:Artifact
S:Mode$ Continuous | Description$ Provided by Cursed Treasure (Equipped Item - Right)
StackDescription$ Create a Treasure token. You lose 2 life. | SpellDescription$ Create a Treasure token. You lose 2 life.
A:AB$ Token | Cost$ PayShards<1> Sac<1/CARDNAME> | TokenScript$ c_a_treasure_sac | SubAbility$ DBLoseLife2 | SpellDescription$ Create a Treasure token.
SVar:DBLoseLife2:DB$ LoseLife | LifeAmount$ 2 | Defined$ You
Oracle: Provided by Cursed Treasure. Pay {M}, sacrifice Cursed Treasure: Create a Treasure token. You lose 2 life.
A:AB$ Token | Cost$ PayShards<1> | ActivationZone$ Command | TokenScript$ c_a_treasure_sac | SubAbility$ DBLoseLife | ActivationLimit$ 1 | SpellDescription$ Create a Treasure token. You lose 2 life, Exile Cursed Treasure.
SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ 2 | Defined$ You | SubAbility$ Eject
SVar:Eject:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
Oracle:{M}: Create a Treasure token. You lose 2 life, Exile Cursed Treasure.

View File

@@ -1,6 +1,7 @@
Name:Farmer's Tools
ManaCost:no cost
Types:Artifact
S:Mode$ Continuous | Description$ Provided by Farmer's Tools (Equipped Item - Left)
A:AB$ ChangeZone | Cost$ PayShards<2> Sac<1/CARDNAME> | ExileOnMoved$ Battlefield | Optional$ True | Origin$ Hand | Destination$ Battlefield | ChangeType$ Land | DefinedPlayer$ Player | ChangeNum$ 1 | StackDescription$ Each player may put a land card from their hand onto the battlefield.
Oracle: Provided by Farmer's Tools. Pay {M}{M}, sacrifice Farmer's Tools: Starting with you, each player may place a land card from their hand onto the battlefield.
A:AB$ RepeatEach | Cost$ PayShards<2> | ActivationZone$ Command | RepeatSubAbility$ DBChangeZone | RepeatPlayers$ Player | SubAbility$ Eject | StartingWithActivator$ True | SpellDescription$ Starting with you, each player may put a land card from their hand onto the battlefield. Exile Farmer's Tools.
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | ChangeType$ Land.RememberedPlayerCtrl | DefinedPlayer$ Player.IsRemembered | Chooser$ Player.IsRemembered | ChangeNum$ 1 | Hidden$ True
SVar:Eject:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
Oracle:{M}{M}: Starting with you, each player may put a land card from their hand onto the battlefield. Exile Farmer's Tools.

View File

@@ -0,0 +1,12 @@
Name:Garruk's Boss Effect Phase One
ManaCost:no cost
Types:Enchantment
S:Mode$ ReduceCost | ValidCard$ Beast,Garruk | EffectZone$ Command | Type$ Spell | Activator$ You | Amount$ 1 | Description$ Beast and Garruk spells you cast cost {1} less.
T:Mode$ SpellCast | ValidCard$ Card.nonCreature | ValidActivatingPlayer$ Opponent | Execute$ TrigPutCounter | TriggerZones$ Command | TriggerDescription$ Whenever an opponent casts a noncreature spell, put an prey counter on CARDNAME.
SVar:TrigPutCounter:DB$ PutCounter | CounterType$ Prey
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | IsPresent$ Card.Self+counters_GE5_PREY | PresentZone$ Command | Execute$ TrigConjure | TriggerDescription$ At the beginning of your upkeep, if there are 5 or more Prey counters on CARDNAME, conjure one of Garruk's beasts unto the battlefield under your control.
SVar:TrigConjure:DB$ MakeCard | Conjure$ True | Zone$ Battlefield | AtRandom$ True | Spellbook$ Garruk's Companion,Garruk's Gorehorn,Garruk's Harbinger,Garruk's Horde,Garruk's Packleader,Garruk's Warsteed,Briarpack Alpha,Mist Leopard,Predatory Wurm,Primal Huntbeast
R:Event$ GameLoss | ActiveZones$ Command | ValidPlayer$ You | ReplaceWith$ ExileSetLife | Description$ If Garruk would be defeated, instead exile CARDNAME and Garruk's life total becomes 40. Activate Phase 2
SVar:ExileSetLife:DB$ ChangeZone | Origin$ Command | Destination$ Exile | Defined$ Self | SubAbility$ DBSetLife
SVar:DBSetLife:DB$ SetLife | Defined$ You | LifeAmount$ 40
Oracle:Beast and Garruk spells you cast cost {1} less.\nWhenever an opponent casts a noncreature spell, put an prey counter on Garruk Boss Effect, Phase One.\nAt the beginning of your upkeep, if there are 5 or more Prey counters on Garuk Boss Effect, Phase One, conjure one of Garruk's beasts unto the battlefield under your control.\nIf Garruk would be defeated, instead exile Garruk Boss Effect, Phase One and Garruk's life total becomes 40. Activate Phase 2

View File

@@ -0,0 +1,16 @@
Name:Garruk's Boss Effect Phase Two
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
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.
SVar:DBEffect:DB$ Effect | RememberObjects$ Valid Creature.YouCtrl,ValidHand Creature.YouOwn,ValidGraveyard Creature.YouOwn,ValidLibrary Creature.YouOwn | StaticAbilities$ PerpetualP1P1 | Name$ Garruk's Rage Effect | Duration$ Permanent
SVar:PerpetualP1P1:Mode$ Continuous | Affected$ Card.IsRemembered | AddPower$ 1 | AddToughness$ 1 | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ At the beginning of your end step, creatures you control and creature cards in your hand, library, and graveyard perpetually get +1/+1.
SVar:Update:Mode$ ChangesZone | Origin$ Any | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBUpdate
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".
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".

View File

@@ -0,0 +1,9 @@
Name:Garruk's Mighty Axe
ManaCost:no cost
Types:Artifact Equipment
S:Mode$ ReduceCost | ValidCard$ Creature.powerGE4,Garruk | EffectZone$ Command | Type$ Spell | Activator$ You | Amount$ 1 | Description$ Garruk and green creature spells you cast with power 4 or greater cost {1} less to cast.
S:Mode$ Continuous | Affected$ Planeswalker.YouCtrl+Garruk | EffectZone$ Command | AddAbility$ PWWolf | Description$ Garruk planeswalkers you control have "[0]: Create a 2/2 black and green Wolf creature token with "When this creature dies, put a loyalty counter on each Garruk you control.""
SVar:PWWolf:AB$ Token | Cost$ AddCounter<0/LOYALTY> | Planeswalker$ True | TokenAmount$ 1 | TokenScript$ bg_2_2_wolf_garruk | TokenOwner$ You | SpellDescription$ Create a 2/2 black and green Wolf creature token with "When this creature dies, put a loyalty counter on each Garruk you control."
A:AB$ MakeCard | Cost$ G G PayShards<2> | Conjure$ True | ActivationLimit$ 1 | Zone$ Battlefield | ActivationZone$ Command | AtRandom$ True | SubAbility$ Eject | Spellbook$ Garruk's Companion,Garruk's Gorehorn,Garruk's Harbinger,Garruk's Horde,Garruk's Packleader,Garruk's Warsteed,Briarpack Alpha,Mist Leopard,Predatory Wurm,Primal Huntbeast | SpellDescription$ Conjure one of Garruk's Beast unto the battlefield unto your control. Activate this ability only once each game. Exile CARDNAME.
SVar:Eject:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
Oracle:Garruk and green creature spells you cast with power 4 or greater cost {1} less to cast.\nGarruk planeswalkers you control have "[0]: Create a 2/2 black and green Wolf creature token with "When this creature dies, put a loyalty counter on each Garruk you control.""\n{M}{M},{G}{G}:Conjure one of Garruk's Beast unto the battlefield unto your control. Activate this ability only once each game. Exile Garruk's Mighty Axe

View File

@@ -1,10 +1,7 @@
Name:Hill Giant Club
ManaCost:no cost
Types:Artifact
S:Mode$ Continuous | Description$ Provided by Hill Giant Club (Equipped Item - Right)
A:AB$ Effect | Cost$ PayShards<2> Sac<1/CARDNAME> | ValidTgts$ Creature | TgtPrompt$ Select target creature | ExileOnMoved$ Battlefield | StaticAbilities$ UnblockableLE2 | RememberObjects$ Targeted | StackDescription$ {c:Targeted} can't be blocked by creatures with power 2 or less this turn. | SpellDescription$ Targe creature can't be blocked by creatures with power 2 or less this turn.
A:AB$ Effect | Cost$ PayShards<2> | ActivationZone$ Command | ActivationLimit$ 1 | SubAbility$ Eject | ValidTgts$ Creature | StaticAbilities$ UnblockableLE2 | RememberObjects$ Targeted | SpellDescription$ Target creature can't be blocked by creatures with power 2 or less this turn. Exile Hill Giant Club
SVar:UnblockableLE2:Mode$ CantBlockBy | ValidAttacker$ Card.IsRemembered | ValidBlocker$ Creature.powerLE2 | Description$ {c:Targeted} can't be blocked by creatures with power 2 or less this turn.
Oracle: Provided by Hill Giant Club. Pay {M}{M}, sacrifice Hill Giant Club: Target creature can't be blocked by creatures with power 2 or less this turn.
SVar:Eject:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
Oracle:{M}{M}: Target creature can't be blocked by creatures with power 2 or less this turn. Exile Hill Giant Club

View File

@@ -2,7 +2,7 @@ Name:Jace Boss Effect
ManaCost:no cost
Colors:Blue
Types:Enchantment
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigChoose | TriggerDescription$ At the beginning of your end step, conjure a duplicate of a random creature card from your opponent's library unto the battlefield under your control. The duplicate perpetually becomes a blue Illusion creature with base power and toughness 2/2 and has "When this creature becomes the target of a spell or ability, sacrifice it."
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigChoose | TriggerDescription$ At the beginning of your end step, conjure a duplicate of a random creature card from your opponent's library unto the battlefield under your control. The duplicate perpetually becomes a blue Illusion creature with base power and toughness 2/2 and has "When this creature becomes the target of a spell or ability, sacrifice it."
SVar:TrigChoose:DB$ ChooseCard | Choices$ Creature.OppCtrl | ChoiceZone$ Library | AtRandom$ True | SubAbility$ DBConjure
SVar:DBConjure:DB$ MakeCard | Conjure$ True | DefinedName$ ChosenCard | Zone$ Battlefield | RememberMade$ True | SubAbility$ DBClearChosen
SVar:DBClearChosen:DB$ Cleanup | ClearChosenCard$ True | SubAbility$ DBEffect

View File

@@ -2,9 +2,12 @@ Name:Jace's Signature Hoodie
ManaCost:no cost
Colors:Blue
Types:Enchantment
A:AB$ ChooseCard | Cost$ PayShards<2> Exile<1/CARDNAME> | Choices$ Creature.OppCtrl | ChoiceZone$ Library | AtRandom$ True | SubAbility$ DBConjure | SpellDescription$ Conjure a duplicate of a random creature card from your opponent's library unto the battlefield under your control. The duplicate perpetually becomes a blue Illusion creature with base power and toughness 2/2.
T:Mode$ Drawn | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigMill | TriggerDescription$ Whenever you draw a card, each opponent mills a card.
SVar:TrigMill:DB$ Mill | Defined$ Opponent | NumCards$ 1
A:AB$ ChooseCard | Cost$ PayShards<2> | ActivationZone$ Command | ActiviationChoices$ Creature.OppCtrl | Choices$ Creature.OppOwn | ChoiceZone$ Library | AtRandom$ True | SubAbility$ DBConjure | SpellDescription$ Conjure a duplicate of a random creature card from your opponent's library unto the battlefield under your control. The duplicate perpetually becomes a blue Illusion creature with base power and toughness 2/2. Exile Jace's Signature Hoodie.
SVar:DBConjure:DB$ MakeCard | Conjure$ True | DefinedName$ ChosenCard | Zone$ Battlefield | RememberMade$ True | SubAbility$ DBClearChosen
SVar:DBClearChosen:DB$ Cleanup | ClearChosenCard$ True | SubAbility$ DBEffect
SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ PerpetualAbility | Duration$ Permanent | Name$ Jace's Signature Hoodie's Perpetual Effect
SVar:PerpetualAbility:Mode$ Continuous | Affected$ Card.IsRemembered | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | SetPower$ 2 | SetToughness$ 2 | RemoveCardTypes$ True | SetColor$ Blue | AddType$ Creature & Illusion | Description$ That duplicate perpetually has base power and toughness 2/2 and becomes an Illusion creature.
Oracle:Provided by Jace's Signature Hoodie\n{M}{M}, Exile Jace's Signature Hoodie: Conjure a duplicate of a random creature card from your opponent's library unto the battlefield under your control. The duplicate perpetually becomes a blue Illusion creature with base power and toughness 2/2.
SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ PerpetualAbility | Duration$ Permanent | Name$ Jace's Signature Hoodie's Perpetual Effect | SubAbility$ Eject
SVar:Eject:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
SVar:PerpetualAbility:Mode$ Continuous | Affected$ Card.IsRemembered | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | SetPower$ 2 | SetToughness$ 2 | RemoveCardTypes$ True | SetColor$ Blue | AddType$ Creature & Illusion | Description$ The duplicate perpetually becomes a blue Illusion creature with base power and toughness 2/2
Oracle:Whenever you draw a card, each opponent mills a card.\n{M}{M}: Conjure a duplicate of a random creature card from your opponent's library unto the battlefield under your control. The duplicate perpetually becomes a blue Illusion creature with base power and toughness 2/2. Exile Jace's Signature Hoodie

View File

@@ -0,0 +1,7 @@
Name:Kiora's Bident
ManaCost:no cost
Types:Artifact Equipment
S:Mode$ ReduceCost | EffectZone$ Command | ValidCard$ Crab.YouCtrl,Kraken.YouCtrl,Serpent.YouCtrl,Leviathan.YouCtrl,Octopus.YouCtrl | Type$ Spell | Activator$ You | Amount$ 1 | Description$ Kraken, Leviathan, Octopus, Crab and Serpent spells you cast cost {1} less.
A:AB$ MakeCard | Cost$ U G PayShards<2> | Conjure$ True | ActivationLimit$ 1 | Zone$ Hand | ActivationZone$ Command | AtRandom$ True | SubAbility$ Eject | Spellbook$ Kiora; Behemoth Beckoner,Kiora;Master of the Depths,Kiora; the Crashing Wave,Kiora; the Tide's Fury | SpellDescription$ Conjure a random Kiora planeswalker card into your hand. Exile Kiora's Bident.
SVar:Eject:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
Oracle:Kraken, Leviathan, Octopus, Crab and Serpent spells you cast cost {1} less.\n {M}{M}, {U}{G}:Conjure a random Kiora planeswalker card into your hand. Exile Kiora's Bident

View File

@@ -0,0 +1,7 @@
Name:Nahiri's Armory
ManaCost:no cost
Types:Artifact
S:Mode$ ReduceCost | ValidCard$ Card | ValidSpell$ Activated.Equip | Activator$ You | Amount$ 1 | EffectZone$ Command | Description$ Equip costs you pay cost {1} less.
T:Mode$ AttackersDeclared | ValidAttackers$ Creature.modified+YouCtrl | TriggerZones$ Command | Execute$ TrigConjure | TriggerDescription$ Whenever a modified creature you control attacks, you may pay {M}{M}, if you do conjure a random card from Nahiri's Armory's Spellbook into your hand.
SVar:TrigConjure:AB$ MakeCard | Cost$ PayShards<2> | Conjure$ True | AtRandom$ True | Zone$ Hand | Spellbook$ Stoneforge Mystic,Danitha; Benalia's Hope,Ardenn; Intrepid Archaeologist,Open the Armory,Stone Haven Outfitter,Argentum Armor,Sword of the Animist,Masterwork of Ingenuity,Kaldra Compleat,Armored Skyhunter,Lion Sash,Relic Seeker,Esper Sentinel,Forgeborn Phoenix,Foundry Beetle,Inchblade Companion,Komainu Battle Armor,Luxior; Giada's Gift,Mace of Disruption,Nettlecyst,Shadowspear,Seraphic Greatsword,Soulstealer Axe,Sword of Body and Mind,Sword of Fire and Ice,Junkyard Scrapper,Soulstealer AxeSword of Feast and Famine,Expedition Supplier,Foundry Beetle,Armory Automaton,Bladegraft Aspirant,Dancing Sword,Jor Kadeen; First Goldwarden,Akiri; Fearless Voyager,Acclaimed Contender,Embercleave,Puresteel Paladin,Champion of the Flame,Tiana; Ship's Caretaker,Reyav; Master Smith,Sigarda's Aid,Armored Skyhunter,Bruenor Battlehammer,Halvar; God of Battle,Wyleth; Soul of Steel,Koll; the Forgemaster,Valduk; Keeper of the Flame,Fervent Champion,Cloudsteel Kirin,Leonin Shikari,Balan; Wandering Knight,Kor Duelist,Leonin Abunas,Zamriel; Seraph of Steel,Auriok Steelshaper
Oracle:Equip costs you pay cost {1} less.\nWhenever a modified creature you control attacks, you may pay {M}{M}, if you do conjure a random card from Nahiri's Armory's Spellbook into your hand.

View File

@@ -0,0 +1,10 @@
Name:Nahiri Boss Effect
ManaCost:no cost
Types:Enchantment
S:Mode$ ReduceCost | ValidCard$ Card | ValidSpell$ Activated.Equip | Activator$ You | Amount$ 1 | EffectZone$ Command | Description$ Equip costs you pay cost {1} less.
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | Secondary$ True | Execute $ TrigConjure | TriggerDescription$ At the beginning of your upkeep or when an equipped creature you control attacks, conjure a card from Nahiri's Spellbook into your hand.
T:Mode$ Attacks | ValidCard$ Creature.YouCtrl+equipped | TriggerZones$ Command | Execute$ TrigConjure | TriggerDescription$ At the beginning of your upkeep or when an equipped creature you control attacks, conjure a card from Nahiri's Spellbook into your hand.
SVar:TrigConjure:DB$ MakeCard | Zone$ Hand | Conjure$ True | AtRandom$ True | Spellbook$ Stoneforge Mystic,Danitha; Benalia's Hope,Ardenn, Intrepid Archaeologist,Open the Armory,Stone Haven Outfitter,Argentum Armor,Sword of the Animist,Masterwork of Ingenuity,Kaldra Compleat,Armored Skyhunter,Lion Sash,Relic Seeker,Esper Sentinel,Forgeborn Phoenix,Foundry Beetle,Inchblade Companion,Komainu Battle Armor,Luxior;Giada's Gift,Mace of Disruption,Nettlecyst,Shadowspear,Seraphic Greatsword,Soulstealer Axe,Sword of Body and Mind,Sword of Fire and Ice,Junkyard Scrapper,Soulstealer Axe,Sword of Feast and Famine,Expedition Supplier,Foundry Beetle,Armory Automaton,Bladegraft Aspirant,Dancing Sword,Jor Kadeen; First Goldwarden,Akiri; Fearless Voyager,Acclaimed Contender,Embercleave,Puresteel Paladin,Champion of the Flame,Tiana; Ship's Caretaker,Reyav; Master Smith,Sigarda's Aid,Armored Skyhunter,Bruenor Battlehammer,Halvar; God of Battle,Wyleth; Soul of Steel,Koll; the Forgemaster,Valduk; Keeper of the Flame,Fervent Champion,Cloudsteel Kirin,Leonin Shikari,Balan, Wandering Knight,Kor Duelist,Leonin Abunas,Zamriel, Seraph of Steel,Auriok Steelshaper
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigToken | TriggerDescription$ At the beginning of your end step, create a 1/1 white Kor Soldier creature token
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_kor_soldier
Oracle:Equip costs you pay cost {1} less.\nAt the beginning of your upkeep or whenever an equipped creature you control attacks, conjure a card from Nahiri's Spellbook into your hand\nAt the beginning of your end step, create a 1/1 white Kor Soldier creature token.

View File

@@ -1,7 +1,7 @@
Name:Piper's Charm
ManaCost:no cost
Types:Artifact
S:Mode$ Continuous | Description$ Provided by Piper's Charm (Equipped Item - Neck)
A:AB$ Effect | Cost$ PayShards<3> Sac<1/CARDNAME> | ValidTgts$ Creature | ExileOnMoved$ Battlefield | StaticAbilities$ MustBlock | RememberObjects$ Targeted | StackDescription$ {c:Targeted} blocks this turn if able. | SpellDescription$ Target creature blocks this turn if able.
A:AB$ Effect | Cost$ PayShards<3> | ActivationZone$ Command | SubAbility$ Eject | ValidTgts$ Creature | StaticAbilities$ MustBlock | RememberObjects$ Targeted | StackDescription$ {c:Targeted} blocks this turn if able. | SpellDescription$ Target creature blocks this turn if able. Exile CARDNAME.
SVar:MustBlock:Mode$ MustBlock | ValidCreature$ Card.IsRemembered | Description$ This creature blocks this turn if able.
Oracle: Provided by Piper's Charm. Pay {M}{M}{M}, sacrifice Piper's Charm: Target creature blocks this turn if able.
SVar:Eject:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
Oracle:{M}{M}{M}: Target creature blocks this turn if able. Exile Piper's Charm

View File

@@ -1,6 +1,6 @@
Name:Sleep Wand
ManaCost:no cost
Types:Artifact
S:Mode$ Continuous | Description$ Provided by Sleep Wand (Equipped Item - Left)
A:AB$ PutCounter | Cost$ PayShards<2> Sac<1/CARDNAME> | ValidTgts$ Creature | ExileOnMoved$ Battlefield ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ Stun | CounterNum$ 1 | StackDescription$ Put a stun counter on target creature. (If a permanent with a stun counter would become untapped, remove one from it instead.)
Oracle: Provided by Sleep Wand. Pay {M}, sacrifice Sleep Wand: Put a stun counter on target creature.
A:AB$ PutCounter | Cost$ PayShards<2> | ActivationZone$ Command | ActivationLimit$ 1 | SubAbility$ Eject | ValidTgts$ Creature | CounterType$ Stun | CounterNum$ 1 | SpellDescription$ Put a stun counter on target creature. (If a permanent with a stun counter would become untapped, remove one from it instead.). Exile CARDNAME
SVar:Eject:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
Oracle:{M}:Put a stun counter on target creature. Exile Sleep Wand

View File

@@ -2,10 +2,10 @@ Name:Slime Boss Effect
ManaCost:no cost
Colors:black,green
Types:Enchantment
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPut | TriggerDescription$ At the beginning of your upkeep, put a slime counter on CARDNAME, then each opponent conjures X cards named Blasted Landscape into their library, where X is the amount of slime counters on CARDNAME.
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigPut | TriggerDescription$ At the beginning of your upkeep, put a slime counter on CARDNAME, then each opponent conjures X cards named Blasted Landscape into their library, where X is the amount of slime counters on CARDNAME.
SVar:TrigPut:DB$ PutCounter | Defined$ Self | CounterType$ SLIME | CounterNum$ 1 | SubAbility$ DBGunk
SVar:DBGunk:DB$ MakeCard | Defined$ Opponent | Name$ Blasted Landscape | Zone$ Library | Amount$ X | Conjure$ True
T:Mode$ Cycled | ValidCard$ Card | Execute$ TrigGainLife | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player cycles a card, you gain 2 life.
T:Mode$ Cycled | ValidCard$ Card | Execute$ TrigGainLife | TriggerZones$ Command | TriggerDescription$ Whenever a player cycles a card, you gain 2 life.
SVar:TrigGainLife:DB$ GainLife | LifeAmount$ 2
SVar:X:Count$CardCounters.SLIME
Oracle:At the beginning of your upkeep, put a slime counter on Slime Boss Effect, then each opponent conjures X cards named Blasted Landscape into their library, where X is the amount of slime counters on Slime Boss Effect.\nWhenever a player cycles a card, you gain 2 life.

View File

@@ -0,0 +1,11 @@
Name:Slimefoot's Boss Effect
ManaCost:no cost
Colors:black,green
Types:Enchantment
S:Mode$ Continuous | Affected$ Forest,Saproling | SetPower$ 1 | SetToughness$ 1 | EffectZone$ Command | AddType$ Land & Creature & Forest & Saproling | SetColor$ Green | Description$ All Forests and all Saprolings are 1/1 green Saproling creatures and Forest lands in addition to their other types. (They're affected by summoning sickness.)
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature | TriggerZones$ Command | Execute$ TrigToken | TriggerDescription$ Whenever a creature dies, that creature's controller creates a 1/1 green Saproling creature token.
SVar:TrigToken:DB$ Token | TokenOwner$ TriggeredCardController | TokenAmount$ 1 | TokenScript$ g_1_1_saproling
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Saproling | TriggerZones$ Command | Execute$ TrigDealDamage | TriggerDescription$ Whenever a Saproling dies, Slimefoot deals 1 damage to each opponent and you gain 1 life.
SVar:TrigDealDamage:DB$ DamageAll | ValidPlayers$ Player.Opponent | NumDmg$ 1 | SubAbility$ DBGainLife
SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1
Oracle:Whenever a Saproling dies, Slimefoot deals 1 damage to each opponent and gains 1 life.\nAll Forests and all Saprolings are 1/1 green Saproling creatures and Forest lands in addition to their other types. (Theyre affected by summoning sickness.)\nWhenever a creature dies, that creature's controller creates a 1/1 green Saproling creature token.\n

View File

@@ -0,0 +1,8 @@
Name:Slimefoot's Slimy Staff
ManaCost:no cost
Colors:black,green
Types:Artifact Equipment
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigPutCounter | TriggerDescription$ At the beginning of your end step, put a spore counter on each fungus you control.
SVar:TrigPutCounter:DB$ PutCounterAll | ValidCards$ Fungus.YouCtrl | CounterType$ SPORE | CounterNum$ 1
A:AB$ MakeCard | Cost$ G PayShards<2> | Name$ Bayou | ActivationZone$ Command | Zone$ Hand | IsPresent$ Land.YouOwn | PresentZone$ Hand | PresentCompare$ EQ0 | GameActivationLimit$ 1 | SpellDescription$ Conjure a card named Bayou into your hand. Activate only if there are no land cards in your hand and only once each game.
Oracle:At the beginning of your end step, put a spore counter on each fungus you control.\n{M}{M},{G}:Conjure a card named Bayou into your hand. Activate only if there are no land cards in your hand and only once each game.

View File

@@ -0,0 +1,8 @@
Name:Teferi's Staff
ManaCost:no cost
Types:Artifact Equipment
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigUntap | TriggerDescription$ At the beginning of your end step, untap target artifact or land you control.
SVar:TrigUntap:DB$ Untap | ValidTgts$ Artifact.YouCtrl,Land.YouCtrl | TgtPrompt$ Select target artifact or land you control
A:AB$ Phases | Cost$ U W PayShards<2> | ValidTgts$ Permanent | SubAbility$ Eject | ActivationZone$ Command | SpellDescription$ Target permanent phases out. (Treat it and anything attached to it as though they don't exist until its controllers's next turn.)
SVar:Eject:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
Oracle:At the beginning of your end step, untap target artifact or land you control.\n{M}{M}, {U{W}: Target permanent phases out. (Treat it and anything attached to it as though they don't exist until its controllers's next turn.). Exile Teferi's Staff.

View File

@@ -0,0 +1,51 @@
[metadata]
Name=armored_knight
[Avatar]
[Main]
1 Acclaimed Contender|ELD|1
1 Adeline, Resplendent Cathar|MID|1
1 Armored Skyhunter|CMR|1
1 Basilisk Collar|CLB|1
1 Benalish Marshal|DOM|1
4 Clifftop Retreat|DOM|1
1 Colossus Hammer|GN3|1
1 Danitha Capashen, Paragon|CMR|1
1 Embercleave|ELD|1
3 Fervent Champion|ELD|1
1 Furycalm Snarl|ONC|1
1 Glimmer Lens|ONC|1
1 Hero of Bladehold|MBS|1
1 History of Benalia|DOM|1
1 Inspiring Veteran|ELD|1
1 Kemba's Banner|ONC|1
1 Kinsbaile Cavalier|DDG|1
1 Knight Exemplar|SLD|2
1 Loxodon Warhammer|CM2|1
1 Mace of the Valiant|ONC|1
1 Maul of the Skyclaves|ONC|1
4 Mountain|BRO|3
3 Novice Knight|M19|1
7 Plains|BRO|3
4 Plateau|OLGC|1
3 Puresteel Paladin|2XM|1
4 Sacred Foundry|GRN|1
1 Shadowspear|THB|1
1 Shining Armor|MB1|1
1 Sword of Vengeance|GN3|1
1 The Circle of Loyalty|ELD|1
1 The Reaver Cleaver|DMC|1
1 Thran Power Suit|BRO|1
1 Trailblazer's Boots|ONC|1
1 Valiant Endeavor|AFC|1
1 Varchild, Betrayer of Kjeldor|C18|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,12 @@
{
"name":"Crab",
"template":
{
"count":60,
"colors":["Blue"],
"tribe":"Crab",
"tribeCards":1.0,
"tribeSynergyCards":0.2,
"rares":0.4
}
}

View File

@@ -0,0 +1,42 @@
[metadata]
Name=disciple_of_teferi
[Avatar]
[Main]
2 Arcane Denial|CMA|1
2 Brainstorm|SLD|1
1 Denry Klin, Editor in Chief|NCC|1
1 Elsha of the Infinite|2X2|1
4 Flooded Strand|KTK|1
1 Grand Arbiter Augustin IV|2X2|1
1 Ishai, Ojutai Dragonspeaker|CM2|1
2 Island|DMU|4
2 Ivory Tower|VMA|1
2 Ledger Shredder|SNC|1
3 Lightning Bolt|CLB|1
1 Loran of the Third Path|BRO|1
1 Magnanimous Magistrate|J22|1
4 Monastery Mentor|FRF|1
1 Mountain|DMU|4
1 Oji, the Exquisite Blade|CLB|1
3 Plains|DMU|4
4 Plateau|30A|1
4 Raugrin Triome|IKO|1
2 Revitalize|M21|1
2 Rhox Faithmender|JMP|1
4 Serra Ascendant|IMA|1
1 Shu Yun, the Silent Tempest|FRF|1
3 Swords to Plowshares|DMR|1
3 The Archimandrite|BRC|1
4 Tundra|30A|1
1 Volcanic Island|30A|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,12 @@
{
"name":"Fox",
"template":
{
"count":60,
"colors":["White"],
"tribe":"Fox",
"tribeCards":0.5,
"tribeSynergyCards":0.2,
"rares":0.2
}
}

View File

@@ -3,12 +3,13 @@ Name=illusion
[Avatar]
[Main]
3 Chart a Course|XLN|1
1 Ephemeron|VMA|1
23 Island|KLD|3
2 Krovikan Mist|CSP|1
4 Krovikan Mist|CSP|1
2 Labyrinth Guardian|MB1|1
4 Lord of the Unreal|M12|1
4 Minn, Wily Illusionist|AFC|1
2 Minn, Wily Illusionist|AFC|1
1 Mordenkainen|AFR|1
2 Oneirophage|MH1|1
4 Phantasmal Bear|A25|1
@@ -18,7 +19,6 @@ Name=illusion
1 Phantom Beast|M11|1
2 Phantom Steed|AFC|1
2 Phantom Warrior|DPA|1
3 Summoner's Bane|DDM|1
1 Toothy, Imaginary Friend|BBD|1
[Sideboard]

View File

@@ -1,30 +1,37 @@
[metadata]
Name=kobold
Name=Kobolds Mid
[Avatar]
[Main]
4 Badlands|VMA|1
1 Ancient Brass Dragon|CLB|1
1 Bladewing, Deathless Tyrant|DMC|1
2 Darigaaz's Whelp|YDMU|1
2 Draconic Destiny|BRO|1
4 Dragonskull Summit|E01|1
1 Goldspan Dragon|PLIST|1
2 Haunted Ridge|MID|1
2 Kobold Drill Sergeant|ME3|1
4 Dragonskull Summit|C16|1
2 Geothermal Bog|DMU|1
4 Haunted Ridge|MID|1
2 Heraldic Banner|ELD|1
1 Kher Keep|TSR|1
2 Kobold Overlord|ME3|1
2 Kobold Taskmaster|TSB|1
1 Kobold Warcaller|HBG|1
4 Kobolds of Kher Keep|ME3|1
2 Kolaghan's Command|2X2|1
4 Lightning Bolt|A25|1
4 Minion of the Mighty|AFR|1
2 Minion of the Mighty|AFR|1
5 Mountain|DMU|4
3 Nogi, Draco-Zealot|GN3|1
2 Pact of the Serpent|KHC|1
2 Rograkh, Son of Rohgahh|CMR|1
3 Rohgahh, Kher Keep Overlord|DMC|1
1 Nogi, Draco-Zealot|GN3|1
2 Rakdos Charm|AFC|1
1 Rograkh, Son of Rohgahh|CMR|1
1 Rohgahh of Kher Keep|ME3|1
2 Rohgahh, Kher Keep Overlord|DMC|1
1 Rosnakht, Heir of Rohgahh|DMC|1
4 Sulfurous Springs|DMU|1
1 Shivan Dragon|DMR|1
2 Shock|DDN|1
2 Slumbering Dragon|M13|1
4 Smoldering Marsh|DMC|1
4 Swamp|DMU|4
1 Taunting Kobold|CLB|1
2 Wheel of Fortune|LEA|1
2 Terminate|DMC|1
1 Vanquisher's Banner|XLN|1
[Sideboard]
[Planes]

View File

@@ -0,0 +1,53 @@
[metadata]
Name=Kor Warrior
[Avatar]
[Main]
1 Akiri, Fearless Voyager|ZNR|1
1 Akiri, Line-Slinger|C16|1
2 Axgard Armory|KHM|1
1 Balduvian Berserker|DMU|1
1 Basilisk Collar|AFC|1
1 Bloodforged Battle-Axe|C17|1
1 Captain's Claws|OGW|1
4 Clifftop Retreat|DOM|1
1 Darksteel Plate|DDU|1
1 Embercleave|ELD|1
1 Empyrial Plate|C16|1
1 Fiendlash|AFC|1
4 Furycalm Snarl|STX|1
2 Kitesail Apprentice|GN3|1
2 Kitesail Scout|BFZ|1
1 Knight of Cliffhaven|DDP|1
1 Kor Blademaster|ZNR|1
1 Kor Celebrant|ZNR|1
2 Lone Missionary|MM3|1
1 Mountain|ZNR|1
1 Mountain|ZNR|3
1 Nomads' Assembly|C14|1
1 Plains|ZNR|1
3 Plains|ZNR|2
3 Plains|ZNR|3
1 Plains|ZNR|4
1 Priest of Possibility|YDMU|1
1 Retreat to Emeria|MB1|1
4 Sacred Foundry|SLD|1
1 Seraphic Greatsword|CMR|1
1 Shadowspear|THB|1
1 Sigarda's Aid|CMR|1
3 Skyclave Apparition|ZNR|1
1 Squad Commander|ZNR|1
2 Stone Haven Outfitter|OGW|1
2 Stoneforge Mystic|TD1|1
1 Sword of the Animist|AFC|1
2 Valiant Veteran|DMU|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,40 @@
[metadata]
Name=mammoth
[Avatar]
[Main]
2 Aggressive Mammoth|M20|1
2 Battle Mammoth|CLB|1
1 Bestial Menace|MIC|1
4 Call of the Herd|MM3|1
4 Canopy Vista|ONC|1
2 Cultivate|J22|1
3 Elephant Graveyard|ME4|1
1 Forest|30A|1
1 Forest|30A|2
1 Forest|30A|3
2 Generous Gift|MH1|1
4 Grasslands|DMC|1
4 Kazandu Mammoth|ZNR|1
2 Loxodon Line Breaker|M19|1
2 Lulu, Forgetful Hollyphant|HBG|1
3 Nature's Lore|CLB|1
2 Overrun|PCA|1
2 Plains|30A|4
4 Rampant Growth|NEC|1
4 Savannah|30A|1
1 Terastodon|CMR|1
2 Thorn Mammoth|ELD|1
2 Trained Armodon|TPR|1
1 Trumpeting Herd|J21|1
4 War Mammoth|30A|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,50 @@
[metadata]
Name=garruk
[Avatar]
[Main]
1 Apex Altisaur|C19|1
1 Argoth, Sanctum of Nature|BRO|1
1 Bramblecrush|ISD|1
1 Castle Garenbrig|ELD|1
1 Elder Gargaroth|M21|1
4 Elvish Mystic|KHC|1
19 Forest|J14|1
1 Garruk Wildspeaker|GVL|1
2 Garruk's Harbinger|M21|1
1 Garruk's Horde|M12|1
1 Garruk, Caller of Beasts|M14|1
1 Garruk, Primal Hunter|C21|1
1 Garruk, Unleashed|M21|1
1 Garruk, Wrath of the Wilds|YMID|1
1 Gate to Manorborn|HBG|1
1 Gemrazer|IKO|1
1 Gingerbread Cabin|ELD|1
1 Goreclaw, Terror of Qal Sisma|J21|1
1 Kogla, the Titan Ape|IKO|2
2 Krosan Warchief|C13|1
1 Nature's Chosen|ALL|1
4 Nature's Claim|MB1|1
4 Prey Upon|ISD|1
2 Primeval Titan|IMA|1
1 Rampaging Baloths|C14|1
1 Ravenous Gigantotherium|C20|1
2 Return to Nature|M21|1
1 Rhox|10E|1
1 Sawtusk Demolisher|C20|1
1 Spearbreaker Behemoth|ALA|1
1 Thorn Mammoth|ELD|1
1 Thragtusk|MM3|1
2 Wicked Wolf|ELD|1
1 Wild Endeavor|AFC|1
1 Yedora, Grave Gardener|C21|2
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -3,8 +3,9 @@ Name=jace_boss
[Avatar]
[Main]
2 Ancestral Recall|30A|1
1 Ancestral Recall|30A|1
1 Arcanis the Omnipotent|C17|1
2 Azorius Signet|NEC|1
1 Bruvac the Grandiloquent|PLIST|1
3 Counterspell|SLD|1
1 Evacuation|C16|1
@@ -21,6 +22,7 @@ Name=jace_boss
2 Jace's Triumph|WAR|1
1 Jace, Architect of Thought|RTR|1
1 Jace, Cunning Castaway|XLN|1
1 Jace, Ingenious Mind-Mage|XLN|1
1 Jace, Memory Adept|M14|1
1 Jace, Mirror Mage|ZNR|2
1 Jace, the Living Guildpact|M15|1
@@ -32,14 +34,11 @@ Name=jace_boss
1 Karakas|OLGC|1
1 Library of Alexandria|OVNT|1
1 Maze of Ith|OLGC|1
2 Mox Sapphire|VMA|1
1 Preston, the Vanisher|J22|1
1 River's Rebuke|GN2|1
4 Seachrome Coast|ONE|1
1 Sol Ring|PF19|1
1 Space Beleren|UNF|1
1 Strip Mine|VMA|1
2 Supreme Verdict|IMA|1
1 Supreme Verdict|IMA|1
1 Time Warp|E02|1
1 Timetwister|OVNT|4
4 Tundra|VMA|1

View File

@@ -0,0 +1,54 @@
[metadata]
Name=nahiri
[Avatar]
[Main]
2 Akiri, Fearless Voyager|ZNR|1
4 Arid Mesa|SLU|1
1 Basilisk Collar|CLB|1
1 Bladegraft Aspirant|ONE|1
4 Clifftop Retreat|DMR|1
1 Cloudsteel Kirin|NEO|1
1 Danitha Capashen, Paragon|J22|1
2 Disenchant|S00|1
1 Embercleave|ELD|1
2 Fervent Champion|ELD|1
2 Goblin Gaveleer|2XM|1
4 Inspiring Vantage|KLD|1
1 Kaldra Compleat|PLIST|1
1 Kemba, Kha Enduring|ONE|1
1 Kemba, Kha Regent|2XM|1
1 Lion Sash|NEO|1
1 Lizard Blades|NEO|1
1 Luxior, Giada's Gift|SNC|1
1 Mask of Memory|ONC|1
4 Mountain|BRO|3
2 Nahiri's Binding|ZNR|1
1 Nahiri, Heir of the Ancients|ZNR|1
1 Nahiri, Storm of Stone|WAR|1
1 Nahiri, the Harbinger|SOI|1
1 Nahiri, the Lithomancer|PLIST|1
1 Nahiri, the Unforgiving|ONE|1
4 Plains|BRO|3
4 Plateau|PRM|1
4 Puresteel Paladin|AFC|1
4 Sacred Foundry|GRN|1
1 Seraphic Greatsword|CMR|1
4 Sram, Senior Edificer|NEC|1
2 Stoneforge Mystic|2XM|1
1 Sword of Body and Mind|2XM|1
1 Sword of Body and Mind|MPS_KLD|1
1 Sword of Feast and Famine|PLIST|1
1 Sword of Hearth and Home|MH2|1
1 Sword of Sinew and Steel|MH1|1
3 Swords to Plowshares|DMR|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,46 @@
[metadata]
Name=teferi_boss
[Avatar]
[Main]
1 Back to Basics|UMA|1
1 Balance|30A|1
2 Disenchant|30A|1
3 Historian of Zhalfir|M21|1
8 Island|DMU|4
1 Niambi, Beloved Protector|YDMU|1
1 Niambi, Esteemed Speaker|M21|1
1 Oath of Teferi|DOM|1
4 Path to Exile|2X2|1
10 Plains|DMU|4
1 Propaganda|AFC|1
1 Teferi's Ageless Insight|M21|1
1 Teferi's Contingency|YDMU|1
1 Teferi's Drake|MIR|1
1 Teferi's Moat|TSB|1
1 Teferi's Protege|J22|1
3 Teferi's Sentinel|DOM|1
1 Teferi's Tutelage|M21|1
2 Teferi, Hero of Dominaria|PPRO|1
1 Teferi, Mage of Zhalfir|IMA|1
1 Teferi, Master of Time|M21|9
1 Teferi, Temporal Archmage|C14|1
1 Teferi, Temporal Pilgrim|BRO|1
1 Teferi, Time Raveler|WAR|1
1 Teferi, Who Slows the Sunset|MID|1
1 The Tabernacle at Pendrell Vale|OLGC|1
1 Time Warp|E02|1
2 Time Wipe|PWAR|1
4 Tundra|30A|1
1 Winter Orb|EMA|1
1 Zhalfirin Void|PDOM|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,12 @@
{
"name":"Ooze",
"template":
{
"count":60,
"colors":["Green","Blue","Black"],
"tribe":"Ooze",
"tribeCards":1.0,
"tribeSynergyCards":0.2,
"rares":0.6
}
}

View File

@@ -0,0 +1,41 @@
[metadata]
Name=squirrel
[Avatar]
[Main]
4 Bayou|30A|1
4 Chatter of the Squirrel|SLD|1
2 Chatterfang, Squirrel General|J21|1
2 Chitterspitter|J21|1
1 Deep Forest Hermit|MH1|1
1 Deranged Hermit|VMA|1
1 Drey Keeper|MH2|1
1 Earl of Squirrel|UST|1
3 Forest|MH2|1
2 Forest|MH2|2
2 Krosan Beast|SLD|1
1 Liege of the Hollows|WTH|1
4 Necroblossom Snarl|STX|1
1 Nut Collector|DMR|1
3 Ravenous Squirrel|J21|1
2 Scurrid Colony|STX|1
4 Squirrel Mob|MH2|1
3 Squirrel Sanctuary|MH2|1
4 Squirrel Sovereign|J21|1
1 Squirrel Wrangler|J21|1
1 Swamp|MH2|1
2 Swamp|MH2|2
4 Swarmyard|SLD|1
2 Toski, Bearer of Secrets|KHM|1
1 Verdant Command|MH2|1
4 Woodland Cemetery|DOM|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -0,0 +1,35 @@
[metadata]
Name=water_elemental
[Avatar]
[Main]
1 Aethersnipe|UMA|1
1 Air-Cult Elemental|AFR|1
4 Boomerang|10E|1
1 Boreal Elemental|M20|1
1 Brine Elemental|TSP|1
2 Cavalier of Gales|M20|1
3 Cloudkin Seer|MB1|1
4 Floodhound|J21|1
3 Glimmerbell|IKO|1
23 Island|BRO|4
1 Nimbus of the Isles|BBD|1
1 Plasma Elemental|5DN|1
2 Subtlety|MH2|1
1 Supreme Exemplar|MOR|1
4 Unsummon|M20|1
1 Void Stalker|M13|1
2 Water Elemental|30A|1
2 Water Servant|M14|1
2 Water Weird|HBG|1
1 Watercourser|MB1|1
[Sideboard]
[Planes]
[Schemes]
[Conspiracy]
[Dungeon]

View File

@@ -3,12 +3,12 @@
"height": 4300,
"width": 2
},
"activeFile": "map/jacehold.tmx",
"activeFile": "map/nahiri.tmx",
"automapping.whileDrawing": false,
"expandedProjectPaths": [
"tileset",
"obj",
"map/main_story",
"obj",
"tileset",
"map"
],
"file.lastUsedOpenFilter": "All Files (*)",
@@ -1553,7 +1553,7 @@
"scale": 1.5,
"selectedLayer": 0,
"viewCenter": {
"x": 240,
"x": 239.99999999999997,
"y": 136.33333333333334
}
},
@@ -1596,7 +1596,7 @@
"scale": 1.3517708333333331,
"selectedLayer": 0,
"viewCenter": {
"x": 240.4253679586962,
"x": 240.42536795869617,
"y": 136.48763196424449
}
},
@@ -1736,6 +1736,17 @@
"y": 239.75
}
},
"map/garruk.tmx": {
"expandedObjectLayers": [
4
],
"scale": 2.0504166666666666,
"selectedLayer": 3,
"viewCenter": {
"x": 271.6521032310506,
"y": 215.8097947571632
}
},
"map/graveyard.tmx": {
"expandedObjectLayers": [
4
@@ -1930,8 +1941,8 @@
"scale": 1.5,
"selectedLayer": 3,
"viewCenter": {
"x": 240,
"y": 135.99999999999994
"x": 239.99999999999997,
"y": 136.33333333333334
}
},
"map/grove_5.tmx": {
@@ -1993,9 +2004,9 @@
4
],
"scale": 2,
"selectedLayer": 0,
"selectedLayer": 4,
"viewCenter": {
"x": 265.5,
"x": 265,
"y": 123.25
}
},
@@ -2012,9 +2023,9 @@
4
],
"scale": 2.177083333333333,
"selectedLayer": 3,
"selectedLayer": 2,
"viewCenter": {
"x": 240.2296650717704,
"x": 239.77033492822972,
"y": 136.19138755980865
}
},
@@ -2022,7 +2033,7 @@
"scale": 1.2623540856031128,
"selectedLayer": 0,
"viewCenter": {
"x": 255.07898589812746,
"x": 255.07898589812743,
"y": 159.62240887724434
}
},
@@ -2030,7 +2041,7 @@
"scale": 1.3517708333333331,
"selectedLayer": 0,
"viewCenter": {
"x": 240.4253679586962,
"x": 240.42536795869617,
"y": 136.48763196424449
}
},
@@ -2038,7 +2049,7 @@
"scale": 1.3517708333333331,
"selectedLayer": 0,
"viewCenter": {
"x": 240.4253679586962,
"x": 240.42536795869617,
"y": 136.48763196424449
}
},
@@ -2580,6 +2591,17 @@
"y": 135.5
}
},
"map/nahiri.tmx": {
"expandedObjectLayers": [
4
],
"scale": 1.5333593749999999,
"selectedLayer": 3,
"viewCenter": {
"x": 324.77709278035366,
"y": 209.01818922912318
}
},
"map/nest_blue_1.tmx": {
"scale": 0.75,
"selectedLayer": 4,
@@ -2868,12 +2890,23 @@
11
],
"scale": 3,
"selectedLayer": 3,
"selectedLayer": 4,
"viewCenter": {
"x": 229,
"x": 296,
"y": 183.83333333333331
}
},
"map/slimefoot_boss.tmx": {
"expandedObjectLayers": [
4
],
"scale": 2.044479166666666,
"selectedLayer": 0,
"viewCenter": {
"x": 239.6698425638152,
"y": 136.22051255922963
}
},
"map/snowabbey_1.tmx": {
"scale": 1.6011458333333333,
"selectedLayer": 0,
@@ -2917,6 +2950,14 @@
"y": 320.5
}
},
"map/teferi.tmx": {
"scale": 3,
"selectedLayer": 1,
"viewCenter": {
"x": 240,
"y": 136.16666666666663
}
},
"map/tileset/buildings.tsx": {
"scaleInDock": 1
},
@@ -3060,23 +3101,28 @@
"map/kiora_island.tmx",
"map/kobold_mine.tmx",
"map/lavaforge_1.tmx",
"map/lavaforge_2.tmx"
"map/lavaforge_2.tmx",
"map/garruk.tmx",
"map/grove_4.tmx",
"map/slime_hive.tmx",
"map/slimefoot_boss.tmx",
"map/nahiri.tmx"
],
"project": "main.tiled-project",
"property.type": "string",
"recentFiles": [
"map/lavaforge_2.tmx",
"map/lavaforge_1.tmx",
"map/kobold_mine.tmx",
"map/kiora_island.tmx",
"map/fort_9.tmx",
"map/forest_town_generic.tmx",
"map/factory_3.tmx",
"map/factory_2.tmx",
"map/factory_1.tmx",
"map/fort_3.tmx",
"map/jacehold.tmx",
"map/fort_6.tmx",
"map/fort_5.tmx",
"map/fort_4.tmx",
"map/fort_5.tmx"
"map/fort_3.tmx",
"map/factory_1.tmx",
"map/factory_2.tmx",
"map/factory_3.tmx",
"map/forest_town_generic.tmx",
"map/fort_9.tmx",
"map/kiora_island.tmx",
"map/kobold_mine.tmx"
],
"resizeMap.removeObjects": true,
"textEdit.monospace": true

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.2" orientation="orthogonal" renderorder="right-down" width="34" height="27" tilewidth="16" tileheight="16" infinite="0" nextlayerid="11" nextobjectid="73">
<editorsettings>
<export target="wastetown..tmx" format="tmx"/>
</editorsettings>
<tileset firstgid="1" source="../tileset/main.tsx"/>
<tileset firstgid="10113" source="../tileset/buildings.tsx"/>
<layer id="10" name="Kopie van Background" width="34" height="27">
<data encoding="base64" compression="zlib">
eJz7ysbA8JWOeBsrA8N2VvraiW4/CIcA2focA+uOiewDZ/9gcgfIDQuYGBhuMQ+sGwYyPcDcMJB5YzC5AxkMhvAAYZsBTJ+jbiHsjoFOs8hu+TxI3DHQYTLqjlF3jLpj6LkD2S123IPDHaAwSeOE4IF0CyxuBos7BjpusLkDAFXcau0=
</data>
</layer>
<layer id="8" name="Background" width="34" height="27">
<data encoding="base64" compression="zlib">
eJxjYBgFo2DgwTZWCB4FowAEbrMh8GABgymNgtzxcKAdAQWDKUyoAdq4B4c7KAWDxR2jYBSMgqELJrAPtAsgYNQdQwcAAJf3DG4=
</data>
</layer>
<layer id="7" name="Background" width="34" height="27">
<data encoding="base64" compression="zlib">
eJzFljtOw0AQhkcgY1uxBA1H4FXRUSFOwRkoKFxSU2EeDdyAU8ABQkDpKGigCxwB0bOj7MiT8exLdiDSr2TXm51v/5mx3YwALo2ujK6NGjtuxPyN0c9afz1kAI9Zd36rAtg22jHardqxnN+r+sdHHZvf+0X3+tjs/2Q0MXqudB9w/mUAjrs8fj35UJdzcR9wnOV+uXxI5RhbhgljIQbUmRWPzccuhvsVgI/VNA8ppsbB4xcb7fdn4WbQ6mEIDjw/xuY6Lxf3OCn13pjC4vgNdIZp3uXg4nkgBhxLDl+PdmI6WDTOzPLx2NwPmRf+CcUKxfblivRVzOXqVdShrc/3BJaQwJFfZNLOIVmGEPUsieqR+xXjC1dfj+jsyMFZfJ7E1Gyf3BCLyw/O8q1ck57QWXz1iroYuTnqctEjznEAXU9mkTFlfG395nq3RnAd5+mTm9OI+zF5A6D7gGNcE8shc66pLtu4MjfcJ8ni4wjd33BfmQP5zHFJctzmfj9mPXs3Vq8wfO829t019X/L4khhSanTvxCxHA307h/jWSg3Wo+TUu5pIQ7XXjw3Lo5l+yE5/rtGNI5ff6f+Yg==
</data>
</layer>
<layer id="9" name="Tree" width="34" height="27">
<properties>
<property name="spriteLayer" type="bool" value="true"/>
</properties>
<data encoding="base64" compression="zlib">
eJydV8tOwlAQvUqkEFp/ohEwimsTv8adceHKuNUViCb0a/AHAJPuWbryF/oDdtJOejqd+6g3OSnFcufMOTPTaxobk5ZYTirkUXVNYz8uAp4hbM+M+arBi2K8K3Ho++uSw+MonIcPU+Ahly0GauHjsSux78FnK3RwxQjlMYubPU8HxvzG7TzlnvcnXT9cnEN50HpNuhrLGMzB5cfMwuOhrI0bT51yTM79p7yeRd0YkgP6oYF+8wn3vn6hxbERm6Ex2bDJQ6sJ6oNsqEPL1ceDvWEO2PesaRZ1eaDvDFtd5VE7lsblZVw9i3owd+YyHTfgnGkmuDzGXDXOad2nh1jP50r5zWKk13KI/pp2Lk8xz6cy76Np5qTGRerr8oU05f0XUaOlzSMEcSFMYT+skz56oIZ5FD4z2VfSZA/7SU18eqxF/b4lFY95/fdLJe5c3BOHXdzUE3tr08TlCy6bHt8WPY6iJsnL//JA9PWF5uER4tl6R85Oya0w7f6gJbUPqRFtb9RE5i2/w/MHL80Dmy+MVQ8e2nc4O1DbPnoweAu63g3C68M2/5FHqEfcW+s6jq9O5XmBefD5gj4/J34fbJ4xD9sMsemBszSD9zhzkn2983Cic05huppos4LvPyZNL90m7fe4jVth3DwOcRNbnpWxv/Be834GnLG3c0tuWp6sZSiPEOB7h/isPOclen5zXn2mGsHzsqu+5VXqxF6zHq7/o3Atlb6RcfoCeWCdyp7i+iqAi61WCX9fbgUK
</data>
</layer>
<objectgroup id="4" name="Objects">
<object id="38" template="../obj/entry_up.tx" x="209" y="431.5">
<properties>
<property name="teleport" value=""/>
</properties>
</object>
<object id="48" template="../obj/treasure.tx" x="522.915" y="383.179"/>
<object id="54" template="../obj/enemy.tx" x="104.779" y="294.529">
<properties>
<property name="enemy" value="Viper"/>
</properties>
</object>
<object id="55" template="../obj/enemy.tx" x="253.388" y="115.167">
<properties>
<property name="effect">{ &quot;startBattleWithCardInCommandZone&quot;: [ &quot;Garruk's Boss Effect Phase One&quot;,&quot;Garruk's Boss Effect Phase Two&quot;]
}</property>
<property name="enemy" value="Garruk"/>
</properties>
</object>
<object id="56" template="../obj/enemy.tx" x="310.809" y="193.554">
<properties>
<property name="enemy" value="Beastmaster"/>
</properties>
</object>
<object id="62" template="../obj/enemy.tx" x="140.389" y="364.701">
<properties>
<property name="enemy" value="Squirrel"/>
</properties>
</object>
<object id="63" template="../obj/enemy.tx" x="519.21" y="217.808">
<properties>
<property name="enemy" value="Treefolk"/>
</properties>
</object>
<object id="64" template="../obj/enemy.tx" x="527.989" y="340.222">
<properties>
<property name="enemy" value="Green Beast"/>
</properties>
</object>
<object id="65" template="../obj/enemy.tx" x="387.042" y="397.283">
<properties>
<property name="enemy" value="Fox"/>
</properties>
</object>
<object id="66" template="../obj/enemy.tx" x="69.0575" y="142.701">
<properties>
<property name="enemy" value="Bear"/>
</properties>
</object>
<object id="67" template="../obj/enemy.tx" x="515.308" y="140.263">
<properties>
<property name="enemy" value="Treefolk"/>
</properties>
</object>
<object id="68" template="../obj/treasure.tx" x="222.685" y="60.7665"/>
<object id="70" template="../obj/gold.tx" x="68.0821" y="226.099"/>
<object id="71" template="../obj/gold.tx" x="401.185" y="431.423"/>
<object id="72" template="../obj/gold.tx" x="63.6927" y="29.0656"/>
</objectgroup>
</map>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.2" orientation="orthogonal" renderorder="right-down" width="39" height="17" tilewidth="16" tileheight="16" infinite="0" nextlayerid="9" nextobjectid="70">
<map version="1.9" tiledversion="1.9.2" orientation="orthogonal" renderorder="right-down" width="39" height="17" tilewidth="16" tileheight="16" infinite="0" nextlayerid="9" nextobjectid="74">
<editorsettings>
<export target="wastetown..tmx" format="tmx"/>
</editorsettings>
@@ -7,17 +7,17 @@
<tileset firstgid="10113" source="../tileset/buildings.tsx"/>
<layer id="6" name="Collision" width="39" height="17">
<data encoding="base64" compression="zlib">
eJxjYEAFX9kgGATyOGmDGRkgmFSwjZU0DPIHqXp6OBEYBpDF0OXQw45WgJEB1W4QvYRp8LkN2X3Euo0c+wiB90gYl/3ocTwQQIWNcBgNlNuQ7ad2HFILDDZ3IadNWrmL3PITBogJM/RykV5uIwYYczAwmACxKRCbcdDYsgEA9AhDUgEjGiYWGLIiMAzA2hi0rJMoAQPlLlx15mAuf/EBAMRoTfA=
eJzFlkkOgzAMRR0kpk3vUjEci5NwGFY9SO/SXReAIgsnYNNQnDzpCZQs/idBBACXT2FdGWodDVi1wefgeD+slLHePBrz50LyJL6ZlcOAm02v2t3OoN2kXly3K3khYPZU7seP7u9G2lfMXrtR/fmU0PXzu8UEs2kHbs1iI3W7m6vfT+yCeym9V6/cVbtbCE0F0C52i32lHJaAWOdjCMbzV575JoL/GJpn0j+k6sWdmRpnaAxmG6hDZg==
</data>
</layer>
<layer id="1" name="Background" width="39" height="17">
<data encoding="base64" compression="zlib">
eJytlrFOxDAMhkOPNlS9ARCPABISEwszvAX7SQwM9wxM6MQAN3VEQqwMXTjExsIb8AxMDCB0GwOxfFZd4zRNyy/9atK09RcndbvMjFkKS72K/oHzWd60ds/56louGQs8t8YsUn1M+qL4G1szXKtxdrmvLxtXmTfbpZIjrp8ELUX3UYxkx5jK4hHYHjbj2WKkMX0yP4/x3JeL8cH4qB3iOh3ApunQ8b679XpxDNMR+sa1r2zNBu2K+VvJEc8brR+thexL+c7vWRyDIxg4QZdbyEbmbNcWOd7y2sQHug3sK8mVFP5x4iKD9rebbNAntonyznC20J4HHY9xDsSm2TfH3cyfN41NrilIPluL1TYPLZ8Q9zHVudpqTZd4MWyapjm+D5ItVAf7iLOF9un9COMC21MaV6OHsoV0st6PzScYK/NhdRnE48awHW20PzeWa9YyNllzNdlx3SWMNasdm7eua97lOwjfz/mqzsl/GS1voEXRdB+F+CvGJVl8a/pf0p5F53gdq5S8Sf8C0KXdjQ==
eJytlrFOwzAQhk2gNVY7AOIRqITExMIMb8FeqQNDH6MDQ+nUsVJ3Bk9FbCy8Ac/QiQGEujHg09nK5XpOcym/9Ctx7Pg+3yVONl1jNsxc76x9FTxyVUv3PMSxVDwWeGaNWXXkPomNx5YMYyXOJvftwwZaOL1/C3SuP8Uozo3xFo/A9nyiY9MKmLi+iF/7eO07xPgkfOl8F9d9ZJu0R6zoOvCuQ73eAsP4EP0Uzh8t9vt47ol/hBzRvM1daanNtXU9tgcW++AIXsfnanK6PUdim1oc8+FKJz7QIsOQ4yp6+f7ElQy6PMM6gjnbUHhnKFsuP1S3fVxDYpOcW+MFqxmtqcTGawric0ux6tYh5XPs8JmTuOr2mibxNGz83YU2Zctx1bFpRNloXilX2vfAo8j20tHt0fuyUUlsd0ft2HKCvrnTsdM8JUYaV8N2c1wfS5tTysQ1PAh7cuBaFoS1W1qbt6Y1b/IdhO/nLL4L/F9Gyhto1au6jXbxe8LFWXI1/S9Jc6VrdL/wQt64/wAAbfTL
</data>
</layer>
<layer id="2" name="Ground" width="39" height="17">
<data encoding="base64" compression="zlib">
eJxjYEAAbSDO40TF+IA2fmkMkIVD/DYzA8N2VsL6kd2FyyxS7CWkvpqFeLfB3KfKDsGibKjs2doIPjoGyT3kwRQ/jmQeDLwHmvUJinm5EG4j5Edkt5GC/zBhspEBuvuQAbZwu8qIiilxGzZ3PmPFxMFs2N1nxwzBn6HyX9lQcQkTeW5Dj2vkMETHIHv6cYQfCISiue01C6rbkOOAEJbFksaQ8S4eVAyyh48f4RZGJHdNxOFmcsINFF743IYt7+ALN1xuAwEhZlS3oYcftvAkFG7oGB/Q58AtByvbKM0L+PAlJPurWBAY3V2T2RGYXLdREm7vCYQjtnADAVq4jVyAXpfCsDWw3J4GpG25cKshBZMKzDjwm3eSnXI3pUExtcIMhjM5iFOnC/RDPxsqzuJAlKMgt22D1k/MTNRxG7EYV/jC3AZy12BymwoDIp2R4jYABLGkug==
eJxjYEAAbSDO40TF+IA2fmkMkIVD/DYzA8N2VsL6kd2FyyxS7CWkvpqFeLfB3LeLh3T8hwk7GxnL8EDseM/GwPAJinm5EG4j5EeQ21TZSccg96CzkQFMDhvAFm5XGVExJW7D5s5nrJg4mA27++yYIfgzVP4rGyouYSLPbbO10fjMmGqmQc3VBdrbjyP8QCAUzW2vWVDdhhwHhLAsD3559DQHsoePH7u7JuJwMznhBgovfG5DD08QBtmDK9xwuQ0EhJhR3YYeftjCk1C4oWN8QJ8DtxysbKM0L+DDJ5Hsq2JBYHR3TWZHYHLdRkm4vScQjtjCDQRo4TZyAXpdCsPWXJD8b8uFWw0pmFRgxoHfvJPslLspDYqpFWYwnMlBnDpdoB/62VBxFgeiHAW5bRu0fmJmoo7biMW4whfmNpC7BpPbVBgQ6YwUtwEAsGSvSg==
</data>
</layer>
<layer id="3" name="Clutter" width="39" height="17">
@@ -25,7 +25,7 @@
<property name="spriteLayer" type="bool" value="true"/>
</properties>
<data encoding="base64" compression="zlib">
eJy1Vs9LFVEUviPvzQ/fey7bZK6Eeo5gCoW7+iesoL2LWbetXEWCIJaBILjVnUIL8QXRAxXtx9+Q/gNFSUHQwnM453jPnHfHxkUffNy5v85897tzzx3nnGu23AUKLnMXRqH6iop+i+nMP+93qXwfeQpuAk8a5bkrqXOvUnruA990nHvW+n98zl6MmzVIffSab5uCdd0GPulQ/Xob+oE32gETHLXnUZk45++Qc6dQnvAzjjvMPHXcKBDXtn0OjMEYPeC7Cm0h4JxOTpqQ3xLS0Gp47nFcq20uoXJf6TsAPozJLyyR8p4QIuZlvgl/srZ7w4Os2g8L1PMopu/sE8yJh+g9W11PhK5j7JWR8tqttjH2/TH0fe36cX9c2bfIUDDOen6Dtl/smWjrKSJ67XqUsfp7EJ9eqPo2vG+HqfdFdOF5fw3eryaksa+06bWGgHHu19wb1PKB8wiWotV6FjofGlZbl5NZnpep12lxDO//qHJalTatr+nCe9pXbWtJfd+uAqst5JnwS2A/7kD+vZuSNsmRExW+Ve3BRjbYJj495dxrz+ki5+KLO4ljZNA+zH0zGfXbHFmVJ5HrOa1hKfVE6LpoCeX0vom7DnwAezcBwTch7larPGbPnL0F1j5W86z+i/oMY76V+9bexS+5xL18GxOtP5NsnJTiWcGl9kh8k7jfwYNJ4HLseSvznG0QNaRNz7mMiLrj9Fi7d3hHLoPWqZRy6pHxynon82aywbbQP4/2bjWl8iwZHFOosVL/AXp2m6QLKedAw/47hTRcRWuVLgGuYT4jzxBn6i5CyDen/+vOAVKSt+c=
eJydVk1LHEEQ7ZXdmWlnzdGLHyfBrCOYCAZv+ieSCN497NmrSU6iEBATA4FArvGWQA7BFUIWTDAh/0H9A4qKQiCHVFFd6Zqabp3kwaOne6qrX1d114wxxrRy8xdd164OmSDwfaFs9XuN+9Y/H3So/dzwZEwCj5vluduZMS8y0tOH/iton4Dep7mpIKa5js1aXvY7od5zf3TYj83Avu5Z73OkDe+BY+3wGjheNMrEOT3gCfDYPaPdN+sp/TYCfvXYz4ANr7Mf0RYCzhmCZP8eIJ6mpCFveu4JzVLHw5TaA6HvK/BxQvHCFsnrrEf2hYzFjXUhL5y2hcEqY/nQQD1LCZ0zPMfJAK2z2/FEyD763r5T3rvWNu7ivixscO4vUy+nE07PNWi7cjFjbT1BRK9dj2wrzwPHaV3038N6Hxy1Nr4TLyH2Oylp7AttR52bok1+FmvmBrV8cXUE21BO+bwgQnXIBLR1XDErijLZXwjfYf0foqbdpg39tEw4p30x9jqtH7f/AWvj+Y0AQ5iD+vsgI21cI6cicYv5eWurYxwnrr2xe8q5LJwPC7aDrk7PWnqva2TsTiHfFLSH55knQvZZS6im97VjwCPI3RQ4fwd+d/OyzZ66e8+c9vGad/U2yjuM9Za/t/oObLgWc/kxIer4TLvAccsx67pWxojjxn7PIAbTwK3E8671nG8SJXhMzrmJiLp20lbnDr+RW6B1JqOaeqhipWPH82ZtdSxWazh2Oxm1l2nVpitsuX8Oej61SBdyM/Cvo/+dQhr+RWtMFwP3sGIpZohL8S1C8JmT/3V/AEXhquc=
</data>
</layer>
<objectgroup id="4" name="Objects">
@@ -35,7 +35,7 @@
</properties>
</object>
<object id="47" template="../obj/gold.tx" x="282.663" y="66.101"/>
<object id="56" template="../obj/gold.tx" x="422.5" y="97.5">
<object id="56" template="../obj/gold.tx" x="400" y="95.75">
<properties>
<property name="reward">[
{
@@ -104,7 +104,7 @@
</object>
<object id="54" template="../obj/enemy.tx" gid="11419" x="323.079" y="72.763">
<properties>
<property name="effect">{ &quot;startBattleWithCard&quot;: [ &quot;Jace Boss Effect&quot; ]
<property name="effect">{ &quot;startBattleWithCardInCommandZone&quot;: [ &quot;Jace Boss Effect&quot; ]
}</property>
<property name="enemy" value="Jace"/>
</properties>
@@ -202,5 +202,9 @@
<property name="enemy" value="Bandit"/>
</properties>
</object>
<object id="70" gid="3139" x="247.75" y="96.5" width="16" height="16"/>
<object id="71" gid="3139" x="-1.25" y="93.75" width="16" height="16"/>
<object id="72" gid="3139" x="463.75" y="16.75" width="16" height="16"/>
<object id="73" gid="3139" x="608" y="15.25" width="16" height="16"/>
</objectgroup>
</map>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.0" orientation="orthogonal" renderorder="right-down" width="30" height="17" tilewidth="16" tileheight="16" infinite="0" nextlayerid="10" nextobjectid="77">
<map version="1.9" tiledversion="1.9.2" orientation="orthogonal" renderorder="right-down" width="30" height="17" tilewidth="16" tileheight="16" infinite="0" nextlayerid="10" nextobjectid="77">
<editorsettings>
<export format="tmx"/>
</editorsettings>
@@ -63,7 +63,7 @@
</object>
<object id="76" template="../obj/enemy.tx" x="19.093" y="127.799">
<properties>
<property name="enemy" value="Crab"/>
<property name="enemy" value="Giant Crab"/>
</properties>
</object>
</objectgroup>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.0" orientation="orthogonal" renderorder="right-down" width="32" height="20" tilewidth="16" tileheight="16" infinite="0" nextlayerid="13" nextobjectid="159">
<map version="1.9" tiledversion="1.9.2" orientation="orthogonal" renderorder="right-down" width="32" height="20" tilewidth="16" tileheight="16" infinite="0" nextlayerid="13" nextobjectid="159">
<editorsettings>
<export format="tmx"/>
</editorsettings>

View File

@@ -29,7 +29,7 @@
<property name="spriteLayer" type="bool" value="true"/>
</properties>
<data encoding="base64" compression="zlib">
eJztmH0OwiAMxTnBNo3uIu4WXsePHUt3FS+kiyOZhNI3RsFkJelfkr5fhm0fdJUxnYaGhoaGhoaGYLSNMU8wzjt877HJw3/46EisvfJvgr+vjbkCcau/XBdw/73OX8vIOeX6rlvhR/vnMPE/tH8qv/KL83N1aetLmh/pD75a57j2mfiR/L6ziuVH5ys1n1Px91NOisfOdzd/7P+WykP5kzkb5TXGnBwPpYvONaqOEF1qj9UeZyY3L19V/LmH9nO6cza3ftfUZCr+GE3l/w/+pXcSKX7pu45PMyX/Gg/h63/2/SPkHST4W0cfuSeE9BHNlPwIi/L//ub2AOr9gfIhpfmpfEv01vCH/Fvom1Fzn7u/DwvOcu7fQr2T829S3p/7thwb6t9c75Z6hbSl/FuJldL/lFix/ifmfhh7vyz91mvP9CSso/xl+d+e+Pwi
eJztmH0OgjAMxXcCQKKchFt4HT84lnIVL6REluCyro+xbiZ0yfvLpf2F2fZtfWVMr1KpVCqVSiWorjHmCep8wPeemjz8x08eidUq/y74h9qYK6Bb/eW6gPvvdf5aRs4p13fdCz/aP8eZ/6H9U/mVX5yfq0tbX9L8SH/w1TrH1WbiR+L7ziqWH52v1HxOxT/MMSkeO9/d+LH/WyoO5U+WbJTXmGJyPFRedK5RdYTkpfbY3NPM5Oblq4o/99B+Lu+Sza3fLTWZij8mp/L/B//aO4kUv/Rdx5czJf8WD+Hrf/b9I+QdJPg7Jz9yTwjlR3Km5EdYlP/3N7cHUO8PlA8pzU/FW5NvC3/Iv4W+GTX3ufv7uOIsl/4t1Ds5/ybl/blvy7Gh/s31bqlXKLeUfyuxUvqfEivW/8TcD2Pvl6Xfev/1/VP50+oNNlL7xQ==
</data>
</layer>
<layer id="5" name="AboveSprites" width="48" height="48">

View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.2" orientation="orthogonal" renderorder="right-down" width="40" height="26" tilewidth="16" tileheight="16" infinite="0" nextlayerid="8" nextobjectid="74">
<editorsettings>
<export target="wastetown..tmx" format="tmx"/>
</editorsettings>
<tileset firstgid="1" source="../tileset/main.tsx"/>
<tileset firstgid="10113" source="../tileset/buildings.tsx"/>
<layer id="1" name="Background" width="40" height="26">
<data encoding="base64" compression="zlib">
eJzllm0KgCAMhoX80xE9SdAhg6BbeIkQCsJm23TOQcH7o5jt0X0ZZudCpTb/FsUGsi2tbxHHL2YrzYf5vX1BvNS9SfPkXFi8of+2sFE546VkH/03X+kbl6/2LClxl4qxROxzPskc5OQBVgOcvWBKTw0flB/cetcQla93fKl8Oad2HnLOr2SnGWvJXteb7/m+EOtuBG9is8pnme1P2qfxDBxZ6gkafCPmhPYZl+4jVmY8dqdbnQ0+yPfoOcq5695rDuGedAJSX/Xt
</data>
</layer>
<layer id="2" name="Ground" width="40" height="26">
<data encoding="base64" compression="zlib">
eJz7x8nAcI5lYDAIILNBYD8HA8N/oJsYuBgY4jgheKDchuw+ZAxy0yGgO/8A6dcDFHbo4QfmcyHYCZy43T8QOBYaj7Bww+Z+XPgoljSALdxh5g0mf+OLL3LNwJc2KcHUSsu0dONIcB+sDPw/gGUz3vAb4LKZGDzY3TcU8GDNH0PFfaN4FA8lfJN34N0wijHxnUFajy1jRcUD6Q587kJ3H73rDVzuIRR+9HInKW5DbpOCAABBQjfn
</data>
</layer>
<layer id="7" name="Mountain Walls" width="40" height="26">
<data encoding="base64" compression="zlib">
eJy9ljFOwzAUhpPS0i7QpW1IjgAXYEXiFByDqYWiDqxsSFyAC1Q0kFyCMrFwhG4IwUxM8iuvL362k1T80q/WsRN/ee/ZTuB7XuDgi45sPnaU+Zl57DhPHdN5wAKhHZP5Mf7F9yqK/fa8/L1180iKG4yvwzkqnn9teOZr333+Opw2RsUEQ587ZJlmvjL0Tyxsc88cN+iNMJ92t/vmhvtUjNLMM4HTxBdmjix5hS57nnci1NjcgVHl8cmvMppynBTvxvP7uOcALPDdD+ozSjEEH3IMn3Urj/+LX1uB8YjlwYUP5rFsy7fulgaLiuGiBh+Y/osvYDGUahB8oYaR1zvnuz1oxkvr0BZDXn88z5SR83WKNXQ3yC0p3a9em5AzwYUvKhgjvzRdL6a9o65uMq8c1wj4wJgSh8SRsO81kS52El/KGBPSTlj7o2G96fh47NQZuBL4VO7A10Ydw56+Jvvp+aGemX9DjQlf4sjXdM3ahO8tmvO4AR+ViRV9au1+ke+KY7+M36J6W0U0vy7S1SDde11E97+ZhZOuW5vCYTZ2WLYRI34+uDKizqRvL7Vm6Np10ZTVNmXCfxvr+37uZT93zDjhld+cj7JQPhgMsO6a0pLUpm3/qyPKovNDb9ubfv5L+7lM58cu2CDd3JsiTt+B/Nxd8NnYbPoR+KTz4xdQH9Hf
</data>
</layer>
<layer id="3" name="Clutter" width="40" height="26">
<properties>
<property name="spriteLayer" type="bool" value="true"/>
</properties>
<data encoding="base64" compression="zlib">
eJyllz1vE0EQhueQnSgIG6OgmIPCpS+WIVCAKCG/A5CgpkJCNkFA/gFQ8tHxB5BwTAR0qSEFEaFLDwIpSY+Y1e3o5uZmP85+pVd7vq99bmZ2NuklAD3r7hwege55RWxjPH6E3nDc9ycD+Is+RB9lBRd/TjJdWcrH36fK77o7BLg3rMe3YudLE/2+pVWAk+gWur1a8NFz55L4eD1Btqc1+EwMJjhuWT4+zyd2/HUxH9MBwPlBfkzPTRU+GTep0HXiW2F5Ir4LC4Ul31Vku2b5eH5DtajFl2rAxzcR+TXvud6oGqB6zPNbZy3FiuqP59dVg5p4fuuu93n5uh2cl9nkd9rRLSXn5znu1vh+4iNLPtIwKY+kQ6zxI/SxUusjMZKIL3Z9aHzmnVpcSI9b+fgcxxfol63qNdIN7Jc30etZ/jvUa2P5YnSxDXAJvdZ233MLuW6j71g+vqZm4aP4a4zLOMfZTH8X5eszXv8i7nnQLN45idivXHxyz5Jaw3kvO/hI+3j9p73nGNfUvxNlvp0sPoau/JJ53z6zoPdF4x+O8+Rl1ucPsmoMPjj4Ug9byvKt9cTTdg81c1B8fNq2o9y3jVxrOQ2wcUttMHO+ZxifTZtfquFvjcLdpNzXfeJ8IY3b+rea35zvDbK9zcrXTQ0aDWr0Zo1P67cUg7Gnh/hq01ef+40wH8+f1m9JPj7SO0d8KL4UP9rr+HdprHJP8/Vb4pP7g2+Pk3xGO6I/UX60HPQC9Rezj/CYd9jfxR+RYzur8h0E+ievb977ZpUr5t+RYy/L4/CwWcSd1vH9Zm6fQnxabxmBuwdtQm7eT4xN/OS5XfT7RT+fr8/5OHhflzZ8FBseIzO+6gO87ufHu4G1K+MX2uv4/wC+58zcJi7cv+y4hWzTfnF+Vr6Y/cT1rGTzOaT/W07H9w==
</data>
</layer>
<objectgroup id="4" name="Objects">
<object id="48" template="../obj/treasure.tx" x="122.611" y="290.898"/>
<object id="50" template="../obj/enemy.tx" x="181.5" y="221.5">
<properties>
<property name="enemy" value="Armored Knight"/>
</properties>
</object>
<object id="51" template="../obj/treasure.tx" x="135.833" y="53.833"/>
<object id="57" template="../obj/enemy.tx" x="469.833" y="71.8337">
<properties>
<property name="enemy" value="Bear"/>
</properties>
</object>
<object id="58" template="../obj/enemy.tx" x="339.5" y="288.167">
<properties>
<property name="enemy" value="Kor Warrior"/>
</properties>
</object>
<object id="59" template="../obj/enemy.tx" x="417" y="198">
<properties>
<property name="enemy" value="Dwarf"/>
</properties>
</object>
<object id="61" template="../obj/entry_right.tx" x="602.5" y="313.5">
<properties>
<property name="direction" value="right"/>
</properties>
</object>
<object id="67" template="../obj/gold.tx" x="140.978" y="184.022"/>
<object id="68" template="../obj/enemy.tx" x="471" y="285">
<properties>
<property name="enemy" value="Kor Warrior"/>
</properties>
</object>
<object id="69" template="../obj/enemy.tx" x="290.5" y="222.5">
<properties>
<property name="enemy" value="Kor Warrior"/>
</properties>
</object>
<object id="70" template="../obj/enemy.tx" x="176" y="145">
<properties>
<property name="enemy" value="Armored Knight "/>
</properties>
</object>
<object id="71" template="../obj/enemy.tx" x="177" y="94">
<properties>
<property name="effect">{ &quot;startBattleWithCardInCommandZone&quot;: [ &quot;Nahiri Boss Effect&quot;]
}</property>
<property name="enemy" value="Nahiri"/>
</properties>
</object>
<object id="72" template="../obj/treasure.tx" x="399.107" y="62.4997"/>
<object id="73" template="../obj/enemy.tx" x="446.557" y="366.341">
<properties>
<property name="enemy" value="Armored Knight "/>
</properties>
</object>
</objectgroup>
</map>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.2" orientation="orthogonal" renderorder="right-down" width="37" height="23" tilewidth="16" tileheight="16" infinite="0" nextlayerid="15" nextobjectid="114">
<map version="1.9" tiledversion="1.9.2" orientation="orthogonal" renderorder="right-down" width="37" height="23" tilewidth="16" tileheight="16" infinite="0" nextlayerid="15" nextobjectid="117">
<editorsettings>
<export target="wastetown..tmx" format="tmx"/>
</editorsettings>
@@ -7,17 +7,17 @@
<tileset firstgid="10113" source="../tileset/buildings.tsx"/>
<layer id="13" name="subsublaag" width="37" height="23">
<data encoding="base64" compression="zlib">
eJztlDEKgDAMRV1UBD2Ui0fwvJ7GQzhJKBksiW1qajL0wR+kkjzS0K5rNPI5e2sDnmN8foOrlS/25vpvk7xebScJq9JctZzQR8uLYlhCcoh3kfKCfyBwFieHaw7RQuqA/hhpL4lLjhPsEOdR+y3g9hid3uYjfQu+Es+Jmou1E4WVU+ru/vZKgU6evDy5ILWd9oL6tZ1K6nu8O4/cko4uDQ==
eJxjYBgFo4Ay4MY50C7ABF4D7KYPWMSQ3URqmD1jpcg5YPCBAbu7SHUHOqaGuyh1kyPUHY5UdBc6YOOFYGLcA7OfQwBBU9tdv3ggmFjALYDKh7kNOS4PsFPPfchgGlp6d6RB/AxVMJDlJ668NxjL9MHqJlq6C5RnYZhUN9HDXaS4iZaAVPeAAK3dFEaG+bR2EznmD8Z8NxgBAK1JHpE=
</data>
</layer>
<layer id="10" name="sublaag" width="37" height="23">
<data encoding="base64" compression="zlib">
eJzNll9OwzAMxieklQax3Wma1CPsEXjkaHALJs6y7QY8bsyk1pyvX5yUFglLn5I2sf2Lk/5pVotF4+jjngvnbNfzqZbluIzKMdlrG9/G+EsmNhfv1TLhWlks0evjkEnNY2I52bruVilPDZOtE/MpSQz9bH4mmXMKUYzF86thLOV/b291Z7USs0xsfWiMdQzfIQxjlXxwHzbLqEuIbU0d3X261ukcYqv3xq550/vsAvfxfNk8iWOFz1HpbP/wPKQxZI2YB01rW+JRJnnWVcjEjMXZhVuO2vOmfp9tKpmDTLmcJUm9Lr3EXvrW1hp57Dg+x/ZdgLkOTSqPS8dtq31W4+eQMum7VvpdiP1uIg+ylHz2bcp0CsPvDjKNEfKzmpXqhN8iMY+pM2L3GFOOUftnOFPsO91l9n0uJqbSv8MUpt9yKRMbUybcP8zr6T8ylbjeWn/868r2FDjTFMm7N5dTz0xuXHis5mLyaoVM9jr3Py5r1LVOkcczVt+PMc9P
eJy1lj1uwzAMhbXYgfNTdO7egxQFuvcWvUKm9hQdfZYepVPmHKEgFAIP7CMp2c4DHmxTNvWZVOSMp1LGwD87bnvP68N2bmW5DNUeE15jftQ9mdi9NhYx4TUT4/k4/mdSRUzsnZkOj9wRE9bJ9qzFmXB+FmMsyoH+HEv5GtsY1zJZLjunnIs0jucen6fvqTrrHauJzf8yVEfPXIaSKmKSuJc/6sXvbd7zYXsmHRdla1v0dKzH510148rE6oKM8ltXI4+M7W/O8ivXe45Dmawt07VUZ88pix73Zm2uYRK/TdUek8eI0pp64y0c6Hmq+6xw9dbJymPr4cG9v5cJ1xv2cCkT+xYpk82p82uPbd89Jta7iE847LXkZ+8ZMWmczcnyWNv/DoypOHVSHpz/Wni817r3sLpp7oxJe2xjWzPNUx8T87yCq4UJ11ULzz24bO96OKyjtc3WsQj3AByT74vkxO/NEnssS/wHYQ/U7g==
</data>
</layer>
<layer id="9" name="slim" width="37" height="23">
<data encoding="base64" compression="zlib">
eJy1Vktug0AMpeqPiULvlAVJlAN02UVWvU5PQZP0EL0LJOEEXURVW6yZJx7GgUnVPumJCRD72WObSZI+5q7lwvl7Oa1XtBYsnafGXWbzNxAt2zRJ3lLvu2iudfCLdawmsbMLtsQua7pEM/JTNtyHaxXWedC7j9TEeYYmJmKH9sr1bQjlv4eGx8BN8+77vWdOz15Tf4UmK2bO8zb4RM4Qm8ScZN6eUGtCHbFu+R80rcg2WNJa/HH8or923dxy3kWvxCx2xd9p2s83bPFeiBYAeUJMGxXXivxjn6ENuWWgPnLKg8aS6gg43HpdchVUrpvDIm39Wb2gc6uBdxEr70GltEDPLFAwU78B1ClyXAbdeyNGxlfQzPPnOutS7wXj0XV1MTC/hvwL1uEZ+0FPWtD9xn1nxSf4dp4xWJ95TzQ9T1vO3TgXkT7H9BRpOz9A1CADfc81taM5gJoYxaTvDz7Rn6Xr9gf8aPbyMPldHrQ/ns1DcWHu1f+wN5bGsfyKlqPr65m77nzEnjNR5/rZUI/G4Co7X8MH6i3MFXyTWDfmiEDHwijSfj0hBo4L+dFnBytXglz5X1ygCXEx+Vxh7dPJ8An7hYoBz/Et5Xs3Eeezlwc7Vu531J2endCk5zz863usi+uK982at2xf53ml7OP7V6v7Q4Bt1sX7hnMq9wOeIz9PDT+y9jusY7ZyEavr0zj3cE5wtuO653NhPeD7Ej38H+5dAcet63GMfwE+xwJWf8XyB8LPIec=
eJydlm1ugzAMhqnWbYS20i6xK+wGlIqT7AY7Ev06xK6x7s+kfnGGaj+GRd7xYhxKa8lKlID92EmcRFFX5q7RzNVjKfVz6ossXK1anma23iPCso6jaBvXvouqLb1f9IcyiZ2NtyV2mekWZuRnX+nRtwffTz3vcSAT5xlMrIgd7AfXtSEq/54qPXtdVd9+Ptea0twyrlswWTFzntfe5+TFVrEnqpmwj5hbcgKmnGxD99SXmDn/wl+q2ENM4u8y7eYbueS1EBYI8oSYViqu3FhDLRZPSnnQsqB99B/rY/sbyQfnsIibtdQ50TL366yZSoqV1+CgWMDzlUTRjvQ76XJujfg0C1Qz5a49/zBrq14LkY9J3f54jp3BlA7IT4gppTnrPz5vZ+Ob1+eGS0TYoH3C5+JoML1Pa/9or2lIsJbCY/GzZMa83oNzatk39i/2sLSJj0fEOjPX2ENM8IOzhj5qNmyKf9ZQLYGgjxqFWLg2b+Lu2dHxlWptrBg0W6J4mEvzgfFtZH+Hb1FDNA/OAaSIm3oIxf0SypXF1DeG8dEsvIdPrqkBe9e+x5k7d+19yLEwK+LncStm5Ee/HaxciaTKf3aFyfJv5Sk1ciJ2LoZP2C9UDJjHXcpjY+OtA4YksI7MhJqF/c9MImDSdR7+rXrFXGDBuvE7h4Xtwyf+zZV93H+lGu8T2B7PuvsR+yNz7fcD5nU9LwzfQ2t3iOvXePdwTvC2Q+1exu13Ydnj+xYe/ofPrgjHrffjvXfZrUz6jW6dr6H6B2+d87s=
</data>
</layer>
<layer id="12" name="clutter" width="37" height="23">
@@ -25,49 +25,47 @@
<property name="spriteLayer" type="bool" value="true"/>
</properties>
<data encoding="base64" compression="zlib">
eJxjYCAPuHEi2K6cqPyBAoPNTW6cg9dNMDwY3IQOng4y99AbLOdgYFjJgSr2eIDDBGQ/LF4cWRE0jI2sjt4A7AYuBoYwoN3/ODHdhA2AwngFlnCmBngODYNPaGEBCy8YBoXVDx5EfIP4TziJT/9svAhMCjjAAcEgMI0BdzySkw/JdRMIoIcXDCynQRzBwhyXnTBgzEh9u3EBbGGO7D50t25iw20WIX/BAKGwJWQOMfkH3QwQn1j3URPgC8uBACvQ0uAtFgaG2yzUtSOCnTT1oLaAxyAIG3IBoXgdDPE+mMA8npFpNy0AAKwTN0M=
eJzNlkFOwzAQRQ0SYBeCuuQusE1b9QTchVNwANhSKDdimbb0GHhwvjKZ2rGNg9ovjZI2jv38ZzKJUn/TzHTnten/PpZSmWami9i1kn3JNcZgGhoX0u7ChW+uEFNozQ+t1FrEpy5jktpm8FAsbFxPlXqx415tvFmefaJPNPZdx5lyeDjT/ZlSDzYak+4TjZUeNAneDvH87s8ev43bL7Hl+BTS18Qd4SM4YyySed76lSvki+5F3N04LuljChOdb9pcERM8yhH32MeFOltGaggiFqon7Ae1dFl1IYWa5oLHCPhGXLTPlU5jgicL039+SCEm5Pi8cj0Eov08VW4e6VsdYeFMTZs3mm/ZrsX9kz2dP6e1GI/1aU7qb1vT/2/DaiSlH8Mv7r8U76/IMR0n08PAHOSbrDG537k5ZCGf92ytkLhHIVG+MCfCV/s8l9IH+LyO8IApxh2SrHte6+jX3NP/Emplpfu9GP2Te+HLb44er/LZkG/UoG/dEqYSDa1H155vh6+n8I71LbuLzHMM/0p0Ct/4UMp7IeW9MaZ+AIaemRA=
</data>
</layer>
<objectgroup id="11" name="obj">
<object id="75" gid="303" x="506.5" y="325" width="16" height="16"/>
<object id="76" gid="303" x="316" y="366" width="16" height="16"/>
<object id="77" gid="2347" x="442" y="305.5" width="16" height="16"/>
<object id="78" gid="5197" x="273" y="298.5" width="16" height="16"/>
<object id="89" template="../obj/enemy.tx" x="78" y="219.5">
<object id="89" template="../obj/enemy.tx" x="132" y="219">
<properties>
<property name="enemy" value="Cave Spider"/>
<property name="enemy" value="Ooze"/>
</properties>
</object>
<object id="91" template="../obj/enemy.tx" x="413.492" y="228.218">
<object id="91" template="../obj/enemy.tx" x="424.992" y="215.718">
<properties>
<property name="enemy" value="Zombie"/>
</properties>
</object>
<object id="95" template="../obj/enemy.tx" x="58" y="271.5">
<object id="95" template="../obj/enemy.tx" x="53.5" y="245">
<properties>
<property name="enemy" value="Cave Spider"/>
</properties>
</object>
<object id="96" template="../obj/enemy.tx" x="306.5" y="321.5">
<object id="96" template="../obj/enemy.tx" x="299.5" y="312.5">
<properties>
<property name="enemy" value="Skeleton"/>
</properties>
</object>
<object id="97" template="../obj/enemy.tx" x="279.833" y="229.5">
<object id="97" template="../obj/enemy.tx" x="275.333" y="233.5">
<properties>
<property name="enemy" value="Skeleton"/>
<property name="enemy" value="Ooze"/>
</properties>
</object>
<object id="98" template="../obj/enemy.tx" x="487.333" y="153.667">
<object id="98" template="../obj/enemy.tx" x="505.833" y="115.167">
<properties>
<property name="enemy" value="Horror"/>
</properties>
</object>
<object id="100" template="../obj/enemy.tx" x="176.588" y="143.029">
<object id="100" template="../obj/enemy.tx" x="178.088" y="149.029">
<properties>
<property name="effect">{ &quot;startBattleWithCard&quot;: [ &quot;Slime Boss Effect&quot;]
<property name="effect">{ &quot;startBattleWithCardInCommandZone&quot;: [ &quot;Slime Boss Effect&quot;]
}</property>
<property name="enemy" value="Slime Boss"/>
<property name="enemy" value="Ooze Boss"/>
</properties>
</object>
<object id="101" template="../obj/enemy.tx" x="461" y="329">
@@ -75,16 +73,19 @@
<property name="enemy" value="Horror"/>
</properties>
</object>
<object id="104" template="../obj/gold.tx" x="512.5" y="159"/>
<object id="106" template="../obj/gold.tx" x="444.5" y="271"/>
<object id="104" template="../obj/gold.tx" x="532" y="73"/>
<object id="106" template="../obj/gold.tx" x="522.333" y="202.833"/>
<object id="107" template="../obj/gold.tx" x="169.5" y="276"/>
<object id="108" template="../obj/treasure.tx" x="88" y="275.5"/>
<object id="109" template="../obj/treasure.tx" x="505" y="144.5"/>
<object id="109" template="../obj/treasure.tx" x="476.75" y="76"/>
<object id="110" template="../obj/treasure.tx" x="545.5" y="289"/>
<object id="111" template="../obj/entry_up.tx" x="325.5" y="362">
<properties>
<property name="teleport" value=""/>
</properties>
</object>
<object id="114" gid="10615" x="430.5" y="170.5" width="16" height="16"/>
<object id="115" gid="10615" x="47" y="310.5" width="16" height="16"/>
<object id="116" gid="10615" x="538.5" y="266.5" width="16" height="16"/>
</objectgroup>
</map>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.0" orientation="orthogonal" renderorder="right-down" width="30" height="17" tilewidth="16" tileheight="16" infinite="0" nextlayerid="7" nextobjectid="55">
<map version="1.9" tiledversion="1.9.2" orientation="orthogonal" renderorder="right-down" width="30" height="17" tilewidth="16" tileheight="16" infinite="0" nextlayerid="7" nextobjectid="55">
<editorsettings>
<export target="wastetown..tmx" format="tmx"/>
</editorsettings>
@@ -12,7 +12,7 @@
<tileset firstgid="10113" source="../tileset/buildings.tsx"/>
<layer id="6" name="Collision" width="30" height="17">
<data encoding="base64" compression="zlib">
eJyL5mVg2MWDH0cRoQaEo4lUBzJPFkjjA7XcDAx7CKgBAZCdu4lQBwLSPPjtJdZOUgE+e2llJz57aWknLntpbScue6VpbOdgs5ceYNTeUXtH7aWOvcTUl8gYGZCqFxkDAGuQN1o=
eJyL5mVg2MWDH0cRoQaEo4lUBzJPFkjTG0jzjNo7au+ovaP2jto7au/gsJeY+hIZIwNS9SJjAAIUL00=
</data>
</layer>
<layer id="1" name="Background" width="30" height="17">
@@ -42,6 +42,8 @@
<object id="49" template="../obj/gold.tx" x="209.038" y="33.8697"/>
<object id="53" template="../obj/enemy.tx" x="223.924" y="101.602" width="16" height="17.6724">
<properties>
<property name="effect">{ &quot;startBattleWithCardInCommandZone&quot;: [ &quot;Slimefoot's Boss Effect&quot;]
}</property>
<property name="enemy" value="Slimefoot"/>
</properties>
</object>

Some files were not shown because too many files have changed in this diff Show More