NotAttackedSinceLastUpkeepOf = Lists.newArrayList();
@@ -59,6 +60,12 @@ public class CardDamageHistory {
if (defender != null) {
attackedThisTurn.add(defender);
+ if (defender instanceof Card) {
+ final Card def = (Card) defender;
+ if (def.isBattle()) {
+ attackedBattleThisTurn = true;
+ }
+ }
}
}
/**
@@ -84,6 +91,9 @@ public class CardDamageHistory {
public final boolean hasAttackedThisTurn(GameEntity e) {
return this.attackedThisTurn.contains(e);
}
+ public final boolean hasAttackedBattleThisTurn() {
+ return this.attackedBattleThisTurn;
+ }
/**
*
* Setter for the field creatureAttackedLastTurn.
@@ -272,6 +282,7 @@ public class CardDamageHistory {
public void newTurn() {
attackedThisTurn.clear();
+ attackedBattleThisTurn = false;
damagedThisCombat.clear();
damageDoneThisTurn.clear();
diff --git a/forge-game/src/main/java/forge/game/card/CardProperty.java b/forge-game/src/main/java/forge/game/card/CardProperty.java
index eae03fdeb38..2bd75aaebd3 100644
--- a/forge-game/src/main/java/forge/game/card/CardProperty.java
+++ b/forge-game/src/main/java/forge/game/card/CardProperty.java
@@ -218,6 +218,14 @@ public class CardProperty {
|| !sourceController.getOpponents().contains(card.getProtectingPlayer())) {
return false;
}
+ } else if (property.startsWith("ProtectedBy")) {
+ if (card.getProtectingPlayer() == null) {
+ return false;
+ }
+ final List lp = AbilityUtils.getDefinedPlayers(source, property.substring(12), spellAbility);
+ if (!lp.contains(card.getProtectingPlayer())) {
+ return false;
+ }
} else if (property.startsWith("DefendingPlayer")) {
Player p = property.endsWith("Ctrl") ? controller : card.getOwner();
if (!game.getPhaseHandler().inCombat()) {
@@ -1238,6 +1246,10 @@ public class CardProperty {
if (card.getDamageHistory().getCreatureAttacksThisTurn() == 0) {
return false;
}
+ } else if (property.startsWith("attackedBattleThisTurn")) {
+ if (!card.getDamageHistory().hasAttackedBattleThisTurn()) {
+ return false;
+ }
} else if (property.startsWith("attackedYouThisTurn")) {
if (!card.getDamageHistory().hasAttackedThisTurn(sourceController)) {
return false;
diff --git a/forge-gui/res/cardsfolder/upcoming/rampaging_raptor.txt b/forge-gui/res/cardsfolder/upcoming/rampaging_raptor.txt
new file mode 100644
index 00000000000..8849399ff1c
--- /dev/null
+++ b/forge-gui/res/cardsfolder/upcoming/rampaging_raptor.txt
@@ -0,0 +1,11 @@
+Name:Rampaging Raptor
+ManaCost:2 R R
+Types:Creature Dinosaur
+PT:4/4
+K:Trample
+K:Haste
+A:AB$ Pump | Cost$ 2 R | NumAtt$ 2 | SpellDescription$ CARDNAME gets +2/+0 until end of turn.
+T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Opponent | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ Whenever CARDNAME deals combat damage to an opponent, it deals that much damage to target planeswalker that player controls or battle that player protects.
+SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Planeswalker.ControlledBy TriggeredTarget,Battle.ProtectedBy TriggeredTarget | TgtPrompt$ Select target planeswalker that player controls or battle that player protects | NumDmg$ X
+SVar:X:TriggerCount$DamageAmount
+Oracle:Trample, haste\n{2}{R}: Rampaging Raptor gets +2/+0 until end of turn.\nWhenever Rampaging Raptor deals combat damage to an opponent, it deals that much damage to target planeswalker that player controls or battle that player protects.
diff --git a/forge-gui/res/cardsfolder/upcoming/war_historian.txt b/forge-gui/res/cardsfolder/upcoming/war_historian.txt
new file mode 100644
index 00000000000..e1dcb3b4d54
--- /dev/null
+++ b/forge-gui/res/cardsfolder/upcoming/war_historian.txt
@@ -0,0 +1,8 @@
+Name:War Historian
+ManaCost:2 G
+Types:Creature Human Monk
+PT:3/3
+K:Reach
+S:Mode$ Continuous | Affected$ Card.Self+attackedBattleThisTurn | AddKeyword$ Indestructible | Description$ CARDNAME has indestructible as long as it attacked a battle this turn.
+AI:RemoveDeck:Random
+Oracle:Reach\nWar Historian has indestructible as long as it attacked a battle this turn.
diff --git a/forge-gui/res/cardsfolder/upcoming/wildwood_escort.txt b/forge-gui/res/cardsfolder/upcoming/wildwood_escort.txt
new file mode 100644
index 00000000000..c69dfea3de4
--- /dev/null
+++ b/forge-gui/res/cardsfolder/upcoming/wildwood_escort.txt
@@ -0,0 +1,11 @@
+Name:Wildwood Escort
+ManaCost:4 G
+Types:Creature Elf Warrior
+PT:3/3
+T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return target creature or battle card from your graveyard to your hand.
+SVar:TrigReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | TgtPrompt$ Select target creature or battle card in your graveyard | ValidTgts$ Creature.YouOwn,Battle.YouOwn
+R:Event$ Moved | ActiveZones$ Battlefield | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | ReplaceWith$ Exile | Description$ If CARDNAME would die, exile it instead.
+SVar:Exile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | Defined$ ReplacedCard
+DeckHints:Type$Battle
+DeckHas:Ability$Graveyard
+Oracle:When Wildwood Escort enters the battlefield, return target creature or battle card from your graveyard to your hand.\nIf Wildwood Escort would die, exile it instead.
diff --git a/forge-gui/res/languages/de-DE.properties b/forge-gui/res/languages/de-DE.properties
index 66bc9749d37..19688b1830d 100644
--- a/forge-gui/res/languages/de-DE.properties
+++ b/forge-gui/res/languages/de-DE.properties
@@ -1858,6 +1858,7 @@ lblSearchPlayerZoneConfirm=Durchsuche {0} {1}?
lblCardMatchSearchingTypeInAlternateZones=Karten entsprechen deiner Suche in alternativen Zonen
lblLookingCardIn=Schaue nach Karten in
lblDoYouWantPlayCard=Möchtest du {0} spielen?
+lblDoYouWantPlayCardTransformed=Möchtest du {0} verwandelt spielen?
lblSelectCardFromPlayerZone=Wähle Karte von {0} {1}
lblSelectUpToNumCardFromPlayerZone=Wähle bis zu {0} Karte(n) von {1} {2}
lblSelectCardsFromPlayerZone=Wähle Karten {0} {1}
diff --git a/forge-gui/res/languages/en-US.properties b/forge-gui/res/languages/en-US.properties
index a3000025656..5189e430adb 100644
--- a/forge-gui/res/languages/en-US.properties
+++ b/forge-gui/res/languages/en-US.properties
@@ -1863,6 +1863,7 @@ lblSearchPlayerZoneConfirm=Search {0} {1}?
lblCardMatchSearchingTypeInAlternateZones=cards match your searching type in Alternate Zones.
lblLookingCardIn=Looking at cards in
lblDoYouWantPlayCard=Do you want to play {0}?
+lblDoYouWantPlayCardTransformed=Do you want to play {0} transformed?
lblSelectCardFromPlayerZone=Select a card from {0} {1}
lblSelectUpToNumCardFromPlayerZone=Select up to {0} cards from {1} {2}
lblSelectCardsFromPlayerZone=Select cards from {0} {1}
diff --git a/forge-gui/res/languages/es-ES.properties b/forge-gui/res/languages/es-ES.properties
index 30fa9aba09d..e32553c66d6 100644
--- a/forge-gui/res/languages/es-ES.properties
+++ b/forge-gui/res/languages/es-ES.properties
@@ -1859,6 +1859,7 @@ lblSearchPlayerZoneConfirm=¿Buscar {0} {1}?
lblCardMatchSearchingTypeInAlternateZones=las cartas coinciden con tu tipo de búsqueda en las zonas alternativas.
lblLookingCardIn=Mirando las cartas en
lblDoYouWantPlayCard=¿Quieres jugar {0}?
+lblDoYouWantPlayCardTransformed=¿Quieres jugar {0} transformada?
lblSelectCardFromPlayerZone=Selecciona una carta de {0} {1}
lblSelectUpToNumCardFromPlayerZone=Selecciona hasta {0} cartas de {1} {2}
lblSelectCardsFromPlayerZone=Selecciona cartas de {0} {1}
diff --git a/forge-gui/res/languages/fr-FR.properties b/forge-gui/res/languages/fr-FR.properties
index 894bb4b92f5..47aefb3a90f 100644
--- a/forge-gui/res/languages/fr-FR.properties
+++ b/forge-gui/res/languages/fr-FR.properties
@@ -1860,6 +1860,7 @@ lblSearchPlayerZoneConfirm=Rechercher {0} {1} ?
lblCardMatchSearchingTypeInAlternateZones=les cartes correspondent à votre type de recherche dans les zones alternatives.
lblLookingCardIn=Regarder les cartes dans
lblDoYouWantPlayCard=Voulez-vous jouer à {0} ?
+lblDoYouWantPlayCardTransformed=Voulez-vous jouer à {0} transformée?
lblSelectCardFromPlayerZone=Sélectionnez une carte de {0} {1}
lblSelectUpToNumCardFromPlayerZone=S\u00e9lectionnez jusqu''\u00e0 {0} cartes de {1} {2}
lblSelectCardsFromPlayerZone=Sélectionner les cartes de {0} {1}
diff --git a/forge-gui/res/languages/it-IT.properties b/forge-gui/res/languages/it-IT.properties
index 20950183eca..e27c9a00769 100644
--- a/forge-gui/res/languages/it-IT.properties
+++ b/forge-gui/res/languages/it-IT.properties
@@ -1858,6 +1858,7 @@ lblSearchPlayerZoneConfirm=Cerchi {1} di {0}?
lblCardMatchSearchingTypeInAlternateZones=carte corrispondono alla tua ricerca in zone diverse..
lblLookingCardIn=Stai guardando le carte in
lblDoYouWantPlayCard=Vuoi giocare {0}?
+lblDoYouWantPlayCardTransformed=Vuoi giocare {0} transformata?
lblSelectCardFromPlayerZone=Scegl;i una carta da {1} di {0}
lblSelectUpToNumCardFromPlayerZone=Scegli fino a {0} carte da {2} di {1}
lblSelectCardsFromPlayerZone=Scegli carte a {1} di {0}
diff --git a/forge-gui/res/languages/ja-JP.properties b/forge-gui/res/languages/ja-JP.properties
index d1642860f10..f4992d475cd 100644
--- a/forge-gui/res/languages/ja-JP.properties
+++ b/forge-gui/res/languages/ja-JP.properties
@@ -1858,6 +1858,7 @@ lblSearchPlayerZoneConfirm={0} {1}を探しますか?
lblCardMatchSearchingTypeInAlternateZones=枚もう一つの領域のカードが探すタイプと一致します。
lblLookingCardIn=カードを見る
lblDoYouWantPlayCard={0}をプレイしますか?
+lblDoYouWantPlayCardTransformed={0}をプレイしますか変換?
lblSelectCardFromPlayerZone={0} {1}から 1枚のカードを選ぶ
lblSelectUpToNumCardFromPlayerZone={1} {2}から最大 {0}枚のカードを選ぶ
lblSelectCardsFromPlayerZone={0} {1}からカードを選ぶ
diff --git a/forge-gui/res/languages/pt-BR.properties b/forge-gui/res/languages/pt-BR.properties
index 34bd93140ca..2982074468c 100644
--- a/forge-gui/res/languages/pt-BR.properties
+++ b/forge-gui/res/languages/pt-BR.properties
@@ -1920,6 +1920,7 @@ lblSearchPlayerZoneConfirm=Procurar {0} {1}?
lblCardMatchSearchingTypeInAlternateZones=cartas que correspondem à busca de tipo em Zonas Alternativas.
lblLookingCardIn=Olhando as cartas em
lblDoYouWantPlayCard=Quer jogar {0}?
+lblDoYouWantPlayCardTransformed=Você quer jogar {0} transformada?
lblSelectCardFromPlayerZone=Escolha a carta de {0} {1}
lblSelectUpToNumCardFromPlayerZone=Escolha até {0} cartas de {1} {2}
lblSelectCardsFromPlayerZone=Escolha cartas de {0} {1}
diff --git a/forge-gui/res/languages/zh-CN.properties b/forge-gui/res/languages/zh-CN.properties
index c3c3fe5acf7..d15e7bfcbb3 100644
--- a/forge-gui/res/languages/zh-CN.properties
+++ b/forge-gui/res/languages/zh-CN.properties
@@ -1862,6 +1862,7 @@ lblSearchPlayerZoneConfirm=搜索{0}的{1}?
lblCardMatchSearchingTypeInAlternateZones=在你的备用区域搜索匹配类型的卡牌。
lblLookingCardIn=看牌自
lblDoYouWantPlayCard=你想要使用{0}?
+lblDoYouWantPlayCardTransformed=你想要使用转化{0}?
lblSelectCardFromPlayerZone=选择一张牌从{0}的{1}
lblSelectUpToNumCardFromPlayerZone=最多选择{0}张牌来自{1}的{2}
lblSelectCardsFromPlayerZone=选择卡牌来自{0}的{1}
From 0a82769405b50253fc57ca39b6237fdf913dfdcf Mon Sep 17 00:00:00 2001
From: Northmoc
Date: Thu, 13 Apr 2023 10:19:42 -0400
Subject: [PATCH 07/18] add some battle cards
---
.../h/hidetsugu_devouring_chaos.txt | 6 ++--
...nvasion_of_ixalan_belligerent_regisaur.txt | 20 +++++++++++++
...ion_of_kaldheim_pyre_of_the_world_tree.txt | 29 +++++++++++++++++++
3 files changed, 52 insertions(+), 3 deletions(-)
create mode 100644 forge-gui/res/cardsfolder/upcoming/invasion_of_ixalan_belligerent_regisaur.txt
create mode 100644 forge-gui/res/cardsfolder/upcoming/invasion_of_kaldheim_pyre_of_the_world_tree.txt
diff --git a/forge-gui/res/cardsfolder/h/hidetsugu_devouring_chaos.txt b/forge-gui/res/cardsfolder/h/hidetsugu_devouring_chaos.txt
index 5cf23551f75..ec6ce4b3bd1 100644
--- a/forge-gui/res/cardsfolder/h/hidetsugu_devouring_chaos.txt
+++ b/forge-gui/res/cardsfolder/h/hidetsugu_devouring_chaos.txt
@@ -3,12 +3,12 @@ ManaCost:3 B
Types:Legendary Creature Ogre Demon
PT:4/4
A:AB$ Scry | Cost$ B Sac<1/Creature> | ScryNum$ 2 | SpellDescription$ Scry 2.
-A:AB$ Dig | Cost$ 2 R T | Defined$ You | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | AILogic$ ExileAndPlayUntilEOT | StackDescription$ SpellDescription | SpellDescription$ Exile the top card of your library. You may play that card this turn. When you exile a nonland card this way, CARDNAME deals damage equal to the exiled card's mana value to any target.
+A:AB$ Dig | Cost$ 2 R T | Defined$ You | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | AILogic$ ExileAndPlayUntilEOT | StackDescription$ SpellDescription | SpellDescription$ Exile the top card of your library. You may play that card this turn.
SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ Play | SubAbility$ DBImmediateTrigger | ExileOnMoved$ Exile
SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play this card this turn.
-SVar:DBImmediateTrigger:DB$ ImmediateTrigger | ConditionDefined$ Remembered | ConditionPresent$ Card.nonLand | Execute$ TrigDealDamage | RememberObjects$ RememberedCard | SubAbility$ DBCleanup | StackDescription$ None | TriggerDescription$ When you exile a nonland card this way, CARDNAME deals damage equal to the exiled card's mana value to any target.
+SVar:DBImmediateTrigger:DB$ ImmediateTrigger | ConditionDefined$ Remembered | ConditionPresent$ Card.nonLand | Execute$ TrigDealDamage | RememberObjects$ RememberedCard | SubAbility$ DBCleanup | TriggerDescription$ When you exile a nonland card this way, CARDNAME deals damage equal to the exiled card's mana value to any target.
SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ X
SVar:X:TriggerRemembered$CardManaCost
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
Deckhas:Ability$Sacrifice
-Oracle:{B}, Sacrifice a creature: Scry 2.\n{2}{R}, {T}, Exile the top card of your library. You may play that card this turn. When you exile a nonland card this way, Hidetsugu, Devouring Chaos deals damage equal to the exiled card's mana value to any target.
+Oracle:{B}, Sacrifice a creature: Scry 2.\n{2}{R}, {T}: Exile the top card of your library. You may play that card this turn. When you exile a nonland card this way, Hidetsugu, Devouring Chaos deals damage equal to the exiled card's mana value to any target.
diff --git a/forge-gui/res/cardsfolder/upcoming/invasion_of_ixalan_belligerent_regisaur.txt b/forge-gui/res/cardsfolder/upcoming/invasion_of_ixalan_belligerent_regisaur.txt
new file mode 100644
index 00000000000..06364711329
--- /dev/null
+++ b/forge-gui/res/cardsfolder/upcoming/invasion_of_ixalan_belligerent_regisaur.txt
@@ -0,0 +1,20 @@
+Name:Invasion of Ixalan
+ManaCost:1 G
+Types:Battle Siege
+Defense:4
+T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDig | TriggerDescription$ When CARDNAME enters the battlefield, look at the top five cards of your library. You may reveal a permanent card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
+SVar:TrigDig:DB$ Dig | DigNum$ 5 | ChangeNum$ 1 | Optional$ True | ChangeValid$ Permanent | ForceRevealToController$ True | RestRandomOrder$ True
+AlternateMode:DoubleFaced
+Oracle:(As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)\nWhen Invasion of Ixalan enters the battlefield, look at the top five cards of your library. You may reveal a permanent card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
+
+ALTERNATE
+
+Name:Belligerent Regisaur
+ManaCost:no cost
+Colors:green
+Types:Creature Dinosaur
+PT:4/3
+K:Trample
+T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a spell, CARDNAME gains indestructible until end of turn.
+SVar:TrigPump:DB$ Pump | KW$ Indestructible
+Oracle:Trample\nWhenever you cast a spell, Belligerent Regisaur gains indestructible until end of turn.
diff --git a/forge-gui/res/cardsfolder/upcoming/invasion_of_kaldheim_pyre_of_the_world_tree.txt b/forge-gui/res/cardsfolder/upcoming/invasion_of_kaldheim_pyre_of_the_world_tree.txt
new file mode 100644
index 00000000000..98ec4966173
--- /dev/null
+++ b/forge-gui/res/cardsfolder/upcoming/invasion_of_kaldheim_pyre_of_the_world_tree.txt
@@ -0,0 +1,29 @@
+Name:Invasion of Kaldheim
+ManaCost:3 R
+Types:Battle Siege
+Defense:4
+T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExileHand | TriggerDescription$ When CARDNAME enters the battlefield, exile all cards from your hand, then draw that many cards. Until the end of your next turn, you may play cards exiled this way.
+SVar:TrigExileHand:DB$ ChangeZoneAll | ChangeType$ Card.YouOwn | Origin$ Hand | Destination$ Exile | RememberChanged$ True | SubAbility$ DBDraw
+SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ Y | SubAbility$ DBEffect
+SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ Play | Duration$ UntilTheEndOfYourNextTurn | ForgetOnMoved$ Exile | SubAbility$ DBCleanup
+SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ Until the end of your next turn, you may play cards exiled this way.
+SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
+SVar:Y:Count$RememberedSize
+AlternateMode:DoubleFaced
+Oracle:(As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)\nWhen Invasion of Kaldheim enters the battlefield, exile all cards from your hand, then draw that many cards. Until the end of your next turn, you may play cards exiled this way.
+
+ALTERNATE
+
+Name:Pyre of the World Tree
+ManaCost:no cost
+Colors:red
+Types:Enchantment
+A:AB$ DealDamage | Cost$ Discard<1/Land> | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 2 | SpellDescription$ CARDNAME deals 2 damage to any target.
+T:Mode$ Discarded | ValidCard$ Land.YouOwn | TriggerZones$ Battlefield | Execute$ TrigExile | TriggerDescription$ Whenever you discard a land card, exile the top card of your library. You may play that card this turn.
+SVar:TrigExile:DB$ Dig | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | AILogic$ ExileAndPlayUntilEOT
+SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ Play | ExileOnMoved$ Exile | SubAbility$ DBCleanup
+SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play that card this turn.
+SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
+DeckHas:Ability$Discard
+DeckHints:Ability$Discard
+Oracle:Discard a land card: Pyre of the World Tree deals 2 damage to any target.\nWhenever you discard a land card, exile the top card of your library. You may play that card this turn.
From 219b06a46a78a42dde38617b2471b20b0007670c Mon Sep 17 00:00:00 2001
From: Northmoc
Date: Thu, 13 Apr 2023 12:30:15 -0400
Subject: [PATCH 08/18] hidetsugu_devouring_chaos.txt better
---
.../game/ability/effects/ImmediateTriggerEffect.java | 2 ++
forge-gui/res/cardsfolder/h/hidetsugu_devouring_chaos.txt | 8 ++++----
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/forge-game/src/main/java/forge/game/ability/effects/ImmediateTriggerEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ImmediateTriggerEffect.java
index cf2c22ca2b7..9584388d40f 100644
--- a/forge-game/src/main/java/forge/game/ability/effects/ImmediateTriggerEffect.java
+++ b/forge-game/src/main/java/forge/game/ability/effects/ImmediateTriggerEffect.java
@@ -23,6 +23,8 @@ public class ImmediateTriggerEffect extends SpellAbilityEffect {
protected String getStackDescription(SpellAbility sa) {
if (sa.hasParam("TriggerDescription")) {
return sa.getParam("TriggerDescription");
+ } else if (sa.hasParam("SpellDescription")) {
+ return sa.getParam("SpellDescription");
}
return "";
diff --git a/forge-gui/res/cardsfolder/h/hidetsugu_devouring_chaos.txt b/forge-gui/res/cardsfolder/h/hidetsugu_devouring_chaos.txt
index ec6ce4b3bd1..ca7bd4fc88b 100644
--- a/forge-gui/res/cardsfolder/h/hidetsugu_devouring_chaos.txt
+++ b/forge-gui/res/cardsfolder/h/hidetsugu_devouring_chaos.txt
@@ -3,10 +3,10 @@ ManaCost:3 B
Types:Legendary Creature Ogre Demon
PT:4/4
A:AB$ Scry | Cost$ B Sac<1/Creature> | ScryNum$ 2 | SpellDescription$ Scry 2.
-A:AB$ Dig | Cost$ 2 R T | Defined$ You | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | AILogic$ ExileAndPlayUntilEOT | StackDescription$ SpellDescription | SpellDescription$ Exile the top card of your library. You may play that card this turn.
-SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ Play | SubAbility$ DBImmediateTrigger | ExileOnMoved$ Exile
-SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play this card this turn.
-SVar:DBImmediateTrigger:DB$ ImmediateTrigger | ConditionDefined$ Remembered | ConditionPresent$ Card.nonLand | Execute$ TrigDealDamage | RememberObjects$ RememberedCard | SubAbility$ DBCleanup | TriggerDescription$ When you exile a nonland card this way, CARDNAME deals damage equal to the exiled card's mana value to any target.
+A:AB$ Dig | Cost$ 2 R T | Defined$ You | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | AILogic$ ExileAndPlayUntilEOT | StackDescription$ SpellDescription | SpellDescription$ Exile the top card of your library.
+SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ Play | SubAbility$ DBImmediateTrigger | ExileOnMoved$ Exile | SpellDescription$ You may play that card this turn.
+SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play that card this turn.
+SVar:DBImmediateTrigger:DB$ ImmediateTrigger | ConditionDefined$ Remembered | ConditionPresent$ Card.nonLand | Execute$ TrigDealDamage | RememberObjects$ RememberedCard | SubAbility$ DBCleanup | SpellDescription$ When you exile a nonland card this way, CARDNAME deals damage equal to the exiled card's mana value to any target.
SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ X
SVar:X:TriggerRemembered$CardManaCost
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
From 8ccdabcdf67ba63ae9ea1879ff73b651e0047819 Mon Sep 17 00:00:00 2001
From: Anthony Calosa
Date: Fri, 14 Apr 2023 02:49:09 +0800
Subject: [PATCH 09/18] update GameHUD, InventoryScene - can equip activatable
items for quick access on GameHUD
---
.../adventure/player/AdventurePlayer.java | 577 ++++++++++--------
.../forge/adventure/scene/InventoryScene.java | 11 +-
.../forge/adventure/scene/MapViewScene.java | 12 +-
.../src/forge/adventure/stage/GameHUD.java | 123 ++--
.../util/AdventureQuestController.java | 1 -
.../Shandalar/ui/deck_selector_portrait.json | 3 -
.../adventure/Shandalar/ui/hud_landscape.json | 46 +-
.../adventure/Shandalar/ui/hud_portrait.json | 53 +-
.../adventure/Shandalar/ui/inn_portrait.json | 3 -
.../res/adventure/Shandalar/ui/inventory.json | 18 +
.../Shandalar/ui/inventory_portrait.json | 32 +-
.../Shandalar/ui/items_portrait.json | 2 -
.../adventure/Shandalar/ui/map_portrait.json | 1 -
.../Shandalar/ui/new_game_portrait.json | 2 -
.../Shandalar/ui/quests_portrait.json | 2 -
.../Shandalar/ui/save_load_portrait.json | 2 -
.../Shandalar/ui/settings_portrait.json | 1 -
.../Shandalar/ui/shardtrader_portrait.json | 3 -
.../Shandalar/ui/spellsmith_portrait.json | 3 -
.../Shandalar/ui/start_menu_portrait.json | 1 -
.../Shandalar/ui/statistic_portrait.json | 2 -
.../res/adventure/Shandalar/world/items.json | 13 +-
22 files changed, 490 insertions(+), 421 deletions(-)
diff --git a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java
index 59064e3587c..aefb53e2a8b 100644
--- a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java
+++ b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java
@@ -26,7 +26,7 @@ import java.util.*;
* Class that represents the player (not the player sprite)
*/
public class AdventurePlayer implements Serializable, SaveFileContent {
- public static final int NUMBER_OF_DECKS=10;
+ public static final int NUMBER_OF_DECKS = 10;
// Player profile data.
private String name;
private int heroRace;
@@ -43,53 +43,57 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
// Game data.
private float worldPosX;
private float worldPosY;
- private int gold = 0;
- private int maxLife= 20;
- private int life = 20;
+ private int gold = 0;
+ private int maxLife = 20;
+ private int life = 20;
private int shards = 0;
private EffectData blessing; //Blessing to apply for next battle.
- private final PlayerStatistic statistic = new PlayerStatistic();
+ private final PlayerStatistic statistic = new PlayerStatistic();
private final Map questFlags = new HashMap<>();
- private final Array inventoryItems=new Array<>();
- private final HashMap equippedItems=new HashMap<>();
- private List quests= new ArrayList<>();
+ private final Array inventoryItems = new Array<>();
+ private final HashMap equippedItems = new HashMap<>();
+ private final List quests = new ArrayList<>();
// Fantasy/Chaos mode settings.
- private boolean fantasyMode = false;
+ private boolean fantasyMode = false;
private boolean announceFantasy = false;
private boolean usingCustomDeck = false;
private boolean announceCustom = false;
// Signals
final SignalList onLifeTotalChangeList = new SignalList();
- final SignalList onShardsChangeList = new SignalList();
- final SignalList onGoldChangeList = new SignalList();
- final SignalList onPlayerChangeList = new SignalList();
- final SignalList onEquipmentChange = new SignalList();
- final SignalList onBlessing = new SignalList();
+ final SignalList onShardsChangeList = new SignalList();
+ final SignalList onGoldChangeList = new SignalList();
+ final SignalList onPlayerChangeList = new SignalList();
+ final SignalList onEquipmentChange = new SignalList();
+ final SignalList onBlessing = new SignalList();
- public AdventurePlayer() { clear(); }
+ public AdventurePlayer() {
+ clear();
+ }
- public PlayerStatistic getStatistic(){ return statistic; }
+ public PlayerStatistic getStatistic() {
+ return statistic;
+ }
private void clearDecks() {
- for(int i=0; i < NUMBER_OF_DECKS; i++) decks[i] = new Deck("Empty Deck");
- deck = decks[0];
+ for (int i = 0; i < NUMBER_OF_DECKS; i++) decks[i] = new Deck("Empty Deck");
+ deck = decks[0];
selectedDeckIndex = 0;
}
private void clear() {
//Ensure sensitive gameplay data is properly reset between games.
//Reset all properties HERE.
- fantasyMode = false;
- announceFantasy = false;
- usingCustomDeck = false;
- blessing = null;
- gold = 0;
- maxLife = 20;
- life = 20;
- shards = 0;
+ fantasyMode = false;
+ announceFantasy = false;
+ usingCustomDeck = false;
+ blessing = null;
+ gold = 0;
+ maxLife = 20;
+ life = 20;
+ shards = 0;
clearDecks();
inventoryItems.clear();
equippedItems.clear();
@@ -105,33 +109,33 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
return WorldSave.getCurrentSave().getPlayer();
}
- private final CardPool cards=new CardPool();
- private final ItemPool newCards=new ItemPool<>(InventoryItem.class);
+ private final CardPool cards = new CardPool();
+ private final ItemPool newCards = new ItemPool<>(InventoryItem.class);
- public void create(String n, Deck startingDeck, boolean male, int race, int avatar, boolean isFantasy, boolean isUsingCustomDeck, DifficultyData difficultyData) {
+ public void create(String n, Deck startingDeck, boolean male, int race, int avatar, boolean isFantasy, boolean isUsingCustomDeck, DifficultyData difficultyData) {
clear();
announceFantasy = fantasyMode = isFantasy; //Set Chaos mode first.
announceCustom = usingCustomDeck = isUsingCustomDeck;
- deck = startingDeck;
+ deck = startingDeck;
decks[0] = deck;
cards.addAllFlat(deck.getAllCardsInASinglePool().toFlatList());
- this.difficultyData.startingLife = difficultyData.startingLife;
- this.difficultyData.staringMoney = difficultyData.staringMoney;
+ this.difficultyData.startingLife = difficultyData.startingLife;
+ this.difficultyData.staringMoney = difficultyData.staringMoney;
this.difficultyData.startingDifficulty = difficultyData.startingDifficulty;
- this.difficultyData.name = difficultyData.name;
- this.difficultyData.spawnRank = difficultyData.spawnRank;
- this.difficultyData.enemyLifeFactor = difficultyData.enemyLifeFactor;
- this.difficultyData.sellFactor = difficultyData.sellFactor;
- this.difficultyData.shardSellRatio = difficultyData.shardSellRatio;
+ this.difficultyData.name = difficultyData.name;
+ this.difficultyData.spawnRank = difficultyData.spawnRank;
+ this.difficultyData.enemyLifeFactor = difficultyData.enemyLifeFactor;
+ this.difficultyData.sellFactor = difficultyData.sellFactor;
+ this.difficultyData.shardSellRatio = difficultyData.shardSellRatio;
- gold = difficultyData.staringMoney;
- name = n;
- heroRace = race;
+ gold = difficultyData.staringMoney;
+ name = n;
+ heroRace = race;
avatarIndex = avatar;
- isFemale = !male;
+ isFemale = !male;
setColorIdentity(DeckProxy.getColorIdentity(deck));
@@ -145,12 +149,13 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
}
public void setSelectedDeckSlot(int slot) {
- if(slot>=0&&slot= 0 && slot < NUMBER_OF_DECKS) {
selectedDeckIndex = slot;
deck = decks[selectedDeckIndex];
setColorIdentity(DeckProxy.getColorIdentity(deck));
}
}
+
public void updateDifficulty(DifficultyData diff) {
maxLife = diff.startingLife;
this.difficultyData.startingShards = diff.startingShards;
@@ -166,28 +171,71 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
}
//Getters
- public int getSelectedDeckIndex() { return selectedDeckIndex; }
- public Deck getSelectedDeck() { return deck; }
- public Array getItems() { return inventoryItems; }
- public Deck getDeck(int index) { return decks[index]; }
- public CardPool getCards() { return cards; }
- public String getName() { return name; }
- public float getWorldPosX() { return worldPosX; }
- public float getWorldPosY() { return worldPosY; }
- public int getGold() { return gold; }
- public int getLife() { return life; }
- public int getMaxLife() { return maxLife; }
- public int getShards() { return shards; }
- public @Null EffectData getBlessing() { return blessing; }
+ public int getSelectedDeckIndex() {
+ return selectedDeckIndex;
+ }
- public Collection getEquippedItems() { return equippedItems.values(); }
- public ItemPool getNewCards() { return newCards; }
+ public Deck getSelectedDeck() {
+ return deck;
+ }
- public ColorSet getColorIdentity(){
+ public Array getItems() {
+ return inventoryItems;
+ }
+
+ public Deck getDeck(int index) {
+ return decks[index];
+ }
+
+ public CardPool getCards() {
+ return cards;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public float getWorldPosX() {
+ return worldPosX;
+ }
+
+ public float getWorldPosY() {
+ return worldPosY;
+ }
+
+ public int getGold() {
+ return gold;
+ }
+
+ public int getLife() {
+ return life;
+ }
+
+ public int getMaxLife() {
+ return maxLife;
+ }
+
+ public int getShards() {
+ return shards;
+ }
+
+ public @Null EffectData getBlessing() {
+ return blessing;
+ }
+
+ public Collection getEquippedItems() {
+ return equippedItems.values();
+ }
+
+ public ItemPool getNewCards() {
+ return newCards;
+ }
+
+ public ColorSet getColorIdentity() {
return colorIdentity;
}
- public String getColorIdentityLong(){
+ public String getColorIdentityLong() {
return colorIdentity.toString();
}
@@ -196,62 +244,61 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
public void setWorldPosX(float worldPosX) {
this.worldPosX = worldPosX;
}
+
public void setWorldPosY(float worldPosY) {
this.worldPosY = worldPosY;
}
- public void setColorIdentity(String C){
- colorIdentity= ColorSet.fromNames(C.toCharArray());
+ public void setColorIdentity(String C) {
+ colorIdentity = ColorSet.fromNames(C.toCharArray());
}
- public void setColorIdentity(ColorSet set){
+ public void setColorIdentity(ColorSet set) {
this.colorIdentity = set;
}
-
-
@Override
public void load(SaveFileData data) {
clear(); //Reset player data.
this.statistic.load(data.readSubData("statistic"));
- this.difficultyData.startingLife=data.readInt("startingLife");
- this.difficultyData.staringMoney=data.readInt("staringMoney");
- this.difficultyData.startingDifficulty=data.readBool("startingDifficulty");
- this.difficultyData.name=data.readString("difficultyName");
- this.difficultyData.enemyLifeFactor=data.readFloat("enemyLifeFactor");
- this.difficultyData.sellFactor=data.readFloat("sellFactor");
- if(this.difficultyData.sellFactor==0)
- this.difficultyData.sellFactor=0.2f;
+ this.difficultyData.startingLife = data.readInt("startingLife");
+ this.difficultyData.staringMoney = data.readInt("staringMoney");
+ this.difficultyData.startingDifficulty = data.readBool("startingDifficulty");
+ this.difficultyData.name = data.readString("difficultyName");
+ this.difficultyData.enemyLifeFactor = data.readFloat("enemyLifeFactor");
+ this.difficultyData.sellFactor = data.readFloat("sellFactor");
+ if (this.difficultyData.sellFactor == 0)
+ this.difficultyData.sellFactor = 0.2f;
- this.difficultyData.shardSellRatio=data.readFloat("sellFactor");
- if(this.difficultyData.shardSellRatio==0)
- this.difficultyData.shardSellRatio=0.8f;
+ this.difficultyData.shardSellRatio = data.readFloat("sellFactor");
+ if (this.difficultyData.shardSellRatio == 0)
+ this.difficultyData.shardSellRatio = 0.8f;
- name = data.readString("name");
- heroRace = data.readInt("heroRace");
+ name = data.readString("name");
+ heroRace = data.readInt("heroRace");
avatarIndex = data.readInt("avatarIndex");
- isFemale = data.readBool("isFemale");
- if(data.containsKey("colorIdentity"))
+ isFemale = data.readBool("isFemale");
+ if (data.containsKey("colorIdentity"))
setColorIdentity(data.readString("colorIdentity"));
else
colorIdentity = ColorSet.ALL_COLORS;
- gold = data.readInt("gold");
- maxLife = data.readInt("maxLife");
- life = data.readInt("life");
- shards = data.containsKey("shards")?data.readInt("shards"):0;
- worldPosX = data.readFloat("worldPosX");
- worldPosY = data.readFloat("worldPosY");
+ gold = data.readInt("gold");
+ maxLife = data.readInt("maxLife");
+ life = data.readInt("life");
+ shards = data.containsKey("shards") ? data.readInt("shards") : 0;
+ worldPosX = data.readFloat("worldPosX");
+ worldPosY = data.readFloat("worldPosY");
- if(data.containsKey("blessing")) blessing = (EffectData)data.readObject("blessing");
+ if (data.containsKey("blessing")) blessing = (EffectData) data.readObject("blessing");
- if(data.containsKey("inventory")) {
- String[] inv=(String[])data.readObject("inventory");
+ if (data.containsKey("inventory")) {
+ String[] inv = (String[]) data.readObject("inventory");
//Prevent items with wrong names from getting through. Hell breaks loose if it causes null pointers.
//This only needs to be done on load.
- for(String i : inv){
- if(ItemData.getItem(i) != null) inventoryItems.add(i);
+ for (String i : inv) {
+ if (ItemData.getItem(i) != null) inventoryItems.add(i);
else {
System.err.printf("Cannot find item name %s\n", i);
//Allow official© permission for the player to get a refund. We will allow it this time.
@@ -260,15 +307,15 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
}
}
}
- if(data.containsKey("equippedSlots") && data.containsKey("equippedItems")) {
- String[] slots=(String[])data.readObject("equippedSlots");
- String[] items=(String[])data.readObject("equippedItems");
+ if (data.containsKey("equippedSlots") && data.containsKey("equippedItems")) {
+ String[] slots = (String[]) data.readObject("equippedSlots");
+ String[] items = (String[]) data.readObject("equippedItems");
- assert(slots.length==items.length);
+ assert (slots.length == items.length);
//Like above, prevent items with wrong names. If it triggered in inventory it'll trigger here as well.
- for(int i=0;i slots=new ArrayList<>();
- ArrayList items=new ArrayList<>();
- for (Map.Entry entry : equippedItems.entrySet()) {
+ ArrayList slots = new ArrayList<>();
+ ArrayList items = new ArrayList<>();
+ for (Map.Entry entry : equippedItems.entrySet()) {
slots.add(entry.getKey());
items.add(entry.getValue());
}
- data.storeObject("equippedSlots",slots.toArray(new String[0]));
- data.storeObject("equippedItems",items.toArray(new String[0]));
+ data.storeObject("equippedSlots", slots.toArray(new String[0]));
+ data.storeObject("equippedItems", items.toArray(new String[0]));
data.storeObject("blessing", blessing);
//Save quest flags.
ArrayList questFlagsKey = new ArrayList<>();
- ArrayList questFlagsValue = new ArrayList<>();
- for(Map.Entry entry : questFlags.entrySet()){
+ ArrayList questFlagsValue = new ArrayList<>();
+ for (Map.Entry entry : questFlags.entrySet()) {
questFlagsKey.add(entry.getKey());
questFlagsValue.add(entry.getValue());
}
@@ -378,17 +425,17 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
data.storeObject("questFlagsValue", questFlagsValue.toArray(new Byte[0]));
data.storeObject("quests", quests.toArray());
- data.storeObject("deckCards",deck.getMain().toCardList("\n").split("\n"));
- if(deck.get(DeckSection.Sideboard)!=null)
- data.storeObject("sideBoardCards",deck.get(DeckSection.Sideboard).toCardList("\n").split("\n"));
- for(int i=0;i 0) result += data.effect.cardRewardBonus;
+ for (String name : equippedItems.values()) {
+ ItemData data = ItemData.getItem(name);
+ if (data != null && data.effect != null && data.effect.cardRewardBonus > 0)
+ result += data.effect.cardRewardBonus;
}
- if(blessing != null) {
- if(blessing.cardRewardBonus > 0) result += blessing.cardRewardBonus;
+ if (blessing != null) {
+ if (blessing.cardRewardBonus > 0) result += blessing.cardRewardBonus;
}
return Math.min(result, 3);
}
@@ -606,50 +687,52 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
return difficultyData;
}
- public void renameDeck( String text) {
- deck = (Deck)deck.copyTo(text);
- decks[selectedDeckIndex]=deck;
+ public void renameDeck(String text) {
+ deck = (Deck) deck.copyTo(text);
+ decks[selectedDeckIndex] = deck;
}
public int cardSellPrice(PaperCard card) {
- return (int)(CardUtil.getCardPrice(card)*difficultyData.sellFactor);
+ return (int) (CardUtil.getCardPrice(card) * difficultyData.sellFactor);
}
public void sellCard(PaperCard card, Integer result) {
float price = CardUtil.getCardPrice(card) * result;
price *= difficultyData.sellFactor;
cards.remove(card, result);
- addGold((int)price);
+ addGold((int) price);
}
public void removeItem(String name) {
- if(name == null || name.equals("")) return;
- inventoryItems.removeValue(name,false);
- if(equippedItems.values().contains(name) && !inventoryItems.contains(name,false)) {
+ if (name == null || name.equals("")) return;
+ inventoryItems.removeValue(name, false);
+ if (equippedItems.values().contains(name) && !inventoryItems.contains(name, false)) {
equippedItems.values().remove(name);
}
}
public void equip(ItemData item) {
- if(equippedItems.get(item.equipmentSlot) != null && equippedItems.get(item.equipmentSlot).equals(item.name)) {
+ if (equippedItems.get(item.equipmentSlot) != null && equippedItems.get(item.equipmentSlot).equals(item.name)) {
equippedItems.remove(item.equipmentSlot);
} else {
- equippedItems.put(item.equipmentSlot,item.name);
+ equippedItems.put(item.equipmentSlot, item.name);
}
onEquipmentChange.emit();
}
- public String itemInSlot(String key) { return equippedItems.get(key); }
+ public String itemInSlot(String key) {
+ return equippedItems.get(key);
+ }
public float equipmentSpeed() {
- float factor=1.0f;
- for(String name:equippedItems.values()) {
- ItemData data=ItemData.getItem(name);
- if(data != null && data.effect.moveSpeed > 0.0) //Avoid negative speeds. It would be silly.
- factor*=data.effect.moveSpeed;
+ float factor = 1.0f;
+ for (String name : equippedItems.values()) {
+ ItemData data = ItemData.getItem(name);
+ if (data != null && data.effect != null && data.effect.moveSpeed > 0.0) //Avoid negative speeds. It would be silly.
+ factor *= data.effect.moveSpeed;
}
- if(blessing != null) { //If a blessing gives speed, take it into account.
- if(blessing.moveSpeed > 0.0)
+ if (blessing != null) { //If a blessing gives speed, take it into account.
+ if (blessing.moveSpeed > 0.0)
factor *= blessing.moveSpeed;
}
return factor;
@@ -657,19 +740,20 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
public float goldModifier(boolean sale) {
float factor = 1.0f;
- for(String name:equippedItems.values()) {
- ItemData data=ItemData.getItem(name);
- if(data != null && data.effect.goldModifier > 0.0) //Avoid negative modifiers.
+ for (String name : equippedItems.values()) {
+ ItemData data = ItemData.getItem(name);
+ if (data != null && data.effect != null && data.effect.goldModifier > 0.0) //Avoid negative modifiers.
factor *= data.effect.goldModifier;
}
- if(blessing != null) { //If a blessing gives speed, take it into account.
- if(blessing.goldModifier > 0.0)
+ if (blessing != null) { //If a blessing gives speed, take it into account.
+ if (blessing.goldModifier > 0.0)
factor *= blessing.goldModifier;
}
- if(sale) return Math.max(1.0f + (1.0f - factor), 2.5f);
+ if (sale) return Math.max(1.0f + (1.0f - factor), 2.5f);
return Math.max(factor, 0.25f);
}
- public float goldModifier(){
+
+ public float goldModifier() {
return goldModifier(false);
}
@@ -678,8 +762,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
}
public boolean addItem(String name) {
- ItemData item=ItemData.getItem(name);
- if(item==null)
+ ItemData item = ItemData.getItem(name);
+ if (item == null)
return false;
inventoryItems.add(name);
return true;
@@ -687,45 +771,48 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
// Quest functions.
- public void setQuestFlag(String key, int value){
+ public void setQuestFlag(String key, int value) {
questFlags.put(key, (byte) value);
}
- public void advanceQuestFlag(String key){
- if(questFlags.get(key) != null){
+
+ public void advanceQuestFlag(String key) {
+ if (questFlags.get(key) != null) {
questFlags.put(key, (byte) (questFlags.get(key) + 1));
} else {
questFlags.put(key, (byte) 1);
}
}
- public boolean checkQuestFlag(String key){
+
+ public boolean checkQuestFlag(String key) {
return questFlags.get(key) != null;
}
- public int getQuestFlag(String key){
+
+ public int getQuestFlag(String key) {
return (int) questFlags.getOrDefault(key, (byte) 0);
}
- public void resetQuestFlags(){
+
+ public void resetQuestFlags() {
questFlags.clear();
}
- public void addQuest(String questID){
+ public void addQuest(String questID) {
int id = Integer.parseInt(questID);
addQuest(id);
}
- public void addQuest(int questID){
+ public void addQuest(int questID) {
AdventureQuestData toAdd = AdventureQuestController.instance().generateQuest(questID);
- if (toAdd != null){
+ if (toAdd != null) {
addQuest(toAdd);
}
}
- public void addQuest(AdventureQuestData q){
+ public void addQuest(AdventureQuestData q) {
//TODO: add a config flag for this
boolean autoTrack = true;
- for (AdventureQuestData existing : quests){
- if (autoTrack && existing.isTracked)
- {
+ for (AdventureQuestData existing : quests) {
+ if (autoTrack && existing.isTracked) {
autoTrack = false;
break;
}
@@ -738,23 +825,21 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
return quests;
}
- public int getEnemyDeckNumber(String enemyName, int maxDecks){
- int deckNumber = 0;
- if (statistic.getWinLossRecord().get(enemyName)!=null)
- {
- int playerWins = statistic.getWinLossRecord().get(enemyName).getKey();
- int enemyWins = statistic.getWinLossRecord().get(enemyName).getValue();
- if (playerWins > enemyWins){
- int deckNumberAfterAlgorithmOutput = (int)((playerWins-enemyWins) * (difficultyData.enemyLifeFactor / 3));
- if (deckNumberAfterAlgorithmOutput < maxDecks){
- deckNumber = deckNumberAfterAlgorithmOutput;
- }
- else {
- deckNumber = maxDecks-1;
+ public int getEnemyDeckNumber(String enemyName, int maxDecks) {
+ int deckNumber = 0;
+ if (statistic.getWinLossRecord().get(enemyName) != null) {
+ int playerWins = statistic.getWinLossRecord().get(enemyName).getKey();
+ int enemyWins = statistic.getWinLossRecord().get(enemyName).getValue();
+ if (playerWins > enemyWins) {
+ int deckNumberAfterAlgorithmOutput = (int) ((playerWins - enemyWins) * (difficultyData.enemyLifeFactor / 3));
+ if (deckNumberAfterAlgorithmOutput < maxDecks) {
+ deckNumber = deckNumberAfterAlgorithmOutput;
+ } else {
+ deckNumber = maxDecks - 1;
+ }
}
}
- }
- return deckNumber;
+ return deckNumber;
}
public void removeQuest(AdventureQuestData quest) {
diff --git a/forge-gui-mobile/src/forge/adventure/scene/InventoryScene.java b/forge-gui-mobile/src/forge/adventure/scene/InventoryScene.java
index 3cf00da2618..f7e6c07c25d 100644
--- a/forge-gui-mobile/src/forge/adventure/scene/InventoryScene.java
+++ b/forge-gui-mobile/src/forge/adventure/scene/InventoryScene.java
@@ -39,11 +39,11 @@ public class InventoryScene extends UIScene {
public InventoryScene() {
super(Forge.isLandscapeMode() ? "ui/inventory.json" : "ui/inventory_portrait.json");
equipOverlay = Forge.getAssets().getTexture(Config.instance().getFile(Paths.ITEMS_EQUIP));
- ui.onButtonPress("return", () -> done());
+ ui.onButtonPress("return", this::done);
leave = ui.findActor("return");
- ui.onButtonPress("delete", () -> showConfirm());
- ui.onButtonPress("equip", () -> equip());
- ui.onButtonPress("use", () -> use());
+ ui.onButtonPress("delete", this::showConfirm);
+ ui.onButtonPress("equip", this::equip);
+ ui.onButtonPress("use", this::use);
equipButton = ui.findActor("equip");
useButton = ui.findActor("use");
useButton.setDisabled(true);
@@ -299,7 +299,6 @@ public class InventoryScene extends UIScene {
}
public Button createInventorySlot() {
- ImageButton button = new ImageButton(Controls.getSkin(), "item_frame");
- return button;
+ return new ImageButton(Controls.getSkin(), "item_frame");
}
}
diff --git a/forge-gui-mobile/src/forge/adventure/scene/MapViewScene.java b/forge-gui-mobile/src/forge/adventure/scene/MapViewScene.java
index 712aacd2d67..3488ceb0450 100644
--- a/forge-gui-mobile/src/forge/adventure/scene/MapViewScene.java
+++ b/forge-gui-mobile/src/forge/adventure/scene/MapViewScene.java
@@ -1,6 +1,5 @@
package forge.adventure.scene;
-import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.scenes.scene2d.Group;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
@@ -32,7 +31,7 @@ public class MapViewScene extends UIScene {
super(Forge.isLandscapeMode() ? "ui/map.json" : "ui/map_portrait.json");
- ui.onButtonPress("done", () -> done());
+ ui.onButtonPress("done", this::done);
scroll = ui.findActor("map");
Group table=new Group();
@@ -78,13 +77,4 @@ public class MapViewScene extends UIScene {
super.enter();
}
-
- @Override
- public boolean keyPressed(int keycode) {
- if (keycode == Input.Keys.ESCAPE || keycode == Input.Keys.BACK || keycode == Input.Keys.BUTTON_B) {
- done();
- }
- return true;
- }
-
}
diff --git a/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java b/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java
index 0f89fdb4477..49d33adfb53 100644
--- a/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java
+++ b/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java
@@ -22,12 +22,12 @@ import com.github.tommyettinger.textra.TextraButton;
import com.github.tommyettinger.textra.TextraLabel;
import com.github.tommyettinger.textra.TypingLabel;
import forge.Forge;
+import forge.adventure.data.ItemData;
import forge.adventure.player.AdventurePlayer;
import forge.adventure.scene.*;
import forge.adventure.util.*;
import forge.adventure.world.WorldSave;
import forge.deck.Deck;
-import forge.gui.FThreads;
import forge.gui.GuiBase;
import forge.localinstance.properties.ForgePreferences;
import forge.model.FModel;
@@ -51,16 +51,15 @@ public class GameHUD extends Stage {
private final Touchpad touchpad;
private final Console console;
float TOUCHPAD_SCALE = 70f, referenceX;
- boolean isHiding = false, isShowing = false;
float opacity = 1f;
private boolean debugMap, updatelife;
private final Dialog dialog;
private boolean dialogOnlyInput;
private final Array dialogButtonMap = new Array<>();
+ private final Array abilityButtonMap = new Array<>();
private final Array questKeys = new Array<>();
private String lifepointsTextColor = "";
- private TextraButton selectedKey;
private final ScrollPane scrollPane;
private GameHUD(GameStage gameStage) {
@@ -68,9 +67,7 @@ public class GameHUD extends Stage {
instance = this;
this.gameStage = gameStage;
- ui = new UIActor(Config.instance().getFile(GuiBase.isAndroid()
- ? Forge.isLandscapeMode() ? "ui/hud_landscape.json" : "ui/hud_portrait.json"
- : Forge.isLandscapeMode() ? "ui/hud.json" : "ui/hud_portrait.json"));
+ ui = new UIActor(Config.instance().getFile(Forge.isLandscapeMode() ? "ui/hud_landscape.json" : "ui/hud_portrait.json"));
blank = ui.findActor("blank");
@@ -80,7 +77,7 @@ public class GameHUD extends Stage {
avatarborder = ui.findActor("avatarborder");
deckActor = ui.findActor("deck");
openMapActor = ui.findActor("openmap");
- ui.onButtonPress("openmap", () -> GameHUD.this.openMap());
+ ui.onButtonPress("openmap", this::openMap);
menuActor = ui.findActor("menu");
referenceX = menuActor.getX();
logbookActor = ui.findActor("logbook");
@@ -113,11 +110,11 @@ public class GameHUD extends Stage {
ui.addActor(touchpad);
avatar = ui.findActor("avatar");
- ui.onButtonPress("menu", () -> menu());
- ui.onButtonPress("inventory", () -> openInventory());
- ui.onButtonPress("logbook", () -> logbook());
- ui.onButtonPress("deck", () -> openDeck());
- ui.onButtonPress("exittoworldmap", () -> exitToWorldMap());
+ ui.onButtonPress("menu", this::menu);
+ ui.onButtonPress("inventory", this::openInventory);
+ ui.onButtonPress("logbook", this::logbook);
+ ui.onButtonPress("deck", this::openDeck);
+ ui.onButtonPress("exittoworldmap", this::exitToWorldMap);
lifePoints = ui.findActor("lifePoints");
shards = ui.findActor("shards");
money = ui.findActor("money");
@@ -131,6 +128,7 @@ public class GameHUD extends Stage {
addActor(scrollPane);
AdventurePlayer.current().onLifeChange(() -> lifePoints.setText("[%95][+Life]" + lifepointsTextColor + " " + AdventurePlayer.current().getLife() + "/" + AdventurePlayer.current().getMaxLife()));
AdventurePlayer.current().onShardsChange(() -> shards.setText("[%95][+Shards] " + AdventurePlayer.current().getShards()));
+ AdventurePlayer.current().onEquipmentChanged(this::updateAbility);
WorldSave.getCurrentSave().getPlayer().onGoldChange(() -> money.setText("[%95][+Gold] " + String.valueOf(AdventurePlayer.current().getGold())));
addActor(ui);
@@ -144,7 +142,7 @@ public class GameHUD extends Stage {
avatarborder.addListener(new ConsoleToggleListener());
gamehud.addListener(new ConsoleToggleListener());
}
- WorldSave.getCurrentSave().onLoad(() -> GameHUD.this.enter());
+ WorldSave.getCurrentSave().onLoad(this::enter);
eventTouchDown = new InputEvent();
eventTouchDown.setPointer(-1);
eventTouchDown.setType(InputEvent.Type.touchDown);
@@ -230,7 +228,6 @@ public class GameHUD extends Stage {
touchpad.setBounds(touch.x - TOUCHPAD_SCALE / 2, touch.y - TOUCHPAD_SCALE / 2, TOUCHPAD_SCALE, TOUCHPAD_SCALE);
touchpad.setVisible(true);
touchpad.setResetOnTouchUp(true);
- hideButtons();
return super.touchDown(screenX, screenY, pointer, button);
}
}
@@ -333,6 +330,41 @@ public class GameHUD extends Stage {
}
}
+ void updateAbility() {
+ for (TextraButton button : abilityButtonMap) {
+ button.remove();
+ }
+ abilityButtonMap.clear();
+ setAbilityButton(AdventurePlayer.current().getEquippedAbility1());
+ setAbilityButton(AdventurePlayer.current().getEquippedAbility2());
+ float x = Forge.isLandscapeMode() ? 426f : 216f;
+ float y = 10f;
+ float w = 45f;
+ float h = 35f;
+ for (TextraButton button : abilityButtonMap) {
+ button.getColor().a = opacity;
+ button.setSize(w, h);
+ button.setPosition(x, y);
+ y += h + 10f;
+ addActor(button);
+ }
+ }
+
+ void setAbilityButton(ItemData data) {
+ if (data != null) {
+ TextraButton button = Controls.newTextButton("[%120][+" + data.iconName + "][+Shards]" + data.shardsNeeded, () -> {
+ boolean isInPoi = MapStage.getInstance().isInMap();
+ if (!(isInPoi && data.usableInPoi || !isInPoi && data.usableOnWorldMap))
+ return;
+ if (data.shardsNeeded > Current.player().getShards())
+ return;
+ Current.player().addShards(-data.shardsNeeded);
+ ConsoleCommandInterpreter.getInstance().command(data.commandOnUse);
+ });
+ abilityButtonMap.add(button);
+ }
+ }
+
private Pair audio = null;
public void playAudio() {
@@ -368,12 +400,12 @@ public class GameHUD extends Stage {
public void act(float delta) {
super.act(delta);
if (fade < targetfade) {
- fade += (delta/2);
+ fade += (delta / 2);
if (fade > targetfade)
fade = targetfade;
fadeAudio(fade);
} else if (fade > targetfade) {
- fade -= (delta/2);
+ fade -= (delta / 2);
if (fade < targetfade)
fade = targetfade;
fadeAudio(fade);
@@ -479,6 +511,11 @@ public class GameHUD extends Stage {
actor.setVisible(visible);
}
+ private void setDisabled(Actor actor, boolean enable) {
+ if (actor != null && actor instanceof Button)
+ ((Button) actor).setDisabled(enable);
+ }
+
private void setAlpha(Actor actor, boolean visible) {
if (actor != null) {
if (visible)
@@ -498,7 +535,7 @@ public class GameHUD extends Stage {
setVisibility(shards, visible);
setVisibility(money, visible);
setVisibility(blank, visible);
- setVisibility(exitToWorldMapActor, GameScene.instance().isNotInWorldMap());
+ setDisabled(exitToWorldMapActor, !GameScene.instance().isNotInWorldMap());
setAlpha(avatarborder, visible);
setAlpha(avatar, visible);
setAlpha(deckActor, visible);
@@ -506,6 +543,9 @@ public class GameHUD extends Stage {
setAlpha(logbookActor, visible);
setAlpha(inventoryActor, visible);
setAlpha(exitToWorldMapActor, visible);
+ for (TextraButton button : abilityButtonMap) {
+ setAlpha(button, visible);
+ }
opacity = visible ? 1f : 0.4f;
}
@@ -528,11 +568,6 @@ public class GameHUD extends Stage {
if (keycode == Input.Keys.BACK) {
if (console.isVisible()) {
console.toggle();
- } else {
- if (menuActor.isVisible())
- hideButtons();
- else
- showButtons();
}
}
if (console.isVisible())
@@ -571,38 +606,6 @@ public class GameHUD extends Stage {
}, 0.10f);
}
- private void hideButtons() {
- if (isShowing)
- return;
- if (isHiding)
- return;
- isHiding = true;
- deckActor.addAction(Actions.sequence(Actions.fadeOut(0.10f), Actions.hide(), Actions.moveTo(deckActor.getX() + deckActor.getWidth(), deckActor.getY())));
- inventoryActor.addAction(Actions.sequence(Actions.fadeOut(0.15f), Actions.hide(), Actions.moveTo(inventoryActor.getX() + inventoryActor.getWidth(), inventoryActor.getY())));
- logbookActor.addAction(Actions.sequence(Actions.fadeOut(0.20f), Actions.hide(), Actions.moveTo(logbookActor.getX() + logbookActor.getWidth(), logbookActor.getY())));
- menuActor.addAction(Actions.sequence(Actions.fadeOut(0.25f), Actions.hide(), Actions.moveTo(menuActor.getX() + menuActor.getWidth(), menuActor.getY())));
- if (GameScene.instance().isNotInWorldMap())
- exitToWorldMapActor.addAction(Actions.sequence(Actions.fadeOut(0.2f), Actions.hide(), Actions.moveTo(exitToWorldMapActor.getX() + exitToWorldMapActor.getWidth(), exitToWorldMapActor.getY())));
- FThreads.delayInEDT(300, () -> isHiding = false);
- }
-
- private void showButtons() {
- if (console.isVisible())
- return;
- if (isHiding)
- return;
- if (isShowing)
- return;
- isShowing = true;
- menuActor.addAction(Actions.sequence(Actions.delay(0.1f), Actions.parallel(Actions.show(), Actions.alpha(opacity, 0.1f), Actions.moveTo(referenceX, menuActor.getY(), 0.25f))));
- logbookActor.addAction(Actions.sequence(Actions.delay(0.15f), Actions.parallel(Actions.show(), Actions.alpha(opacity, 0.1f), Actions.moveTo(referenceX, logbookActor.getY(), 0.25f))));
- inventoryActor.addAction(Actions.sequence(Actions.delay(0.2f), Actions.parallel(Actions.show(), Actions.alpha(opacity, 0.1f), Actions.moveTo(referenceX, inventoryActor.getY(), 0.25f))));
- deckActor.addAction(Actions.sequence(Actions.delay(0.25f), Actions.parallel(Actions.show(), Actions.alpha(opacity, 0.1f), Actions.moveTo(referenceX, deckActor.getY(), 0.25f))));
- if (GameScene.instance().isNotInWorldMap())
- exitToWorldMapActor.addAction(Actions.sequence(Actions.delay(0.25f), Actions.parallel(Actions.show(), Actions.alpha(opacity, 0.1f), Actions.moveTo(referenceX, exitToWorldMapActor.getY(), 0.25f))));
- FThreads.delayInEDT(300, () -> isShowing = false);
- }
-
public void setDebug(boolean b) {
debugMap = b;
}
@@ -626,13 +629,12 @@ public class GameHUD extends Stage {
public boolean act(float v) {
if (exitDungeon) {
MapStage.getInstance().exitDungeon();
- exitToWorldMapActor.setVisible(false);
+ setDisabled(exitToWorldMapActor, true);
}
return true;
}
}));
dialogOnlyInput = false;
- selectedKey = null;
}
private void selectNextDialogButton() {
@@ -677,18 +679,9 @@ public class GameHUD extends Stage {
@Override
public boolean longPress(Actor actor, float x, float y) {
- hideButtons();
console.toggle();
return super.longPress(actor, x, y);
}
-
- @Override
- public void tap(InputEvent event, float x, float y, int count, int button) {
- super.tap(event, x, y, count, button);
- //show menu buttons if double tapping the avatar, for android devices without visible navigation buttons
- if (count > 1)
- showButtons();
- }
}
public void updateMusic() {
diff --git a/forge-gui-mobile/src/forge/adventure/util/AdventureQuestController.java b/forge-gui-mobile/src/forge/adventure/util/AdventureQuestController.java
index 9784a5ca73f..f508e47097d 100644
--- a/forge-gui-mobile/src/forge/adventure/util/AdventureQuestController.java
+++ b/forge-gui-mobile/src/forge/adventure/util/AdventureQuestController.java
@@ -17,7 +17,6 @@ import forge.util.Aggregates;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.*;
-import java.util.List;
public class AdventureQuestController implements Serializable {
diff --git a/forge-gui/res/adventure/Shandalar/ui/deck_selector_portrait.json b/forge-gui/res/adventure/Shandalar/ui/deck_selector_portrait.json
index 65a62df2d12..9972c0107e7 100644
--- a/forge-gui/res/adventure/Shandalar/ui/deck_selector_portrait.json
+++ b/forge-gui/res/adventure/Shandalar/ui/deck_selector_portrait.json
@@ -21,7 +21,6 @@
"type": "TextButton",
"name": "return",
"text": "tr(lblBack)",
- "binding": "Back",
"width": 86,
"height": 30,
"x": 4,
@@ -31,7 +30,6 @@
"type": "TextButton",
"name": "rename",
"text": "tr(lblRename)",
- "binding": "Equip",
"width": 86,
"height": 30,
"x": 92,
@@ -41,7 +39,6 @@
"type": "TextButton",
"name": "edit",
"text": "tr(lblEdit)",
- "binding": "Use",
"width": 86,
"height": 30,
"x": 180,
diff --git a/forge-gui/res/adventure/Shandalar/ui/hud_landscape.json b/forge-gui/res/adventure/Shandalar/ui/hud_landscape.json
index dc0eb34866b..a18af1a95ac 100644
--- a/forge-gui/res/adventure/Shandalar/ui/hud_landscape.json
+++ b/forge-gui/res/adventure/Shandalar/ui/hud_landscape.json
@@ -85,45 +85,42 @@
{
"type": "TextButton",
"name": "deck",
- "style":"menu",
"text": "[%120][+Deck]",
"binding": "Deck",
- "width": 64,
- "height": 36,
- "x": 416,
- "y": 106
+ "width": 45,
+ "height": 25,
+ "x": 175,
+ "y": 0
},
{
"type": "TextButton",
"name": "inventory",
- "style":"menu",
"text": "[%120][+Item]",
"binding": "Inventory",
- "width": 64,
- "height": 36,
- "x": 416,
- "y": 146
+ "width": 45,
+ "height": 25,
+ "x": 220,
+ "y": 0
},
{
"type": "TextButton",
"name": "logbook",
- "style":"menu",
"text": "[%120][+Logbook]",
- "width": 64,
- "height": 36,
- "x": 416,
- "y": 186
+ "binding": "Status",
+ "width": 45,
+ "height": 25,
+ "x": 265,
+ "y": 0
},
{
"type": "TextButton",
"name": "menu",
- "style":"menu",
"text": "[%120][+Menu]",
"binding": "Menu",
- "width": 64,
- "height": 36,
- "x": 416,
- "y": 226
+ "width": 45,
+ "height": 25,
+ "x": 130,
+ "y": 0
},
{
"type": "TextButton",
@@ -138,13 +135,12 @@
{
"type": "TextButton",
"name": "exittoworldmap",
- "style":"menu",
"text": "[%120][+ExitToWorldMap]",
"binding": "ExitToWorldMap",
- "width": 64,
- "height": 32,
- "x": 416,
- "y": 66
+ "width": 45,
+ "height": 25,
+ "x": 310,
+ "y": 0
}
]
}
\ No newline at end of file
diff --git a/forge-gui/res/adventure/Shandalar/ui/hud_portrait.json b/forge-gui/res/adventure/Shandalar/ui/hud_portrait.json
index 4d8f7d73e58..f29e66a2401 100644
--- a/forge-gui/res/adventure/Shandalar/ui/hud_portrait.json
+++ b/forge-gui/res/adventure/Shandalar/ui/hud_portrait.json
@@ -84,53 +84,44 @@
{
"type": "TextButton",
"name": "deck",
- "style":"menu",
"text": "[%120][+Deck]",
- "binding": "Deck",
- "width": 64,
- "height": 32,
- "x": 206,
- "y": 306
+ "width": 25,
+ "height": 25,
+ "x": 105,
+ "y": 0
},
{
"type": "TextButton",
"name": "inventory",
- "style":"menu",
"text": "[%120][+Item]",
- "binding": "Inventory",
- "width": 64,
- "height": 32,
- "x": 206,
- "y": 346
+ "width": 25,
+ "height": 25,
+ "x": 130,
+ "y": 0
},
{
"type": "TextButton",
"name": "logbook",
- "style":"menu",
"text": "[%120][+Logbook]",
- "binding": "Status",
- "width": 64,
- "height": 32,
- "x": 206,
- "y": 386
+ "width": 25,
+ "height": 25,
+ "x": 155,
+ "y": 0
},
{
"type": "TextButton",
"name": "menu",
- "style":"menu",
"text": "[%120][+Menu]",
- "binding": "Menu",
- "width": 64,
- "height": 32,
- "x": 206,
- "y": 426
+ "width": 25,
+ "height": 25,
+ "x": 80,
+ "y": 0
},
{
"type": "TextButton",
"name": "openmap",
"text": "[%80]tr(lblZoom)",
- "binding": "Map",
"width": 80,
"height": 20,
"x": 0,
@@ -138,14 +129,12 @@
},
{
"type": "TextButton",
- "name": "exittoworldmap",
- "style":"menu",
+ "name": "exittoworldmap",
"text": "[%120][+ExitToWorldMap]",
- "binding": "ExitToWorldMap",
- "width": 64,
- "height": 32,
- "x": 206,
- "y": 266
+ "width": 25,
+ "height": 25,
+ "x": 180,
+ "y": 0
}
]
}
\ No newline at end of file
diff --git a/forge-gui/res/adventure/Shandalar/ui/inn_portrait.json b/forge-gui/res/adventure/Shandalar/ui/inn_portrait.json
index eb6ba344c16..1a7c8722071 100644
--- a/forge-gui/res/adventure/Shandalar/ui/inn_portrait.json
+++ b/forge-gui/res/adventure/Shandalar/ui/inn_portrait.json
@@ -22,7 +22,6 @@
"type": "TextButton",
"name": "tempHitPointCost",
"text": "Cost",
- "binding": "Status",
"width": 100,
"height": 30,
"x": 165,
@@ -51,7 +50,6 @@
"type": "TextButton",
"name": "sell",
"text": "tr(lblSell)",
- "binding": "Equip",
"width": 100,
"height": 30,
"x": 165,
@@ -70,7 +68,6 @@
"type": "TextButton",
"name": "done",
"text": "tr(lblBack)",
- "binding": "Back",
"width": 100,
"height": 30,
"x": 165,
diff --git a/forge-gui/res/adventure/Shandalar/ui/inventory.json b/forge-gui/res/adventure/Shandalar/ui/inventory.json
index f025b8fa88c..cf4d971a56e 100644
--- a/forge-gui/res/adventure/Shandalar/ui/inventory.json
+++ b/forge-gui/res/adventure/Shandalar/ui/inventory.json
@@ -17,6 +17,24 @@
"width": 129,
"height": 243
},
+ {
+ "type": "ImageButton",
+ "name": "Equipment_Ability1",
+ "style": "item_frame",
+ "width": 20,
+ "height": 20,
+ "x": 17,
+ "y": 20
+ },
+ {
+ "type": "ImageButton",
+ "name": "Equipment_Ability2",
+ "style": "item_frame",
+ "width": 20,
+ "height": 20,
+ "x": 107,
+ "y": 20
+ },
{
"type": "ImageButton",
"name": "Equipment_Neck",
diff --git a/forge-gui/res/adventure/Shandalar/ui/inventory_portrait.json b/forge-gui/res/adventure/Shandalar/ui/inventory_portrait.json
index c55ddeace12..e561453c675 100644
--- a/forge-gui/res/adventure/Shandalar/ui/inventory_portrait.json
+++ b/forge-gui/res/adventure/Shandalar/ui/inventory_portrait.json
@@ -16,7 +16,25 @@
"y": 112,
"width": 129,
"height": 243
- },
+ },
+ {
+ "type": "ImageButton",
+ "name": "Equipment_Ability1",
+ "style": "item_frame",
+ "width": 20,
+ "height": 20,
+ "x": 17,
+ "y": 124
+ },
+ {
+ "type": "ImageButton",
+ "name": "Equipment_Ability2",
+ "style": "item_frame",
+ "width": 20,
+ "height": 20,
+ "x": 107,
+ "y": 124
+ },
{
"type": "ImageButton",
"name": "Equipment_Neck",
@@ -25,7 +43,7 @@
"height": 20,
"x": 62,
"y": 144
- } ,
+ },
{
"type": "ImageButton",
"name": "Equipment_Body",
@@ -34,7 +52,7 @@
"height": 20,
"x": 62,
"y": 189
- } ,
+ },
{
"type": "ImageButton",
"name": "Equipment_Boots",
@@ -43,7 +61,7 @@
"height": 20,
"x": 62,
"y": 324
- } ,
+ },
{
"type": "ImageButton",
"name": "Equipment_Left",
@@ -84,12 +102,11 @@
"y": 16,
"width": 246,
"height": 90
- } ,
+ },
{
"type": "TextButton",
"name": "delete",
"text": "tr(lblDispose)",
- "binding": "Status",
"width": 60,
"height": 30,
"x": 8,
@@ -99,7 +116,6 @@
"type": "TextButton",
"name": "equip",
"text": "tr(lblEquip)",
- "binding": "Equip",
"width": 60,
"height": 30,
"x": 75,
@@ -109,7 +125,6 @@
"type": "TextButton",
"name": "use",
"text": "tr(lblUse)",
- "binding": "Use",
"width": 60,
"height": 30,
"x": 140,
@@ -119,7 +134,6 @@
"type": "TextButton",
"name": "return",
"text": "tr(lblBack)",
- "binding": "Back",
"width": 60,
"height": 30,
"x": 205,
diff --git a/forge-gui/res/adventure/Shandalar/ui/items_portrait.json b/forge-gui/res/adventure/Shandalar/ui/items_portrait.json
index 45d33a8a045..31663fbbbcf 100644
--- a/forge-gui/res/adventure/Shandalar/ui/items_portrait.json
+++ b/forge-gui/res/adventure/Shandalar/ui/items_portrait.json
@@ -28,7 +28,6 @@
"type": "TextButton",
"name": "detail",
"text": "Detail",
- "binding": "Equip",
"width": 128,
"height": 32,
"x": 140,
@@ -38,7 +37,6 @@
"type": "TextButton",
"name": "done",
"text": "tr(lblLeave)",
- "binding": "Back",
"width": 128,
"height": 32,
"x": 140,
diff --git a/forge-gui/res/adventure/Shandalar/ui/map_portrait.json b/forge-gui/res/adventure/Shandalar/ui/map_portrait.json
index 6eeb1cba545..9e165c0f637 100644
--- a/forge-gui/res/adventure/Shandalar/ui/map_portrait.json
+++ b/forge-gui/res/adventure/Shandalar/ui/map_portrait.json
@@ -13,7 +13,6 @@
"type": "TextButton",
"name": "done",
"text": "[%80]tr(lblBack)",
- "binding": "Back",
"width": 48,
"height": 20,
"x": 5,
diff --git a/forge-gui/res/adventure/Shandalar/ui/new_game_portrait.json b/forge-gui/res/adventure/Shandalar/ui/new_game_portrait.json
index 6ffc8a8a582..0fab6dc9ef8 100644
--- a/forge-gui/res/adventure/Shandalar/ui/new_game_portrait.json
+++ b/forge-gui/res/adventure/Shandalar/ui/new_game_portrait.json
@@ -187,7 +187,6 @@
"name": "back",
"text": "tr(lblBack)",
"selectable": true,
- "binding": "Back",
"width": 64,
"height": 28,
"x": 32,
@@ -198,7 +197,6 @@
"name": "start",
"text": "tr(lblStart)",
"selectable": true,
- "binding": "Status",
"width": 64,
"height": 28,
"x": 165,
diff --git a/forge-gui/res/adventure/Shandalar/ui/quests_portrait.json b/forge-gui/res/adventure/Shandalar/ui/quests_portrait.json
index 6cfc29125d4..0a8400244a5 100644
--- a/forge-gui/res/adventure/Shandalar/ui/quests_portrait.json
+++ b/forge-gui/res/adventure/Shandalar/ui/quests_portrait.json
@@ -66,7 +66,6 @@
"type": "TextButton",
"name": "return",
"text": "tr(lblBack)",
- "binding": "Back",
"width": 130,
"height": 30,
"x": 135,
@@ -76,7 +75,6 @@
"type": "TextButton",
"name": "status",
"text": "Status",
- "binding": "Status",
"width": 130,
"height": 30,
"x": 5,
diff --git a/forge-gui/res/adventure/Shandalar/ui/save_load_portrait.json b/forge-gui/res/adventure/Shandalar/ui/save_load_portrait.json
index 0657e17d835..9c5f9202b2f 100644
--- a/forge-gui/res/adventure/Shandalar/ui/save_load_portrait.json
+++ b/forge-gui/res/adventure/Shandalar/ui/save_load_portrait.json
@@ -45,7 +45,6 @@
"type": "TextButton",
"name": "return",
"text": "tr(lblBack)",
- "binding": "Back",
"width": 120,
"height": 32,
"x": 10,
@@ -54,7 +53,6 @@
{
"type": "TextButton",
"name": "save",
- "binding": "Use",
"width": 120,
"height": 32,
"x": 140,
diff --git a/forge-gui/res/adventure/Shandalar/ui/settings_portrait.json b/forge-gui/res/adventure/Shandalar/ui/settings_portrait.json
index 2589272e2e9..eb9ec94b0ae 100644
--- a/forge-gui/res/adventure/Shandalar/ui/settings_portrait.json
+++ b/forge-gui/res/adventure/Shandalar/ui/settings_portrait.json
@@ -21,7 +21,6 @@
"type": "TextButton",
"name": "return",
"text": "tr(lblBack)",
- "binding": "Back",
"width": 250,
"height": 32,
"x": 10,
diff --git a/forge-gui/res/adventure/Shandalar/ui/shardtrader_portrait.json b/forge-gui/res/adventure/Shandalar/ui/shardtrader_portrait.json
index 67ca39c0390..ee9464962d4 100644
--- a/forge-gui/res/adventure/Shandalar/ui/shardtrader_portrait.json
+++ b/forge-gui/res/adventure/Shandalar/ui/shardtrader_portrait.json
@@ -22,7 +22,6 @@
"type": "TextButton",
"name": "btnBuyShardsCost",
"text": "btnBuyShardsCost",
- "binding": "Status",
"width": 100,
"height": 30,
"x": 165,
@@ -41,7 +40,6 @@
"type": "TextButton",
"name": "btnSellShardsQuantity",
"text": "btnSellShardsQuantity",
- "binding": "Equip",
"width": 100,
"height": 30,
"x": 165,
@@ -60,7 +58,6 @@
"type": "TextButton",
"name": "done",
"text": "tr(lblBack)",
- "binding": "Back",
"width": 100,
"height": 30,
"x": 165,
diff --git a/forge-gui/res/adventure/Shandalar/ui/spellsmith_portrait.json b/forge-gui/res/adventure/Shandalar/ui/spellsmith_portrait.json
index ce7935278ae..dd0a389b188 100644
--- a/forge-gui/res/adventure/Shandalar/ui/spellsmith_portrait.json
+++ b/forge-gui/res/adventure/Shandalar/ui/spellsmith_portrait.json
@@ -64,7 +64,6 @@
"selectable": true,
"name": "done",
"text": "tr(lblBack)",
- "binding": "Back",
"x": 180,
"y": 150,
"width": 90,
@@ -151,7 +150,6 @@
"type": "TextButton",
"selectable": true,
"name": "pullUsingGold",
- "binding": "Status",
"text": "tr(lblDraw) [+gold]",
"x": 180,
"y": 25,
@@ -171,7 +169,6 @@
"type": "TextButton",
"selectable": true,
"name": "pullUsingShards",
- "binding": "Equip",
"text": "tr(lblDraw) [+shards]",
"x": 180,
"y": 75,
diff --git a/forge-gui/res/adventure/Shandalar/ui/start_menu_portrait.json b/forge-gui/res/adventure/Shandalar/ui/start_menu_portrait.json
index 8f662520582..484bab545b7 100644
--- a/forge-gui/res/adventure/Shandalar/ui/start_menu_portrait.json
+++ b/forge-gui/res/adventure/Shandalar/ui/start_menu_portrait.json
@@ -54,7 +54,6 @@
"name": "Resume",
"text": "tr(lblResume)",
"selectable": true,
- "binding": "Back",
"width": 238,
"height": 48,
"x": 16,
diff --git a/forge-gui/res/adventure/Shandalar/ui/statistic_portrait.json b/forge-gui/res/adventure/Shandalar/ui/statistic_portrait.json
index bfbecae1869..3f8b45b6187 100644
--- a/forge-gui/res/adventure/Shandalar/ui/statistic_portrait.json
+++ b/forge-gui/res/adventure/Shandalar/ui/statistic_portrait.json
@@ -112,7 +112,6 @@
"type": "TextButton",
"name": "return",
"text": "tr(lblBack)",
- "binding": "Back",
"width": 115,
"height": 30,
"x": 155,
@@ -122,7 +121,6 @@
"type": "TextButton",
"name": "quests",
"text": "Quests",
- "binding": "Status",
"width": 115,
"height": 30,
"x": 35,
diff --git a/forge-gui/res/adventure/Shandalar/world/items.json b/forge-gui/res/adventure/Shandalar/world/items.json
index 93040574945..2d023e2a37d 100644
--- a/forge-gui/res/adventure/Shandalar/world/items.json
+++ b/forge-gui/res/adventure/Shandalar/world/items.json
@@ -869,7 +869,8 @@
},
{
"name": "Colorless rune",
- "usableOnWorldMap":true,
+ "usableOnWorldMap":true,
+ "equipmentSlot": "Ability2",
"description": "Teleports you to the center",
"commandOnUse": "teleport to poi Spawn",
"iconName": "ColorlessRune",
@@ -880,6 +881,7 @@
{
"name": "White rune",
"usableOnWorldMap":true,
+ "equipmentSlot": "Ability2",
"effect": {
"name": ""
},
@@ -893,6 +895,7 @@
{
"name": "Black rune",
"usableOnWorldMap":true,
+ "equipmentSlot": "Ability2",
"effect": {
"name": ""
},
@@ -906,6 +909,7 @@
{
"name": "Blue rune",
"usableOnWorldMap":true,
+ "equipmentSlot": "Ability2",
"effect": {
"name": ""
},
@@ -919,6 +923,7 @@
{
"name": "Red rune",
"usableOnWorldMap":true,
+ "equipmentSlot": "Ability2",
"effect": {
"name": ""
},
@@ -932,6 +937,7 @@
{
"name": "Green rune",
"usableOnWorldMap":true,
+ "equipmentSlot": "Ability2",
"effect": {
"name": ""
},
@@ -944,6 +950,7 @@
},
{
"name": "White Staff",
+ "equipmentSlot": "Ability1",
"usableOnWorldMap":true,
"usableInPoi":true,
"effect": {
@@ -958,6 +965,7 @@
},
{
"name": "Black Staff",
+ "equipmentSlot": "Ability1",
"usableOnWorldMap":true,
"usableInPoi":false,
"effect": {
@@ -973,6 +981,7 @@
{
"name": "Blue Staff",
"usableOnWorldMap":true,
+ "equipmentSlot": "Ability1",
"effect": {
"name": ""
},
@@ -986,6 +995,7 @@
{
"name": "Red Staff",
"usableOnWorldMap":true,
+ "equipmentSlot": "Ability1",
"effect": {
"name": ""
},
@@ -998,6 +1008,7 @@
},
{
"name": "Green Staff",
+ "equipmentSlot": "Ability1",
"usableOnWorldMap":true,
"usableInPoi":true,
"effect": {
From 95852d0d2fccd550addf8cd8533d6720b5a19289 Mon Sep 17 00:00:00 2001
From: paulsnoops
Date: Thu, 13 Apr 2023 20:31:00 +0100
Subject: [PATCH 10/18] Edition updates: MOC, MUL
---
...vasion_of_kylem_valors_reach_tag_team.txt} | 0
.../March of the Machine Commander.txt | 2 +-
forge-gui/res/editions/Multiverse Legends.txt | 36 +++++++++++++++++++
3 files changed, 37 insertions(+), 1 deletion(-)
rename forge-gui/res/cardsfolder/upcoming/{invasion_of_kylem__valors_reach_tag_team.txt => invasion_of_kylem_valors_reach_tag_team.txt} (100%)
diff --git a/forge-gui/res/cardsfolder/upcoming/invasion_of_kylem__valors_reach_tag_team.txt b/forge-gui/res/cardsfolder/upcoming/invasion_of_kylem_valors_reach_tag_team.txt
similarity index 100%
rename from forge-gui/res/cardsfolder/upcoming/invasion_of_kylem__valors_reach_tag_team.txt
rename to forge-gui/res/cardsfolder/upcoming/invasion_of_kylem_valors_reach_tag_team.txt
diff --git a/forge-gui/res/editions/March of the Machine Commander.txt b/forge-gui/res/editions/March of the Machine Commander.txt
index a3cee2575d1..710b47347ad 100644
--- a/forge-gui/res/editions/March of the Machine Commander.txt
+++ b/forge-gui/res/editions/March of the Machine Commander.txt
@@ -201,7 +201,7 @@ ScryfallCode=MOC
193 R Knight of the White Orchid @Mark Zug
194 U Master Splicer @Chippy
195 R Maul of the Skyclaves @Joseph Meehan
-196 U Mentor of the Meek @Jana Schirmer & Johannes Voss
+196 R Mentor of the Meek @Jana Schirmer & Johannes Voss
197 M Mikaeus, the Lunarch @Steven Belledin
198 U Path to Exile @Todd Lockwood
199 R Phyrexian Rebirth @Scott Chou
diff --git a/forge-gui/res/editions/Multiverse Legends.txt b/forge-gui/res/editions/Multiverse Legends.txt
index 546b30b4d43..bbe09c081c2 100644
--- a/forge-gui/res/editions/Multiverse Legends.txt
+++ b/forge-gui/res/editions/Multiverse Legends.txt
@@ -71,22 +71,52 @@ ScryfallCode=MUL
63 M Yarok, the Desecrated @Jessica Rossier
64 R Yorion, Sky Nomad @Justine Mara Andersen
65 R Zirda, the Dawnwaker @Justine Mara Andersen
+66 R Anafenza, Kin-Tree Spirit @Ryan Yee
+67 U Daxos, Blessed by the Sun @Lius Lasahido
68 M Elesh Norn, Grand Cenobite @Igor Kieryluk
69 M Kenrith, the Returned King @Kieran Yanner
+70 U Kwende, Pride of Femeref @Daarken
71 R Sram, Senior Edificer @Chris Rahn
+72 R Thalia, Guardian of Thraben @Jana Schirmer & Johannes Voss
73 R Baral, Chief of Compliance @Wesley Burt
+74 R Emry, Lurker of the Loch @Livia Prima
+75 U Inga Rune-Eyes @Bram Sels
76 M Jin-Gitaxias, Core Augur @Eric Deschamps
+77 U Tetsuko Umezawa, Fugitive @Randy Vargas
+78 R Ayara, First of Locthwain @Ryan Pancoast
+79 R Horobi, Death's Wail @John Bolton
+80 R Seizan, Perverter of Truth @Kev Walker
81 M Sheoldred, Whispering One @Jana Schirmer & Johannes Voss
82 M Skithiryx, the Blight Dragon @Chippy
+83 U Tymaret, Chosen from Death @Chase Stone
84 U Yargle, Glutton of Urborg @Jehan Choo
+85 R Captain Lannery Storm @Chris Rallis
+86 M Ragavan, Nimble Pilferer @Simon Dominic
+87 R Squee, the Immortal @Svetlin Velinov
88 M Urabrask the Hidden @Brad Rigney
+89 U Valduk, Keeper of the Flame @Victor Adame Minguez
90 U Zada, Hedron Grinder @Chris Rallis
+91 U Fynn, the Fangbearer @Lie Setiawan
+92 R Goreclaw, Terror of Qal Sisma @Svetlin Velinov
+93 U Renata, Called to the Hunt @Chris Rahn
94 M Vorinclex, Voice of Hunger @Karl Kopinski
+95 R Yedora, Grave Gardener @Svetlin Velinov
+96 U Aegar, the Freezing Flame @Chris Rahn
97 R Arixmethes, Slumbering Isle @Dimitar Marinski
+98 M Atraxa, Praetors' Voice @Victor Adame Minguez
+99 R Atris, Oracle of Half-Truths @Bastien L. Deharme
+100 M Aurelia, the Warleader @Slawomir Maniak
101 R Brudiclad, Telchor Engineer @Daarken
102 U Dina, Soul Steeper @Chris Rahn
+103 M Ezuri, Claw of Progress @James Ryman
+104 R Firesong and Sunspeaker @Zoltan Boros
105 U Firja, Judge of Valor @Livia Prima
+106 M Grimgrin, Corpse-Born @Bartek Fedyczak
107 R Gyruda, Doom of Depths @Tyler Jacobson
+108 U Imoti, Celebrant of Bounty @Ekaterina Burmak
+109 R Jegantha, the Wellspring @Chris Rahn
+110 R Judith, the Scourge Diva @Wesley Burt
+111 U Juri, Master of the Revue @Dmitry Burmak
112 R Kaheera, the Orphanguard @Ryan Pancoast
113 R Keruga, the Macrosage @Dan Scott
114 M Kroxa, Titan of Death's Hunger @Vincent Proce
@@ -95,7 +125,13 @@ ScryfallCode=MUL
117 R Lutri, the Spellchaser @Lie Setiawan
118 M Niv-Mizzet Reborn @Raymond Swanland
119 R Obosh, the Preypiercer @Daarken
+120 U Radha, Coalition Warlord @Randy Vargas
121 U Raff, Weatherlight Stalwart @Eelis Kyttanen
+122 U Reyav, Master Smith @Scott Murphy
+123 U Rona, Sheoldred's Faithful @Ryan Alexander Lee
+124 U Shanna, Sisay's Legacy @Magali Villeneuve
+125 R Taigam, Ojutai Master @Simon Dominic
+126 R Teysa Karlov @Magali Villeneuve
127 R Umori, the Collector @Jehan Choo
128 M Yarok, the Desecrated @Daarken
129 R Yorion, Sky Nomad @Steven Belledin
From edbc2d2e103ddf3700148bdf9b89a12d0886bad6 Mon Sep 17 00:00:00 2001
From: paulsnoops
Date: Thu, 13 Apr 2023 20:41:03 +0100
Subject: [PATCH 11/18] Edition updates: MAT
---
.../res/editions/March of the Machine The Aftermath.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/forge-gui/res/editions/March of the Machine The Aftermath.txt b/forge-gui/res/editions/March of the Machine The Aftermath.txt
index b68a33ebaf9..3a965d2c84e 100644
--- a/forge-gui/res/editions/March of the Machine The Aftermath.txt
+++ b/forge-gui/res/editions/March of the Machine The Aftermath.txt
@@ -6,5 +6,9 @@ Type=Expansion
ScryfallCode=MAT
[cards]
+33 R Jolrael, Voice of Zhalfir @Lorenzo Mastroianni
34 R The Kenriths' Royal Funeral @Manuel Castañón
-230 Jolrael, Voice of Zhalfir @Ernanda Souza
+83 R Jolrael, Voice of Zhalfir @Scott M. Fischer
+133 R Jolrael, Voice of Zhalfir @Lorenzo Mastroianni
+168 R Jolrael, Voice of Zhalfir @Lorenzo Mastroianni
+230 R Jolrael, Voice of Zhalfir @Ernanda Souza
From 3e736104a1ea913e18785d27d6b79e67b8a4bc0d Mon Sep 17 00:00:00 2001
From: Simisays <67333662+Simisays@users.noreply.github.com>
Date: Thu, 13 Apr 2023 21:47:23 +0200
Subject: [PATCH 12/18] Adventure: Grolnok Rework + a bunch of tweaks to my
older PR's (#2915)
---
.../res/adventure/Shandalar/decks/bat.dck | 27 +
.../Shandalar/decks/darkenchanter.dck | 34 +
.../adventure/Shandalar/decks/sandgolem.dck | 32 +
.../adventure/Shandalar/decks/sandwurm.dck | 27 +
.../adventure/Shandalar/decks/swamptroll.dck | 40 +
.../res/adventure/Shandalar/decks/witch.dck | 31 +
.../Shandalar/maps/map/factory_2.tmx | 1 -
.../adventure/Shandalar/maps/map/grolnok.tmx | 409 +-
.../Shandalar/maps/map/grolnok_f1.tmx | 156 +
.../Shandalar/maps/map/magetower_3.tmx | 4 +-
.../Shandalar/maps/map/nest_blue_1.tmx | 101 +-
.../Shandalar/maps/map/nest_white_1.tmx | 272 +-
.../adventure/Shandalar/maps/map/tibalt.tmx | 6 +-
.../Shandalar/maps/tileset/FarmFood.png | Bin 0 -> 165053 bytes
.../Shandalar/maps/tileset/FarmFood.tsx | 4 +
.../adventure/Shandalar/maps/tileset/main.png | Bin 761521 -> 764907 bytes
.../sprites/{dungeon => }/badger.atlas | 0
.../sprites/{dungeon => }/badger.png | Bin
.../sprites/{dungeon => }/boar.atlas | 24 +-
.../Shandalar/sprites/{dungeon => }/boar.png | Bin
.../Shandalar/sprites/boss/frogboss.atlas | 98 +
.../Shandalar/sprites/boss/frogboss.png | Bin 0 -> 69189 bytes
.../sprites/{dungeon => boss}/garruk.atlas | 0
.../sprites/{dungeon => boss}/garruk.png | Bin
.../sprites/{dungeon => boss}/jace.atlas | 0
.../sprites/{dungeon => boss}/jace.png | Bin
.../sprites/{dungeon => boss}/kiora.atlas | 0
.../sprites/{dungeon => boss}/kiora.png | Bin
.../sprites/{dungeon => boss}/nahiri.atlas | 0
.../sprites/{dungeon => boss}/nahiri.png | Bin
.../Shandalar/sprites/boss/oozeboss.atlas | 20 +
.../Shandalar/sprites/boss/oozeboss.png | Bin 0 -> 8714 bytes
.../sprites/{dungeon => boss}/slimefoot.atlas | 0
.../sprites/{dungeon => boss}/slimefoot.png | Bin
.../sprites/{dungeon => boss}/slobad.atlas | 38 +-
.../sprites/{dungeon => boss}/slobad.png | Bin
.../sprites/{dungeon => boss}/teferi.atlas | 0
.../sprites/{dungeon => boss}/teferi.png | Bin
.../sprites/{dungeon => boss}/tibalt.atlas | 0
.../sprites/{dungeon => boss}/tibalt.png | Bin
.../sprites/{dungeon => boss}/xira.atlas | 0
.../sprites/{dungeon => boss}/xira.png | Bin
.../sprites/{dungeon => }/bull.atlas | 65 +-
.../Shandalar/sprites/{dungeon => }/bull.png | Bin
.../Shandalar/sprites/{dungeon => }/cat.atlas | 0
.../Shandalar/sprites/{dungeon => }/cat.png | Bin
.../adventure/Shandalar/sprites/crab.atlas | 56 +
.../Shandalar/sprites/{dungeon => }/crab.png | Bin
.../Shandalar/sprites/{dungeon => }/dog.atlas | 36 +-
.../Shandalar/sprites/{dungeon => }/dog.png | Bin
.../sprites/{dungeon => }/dragonfly.atlas | 2 +-
.../sprites/{dungeon => }/dragonfly.png | Bin
.../Shandalar/sprites/dungeon/bat.atlas | 53 +
.../Shandalar/sprites/dungeon/bat.png | Bin 0 -> 16108 bytes
.../Shandalar/sprites/dungeon/crab.atlas | 56 -
.../sprites/dungeon/flyingwitch.atlas | 86 +
.../Shandalar/sprites/dungeon/frogboss.atlas | 44 -
.../Shandalar/sprites/dungeon/frogboss.png | Bin 5942 -> 0 bytes
.../Shandalar/sprites/dungeon/gorilla.atlas | 53 +-
.../Shandalar/sprites/dungeon/horse.atlas | 6 +-
.../Shandalar/sprites/dungeon/oozeboss.atlas | 20 -
.../Shandalar/sprites/dungeon/oozeboss.png | Bin 6750 -> 0 bytes
.../sprites/dungeon/sandelemental.atlas | 20 +
.../sprites/dungeon/sandelemental.png | Bin 0 -> 9622 bytes
.../Shandalar/sprites/dungeon/sandwurm.atlas | 83 +
.../Shandalar/sprites/dungeon/sandwurm.png | Bin 0 -> 23709 bytes
.../Shandalar/sprites/dungeon/scorpion.atlas | 56 -
.../sprites/dungeon/swamptroll.atlas | 107 +
.../Shandalar/sprites/dungeon/swamptroll.png | Bin 0 -> 37481 bytes
.../Shandalar/sprites/dungeon/vulture.atlas | 40 +-
.../Shandalar/sprites/dungeon/wasp.atlas | 64 +-
.../Shandalar/sprites/dungeon/witch.atlas | 98 +
.../Shandalar/sprites/dungeon/witch.png | Bin 0 -> 32194 bytes
.../Shandalar/sprites/{dungeon => }/eye.atlas | 0
.../Shandalar/sprites/{dungeon => }/eye.png | Bin
.../Shandalar/sprites/{dungeon => }/fox.atlas | 0
.../Shandalar/sprites/{dungeon => }/fox.png | Bin
.../sprites/{dungeon => }/frog.atlas | 0
.../Shandalar/sprites/{dungeon => }/frog.png | Bin
.../sprites/{dungeon => }/fungus.atlas | 3 -
.../sprites/{dungeon => }/fungus.png | Bin
.../sprites/{dungeon => }/humanoidrat.atlas | 2 +-
.../sprites/{dungeon => }/humanoidrat.png | Bin
.../sprites/{dungeon => }/jackalwarrior.atlas | 48 +-
.../sprites/{dungeon => }/jackalwarrior.png | Bin
.../sprites/{dungeon => }/jellyfish.atlas | 0
.../sprites/{dungeon => }/jellyfish.png | Bin
.../sprites/{dungeon => }/kobold.atlas | 0
.../sprites/{dungeon => }/kobold.png | Bin
...emental.atlas => magmafireelemental.atlas} | 36 +-
...maelemental.png => magmafireelemental.png} | Bin
.../sprites/{dungeon => }/mummy.atlas | 0
.../Shandalar/sprites/{dungeon => }/mummy.png | Bin
.../sprites/{dungeon => }/octopus.atlas | 0
.../sprites/{dungeon => }/octopus.png | Bin
.../sprites/{dungeon => }/ooze.atlas | 0
.../Shandalar/sprites/{dungeon => }/ooze.png | Bin
.../Shandalar/sprites/{dungeon => }/owl.atlas | 0
.../Shandalar/sprites/{dungeon => }/owl.png | Bin
.../sprites/{dungeon => }/plant.atlas | 0
.../Shandalar/sprites/{dungeon => }/plant.png | Bin
.../sprites/{dungeon => }/raven.atlas | 0
.../Shandalar/sprites/{dungeon => }/raven.png | Bin
.../Shandalar/sprites/scorpion.atlas | 59 +
.../sprites/{dungeon => }/scorpion.png | Bin
.../sprites/{dungeon => }/squirrel.atlas | 0
.../sprites/{dungeon => }/squirrel.png | Bin
.../sprites/{dungeon => }/turtle.atlas | 0
.../sprites/{dungeon => }/turtle.png | Bin
.../sprites/{dungeon => }/unused/insect.atlas | 0
.../sprites/{dungeon => }/unused/insect.png | Bin
.../sprites/{dungeon => }/walkingbrain.atlas | 4 +-
.../sprites/{dungeon => }/walkingbrain.png | Bin
.../sprites/{dungeon => }/wildrat.atlas | 0
.../sprites/{dungeon => }/wildrat.png | Bin
.../adventure/Shandalar/world/enemies.json | 5525 +++++++++--------
.../res/adventure/Shandalar/world/items.json | 10 +
117 files changed, 4968 insertions(+), 2988 deletions(-)
create mode 100644 forge-gui/res/adventure/Shandalar/decks/bat.dck
create mode 100644 forge-gui/res/adventure/Shandalar/decks/darkenchanter.dck
create mode 100644 forge-gui/res/adventure/Shandalar/decks/sandgolem.dck
create mode 100644 forge-gui/res/adventure/Shandalar/decks/sandwurm.dck
create mode 100644 forge-gui/res/adventure/Shandalar/decks/swamptroll.dck
create mode 100644 forge-gui/res/adventure/Shandalar/decks/witch.dck
create mode 100644 forge-gui/res/adventure/Shandalar/maps/map/grolnok_f1.tmx
create mode 100644 forge-gui/res/adventure/Shandalar/maps/tileset/FarmFood.png
create mode 100644 forge-gui/res/adventure/Shandalar/maps/tileset/FarmFood.tsx
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/badger.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/badger.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/boar.atlas (76%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/boar.png (100%)
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/boss/frogboss.atlas
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/boss/frogboss.png
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/garruk.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/garruk.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/jace.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/jace.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/kiora.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/kiora.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/nahiri.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/nahiri.png (100%)
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/boss/oozeboss.atlas
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/boss/oozeboss.png
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/slimefoot.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/slimefoot.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/slobad.atlas (74%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/slobad.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/teferi.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/teferi.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/tibalt.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/tibalt.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/xira.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => boss}/xira.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/bull.atlas (55%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/bull.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/cat.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/cat.png (100%)
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/crab.atlas
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/crab.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/dog.atlas (71%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/dog.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/dragonfly.atlas (97%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/dragonfly.png (100%)
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/bat.atlas
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/bat.png
delete mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/crab.atlas
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/flyingwitch.atlas
delete mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/frogboss.atlas
delete mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/frogboss.png
delete mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/oozeboss.atlas
delete mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/oozeboss.png
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/sandelemental.atlas
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/sandelemental.png
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/sandwurm.atlas
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/sandwurm.png
delete mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/scorpion.atlas
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/swamptroll.atlas
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/swamptroll.png
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/witch.atlas
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/dungeon/witch.png
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/eye.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/eye.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/fox.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/fox.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/frog.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/frog.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/fungus.atlas (96%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/fungus.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/humanoidrat.atlas (98%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/humanoidrat.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/jackalwarrior.atlas (59%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/jackalwarrior.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/jellyfish.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/jellyfish.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/kobold.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/kobold.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon/magmaelemental.atlas => magmafireelemental.atlas} (78%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon/magmaelemental.png => magmafireelemental.png} (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/mummy.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/mummy.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/octopus.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/octopus.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/ooze.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/ooze.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/owl.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/owl.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/plant.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/plant.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/raven.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/raven.png (100%)
create mode 100644 forge-gui/res/adventure/Shandalar/sprites/scorpion.atlas
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/scorpion.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/squirrel.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/squirrel.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/turtle.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/turtle.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/unused/insect.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/unused/insect.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/walkingbrain.atlas (97%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/walkingbrain.png (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/wildrat.atlas (100%)
rename forge-gui/res/adventure/Shandalar/sprites/{dungeon => }/wildrat.png (100%)
diff --git a/forge-gui/res/adventure/Shandalar/decks/bat.dck b/forge-gui/res/adventure/Shandalar/decks/bat.dck
new file mode 100644
index 00000000000..7cd23ae0b79
--- /dev/null
+++ b/forge-gui/res/adventure/Shandalar/decks/bat.dck
@@ -0,0 +1,27 @@
+[metadata]
+Name=bat
+[Avatar]
+
+[Main]
+4 Basilica Screecher|GTC|1
+4 Blight Keeper|J22|1
+4 Blighted Bat|AKH|1
+4 Bloodhunter Bat|JMP|1
+4 Dirge Bat|IKO|1
+4 Duskhunter Bat|MM2|1
+4 Murder|M13|1
+4 Sinister Strength|PLS|1
+6 Swamp|J22|1
+8 Swamp|J22|2
+10 Swamp|J22|3
+4 Unholy Strength|30A|1
+[Sideboard]
+
+[Planes]
+
+[Schemes]
+
+[Conspiracy]
+
+[Dungeon]
+
diff --git a/forge-gui/res/adventure/Shandalar/decks/darkenchanter.dck b/forge-gui/res/adventure/Shandalar/decks/darkenchanter.dck
new file mode 100644
index 00000000000..dcddd176447
--- /dev/null
+++ b/forge-gui/res/adventure/Shandalar/decks/darkenchanter.dck
@@ -0,0 +1,34 @@
+[metadata]
+Name=darkenchanter
+[Avatar]
+
+[Main]
+4 Bayou|OLGC|1
+4 Cartouche of Ambition|AKR|1
+4 Doomwake Giant|C15|1
+4 Eidolon of Blossoms|JOU|1
+1 Forest|ELD|1
+2 Forest|ELD|3
+1 Forest|ELD|4
+4 Gnarled Scarhide|JOU|1
+4 Grim Guardian|JOU|1
+4 Necroblossom Snarl|STX|1
+4 Oubliette|2XM|1
+4 Overgrown Tomb|SLD|1
+1 Swamp|ELD|2
+2 Swamp|ELD|4
+4 Trial of Ambition|MB1|1
+4 Verdant Catacombs|SLU|1
+3 Verduran Enchantress|SLD|1
+4 Wild Growth|AFC|1
+2 Yavimaya Enchantress|TD0|1
+[Sideboard]
+
+[Planes]
+
+[Schemes]
+
+[Conspiracy]
+
+[Dungeon]
+
diff --git a/forge-gui/res/adventure/Shandalar/decks/sandgolem.dck b/forge-gui/res/adventure/Shandalar/decks/sandgolem.dck
new file mode 100644
index 00000000000..34f7ea579aa
--- /dev/null
+++ b/forge-gui/res/adventure/Shandalar/decks/sandgolem.dck
@@ -0,0 +1,32 @@
+[metadata]
+Name=sandgolem
+[Avatar]
+
+[Main]
+4 Char-Rumbler|TSR|1
+4 Choking Sands|VMA|1
+4 Mountain|KLD|1
+3 Mountain|KLD|2
+5 Mountain|KLD|3
+5 Plains|KLD|1
+5 Plains|KLD|2
+2 Plains|KLD|3
+3 Sand Golem|MIR|1
+4 Sand Strangler|AKR|1
+4 Sandblast|HOU|1
+1 Sandstone Oracle|IMA|1
+2 Sandstone Warrior|TPR|1
+2 Shock|DDN|1
+4 Tectonic Giant|AFC|1
+4 Thunder Spirit|PRM|1
+4 Viashino Sandstalker|VIS|1
+[Sideboard]
+
+[Planes]
+
+[Schemes]
+
+[Conspiracy]
+
+[Dungeon]
+
diff --git a/forge-gui/res/adventure/Shandalar/decks/sandwurm.dck b/forge-gui/res/adventure/Shandalar/decks/sandwurm.dck
new file mode 100644
index 00000000000..735f526f7bd
--- /dev/null
+++ b/forge-gui/res/adventure/Shandalar/decks/sandwurm.dck
@@ -0,0 +1,27 @@
+[metadata]
+Name=sandwurm
+[Avatar]
+
+[Main]
+4 Beneath the Sands|MB1|1
+4 Dirtcowl Wurm|TMP|1
+7 Forest|IKO|1
+8 Forest|IKO|2
+9 Forest|IKO|3
+4 Greater Sandwurm|IKO|1
+4 Rampant Growth|NCC|1
+4 Roar of the Wurm|DDS|1
+4 Sandwurm Convergence|CLB|1
+4 Spined Wurm|S00|1
+4 Symbiotic Wurm|VMA|1
+4 Teething Wurmlet|BRO|1
+[Sideboard]
+
+[Planes]
+
+[Schemes]
+
+[Conspiracy]
+
+[Dungeon]
+
diff --git a/forge-gui/res/adventure/Shandalar/decks/swamptroll.dck b/forge-gui/res/adventure/Shandalar/decks/swamptroll.dck
new file mode 100644
index 00000000000..32e557a3781
--- /dev/null
+++ b/forge-gui/res/adventure/Shandalar/decks/swamptroll.dck
@@ -0,0 +1,40 @@
+[metadata]
+Name=swamptroll
+[Avatar]
+
+[Main]
+4 Charnel Troll|GRN|1
+4 Clackbridge Troll|ELD|1
+4 Eat to Extinction|THB|1
+2 Feasting Troll King|ELD|1
+1 Forest|ELD|1
+1 Forest|ELD|2
+3 Forest|ELD|4
+4 Gluttonous Troll|ELD|1
+2 Grismold, the Dreadsower|C19|1
+1 Gyome, Master Chef|C21|1
+4 Haunted Mire|DMU|1
+2 Hunted Troll|RAV|1
+3 Infernal Grasp|MID|1
+4 Jungle Hollow|KTK|1
+1 Nature's Claim|IMA|1
+2 Old-Growth Troll|KHM|1
+3 Swamp|ELD|1
+1 Swamp|ELD|2
+2 Swamp|ELD|3
+1 Swamp|ELD|4
+4 Tainted Wood|C15|1
+2 Taste of Death|ELD|1
+2 Thrun, Breaker of Silence|ONE|1
+1 Thrun, the Last Troll|MBS|1
+2 Varolz, the Scar-Striped|DGM|1
+[Sideboard]
+
+[Planes]
+
+[Schemes]
+
+[Conspiracy]
+
+[Dungeon]
+
diff --git a/forge-gui/res/adventure/Shandalar/decks/witch.dck b/forge-gui/res/adventure/Shandalar/decks/witch.dck
new file mode 100644
index 00000000000..8747189507f
--- /dev/null
+++ b/forge-gui/res/adventure/Shandalar/decks/witch.dck
@@ -0,0 +1,31 @@
+[metadata]
+Name=witch
+[Avatar]
+
+[Main]
+2 Accursed Witch|SOI|1
+2 Cast Down|DOM|1
+4 Cuombajj Witches|CMR|1
+4 Curse of Leeches|MID|1
+4 Cursebound Witch|YMID|1
+1 Cut Down|DMU|1
+4 Kindly Stranger|SOI|1
+4 Sedgemoor Witch|STX|1
+20 Swamp|ELD|2
+1 Tempting Witch|JMP|1
+2 The Cauldron of Eternity|ELD|1
+2 The Hourglass Coven|HBG|1
+2 Veinwitch Coven|C21|1
+2 Witch of the Moors|JMP|1
+4 Witch's Cottage|ELD|1
+2 Witch's Vengeance|ELD|1
+[Sideboard]
+
+[Planes]
+
+[Schemes]
+
+[Conspiracy]
+
+[Dungeon]
+
diff --git a/forge-gui/res/adventure/Shandalar/maps/map/factory_2.tmx b/forge-gui/res/adventure/Shandalar/maps/map/factory_2.tmx
index 82b1839f3c4..51b7f46c3ed 100644
--- a/forge-gui/res/adventure/Shandalar/maps/map/factory_2.tmx
+++ b/forge-gui/res/adventure/Shandalar/maps/map/factory_2.tmx
@@ -71,7 +71,6 @@
-
diff --git a/forge-gui/res/adventure/Shandalar/maps/map/grolnok.tmx b/forge-gui/res/adventure/Shandalar/maps/map/grolnok.tmx
index dfa008f4639..69158c0e86c 100644
--- a/forge-gui/res/adventure/Shandalar/maps/map/grolnok.tmx
+++ b/forge-gui/res/adventure/Shandalar/maps/map/grolnok.tmx
@@ -1,81 +1,72 @@
-