diff --git a/forge-ai/src/main/java/forge/ai/AiAttackController.java b/forge-ai/src/main/java/forge/ai/AiAttackController.java index 7f6092d2724..7faac65a862 100644 --- a/forge-ai/src/main/java/forge/ai/AiAttackController.java +++ b/forge-ai/src/main/java/forge/ai/AiAttackController.java @@ -48,10 +48,7 @@ import forge.util.collect.FCollection; import forge.util.collect.FCollectionView; import org.apache.commons.lang3.tuple.Pair; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; +import java.util.*; /** @@ -360,35 +357,41 @@ public class AiAttackController { } // this checks to make sure that the computer player doesn't lose when the human player attacks - public final List notNeededAsBlockers(final List attackers) { + public final List notNeededAsBlockers(final List currentAttackers, final List potentialAttackers) { //check for time walks if (ai.getGame().getPhaseHandler().getNextTurn().equals(ai)) { - return attackers; + return potentialAttackers; } // no need to block (already holding mana to cast fog next turn) if (!AiCardMemory.isMemorySetEmpty(ai, AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT)) { // Don't send the card that'll do the fog effect to attack, it's unsafe! List toRemove = Lists.newArrayList(); - for (Card c : attackers) { + for (Card c : potentialAttackers) { if (AiCardMemory.isRememberedCard(ai, c, AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT)) { toRemove.add(c); } } - attackers.removeAll(toRemove); - return attackers; + potentialAttackers.removeAll(toRemove); + return potentialAttackers; } + if (ai.isCardInPlay("Masako the Humorless")) { + // "Tapped creatures you control can block as though they were untapped." + return potentialAttackers; + } + + final CardCollection notNeededAsBlockers = new CardCollection(potentialAttackers); + final List vigilantes = new ArrayList<>(); - for (final Card c : myList) { - if (c.getName().equals("Masako the Humorless")) { - // "Tapped creatures you control can block as though they were untapped." - return attackers; - } + for (final Card c : Iterables.concat(currentAttackers, potentialAttackers)) { // no need to block if an effect is in play which untaps all creatures // (pseudo-Vigilance akin to Awakening or Prophet of Kruphix) if (c.hasKeyword(Keyword.VIGILANCE) || ComputerUtilCard.willUntap(ai, c)) { vigilantes.add(c); + } else if (currentAttackers.contains(c)) { + // already attacking so can't block + notNeededAsBlockers.add(c); } } // reduce the search space @@ -402,10 +405,8 @@ public class AiAttackController { } }); - final CardCollection notNeededAsBlockers = new CardCollection(attackers); - // don't hold back creatures that can't block any of the human creatures - final List blockers = getPossibleBlockers(attackers, opponentsAttackers, true); + final List blockers = getPossibleBlockers(potentialAttackers, opponentsAttackers, true); if (!blockers.isEmpty()) { notNeededAsBlockers.removeAll(blockers); @@ -476,12 +477,15 @@ public class AiAttackController { // these creatures will be available to block anyway notNeededAsBlockers.addAll(vigilantes); + // remove those that were only included to ensure a full picture for the baseline + notNeededAsBlockers.removeAll(currentAttackers); + // Increase the total number of blockers needed by 1 if Finest Hour in play // (human will get an extra first attack with a creature that untaps) // In addition, if the computer guesses it needs no blockers, make sure // that it won't be surprised by Exalted final int humanExaltedBonus = defendingOpponent.countExaltedBonus(); - int blockersNeeded = attackers.size() - notNeededAsBlockers.size(); + int blockersNeeded = potentialAttackers.size() - notNeededAsBlockers.size(); if (humanExaltedBonus > 0) { final boolean finestHour = defendingOpponent.isCardInPlay("Finest Hour"); @@ -511,6 +515,88 @@ public class AiAttackController { return notNeededAsBlockers; } + public void reinforceWithBanding(final Combat combat) { + reinforceWithBanding(combat, null); + } + public void reinforceWithBanding(final Combat combat, final Card test) { + CardCollection attackers = combat.getAttackers(); + if (attackers.isEmpty()) { + return; + } + + List bandsWithString = Arrays.asList("Bands with Other Legendary Creatures", + "Bands with Other Creatures named Wolves of the Hunt", + "Bands with Other Dinosaurs"); + + List bandingCreatures = null; + if (test == null) { + bandingCreatures = CardLists.filter(myList, card -> card.hasKeyword(Keyword.BANDING) || card.hasAnyKeyword(bandsWithString)); + + // filter out anything that can't legally attack or is already declared as an attacker + bandingCreatures = CardLists.filter(bandingCreatures, card -> !combat.isAttacking(card) && CombatUtil.canAttack(card)); + + bandingCreatures = notNeededAsBlockers(attackers, bandingCreatures); + } else { + // Test a specific creature for Banding + if (test.hasKeyword(Keyword.BANDING) || test.hasAnyKeyword(bandsWithString)) { + bandingCreatures = new CardCollection(test); + } + } + + // respect global attack constraints + GlobalAttackRestrictions restrict = GlobalAttackRestrictions.getGlobalRestrictions(ai, combat.getDefenders()); + int attackMax = restrict.getMax(); + if (attackMax >= attackers.size()) { + return; + } + + if (bandingCreatures != null) { + List evasionKeywords = Arrays.asList("Flying", "Horsemanship", "Shadow", "Plainswalk", "Islandwalk", + "Forestwalk", "Mountainwalk", "Swampwalk"); + + // TODO: Assign to band with the best attacker for now, but needs better logic. + for (Card c : bandingCreatures) { + Card bestBand; + + if (c.getNetPower() <= 0) { + // Don't band a zero power creature if there's already a banding creature in a band + attackers = CardLists.filter(attackers, card -> combat.getBandOfAttacker(card).getAttackers().size() == 1); + } + + Card bestAttacker = ComputerUtilCard.getBestCreatureAI(attackers); + if (c.hasKeyword("Bands with Other Legendary Creatures")) { + bestBand = ComputerUtilCard.getBestCreatureAI(CardLists.getType(attackers, "Legendary")); + } else if (c.hasKeyword("Bands with Other Dinosaurs")) { + bestBand = ComputerUtilCard.getBestCreatureAI(CardLists.getType(attackers, "Dinosaur")); + } else if (c.hasKeyword("Bands with Other Creatures named Wolves of the Hunt")) { + bestBand = ComputerUtilCard.getBestCreatureAI(CardLists.filter(attackers, CardPredicates.nameEquals("Wolves of the Hunt"))); + } else if (!c.hasAnyKeyword(evasionKeywords) && bestAttacker != null && bestAttacker.hasAnyKeyword(evasionKeywords)) { + bestBand = ComputerUtilCard.getBestCreatureAI(CardLists.filter(attackers, card -> !card.hasAnyKeyword(evasionKeywords))); + } else { + bestBand = bestAttacker; + } + + if (c.getNetPower() <= 0) { + attackers = combat.getAttackers(); // restore the unfiltered attackers + } + + if (bestBand != null) { + GameEntity defender = combat.getDefenderByAttacker(bestBand); + if (attackMax == -1) { + // check with the local limitations vs. the chosen defender + attackMax = restrict.getDefenderMax().get(defender) == null ? -1 : restrict.getDefenderMax().get(defender); + } + + if (attackMax == -1 || attackMax > combat.getAttackers().size()) { + if (CombatUtil.canAttack(c, defender)) { + combat.addAttacker(c, defender, combat.getBandOfAttacker(bestBand)); + } + } + } + } + } + } + private boolean doAssault() { if (ai.isCardInPlay("Beastmaster Ascension") && this.attackers.size() > 1) { final CardCollectionView beastions = ai.getCardsIn(ZoneType.Battlefield, "Beastmaster Ascension"); @@ -1199,7 +1285,7 @@ public class AiAttackController { if ( LOG_AI_ATTACKS ) System.out.println("Normal attack"); - attackersLeft = notNeededAsBlockers(attackersLeft); + attackersLeft = notNeededAsBlockers(combat.getAttackers(), attackersLeft); attackersLeft = sortAttackers(attackersLeft); if ( LOG_AI_ATTACKS ) diff --git a/forge-ai/src/main/java/forge/ai/AiBlockController.java b/forge-ai/src/main/java/forge/ai/AiBlockController.java index e2d3b50c347..16473ed204a 100644 --- a/forge-ai/src/main/java/forge/ai/AiBlockController.java +++ b/forge-ai/src/main/java/forge/ai/AiBlockController.java @@ -17,11 +17,7 @@ */ package forge.ai; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; +import java.util.*; import com.google.common.base.Predicate; import com.google.common.base.Predicates; @@ -36,6 +32,7 @@ import forge.game.card.CardCollectionView; import forge.game.card.CardLists; import forge.game.card.CardPredicates; import forge.game.card.CounterEnumType; +import forge.game.combat.AttackingBand; import forge.game.combat.Combat; import forge.game.combat.CombatUtil; import forge.game.cost.Cost; @@ -770,21 +767,52 @@ public class AiBlockController { tramplingAttackers = CardLists.filter(tramplingAttackers, Predicates.not(changesPTWhenBlocked(true))); for (final Card attacker : tramplingAttackers) { + boolean staticAssignCombatDamageAsUnblocked = StaticAbilityAssignCombatDamageAsUnblocked.assignCombatDamageAsUnblocked(attacker); + if (CombatUtil.getMinNumBlockersForAttacker(attacker, combat.getDefenderPlayerByAttacker(attacker)) > combat.getBlockers(attacker).size() - || StaticAbilityAssignCombatDamageAsUnblocked.assignCombatDamageAsUnblocked(attacker) || attacker.hasKeyword("CARDNAME can't be blocked unless all creatures defending player controls block it.")) { continue; } + boolean needsMoreChumpBlockers = true; + + // See if it's possible to tank up the damage with Banding + List bandsWithString = Arrays.asList("Bands with Other Legendary Creatures", + "Bands with Other Creatures named Wolves of the Hunt", + "Bands with Other Dinosaurs"); + if (AttackingBand.isValidBand(combat.getBlockers(attacker), true)) { + continue; + } + chumpBlockers = getPossibleBlockers(combat, attacker, blockersLeft, false); chumpBlockers.removeAll(combat.getBlockers(attacker)); + + // See if there's a Banding blocker that can tank the damage for (final Card blocker : chumpBlockers) { - // Add an additional blocker if the current blockers are not - // enough and the new one would suck some of the damage - if (ComputerUtilCombat.getAttack(attacker) > ComputerUtilCombat.totalShieldDamage(attacker, combat.getBlockers(attacker)) - && ComputerUtilCombat.shieldDamage(attacker, blocker) > 0 - && CombatUtil.canBlock(attacker, blocker, combat) && ComputerUtilCombat.lifeInDanger(ai, combat)) { - combat.addBlocker(attacker, blocker); + if (blocker.hasKeyword(Keyword.BANDING) || blocker.hasAnyKeyword(bandsWithString)) { + if (ComputerUtilCombat.getAttack(attacker) > ComputerUtilCombat.totalShieldDamage(attacker, combat.getBlockers(attacker)) + && ComputerUtilCombat.shieldDamage(attacker, blocker) > 0 + && CombatUtil.canBlock(attacker, blocker, combat) && ComputerUtilCombat.lifeInDanger(ai, combat)) { + combat.addBlocker(attacker, blocker); + needsMoreChumpBlockers = false; + break; + } + } + } + + if (staticAssignCombatDamageAsUnblocked) { + continue; + } + + if (needsMoreChumpBlockers) { + for (final Card blocker : chumpBlockers) { + // Add an additional blocker if the current blockers are not + // enough and the new one would suck some of the damage + if (ComputerUtilCombat.getAttack(attacker) > ComputerUtilCombat.totalShieldDamage(attacker, combat.getBlockers(attacker)) + && ComputerUtilCombat.shieldDamage(attacker, blocker) > 0 + && CombatUtil.canBlock(attacker, blocker, combat) && ComputerUtilCombat.lifeInDanger(ai, combat)) { + combat.addBlocker(attacker, blocker); + } } } } diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index fb05d635995..d36f180b66d 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -1304,6 +1304,9 @@ public class AiController { AiAttackController aiAtk = new AiAttackController(attacker); lastAttackAggression = aiAtk.declareAttackers(combat); + // Check if we can reinforce with Banding creatures + aiAtk.reinforceWithBanding(combat); + // if invalid: just try an attack declaration that we know to be legal if (!CombatUtil.validateAttackers(combat)) { combat.clearAttackers(); @@ -1618,8 +1621,7 @@ public class AiController { AiPlayDecision opinion = canPlayAndPayFor(sa); // reset LastStateBattlefield - sa.setLastStateBattlefield(CardCollection.EMPTY); - sa.setLastStateGraveyard(CardCollection.EMPTY); + sa.clearLastState(); // PhaseHandler ph = game.getPhaseHandler(); // System.out.printf("Ai thinks '%s' of %s -> %s @ %s %s >>> \n", opinion, sa.getHostCard(), sa, Lang.getPossesive(ph.getPlayerTurn().getName()), ph.getPhase()); diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java index 308137f97e3..f2ca7b1972f 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java @@ -1406,6 +1406,39 @@ public class ComputerUtilCard { } } + if (keywords.contains("Banding") && !c.hasKeyword(Keyword.BANDING)) { + if (phase.is(PhaseType.COMBAT_BEGIN) && phase.isPlayerTurn(ai) && !ComputerUtilCard.doesCreatureAttackAI(ai, c)) { + // will this card participate in an attacking band? + Card bandingCard = getPumpedCreature(ai, sa, c, toughness, power, keywords); + // TODO: It may be possible to use AiController.getPredictedCombat here, but that makes it difficult to + // use reinforceWithBanding through the attack controller, especially with the extra card parameter in mind + AiAttackController aiAtk = new AiAttackController(ai); + Combat predicted = new Combat(ai); + aiAtk.declareAttackers(predicted); + aiAtk.reinforceWithBanding(predicted, bandingCard); + if (predicted.isAttacking(bandingCard) && predicted.getBandOfAttacker(bandingCard).getAttackers().size() > 1) { + return true; + } + } else if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS) && combat != null) { + // does this card block a Trample card or participate in a multi block? + for (Card atk : combat.getAttackers()) { + if (atk.getController().isOpponentOf(ai)) { + CardCollection blockers = combat.getBlockers(atk); + boolean hasBanding = false; + for (Card blocker : blockers) { + if (blocker.hasKeyword(Keyword.BANDING)) { + hasBanding = true; + break; + } + } + if (!hasBanding && ((blockers.contains(c) && blockers.size() > 1) || atk.hasKeyword(Keyword.TRAMPLE))) { + return true; + } + } + } + } + } + final Player opp = ai.getWeakestOpponent(); Card pumped = getPumpedCreature(ai, sa, c, toughness, power, keywords); List oppCreatures = opp.getCreaturesInPlay(); diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java index 4487a23b27c..db2f505d62f 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java @@ -17,26 +17,17 @@ */ package forge.ai; -import java.util.List; -import java.util.Map; - import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; - import forge.game.Game; import forge.game.GameEntity; import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; -import forge.game.card.Card; -import forge.game.card.CardCollection; -import forge.game.card.CardCollectionView; -import forge.game.card.CardLists; -import forge.game.card.CardPredicates; -import forge.game.card.CardUtil; -import forge.game.card.CounterEnumType; +import forge.game.card.*; +import forge.game.combat.AttackingBand; import forge.game.combat.Combat; import forge.game.combat.CombatUtil; import forge.game.cost.CostPayment; @@ -57,6 +48,9 @@ import forge.util.MyRandom; import forge.util.TextUtil; import forge.util.collect.FCollection; +import java.util.List; +import java.util.Map; + /** *

@@ -2023,6 +2017,8 @@ public class ComputerUtilCombat { * distributeAIDamage. *

* + * @param self + * a {@link forge.game.player.Player} object. * @param attacker * a {@link forge.game.card.Card} object. * @param block @@ -2031,16 +2027,20 @@ public class ComputerUtilCombat { * @param defender * @param overrideOrder overriding combatant order */ - public static Map distributeAIDamage(final Card attacker, final CardCollectionView block, final CardCollectionView remaining, int dmgCanDeal, GameEntity defender, boolean overrideOrder) { - // TODO: Distribute defensive Damage (AI controls how damage is dealt to own cards) for Banding and Defensive Formation + public static Map distributeAIDamage(final Player self, final Card attacker, final CardCollectionView block, final CardCollectionView remaining, int dmgCanDeal, GameEntity defender, boolean overrideOrder) { Map damageMap = Maps.newHashMap(); Combat combat = attacker.getGame().getCombat(); boolean isAttacking = defender != null; + // Check for Banding, Defensive Formation + boolean isAttackingMe = isAttacking && combat.getDefenderPlayerByAttacker(attacker).equals(self); + boolean isBlockingMyBand = attacker.getController().isOpponentOf(self) && AttackingBand.isValidBand(block, true); + final boolean aiDistributesBandingDmg = isAttackingMe || isBlockingMyBand; + final boolean hasTrample = attacker.hasKeyword(Keyword.TRAMPLE); - if (combat != null && remaining != null && hasTrample && attacker.isAttacking()) { + if (combat != null && remaining != null && hasTrample && attacker.isAttacking() && !aiDistributesBandingDmg) { // if attacker has trample and some of its blockers are also blocking others it's generally a good idea // to assign those without trample first so we can maximize the damage to the defender for (final Card c : remaining) { @@ -2061,7 +2061,7 @@ public class ComputerUtilCombat { final Card blocker = block.getFirst(); int dmgToBlocker = dmgCanDeal; - if (hasTrample && isAttacking) { // otherwise no entity to deliver damage via trample + if (hasTrample && isAttacking && !aiDistributesBandingDmg) { // otherwise no entity to deliver damage via trample dmgToBlocker = getEnoughDamageToKill(blocker, dmgCanDeal, attacker, true); if (dmgCanDeal < dmgToBlocker) { @@ -2077,7 +2077,7 @@ public class ComputerUtilCombat { } damageMap.put(blocker, dmgToBlocker); } // 1 blocker - else { + else if (!aiDistributesBandingDmg) { // Does the attacker deal lethal damage to all blockers //Blocking Order now determined after declare blockers Card lastBlocker = null; @@ -2098,13 +2098,26 @@ public class ComputerUtilCombat { } } // for - if (dmgCanDeal > 0 ) { // if any damage left undistributed, + if (dmgCanDeal > 0) { // if any damage left undistributed, if (hasTrample && isAttacking) // if you have trample, deal damage to defending entity damageMap.put(null, dmgCanDeal); else if (lastBlocker != null) { // otherwise flush it into last blocker damageMap.put(lastBlocker, dmgCanDeal + damageMap.get(lastBlocker)); } } + } else { + // In the event of Banding or Defensive Formation, assign max damage to the blocker who + // can tank all the damage or to the worst blocker to lose as little as possible + for (final Card b : block) { + final int dmgToKill = getEnoughDamageToKill(b, dmgCanDeal, attacker, true); + if (dmgToKill > dmgCanDeal) { + damageMap.put(b, dmgCanDeal); + break; + } + } + if (damageMap.isEmpty()) { + damageMap.put(ComputerUtilCard.getWorstCreatureAI(block), dmgCanDeal); + } } return damageMap; } diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java index a0636a9d475..1505459ca3f 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java @@ -962,7 +962,12 @@ public class ComputerUtilMana { ManaCostShard toPay, SpellAbility saPayment) { AbilityManaPart m = saPayment.getManaPart(); if (m.isComboMana()) { - m.setExpressChoice(ColorSet.fromMask(toPay.getColorMask())); + // usually we'll want to produce color that matches the shard + ColorSet shared = ColorSet.fromMask(toPay.getColorMask()).getSharedColors(ColorSet.fromNames(m.getComboColors(saPayment).split(" "))); + // but other effects might still lead to a more permissive payment + if (!shared.isColorless()) { + m.setExpressChoice(ColorSet.fromMask(shared.iterator().next())); + } getComboManaChoice(ai, saPayment, sa, cost); } else if (saPayment.getApi() == ApiType.ManaReflected) { diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index d8b7f053ffd..5b2e1834c62 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -106,7 +106,7 @@ public class PlayerControllerAi extends PlayerController { @Override public Map assignCombatDamage(Card attacker, CardCollectionView blockers, CardCollectionView remaining, int damageDealt, GameEntity defender, boolean overrideOrder) { - return ComputerUtilCombat.distributeAIDamage(attacker, blockers, remaining, damageDealt, defender, overrideOrder); + return ComputerUtilCombat.distributeAIDamage(player, attacker, blockers, remaining, damageDealt, defender, overrideOrder); } @Override diff --git a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java index da837478f35..92385a56eee 100644 --- a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java +++ b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java @@ -651,6 +651,21 @@ public class SpecialCardAi { } } + // Grothama, All-Devouring + public static class GrothamaAllDevouring { + public static boolean consider(final Player ai, final SpellAbility sa) { + final Card source = sa.getHostCard(); + final Card devourer = AbilityUtils.getDefinedCards(source, sa.getParam("ExtraDefined"), sa).getFirst(); // maybe just getOriginalHost()? + if (ai.getTeamMates(true).contains(devourer.getController())) { + return false; // TODO: Currently, the AI doesn't ever fight its own (or allied) Grothama for card draw. This can be improved. + } + final Card fighter = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa).getFirst(); + boolean goodTradeOrNoTrade = devourer.canBeDestroyed() && (devourer.getNetPower() < fighter.getNetToughness() || !fighter.canBeDestroyed() + || ComputerUtilCard.evaluateCreature(devourer) > ComputerUtilCard.evaluateCreature(fighter)); + return goodTradeOrNoTrade && fighter.getNetPower() >= devourer.getNetToughness(); + } + } + // Guilty Conscience public static class GuiltyConscience { public static Card getBestAttachTarget(final Player ai, final SpellAbility sa, final List list) { diff --git a/forge-ai/src/main/java/forge/ai/ability/ControlGainAi.java b/forge-ai/src/main/java/forge/ai/ability/ControlGainAi.java index efcfb81d930..9785a0b665c 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ControlGainAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ControlGainAi.java @@ -112,7 +112,7 @@ public class ControlGainAi extends SpellAbilityAi { // Don't steal something if I can't Attack without, or prevent it from blocking at least if (lose.contains("EOT") - && ai.getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) + && game.getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) && !sa.isTrigger()) { return false; } diff --git a/forge-ai/src/main/java/forge/ai/ability/CounterAi.java b/forge-ai/src/main/java/forge/ai/ability/CounterAi.java index 1c175905e1f..669e89903f9 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CounterAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CounterAi.java @@ -144,7 +144,7 @@ public class CounterAi extends SpellAbilityAi { String logic = sa.getParam("AILogic"); if ("Never".equals(logic)) { return false; - } else if (logic.startsWith("MinCMC.")) { + } else if (logic.startsWith("MinCMC.")) { // TODO fix Daze and fold into AITgts int minCMC = Integer.parseInt(logic.substring(7)); if (tgtCMC < minCMC) { return false; diff --git a/forge-ai/src/main/java/forge/ai/ability/DebuffAi.java b/forge-ai/src/main/java/forge/ai/ability/DebuffAi.java index 877f6a6284c..02fc95813d7 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DebuffAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DebuffAi.java @@ -59,8 +59,8 @@ public class DebuffAi extends SpellAbilityAi { || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS) || !game.getStack().isEmpty()) { // Instant-speed pumps should not be cast outside of combat when the - // stack is empty - if (!SpellAbilityAi.isSorcerySpeed(sa, ai)) { + // stack is empty, unless there are specific activation phase requirements + if (!SpellAbilityAi.isSorcerySpeed(sa, ai) && !sa.hasParam("ActivationPhases")) { return false; } } diff --git a/forge-ai/src/main/java/forge/ai/ability/FightAi.java b/forge-ai/src/main/java/forge/ai/ability/FightAi.java index 4a3765d8111..3d1eb307a79 100644 --- a/forge-ai/src/main/java/forge/ai/ability/FightAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/FightAi.java @@ -2,11 +2,7 @@ package forge.ai.ability; import java.util.List; -import forge.ai.ComputerUtil; -import forge.ai.ComputerUtilAbility; -import forge.ai.ComputerUtilCard; -import forge.ai.ComputerUtilCombat; -import forge.ai.SpellAbilityAi; +import forge.ai.*; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.card.Card; @@ -32,9 +28,13 @@ public class FightAi extends SpellAbilityAi { sa.resetTargets(); final Card source = sa.getHostCard(); - // everything is defined or targeted above, can't do anything there? + // everything is defined or targeted above, can't do anything there unless a specific logic is set if (sa.hasParam("Defined") && !sa.usesTargeting()) { - // TODO extend Logic for cards like Arena or Grothama + // TODO extend Logic for cards like Arena + if ("Grothama".equals(sa.getParam("AILogic"))) { // Grothama, All-Devouring + return SpecialCardAi.GrothamaAllDevouring.consider(ai, sa); + } + return true; } @@ -120,7 +120,7 @@ public class FightAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - if (canPlayAI(ai, sa)) { + if (checkApiLogic(ai, sa)) { return true; } if (!mandatory) { diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 7097c55a907..e016bd951f8 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -223,7 +223,7 @@ public class GameAction { // Don't copy Tokens, copy only cards leaving the battlefield // and returning to hand (to recreate their spell ability information) - if (suppress || toBattlefield) { + if (toBattlefield || (suppress && zoneTo.getZoneType().isHidden())) { copied = c; if (lastKnownInfo == null) { @@ -295,7 +295,6 @@ public class GameAction { } copied.setUnearthed(c.isUnearthed()); - copied.setTapped(false); // need to copy counters when card enters another zone than hand or library if (lastKnownInfo.hasKeyword("Counters remain on CARDNAME as it moves to any zone other than a player's hand or library.") && @@ -386,7 +385,7 @@ public class GameAction { } } - if (!zoneTo.is(ZoneType.Stack) && !suppress) { + if (!zoneTo.is(ZoneType.Stack)) { // reset timestamp in changezone effects so they have same timestamp if ETB simultaneously copied.setTimestamp(game.getNextTimestamp()); } @@ -600,7 +599,7 @@ public class GameAction { } // only now that the LKI preserved it - if (!zoneTo.is(ZoneType.Exile) && !zoneTo.is(ZoneType.Stack)) { + if (!zoneTo.is(ZoneType.Stack)) { c.cleanupExiledWith(); } @@ -636,7 +635,6 @@ public class GameAction { } game.getTriggerHandler().runTrigger(TriggerType.ChangesController, runParams2, false); } - // AllZone.getStack().chooseOrderOfSimultaneousStackEntryAll(); if (suppress) { game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone); @@ -923,10 +921,6 @@ public class GameAction { return result; } public final Card exile(final Card c, SpellAbility cause, Map params) { - if (game.isCardExiled(c)) { - return c; - } - final Zone origin = c.getZone(); final PlayerZone removed = c.getOwner().getZone(ZoneType.Exile); final Card copied = moveTo(removed, c, cause, params); diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index da0f0f27f87..7726682a192 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -561,9 +561,6 @@ public class AbilityUtils { } } else if (calcX[0].equals("OriginalHost")) { val = xCount(ability.getOriginalHost(), calcX[1], ability); - } else if (calcX[0].equals("LastStateBattlefield") && ability instanceof SpellAbility) { - Card c = ((SpellAbility) ability).getLastStateBattlefield().get(card); - val = c == null ? 0 : xCount(c, calcX[1], ability); } else if (calcX[0].startsWith("ExiledWith")) { val = handlePaid(card.getExiledCards(), calcX[1], card, ability); } else if (calcX[0].startsWith("Convoked")) { diff --git a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java index 96ecb57f0b6..d6918135c25 100644 --- a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java @@ -393,11 +393,16 @@ public abstract class SpellAbilityEffect { } public static void addForgetOnMovedTrigger(final Card card, final String zone) { - String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ " + zone + " | ExcludedDestinations$ Stack | Destination$ Any | TriggerZones$ Command | Static$ True"; + String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ " + zone + " | ExcludedDestinations$ Stack,Exile | Destination$ Any | TriggerZones$ Command | Static$ True"; + String trig2 = "Mode$ Exiled | ValidCard$ Card.IsRemembered | TriggerZones$ Command | Static$ True"; final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true); - parsedTrigger.setOverridingAbility(getForgetSpellAbility(card)); + final Trigger parsedTrigger2 = TriggerHandler.parseTrigger(trig2, card, true); + SpellAbility forget = getForgetSpellAbility(card); + parsedTrigger.setOverridingAbility(forget); + parsedTrigger2.setOverridingAbility(forget); card.addTrigger(parsedTrigger); + card.addTrigger(parsedTrigger2); } protected static void addForgetOnCastTrigger(final Card card) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java index 915fa92dfc8..0aff84600ee 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java @@ -122,9 +122,8 @@ public class SacrificeEffect extends SpellAbilityEffect { String [] msgArray = msg.split(" & "); List validTargetsList = new ArrayList<>(validArray.length); for (String subValid : validArray) { - CardCollectionView validTargets = AbilityUtils.filterListByType(battlefield, subValid, sa); - validTargets = CardLists.filter(validTargets, CardPredicates.canBeSacrificedBy(sa, true)); - validTargetsList.add(new CardCollection(validTargets)); + CardCollection validTargets = CardLists.filter(AbilityUtils.filterListByType(battlefield, subValid, sa), CardPredicates.canBeSacrificedBy(sa, true)); + validTargetsList.add(validTargets); } CardCollection chosenCards = new CardCollection(); for (int i = 0; i < validArray.length; ++i) { diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 5b5e9b24346..0f9dbc5211f 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -523,7 +523,13 @@ public class CardFactoryUtil { public static List sharedKeywords(final Iterable kw, final String[] restrictions, final Iterable zones, final Card host, CardTraitBase ctb) { final List filteredkw = Lists.newArrayList(); - final Player p = host.getController(); + Player p = null; + if (ctb instanceof SpellAbility) { + p = ((SpellAbility)ctb).getActivatingPlayer(); + } + if (p == null) { + p = host.getController(); + } CardCollectionView cardlist = p.getGame().getCardsIn(zones); final Set landkw = Sets.newHashSet(); final Set protectionkw = Sets.newHashSet(); diff --git a/forge-game/src/main/java/forge/game/combat/AttackingBand.java b/forge-game/src/main/java/forge/game/combat/AttackingBand.java index e509c577361..56aa6b296bf 100644 --- a/forge-game/src/main/java/forge/game/combat/AttackingBand.java +++ b/forge-game/src/main/java/forge/game/combat/AttackingBand.java @@ -1,14 +1,13 @@ package forge.game.combat; -import java.util.ArrayList; -import java.util.List; - import forge.game.card.Card; import forge.game.card.CardCollection; import forge.game.card.CardCollectionView; import forge.game.card.CardLists; import forge.game.keyword.Keyword; +import java.util.List; + public class AttackingBand { private CardCollection attackers = new CardCollection(); private Boolean blocked = null; // even if all blockers were killed before FS or CD, band remains blocked @@ -26,7 +25,7 @@ public class AttackingBand { public void addAttacker(Card card) { attackers.add(card); } public void removeAttacker(Card card) { attackers.remove(card); } - public static boolean isValidBand(List band, boolean shareDamage) { + public static boolean isValidBand(CardCollectionView band, boolean shareDamage) { if (band.isEmpty()) { // An empty band is not a valid band return false; @@ -64,7 +63,7 @@ public class AttackingBand { public boolean canJoinBand(Card card) { // Trying to join an existing band, attackers should be non-empty and card should exist - List newBand = new ArrayList<>(attackers); + CardCollection newBand = new CardCollection(attackers); if (card != null) { newBand.add(card); } diff --git a/forge-game/src/main/java/forge/game/combat/CombatUtil.java b/forge-game/src/main/java/forge/game/combat/CombatUtil.java index 4e758170131..39f5e273772 100644 --- a/forge-game/src/main/java/forge/game/combat/CombatUtil.java +++ b/forge-game/src/main/java/forge/game/combat/CombatUtil.java @@ -1126,7 +1126,7 @@ public class CombatUtil { if (!canBlock(blocker, nextTurn)) { return false; } - + if (isUnblockableFromLandwalk(attacker, blocker.getController()) && !blocker.hasKeyword("CARDNAME can block creatures with landwalk abilities as though they didn't have those abilities.")) { return false; diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index abd4461d02d..fbfe4c1a214 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -327,7 +327,6 @@ public class Player extends GameEntity implements Comparable { game.getTriggerHandler().suppressMode(TriggerType.ChangesZone); activeScheme = getZone(ZoneType.SchemeDeck).get(0); - // gameAction moveTo ? game.getAction().moveTo(ZoneType.Command, activeScheme, null, moveParams); game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone); @@ -800,7 +799,7 @@ public class Player extends GameEntity implements Comparable { restDamage = 2; } } else if (c.getName().equals("Elderscale Wurm")) { - if (c.getController().equals(this) && getLife() - restDamage < 7) { + if (c.getController().equals(this) && getLife() >= 7 && getLife() - restDamage < 7) { restDamage = getLife() - 7; if (restDamage < 0) { restDamage = 0; @@ -3268,9 +3267,7 @@ public class Player extends GameEntity implements Comparable { } final TriggerHandler triggerHandler = game.getTriggerHandler(); - triggerHandler.suppressMode(TriggerType.ChangesZone); - game.getAction().moveTo(ZoneType.Command, initiativeEffect, null, null); - triggerHandler.clearSuppression(TriggerType.ChangesZone); + com.add(initiativeEffect); triggerHandler.clearActiveTriggers(initiativeEffect, null); triggerHandler.registerActiveTrigger(initiativeEffect, false); diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java index 37ccfd8ed42..2d2d322951a 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java @@ -231,7 +231,7 @@ public class ReplacementHandler { chosenRE.setHasRun(true); hasRun.add(chosenRE); chosenRE.setOtherChoices(possibleReplacers); - ReplacementResult res = executeReplacement(runParams, chosenRE, decider, game); + ReplacementResult res = executeReplacement(runParams, chosenRE, decider); if (res == ReplacementResult.NotReplaced) { if (!possibleReplacers.isEmpty()) { res = run(event, runParams); @@ -287,8 +287,7 @@ public class ReplacementHandler { * the replacement effect to run */ private ReplacementResult executeReplacement(final Map runParams, - final ReplacementEffect replacementEffect, final Player decider, final Game game) { - + final ReplacementEffect replacementEffect, final Player decider) { SpellAbility effectSA = null; Card host = replacementEffect.getHostCard(); @@ -441,7 +440,7 @@ public class ReplacementHandler { int damage = (int) runParams.get(AbilityKey.DamageAmount); Map mapParams = re.getMapParams(); - ReplacementResult res = executeReplacement(runParams, re, decider, game); + ReplacementResult res = executeReplacement(runParams, re, decider); GameEntity newTarget = (GameEntity) runParams.get(AbilityKey.Affected); int newDamage = (int) runParams.get(AbilityKey.DamageAmount); diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index c2673f0d8be..66ab466585d 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -201,6 +201,11 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit this.lastStateGraveyard = new CardCollection(lastStateGraveyard); } + public void clearLastState() { + lastStateBattlefield = null; + lastStateGraveyard = null; + } + protected SpellAbility(final Card iSourceCard, final Cost toPay) { this(iSourceCard, toPay, null); } @@ -828,10 +833,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit if (isActivatedAbility()) { setXManaCostPaid(null); } - - // reset last state when finished resolving - setLastStateBattlefield(CardCollection.EMPTY); - setLastStateGraveyard(CardCollection.EMPTY); } // key for autoyield - the card description (including number) (if there is a card) plus the effect description diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbilityCondition.java b/forge-game/src/main/java/forge/game/spellability/SpellAbilityCondition.java index 34e7a416ca7..e98bd969b8c 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbilityCondition.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbilityCondition.java @@ -243,7 +243,7 @@ public class SpellAbilityCondition extends SpellAbilityVariables { if (params.containsKey("ConditionTargetsSingleTarget")) { this.setTargetsSingleTarget(true); } - } // setConditions + } /** *

diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java b/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java index c0234a7c059..6dcc8ba06a3 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java @@ -189,7 +189,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables { this.setClassLevelOperator(params.get("ClassLevel").substring(0, 2)); this.setClassLevel(params.get("ClassLevel").substring(2)); } - } // end setRestrictions() + } /** *

diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java index ad3ca9af8db..566eb0ef116 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java @@ -528,9 +528,6 @@ public class TriggerHandler { sa = sa.copy(host, controller, false); } - sa.setLastStateBattlefield(game.getLastStateBattlefield()); - sa.setLastStateGraveyard(game.getLastStateGraveyard()); - sa.setTrigger(regtrig); sa.setSourceTrigger(regtrig.getId()); regtrig.setTriggeringObjects(sa, runParams); @@ -565,7 +562,6 @@ public class TriggerHandler { //wrapperAbility.setDescription(wrapperAbility.getStackDescription()); //wrapperAbility.setDescription(wrapperAbility.toUnsuppressedString()); - wrapperAbility.setLastStateBattlefield(game.getLastStateBattlefield()); if (regtrig.isStatic()) { wrapperAbility.getActivatingPlayer().getController().playTrigger(host, wrapperAbility, isMandatory); } else { diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCastOrCopy.java b/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCastOrCopy.java index 130ae4bbce7..4e21b9f876d 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCastOrCopy.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCastOrCopy.java @@ -279,11 +279,12 @@ public class TriggerSpellAbilityCastOrCopy extends Trigger { sa.setTriggeringObject(AbilityKey.LifeAmount, castSA.getAmountLifePaid()); sa.setTriggeringObjectsFrom( runParams, - AbilityKey.Player, - AbilityKey.Activator, - AbilityKey.CurrentStormCount, - AbilityKey.CurrentCastSpells - ); + AbilityKey.CardLKI, + AbilityKey.Player, + AbilityKey.Activator, + AbilityKey.CurrentStormCount, + AbilityKey.CurrentCastSpells + ); } @Override diff --git a/forge-game/src/main/java/forge/game/zone/MagicStack.java b/forge-game/src/main/java/forge/game/zone/MagicStack.java index 1a5ddd04159..8f9d1b30ed0 100644 --- a/forge-game/src/main/java/forge/game/zone/MagicStack.java +++ b/forge-game/src/main/java/forge/game/zone/MagicStack.java @@ -44,7 +44,6 @@ import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.card.Card; -import forge.game.card.CardCollection; import forge.game.card.CardUtil; import forge.game.event.EventValueChangeType; import forge.game.event.GameEventCardStatsChanged; @@ -321,6 +320,14 @@ public class MagicStack /* extends MyObservable */ implements Iterable runParams = AbilityKey.mapFromPlayer(sp.getHostCard().getController()); + + if (sp.isSpell() && !sp.isCopied()) { + final Card lki = CardUtil.getLKICopy(sp.getHostCard()); + runParams.put(AbilityKey.CardLKI, lki); + thisTurnCast.add(lki); + sp.getActivatingPlayer().addSpellCastThisTurn(); + } + runParams.put(AbilityKey.Cost, sp.getPayCosts()); runParams.put(AbilityKey.Activator, sp.getActivatingPlayer()); runParams.put(AbilityKey.CastSA, si.getSpellAbility(true)); @@ -462,10 +469,6 @@ public class MagicStack /* extends MyObservable */ implements Iterable getMusic(MusicPlaylist playlist) { - FileHandle file = Gdx.files.absolute(playlist.getNewRandomFilename()); + String filename = playlist.getNewRandomFilename(); + if (filename == null) + return null; + FileHandle file = Gdx.files.absolute(filename); Music music = Forge.getAssets().getMusic(file); if (music != null) { currentAudioPlaylist = playlist; @@ -776,7 +781,7 @@ public class GameHUD extends Stage { changeBGM(MusicPlaylist.WHITE); break; case "waste": - changeBGM(MusicPlaylist.MENUS); + changeBGM(MusicPlaylist.COLORLESS); break; default: break; diff --git a/forge-gui/res/adventure/Shandalar/world/world.json b/forge-gui/res/adventure/Shandalar/world/world.json index f57c8eb4d90..60a70832fb3 100644 --- a/forge-gui/res/adventure/Shandalar/world/world.json +++ b/forge-gui/res/adventure/Shandalar/world/world.json @@ -15,7 +15,7 @@ "maxRoadDistance": 1000, "biomesNames": [ "world/biomes/base.json", - "world/biomes/waste.json", + "world/biomes/colorless.json", "world/biomes/white.json", "world/biomes/blue.json", "world/biomes/black.json", diff --git a/forge-gui/res/adventure/Shandalar/music/black/black1.mp3 b/forge-gui/res/adventure/common/music/black/black1.mp3 similarity index 100% rename from forge-gui/res/adventure/Shandalar/music/black/black1.mp3 rename to forge-gui/res/adventure/common/music/black/black1.mp3 diff --git a/forge-gui/res/adventure/Shandalar/music/blue/blue1.mp3 b/forge-gui/res/adventure/common/music/blue/blue1.mp3 similarity index 100% rename from forge-gui/res/adventure/Shandalar/music/blue/blue1.mp3 rename to forge-gui/res/adventure/common/music/blue/blue1.mp3 diff --git a/forge-gui/res/adventure/Shandalar/music/boss/boss1.mp3 b/forge-gui/res/adventure/common/music/boss/boss1.mp3 similarity index 100% rename from forge-gui/res/adventure/Shandalar/music/boss/boss1.mp3 rename to forge-gui/res/adventure/common/music/boss/boss1.mp3 diff --git a/forge-gui/res/adventure/Shandalar/music/boss/boss2.mp3 b/forge-gui/res/adventure/common/music/boss/boss2.mp3 similarity index 100% rename from forge-gui/res/adventure/Shandalar/music/boss/boss2.mp3 rename to forge-gui/res/adventure/common/music/boss/boss2.mp3 diff --git a/forge-gui/res/adventure/Shandalar/music/castle/castle1.mp3 b/forge-gui/res/adventure/common/music/castle/castle1.mp3 similarity index 100% rename from forge-gui/res/adventure/Shandalar/music/castle/castle1.mp3 rename to forge-gui/res/adventure/common/music/castle/castle1.mp3 diff --git a/forge-gui/res/adventure/Shandalar/music/cave/cave1.mp3 b/forge-gui/res/adventure/common/music/cave/cave1.mp3 similarity index 100% rename from forge-gui/res/adventure/Shandalar/music/cave/cave1.mp3 rename to forge-gui/res/adventure/common/music/cave/cave1.mp3 diff --git a/forge-gui/res/adventure/Shandalar/music/menus/menu1.mp3 b/forge-gui/res/adventure/common/music/colorless/menu1.mp3 similarity index 100% rename from forge-gui/res/adventure/Shandalar/music/menus/menu1.mp3 rename to forge-gui/res/adventure/common/music/colorless/menu1.mp3 diff --git a/forge-gui/res/adventure/Shandalar/music/green/green1.mp3 b/forge-gui/res/adventure/common/music/green/green1.mp3 similarity index 100% rename from forge-gui/res/adventure/Shandalar/music/green/green1.mp3 rename to forge-gui/res/adventure/common/music/green/green1.mp3 diff --git a/forge-gui/res/adventure/Shandalar/music/match/match1.mp3 b/forge-gui/res/adventure/common/music/match/match1.mp3 similarity index 100% rename from forge-gui/res/adventure/Shandalar/music/match/match1.mp3 rename to forge-gui/res/adventure/common/music/match/match1.mp3 diff --git a/forge-gui/res/adventure/Shandalar/music/match/match2.mp3 b/forge-gui/res/adventure/common/music/match/match2.mp3 similarity index 100% rename from forge-gui/res/adventure/Shandalar/music/match/match2.mp3 rename to forge-gui/res/adventure/common/music/match/match2.mp3 diff --git a/forge-gui/res/adventure/Shandalar/music/match/match3.mp3 b/forge-gui/res/adventure/common/music/match/match3.mp3 similarity index 100% rename from forge-gui/res/adventure/Shandalar/music/match/match3.mp3 rename to forge-gui/res/adventure/common/music/match/match3.mp3 diff --git a/forge-gui/res/adventure/common/music/menus/menu1.mp3 b/forge-gui/res/adventure/common/music/menus/menu1.mp3 new file mode 100644 index 00000000000..539fe0131af Binary files /dev/null and b/forge-gui/res/adventure/common/music/menus/menu1.mp3 differ diff --git a/forge-gui/res/adventure/Shandalar/music/red/red1.mp3 b/forge-gui/res/adventure/common/music/red/red1.mp3 similarity index 100% rename from forge-gui/res/adventure/Shandalar/music/red/red1.mp3 rename to forge-gui/res/adventure/common/music/red/red1.mp3 diff --git a/forge-gui/res/adventure/Shandalar/music/town/town1.mp3 b/forge-gui/res/adventure/common/music/town/town1.mp3 similarity index 100% rename from forge-gui/res/adventure/Shandalar/music/town/town1.mp3 rename to forge-gui/res/adventure/common/music/town/town1.mp3 diff --git a/forge-gui/res/adventure/Shandalar/music/white/white1.mp3 b/forge-gui/res/adventure/common/music/white/white1.mp3 similarity index 100% rename from forge-gui/res/adventure/Shandalar/music/white/white1.mp3 rename to forge-gui/res/adventure/common/music/white/white1.mp3 diff --git a/forge-gui/res/adventure/common/world/biomes/black.json b/forge-gui/res/adventure/common/world/biomes/black.json index aee2248968c..5815a3276c6 100644 --- a/forge-gui/res/adventure/common/world/biomes/black.json +++ b/forge-gui/res/adventure/common/world/biomes/black.json @@ -23,11 +23,8 @@ "height": 0.7, "color": "110903", "spriteNames": [ - "SwampTree", - "SwampTree2", "DarkGras", "Skull", - "SwampRock", "DarkWood", "Reed", "Waterlily", @@ -120,22 +117,46 @@ "N": 2, "x": 0.5, "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", - "sourcePath": "world/models/swamp_forest.png", - "maskPath": "world/masks/ring.png", + "structureAtlasPath": "world/structures/black_structures.atlas", + "sourcePath": "world/structures/models/black.png", + "maskPath": "world/structures/masks/ring.png", "height": 0.5, "width": 0.5, "symmetry": 8, - "periodicOutput": false, "mappingInfo": [ { - "name": "swamp_forest", - "color": "007000", + "name": "water", + "color": "00ffff", "collision": true }, { - "name": "swamp_water", - "color": "005050", + "name": "tree", + "color": "004000", + "collision": true + }, + { + "name": "tree2", + "color": "008000", + "collision": true + }, + { + "name": "tree3", + "color": "ff00ff", + "collision": true + }, + { + "name": "tree4", + "color": "00f000", + "collision": true + }, + { + "name": "rock", + "color": "808080", + "collision": true + }, + { + "name": "rock2", + "color": "ff0000", "collision": true } ] @@ -144,27 +165,41 @@ "N": 2, "x": 0.5, "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", - "sourcePath": "world/models/swamp_ruins.png", - "maskPath": "world/masks/circle.png", + "structureAtlasPath": "world/structures/black_structures.atlas", + "sourcePath": "world/structures/models/black.png", + "maskPath": "world/structures/masks/circle.png", "height": 0.20000002, "width": 0.20000002, - "symmetry": 1, - "periodicOutput": false, + "symmetry": 8, "mappingInfo": [ { - "name": "deep_swamp", - "color": "002000", + "name": "muck", + "color": "00ffff", "collision": true }, { - "name": "structure", - "color": "505050", + "name": "dead_tree", + "color": "004000", "collision": true }, { - "name": "swamp_forest2", - "color": "007000", + "name": "dead_tree2", + "color": "008000", + "collision": true + }, + { + "name": "dead_tree3", + "color": "ff00ff", + "collision": true + }, + { + "name": "rock", + "color": "808080", + "collision": true + }, + { + "name": "rock2", + "color": "ff0000", "collision": true } ] diff --git a/forge-gui/res/adventure/common/world/biomes/blue.json b/forge-gui/res/adventure/common/world/biomes/blue.json index 473a447e1fb..9914d918d23 100644 --- a/forge-gui/res/adventure/common/world/biomes/blue.json +++ b/forge-gui/res/adventure/common/world/biomes/blue.json @@ -23,8 +23,6 @@ "height": 0.7, "color": "10a2e0", "spriteNames": [ - "IslandTree", - "Coral", "Shell" ], "enemies": [ @@ -108,47 +106,93 @@ ], "structures": [ { + "N":2, "x": 0.5, "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", - "sourcePath": "world/models/water.png", - "maskPath": "world/masks/circle.png", - "height": 0.20000002, - "width": 0.20000002, + "structureAtlasPath": "world/structures/blue_structures.atlas", + "sourcePath": "world/structures/models/blue.png", + "maskPath": "world/structures/masks/circle.png", + "height": 0.1, + "width": 0.1, "symmetry": 8, "periodicOutput": false, "mappingInfo": [ { "name": "water", - "color": "0070a0", + "color": "00ffff", "collision": true }, { - "name": "island_forest", - "color": "00a000", + "name": "tree", + "color": "00ff00", + "collision": true + }, + { + "name": "tree2", + "color": "008000", + "collision": true + }, + { + "name": "pineapple", + "color": "ffff00", + "collision": true + }, + { + "name": "rock", + "color": "ff8000", + "collision": true + }, + { + "name": "rock2", + "color": "804000", + "collision": true + }, + { + "name": "rock3", + "color": "402000", + "collision": true + }, + { + "name": "rock4", + "color": "201000", "collision": true } ] }, { + "N": 2, "x": 0.5, "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", - "sourcePath": "world/models/island_forest.png", - "maskPath": "world/masks/ring.png", + "structureAtlasPath": "world/structures/blue_structures.atlas", + "sourcePath": "world/structures/models/beach.png", + "maskPath": "world/structures/masks/ring.png", "height": 0.5, "width": 0.5, "symmetry": 8, - "periodicOutput": false, "mappingInfo": [ { "name": "water", - "color": "0070a0", + "color": "00ffff", "collision": true }, { - "name": "island_forest", - "color": "00a000", + "name": "tree", + "color": "00ff00", + "collision": true + }, + { + "name": "tree2", + "color": "008000", + "collision": true + }, + { + "name": "dune", + "color": "ff8000", + "collision": true + }, + { + "name": "dune2", + "color": "402000", "collision": true } ] diff --git a/forge-gui/res/adventure/common/world/biomes/waste.json b/forge-gui/res/adventure/common/world/biomes/colorless.json similarity index 56% rename from forge-gui/res/adventure/common/world/biomes/waste.json rename to forge-gui/res/adventure/common/world/biomes/colorless.json index c93077309c7..41424b80af7 100644 --- a/forge-gui/res/adventure/common/world/biomes/waste.json +++ b/forge-gui/res/adventure/common/world/biomes/colorless.json @@ -5,15 +5,15 @@ "distWeight": 1, "name": "waste", "tilesetAtlas": "world/tilesets/terrain.atlas", -"tilesetName": "Waste", +"tilesetName": "Colorless", "terrain": [ { - "spriteName": "Waste_1", + "spriteName": "Colorless_1", "max": 0.2, "resolution": 5 }, { - "spriteName": "Waste_2", + "spriteName": "Colorless_2", "min": 0.8, "max": 1, "resolution": 5 @@ -23,9 +23,7 @@ "height": 0.85, "color": "aeaeae", "spriteNames": [ - "WasteTree", - "Stone", - "WasteRock" + "Stone" ], "enemies": [ "Adept Black Wizard", @@ -118,44 +116,94 @@ "N": 2, "x": 0.5, "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", - "sourcePath": "world/models/waste_structure.png", - "maskPath": "world/masks/circle.png", - "periodicInput": false, - "height": 0.20000002, - "width": 0.20000002, - "symmetry": 4, + "structureAtlasPath": "world/structures/colorless_structures.atlas", + "sourcePath": "world/structures/models/colorless.png", + "maskPath": "world/structures/masks/circle.png", + "height": 0.25, + "width": 0.25, + "symmetry": 8, "mappingInfo": [ { - "name": "waste_structure", - "color": "444444", + "name": "crater", + "color": "808080", "collision": true }, { - "name": "waste_mountain", - "color": "9a9a9a", + "name": "tree", + "color": "ff0000", + "collision": true + }, + { + "name": "tree2", + "color": "00ff00", + "collision": true + }, + { + "name": "tree3", + "color": "0000ff", + "collision": true + }, + { + "name": "tree4", + "color": "00ffff", + "collision": true + }, + { + "name": "rock", + "color": "ff00ff", + "collision": true + }, + { + "name": "mountain", + "color": "000000", "collision": true } ] }, { + "N": 2, "x": 0.5, "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", - "sourcePath": "world/models/hole.png", - "maskPath": "world/masks/ring.png", + "structureAtlasPath": "world/structures/colorless_structures.atlas", + "sourcePath": "world/structures/models/colorless.png", + "maskPath": "world/structures/masks/ring.png", "height": 0.5, "width": 0.5, - "periodicOutput": false, + "symmetry": 8, "mappingInfo": [ { "name": "hole", - "color": "111111", + "color": "808080", "collision": true }, { - "name": "waste_mountain", - "color": "9a9a9a", + "name": "tree", + "color": "ff0000", + "collision": true + }, + { + "name": "tree2", + "color": "00ff00", + "collision": true + }, + { + "name": "tree3", + "color": "0000ff", + "collision": true + }, + { + "name": "tree4", + "color": "00ffff", + "collision": true + }, + { + "name": "rock", + "color": "ff00ff", + "collision": true + }, + { + "name": "mountain", + "color": "000000", "collision": true } ] diff --git a/forge-gui/res/adventure/common/world/biomes/green.json b/forge-gui/res/adventure/common/world/biomes/green.json index 27cc104a4b3..d57989463d0 100644 --- a/forge-gui/res/adventure/common/world/biomes/green.json +++ b/forge-gui/res/adventure/common/world/biomes/green.json @@ -23,9 +23,6 @@ "height": 0.7, "color": "59a650", "spriteNames": [ - "WoodTree", - "WoodTree2", - "Bush", "Stump", "Moss", "Stone", @@ -122,39 +119,66 @@ "N": 2, "x": 0.5, "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", - "sourcePath": "world/models/forest.png", - "maskPath": "world/masks/circle.png", - "height": 0.20000002, - "width": 0.20000002, + "structureAtlasPath": "world/structures/green_structures.atlas", + "sourcePath": "world/structures/models/green.png", + "maskPath": "world/structures/masks/circle.png", + "height": 0.5, + "width": 0.5, "symmetry": 1, "mappingInfo": [ { - "name": "forest", - "color": "007000", - "collision": true - } - ] - }, - { - "N": 2, - "x": 0.5, - "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", - "sourcePath": "world/models/lake.png", - "maskPath": "world/masks/ring.png", - "height": 0.5, - "width": 0.5, - "periodicOutput": false, - "mappingInfo": [ - { - "name": "lake", - "color": "0070a0", + "name": "water", + "color": "000080", "collision": true }, { - "name": "forest2", - "color": "009000", + "name": "tree", + "color": "008000", + "collision": true + }, + { + "name": "tree2", + "color": "004000", + "collision": true + }, + { + "name": "vine", + "color": "8080ff", + "collision": true + }, + { + "name": "tree3", + "color": "00c000", + "collision": true + }, + { + "name": "tree4", + "color": "00f000", + "collision": true + }, + { + "name": "tree5", + "color": "006000", + "collision": true + }, + { + "name": "rock", + "color": "808080", + "collision": true + }, + { + "name": "mountain", + "color": "ff0000", + "collision": true + }, + { + "name": "plant", + "color": "800000", + "collision": true + }, + { + "name": "bush", + "color": "ff8080", "collision": true } ] diff --git a/forge-gui/res/adventure/common/world/biomes/ifnir.json b/forge-gui/res/adventure/common/world/biomes/ifnir.json index dfe531b754f..350c5cd7cb3 100644 --- a/forge-gui/res/adventure/common/world/biomes/ifnir.json +++ b/forge-gui/res/adventure/common/world/biomes/ifnir.json @@ -23,8 +23,7 @@ "height": 1, "color": "110903", "spriteNames": [ - "Skull", - "PlainsRock" + "Skull" ], "enemies": [ "Ammit", @@ -60,9 +59,9 @@ "N": 2, "x": 0.5, "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", - "sourcePath": "world/models/mountain.png", - "maskPath": "world/masks/circle.png", + "structureAtlasPath": "world/structures/structures.atlas", + "sourcePath": "world/structures/models/mountain.png", + "maskPath": "world/structures/masks/circle.png", "height": 0.5, "width": 0.5, "symmetry": 8, diff --git a/forge-gui/res/adventure/common/world/biomes/outlands.json b/forge-gui/res/adventure/common/world/biomes/outlands.json index 20245de45ac..ff3d4b8ceba 100644 --- a/forge-gui/res/adventure/common/world/biomes/outlands.json +++ b/forge-gui/res/adventure/common/world/biomes/outlands.json @@ -31,7 +31,7 @@ "N": 2, "x": 0.5, "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", + "structureAtlasPath": "world/structures/structures.atlas", "sourcePath": "world/models/fill.png", "maskPath": "world/masks/fill.png", "height": 0.99, diff --git a/forge-gui/res/adventure/common/world/biomes/ramunap.json b/forge-gui/res/adventure/common/world/biomes/ramunap.json index 8157dde434d..722f2ae1146 100644 --- a/forge-gui/res/adventure/common/world/biomes/ramunap.json +++ b/forge-gui/res/adventure/common/world/biomes/ramunap.json @@ -45,9 +45,9 @@ "N": 2, "x": 0.5, "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", - "sourcePath": "world/models/mountain.png", - "maskPath": "world/masks/circle.png", + "structureAtlasPath": "world/structures/structures.atlas", + "sourcePath": "world/structures/models/mountain.png", + "maskPath": "world/structures/masks/circle.png", "height": 0.5, "width": 0.5, "periodicOutput": false, diff --git a/forge-gui/res/adventure/common/world/biomes/red.json b/forge-gui/res/adventure/common/world/biomes/red.json index b1bad77d6b3..0985e016231 100644 --- a/forge-gui/res/adventure/common/world/biomes/red.json +++ b/forge-gui/res/adventure/common/world/biomes/red.json @@ -23,9 +23,6 @@ "height": 0.7, "color": "b63729", "spriteNames": [ - "MountainTree", - "MountainTree2", - "MountainRock", "Gravel" ], "enemies": [ @@ -127,21 +124,41 @@ "N": 2, "x": 0.5, "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", - "sourcePath": "world/models/mountain.png", - "maskPath": "world/masks/ring.png", + "structureAtlasPath": "world/structures/red_structures.atlas", + "sourcePath": "world/structures/models/red.png", + "maskPath": "world/structures/masks/ring.png", "height": 0.5, "width": 0.5, - "periodicOutput": false, + "symmetry": 8, "mappingInfo": [ { "name": "mountain", - "color": "a07020", + "color": "ff0000", "collision": true }, { - "name": "mountain_forest", - "color": "007000", + "name": "tree", + "color": "00ff00", + "collision": true + }, + { + "name": "tree2", + "color": "00ffff", + "collision": true + }, + { + "name": "tree3", + "color": "0000ff", + "collision": true + }, + { + "name": "tree4", + "color": "ff00ff", + "collision": true + }, + { + "name": "rock", + "color": "ffff00", "collision": true } ] @@ -149,15 +166,37 @@ { "x": 0.5, "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", - "sourcePath": "world/models/lava.png", - "maskPath": "world/masks/circle.png", + "structureAtlasPath": "world/structures/red_structures.atlas", + "sourcePath": "world/structures/models/volcano.png", + "maskPath": "world/structures/masks/circle.png", "height": 0.2, "width": 0.2, + "N": 2, + "symmetry": 8, "mappingInfo": [ { "name": "lava", - "color": "ff5000", + "color": "ffff00", + "collision": true + }, + { + "name": "mountain", + "color": "ff0000", + "collision": true + }, + { + "name": "dead_tree", + "color": "000000", + "collision": true + }, + { + "name": "dead_tree2", + "color": "808080", + "collision": true + }, + { + "name": "rock", + "color": "0000ff", "collision": true } ] diff --git a/forge-gui/res/adventure/common/world/biomes/shefet.json b/forge-gui/res/adventure/common/world/biomes/shefet.json index e17fa445638..8a70df0282b 100644 --- a/forge-gui/res/adventure/common/world/biomes/shefet.json +++ b/forge-gui/res/adventure/common/world/biomes/shefet.json @@ -23,7 +23,6 @@ "height": 0.5, "color": "efe697", "spriteNames": [ - "PlainsRock", "Skull" ], "enemies": [ diff --git a/forge-gui/res/adventure/common/world/biomes/white.json b/forge-gui/res/adventure/common/world/biomes/white.json index 60d6b810ad1..6bf5c73f376 100644 --- a/forge-gui/res/adventure/common/world/biomes/white.json +++ b/forge-gui/res/adventure/common/world/biomes/white.json @@ -23,9 +23,6 @@ "height": 0.7, "color": "efe697", "spriteNames": [ - "PlainsTree", - "Cactus", - "PlainsRock", "DarkGras" ], "enemies": [ @@ -117,33 +114,74 @@ "N": 2, "x": 0.5, "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", - "sourcePath": "world/models/plains_forest.png", - "maskPath": "world/masks/circle.png", + "structureAtlasPath": "world/structures/white_structures.atlas", + "sourcePath": "world/structures/models/white.png", + "maskPath": "world/structures/masks/circle.png", "height": 0.20000002, "width": 0.20000002, "symmetry": 8, "mappingInfo": [ { - "name": "plains_forest", - "color": "9c4000", + "name": "tree", + "color": "ff8000", + "collision": true + }, + { + "name": "tree2", + "color": "008000", + "collision": true + }, + { + "name": "tree3", + "color": "00ff00", "collision": true } ] }, { + "N": 2, "x": 0.5, "y": 0.5, - "structureAtlasPath": "world/tilesets/structures.atlas", - "sourcePath": "world/models/plateau.png", - "maskPath": "world/masks/ring.png", + "symmetry": 8, + "structureAtlasPath": "world/structures/white_structures.atlas", + "sourcePath": "world/structures/models/desert.png", + "maskPath": "world/structures/masks/ring.png", "height": 0.5, "width": 0.5, - "periodicOutput": false, "mappingInfo": [ { "name": "plateau", - "color": "caaa66", + "color": "804000", + "collision": true + }, + { + "name": "rock", + "color": "402000", + "collision": true + }, + { + "name": "mesa", + "color": "201000", + "collision": true + }, + { + "name": "plateau", + "color": "804000", + "collision": true + }, + { + "name": "cactus", + "color": "00ff00", + "collision": true + }, + { + "name": "cactus2", + "color": "008000", + "collision": true + }, + { + "name": "cactus3", + "color": "004000", "collision": true } ] diff --git a/forge-gui/res/adventure/common/world/enemies.json b/forge-gui/res/adventure/common/world/enemies.json index 9c39d17828d..6596fe86d44 100644 --- a/forge-gui/res/adventure/common/world/enemies.json +++ b/forge-gui/res/adventure/common/world/enemies.json @@ -6369,9 +6369,7 @@ "IdentityBlack", "IdentityGreen", "IdentityAbzan", - "BiomeColorless", - "BiomeWhite", - "BiomeBlack" + "BiomeBlue" ] }, { @@ -7242,7 +7240,7 @@ ] } ], - "colors": "W", + "colors": "GW", "questTags": [ "Elephant", "Beast", @@ -12544,7 +12542,7 @@ "spawnRate": 1, "difficulty": 0.1, "speed": 25, - "scale": 0.6, + "scale": 1.3, "life": 11, "rewards": [ { diff --git a/forge-gui/res/adventure/common/world/sprites/map_sprites.atlas b/forge-gui/res/adventure/common/world/sprites/map_sprites.atlas index fd1b23ea6e2..90bc5f6c636 100644 --- a/forge-gui/res/adventure/common/world/sprites/map_sprites.atlas +++ b/forge-gui/res/adventure/common/world/sprites/map_sprites.atlas @@ -5,289 +5,382 @@ filter: Nearest,Nearest repeat: none DarkWood xy: 0, 0 - size: 16, 16 + size: 16, 16 DarkWood xy: 16, 0 - size: 16, 16 + size: 16, 16 DarkWood xy: 32, 0 - size: 16, 16 + size: 16, 16 DarkWood xy: 48, 0 - size: 16, 16 + size: 16, 16 Reed xy: 64, 0 - size: 16, 16 + size: 16, 16 Reed xy: 80, 0 - size: 16, 16 -Reed - xy: 64, 16 - size: 16, 16 -Reed - xy: 80, 16 - size: 16, 16 + size: 16, 16 DarkWood xy: 96, 0 - size: 16, 16 + size: 16, 16 DarkWood xy: 112, 0 - size: 16, 16 -Waterlily - xy: 96, 16 - size: 16, 16 -Waterlily - xy: 112, 16 - size: 16, 16 -Shroom - xy: 96, 32 - size: 16, 16 -Shroom - xy: 96, 48 - size: 16, 16 -Shroom2 - xy: 112, 32 - size: 16, 16 -Shroom2 - xy: 112, 48 - size: 16, 16 + size: 16, 16 DarkWood xy: 0, 16 - size: 16, 16 + size: 16, 16 DarkWood xy: 16, 16 - size: 16, 16 + size: 16, 16 DarkWood xy: 32, 16 - size: 16, 16 + size: 16, 16 DarkWood xy: 48, 16 - size: 16, 16 + size: 16, 16 +Reed + xy: 64, 16 + size: 16, 16 +Reed + xy: 80, 16 + size: 16, 16 +Waterlily + xy: 96, 16 + size: 16, 16 +Waterlily + xy: 112, 16 + size: 16, 16 DarkGras xy: 0, 32 - size: 16, 16 + size: 16, 16 DarkGras xy: 16, 32 - size: 16, 16 -DarkGras - xy: 0, 48 - size: 16, 16 -DarkGras - xy: 16, 48 - size: 16, 16 + size: 16, 16 Stone xy: 32, 32 - size: 16, 16 + size: 16, 16 Stone xy: 48, 32 - size: 16, 16 -Stone - xy: 32, 48 - size: 16, 16 -Stone - xy: 48, 48 - size: 16, 16 + size: 16, 16 Gravel xy: 64, 32 - size: 16, 16 + size: 16, 16 Gravel xy: 80, 32 - size: 16, 16 + size: 16, 16 +Shroom + xy: 96, 32 + size: 16, 16 +Shroom2 + xy: 112, 32 + size: 16, 16 +DarkGras + xy: 0, 48 + size: 16, 16 +DarkGras + xy: 16, 48 + size: 16, 16 +Shroom + xy: 96, 48 + size: 16, 16 +Shroom2 + xy: 112, 48 + size: 16, 16 +Stone + xy: 32, 48 + size: 16, 16 +Stone + xy: 48, 48 + size: 16, 16 Gravel xy: 64, 48 - size: 16, 16 + size: 16, 16 Gravel xy: 80, 48 - size: 16, 16 + size: 16, 16 Flower xy: 0, 64 - size: 16, 16 + size: 16, 16 Flower xy: 16, 64 - size: 16, 16 -Flower - xy: 0, 80 - size: 16, 16 -Flower - xy: 16, 80 - size: 16, 16 + size: 16, 16 Stone xy: 32, 64 - size: 16, 16 + size: 16, 16 Stone xy: 48, 64 - size: 16, 16 -Stone - xy: 32, 80 - size: 16, 16 -Stone - xy: 48, 80 - size: 16, 16 + size: 16, 16 Moss xy: 64, 64 - size: 16, 16 + size: 16, 16 Moss xy: 80, 64 - size: 16, 16 -Moss - xy: 64, 80 - size: 16, 16 -Moss - xy: 80, 80 - size: 16, 16 + size: 16, 16 Wood xy: 96, 64 - size: 16, 16 + size: 16, 16 Wood xy: 112, 64 - size: 16, 16 + size: 16, 16 +Flower + xy: 0, 80 + size: 16, 16 +Flower + xy: 16, 80 + size: 16, 16 +Stone + xy: 32, 80 + size: 16, 16 +Stone + xy: 48, 80 + size: 16, 16 +Moss + xy: 64, 80 + size: 16, 16 +Moss + xy: 80, 80 + size: 16, 16 Wood xy: 96, 80 - size: 16, 16 + size: 16, 16 Wood xy: 112, 80 - size: 16, 16 + size: 16, 16 WasteTree xy: 0, 96 - size: 16, 16 + size: 16, 16 WasteTree xy: 16, 96 - size: 16, 16 + size: 16, 16 WasteTree xy: 32, 96 - size: 16, 16 + size: 16, 16 WasteRock xy: 48, 96 - size: 16, 16 + size: 16, 16 WasteRock xy: 64, 96 - size: 16, 16 -SwampTree - xy: 0, 112 - size: 16, 16 -SwampTree - xy: 16, 112 - size: 16, 16 -SwampTree - xy: 32, 112 - size: 16, 16 -Skull - xy: 48, 112 - size: 16, 16 -Skull - xy: 112, 144 - size: 16, 16 -Skull - xy: 112, 128 - size: 16, 16 -SwampRock - xy: 64, 112 - size: 16, 16 -SwampRock - xy: 80, 112 - size: 16, 16 -SwampTree2 - xy: 96, 112 - size: 16, 16 -SwampTree2 - xy: 112, 112 - size: 16, 16 + size: 16, 16 +Placeholder + xy: 80, 96 + size: 16,16 SwampTree2 xy: 96, 96 - size: 16, 16 + size: 16, 16 SwampTree2 xy: 112, 96 - size: 16, 16 + size: 16, 16 +SwampTree + xy: 0, 112 + size: 16, 16 +SwampTree + xy: 16, 112 + size: 16, 16 +SwampTree + xy: 32, 112 + size: 16, 16 +Skull + xy: 48, 112 + size: 16, 16 +SwampRock + xy: 64, 112 + size: 16, 16 +SwampRock + xy: 80, 112 + size: 16, 16 +SwampTree2 + xy: 96, 112 + size: 16, 16 +SwampTree2 + xy: 112, 112 + size: 16, 16 PlainsTree xy: 0, 128 - size: 16, 16 + size: 16, 16 PlainsTree xy: 16, 128 - size: 16, 16 + size: 16, 16 Cactus xy: 32, 128 - size: 16, 16 + size: 16, 16 Cactus xy: 48, 128 - size: 16, 16 + size: 16, 16 Cactus xy: 64, 128 - size: 16, 16 + size: 16, 16 PlainsRock - xy: 70, 128 - size: 16, 16 + xy: 80, 128 + size: 16, 16 PlainsRock xy: 96, 128 - size: 16, 16 + size: 16, 16 +Skull + xy: 112, 128 + size: 16, 16 IslandTree xy: 0, 144 - size: 16, 16 + size: 16, 16 IslandTree xy: 16, 144 - size: 16, 16 + size: 16, 16 Coral xy: 32, 144 - size: 16, 16 + size: 16, 16 Shell xy: 48, 144 - size: 16, 16 + size: 16, 16 Shell xy: 64, 144 - size: 16, 16 + size: 16, 16 +Placeholder + xy: 80, 144 + size: 16, 16 +Placeholder + xy: 96, 144 + size: 16, 16 +Skull + xy: 112, 144 + size: 16, 16 WoodTree xy: 0, 160 - size: 16, 16 + size: 16, 16 WoodTree xy: 16, 160 - size: 16, 16 + size: 16, 16 WoodTree xy: 32, 160 - size: 16, 16 + size: 16, 16 WoodTree xy: 48, 160 - size: 16, 16 + size: 16, 16 WoodTree2 xy: 64, 160 - size: 16, 16 + size: 16, 16 WoodTree2 xy: 80, 160 - size: 16, 16 + size: 16, 16 Bush xy: 96, 160 - size: 16, 16 + size: 16, 16 Stump xy: 112, 160 - size: 16, 16 + size: 16, 16 MountainTree xy: 0, 176 - size: 16, 16 + size: 16, 16 MountainTree xy: 16, 176 - size: 16, 16 + size: 16, 16 MountainTree2 xy: 32, 176 - size: 16, 16 + size: 16, 16 MountainTree2 xy: 48, 176 - size: 16, 16 -MountainTree2 - xy: 96, 176 - size: 16, 16 -MountainTree2 - xy: 112, 176 - size: 16, 16 + size: 16, 16 MountainRock xy: 64, 176 - size: 16, 16 + size: 16, 16 MountainRock xy: 80, 176 - size: 16, 16 + size: 16, 16 +MountainTree2 + xy: 96, 176 + size: 16, 16 +MountainTree2 + xy: 112, 176 + size: 16, 16 +WoodTree + xy: 0, 192 + size: 16, 16 +AutumnTree + xy: 16, 192 + size: 16, 16 +WinterTree + xy: 32, 192 + size: 16, 16 +AutumnTree + xy: 48, 192 + size: 16, 16 +Coral + xy: 64, 192 + size: 16, 16 +SnowMountain + xy: 80, 192 + size: 16, 16 +Coral + xy: 96, 192 + size: 16, 16 +AutumnTree + xy: 112, 192 + size: 16, 16 +Placeholder + xy: 0, 208 + size: 16, 16 +AutumnTree + xy: 16, 208 + size: 16, 16 +SwampTree + xy: 32, 208 + size: 16, 16 +Coral + xy: 48, 208 + size: 16, 16 +WoodTree + xy: 64, 208 + size: 16, 16 +IslandRock + xy: 80, 208 + size: 16, 16 +WoodRock + xy: 96, 208 + size: 16, 16 +Placeholder + xy: 112, 208 + size: 16, 16 +LargeWoodRock + xy: 0, 224 + size: 32, 32 +LargeIslandRock + xy: 32, 224 + size: 32, 32 +LargeWasteRock + xy: 64, 224 + size: 32, 32 LargeMountainRock xy: 96, 224 - size: 32, 32 + size: 32, 32 LargePlainsRock xy: 96, 256 - size: 32, 32 + size: 32, 32 +Placeholder + xy: 0, 256 + size: 16, 16 +WasteRock + xy: 16, 256 + size: 16, 16 LargeSwampRock xy: 32, 256 - size: 32, 32 \ No newline at end of file + size: 32, 32 +PlainsRock + xy: 64, 256 + size: 16, 16 +PlainsRock + xy: 80, 256 + size: 16, 16 +LargePlainsRock + xy: 96, 256 + size: 32, 32 +WoodRock + xy: 0, 272 + size: 16, 16 +SwampRock + xy: 16, 272 + size: 16, 16 +WinterTree: + xy: 64, 272 + size: 16, 16 +WinterTree: + xy: 80, 272 + size: 16, 16 \ No newline at end of file diff --git a/forge-gui/res/adventure/common/world/sprites/map_sprites.json b/forge-gui/res/adventure/common/world/sprites/map_sprites.json index 6aa2f183d0a..9324d76a928 100644 --- a/forge-gui/res/adventure/common/world/sprites/map_sprites.json +++ b/forge-gui/res/adventure/common/world/sprites/map_sprites.json @@ -2,7 +2,7 @@ "textureAtlas":"world/sprites/map_sprites.atlas", "sprites":[ { -"name":"DarkWood", +"name":"DarkWood", "startArea":0.2, "endArea":0.7, "layer":-1, @@ -22,7 +22,7 @@ "layer":-1, "density":0.03 },{ -"name":"Reed", +"name":"Reed", "startArea":0.9, "endArea":0.99, "layer":0, @@ -46,7 +46,7 @@ "name":"Stone", "startArea":0.2, "endArea":0.7, -"layer":-1, +"layer":-1, "resolution" :5, "density":0.01 },{ @@ -79,21 +79,21 @@ "name":"WasteTree", "startArea":0.0, "endArea":0.2, -"layer":0, +"layer":1, "resolution" :10, "density":0.7 },{ "name":"WasteRock", "startArea":0.8, "endArea":1.0, -"layer":0, +"layer":1, "resolution" :10, "density":0.5 },{ "name":"SwampTree", "startArea":0.8, "endArea":1.0, -"layer":0, +"layer":1, "resolution" :10, "density":0.5 },{ @@ -106,45 +106,45 @@ "name":"SwampRock", "startArea":0.5, "endArea":0.6, -"layer":0, +"layer":1, "density":0.1 },{ "name":"SwampTree2", "startArea":0.0, "endArea":0.2, -"layer":0, +"layer":1, "resolution" :10, "density":0.7 },{ "name":"PlainsTree", "startArea":0.0, "endArea":0.2, -"layer":0, +"layer":1, "resolution" :10, "density":0.7 },{ "name":"Cactus", "startArea":0.5, -"layer":0, +"layer":1, "endArea":0.7, "density":0.06 },{ "name":"PlainsRock", "startArea":0.7, -"layer":0, +"layer":1, "endArea":0.99, "density":0.06 },{ "name":"IslandTree", "startArea":0.0, "endArea":0.2, -"layer":0, +"layer":1, "resolution" :10, "density":0.7 },{ "name":"Coral", "startArea":0.0, -"layer":0, +"layer":1, "endArea":0.9, "density":0.01 },{ @@ -157,65 +157,65 @@ "name":"WoodTree", "startArea":0.0, "endArea":0.2, -"layer":0, +"layer":1, "resolution" :10, "density":0.7 },{ "name":"WoodTree2", "startArea":0.8, "endArea":0.99, -"layer":0, +"layer":1, "resolution" :5, "density":0.7 },{ "name":"Bush", "startArea":0.0, "endArea":0.2, -"layer":0, +"layer":1, "resolution" :5, "density":0.4 },{ "name":"Stump", "startArea":0.0, -"layer":0, +"layer":-1, "endArea":0.9, "density":0.01 },{ "name":"MountainTree", "startArea":0.0, "endArea":0.2, -"layer":0, +"layer":1, "resolution" :5, "density":0.7 },{ "name":"MountainTree2", "startArea":0.8, "endArea":0.99, -"layer":0, +"layer":1, "resolution" :5, "density":0.7 },{ "name":"MountainRock", "startArea":0.1, -"layer":0, +"layer":1, "endArea":0.9, "density":0.08 },{ "name":"LargeMountainRock", "startArea":0.0, -"layer":0, +"layer":1, "endArea":0.9, "density":0.02 },{ "name":"LargePlainsRock", "startArea":0.0, -"layer":0, +"layer":1, "endArea":0.9, "density":0.01 },{ "name":"LargeSwampRock", "startArea":0.0, -"layer":0, +"layer":1, "endArea":0.9, "density":0.01 } diff --git a/forge-gui/res/adventure/common/world/structures/black_structures.atlas b/forge-gui/res/adventure/common/world/structures/black_structures.atlas new file mode 100644 index 00000000000..470505cba3d --- /dev/null +++ b/forge-gui/res/adventure/common/world/structures/black_structures.atlas @@ -0,0 +1,38 @@ +black_structures.png +size: 192,192 +format: RGBA8888 +filter: Nearest,Nearest +repeat: none +water + xy: 0, 0 + size: 48, 64 +muck + xy: 48,0 + size:48,64 +tree + xy: 96,0 + size: 48,64 +tree2 + xy:144,0 + size:48,64 +dead_tree + xy: 0,64 + size: 48,64 +dead_tree2 + xy: 48,64 + size: 48,64 +tree3 + xy: 96,64 + size: 48,64 +tree4 + xy:144,64 + size:48,64 +rock + xy: 0, 128 + size: 48, 64 +rock2 + xy: 48, 128 + size: 48,64 +dead_tree3 + xy:96,128 + size:48,64 \ No newline at end of file diff --git a/forge-gui/res/adventure/common/world/structures/black_structures.png b/forge-gui/res/adventure/common/world/structures/black_structures.png new file mode 100644 index 00000000000..ab1ff230166 Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/black_structures.png differ diff --git a/forge-gui/res/adventure/common/world/structures/blue_structures.atlas b/forge-gui/res/adventure/common/world/structures/blue_structures.atlas new file mode 100644 index 00000000000..7250edec4f5 --- /dev/null +++ b/forge-gui/res/adventure/common/world/structures/blue_structures.atlas @@ -0,0 +1,34 @@ +blue_structures.png +size: 192,192 +format: RGBA8888 +filter: Nearest,Nearest +repeat: none +water + xy: 0, 0 + size: 48, 64 +tree + xy: 48,0 + size:48,64 +tree2 + xy: 96,0 + size: 48,64 +rock + xy: 0,64 + size: 48,64 +rock2 + xy: 48,64 + size: 48,64 +pineapple + xy: 96,64 + size: 48,64 +rock3 + xy: 0, 128 + size: 48, 64 +rock4 + xy: 48, 128 + size: 48,64 +dune + xy:96,128 + size:48,64 +dune2 + xy:144,128 \ No newline at end of file diff --git a/forge-gui/res/adventure/common/world/structures/blue_structures.png b/forge-gui/res/adventure/common/world/structures/blue_structures.png new file mode 100644 index 00000000000..c4093113714 Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/blue_structures.png differ diff --git a/forge-gui/res/adventure/common/world/structures/colorless_structures.atlas b/forge-gui/res/adventure/common/world/structures/colorless_structures.atlas new file mode 100644 index 00000000000..32547a101c0 --- /dev/null +++ b/forge-gui/res/adventure/common/world/structures/colorless_structures.atlas @@ -0,0 +1,29 @@ +colorless_structures.png +size: 144,192 +format: RGBA8888 +filter: Nearest,Nearest +repeat: none +hole + xy: 0, 0 + size: 48, 64 +crater + xy: 48,0 + size:48,64 +tree + xy: 96,0 + size: 48,64 +tree2 + xy: 0,64 + size: 48,64 +tree3 + xy: 48,64 + size: 48,64 +tree4 + xy: 96,64 + size: 48,64 +rock + xy: 0, 128 + size: 48, 64 +mountain + xy: 48, 128 + size: 48,64 \ No newline at end of file diff --git a/forge-gui/res/adventure/common/world/structures/colorless_structures.png b/forge-gui/res/adventure/common/world/structures/colorless_structures.png new file mode 100644 index 00000000000..3c1158ba5f2 Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/colorless_structures.png differ diff --git a/forge-gui/res/adventure/common/world/structures/green_structures.atlas b/forge-gui/res/adventure/common/world/structures/green_structures.atlas new file mode 100644 index 00000000000..d6b1be514e1 --- /dev/null +++ b/forge-gui/res/adventure/common/world/structures/green_structures.atlas @@ -0,0 +1,41 @@ +green_structures.png +size: 192,192 +format: RGBA8888 +filter: Nearest,Nearest +repeat: none +water + xy: 0, 0 + size: 48, 64 +tree + xy: 48,0 + size:48,64 +tree2 + xy: 96,0 + size: 48,64 +vine + xy: 144,0 + size: 48,64 +tree3 + xy: 0,64 + size: 48,64 +tree4 + xy: 48,64 + size: 48,64 +tree5 + xy: 96,64 + size: 48,64 +tree6 + xy: 144, 64 + size: 48,64 +rock + xy: 0, 128 + size: 48, 64 +mountain + xy: 48, 128 + size: 48,64 +plant + xy:96,128 + size:48,64 +bush + xy:144,128 + size:48,64 \ No newline at end of file diff --git a/forge-gui/res/adventure/common/world/structures/green_structures.png b/forge-gui/res/adventure/common/world/structures/green_structures.png new file mode 100644 index 00000000000..c3dc04e858e Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/green_structures.png differ diff --git a/forge-gui/res/adventure/common/world/masks/circle.png b/forge-gui/res/adventure/common/world/structures/masks/circle.png similarity index 100% rename from forge-gui/res/adventure/common/world/masks/circle.png rename to forge-gui/res/adventure/common/world/structures/masks/circle.png diff --git a/forge-gui/res/adventure/common/world/masks/fill.png b/forge-gui/res/adventure/common/world/structures/masks/fill.png similarity index 100% rename from forge-gui/res/adventure/common/world/masks/fill.png rename to forge-gui/res/adventure/common/world/structures/masks/fill.png diff --git a/forge-gui/res/adventure/common/world/masks/moon.png b/forge-gui/res/adventure/common/world/structures/masks/moon.png similarity index 100% rename from forge-gui/res/adventure/common/world/masks/moon.png rename to forge-gui/res/adventure/common/world/structures/masks/moon.png diff --git a/forge-gui/res/adventure/common/world/masks/moon2.png b/forge-gui/res/adventure/common/world/structures/masks/moon2.png similarity index 100% rename from forge-gui/res/adventure/common/world/masks/moon2.png rename to forge-gui/res/adventure/common/world/structures/masks/moon2.png diff --git a/forge-gui/res/adventure/common/world/masks/moon3.png b/forge-gui/res/adventure/common/world/structures/masks/moon3.png similarity index 100% rename from forge-gui/res/adventure/common/world/masks/moon3.png rename to forge-gui/res/adventure/common/world/structures/masks/moon3.png diff --git a/forge-gui/res/adventure/common/world/masks/moon4.png b/forge-gui/res/adventure/common/world/structures/masks/moon4.png similarity index 100% rename from forge-gui/res/adventure/common/world/masks/moon4.png rename to forge-gui/res/adventure/common/world/structures/masks/moon4.png diff --git a/forge-gui/res/adventure/common/world/masks/ring.png b/forge-gui/res/adventure/common/world/structures/masks/ring.png similarity index 100% rename from forge-gui/res/adventure/common/world/masks/ring.png rename to forge-gui/res/adventure/common/world/structures/masks/ring.png diff --git a/forge-gui/res/adventure/common/world/masks/ring2.png b/forge-gui/res/adventure/common/world/structures/masks/ring2.png similarity index 100% rename from forge-gui/res/adventure/common/world/masks/ring2.png rename to forge-gui/res/adventure/common/world/structures/masks/ring2.png diff --git a/forge-gui/res/adventure/common/world/masks/tallrect.png b/forge-gui/res/adventure/common/world/structures/masks/tallrect.png similarity index 100% rename from forge-gui/res/adventure/common/world/masks/tallrect.png rename to forge-gui/res/adventure/common/world/structures/masks/tallrect.png diff --git a/forge-gui/res/adventure/common/world/structures/models/beach.png b/forge-gui/res/adventure/common/world/structures/models/beach.png new file mode 100644 index 00000000000..90f9681ae84 Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/models/beach.png differ diff --git a/forge-gui/res/adventure/common/world/structures/models/black.png b/forge-gui/res/adventure/common/world/structures/models/black.png new file mode 100644 index 00000000000..b734585f372 Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/models/black.png differ diff --git a/forge-gui/res/adventure/common/world/structures/models/blue.png b/forge-gui/res/adventure/common/world/structures/models/blue.png new file mode 100644 index 00000000000..c04249ffaf2 Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/models/blue.png differ diff --git a/forge-gui/res/adventure/common/world/structures/models/colorless.png b/forge-gui/res/adventure/common/world/structures/models/colorless.png new file mode 100644 index 00000000000..b0713fdec13 Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/models/colorless.png differ diff --git a/forge-gui/res/adventure/common/world/models/deep_swamp.png b/forge-gui/res/adventure/common/world/structures/models/deep_swamp.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/deep_swamp.png rename to forge-gui/res/adventure/common/world/structures/models/deep_swamp.png diff --git a/forge-gui/res/adventure/common/world/structures/models/desert.png b/forge-gui/res/adventure/common/world/structures/models/desert.png new file mode 100644 index 00000000000..7a12642eaef Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/models/desert.png differ diff --git a/forge-gui/res/adventure/common/world/models/desert_river.png b/forge-gui/res/adventure/common/world/structures/models/desert_river.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/desert_river.png rename to forge-gui/res/adventure/common/world/structures/models/desert_river.png diff --git a/forge-gui/res/adventure/common/world/models/fill.png b/forge-gui/res/adventure/common/world/structures/models/fill.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/fill.png rename to forge-gui/res/adventure/common/world/structures/models/fill.png diff --git a/forge-gui/res/adventure/common/world/models/forest.png b/forge-gui/res/adventure/common/world/structures/models/forest.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/forest.png rename to forge-gui/res/adventure/common/world/structures/models/forest.png diff --git a/forge-gui/res/adventure/common/world/structures/models/green.png b/forge-gui/res/adventure/common/world/structures/models/green.png new file mode 100644 index 00000000000..25f209055d6 Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/models/green.png differ diff --git a/forge-gui/res/adventure/common/world/models/hole.png b/forge-gui/res/adventure/common/world/structures/models/hole.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/hole.png rename to forge-gui/res/adventure/common/world/structures/models/hole.png diff --git a/forge-gui/res/adventure/common/world/models/island_forest.png b/forge-gui/res/adventure/common/world/structures/models/island_forest.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/island_forest.png rename to forge-gui/res/adventure/common/world/structures/models/island_forest.png diff --git a/forge-gui/res/adventure/common/world/models/lake.png b/forge-gui/res/adventure/common/world/structures/models/lake.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/lake.png rename to forge-gui/res/adventure/common/world/structures/models/lake.png diff --git a/forge-gui/res/adventure/common/world/models/lava.png b/forge-gui/res/adventure/common/world/structures/models/lava.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/lava.png rename to forge-gui/res/adventure/common/world/structures/models/lava.png diff --git a/forge-gui/res/adventure/common/world/models/mountain.png b/forge-gui/res/adventure/common/world/structures/models/mountain.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/mountain.png rename to forge-gui/res/adventure/common/world/structures/models/mountain.png diff --git a/forge-gui/res/adventure/common/world/models/mountain_forest.png b/forge-gui/res/adventure/common/world/structures/models/mountain_forest.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/mountain_forest.png rename to forge-gui/res/adventure/common/world/structures/models/mountain_forest.png diff --git a/forge-gui/res/adventure/common/world/models/plains_forest.png b/forge-gui/res/adventure/common/world/structures/models/plains_forest.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/plains_forest.png rename to forge-gui/res/adventure/common/world/structures/models/plains_forest.png diff --git a/forge-gui/res/adventure/common/world/models/plateau.png b/forge-gui/res/adventure/common/world/structures/models/plateau.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/plateau.png rename to forge-gui/res/adventure/common/world/structures/models/plateau.png diff --git a/forge-gui/res/adventure/common/world/structures/models/red.png b/forge-gui/res/adventure/common/world/structures/models/red.png new file mode 100644 index 00000000000..34d8ed03064 Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/models/red.png differ diff --git a/forge-gui/res/adventure/common/world/models/swamp.png b/forge-gui/res/adventure/common/world/structures/models/swamp.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/swamp.png rename to forge-gui/res/adventure/common/world/structures/models/swamp.png diff --git a/forge-gui/res/adventure/common/world/models/swamp_forest.png b/forge-gui/res/adventure/common/world/structures/models/swamp_forest.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/swamp_forest.png rename to forge-gui/res/adventure/common/world/structures/models/swamp_forest.png diff --git a/forge-gui/res/adventure/common/world/models/swamp_ruins.png b/forge-gui/res/adventure/common/world/structures/models/swamp_ruins.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/swamp_ruins.png rename to forge-gui/res/adventure/common/world/structures/models/swamp_ruins.png diff --git a/forge-gui/res/adventure/common/world/structures/models/volcano.png b/forge-gui/res/adventure/common/world/structures/models/volcano.png new file mode 100644 index 00000000000..bf4041f054d Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/models/volcano.png differ diff --git a/forge-gui/res/adventure/common/world/models/waste_structure.png b/forge-gui/res/adventure/common/world/structures/models/waste_structure.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/waste_structure.png rename to forge-gui/res/adventure/common/world/structures/models/waste_structure.png diff --git a/forge-gui/res/adventure/common/world/models/water.png b/forge-gui/res/adventure/common/world/structures/models/water.png similarity index 100% rename from forge-gui/res/adventure/common/world/models/water.png rename to forge-gui/res/adventure/common/world/structures/models/water.png diff --git a/forge-gui/res/adventure/common/world/structures/models/white.png b/forge-gui/res/adventure/common/world/structures/models/white.png new file mode 100644 index 00000000000..3ecbe626fdd Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/models/white.png differ diff --git a/forge-gui/res/adventure/common/world/structures/red_structures.atlas b/forge-gui/res/adventure/common/world/structures/red_structures.atlas new file mode 100644 index 00000000000..aa749263c90 --- /dev/null +++ b/forge-gui/res/adventure/common/world/structures/red_structures.atlas @@ -0,0 +1,32 @@ +red_structures.png +size: 144,192 +format: RGBA8888 +filter: Nearest,Nearest +repeat: none +lava + xy: 0, 0 + size: 48, 64 +tree + xy: 48,0 + size:48,64 +tree2 + xy: 96,0 + size: 48,64 +dead_tree + xy: 0,64 + size: 48,64 +dead_tree2 + xy: 48,64 + size: 48,64 +tree3 + xy: 96,64 + size: 48,64 +rock + xy: 0, 128 + size: 48, 64 +mountain + xy: 48, 128 + size: 48,64 +tree4 + xy: 96,128 + size: 48,64 \ No newline at end of file diff --git a/forge-gui/res/adventure/common/world/structures/red_structures.png b/forge-gui/res/adventure/common/world/structures/red_structures.png new file mode 100644 index 00000000000..c61b7d4238c Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/red_structures.png differ diff --git a/forge-gui/res/adventure/common/world/tilesets/structures.atlas b/forge-gui/res/adventure/common/world/structures/structures.atlas similarity index 97% rename from forge-gui/res/adventure/common/world/tilesets/structures.atlas rename to forge-gui/res/adventure/common/world/structures/structures.atlas index 9ea32b0053c..e26163bc294 100644 --- a/forge-gui/res/adventure/common/world/tilesets/structures.atlas +++ b/forge-gui/res/adventure/common/world/structures/structures.atlas @@ -57,4 +57,4 @@ waste_mountain size: 48, 64 waste_structure xy: 96, 320 - size: 48, 64 \ No newline at end of file + size: 48, 64 \ No newline at end of file diff --git a/forge-gui/res/adventure/common/world/structures/structures.png b/forge-gui/res/adventure/common/world/structures/structures.png new file mode 100644 index 00000000000..312e7641700 Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/structures.png differ diff --git a/forge-gui/res/adventure/common/world/structures/white_structures.atlas b/forge-gui/res/adventure/common/world/structures/white_structures.atlas new file mode 100644 index 00000000000..f85597ac361 --- /dev/null +++ b/forge-gui/res/adventure/common/world/structures/white_structures.atlas @@ -0,0 +1,32 @@ +white_structures.png +size: 144,192 +format: RGBA8888 +filter: Nearest,Nearest +repeat: none +tree + xy: 0, 0 + size: 48, 64 +tree2 + xy: 48,0 + size:48,64 +tree3 + xy: 96,0 + size: 48,64 +cactus + xy: 0,64 + size: 48,64 +cactus2 + xy: 48,64 + size: 48,64 +cactus3 + xy: 96,64 + size: 48,64 +rock + xy: 0, 128 + size: 48, 64 +mesa + xy: 48, 128 + size: 48,64 +plateau + xy:96,128 + size:48,64 \ No newline at end of file diff --git a/forge-gui/res/adventure/common/world/structures/white_structures.png b/forge-gui/res/adventure/common/world/structures/white_structures.png new file mode 100644 index 00000000000..556ffc0df43 Binary files /dev/null and b/forge-gui/res/adventure/common/world/structures/white_structures.png differ diff --git a/forge-gui/res/adventure/common/world/tilesets/waste.atlas b/forge-gui/res/adventure/common/world/tilesets/colorless.atlas similarity index 100% rename from forge-gui/res/adventure/common/world/tilesets/waste.atlas rename to forge-gui/res/adventure/common/world/tilesets/colorless.atlas diff --git a/forge-gui/res/adventure/common/world/tilesets/structures.png b/forge-gui/res/adventure/common/world/tilesets/structures.png deleted file mode 100644 index d75441d3dde..00000000000 Binary files a/forge-gui/res/adventure/common/world/tilesets/structures.png and /dev/null differ diff --git a/forge-gui/res/adventure/common/world/tilesets/terrain.atlas b/forge-gui/res/adventure/common/world/tilesets/terrain.atlas index 6c9abb3911c..cc1a492d295 100644 --- a/forge-gui/res/adventure/common/world/tilesets/terrain.atlas +++ b/forge-gui/res/adventure/common/world/tilesets/terrain.atlas @@ -4,16 +4,16 @@ size: 192,512 format: RGBA8888 filter: Nearest,Nearest repeat: none -Waste +Colorless xy: 0, 64 size: 48, 64 -Waste_1 +Colorless_1 xy: 48, 64 size: 48, 64 -Waste_2 +Colorless_2 xy: 96, 64 size: 48, 64 -Waste_3 +Colorless_3 xy: 144, 64 size: 48, 64 White diff --git a/forge-gui/res/cardsfolder/a/adventurers_guildhouse.txt b/forge-gui/res/cardsfolder/a/adventurers_guildhouse.txt index 9d843378699..8ca2fdb2e5a 100644 --- a/forge-gui/res/cardsfolder/a/adventurers_guildhouse.txt +++ b/forge-gui/res/cardsfolder/a/adventurers_guildhouse.txt @@ -2,7 +2,6 @@ Name:Adventurers' Guildhouse ManaCost:no cost Types:Land S:Mode$ Continuous | Affected$ Creature.Green+Legendary | AddKeyword$ Bands with Other Legendary Creatures | Description$ Green legendary creatures you control have "bands with other legendary creatures." (Any legendary creatures can attack in a band as long as at least one has "bands with other legendary creatures." Bands are blocked as a group. If at least two legendary creatures you control, one of which has "bands with other legendary creatures," are blocking or being blocked by the same creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) -AI:RemoveDeck:All SVar:NonStackingEffect:True DeckNeeds:Color$Green & Type$Legendary Oracle:Green legendary creatures you control have "bands with other legendary creatures." (Any legendary creatures can attack in a band as long as at least one has "bands with other legendary creatures." Bands are blocked as a group. If at least two legendary creatures you control, one of which has "bands with other legendary creatures," are blocking or being blocked by the same creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/a/ayesha_tanaka.txt b/forge-gui/res/cardsfolder/a/ayesha_tanaka.txt index ad87d7898f9..c2ee7c763dd 100644 --- a/forge-gui/res/cardsfolder/a/ayesha_tanaka.txt +++ b/forge-gui/res/cardsfolder/a/ayesha_tanaka.txt @@ -4,5 +4,4 @@ Types:Legendary Creature Human Artificer PT:2/2 K:Banding A:AB$ Counter | Cost$ T | TargetType$ Activated | TgtPrompt$ Select target activated ability from an artifact source | ValidTgts$ Artifact | UnlessCost$ W | SpellDescription$ Counter target activated ability from an artifact source unless that ability's controller pays {W}. (Mana abilities can't be targeted.) -AI:RemoveDeck:All Oracle:Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)\n{T}: Counter target activated ability from an artifact source unless that ability's controller pays {W}. (Mana abilities can't be targeted.) diff --git a/forge-gui/res/cardsfolder/b/baton_of_morale.txt b/forge-gui/res/cardsfolder/b/baton_of_morale.txt index 223992c64f6..f066cd316b3 100644 --- a/forge-gui/res/cardsfolder/b/baton_of_morale.txt +++ b/forge-gui/res/cardsfolder/b/baton_of_morale.txt @@ -2,5 +2,4 @@ Name:Baton of Morale ManaCost:2 Types:Artifact A:AB$ Pump | Cost$ 2 | ValidTgts$ Creature | TgtPrompt$ Select target creature | KW$ Banding | SpellDescription$ Target creature gains banding until end of turn. -AI:RemoveDeck:All Oracle:{2}: Target creature gains banding until end of turn. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding a player controls are blocking or being blocked by a creature, that player divides that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/b/battering_ram.txt b/forge-gui/res/cardsfolder/b/battering_ram.txt index 6642171ef93..872f3cfd1f1 100644 --- a/forge-gui/res/cardsfolder/b/battering_ram.txt +++ b/forge-gui/res/cardsfolder/b/battering_ram.txt @@ -7,5 +7,4 @@ SVar:TrigBanding:DB$ Pump | Defined$ Self | KW$ Banding | Duration$ UntilEndOfCo T:Mode$ AttackerBlockedByCreature | ValidCard$ Card.Self | ValidBlocker$ Creature.Wall | Execute$ DelayAttackTrig | TriggerDescription$ Whenever CARDNAME becomes blocked by a Wall, destroy that Wall at end of combat. SVar:DelayAttackTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ EndCombat | ValidPlayer$ Player | Execute$ TrigDestroyBlocker | RememberObjects$ TriggeredBlockerLKICopy | TriggerDescription$ Destroy blocked creature at end of combat. SVar:TrigDestroyBlocker:DB$ Destroy | Defined$ DelayTriggerRememberedLKI -AI:RemoveDeck:All Oracle:At the beginning of combat on your turn, Battering Ram gains banding until end of combat. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's blocking.)\nWhenever Battering Ram becomes blocked by a Wall, destroy that Wall at end of combat. diff --git a/forge-gui/res/cardsfolder/b/beast_walkers.txt b/forge-gui/res/cardsfolder/b/beast_walkers.txt index ea48e0ef85d..b39b74b84ca 100644 --- a/forge-gui/res/cardsfolder/b/beast_walkers.txt +++ b/forge-gui/res/cardsfolder/b/beast_walkers.txt @@ -3,5 +3,4 @@ ManaCost:1 W W Types:Creature Human Beast Soldier PT:2/2 A:AB$ Pump | Cost$ G | Defined$ Self | KW$ Banding | SpellDescription$ CARDNAME gains banding until end of turn. -AI:RemoveDeck:All Oracle:{G}: Beast Walkers gains banding until end of turn. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/b/benalish_hero.txt b/forge-gui/res/cardsfolder/b/benalish_hero.txt index a18e5ffc41a..b542da2999b 100644 --- a/forge-gui/res/cardsfolder/b/benalish_hero.txt +++ b/forge-gui/res/cardsfolder/b/benalish_hero.txt @@ -3,5 +3,4 @@ ManaCost:W Types:Creature Human Soldier PT:1/1 K:Banding -AI:RemoveDeck:All Oracle:Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/b/benalish_infantry.txt b/forge-gui/res/cardsfolder/b/benalish_infantry.txt index 5538df69259..6b0fa9074e3 100644 --- a/forge-gui/res/cardsfolder/b/benalish_infantry.txt +++ b/forge-gui/res/cardsfolder/b/benalish_infantry.txt @@ -3,5 +3,4 @@ ManaCost:2 W Types:Creature Human Soldier PT:1/3 K:Banding -AI:RemoveDeck:All Oracle:Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/b/bog_down.txt b/forge-gui/res/cardsfolder/b/bog_down.txt index 3d5397ba72e..c4d6825b58f 100644 --- a/forge-gui/res/cardsfolder/b/bog_down.txt +++ b/forge-gui/res/cardsfolder/b/bog_down.txt @@ -5,6 +5,6 @@ K:Kicker:Sac<2/Land> A:SP$ Discard | Cost$ 2 B | ValidTgts$ Player | TgtPrompt$ Choose a player | NumCards$ WasKicked | Mode$ TgtChoose | SpellDescription$ Target player discards two cards. If CARDNAME was kicked, that player discards three cards instead. SVar:WasKicked:Count$Kicked.3.2 SVar:NeedsToPlayKickedVar:Z GE3 -SVar:Z:Count$ValidHand Card.OppCtrl +SVar:Z:Count$ValidHand Card.OppOwn SVar:AIPreference:SacCost$Land.basic+YouCtrl Oracle:Kicker—Sacrifice two lands. (You may sacrifice two lands in addition to any other costs as you cast this spell.)\nTarget player discards two cards. If this spell was kicked, that player discards three cards instead. diff --git a/forge-gui/res/cardsfolder/c/caligo_skin_witch.txt b/forge-gui/res/cardsfolder/c/caligo_skin_witch.txt index 09282fc143a..a666238bd2d 100644 --- a/forge-gui/res/cardsfolder/c/caligo_skin_witch.txt +++ b/forge-gui/res/cardsfolder/c/caligo_skin_witch.txt @@ -6,5 +6,5 @@ K:Kicker:3 B T:Mode$ ChangesZone | ValidCard$ Card.Self+kicked | Origin$ Any | Destination$ Battlefield | Execute$ TrigDiscard | TriggerDescription$ When CARDNAME enters the battlefield, if it was kicked, each opponent discards two cards. SVar:TrigDiscard:DB$ Discard | Defined$ Player.Opponent | NumCards$ 2 | Mode$ TgtChoose SVar:NeedsToPlayKickedVar:Z GE1 -SVar:Z:Count$ValidHand Card.OppCtrl +SVar:Z:Count$ValidHand Card.OppOwn Oracle:Kicker {3}{B} (You may pay an additional {3}{B} as you cast this spell.)\nWhen Caligo Skin-Witch enters the battlefield, if it was kicked, each opponent discards two cards. diff --git a/forge-gui/res/cardsfolder/c/camel.txt b/forge-gui/res/cardsfolder/c/camel.txt index 73b26696b5d..6633140bb17 100644 --- a/forge-gui/res/cardsfolder/c/camel.txt +++ b/forge-gui/res/cardsfolder/c/camel.txt @@ -4,5 +4,4 @@ Types:Creature Camel PT:0/1 K:Banding R:Event$ DamageDone | Prevent$ True | ValidSource$ Desert | ValidTarget$ Creature.Self+attacking,Creature.attackersBandedWith | Description$ As long as CARDNAME is attacking, prevent all damage Deserts would deal to Camel and to creatures banded with CARDNAME. -AI:RemoveDeck:All Oracle:Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)\nAs long as Camel is attacking, prevent all damage Deserts would deal to Camel and to creatures banded with Camel. diff --git a/forge-gui/res/cardsfolder/c/cathedral_of_serra.txt b/forge-gui/res/cardsfolder/c/cathedral_of_serra.txt index 3cfbce7eb25..30cede8f6ad 100644 --- a/forge-gui/res/cardsfolder/c/cathedral_of_serra.txt +++ b/forge-gui/res/cardsfolder/c/cathedral_of_serra.txt @@ -2,7 +2,6 @@ Name:Cathedral of Serra ManaCost:no cost Types:Land S:Mode$ Continuous | Affected$ Creature.White+Legendary | AddKeyword$ Bands with Other Legendary Creatures | Description$ White legendary creatures you control have "bands with other legendary creatures." (Any legendary creatures can attack in a band as long as at least one has "bands with other legendary creatures." Bands are blocked as a group. If at least two legendary creatures you control, one of which has "bands with other legendary creatures," are blocking or being blocked by the same creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) -AI:RemoveDeck:All SVar:NonStackingEffect:True DeckHas:Keyword$BandsWithOther DeckNeeds:Type$Legendary & Color$White diff --git a/forge-gui/res/cardsfolder/d/defensive_formation.txt b/forge-gui/res/cardsfolder/d/defensive_formation.txt index 1644fb9608c..215f7a5de6b 100644 --- a/forge-gui/res/cardsfolder/d/defensive_formation.txt +++ b/forge-gui/res/cardsfolder/d/defensive_formation.txt @@ -3,5 +3,4 @@ ManaCost:W Types:Enchantment S:Mode$ Continuous | Affected$ You | AddKeyword$ You assign combat damage of each creature attacking you. | Description$ Rather than the attacking player, you assign the combat damage of each creature attacking you. You can divide that creature's combat damage as you choose among any of the creatures blocking it. SVar:NonStackingEffect:True -AI:RemoveDeck:All Oracle:Rather than the attacking player, you assign the combat damage of each creature attacking you. You can divide that creature's combat damage as you choose among any of the creatures blocking it. diff --git a/forge-gui/res/cardsfolder/f/formation.txt b/forge-gui/res/cardsfolder/f/formation.txt index 7d7ca45b7bc..37abb178987 100644 --- a/forge-gui/res/cardsfolder/f/formation.txt +++ b/forge-gui/res/cardsfolder/f/formation.txt @@ -4,5 +4,4 @@ Types:Instant A:SP$ Pump | Cost$ 1 W | ValidTgts$ Creature | TgtPrompt$ Select target creature | KW$ Banding | SubAbility$ DelTrigSlowtrip | SpellDescription$ Target creature gains banding until end of turn. Draw a card at the beginning of the next turn's upkeep. SVar:DelTrigSlowtrip:DB$ DelayedTrigger | NextTurn$ True | Mode$ Phase | Phase$ Upkeep | ValidPlayer$ Player | Execute$ DrawSlowtrip | TriggerDescription$ Draw a card. SVar:DrawSlowtrip:DB$ Draw | NumCards$ 1 | Defined$ You -AI:RemoveDeck:All Oracle:Target creature gains banding until end of turn. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding a player controls are blocking or being blocked by a creature, that player divides that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)\nDraw a card at the beginning of the next turn's upkeep. diff --git a/forge-gui/res/cardsfolder/g/grothama_all_devouring.txt b/forge-gui/res/cardsfolder/g/grothama_all_devouring.txt index 96c6f1854f4..c4d0d4ff244 100644 --- a/forge-gui/res/cardsfolder/g/grothama_all_devouring.txt +++ b/forge-gui/res/cardsfolder/g/grothama_all_devouring.txt @@ -4,8 +4,8 @@ Types:Legendary Creature Wurm PT:10/8 S:Mode$ Continuous | Affected$ Creature.Other | AddTrigger$ GrothamaAttack | AddSVar$ HasAttackEffect | Description$ Other creatures have "Whenever this creature attacks, you may have it fight CARDNAME." SVar:GrothamaAttack:Mode$ Attacks | ValidCard$ Card.Self | Execute$ GrothamaFight | OptionalDecider$ You | TriggerDescription$ Whenever this creature attacks, ABILITY. -SVar:GrothamaFight:DB$ Fight | Defined$ TriggeredAttackerLKICopy | ExtraDefined$ OriginalHost | SpellDescription$ You may have it fight ORIGINALHOST -T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigRepeat | TriggerDescription$ When CARDNAME leaves the battlefield, each player draws cards equal to the amount of damage dealt to Grothama this turn by sources they controlled. +SVar:GrothamaFight:DB$ Fight | Defined$ TriggeredAttackerLKICopy | ExtraDefined$ OriginalHost | AILogic$ Grothama | SpellDescription$ You may have it fight ORIGINALHOST +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigRepeat | TriggerDescription$ When NICKNAME leaves the battlefield, each player draws cards equal to the amount of damage dealt to NICKNAME this turn by sources they controlled. SVar:TrigRepeat:DB$ RepeatEach | RepeatPlayers$ Player | RepeatSubAbility$ TrigDraw SVar:TrigDraw:DB$ Draw | Defined$ Remembered | NumCards$ X SVar:X:TriggeredCard$TotalDamageThisTurn Card.RememberedPlayerCtrl diff --git a/forge-gui/res/cardsfolder/h/helm_of_chatzuk.txt b/forge-gui/res/cardsfolder/h/helm_of_chatzuk.txt index a1d276d583c..bd0b646e8d8 100644 --- a/forge-gui/res/cardsfolder/h/helm_of_chatzuk.txt +++ b/forge-gui/res/cardsfolder/h/helm_of_chatzuk.txt @@ -2,6 +2,5 @@ Name:Helm of Chatzuk ManaCost:1 Types:Artifact A:AB$ Pump | Cost$ 1 T | ValidTgts$ Creature | TgtPrompt$ Select target creature | KW$ Banding | SpellDescription$ Target creature gains banding until end of turn. -AI:RemoveDeck:All DeckHas:Keyword$Banding Oracle:{1}, {T}: Target creature gains banding until end of turn. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding a player controls are blocking or being blocked by a creature, that player divides that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/h/hypnotic_cloud.txt b/forge-gui/res/cardsfolder/h/hypnotic_cloud.txt index 9b698fef80b..bb93203d2c8 100644 --- a/forge-gui/res/cardsfolder/h/hypnotic_cloud.txt +++ b/forge-gui/res/cardsfolder/h/hypnotic_cloud.txt @@ -5,5 +5,5 @@ K:Kicker:4 A:SP$ Discard | Cost$ 1 B | NumCards$ X | ValidTgts$ Player | TgtPrompt$ Select target player | Mode$ TgtChoose | SpellDescription$ Target player discards a card. If this spell was kicked, that player discards three cards instead. SVar:X:Count$Kicked.3.1 SVar:NeedsToPlayKickedVar:Z GE2 -SVar:Z:Count$ValidHand Card.OppCtrl +SVar:Z:Count$ValidHand Card.OppOwn Oracle:Kicker {4} (You may pay an additional {4} as you cast this spell.)\nTarget player discards a card. If this spell was kicked, that player discards three cards instead. diff --git a/forge-gui/res/cardsfolder/i/icatian_infantry.txt b/forge-gui/res/cardsfolder/i/icatian_infantry.txt index 35752f076be..19758aa2e99 100644 --- a/forge-gui/res/cardsfolder/i/icatian_infantry.txt +++ b/forge-gui/res/cardsfolder/i/icatian_infantry.txt @@ -4,5 +4,4 @@ Types:Creature Human Soldier PT:1/1 A:AB$ Pump | Cost$ 1 | Defined$ Self | KW$ First Strike | SpellDescription$ CARDNAME gains first strike until end of turn. A:AB$ Pump | Cost$ 1 | Defined$ Self | KW$ Banding | SpellDescription$ CARDNAME gains banding until end of turn. -AI:RemoveDeck:All Oracle:{1}: Icatian Infantry gains first strike until end of turn.\n{1}: Icatian Infantry gains banding until end of turn. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/i/icatian_phalanx.txt b/forge-gui/res/cardsfolder/i/icatian_phalanx.txt index 6e39f9585ad..85c4fea69c8 100644 --- a/forge-gui/res/cardsfolder/i/icatian_phalanx.txt +++ b/forge-gui/res/cardsfolder/i/icatian_phalanx.txt @@ -3,5 +3,4 @@ ManaCost:4 W Types:Creature Human Soldier PT:2/4 K:Banding -AI:RemoveDeck:All Oracle:Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/i/icatian_skirmishers.txt b/forge-gui/res/cardsfolder/i/icatian_skirmishers.txt index d5553469664..70ade58c2b8 100644 --- a/forge-gui/res/cardsfolder/i/icatian_skirmishers.txt +++ b/forge-gui/res/cardsfolder/i/icatian_skirmishers.txt @@ -6,5 +6,4 @@ K:First Strike K:Banding T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever CARDNAME attacks, all creatures banded with it gain first strike until end of turn. SVar:TrigPump:DB$ PumpAll | ValidCards$ Creature.attackersBandedWith | KW$ First Strike -AI:RemoveDeck:All Oracle:First strike; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)\nWhenever Icatian Skirmishers attacks, all creatures banded with it gain first strike until end of turn. diff --git a/forge-gui/res/cardsfolder/i/imminent_doom.txt b/forge-gui/res/cardsfolder/i/imminent_doom.txt index 66524866ddf..a5ed8ebfd80 100644 --- a/forge-gui/res/cardsfolder/i/imminent_doom.txt +++ b/forge-gui/res/cardsfolder/i/imminent_doom.txt @@ -6,5 +6,5 @@ T:Mode$ SpellCast | ValidCard$ Card.cmcEQX | ValidActivatingPlayer$ You | Trigge SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ Y | SubAbility$ DBPutCounter SVar:DBPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ DOOM | CounterNum$ 1 SVar:X:Count$CardCounters.DOOM -SVar:Y:LastStateBattlefield$CardCounters.DOOM +SVar:Y:TriggeredCardLKI$CardManaCost Oracle:Imminent Doom enters the battlefield with a doom counter on it.\nWhenever you cast a spell with mana value equal to the number of doom counters on Imminent Doom, Imminent Doom deals that much damage to any target. Then put a doom counter on Imminent Doom. diff --git a/forge-gui/res/cardsfolder/k/khorvaths_fury.txt b/forge-gui/res/cardsfolder/k/khorvaths_fury.txt index edd45208b81..9cd69569c62 100644 --- a/forge-gui/res/cardsfolder/k/khorvaths_fury.txt +++ b/forge-gui/res/cardsfolder/k/khorvaths_fury.txt @@ -11,5 +11,5 @@ SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:Remembered$Amount/Plus.1 SVar:Y:Count$ValidHand Card.RememberedPlayerCtrl SVar:NeedsToPlayVar:Z GE4 -SVar:Z:Count$ValidHand Card.OppCtrl +SVar:Z:Count$ValidHand Card.OppOwn Oracle:For each player, choose friend or foe. Each friend discards all cards from their hand, then draws that many cards plus one. Khorvath's Fury deals damage to each foe equal to the number of cards in their hand. diff --git a/forge-gui/res/cardsfolder/k/kjeldoran_escort.txt b/forge-gui/res/cardsfolder/k/kjeldoran_escort.txt index 1e66c640d36..7d8bc2efe42 100644 --- a/forge-gui/res/cardsfolder/k/kjeldoran_escort.txt +++ b/forge-gui/res/cardsfolder/k/kjeldoran_escort.txt @@ -3,5 +3,4 @@ ManaCost:2 W W Types:Creature Human Soldier PT:2/3 K:Banding -AI:RemoveDeck:All Oracle:Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/k/kjeldoran_knight.txt b/forge-gui/res/cardsfolder/k/kjeldoran_knight.txt index 44ce272ade6..128efd5f5ce 100644 --- a/forge-gui/res/cardsfolder/k/kjeldoran_knight.txt +++ b/forge-gui/res/cardsfolder/k/kjeldoran_knight.txt @@ -5,5 +5,4 @@ PT:1/1 K:Banding A:AB$ Pump | Cost$ 1 W | Defined$ Self | NumAtt$ +1 | SpellDescription$ CARDNAME gets +1/+0 until end of turn. A:AB$ Pump | Cost$ W W | Defined$ Self | NumDef$ +2 | SpellDescription$ CARDNAME gets +0/+2 until end of turn. -AI:RemoveDeck:All Oracle:Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)\n{1}{W}: Kjeldoran Knight gets +1/+0 until end of turn.\n{W}{W}: Kjeldoran Knight gets +0/+2 until end of turn. diff --git a/forge-gui/res/cardsfolder/k/kjeldoran_phalanx.txt b/forge-gui/res/cardsfolder/k/kjeldoran_phalanx.txt index 81da3e07acd..711bc3a3605 100644 --- a/forge-gui/res/cardsfolder/k/kjeldoran_phalanx.txt +++ b/forge-gui/res/cardsfolder/k/kjeldoran_phalanx.txt @@ -4,5 +4,4 @@ Types:Creature Human Soldier PT:2/5 K:First Strike K:Banding -AI:RemoveDeck:All Oracle:First strike; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/k/kjeldoran_skycaptain.txt b/forge-gui/res/cardsfolder/k/kjeldoran_skycaptain.txt index cfe2f16dd4f..a9b8b0839f1 100644 --- a/forge-gui/res/cardsfolder/k/kjeldoran_skycaptain.txt +++ b/forge-gui/res/cardsfolder/k/kjeldoran_skycaptain.txt @@ -5,5 +5,4 @@ PT:2/2 K:Flying K:First Strike K:Banding -AI:RemoveDeck:All Oracle:Flying; first strike; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/k/kjeldoran_skyknight.txt b/forge-gui/res/cardsfolder/k/kjeldoran_skyknight.txt index 9efa081fcfe..4fd49ace391 100644 --- a/forge-gui/res/cardsfolder/k/kjeldoran_skyknight.txt +++ b/forge-gui/res/cardsfolder/k/kjeldoran_skyknight.txt @@ -5,5 +5,4 @@ PT:1/1 K:Flying K:First Strike K:Banding -AI:RemoveDeck:All Oracle:Flying; first strike; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/k/kjeldoran_warrior.txt b/forge-gui/res/cardsfolder/k/kjeldoran_warrior.txt index bf385e8908f..47bf86155c1 100644 --- a/forge-gui/res/cardsfolder/k/kjeldoran_warrior.txt +++ b/forge-gui/res/cardsfolder/k/kjeldoran_warrior.txt @@ -3,5 +3,4 @@ ManaCost:W Types:Creature Human Warrior PT:1/1 K:Banding -AI:RemoveDeck:All Oracle:Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/k/knights_of_thorn.txt b/forge-gui/res/cardsfolder/k/knights_of_thorn.txt index 9978fd22ce6..156879317e4 100644 --- a/forge-gui/res/cardsfolder/k/knights_of_thorn.txt +++ b/forge-gui/res/cardsfolder/k/knights_of_thorn.txt @@ -4,5 +4,4 @@ Types:Creature Human Knight PT:2/2 K:Protection from red K:Banding -AI:RemoveDeck:All Oracle:Protection from red; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/m/mesa_pegasus.txt b/forge-gui/res/cardsfolder/m/mesa_pegasus.txt index 713ac95abde..83e4d949b32 100644 --- a/forge-gui/res/cardsfolder/m/mesa_pegasus.txt +++ b/forge-gui/res/cardsfolder/m/mesa_pegasus.txt @@ -4,5 +4,4 @@ Types:Creature Pegasus PT:1/1 K:Flying K:Banding -AI:RemoveDeck:All Oracle:Flying; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/m/mishras_war_machine.txt b/forge-gui/res/cardsfolder/m/mishras_war_machine.txt index 051f1d4611e..3535b7c7bc4 100644 --- a/forge-gui/res/cardsfolder/m/mishras_war_machine.txt +++ b/forge-gui/res/cardsfolder/m/mishras_war_machine.txt @@ -8,4 +8,5 @@ SVar:TrigDealDamage:DB$ DealDamage | Defined$ You | NumDmg$ 3 | UnlessPayer$ You SVar:DBTap:DB$ Tap | ConditionPlayerDefined$ Remembered | ConditionPlayerContains$ You | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True DeckHas:Ability$Discard +AI:RemoveDeck:Random Oracle:Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)\nAt the beginning of your upkeep, Mishra's War Machine deals 3 damage to you unless you discard a card. If Mishra's War Machine deals damage to you this way, tap it. diff --git a/forge-gui/res/cardsfolder/m/mountain_stronghold.txt b/forge-gui/res/cardsfolder/m/mountain_stronghold.txt index 78468437b8a..d91145fbd83 100644 --- a/forge-gui/res/cardsfolder/m/mountain_stronghold.txt +++ b/forge-gui/res/cardsfolder/m/mountain_stronghold.txt @@ -2,6 +2,5 @@ Name:Mountain Stronghold ManaCost:no cost Types:Land S:Mode$ Continuous | Affected$ Creature.Red+Legendary | AddKeyword$ Bands with Other Legendary Creatures | Description$ Red legendary creatures you control have "bands with other legendary creatures." (Any legendary creatures can attack in a band as long as at least one has "bands with other legendary creatures." Bands are blocked as a group. If at least two legendary creatures you control, one of which has "bands with other legendary creatures," are blocking or being blocked by the same creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) -AI:RemoveDeck:All DeckNeeds:Color$Red & Type$Legendary Oracle:Red legendary creatures you control have "bands with other legendary creatures." (Any legendary creatures can attack in a band as long as at least one has "bands with other legendary creatures." Bands are blocked as a group. If at least two legendary creatures you control, one of which has "bands with other legendary creatures," are blocking or being blocked by the same creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/n/nalathni_dragon.txt b/forge-gui/res/cardsfolder/n/nalathni_dragon.txt index 6b506f9a98d..5bdb8e19564 100644 --- a/forge-gui/res/cardsfolder/n/nalathni_dragon.txt +++ b/forge-gui/res/cardsfolder/n/nalathni_dragon.txt @@ -6,5 +6,4 @@ K:Flying K:Banding A:AB$ Pump | Cost$ R | Defined$ Self | NumAtt$ +1 | ActivationNumberSacrifice$ GE4 | ActivationResolveSub$ DBPump | SpellDescription$ CARDNAME gets +1/+0 until end of turn. If this ability has been activated four or more times this turn, sacrifice CARDNAME at the beginning of the next end step. SVar:DBPump:DB$ Pump | Defined$ Self | AtEOT$ Sacrifice -AI:RemoveDeck:All Oracle:Flying; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)\n{R}: Nalathni Dragon gets +1/+0 until end of turn. If this ability has been activated four or more times this turn, sacrifice Nalathni Dragon at the beginning of the next end step. diff --git a/forge-gui/res/cardsfolder/n/natures_blessing.txt b/forge-gui/res/cardsfolder/n/natures_blessing.txt index c25f015cbd9..8783a9869bd 100644 --- a/forge-gui/res/cardsfolder/n/natures_blessing.txt +++ b/forge-gui/res/cardsfolder/n/natures_blessing.txt @@ -6,6 +6,5 @@ SVar:DBPutCounter:DB$ PutCounter | Defined$ Targeted | CounterType$ P1P1 | Count SVar:DBBanding:DB$ Pump | Defined$ Targeted | KW$ Banding | Duration$ Permanent | SpellDescription$ Target creature gains Banding SVar:DBFirstStrike:DB$ Pump | Defined$ Targeted | KW$ First Strike | Duration$ Permanent | SpellDescription$ Target creature gains first strike SVar:DBTrample:DB$ Pump | Defined$ Targeted | KW$ Trample | Duration$ Permanent | SpellDescription$ Target creature gains Trample -AI:RemoveDeck:All SVar:NonStackingEffect:True Oracle:{G}{W}, Discard a card: Put a +1/+1 counter on target creature or that creature gains banding, first strike, or trample. (This effect lasts indefinitely. Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding a player controls are blocking or being blocked by a creature, that player divides that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/n/noble_elephant.txt b/forge-gui/res/cardsfolder/n/noble_elephant.txt index e872e3d1253..5fcea9dd6e3 100644 --- a/forge-gui/res/cardsfolder/n/noble_elephant.txt +++ b/forge-gui/res/cardsfolder/n/noble_elephant.txt @@ -4,5 +4,4 @@ Types:Creature Elephant PT:2/2 K:Trample K:Banding -AI:RemoveDeck:All Oracle:Trample; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/o/odric_master_tactician.txt b/forge-gui/res/cardsfolder/o/odric_master_tactician.txt index d22430d8e12..243b4901964 100644 --- a/forge-gui/res/cardsfolder/o/odric_master_tactician.txt +++ b/forge-gui/res/cardsfolder/o/odric_master_tactician.txt @@ -3,8 +3,7 @@ ManaCost:2 W W Types:Legendary Creature Human Soldier PT:3/4 K:First Strike -T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | CheckSVar$ OdricTest | SVarCompare$ GE3 | NoResolvingCheck$ True | Execute$ TrigOdricEffect | TriggerDescription$ Whenever CARDNAME and at least three other creatures attack, you choose which creatures block this combat and how those creatures block. +T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | IsPresent$ Creature.attacking+Other | PresentCompare$ GE3 | NoResolvingCheck$ True | Execute$ TrigOdricEffect | TriggerDescription$ Whenever CARDNAME and at least three other creatures attack, you choose which creatures block this combat and how those creatures block. SVar:TrigOdricEffect:DB$ DeclareCombatants | DeclareBlockers$ True -SVar:OdricTest:Count$Valid Creature.attacking+Other AI:RemoveDeck:All Oracle:First strike (This creature deals combat damage before creatures without first strike.)\nWhenever Odric, Master Tactician and at least three other creatures attack, you choose which creatures block this combat and how those creatures block. diff --git a/forge-gui/res/cardsfolder/p/pikemen.txt b/forge-gui/res/cardsfolder/p/pikemen.txt index 7537e532f8e..4efa839f8fb 100644 --- a/forge-gui/res/cardsfolder/p/pikemen.txt +++ b/forge-gui/res/cardsfolder/p/pikemen.txt @@ -4,5 +4,4 @@ Types:Creature Human Soldier PT:1/1 K:First Strike K:Banding -AI:RemoveDeck:All Oracle:First strike; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/p/probe.txt b/forge-gui/res/cardsfolder/p/probe.txt index c2c476a246a..e9c1361441e 100644 --- a/forge-gui/res/cardsfolder/p/probe.txt +++ b/forge-gui/res/cardsfolder/p/probe.txt @@ -7,5 +7,5 @@ SVar:DBDiscardYou:DB$ Discard | Defined$ You | NumCards$ 2 | SubAbility$ DBDisca SVar:DBDiscardTarget:DB$ Discard | Condition$ Kicked | ValidTgts$ Player | TgtPrompt$ Select target player | NumCards$ 2 | Mode$ TgtChoose | SpellDescription$ If CARDNAME was kicked, target player discards two cards. DeckHints:Color$Black SVar:NeedsToPlayKickedVar:Z GE1 -SVar:Z:Count$ValidHand Card.OppCtrl +SVar:Z:Count$ValidHand Card.OppOwn Oracle:Kicker {1}{B} (You may pay an additional {1}{B} as you cast this spell.)\nDraw three cards, then discard two cards. If this spell was kicked, target player discards two cards. diff --git a/forge-gui/res/cardsfolder/s/seafarers_quay.txt b/forge-gui/res/cardsfolder/s/seafarers_quay.txt index a9910cb8e95..f9569cb9f56 100644 --- a/forge-gui/res/cardsfolder/s/seafarers_quay.txt +++ b/forge-gui/res/cardsfolder/s/seafarers_quay.txt @@ -2,6 +2,5 @@ Name:Seafarer's Quay ManaCost:no cost Types:Land S:Mode$ Continuous | Affected$ Creature.Blue+Legendary | AddKeyword$ Bands with Other Legendary Creatures | Description$ Blue legendary creatures you control have "bands with other legendary creatures." (Any legendary creatures can attack in a band as long as at least one has "bands with other legendary creatures." Bands are blocked as a group. If at least two legendary creatures you control, one of which has "bands with other legendary creatures," are blocking or being blocked by the same creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) -AI:RemoveDeck:All DeckNeeds:Type$Legendary & Color$Blue Oracle:Blue legendary creatures you control have "bands with other legendary creatures." (Any legendary creatures can attack in a band as long as at least one has "bands with other legendary creatures." Bands are blocked as a group. If at least two legendary creatures you control, one of which has "bands with other legendary creatures," are blocking or being blocked by the same creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/s/shelkin_brownie.txt b/forge-gui/res/cardsfolder/s/shelkin_brownie.txt index eda846cee95..37af1363027 100644 --- a/forge-gui/res/cardsfolder/s/shelkin_brownie.txt +++ b/forge-gui/res/cardsfolder/s/shelkin_brownie.txt @@ -3,5 +3,4 @@ ManaCost:1 G Types:Creature Ouphe PT:1/1 A:AB$ Debuff | Cost$ T | ValidTgts$ Creature | TgtPrompt$ Select target creature | Keywords$ Bands with Other Creatures named Wolves of the Hunt & Bands with Other Legendary Creatures | SpellDescription$ Target creature loses all "bands with other" abilities until end of turn. | StackDescription$ SpellDescription -AI:RemoveDeck:All Oracle:{T}: Target creature loses all "bands with other" abilities until end of turn. diff --git a/forge-gui/res/cardsfolder/s/shield_bearer.txt b/forge-gui/res/cardsfolder/s/shield_bearer.txt index 57632e546b4..2a765141c2a 100644 --- a/forge-gui/res/cardsfolder/s/shield_bearer.txt +++ b/forge-gui/res/cardsfolder/s/shield_bearer.txt @@ -3,5 +3,4 @@ ManaCost:1 W Types:Creature Human Soldier PT:0/3 K:Banding -AI:RemoveDeck:All Oracle:Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/s/soraya_the_falconer.txt b/forge-gui/res/cardsfolder/s/soraya_the_falconer.txt index e0513993d44..1ec72b9928c 100644 --- a/forge-gui/res/cardsfolder/s/soraya_the_falconer.txt +++ b/forge-gui/res/cardsfolder/s/soraya_the_falconer.txt @@ -4,5 +4,4 @@ Types:Legendary Creature Human PT:2/2 S:Mode$ Continuous | Affected$ Creature.Bird | AddPower$ 1 | AddToughness$ 1 | Description$ Bird creatures get +1/+1. A:AB$ Pump | Cost$ 1 W | ValidTgts$ Creature.Bird | TgtPrompt$ Select target bird creature | KW$ Banding | SpellDescription$ Target Bird creature gains banding until end of turn. -AI:RemoveDeck:All Oracle:Bird creatures get +1/+1.\n{1}{W}: Target Bird creature gains banding until end of turn. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding a player controls are blocking or being blocked by a creature, that player divides that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/t/tempting_wurm.txt b/forge-gui/res/cardsfolder/t/tempting_wurm.txt index 79e81dfb952..0d21c78f7df 100644 --- a/forge-gui/res/cardsfolder/t/tempting_wurm.txt +++ b/forge-gui/res/cardsfolder/t/tempting_wurm.txt @@ -6,4 +6,6 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S SVar:EachOpponent:DB$ RepeatEach | RepeatPlayers$ Player.Opponent | RepeatSubAbility$ TemptingChange SVar:TemptingChange:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | ChangeType$ Artifact,Creature,Enchantment,Land | DefinedPlayer$ Remembered | ChangeNum$ X SVar:X:Count$ValidHand Artifact.RememberedPlayerCtrl,Creature.RememberedPlayerCtrl,Enchantment.RememberedPlayerCtrl,Land.RememberedPlayerCtrl +SVar:NeedsToPlayVar:Y LE2 +SVar:Y:Count$ValidHand Card.OppOwn Oracle:When Tempting Wurm enters the battlefield, each opponent may put any number of artifact, creature, enchantment, and/or land cards from their hand onto the battlefield. diff --git a/forge-gui/res/cardsfolder/t/teremko_griffin.txt b/forge-gui/res/cardsfolder/t/teremko_griffin.txt index e328c87e3cd..fa25efb612c 100644 --- a/forge-gui/res/cardsfolder/t/teremko_griffin.txt +++ b/forge-gui/res/cardsfolder/t/teremko_griffin.txt @@ -4,5 +4,4 @@ Types:Creature Griffin PT:2/2 K:Flying K:Banding -AI:RemoveDeck:All Oracle:Flying; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/t/timber_wolves.txt b/forge-gui/res/cardsfolder/t/timber_wolves.txt index 08facb5d0b2..db52daf7c4c 100644 --- a/forge-gui/res/cardsfolder/t/timber_wolves.txt +++ b/forge-gui/res/cardsfolder/t/timber_wolves.txt @@ -3,5 +3,4 @@ ManaCost:G Types:Creature Wolf PT:1/1 K:Banding -AI:RemoveDeck:All Oracle:Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/t/tolaria.txt b/forge-gui/res/cardsfolder/t/tolaria.txt index faec1efa3ee..ee04a29458e 100644 --- a/forge-gui/res/cardsfolder/t/tolaria.txt +++ b/forge-gui/res/cardsfolder/t/tolaria.txt @@ -3,5 +3,4 @@ ManaCost:no cost Types:Legendary Land A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U}. A:AB$ Debuff | Cost$ T | ValidTgts$ Creature | TgtPrompt$ Select target creature | Keywords$ Banding & Bands with Other Creatures named Wolves of the Hunt & Bands with Other Legendary Creatures | ActivationPhases$ Upkeep | SpellDescription$ Target creature loses banding and all "bands with other" abilities until end of turn. Activate only during any upkeep step. | StackDescription$ SpellDescription -AI:RemoveDeck:All Oracle:{T}: Add {U}.\n{T}: Target creature loses banding and all "bands with other" abilities until end of turn. Activate only during any upkeep step. diff --git a/forge-gui/res/cardsfolder/u/unholy_citadel.txt b/forge-gui/res/cardsfolder/u/unholy_citadel.txt index 31f81f96e3d..b6f95cb4738 100644 --- a/forge-gui/res/cardsfolder/u/unholy_citadel.txt +++ b/forge-gui/res/cardsfolder/u/unholy_citadel.txt @@ -2,7 +2,6 @@ Name:Unholy Citadel ManaCost:no cost Types:Land S:Mode$ Continuous | Affected$ Creature.Black+Legendary | AddKeyword$ Bands with Other Legendary Creatures | Description$ Black legendary creatures you control have "bands with other legendary creatures." (Any legendary creatures can attack in a band as long as at least one has "bands with other legendary creatures." Bands are blocked as a group. If at least two legendary creatures you control, one of which has "bands with other legendary creatures," are blocking or being blocked by the same creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) -AI:RemoveDeck:All SVar:NonStackingEffect:True DeckNeeds:Type$Legendary & Color$Black Oracle:Black legendary creatures you control have "bands with other legendary creatures." (Any legendary creatures can attack in a band as long as at least one has "bands with other legendary creatures." Bands are blocked as a group. If at least two legendary creatures you control, one of which has "bands with other legendary creatures," are blocking or being blocked by the same creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) diff --git a/forge-gui/res/cardsfolder/u/urzas_engine.txt b/forge-gui/res/cardsfolder/u/urzas_engine.txt index 44d06bd9701..27a119abaa6 100644 --- a/forge-gui/res/cardsfolder/u/urzas_engine.txt +++ b/forge-gui/res/cardsfolder/u/urzas_engine.txt @@ -5,5 +5,4 @@ PT:1/5 K:Trample A:AB$ Pump | Cost$ 3 | Defined$ Self | KW$ Banding | SpellDescription$ CARDNAME gains banding until end of turn. A:AB$ PumpAll | Cost$ 3 | ValidCards$ Creature.attackersBandedWith | KW$ Trample | SpellDescription$ Attacking creatures banded with Urza's Engine gain trample until end of turn. -AI:RemoveDeck:All Oracle:Trample\n{3}: Urza's Engine gains banding until end of turn. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)\n{3}: Attacking creatures banded with Urza's Engine gain trample until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/archivist_of_gondor.txt b/forge-gui/res/cardsfolder/upcoming/archivist_of_gondor.txt index 528b440046d..23c1a46a2cb 100644 --- a/forge-gui/res/cardsfolder/upcoming/archivist_of_gondor.txt +++ b/forge-gui/res/cardsfolder/upcoming/archivist_of_gondor.txt @@ -5,6 +5,6 @@ PT:2/3 T:Mode$ DamageDone | ValidSource$ Card.IsCommander+YouOwn | ValidTarget$ Player | CheckSVar$ Monarch | SVarCompare$ EQ0 | CombatDamage$ True | Execute$ TrigMonarch | TriggerZones$ Battlefield | TriggerDescription$ When your commander deals combat damage to a player, if there is no monarch, you become the monarch. SVar:TrigMonarch:DB$ BecomeMonarch | Defined$ You SVar:Monarch:PlayerCountPlayers$HasPropertyisMonarch -T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ Player.IsMonarch | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ At the beginning of the monarch's end step, that player draws a card. +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ Player.isMonarch | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ At the beginning of the monarch's end step, that player draws a card. SVar:TrigDraw:DB$ Draw | Defined$ TriggeredPlayer Oracle:When your commander deals combat damage to a player, if there is no monarch, you become the monarch.\nAt the beginning of the monarch's end step, that player draws a card. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/lidless_gaze.txt b/forge-gui/res/cardsfolder/upcoming/lidless_gaze.txt index b4c36baf79a..bf9df6b30e4 100644 --- a/forge-gui/res/cardsfolder/upcoming/lidless_gaze.txt +++ b/forge-gui/res/cardsfolder/upcoming/lidless_gaze.txt @@ -3,8 +3,8 @@ ManaCost:2 B R Types:Sorcery K:Flashback:2 B R A:SP$ Dig | Defined$ Player | DigNum$ 1 | DestinationZone$ Exile | RememberChanged$ True | ChangeNum$ All | SubAbility$ DBEffect | SpellDescription$ Exile the top card of each player's library. Until the end of your next turn, you may play those cards, and mana of any type can be spent to cast them. -SVar:DBEffect:DB$ Effect | StaticAbilities$ STPlay | ExileOnMoved$ Exile | Duration$ UntilTheEndOfYourNextTurn | RememberObjects$ Remembered | SubAbility$ DBCleanup +SVar:DBEffect:DB$ Effect | StaticAbilities$ STPlay | ForgetOnMoved$ Exile | Duration$ UntilTheEndOfYourNextTurn | RememberObjects$ Remembered | SubAbility$ DBCleanup SVar:STPlay:Mode$ Continuous | MayPlay$ True | MayPlayIgnoreType$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ Until the end of your next turn, you may play those cards, and mana of any type can be spent to cast them. SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True DeckHas:Ability$Graveyard -Oracle:Exile the top card of each player's library. Until the end of your next turn, you may play those cards, and mana of any type can be spent to cast them.\nFlashback {2}{B}{R} (You may cast this card from your graveyard for its flashback cost. Then exile it.) \ No newline at end of file +Oracle:Exile the top card of each player's library. Until the end of your next turn, you may play those cards, and mana of any type can be spent to cast them.\nFlashback {2}{B}{R} (You may cast this card from your graveyard for its flashback cost. Then exile it.) diff --git a/forge-gui/res/cardsfolder/upcoming/the_grey_havens.txt b/forge-gui/res/cardsfolder/upcoming/the_grey_havens.txt index 13e9ab443d5..d128fe73699 100644 --- a/forge-gui/res/cardsfolder/upcoming/the_grey_havens.txt +++ b/forge-gui/res/cardsfolder/upcoming/the_grey_havens.txt @@ -3,7 +3,7 @@ ManaCost:no cost Types:Legendary Land T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigScry | TriggerDescription$ When CARDNAME enters the battlefield, scry 1. SVar:TrigScry:DB$ Scry | ScryNum$ 1 -A:AB$ Mana | Cost$ T | Produced$ C | Amount$ 1 | SpellDescription$ Add {C} +A:AB$ Mana | Cost$ T | Produced$ C | Amount$ 1 | SpellDescription$ Add {C}. A:AB$ ManaReflected | Cost$ T | ColorOrType$ Color | Valid$ Defined.ValidGraveyard Creature.Legendary+YouOwn | ReflectProperty$ Is | SpellDescription$ Add one mana of any color among legendary creature cards in your graveyard. DeckHints:Type$Legendary & Type$Creature -Oracle:When The Grey Havens enters the battlefield, scry 1.{T}: Add {C}.\n{T}: Add one mana of any color among legendary creature cards in your graveyard. +Oracle:When The Grey Havens enters the battlefield, scry 1.\n{T}: Add {C}.\n{T}: Add one mana of any color among legendary creature cards in your graveyard. diff --git a/forge-gui/res/cardsfolder/v/valakut_the_molten_pinnacle.txt b/forge-gui/res/cardsfolder/v/valakut_the_molten_pinnacle.txt index 9b191193504..7a9db9ad3e3 100644 --- a/forge-gui/res/cardsfolder/v/valakut_the_molten_pinnacle.txt +++ b/forge-gui/res/cardsfolder/v/valakut_the_molten_pinnacle.txt @@ -2,7 +2,7 @@ Name:Valakut, the Molten Pinnacle ManaCost:no cost Types:Land K:CARDNAME enters the battlefield tapped. -T:Mode$ ChangesZone | ValidCard$ Mountain.YouCtrl | Origin$ Any | Destination$ Battlefield | OptionalDecider$ You | Execute$ TrigDamage | IsPresent$ Mountain.YouCtrl | PresentCompare$ GE6 | TriggerZones$ Battlefield | TriggerDescription$ Whenever a Mountain enters the battlefield under your control, if you control at least five other Mountains, you may have CARDNAME deal 3 damage to any target. -SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ 3 +T:Mode$ ChangesZone | ValidCard$ Mountain.YouCtrl | Origin$ Any | Destination$ Battlefield | Execute$ TrigDamage | IsPresent$ Mountain.YouCtrl | PresentCompare$ GE6 | NoResolvingCheck$ True | TriggerZones$ Battlefield | TriggerDescription$ Whenever a Mountain enters the battlefield under your control, if you control at least five other Mountains, you may have CARDNAME deal 3 damage to any target. +SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ 3 | ConditionPresent$ Mountain.YouCtrl+NotTriggeredCard | ConditionCompare$ GE5 | OptionalDecider$ You A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R}. Oracle:Valakut, the Molten Pinnacle enters the battlefield tapped.\nWhenever a Mountain enters the battlefield under your control, if you control at least five other Mountains, you may have Valakut, the Molten Pinnacle deal 3 damage to any target.\n{T}: Add {R}. diff --git a/forge-gui/res/cardsfolder/v/volunteer_reserves.txt b/forge-gui/res/cardsfolder/v/volunteer_reserves.txt index 0e805ed901b..139990c336f 100644 --- a/forge-gui/res/cardsfolder/v/volunteer_reserves.txt +++ b/forge-gui/res/cardsfolder/v/volunteer_reserves.txt @@ -4,5 +4,4 @@ Types:Creature Human Soldier PT:2/4 K:Banding K:Cumulative upkeep:1 -AI:RemoveDeck:All Oracle:Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)\nCumulative upkeep {1} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.) diff --git a/forge-gui/res/cardsfolder/w/wall_of_shields.txt b/forge-gui/res/cardsfolder/w/wall_of_shields.txt index 5df6785060a..f348ca1a4a3 100644 --- a/forge-gui/res/cardsfolder/w/wall_of_shields.txt +++ b/forge-gui/res/cardsfolder/w/wall_of_shields.txt @@ -4,5 +4,4 @@ Types:Artifact Creature Wall PT:0/4 K:Defender K:Banding -AI:RemoveDeck:All Oracle:Defender (This creature can't attack.)\nBanding (If any creatures with banding you control are blocking a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by.) diff --git a/forge-gui/src/main/java/forge/localinstance/properties/ForgeConstants.java b/forge-gui/src/main/java/forge/localinstance/properties/ForgeConstants.java index 2789cb7b605..d23cb2c7f40 100644 --- a/forge-gui/src/main/java/forge/localinstance/properties/ForgeConstants.java +++ b/forge-gui/src/main/java/forge/localinstance/properties/ForgeConstants.java @@ -17,24 +17,25 @@ */ package forge.localinstance.properties; +import forge.gui.GuiBase; +import forge.util.FileUtil; + import java.io.File; import java.util.Collections; import java.util.Map; -import forge.gui.GuiBase; -import forge.util.FileUtil; - public final class ForgeConstants { - public static final String PATH_SEPARATOR = File.separator; - public static final String ASSETS_DIR = GuiBase.getInterface().getAssetsDir(); - public static final String PROFILE_FILE = ASSETS_DIR + "forge.profile.properties"; - public static final String PROFILE_TEMPLATE_FILE = PROFILE_FILE + ".example"; + public static final String PATH_SEPARATOR = File.separator; + public static final String ASSETS_DIR = GuiBase.getInterface().getAssetsDir(); + public static final String PROFILE_FILE = ASSETS_DIR + "forge.profile.properties"; + public static final String PROFILE_TEMPLATE_FILE = PROFILE_FILE + ".example"; - public static final String RES_DIR = ASSETS_DIR + "res" + PATH_SEPARATOR; - public static final String ADVENTURE_DIR = RES_DIR + "adventure" + PATH_SEPARATOR; - public static final String ADVENTURE_DEFAULT_PLANE_DIR = ADVENTURE_DIR + "Shandalar" + PATH_SEPARATOR; - public static final String LISTS_DIR = RES_DIR + "lists" + PATH_SEPARATOR; - public static final String SETLOOKUP_DIR = RES_DIR + "setlookup" + PATH_SEPARATOR; + public static final String RES_DIR = ASSETS_DIR + "res" + PATH_SEPARATOR; + public static final String ADVENTURE_DIR = RES_DIR + "adventure" + PATH_SEPARATOR; + public static final String ADVENTURE_DEFAULT_PLANE_DIR = ADVENTURE_DIR + "Shandalar" + PATH_SEPARATOR; + public static final String ADVENTURE_COMMON_DIR = ADVENTURE_DIR + "common" + PATH_SEPARATOR; + public static final String LISTS_DIR = RES_DIR + "lists" + PATH_SEPARATOR; + public static final String SETLOOKUP_DIR = RES_DIR + "setlookup" + PATH_SEPARATOR; public static final String KEYWORD_LIST_FILE = LISTS_DIR + "NonStackingKWList.txt"; public static final String TYPE_LIST_FILE = LISTS_DIR + "TypeLists.txt"; public static final String SPECIAL_CARD_ACHIEVEMENT_LIST_FILE = LISTS_DIR + "special-card-achievements.txt"; @@ -68,96 +69,96 @@ public final class ForgeConstants { public static final String NET_ARCHIVE_BLOCK_DECKS_LIST_FILE = LISTS_DIR + "net-decks-archive-block.txt"; - public static final String CHANGES_FILE = ASSETS_DIR + "README.txt"; - public static final String CHANGES_FILE_NO_RELEASE = ASSETS_DIR + "CHANGES.txt"; - public static final String LICENSE_FILE = ASSETS_DIR + "LICENSE.txt"; - public static final String README_FILE = ASSETS_DIR + "MANUAL.txt"; - public static final String HOWTO_FILE = RES_DIR + "howto.txt"; + public static final String CHANGES_FILE = ASSETS_DIR + "README.txt"; + public static final String CHANGES_FILE_NO_RELEASE = ASSETS_DIR + "CHANGES.txt"; + public static final String LICENSE_FILE = ASSETS_DIR + "LICENSE.txt"; + public static final String README_FILE = ASSETS_DIR + "MANUAL.txt"; + public static final String HOWTO_FILE = RES_DIR + "howto.txt"; - public static final String DRAFT_DIR = RES_DIR + "draft" + PATH_SEPARATOR; - public static final String DRAFT_RANKINGS_FILE = DRAFT_DIR + "rankings.txt"; - public static final String SEALED_DIR = RES_DIR + "sealed" + PATH_SEPARATOR; - public static final String CARD_DATA_DIR = RES_DIR + "cardsfolder" + PATH_SEPARATOR; - public static final String TOKEN_DATA_DIR = RES_DIR + "tokenscripts" + PATH_SEPARATOR; - public static final String EDITIONS_DIR = RES_DIR + "editions" + PATH_SEPARATOR; - public static final String BLOCK_DATA_DIR = RES_DIR + "blockdata" + PATH_SEPARATOR; - public static final String FORMATS_DATA_DIR = RES_DIR + "formats" + PATH_SEPARATOR; - public static final String DECK_CUBE_DIR = RES_DIR + "cube" + PATH_SEPARATOR; - public static final String AI_PROFILE_DIR = RES_DIR + "ai" + PATH_SEPARATOR; - public static final String SOUND_DIR = RES_DIR + "sound" + PATH_SEPARATOR; - public static final String MUSIC_DIR = RES_DIR + "music" + PATH_SEPARATOR; - public static final String ADVENTURE_MUSIC_DIR = ADVENTURE_DEFAULT_PLANE_DIR + "music" + PATH_SEPARATOR; - public static final String LANG_DIR = RES_DIR + "languages" + PATH_SEPARATOR; - public static final String EFFECTS_DIR = RES_DIR + "effects" + PATH_SEPARATOR; - public static final String PUZZLE_DIR = RES_DIR + "puzzle" + PATH_SEPARATOR; - public static final String TUTORIAL_DIR = RES_DIR + "tutorial" + PATH_SEPARATOR; - public static final String DECK_GEN_DIR = RES_DIR + "deckgendecks" + PATH_SEPARATOR; - public static final String GENETIC_AI_DECK_DIR = RES_DIR + "geneticaidecks" + PATH_SEPARATOR; + public static final String DRAFT_DIR = RES_DIR + "draft" + PATH_SEPARATOR; + public static final String DRAFT_RANKINGS_FILE = DRAFT_DIR + "rankings.txt"; + public static final String SEALED_DIR = RES_DIR + "sealed" + PATH_SEPARATOR; + public static final String CARD_DATA_DIR = RES_DIR + "cardsfolder" + PATH_SEPARATOR; + public static final String TOKEN_DATA_DIR = RES_DIR + "tokenscripts" + PATH_SEPARATOR; + public static final String EDITIONS_DIR = RES_DIR + "editions" + PATH_SEPARATOR; + public static final String BLOCK_DATA_DIR = RES_DIR + "blockdata" + PATH_SEPARATOR; + public static final String FORMATS_DATA_DIR = RES_DIR + "formats" + PATH_SEPARATOR; + public static final String DECK_CUBE_DIR = RES_DIR + "cube" + PATH_SEPARATOR; + public static final String AI_PROFILE_DIR = RES_DIR + "ai" + PATH_SEPARATOR; + public static final String SOUND_DIR = RES_DIR + "sound" + PATH_SEPARATOR; + public static final String MUSIC_DIR = RES_DIR + "music" + PATH_SEPARATOR; + public static final String ADVENTURE_MUSIC_DIR = ADVENTURE_DEFAULT_PLANE_DIR + "music" + PATH_SEPARATOR; + public static final String ADVENTURE_COMMON_MUSIC_DIR = ADVENTURE_COMMON_DIR + "music" + PATH_SEPARATOR; + public static final String LANG_DIR = RES_DIR + "languages" + PATH_SEPARATOR; + public static final String EFFECTS_DIR = RES_DIR + "effects" + PATH_SEPARATOR; + public static final String PUZZLE_DIR = RES_DIR + "puzzle" + PATH_SEPARATOR; + public static final String TUTORIAL_DIR = RES_DIR + "tutorial" + PATH_SEPARATOR; + public static final String DECK_GEN_DIR = RES_DIR + "deckgendecks" + PATH_SEPARATOR; + public static final String GENETIC_AI_DECK_DIR = RES_DIR + "geneticaidecks" + PATH_SEPARATOR; - private static final String QUEST_DIR = RES_DIR + "quest" + PATH_SEPARATOR; - public static final String QUEST_WORLD_DIR = QUEST_DIR + "world" + PATH_SEPARATOR; - public static final String QUEST_PRECON_DIR = QUEST_DIR + "precons" + PATH_SEPARATOR; - public static final String PRICES_BOOSTER_FILE = QUEST_DIR + "booster-prices.txt"; - public static final String BAZAAR_DIR = QUEST_DIR + "bazaar" + PATH_SEPARATOR; - public static final String BAZAAR_INDEX_FILE = BAZAAR_DIR + "index.xml"; - public static final String DEFAULT_DUELS_DIR = QUEST_DIR + "duels"; - public static final String DEFAULT_CHALLENGES_DIR = QUEST_DIR + "challenges"; - public static final String THEMES_DIR = QUEST_DIR + "themes"; + private static final String QUEST_DIR = RES_DIR + "quest" + PATH_SEPARATOR; + public static final String QUEST_WORLD_DIR = QUEST_DIR + "world" + PATH_SEPARATOR; + public static final String QUEST_PRECON_DIR = QUEST_DIR + "precons" + PATH_SEPARATOR; + public static final String PRICES_BOOSTER_FILE = QUEST_DIR + "booster-prices.txt"; + public static final String BAZAAR_DIR = QUEST_DIR + "bazaar" + PATH_SEPARATOR; + public static final String BAZAAR_INDEX_FILE = BAZAAR_DIR + "index.xml"; + public static final String DEFAULT_DUELS_DIR = QUEST_DIR + "duels"; + public static final String DEFAULT_CHALLENGES_DIR = QUEST_DIR + "challenges"; + public static final String THEMES_DIR = QUEST_DIR + "themes"; - private static final String CONQUEST_DIR = RES_DIR + "conquest" + PATH_SEPARATOR; - public static final String CONQUEST_PLANES_DIR = CONQUEST_DIR + "planes" + PATH_SEPARATOR; - - public static final String BASE_SKINS_DIR = RES_DIR + "skins" + PATH_SEPARATOR; - public static final String COMMON_FONTS_DIR = RES_DIR + "fonts" + PATH_SEPARATOR; - public static final String DEFAULT_SKINS_DIR = BASE_SKINS_DIR + "default" + PATH_SEPARATOR; + private static final String CONQUEST_DIR = RES_DIR + "conquest" + PATH_SEPARATOR; + public static final String CONQUEST_PLANES_DIR = CONQUEST_DIR + "planes" + PATH_SEPARATOR; + public static final String BASE_SKINS_DIR = RES_DIR + "skins" + PATH_SEPARATOR; + public static final String COMMON_FONTS_DIR = RES_DIR + "fonts" + PATH_SEPARATOR; + public static final String DEFAULT_SKINS_DIR = BASE_SKINS_DIR + "default" + PATH_SEPARATOR; //don't associate these skin files with a directory since skin directory will be determined later - public static final String SPRITE_ICONS_FILE = "sprite_icons.png"; - public static final String SPRITE_FOILS_FILE = "sprite_foils.png"; - public static final String SPRITE_OLD_FOILS_FILE = "sprite_old_foils.png"; - public static final String SPRITE_TROPHIES_FILE = "sprite_trophies.png"; - public static final String SPRITE_ABILITY_FILE = "sprite_ability.png"; - public static final String SPRITE_BORDER_FILE = "sprite_border.png"; - public static final String SPRITE_ADV_BUTTONS_FILE = "sprite_adv_buttons.png"; - public static final String SPRITE_BUTTONS_FILE = "sprite_buttons.png"; - public static final String SPRITE_DECKBOX_FILE = "sprite_deckbox.png"; - public static final String SPRITE_START_FILE = "sprite_start.png"; - public static final String SPRITE_MANAICONS_FILE = "sprite_manaicons.png"; - public static final String SPRITE_PHYREXIAN_FILE = "sprite_phyrexian.png"; - public static final String SPRITE_CURSOR_FILE = "sprite_cursor.png"; - public static final String SPRITE_AVATARS_FILE = "sprite_avatars.png"; - public static final String SPRITE_CRACKS_FILE = "sprite_cracks.png"; - public static final String SPRITE_SLEEVES_FILE = "sprite_sleeves.png"; - public static final String SPRITE_SLEEVES2_FILE = "sprite_sleeves2.png"; - public static final String SPRITE_FAVICONS_FILE = "sprite_favicons.png"; - public static final String SPRITE_PLANAR_CONQUEST_FILE = "sprite_planar_conquest.png"; - public static final String SPRITE_ADVENTURE_FILE = "sprite_adventure.png"; - public static final String SPRITE_SETLOGO_FILE = "sprite_setlogo.png"; - public static final String SPRITE_WATERMARK_FILE = "sprite_watermark.png"; - public static final String SPRITE_DRAFTRANKS_FILE = "sprite_draftranks.png"; - public static final String FONT_FILE = "font1.ttf"; - public static final String SPLASH_BG_FILE = "bg_splash.png"; - public static final String MATCH_BG_FILE = "bg_match.jpg"; - public static final String MATCH_BG_DAY_FILE = "bg_day.jpg"; - public static final String MATCH_BG_NIGHT_FILE = "bg_night.jpg"; - public static final String ADV_MATCH_BG_FILE = "adv_bg_match.jpg"; - public static final String ADV_MATCH_BG_DAY_FILE = "adv_bg_match_day.jpg"; - public static final String ADV_MATCH_BG_NIGHT_FILE= "adv_bg_match_nigh.jpg"; - public static final String ADV_TEXTURE_BG_FILE = "adv_bg_texture.jpg"; - public static final String TEXTURE_BG_FILE = "bg_texture.jpg"; - public static final String SPACE_BG_FILE = "bg_space.png"; - public static final String CHAOS_WHEEL_IMG_FILE = "bg_chaos_wheel.png"; - public static final String DRAFT_DECK_IMG_FILE = "bg_draft_deck.png"; + public static final String SPRITE_ICONS_FILE = "sprite_icons.png"; + public static final String SPRITE_FOILS_FILE = "sprite_foils.png"; + public static final String SPRITE_OLD_FOILS_FILE = "sprite_old_foils.png"; + public static final String SPRITE_TROPHIES_FILE = "sprite_trophies.png"; + public static final String SPRITE_ABILITY_FILE = "sprite_ability.png"; + public static final String SPRITE_BORDER_FILE = "sprite_border.png"; + public static final String SPRITE_ADV_BUTTONS_FILE = "sprite_adv_buttons.png"; + public static final String SPRITE_BUTTONS_FILE = "sprite_buttons.png"; + public static final String SPRITE_DECKBOX_FILE = "sprite_deckbox.png"; + public static final String SPRITE_START_FILE = "sprite_start.png"; + public static final String SPRITE_MANAICONS_FILE = "sprite_manaicons.png"; + public static final String SPRITE_PHYREXIAN_FILE = "sprite_phyrexian.png"; + public static final String SPRITE_CURSOR_FILE = "sprite_cursor.png"; + public static final String SPRITE_AVATARS_FILE = "sprite_avatars.png"; + public static final String SPRITE_CRACKS_FILE = "sprite_cracks.png"; + public static final String SPRITE_SLEEVES_FILE = "sprite_sleeves.png"; + public static final String SPRITE_SLEEVES2_FILE = "sprite_sleeves2.png"; + public static final String SPRITE_FAVICONS_FILE = "sprite_favicons.png"; + public static final String SPRITE_PLANAR_CONQUEST_FILE = "sprite_planar_conquest.png"; + public static final String SPRITE_ADVENTURE_FILE = "sprite_adventure.png"; + public static final String SPRITE_SETLOGO_FILE = "sprite_setlogo.png"; + public static final String SPRITE_WATERMARK_FILE = "sprite_watermark.png"; + public static final String SPRITE_DRAFTRANKS_FILE = "sprite_draftranks.png"; + public static final String FONT_FILE = "font1.ttf"; + public static final String SPLASH_BG_FILE = "bg_splash.png"; + public static final String MATCH_BG_FILE = "bg_match.jpg"; + public static final String MATCH_BG_DAY_FILE = "bg_day.jpg"; + public static final String MATCH_BG_NIGHT_FILE = "bg_night.jpg"; + public static final String ADV_MATCH_BG_FILE = "adv_bg_match.jpg"; + public static final String ADV_MATCH_BG_DAY_FILE = "adv_bg_match_day.jpg"; + public static final String ADV_MATCH_BG_NIGHT_FILE = "adv_bg_match_nigh.jpg"; + public static final String ADV_TEXTURE_BG_FILE = "adv_bg_texture.jpg"; + public static final String TEXTURE_BG_FILE = "bg_texture.jpg"; + public static final String SPACE_BG_FILE = "bg_space.png"; + public static final String CHAOS_WHEEL_IMG_FILE = "bg_chaos_wheel.png"; + public static final String DRAFT_DECK_IMG_FILE = "bg_draft_deck.png"; //Adventure locations - public static final String ADV_BG_SWAMP_FILE = "adv_bg_swamp.jpg"; - public static final String ADV_BG_FOREST_FILE = "adv_bg_forest.jpg"; - public static final String ADV_BG_MOUNTAIN_FILE = "adv_bg_mountain.jpg"; - public static final String ADV_BG_ISLAND_FILE = "adv_bg_island.jpg"; - public static final String ADV_BG_PLAINS_FILE = "adv_bg_plains.jpg"; - public static final String ADV_BG_WASTE_FILE = "adv_bg_waste.jpg"; - public static final String ADV_BG_COMMON_FILE = "adv_bg_common.jpg"; - public static final String ADV_BG_CAVE_FILE = "adv_bg_cave.jpg"; - public static final String ADV_BG_DUNGEON_FILE = "adv_bg_dungeon.jpg"; - public static final String ADV_BG_CASTLE_FILE = "adv_bg_castle.jpg"; + public static final String ADV_BG_SWAMP_FILE = "adv_bg_swamp.jpg"; + public static final String ADV_BG_FOREST_FILE = "adv_bg_forest.jpg"; + public static final String ADV_BG_MOUNTAIN_FILE = "adv_bg_mountain.jpg"; + public static final String ADV_BG_ISLAND_FILE = "adv_bg_island.jpg"; + public static final String ADV_BG_PLAINS_FILE = "adv_bg_plains.jpg"; + public static final String ADV_BG_WASTE_FILE = "adv_bg_waste.jpg"; + public static final String ADV_BG_COMMON_FILE = "adv_bg_common.jpg"; + public static final String ADV_BG_CAVE_FILE = "adv_bg_cave.jpg"; + public static final String ADV_BG_DUNGEON_FILE = "adv_bg_dungeon.jpg"; + public static final String ADV_BG_CASTLE_FILE = "adv_bg_castle.jpg"; //Planes addon public static final String BG_1 = "Academy_at_Tolaria_West.jpg"; @@ -478,7 +479,7 @@ public final class ForgeConstants { TOP("Top of Card"), BOTTOM("Bottom of Card"); - private String name; + private final String name; CounterDisplayLocation(final String name) { this.name = name; diff --git a/forge-gui/src/main/java/forge/sound/MusicPlaylist.java b/forge-gui/src/main/java/forge/sound/MusicPlaylist.java index a884302fd2d..bb249a028ad 100644 --- a/forge-gui/src/main/java/forge/sound/MusicPlaylist.java +++ b/forge-gui/src/main/java/forge/sound/MusicPlaylist.java @@ -1,26 +1,30 @@ package forge.sound; +import forge.gui.GuiBase; +import forge.localinstance.properties.ForgeConstants; +import forge.util.MyRandom; +import org.apache.commons.lang3.ArrayUtils; + import java.io.File; import java.io.FilenameFilter; -import forge.util.MyRandom; - public enum MusicPlaylist { - BLACK ("black/"), - BLUE ("blue/"), - RED ("red/"), - GREEN ("green/"), - WHITE ("white/"), - CASTLE ("castle/"), - CAVE ("cave/"), - TOWN ("town/"), - BOSS ("boss/"), - MENUS ("menus/"), - MATCH ("match/"); + BLACK ("black/"), + BLUE ("blue/"), + RED ("red/"), + GREEN ("green/"), + WHITE ("white/"), + COLORLESS ("colorless/"), + CASTLE ("castle/"), + CAVE ("cave/"), + TOWN ("town/"), + BOSS ("boss/"), + MENUS ("menus/"), + MATCH ("match/"); private final String subDir; private int mostRecentTrackIdx = -1; - private String[] filenames; + private File[] filenames; private static boolean isInvalidated = false; MusicPlaylist(String subDir0) { @@ -32,20 +36,21 @@ public enum MusicPlaylist { } public String getRandomFilename() { + String path = SoundSystem.instance.getMusicDirectory() + subDir; if (filenames == null || isInvalidated) { try { - FilenameFilter filter = new FilenameFilter(){ - @Override - public boolean accept(File file, String name) { - return name.endsWith(".mp3") || name.endsWith(".wav") || name.endsWith(".m4a"); - } - }; - filenames = new File(SoundSystem.instance.getMusicDirectory() + subDir).list(filter); - if (filenames == null) filenames = new String[0]; + FilenameFilter filter = (file, name) -> name.endsWith(".mp3") || name.endsWith(".wav") || name.endsWith(".m4a"); + filenames = new File(path).listFiles(filter); + if (GuiBase.isAdventureMode() && (filenames == null || ArrayUtils.isEmpty(filenames))) { + path = ForgeConstants.ADVENTURE_COMMON_MUSIC_DIR + subDir; + filenames = new File(path).listFiles(filter); + } + if (filenames == null) + filenames = new File[0]; } catch (Exception e) { e.printStackTrace(); - filenames = new String[0]; + filenames = new File[0]; } isInvalidated = false; } @@ -64,21 +69,21 @@ public enum MusicPlaylist { mostRecentTrackIdx = newIndex; } - return SoundSystem.instance.getMusicDirectory() + subDir + filenames[mostRecentTrackIdx]; + return filenames[mostRecentTrackIdx].getPath(); } public String getNewRandomFilename() { - String[] music; + File[] music; + String path = SoundSystem.instance.getMusicDirectory() + subDir; try { - FilenameFilter filter = new FilenameFilter(){ - @Override - public boolean accept(File file, String name) { - return name.endsWith(".mp3") || name.endsWith(".wav") || name.endsWith(".m4a"); - } - }; - music = new File(SoundSystem.instance.getMusicDirectory() + subDir).list(filter); + FilenameFilter filter = (file, name) -> name.endsWith(".mp3") || name.endsWith(".wav") || name.endsWith(".m4a"); + music = new File(path).listFiles(filter); + if (GuiBase.isAdventureMode() && (music == null || ArrayUtils.isEmpty(music))) { + path = ForgeConstants.ADVENTURE_COMMON_MUSIC_DIR + subDir; + music = new File(path).listFiles(filter); + } if (music == null) - return null; + return null; } catch (Exception e) { return null; @@ -87,6 +92,7 @@ public enum MusicPlaylist { return null; int index = MyRandom.getRandom().nextInt(music.length); - return SoundSystem.instance.getMusicDirectory() + subDir + music[index]; + System.out.println("Looking up " +path + ForgeConstants.PATH_SEPARATOR + music[index]); + return music[index].getPath(); } }