From fde375843140a2a79b69d78a70ce87e4b8893fac Mon Sep 17 00:00:00 2001 From: Magpie Date: Tue, 19 Apr 2022 06:37:30 +0200 Subject: [PATCH 1/9] Big map update 10 Please talk to the Debug Elf for demonstration of these features. * Players can now receive blessings that give them an effect for next battle. * Enemies can also get modified with effects using map attributes. * Preliminary support for a flag to prevent magical escape from dungeons. * Players now have a color identity which can be checked for in dialogue conditions (soon will also allow filter for cards for that color) * Status screen now shows a wreath indicating the color identity around the portrait and information about current blessing. * Dialogue conditions can check for blessings (named ones). * Allow to override an enemy's name from the map editor. * Allow enemies to have dialogue when defeated. * Preliminary support to heal by arbitrary amounts (no overheal beyond max yet) --- .../adventure/character/EnemySprite.java | 6 +- .../adventure/character/RewardSprite.java | 14 +-- .../src/forge/adventure/data/DialogData.java | 14 ++- .../src/forge/adventure/data/EffectData.java | 14 ++- .../adventure/player/AdventurePlayer.java | 89 ++++++++++++---- .../src/forge/adventure/scene/DuelScene.java | 27 +++-- .../src/forge/adventure/scene/InnScene.java | 2 +- .../adventure/scene/PlayerStatisticScene.java | 96 ++++++++++++------ .../stage/ConsoleCommandInterpreter.java | 12 ++- .../src/forge/adventure/stage/MapStage.java | 89 +++++++++++----- .../adventure/util/JSONStringLoader.java | 27 +++++ .../src/forge/adventure/util/MapDialog.java | 50 +++++---- .../src/forge/adventure/world/WorldSave.java | 7 +- .../Shandalar/maps/main.tiled-session | 25 +++-- .../Shandalar/maps/map/debug_map.tmx | 54 +++++++++- .../adventure/Shandalar/skin/ui_skin.atlas | 9 ++ .../res/adventure/Shandalar/skin/ui_skin.json | 25 +++++ .../res/adventure/Shandalar/ui/avatarhud.png | Bin 238 -> 1634 bytes .../res/adventure/Shandalar/ui/colorC.png | Bin 0 -> 981 bytes .../adventure/Shandalar/ui/color_frames.png | Bin 0 -> 25339 bytes .../res/adventure/Shandalar/ui/statistic.json | 39 ++++--- 21 files changed, 435 insertions(+), 164 deletions(-) create mode 100644 forge-gui-mobile/src/forge/adventure/util/JSONStringLoader.java create mode 100644 forge-gui/res/adventure/Shandalar/ui/colorC.png create mode 100644 forge-gui/res/adventure/Shandalar/ui/color_frames.png diff --git a/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java b/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java index 76a5b19c0e1..40fb555258f 100644 --- a/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java +++ b/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.utils.Array; +import forge.adventure.data.EffectData; import forge.adventure.data.EnemyData; import forge.adventure.data.RewardData; import forge.adventure.util.Current; @@ -16,7 +17,10 @@ import forge.adventure.util.Reward; */ public class EnemySprite extends CharacterSprite { EnemyData data; - public MapDialog dialog; + public MapDialog dialog; //Dialog to show on contact. Overrides standard battle (can be started as an action) + public MapDialog defeatDialog; //Dialog to show on defeat. Overrides standard death (can be removed as an action) + public EffectData effect; //Battle effect for this enemy. Similar to a player's blessing. + public String nameOverride = ""; //Override name of this enemy in battles. public EnemySprite(EnemyData enemyData) { this(0,enemyData); diff --git a/forge-gui-mobile/src/forge/adventure/character/RewardSprite.java b/forge-gui-mobile/src/forge/adventure/character/RewardSprite.java index 6eefb159969..f1f0584b085 100644 --- a/forge-gui-mobile/src/forge/adventure/character/RewardSprite.java +++ b/forge-gui-mobile/src/forge/adventure/character/RewardSprite.java @@ -2,9 +2,8 @@ package forge.adventure.character; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.Json; -import com.badlogic.gdx.utils.SerializationException; import forge.adventure.data.RewardData; +import forge.adventure.util.JSONStringLoader; import forge.adventure.util.Reward; /** @@ -26,18 +25,11 @@ public class RewardSprite extends CharacterSprite { public RewardSprite(String data, String _sprite){ super(_sprite); - Json json = new Json(); if (data != null) { - try { rewards = json.fromJson(RewardData[].class, data); } - catch(SerializationException E){ - //JSON parsing could fail. Since this an user written part, assume failure is possible (it happens). - System.err.printf("[%s] while loading JSON file for reward actor. JSON:\n%s\nUsing a default reward.", E.getMessage(), data); - rewards = json.fromJson(RewardData[].class, default_reward); - } - + rewards = JSONStringLoader.parse(RewardData[].class, data, default_reward); } else { //Shouldn't happen, but make sure it doesn't fly by. System.err.printf("Reward data is null. Using a default reward."); - rewards = json.fromJson(RewardData[].class, default_reward); + rewards = JSONStringLoader.parse(RewardData[].class, default_reward, default_reward); } } diff --git a/forge-gui-mobile/src/forge/adventure/data/DialogData.java b/forge-gui-mobile/src/forge/adventure/data/DialogData.java index d85426ac6bf..27aa1d982e3 100644 --- a/forge-gui-mobile/src/forge/adventure/data/DialogData.java +++ b/forge-gui-mobile/src/forge/adventure/data/DialogData.java @@ -5,7 +5,7 @@ package forge.adventure.data; * Carries all text, branches and effects of dialogs. */ public class DialogData { - public EffectData[] effect; //List of effects to cause when the dialog shows. + public ActionData[] effect; //List of effects to cause when the dialog shows. public ConditionData[] condition; //List of conditions for the action to show. public String name; //Text to display when action is listed as a button. public String locname; //References a localized string for the button labels. @@ -13,17 +13,21 @@ public class DialogData { public String loctext; //References a localized string for the text body. public DialogData[] options; // - static public class EffectData { + static public class ActionData { public String removeItem; //Remove item name from inventory. public String addItem; //Add item name to inventory. public int deleteMapObject = 0; //Remove ID from the map. -1 for self. public int battleWithActorID = 0; //Start a battle with enemy ID. -1 for self if possible. + public EffectData giveBlessing; //Give a blessing to the player. + public String setColorIdentity; //Change player's color identity. } static public class ConditionData { public String item; - public int flag = 0; //Check for a local dungeon flag. - public int actorID = 0; //Check for an actor ID. - public boolean not = false; //Reverse the result of a condition ("actorID":"XX" + "not":true => true if XX is not in the map.) + public int flag = 0; //Check for a local dungeon flag. + public int actorID = 0; //Check for an actor ID. + public String hasBlessing = null; //Check for specific blessing, if named. + public String colorIdentity = null;//Check for player's current color identity. + public boolean not = false; //Reverse the result of a condition ("actorID":"XX" + "not":true => true if XX is not in the map.) } } diff --git a/forge-gui-mobile/src/forge/adventure/data/EffectData.java b/forge-gui-mobile/src/forge/adventure/data/EffectData.java index 0dd8ba17424..4b313b95efb 100644 --- a/forge-gui-mobile/src/forge/adventure/data/EffectData.java +++ b/forge-gui-mobile/src/forge/adventure/data/EffectData.java @@ -6,12 +6,16 @@ import forge.item.PaperCard; import forge.item.PaperToken; import forge.model.FModel; -public class EffectData { +import java.io.Serializable; + +public class EffectData implements Serializable { + public String name = null; //Effect name. Can be checked for. //Duel effects. public int lifeModifier = 0; //Amount to add to starting Life. public int changeStartCards = 0; //Amount to add to starting hand size. public String[] startBattleWithCard; //Cards that start in the Battlefield. //Map only effects. + public boolean colorView = false; //Allows to display enemy colors on the map (TODO) public float moveSpeed = 1.0f; //Change of movement speed. Map only. //Opponent field. public EffectData opponent; //Effects to be applied to the opponent's side. @@ -45,6 +49,8 @@ public class EffectData { public String getDescription() { String description = ""; + if(this.name != null && !this.name.isEmpty()) + description += this.name + "\n"; if(this.lifeModifier != 0) description += "Life: " + ((this.lifeModifier > 0) ? "+" : "") + this.lifeModifier + "\n"; if(this.startBattleWithCard != null && this.startBattleWithCard.length != 0) @@ -54,9 +60,9 @@ public class EffectData { if(this.changeStartCards != 0) description+="Starting hand: " + this.changeStartCards + "\n"; if(this.opponent != null) { - String oppEffect=this.opponent.getDescription(); - if(oppEffect != "") { - description += "Gives Opponent:\n"; + String oppEffect = this.opponent.getDescription(); + description += "Gives Opponent:\n"; + if(!oppEffect.isEmpty()) { description += oppEffect; } } diff --git a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java index 8a7207a6991..eee7f13c514 100644 --- a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java +++ b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java @@ -3,8 +3,10 @@ package forge.adventure.player; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.Null; import com.google.common.collect.Lists; import forge.adventure.data.DifficultyData; +import forge.adventure.data.EffectData; import forge.adventure.data.HeroListData; import forge.adventure.data.ItemData; import forge.adventure.util.*; @@ -17,29 +19,30 @@ import forge.item.PaperCard; import forge.util.ItemPool; import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** * Class that represents the player (not the player sprite) */ public class AdventurePlayer implements Serializable, SaveFileContent { + private enum ColorID { COLORLESS, WHITE, BLACK, BLUE, RED, GREEN } public static final int NUMBER_OF_DECKS=10; - private Deck deck; - private int avatarIndex; - private int heroRace; - private boolean isFemale; + + private Deck deck; + private int avatarIndex; + private int heroRace; + private boolean isFemale; private float worldPosX; private float worldPosY; private String name; + private ColorID colorIdentity = ColorID.COLORLESS; private int gold=0; private int maxLife=20; private int life=20; private int selectedDeckIndex=0; + private EffectData blessing; //Blessing to apply for next battle. private PlayerStatistic statistic=new PlayerStatistic(); - private Deck[] decks=new Deck[NUMBER_OF_DECKS]; + private Deck[] decks=new Deck[NUMBER_OF_DECKS]; private final DifficultyData difficultyData=new DifficultyData(); private final Array inventoryItems=new Array<>(); @@ -63,7 +66,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent { 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,DifficultyData difficultyData) { + public void create(String n, int startingColorIdentity, Deck startingDeck, boolean male, int race, int avatar,DifficultyData difficultyData) { inventoryItems.clear(); equippedItems.clear(); deck = startingDeck; @@ -83,11 +86,12 @@ public class AdventurePlayer implements Serializable, SaveFileContent { heroRace = race; isFemale = !male; name = n; + setColorIdentity(startingColorIdentity + 1); statistic.clear(); newCards.clear(); onGoldChangeList.emit(); onLifeTotalChangeList.emit(); - + blessing = null; inventoryItems.addAll(difficultyData.startItems); } @@ -135,12 +139,41 @@ public class AdventurePlayer implements Serializable, SaveFileContent { this.worldPosY = worldPosY; } + public void setColorIdentity(String C){ + switch (C.toUpperCase()){ + case "B": this.colorIdentity = ColorID.BLACK; break; + case "G": this.colorIdentity = ColorID.GREEN; break; + case "R": this.colorIdentity = ColorID.RED; break; + case "U": this.colorIdentity = ColorID.BLUE; break; + case "W": this.colorIdentity = ColorID.WHITE; break; + case "C": default: this.colorIdentity = ColorID.COLORLESS; break; + } + } + public void setColorIdentity(int C){ + switch (C){ + case 2: this.colorIdentity = ColorID.BLACK; break; + case 5: this.colorIdentity = ColorID.GREEN; break; + case 4: this.colorIdentity = ColorID.RED; break; + case 3: this.colorIdentity = ColorID.BLUE; break; + case 1: this.colorIdentity = ColorID.WHITE; break; + case 0: default: this.colorIdentity = ColorID.COLORLESS; break; + } + } + + public String getColorIdentity(){ + switch (colorIdentity){ + case BLUE : return "U"; + case GREEN : return "G"; + case RED : return "R"; + case BLACK : return "B"; + case WHITE : return "W"; + case COLORLESS: default: return "C"; //You are either Ugin or an Eldrazi. Nice. + } + } @Override public void load(SaveFileData data) { - - this.statistic.load(data.readSubData("statistic")); this.difficultyData.startingLife=data.readInt("startingLife"); this.difficultyData.staringMoney=data.readInt("staringMoney"); @@ -151,7 +184,6 @@ public class AdventurePlayer implements Serializable, SaveFileContent { if(this.difficultyData.sellFactor==0) this.difficultyData.sellFactor=0.2f; - name = data.readString("name"); worldPosX = data.readFloat("worldPosX"); worldPosY = data.readFloat("worldPosY"); @@ -159,10 +191,14 @@ public class AdventurePlayer implements Serializable, SaveFileContent { avatarIndex = data.readInt("avatarIndex"); heroRace = data.readInt("heroRace"); isFemale = data.readBool("isFemale"); + colorIdentity = ColorID.COLORLESS; + if(data.containsKey("colorIdentity")) + setColorIdentity(data.readString("colorIdentity")); gold = data.readInt("gold"); life = data.readInt("life"); maxLife = data.readInt("maxLife"); - + blessing = null; + if(data.containsKey("blessing")) blessing = (EffectData)data.readObject("blessing"); inventoryItems.clear(); equippedItems.clear(); if(data.containsKey("inventory")) @@ -231,13 +267,14 @@ public class AdventurePlayer implements Serializable, SaveFileContent { data.store("avatarIndex",avatarIndex); data.store("heroRace",heroRace); data.store("isFemale",isFemale); + data.store("colorIdentity", getColorIdentity()); data.store("gold",gold); data.store("life",life); data.store("maxLife",maxLife); data.store("deckName",deck.getName()); data.storeObject("inventory",inventoryItems.toArray(String.class)); - + data.storeObject("blessing", blessing); ArrayList slots=new ArrayList<>(); ArrayList items=new ArrayList<>(); @@ -266,6 +303,17 @@ public class AdventurePlayer implements Serializable, SaveFileContent { return data; } + public void addBlessing(EffectData bless){ blessing = bless; } + + public void clearBlessing() { blessing = null; } + + public @Null EffectData getBlessing(){ return blessing; } + + public boolean hasBlessing(String name){ + if(blessing == null) return false; + if(blessing.name.equals(name)) return true; + return false; + } public String spriteName() { @@ -348,8 +396,13 @@ public class AdventurePlayer implements Serializable, SaveFileContent { return maxLife; } - public void heal() { - life=maxLife; + public void heal(int amount) { + life = Math.min(life + amount, maxLife); + onLifeTotalChangeList.emit(); + } + + public void fullHeal() { + life = maxLife; onLifeTotalChangeList.emit(); } public void defeated() { diff --git a/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java b/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java index b288d94b93e..eaeb4a3c2e7 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java @@ -54,7 +54,8 @@ public class DuelScene extends ForgeScene { public void GameEnd() { boolean winner=humanPlayer == hostedMatch.getGame().getMatch().getWinner(); - String enemyName=enemy.getData().name; + String enemyName=(enemy.nameOverride.isEmpty() ? enemy.getData().name : enemy.nameOverride); + Current.player().clearBlessing(); Gdx.app.postRunnable(new Runnable() { @Override public void run() { @@ -97,6 +98,7 @@ public class DuelScene extends ForgeScene { public void enter() { Set appliedVariants = new HashSet<>(); appliedVariants.add(GameType.Constructed); + AdventurePlayer advPlayer = Current.player(); List players = new ArrayList<>(); Deck playerDeck=(Deck)AdventurePlayer.current().getSelectedDeck().copyTo("PlayerDeckCopy"); @@ -105,27 +107,25 @@ public class DuelScene extends ForgeScene { playerDeck.getMain().add("Wastes",missingCards); humanPlayer = RegisteredPlayer.forVariants(2, appliedVariants,playerDeck, null, false, null, null); LobbyPlayer playerObject = GamePlayerUtil.getGuiPlayer(); - FSkin.getAvatars().put(90001, Current.player().avatar()); + FSkin.getAvatars().put(90001, advPlayer.avatar()); playerObject.setAvatarIndex(90001); humanPlayer.setPlayer(playerObject); - humanPlayer.setStartingLife(Current.player().getLife()); + humanPlayer.setStartingLife(advPlayer.getLife()); Current.setLatestDeck(enemy.getData().generateDeck()); RegisteredPlayer aiPlayer = RegisteredPlayer.forVariants(2, appliedVariants, Current.latestDeck(), null, false, null, null); LobbyPlayer enemyPlayer = GamePlayerUtil.createAiPlayer(this.enemy.getData().name, selectAI(this.enemy.getData().ai)); - + if(!enemy.nameOverride.isEmpty()) enemyPlayer.setName(enemy.nameOverride); //Override name if defined in the map. FSkin.getAvatars().put(90000, this.enemy.getAvatar()); enemyPlayer.setAvatarIndex(90000); aiPlayer.setPlayer(enemyPlayer); - aiPlayer.setStartingLife(Math.round((float)enemy.getData().life*Current.player().getDifficulty().enemyLifeFactor)); - - + aiPlayer.setStartingLife(Math.round((float)enemy.getData().life*advPlayer.getDifficulty().enemyLifeFactor)); Array playerEffects = new Array<>(); Array oppEffects = new Array<>(); //Collect and add items effects first. - for(String playerItem:Current.player().getEquippedItems()) { + for(String playerItem:advPlayer.getEquippedItems()) { ItemData item=ItemData.getItem(playerItem); playerEffects.add(item.effect); if(item.effect.opponent != null) oppEffects.add(item.effect.opponent); @@ -139,13 +139,22 @@ public class DuelScene extends ForgeScene { } //Collect and add player blessings. + if(advPlayer.getBlessing() != null){ + playerEffects.add(advPlayer.getBlessing()); + if(advPlayer.getBlessing().opponent != null) oppEffects.add(advPlayer.getBlessing().opponent); + } //Collect and add enemy effects (same as blessings but for individual enemies). + if(enemy.effect != null){ + oppEffects.add(enemy.effect); + if(enemy.effect.opponent != null) + playerEffects.add(enemy.effect.opponent); + } //Collect and add dungeon-wide effects. if(dungeonEffect != null) { oppEffects.add(dungeonEffect); - if (dungeonEffect.opponent != null) + if(dungeonEffect.opponent != null) playerEffects.add(dungeonEffect.opponent); } diff --git a/forge-gui-mobile/src/forge/adventure/scene/InnScene.java b/forge-gui-mobile/src/forge/adventure/scene/InnScene.java index 1e6d902ca6c..f78b2df8f18 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/InnScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/InnScene.java @@ -24,7 +24,7 @@ public class InnScene extends UIScene { } public void heal() { - Current.player().heal(); + Current.player().fullHeal(); } @Override diff --git a/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java b/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java index d69fc1e2094..ecf71b3cecd 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java @@ -1,6 +1,9 @@ package forge.adventure.scene; import com.badlogic.gdx.Input; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.ui.Image; import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; @@ -14,6 +17,7 @@ import forge.adventure.data.EnemyData; import forge.adventure.data.WorldData; import forge.adventure.player.AdventurePlayer; import forge.adventure.stage.GameHUD; +import forge.adventure.util.Config; import forge.adventure.util.Controls; import forge.adventure.util.Current; import forge.adventure.world.WorldSave; @@ -24,13 +28,16 @@ import java.util.Map; public class PlayerStatisticScene extends UIScene { Image avatar, avatarBorder, lifeIcon, goldIcon; + Image colorFrame; Label money, life; Label wins, totalWins; Label loss, totalLoss; Label winloss, lossWinRatio; Label playerName; TextButton back; + Texture colorFrames; private Table enemiesGroup; + Label blessingScroll; public PlayerStatisticScene() { super(Forge.isLandscapeMode() ? "ui/statistic.json" : "ui/statistic_portrait.json"); @@ -55,6 +62,20 @@ public class PlayerStatisticScene extends UIScene { Forge.switchToLast(); return true; } + private TextureRegion getColorFrame(String C){ + int x, y; + switch(C){ + case "B": { x = 0 ; y = 0 ; break; } + case "G": { x = 64; y = 0 ; break; } + case "R": { x = 0 ; y = 32; break; } + case "U": { x = 32; y = 32; break; } + case "W": { x = 64; y = 32; break; } + default: + case "C": { x = 32; y = 0 ; break; } + } + TextureRegion result = new TextureRegion(colorFrames, x, y, 32, 32); + return result; + } @Override public void enter() { @@ -99,6 +120,16 @@ public class PlayerStatisticScene extends UIScene { if (lossWinRatio != null) { lossWinRatio.setText(Float.toString(Current.player().getStatistic().winLossRatio())); } + if(colorFrame != null){ + colorFrame.setDrawable(new TextureRegionDrawable(getColorFrame(Current.player().getColorIdentity()))); + } + if(blessingScroll != null){ + if(Current.player().getBlessing() != null) { + blessingScroll.setText(Current.player().getBlessing().getDescription()); + } else { + blessingScroll.setText("No blessing."); + } + } for (Map.Entry> entry : Current.player().getStatistic().getWinLossRecord().entrySet()) { EnemyData data = WorldData.getEnemy(entry.getKey()); @@ -121,38 +152,45 @@ public class PlayerStatisticScene extends UIScene { @Override public void resLoaded() { super.resLoaded(); - enemiesGroup = new Table(Controls.GetSkin()); - enemiesGroup.row(); - ui.onButtonPress("return", new Runnable() { - @Override - public void run() { - PlayerStatisticScene.this.back(); - } - }); - avatar = ui.findActor("avatar"); - avatarBorder = ui.findActor("avatarBorder"); - playerName = ui.findActor("playerName"); - life = ui.findActor("lifePoints"); - money = ui.findActor("money"); - lifeIcon = ui.findActor("lifeIcon"); - goldIcon = ui.findActor("goldIcon"); - wins = ui.findActor("wins"); - wins.setText(Forge.getLocalizer().getMessage("lblWinProper")+":"); - totalWins = ui.findActor("totalWins"); - loss = ui.findActor("loss"); - loss.setText(Forge.getLocalizer().getMessage("lblLossProper")+":"); - totalLoss = ui.findActor("totalLoss"); - winloss = ui.findActor("winloss"); - winloss.setText(Forge.getLocalizer().getMessage("lblWinProper")+"/"+Forge.getLocalizer().getMessage("lblLossProper")); - lossWinRatio = ui.findActor("lossWinRatio"); - back = ui.findActor("return"); - back.getLabel().setText(Forge.getLocalizer().getMessage("lblBack")); - ScrollPane scrollPane = ui.findActor("enemies"); - scrollPane.setActor(enemiesGroup); + enemiesGroup = new Table(Controls.GetSkin()); + enemiesGroup.row(); + blessingScroll = Controls.newLabel(""); + blessingScroll.setStyle(new Label.LabelStyle(Controls.getBitmapFont("default"), Color.BLACK)); + ui.onButtonPress("return", new Runnable() { + @Override + public void run() { + PlayerStatisticScene.this.back(); + } + }); + + avatar = ui.findActor("avatar"); + avatarBorder = ui.findActor("avatarBorder"); + playerName = ui.findActor("playerName"); + life = ui.findActor("lifePoints"); + money = ui.findActor("money"); + lifeIcon = ui.findActor("lifeIcon"); + goldIcon = ui.findActor("goldIcon"); + wins = ui.findActor("wins"); + colorFrame = ui.findActor("colorFrame"); + wins.setText(Forge.getLocalizer().getMessage("lblWinProper")+":"); + totalWins = ui.findActor("totalWins"); + loss = ui.findActor("loss"); + loss.setText(Forge.getLocalizer().getMessage("lblLossProper")+":"); + totalLoss = ui.findActor("totalLoss"); + winloss = ui.findActor("winloss"); + winloss.setText(Forge.getLocalizer().getMessage("lblWinProper")+"/"+Forge.getLocalizer().getMessage("lblLossProper")); + lossWinRatio = ui.findActor("lossWinRatio"); + back = ui.findActor("return"); + back.getLabel().setText(Forge.getLocalizer().getMessage("lblBack")); + ScrollPane scrollPane = ui.findActor("enemies"); + scrollPane.setActor(enemiesGroup); + colorFrames = new Texture(Config.instance().getFile("ui/color_frames.png")); + ScrollPane blessing = ui.findActor("blessingInfo"); + blessing.setActor(blessingScroll); + } @Override public void create() { - } } diff --git a/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java b/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java index 2ac3b863d1e..f156e8acbc1 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java +++ b/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java @@ -161,10 +161,18 @@ public class ConsoleCommandInterpreter { return "Added item "+s[0]; return "can not find item "+s[0]; }); - registerCommand(new String[]{"heal"}, s -> { - Current.player().heal(); + registerCommand(new String[]{"fullHeal"}, s -> { + Current.player().fullHeal(); return "Player life back to "+Current.player().getLife(); }); + registerCommand(new String[]{"heal", "amount"}, s -> { + if(s.length<1) return "Command needs 1 parameter"; + int N = 0; + try { N = Integer.parseInt(s[0]); } + catch (Exception e) { return "Can not convert " + s[0] + " to integer"; } + Current.player().heal(N); + return "Player healed to " + Current.player().getLife() + "/" + Current.player().getMaxLife(); + }); registerCommand(new String[]{"debug","on"}, s -> { Current.setDebug(true); return "Debug mode on"; diff --git a/forge-gui-mobile/src/forge/adventure/stage/MapStage.java b/forge-gui-mobile/src/forge/adventure/stage/MapStage.java index 71488a88042..770245fe57c 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/MapStage.java +++ b/forge-gui-mobile/src/forge/adventure/stage/MapStage.java @@ -15,10 +15,9 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Group; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.ui.Dialog; +import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.Json; import com.badlogic.gdx.utils.ScreenUtils; -import com.badlogic.gdx.utils.SerializationException; import forge.Forge; import forge.adventure.character.*; import forge.adventure.data.*; @@ -64,7 +63,12 @@ public class MapStage extends GameStage { private Stage dialogStage; private boolean dialogOnlyInput; - private EffectData effect; + + //Map properties. + //These maps are defined as embedded properties within the Tiled maps. + private EffectData effect; //"Dungeon Effect": Character Effect applied to all adversaries within the map. + private boolean preventEscape = false; //Prevents player from escaping the dungeon by any means that aren't an exit. + public boolean getDialogOnlyInput() { return dialogOnlyInput; @@ -73,16 +77,18 @@ public class MapStage extends GameStage { return dialog; } + public boolean canEscape() { return (preventEscape ? true : false); } //Check if escape is possible. + public void clearIsInMap() { isInMap = false; - effect = null; + effect = null; //Reset effect so battles outside the dungeon don't use the last visited dungeon's effects. + preventEscape = false; GameHUD.getInstance().showHideMap(true); } public void draw (Batch batch) { //Camera camera = getCamera() ; //camera.update(); //update camera after all layers got drawn - if (!getRoot().isVisible()) return; getRoot().draw(batch, 1); } @@ -125,7 +131,6 @@ public class MapStage extends GameStage { } } return false; - } final ArrayList currentCollidingRectangles = new ArrayList<>(); @@ -185,8 +190,10 @@ public class MapStage extends GameStage { dialog.getButtonTable().clear(); String text = "Strange magical energies flow within this place...\nAll opponents get:\n"; text += E.getDescription(); - dialog.text(text); - dialog.getButtonTable().add(Controls.newTextButton("OK", this::hideDialog)); + Label L = Controls.newLabel(text); + L.setWrap(true); + dialog.getContentTable().add(L).width(260f); + dialog.getButtonTable().add(Controls.newTextButton("OK", this::hideDialog)).width(260f); dialog.setKeepWithinStage(true); showDialog(); } @@ -210,16 +217,17 @@ public class MapStage extends GameStage { collision = new ArrayList[(int) width][(int) height]; //Load dungeon effects. - if( map.getProperties().get("dungeonEffect") != null && !map.getProperties().get("dungeonEffect").toString().isEmpty()){ - Json json = new Json(); - try { effect = json.fromJson(EffectData.class, map.getProperties().get("dungeonEffect").toString()); } - catch(SerializationException E) { - //JSON parsing could fail. Since this an user written part, assume failure is possible (it happens). - System.err.printf("[%s] while loading JSON file for dialog actor. JSON:\n%s\nUsing a default dialog.", E.getMessage(), map.getProperties().get("dungeonEffect").toString()); - effect = json.fromJson(EffectData.class, ""); - } + MapProperties MP = map.getProperties(); + + if( MP.get("dungeonEffect") != null && !MP.get("dungeonEffect").toString().isEmpty()){ + JSONStringLoader json = new JSONStringLoader(); + effect = json.parse(EffectData.class, map.getProperties().get("dungeonEffect").toString(), ""); effectDialog(effect); } + if (MP.get("preventEscape") != null) preventEscape = (boolean)MP.get("preventEscape"); + if (MP.get("music") != null && !MP.get("music").toString().isEmpty()){ + //TODO: Add a way to play a music file directly without using a playlist. + } GetPlayer().stop(); @@ -276,16 +284,37 @@ public class MapStage extends GameStage { addMapActor(obj, entry); break; case "reward": - if (prop.get("reward") != null) { - RewardSprite R = new RewardSprite(id, prop.get("reward").toString(), prop.get("sprite").toString()); - addMapActor(obj, R); + Object R = prop.get("reward"); + if(R != null && !R.toString().isEmpty()) { + Object S = prop.get("sprite"); + String Sp = "sprites/treasure.atlas"; + if(S != null && !S.toString().isEmpty()) Sp = S.toString(); + else System.err.printf("No sprite defined for reward (ID:%s), defaulting to \"sprites/treasure.atlas\"", id); + RewardSprite RW = new RewardSprite(id, R.toString(), Sp); + addMapActor(obj, RW); } break; case "enemy": - EnemySprite mob = new EnemySprite(id, WorldData.getEnemy(prop.get("enemy").toString())); - addMapActor(obj, mob); - if(prop.get("dialog") != null && !prop.get("dialog").toString().isEmpty()) { - mob.dialog = new MapDialog(prop.get("dialog").toString(), this, mob.getId()); + Object E = prop.get("enemy"); + if(E != null && !E.toString().isEmpty()) { + EnemySprite mob = new EnemySprite(id, WorldData.getEnemy(E.toString())); + Object D = prop.get("dialog"); //Check if the enemy has a dialogue attached to it. + if (D != null && !D.toString().isEmpty()) { + mob.dialog = new MapDialog(D.toString(), this, mob.getId()); + } + D = prop.get("defeatDialog"); //Check if the enemy has a defeat dialogue attached to it. + if (D != null && !D.toString().isEmpty()) { + mob.defeatDialog = new MapDialog(D.toString(), this, mob.getId()); + } + D = prop.get("name"); //Check for name override. + if (D != null && !D.toString().isEmpty()) { + mob.nameOverride = D.toString(); + } + D = prop.get("effect"); //Check for special effects. + if (D != null && !D.toString().isEmpty()) { + mob.effect = JSONStringLoader.parse(EffectData.class, D.toString(), ""); + } + addMapActor(obj, mob); } break; case "dummy": //Does nothing. Mostly obstacles to be removed by ID by switches or such. @@ -426,11 +455,17 @@ public class MapStage extends GameStage { protected void getReward() { isLoadingMatch = false; ((RewardScene) SceneType.RewardScene.instance).loadRewards(currentMob.getRewards(), RewardScene.Type.Loot, null); - currentMob.remove(); - actors.removeValue(currentMob, true); - changes.deleteObject(currentMob.getId()); - currentMob = null; Forge.switchScene(SceneType.RewardScene.instance); + if(currentMob.defeatDialog == null) { + currentMob.remove(); + actors.removeValue(currentMob, true); + changes.deleteObject(currentMob.getId()); + } else { + currentMob.defeatDialog.activate(); + player.setAnimation(CharacterSprite.AnimationTypes.Idle); + currentMob.setAnimation(CharacterSprite.AnimationTypes.Idle); + } + currentMob = null; } public void removeAllEnemies() { diff --git a/forge-gui-mobile/src/forge/adventure/util/JSONStringLoader.java b/forge-gui-mobile/src/forge/adventure/util/JSONStringLoader.java new file mode 100644 index 00000000000..c7faac4c2e0 --- /dev/null +++ b/forge-gui-mobile/src/forge/adventure/util/JSONStringLoader.java @@ -0,0 +1,27 @@ +package forge.adventure.util; + +import com.badlogic.gdx.utils.Json; +import com.badlogic.gdx.utils.Null; +import com.badlogic.gdx.utils.SerializationException; +/** + * JSONStringLoader + * Wrapper around Json functions for easier loading of arbitrary JSON strings without + * having to try/catch every time. + */ +public class JSONStringLoader { + private static final Json JSON = new Json(); + public static @Null T parse(Class type, String json, String fallback){ + return parse(type, null, json, fallback); + } + + public static @Null T parse(Class type, Class elementType, String json, String fallback){ + if(json != null && !json.isEmpty()){ + try { return JSON.fromJson(type, elementType, json); } + catch(SerializationException E) { + //JSON parsing could fail. Since this an user written part, assume failure is possible (it happens). + System.err.printf("Error loading JSON string:\n%s\nUsing fallback.", E.getMessage()); + } + } + return JSON.fromJson(type, elementType, fallback); + } +} diff --git a/forge-gui-mobile/src/forge/adventure/util/MapDialog.java b/forge-gui-mobile/src/forge/adventure/util/MapDialog.java index f023bfeff5f..b5e62212b86 100644 --- a/forge-gui-mobile/src/forge/adventure/util/MapDialog.java +++ b/forge-gui-mobile/src/forge/adventure/util/MapDialog.java @@ -2,10 +2,9 @@ package forge.adventure.util; import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.Json; -import com.badlogic.gdx.utils.SerializationException; import forge.Forge; import forge.adventure.data.DialogData; +import forge.adventure.player.AdventurePlayer; import forge.adventure.stage.MapStage; import forge.util.Localizer; @@ -32,21 +31,16 @@ public class MapDialog { "]"; - public MapDialog(String S, MapStage ST, int parentID) { - this.stage = ST; + public MapDialog(String S, MapStage stage, int parentID) { + this.stage = stage; this.parentID = parentID; - Json json = new Json(); - if (S.isEmpty()){ + if (S.isEmpty()) { System.err.print("Dialog error. Dialog property is empty.\n"); - this.data = json.fromJson(Array.class, DialogData.class, defaultJSON); + this.data = JSONStringLoader.parse(Array.class, DialogData.class, defaultJSON, defaultJSON); return; } - try { data = json.fromJson(Array.class, DialogData.class, S); } - catch(SerializationException E){ - //JSON parsing could fail. Since this an user written part, assume failure is possible (it happens). - System.err.printf("[%s] while loading JSON file for dialog actor. JSON:\n%s\nUsing a default dialog.", E.getMessage(), S); - this.data = json.fromJson(Array.class, DialogData.class, defaultJSON); - } + this.data = JSONStringLoader.parse(Array.class, DialogData.class, S, defaultJSON); + } private void loadDialog(DialogData dialog) { //Displays a dialog with dialogue and possible choices. @@ -69,6 +63,7 @@ public class MapDialog { TextButton B = Controls.newTextButton(name,() -> loadDialog(option)); B.getLabel().setWrap(true); //We want this to wrap in case it's a wordy choice. D.getButtonTable().add(B).width(WIDTH - 10); //The button table also returns a Cell when adding. + //TODO: Reducing the space a tiny bit could help. But should be fine as long as there aren't more than 4-5 options. D.getButtonTable().row(); //Add a row. Tried to allow a few per row but it was a bit erratic. } } @@ -87,9 +82,9 @@ public class MapDialog { } } - void setEffects(DialogData.EffectData[] data) { + void setEffects(DialogData.ActionData[] data) { if(data==null) return; - for(DialogData.EffectData E:data) { + for(DialogData.ActionData E:data) { if (E.removeItem != null){ //Removes an item from the player's inventory. Current.player().removeItem(E.removeItem); } @@ -104,20 +99,35 @@ public class MapDialog { if(E.battleWithActorID < 0) stage.beginDuel(stage.getEnemyByID(parentID)); else stage.beginDuel(stage.getEnemyByID(E.battleWithActorID)); } + if (E.giveBlessing != null) { //Gives a blessing for your next battle. + Current.player().addBlessing(E.giveBlessing); + } + if (E.setColorIdentity != null && !E.setColorIdentity.isEmpty()){ //Sets color identity (use sparingly) + Current.player().setColorIdentity(E.setColorIdentity); + } //Create map object. - //Check for quest flags, local. - //Check for quest flags, global. } } boolean isConditionOk(DialogData.ConditionData[] data) { - if(data==null) return true; + if( data==null ) return true; + AdventurePlayer player = Current.player(); for(DialogData.ConditionData condition:data) { - if(condition.item != null && !condition.item.isEmpty()) { //Check for item. - if(!Current.player().hasItem(condition.item)) { + if(condition.item != null && !condition.item.isEmpty()) { //Check for an item in player's inventory. + if(!player.hasItem(condition.item)) { if(!condition.not) return false; //Only return on a false. } else if(condition.not) return false; } + if(condition.colorIdentity != null && !condition.colorIdentity.isEmpty()) { //Check for player's color ID. + if(!player.getColorIdentity().equals(condition.colorIdentity.toUpperCase())){ + if(!condition.not) return false; + } else if(condition.not) return false; + } + if(condition.hasBlessing != null && !condition.hasBlessing.isEmpty()){ //Check for a named blessing. + if(!player.hasBlessing(condition.hasBlessing)){ + if(!condition.not) return false; + } else if(condition.not) return false; + } if(condition.actorID != 0) { //Check for actor ID. if(!stage.lookForID(condition.actorID)){ if(!condition.not) return false; //Same as above. diff --git a/forge-gui-mobile/src/forge/adventure/world/WorldSave.java b/forge-gui-mobile/src/forge/adventure/world/WorldSave.java index adcd6c0af5b..f0a5ab683f0 100644 --- a/forge-gui-mobile/src/forge/adventure/world/WorldSave.java +++ b/forge-gui-mobile/src/forge/adventure/world/WorldSave.java @@ -118,12 +118,11 @@ public class WorldSave { return currentSave; } - public static WorldSave generateNewWorld(String name, boolean male, int race, int avatarIndex, int startingDeckIndex, DifficultyData diff, long seed) { - + public static WorldSave generateNewWorld(String name, boolean male, int race, int avatarIndex, int startingColorIdentity, DifficultyData diff, long seed) { currentSave.world.generateNew(seed); currentSave.pointOfInterestChanges.clear(); - Deck starterDeck = Config.instance().starterDecks()[startingDeckIndex]; - currentSave.player.create(name, starterDeck, male, race, avatarIndex,diff); + Deck starterDeck = Config.instance().starterDecks()[startingColorIdentity]; + currentSave.player.create(name, startingColorIdentity, starterDeck, male, race, avatarIndex,diff); currentSave.player.setWorldPosY((int) (currentSave.world.getData().playerStartPosY * currentSave.world.getData().height * currentSave.world.getTileSize())); currentSave.player.setWorldPosX((int) (currentSave.world.getData().playerStartPosX * currentSave.world.getData().width * currentSave.world.getTileSize())); currentSave.onLoadList.emit(); diff --git a/forge-gui/res/adventure/Shandalar/maps/main.tiled-session b/forge-gui/res/adventure/Shandalar/maps/main.tiled-session index 05bdc7e82df..28b54e498f6 100644 --- a/forge-gui/res/adventure/Shandalar/maps/main.tiled-session +++ b/forge-gui/res/adventure/Shandalar/maps/main.tiled-session @@ -3,12 +3,12 @@ "height": 4300, "width": 2 }, - "activeFile": "map/waste_town.tmx", + "activeFile": "map/debug_map.tmx", "automapping.whileDrawing": false, "expandedProjectPaths": [ + "obj", "tileset", "map/main_story", - "obj", "map" ], "file.lastUsedOpenFilter": "All Files (*)", @@ -1422,11 +1422,11 @@ } }, "map/debug_map.tmx": { - "scale": 8, + "scale": 2, "selectedLayer": 3, "viewCenter": { - "x": 240, - "y": 239.875 + "x": 175.75, + "y": 316 } }, "map/djinnpalace_1.tmx": { @@ -2663,7 +2663,7 @@ "scale": 3, "selectedLayer": 4, "viewCenter": { - "x": 235.33333333333331, + "x": 235.5, "y": 135.66666666666663 } }, @@ -2714,7 +2714,7 @@ "tileset/main.tsx": { "dynamicWrapping": false, "scaleInDock": 1.5, - "scaleInEditor": 0.75 + "scaleInEditor": 1 } }, "map.height": 60, @@ -2726,16 +2726,14 @@ "openFiles": [ "map/debug_map.tmx", "tileset/buildings.tsx", - "tileset/main.tsx", - "map/waste_town.tmx" + "tileset/main.tsx" ], "project": "main.tiled-project", "property.type": "string", "recentFiles": [ - "map/debug_map.tmx", - "tileset/buildings.tsx", "tileset/main.tsx", - "map/waste_town.tmx", + "tileset/buildings.tsx", + "map/debug_map.tmx", "map/main_story/white_castle.tmx", "map/main_story/final_castle.tmx", "map/main_story/black_castle.tmx", @@ -2743,7 +2741,8 @@ "map/main_story/green_castle.tmx", "map/main_story/blue_castle.tmx", "map/main_story/colorless_castle.tmx", - "map/barbariancamp_2.tmx" + "map/barbariancamp_2.tmx", + "map/portal_1G2.tmx" ], "resizeMap.removeObjects": true, "textEdit.monospace": true diff --git a/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx b/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx index bdf8c9d7f65..becd63abe59 100644 --- a/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx +++ b/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx @@ -36,7 +36,14 @@ + { + "lifeModifier": -25, + "opponent":{ + "startBattleWithCard": [ "c_0_1_eldrazi_spawn_sac", "c_0_1_eldrazi_spawn_sac", "c_0_1_eldrazi_spawn_sac", "c_0_1_eldrazi_spawn_sac" ] + } +} + @@ -106,6 +113,13 @@ + [ + { + "text":"Impressive...", + "loctext":"", + "options":[ { "name":"Hey why are you still standing...?" } ] + } +] [ { "effect":[], @@ -120,6 +134,12 @@ "text": "Gladly.", "options": [ { "name": "I FEAR NOTHING!!?", "effect": [ { "battleWithActorID": -1 } ]} ] }, + { + "name": "I want to be eco-friendly too.", + "condition": [ { "colorIdentity": "G", "not": true } ], + "text": "Listen to the forest, friend.\nYour color identity is now green!", + "options": [ { "name": "Awesome.", "effect": [ { "setColorIdentity": "G" } ]} ] + }, { "name":"I wanna fight Emrakul over there!", "condition": [ { "actorID": 50 } ], @@ -133,12 +153,32 @@ "options": [ { "name": "Sorry..." } ] }, { - "name":"That's cool dude.", - "condition": [ { "item": "Treasure", "not": true } ], + "name":"That's cool my green dude.", + "condition": [ { "item": "Treasure", "not": true }, { "colorIdentity": "G" } ], "effect": [ { "addItem": "Treasure" } ], - "text": "You get it. Take this.", + "text": "You get it! Take this.", "options": [ { "name": "Thanks bro." } ] }, + { + "name":"Thanks for the blessing.", + "condition": [ { "hasBlessing": "Debug Elf" } ], + "text": "You are welcome.", + "options": [ { "name": "Thumbs up emoji" } ] + }, + { + "name":"Got any fancy elven blessing?", + "condition": [ { "item": "Treasure" }, { "hasBlessing": "Debug Elf", "not": true } ], + "text": "If you give me a Treasure, I will give you the blessing of the Debug Elf.\nWhich is a Llanowar Elves and 2 extra life in your next battle. Sounds good?", + "options": [ + { "name": "But I love my Treasure! I humbly refuse."}, + { + "name": "I'll take it", + "effect": [ + { "removeItem": "Treasure", "giveBlessing": { "name": "Debug Elf" ,"lifeModifier": 2, "startBattleWithCard": [ "Llanowar Elves" ] } } + ] + } + ] + }, { "name":"Can you open that hidden wall?", "condition": [ { "actorID": 83 } ], @@ -148,8 +188,12 @@ ] } ] - - + { + "lifeModifier": 190, + "startBattleWithCard": [ "Llanowar Elves", "Llanowar Elves", "Forest", "Forest" ] +} + + diff --git a/forge-gui/res/adventure/Shandalar/skin/ui_skin.atlas b/forge-gui/res/adventure/Shandalar/skin/ui_skin.atlas index 1eca92c5dcb..c0e7b918780 100644 --- a/forge-gui/res/adventure/Shandalar/skin/ui_skin.atlas +++ b/forge-gui/res/adventure/Shandalar/skin/ui_skin.atlas @@ -321,3 +321,12 @@ touchKnob orig: 72, 72 offset: 0, 0 index: -1 +dummy + rotate: false + xy: 0, 360 + size: 5,5 + orig: 1,1 + split: 1, 1, 1, 1 + pad: 0, 0, 0, 0 + offset: 0,0 + index:-1 diff --git a/forge-gui/res/adventure/Shandalar/skin/ui_skin.json b/forge-gui/res/adventure/Shandalar/skin/ui_skin.json index d909ab8bef0..3b681e94305 100644 --- a/forge-gui/res/adventure/Shandalar/skin/ui_skin.json +++ b/forge-gui/res/adventure/Shandalar/skin/ui_skin.json @@ -249,6 +249,25 @@ "frameDuration": 0.03, "regions": [], "playMode": 2 + }, + "dummy": { + "region": "dummy", + "horizontalStretchAreas": [ 1, 1 ], + "verticalStretchAreas": [ 1, 1 ], + "tiling": true, + "minWidth": 5, + "minHeight": 5, + "rightWidth": 0, + "leftWidth": 0, + "bottomHeight": 0, + "topHeight": 0, + "offsetX": 0, + "offsetY": 0, + "offsetXspeed": 0, + "offsetYspeed": 0, + "frameDuration": 0.03, + "regions": [], + "playMode": 2 } }, "com.badlogic.gdx.scenes.scene2d.ui.Button$ButtonStyle": { @@ -316,6 +335,9 @@ "whiteBig": { "font": "default" } + "nobg": { + "font": "black" + } }, "com.badlogic.gdx.scenes.scene2d.ui.List$ListStyle": { "default": { @@ -345,6 +367,9 @@ }, "gold": { "background": "9patch4" + }, + "nobg": { + "background": "dummy", } }, "com.badlogic.gdx.scenes.scene2d.ui.SelectBox$SelectBoxStyle": { diff --git a/forge-gui/res/adventure/Shandalar/ui/avatarhud.png b/forge-gui/res/adventure/Shandalar/ui/avatarhud.png index ac39721de692a05b8a35e8fde113f300c68956d9..37cf557fc9ace895c4397831c1f1449a2768c93a 100644 GIT binary patch delta 1574 zcmV+>2HE-U0pbjhBYy+wdQ@0+Qek%>aB^>EX>4U6ba`-PAZ2)IW&i+q+O3sYcH=k< zMgOsiUIGCS9G1iJoZdk#zaAyUPP-gia+jD0GQ|PFeS~QI`ghVlxWvUo-eL+l1c%FK zpQYd-x%)K^yZ5p4+x_d}%ELwX{Yv-$IeVIO?9mk;kcO}awQoUR%V1zdmUNpI&?5c~&v9!RExF7sN|vThS^a7}C2H2LNky9sRrRED^M$v4 z^R{2(gq=HMsDCgPV@!G3=-q%bZO-P9BW6U;N3P(P$l|~&jk@j_1|U2SZnh=(tKBa8 z23A4PwlpUMSX|wgsK$3~=_UZhID_5w#j!7HvZ=&lZ-X z3Iz>5SO_78b>>Rc=%d9DV@xr}k~H~bDWsTE%Bf_@iX&+`=xfJYKJQXXLT`;1Q zDpjkmRzr<7)m%%1e4208LW?c6+)9_O-FNGu$DVrbW$=KMX!v0xj5yNBqfBUR>h#lQ zm~p0=XMed-JE;EAE>Poxnrx)jxOk(6-Wbp=EM_jT_p-<> zW-bd(g$bOr#ip|>!~qEXV6n+Jc6V~8xe;>xj+>kzM+@CwASX2Rf!h;meO1D?5!+AU z%BfSFzLLE$%6?$VI2qPPXVcbDoe_70OU4&}(SN5CAAixu%OE0iZgm>Mi3F<*jxF*nV)`NEKkbvq;cpBT6%vL@Kyk_8U{=mE+gROE z(PA}S*+Wk4E9CbPKSWO7Lch!O1C`PXR+m&tZ$dwsT!!>s*<3eN%a(2|~cg5>fwWG^3ewaWfXWTyqvuFAZ0VnI~IQL9jd3ZYhL)xqS_ zFKE(`q_{W=t_24_7OM^}&bm6d3WDGVh@+E}qKlOHzogJ2)`R1Iyu0_fdj|;hGSjTU zIH2janM%aPOm*;id5g1FuCnGm`3pliePx;JG>4GDB9Gn4P0EeG-VIC+yMrj4B3=j$xl{m(FffCa|5d;cn3Eml_4MmXT^{i_Vy*34t1rvthtumAt((LDwxh5-hn z4j6U7r~^hFFzSF&2aGyk)B&Ro7Hrp4N3nbIdb;+KA3eH<+B=2`&>H{% YJ-`?>`ZtaZRR91007*qoM6N<$g4?A3Qvd(} delta 169 zcmV;a09OCv4DJDtBa^5FE`Q|+1{Vz`;f#980001cNkl(4``EHz-2E+0Ia9)SW@EFnq0Dyg4-IwNE zDpUm}PhG=vsZCWdz_!mqcK100000NkvXXu0mjfS4=|0 diff --git a/forge-gui/res/adventure/Shandalar/ui/colorC.png b/forge-gui/res/adventure/Shandalar/ui/colorC.png new file mode 100644 index 0000000000000000000000000000000000000000..3122325b2f049390fb31ec19f1e4ae8cb2741143 GIT binary patch literal 981 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+0817l%;Plzi}!N-puLqbC4 z%$XAx7YAh2)YRzd>3MrNh6Q*^N=hb#1ytr`)fMHpS6BD9c0>jQcei%>x%+gq_1IWB zPMbQnwWHt1KWyUU+5J;yH+4@;%qlFZZt0jbv%YIWW@&X|epyXte`Q;DNn@L~sa14V zL1KPsW8ajTuKwQM-nI$Tn)|2L_fGor=TBHzSafuBa9nzJMO|)n10Nq>NlD4f73;EV zTB0&b3hJ6?tynjE`ML!wH!fVduC=9aLhFR)iPIV$YuN zwPEeTB{RBv3KQZxr_5@dG^1(4)aFUk`sOc9F00L`YASE(t8VFS@0c`w((DOsy({M} zSTbYAqG^*CPMC(#DS1oTA>ji>57G9aC6YS5VkhUD@AM-`7+#v8!qE zf*CWW_ct_F)YO%Qg!|_g)r3T+_Rd+DQPtel)l^+ml9(J-R*~P@UZ0c_ThZQ^m6H+` z8yXc8{Qv*|Njvw0B8s&n$S)X3GcX*=X4?p)7?Zr+U8*duwq^l2>?NMQuI$fPgoLGJ z&j~#^0F*ZLba4!^IGvmz;nEbxw|fo{_AsEV^+aS0f@9ayHGB z?B*)v4fFN&-N2P5md0beWlL#e~*^J$&-SEE?+V>+PrBYljTkaC4G6_H(XrZUEW@T ze~fZgF4(hZQX??IyHzOfk2c}#1cs+-iEBhjN@7W>RdP`(kYX@0Ff!6LFwr%%2r;y@ zGBUF=veY&(ure@M?lMgaMMG|WN@iLmZVlHY^`-$e2!m|MNlZ%3Vem<;Of6DK&M&A` WP`3Pa=}HVxn!(f6&t;ucLK6Uu1%-70 literal 0 HcmV?d00001 diff --git a/forge-gui/res/adventure/Shandalar/ui/color_frames.png b/forge-gui/res/adventure/Shandalar/ui/color_frames.png new file mode 100644 index 0000000000000000000000000000000000000000..636a66ed7c11be6f00c8d04a8ff61c1774198f9b GIT binary patch literal 25339 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 Date: Tue, 19 Apr 2022 23:46:11 +0200 Subject: [PATCH 2/9] Big map update 10 * Dispose of color frames texture. --- .../src/forge/adventure/scene/PlayerStatisticScene.java | 1 + 1 file changed, 1 insertion(+) diff --git a/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java b/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java index ecf71b3cecd..e6611c6e276 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java @@ -46,6 +46,7 @@ public class PlayerStatisticScene extends UIScene { @Override public void dispose() { + colorFrames.dispose(); //Get rid of the cached color ID texture. } From c058a7c863c00179ca5000d8806bc88c508ecb9a Mon Sep 17 00:00:00 2001 From: Magpie Date: Wed, 20 Apr 2022 11:07:23 +0200 Subject: [PATCH 3/9] Big map update 11 * Added a dummy texture in Graphics. Useful to add raw pixels or solid color boxes to a drawing batch. * Dialogue actions added: Heal (negative too) player, Add gold. * Dialogue conditions added: Check for gold >= X, check for health >= X. * Added "Manasight" effect to equipment and blessings. Allows to see the colors used by enemies. * All existing enemies have their color identities assigned. * Console command to dump all deck colors used by enemies (to update the data for color view) * Console command to force reload of status scenes (for faster design) * Less delay when clicking "Done" in a reward scene. * Adjustments to (landscape) Status and Inventory scenes. * Blessings properly assign map effects (speed, manasight) * Added "Manasight Amulet" (sprite pending) to grant the user manasight. * Added "Scroll" pickup template. It's meant to grant single cards. --- forge-gui-mobile/src/forge/Graphics.java | 17 +- .../adventure/character/EnemySprite.java | 56 +++- .../adventure/character/PlayerSprite.java | 5 +- .../src/forge/adventure/data/DialogData.java | 4 + .../src/forge/adventure/data/EffectData.java | 2 + .../src/forge/adventure/data/EnemyData.java | 40 +-- .../src/forge/adventure/data/WorldData.java | 11 +- .../adventure/player/AdventurePlayer.java | 69 +++-- .../forge/adventure/scene/InventoryScene.java | 155 ++++++----- .../adventure/scene/PlayerStatisticScene.java | 1 + .../forge/adventure/scene/RewardScene.java | 2 +- .../stage/ConsoleCommandInterpreter.java | 31 +++ .../src/forge/adventure/stage/MapStage.java | 27 +- .../src/forge/adventure/util/MapDialog.java | 21 +- .../Shandalar/maps/map/debug_map.tmx | 71 ++++- .../adventure/Shandalar/maps/obj/scroll.tx | 10 + .../Shandalar/maps/tileset/buildings.png | Bin 232982 -> 232587 bytes .../Shandalar/maps/tileset/buildings.xcf | Bin 763811 -> 764619 bytes .../adventure/Shandalar/sprites/1life.atlas | 2 +- .../adventure/Shandalar/sprites/2life.atlas | 2 +- .../adventure/Shandalar/sprites/3life.atlas | 2 +- .../adventure/Shandalar/sprites/booster.atlas | 2 +- .../adventure/Shandalar/sprites/gold.atlas | 2 +- .../adventure/Shandalar/sprites/scroll.atlas | 17 ++ .../adventure/Shandalar/sprites/treasure.png | Bin 16971 -> 13675 bytes .../res/adventure/Shandalar/ui/inventory.json | 61 +++-- .../res/adventure/Shandalar/ui/statistic.json | 52 ++-- .../adventure/Shandalar/world/enemies.json | 256 +++++++++--------- .../res/adventure/Shandalar/world/items.json | 8 + 29 files changed, 585 insertions(+), 341 deletions(-) create mode 100644 forge-gui/res/adventure/Shandalar/maps/obj/scroll.tx create mode 100644 forge-gui/res/adventure/Shandalar/sprites/scroll.atlas diff --git a/forge-gui-mobile/src/forge/Graphics.java b/forge-gui-mobile/src/forge/Graphics.java index ee4b008766b..0183fc15070 100644 --- a/forge-gui-mobile/src/forge/Graphics.java +++ b/forge-gui-mobile/src/forge/Graphics.java @@ -4,9 +4,7 @@ import java.util.ArrayDeque; import java.util.Deque; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.*; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.glutils.ShaderProgram; @@ -44,6 +42,8 @@ public class Graphics { private final ShaderProgram shaderWarp = new ShaderProgram(Gdx.files.internal("shaders").child("grayscale.vert"), Gdx.files.internal("shaders").child("warp.frag")); private final ShaderProgram shaderUnderwater = new ShaderProgram(Gdx.files.internal("shaders").child("grayscale.vert"), Gdx.files.internal("shaders").child("underwater.frag")); + private Texture dummyTexture = null; + public Graphics() { ShaderProgram.pedantic = false; } @@ -87,6 +87,7 @@ public class Graphics { shaderGrayscale.dispose(); shaderUnderwater.dispose(); shaderWarp.dispose(); + if(dummyTexture != null) dummyTexture.dispose(); } public SpriteBatch getBatch() { @@ -1124,4 +1125,14 @@ public class Graphics { int brightness = ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000; return brightness > 155 ? Color.valueOf("#171717") : Color.valueOf("#fffffd"); } + + public Texture getDummyTexture(){ + if (dummyTexture == null){ + Pixmap P = new Pixmap(1, 1, Pixmap.Format.RGBA8888); + P.setColor(1f,1f,1f,1f); + P.drawPixel(0, 0); + dummyTexture = new Texture(P); + } + return dummyTexture; + } } diff --git a/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java b/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java index 40fb555258f..a4d65058e0e 100644 --- a/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java +++ b/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java @@ -1,9 +1,12 @@ package forge.adventure.character; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.utils.Array; +import forge.Forge; import forge.adventure.data.EffectData; import forge.adventure.data.EnemyData; import forge.adventure.data.RewardData; @@ -47,7 +50,6 @@ public class EnemySprite extends CharacterSprite { return data; } - public Array getRewards() { Array ret=new Array(); if(data.rewards == null) @@ -58,5 +60,57 @@ public class EnemySprite extends CharacterSprite { return ret; } + private void drawColorHints(Batch batch){ + int size = Math.min(data.colors.length(), 6); + int DX = Math.round(getX() - 2); + int DY = Math.round(getY()); + + for(int i = 0; i < size; i++){ + char C = data.colors.toUpperCase().charAt(i); + switch (C) { + default: break; + case 'C': { + batch.setColor(Color.DARK_GRAY); + batch.draw(Forge.getGraphics().getDummyTexture(), DX, DY, 2, 2); + DY += 2; break; + } + case 'B': { + batch.setColor(Color.PURPLE); + batch.draw(Forge.getGraphics().getDummyTexture(), DX, DY, 2, 2); + DY += 2; break; + } + case 'G': { + batch.setColor(Color.GREEN); + batch.draw(Forge.getGraphics().getDummyTexture(), DX, DY, 2, 2); + DY += 2; break; + } + case 'R': { + batch.setColor(Color.RED); + batch.draw(Forge.getGraphics().getDummyTexture(), DX, DY, 2, 2); + DY += 2; break; + } + case 'U': { + batch.setColor(Color.BLUE); + batch.draw(Forge.getGraphics().getDummyTexture(), DX, DY, 2, 2); + DY += 2; break; + } + case 'W': { + batch.setColor(Color.WHITE); + batch.draw(Forge.getGraphics().getDummyTexture(), DX, DY, 2, 2); + DY += 2; break; + } + } + } + batch.setColor(Color.WHITE); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + super.draw(batch, parentAlpha); + if(Current.player().hasColorView() && !data.colors.isEmpty()) { + drawColorHints(batch); + } + } + } diff --git a/forge-gui-mobile/src/forge/adventure/character/PlayerSprite.java b/forge-gui-mobile/src/forge/adventure/character/PlayerSprite.java index 7431fbaf1f4..eac20f7d387 100644 --- a/forge-gui-mobile/src/forge/adventure/character/PlayerSprite.java +++ b/forge-gui-mobile/src/forge/adventure/character/PlayerSprite.java @@ -25,8 +25,9 @@ public class PlayerSprite extends CharacterSprite { PlayerSprite.this.updatePlayer(); } }); - playerSpeed=Config.instance().getConfigData().playerBaseSpeed; - Current.player().onEquipmentChanged(() -> playerSpeedEquipmentModifier=Current.player().equipmentSpeed()); + playerSpeed = Config.instance().getConfigData().playerBaseSpeed; + Current.player().onBlessing( () -> playerSpeedEquipmentModifier = Current.player().equipmentSpeed() ); + Current.player().onEquipmentChanged( () -> playerSpeedEquipmentModifier=Current.player().equipmentSpeed() ); } private void updatePlayer() { diff --git a/forge-gui-mobile/src/forge/adventure/data/DialogData.java b/forge-gui-mobile/src/forge/adventure/data/DialogData.java index 27aa1d982e3..3a9de3564f1 100644 --- a/forge-gui-mobile/src/forge/adventure/data/DialogData.java +++ b/forge-gui-mobile/src/forge/adventure/data/DialogData.java @@ -16,6 +16,8 @@ public class DialogData { static public class ActionData { public String removeItem; //Remove item name from inventory. public String addItem; //Add item name to inventory. + public int addLife = 0; //Gives the player X health. Negative to take. + public int addGold = 0; //Gives the player X gold. Negative to take. public int deleteMapObject = 0; //Remove ID from the map. -1 for self. public int battleWithActorID = 0; //Start a battle with enemy ID. -1 for self if possible. public EffectData giveBlessing; //Give a blessing to the player. @@ -27,6 +29,8 @@ public class DialogData { public int flag = 0; //Check for a local dungeon flag. public int actorID = 0; //Check for an actor ID. public String hasBlessing = null; //Check for specific blessing, if named. + public int hasGold = 0; //Check for player gold. True if gold is equal or higher than X. + public int hasLife = 0; //Check for player life. True if life is equal or higher than X. public String colorIdentity = null;//Check for player's current color identity. public boolean not = false; //Reverse the result of a condition ("actorID":"XX" + "not":true => true if XX is not in the map.) } diff --git a/forge-gui-mobile/src/forge/adventure/data/EffectData.java b/forge-gui-mobile/src/forge/adventure/data/EffectData.java index 4b313b95efb..da8b0d99c78 100644 --- a/forge-gui-mobile/src/forge/adventure/data/EffectData.java +++ b/forge-gui-mobile/src/forge/adventure/data/EffectData.java @@ -51,6 +51,8 @@ public class EffectData implements Serializable { String description = ""; if(this.name != null && !this.name.isEmpty()) description += this.name + "\n"; + if(this.colorView) + description += "Manasight.\n"; if(this.lifeModifier != 0) description += "Life: " + ((this.lifeModifier > 0) ? "+" : "") + this.lifeModifier + "\n"; if(this.startBattleWithCard != null && this.startBattleWithCard.length != 0) diff --git a/forge-gui-mobile/src/forge/adventure/data/EnemyData.java b/forge-gui-mobile/src/forge/adventure/data/EnemyData.java index 846d288aaa0..c78e63ce026 100644 --- a/forge-gui-mobile/src/forge/adventure/data/EnemyData.java +++ b/forge-gui-mobile/src/forge/adventure/data/EnemyData.java @@ -1,7 +1,11 @@ package forge.adventure.data; import forge.adventure.util.CardUtil; +import forge.card.ColorSet; import forge.deck.Deck; +import forge.deck.DeckProxy; +import forge.game.GameType; +import forge.model.FModel; /** * Data class that will be used to read Json configuration files @@ -19,29 +23,25 @@ public class EnemyData { public int life; public RewardData[] rewards; public String[] equipment; + public String colors = ""; - public EnemyData() - { - - } + public EnemyData() { } public EnemyData(EnemyData enemyData) { - name =enemyData.name; - sprite =enemyData.sprite; - deck =enemyData.deck; - ai =enemyData.ai; - spawnRate =enemyData.spawnRate; - difficulty =enemyData.difficulty ; - speed =enemyData.speed; - life =enemyData.life; - equipment =enemyData.equipment; - if(enemyData.rewards==null) - { + name = enemyData.name; + sprite = enemyData.sprite; + deck = enemyData.deck; + ai = enemyData.ai; + spawnRate = enemyData.spawnRate; + difficulty = enemyData.difficulty; + speed = enemyData.speed; + life = enemyData.life; + equipment = enemyData.equipment; + colors = enemyData.colors; + if(enemyData.rewards == null) { rewards=null; - } - else - { - rewards =new RewardData[enemyData.rewards.length]; - for(int i=0;i(getAllEnemies())) - { + for(EnemyData data: new Array.ArrayIterator<>(getAllEnemies())) { if(data.name.equals(enemy)) return data; } diff --git a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java index eee7f13c514..eb83097dc10 100644 --- a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java +++ b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java @@ -48,11 +48,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent { private final Array inventoryItems=new Array<>(); private final HashMap equippedItems=new HashMap<>(); - public AdventurePlayer() - { - - for(int i=0;i 0.0) { //Avoid negative speeds. It would be silly. + if(data != 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) + factor *= blessing.moveSpeed; } return factor; } diff --git a/forge-gui-mobile/src/forge/adventure/scene/InventoryScene.java b/forge-gui-mobile/src/forge/adventure/scene/InventoryScene.java index 65aea1de226..dea63ec1147 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/InventoryScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/InventoryScene.java @@ -63,91 +63,92 @@ public class InventoryScene extends UIScene { @Override public void resLoaded() { super.resLoaded(); - equipOverlay = new Texture(Config.instance().getFile(Paths.ITEMS_EQUIP)); - ui.onButtonPress("return", () -> done()); - leave = ui.findActor("return"); - ui.onButtonPress("delete", () -> confirm.show(stage)); - ui.onButtonPress("equip", () -> equip()); - equipButton = ui.findActor("equip"); - deleteButton = ui.findActor("delete"); - itemDescription = ui.findActor("item_description"); - leave.getLabel().setText(Forge.getLocalizer().getMessage("lblBack")); + equipOverlay = new Texture(Config.instance().getFile(Paths.ITEMS_EQUIP)); + ui.onButtonPress("return", () -> done()); + leave = ui.findActor("return"); + ui.onButtonPress("delete", () -> confirm.show(stage)); + ui.onButtonPress("equip", () -> equip()); + equipButton = ui.findActor("equip"); + deleteButton = ui.findActor("delete"); + itemDescription = ui.findActor("item_description"); + itemDescription.setAlignment(Align.topLeft); + leave.getLabel().setText(Forge.getLocalizer().getMessage("lblBack")); - inventoryButtons=new Array<>(); - equipmentSlots=new HashMap<>(); + inventoryButtons=new Array<>(); + equipmentSlots=new HashMap<>(); - Array children = ui.getChildren(); - for (int i = 0, n = children.size; i < n; i++) + Array children = ui.getChildren(); + for (int i = 0, n = children.size; i < n; i++) + { + + if(children.get(i).getName()!=null&&children.get(i).getName().startsWith("Equipment")) { - - if(children.get(i).getName()!=null&&children.get(i).getName().startsWith("Equipment")) - { - String slotName=children.get(i).getName().split("_")[1]; - equipmentSlots.put(slotName, (Button) children.get(i)); - Actor slot=children.get(i); - slot.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - Button button=((Button) actor); - if(button.isChecked()) + String slotName=children.get(i).getName().split("_")[1]; + equipmentSlots.put(slotName, (Button) children.get(i)); + Actor slot=children.get(i); + slot.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + Button button=((Button) actor); + if(button.isChecked()) + { + for(Button otherButton:equipmentSlots.values()) { - for(Button otherButton:equipmentSlots.values()) - { - if(button!=otherButton&&otherButton.isChecked()){ - otherButton.setChecked(false); - } - } - String item=Current.player().itemInSlot(slotName); - if(item!=null&&item!="") - { - Button changeButton=null; - for(Button invButton:inventoryButtons) - { - if(itemLocation.get(invButton)!=null&&itemLocation.get(invButton).equals(item)) - { - changeButton=invButton; - break; - } - } - if(changeButton!=null) - changeButton.setChecked(true); - } - else - { - setSelected(null); + if(button!=otherButton&&otherButton.isChecked()){ + otherButton.setChecked(false); } } - + String item=Current.player().itemInSlot(slotName); + if(item!=null&&item!="") + { + Button changeButton=null; + for(Button invButton:inventoryButtons) + { + if(itemLocation.get(invButton)!=null&&itemLocation.get(invButton).equals(item)) + { + changeButton=invButton; + break; + } + } + if(changeButton!=null) + changeButton.setChecked(true); + } + else + { + setSelected(null); + } } - }); - } + + } + }); } - inventory = new Table(Controls.GetSkin()); - ScrollPane scrollPane = ui.findActor("inventory"); - scrollPane.setScrollingDisabled(true,false); - scrollPane.setActor(inventory); - columns= (int) (scrollPane.getWidth()/createInventorySlot().getWidth()); - columns-=1; - if(columns<=0)columns=1; - scrollPane.setActor(inventory); - confirm = new Dialog("\n "+Forge.getLocalizer().getMessage("lblDelete"), Controls.GetSkin()) + } + inventory = new Table(Controls.GetSkin()); + ScrollPane scrollPane = ui.findActor("inventory"); + scrollPane.setScrollingDisabled(true,false); + scrollPane.setActor(inventory); + columns= (int) (scrollPane.getWidth()/createInventorySlot().getWidth()); + columns-=1; + if(columns<=0)columns=1; + scrollPane.setActor(inventory); + confirm = new Dialog("\n "+Forge.getLocalizer().getMessage("lblDelete"), Controls.GetSkin()) + { + protected void result(Object object) { - protected void result(Object object) - { - if(object!=null&&object.equals(true)) - delete(); - confirm.hide(); - }; + if(object!=null&&object.equals(true)) + delete(); + confirm.hide(); }; + }; - confirm.button(Forge.getLocalizer().getMessage("lblYes"), true); - confirm.button(Forge.getLocalizer().getMessage("lblNo"), false); - ui.addActor(confirm); - confirm.hide(); + confirm.button(Forge.getLocalizer().getMessage("lblYes"), true); + confirm.button(Forge.getLocalizer().getMessage("lblNo"), false); + ui.addActor(confirm); + confirm.hide(); - itemDescription.setWrap(true); - //makes confirm dialog hidden immediately when you open inventory first time.. - confirm.getColor().a = 0; + itemDescription.setWrap(true); + //makes confirm dialog hidden immediately when you open inventory first time.. + confirm.getColor().a = 0; } private void setSelected(Button actor) { @@ -198,17 +199,15 @@ public class InventoryScene extends UIScene { } - private void updateInventory() - { + private void updateInventory() { inventoryButtons.clear(); inventory.clear(); - for(int i=0;i { + SceneType.InventoryScene.instance.resLoaded(); + SceneType.PlayerStatisticScene.instance.resLoaded(); + + return "Force reload status scenes. Might be unstable."; + }); + registerCommand(new String[]{"dumpEnemyDeckColors"}, s -> { + for(EnemyData E : new Array.ArrayIterator<>(WorldData.getAllEnemies())){ + Deck D = E.generateDeck(); + DeckProxy DP = new DeckProxy(D, "Constructed", GameType.Constructed, null); + ColorSet colorSet = DP.getColor(); + System.out.printf("%s: Colors: %s (%s%s%s%s%s%s)\n", D.getName(), DP.getColor(), + (colorSet.hasBlack() ? "B" : ""), + (colorSet.hasGreen() ? "G" : ""), + (colorSet.hasRed() ? "R" : ""), + (colorSet.hasBlue() ? "U" : ""), + (colorSet.hasWhite() ? "W" : ""), + (colorSet.isColorless() ? "C" : "") + ); + } + return "Enemy deck color list dumped to stdout."; + }); registerCommand(new String[]{"heal", "amount"}, s -> { if(s.length<1) return "Command needs 1 parameter"; int N = 0; diff --git a/forge-gui-mobile/src/forge/adventure/stage/MapStage.java b/forge-gui-mobile/src/forge/adventure/stage/MapStage.java index 770245fe57c..8766a73ddd7 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/MapStage.java +++ b/forge-gui-mobile/src/forge/adventure/stage/MapStage.java @@ -206,8 +206,8 @@ public class MapStage extends GameStage { for (MapActor actor : new Array.ArrayIterator<>(actors)) { actor.remove(); foregroundSprites.removeActor(actor); - } + actors = new Array<>(); width = Float.parseFloat(map.getProperties().get("width").toString()); height = Float.parseFloat(map.getProperties().get("height").toString()); @@ -220,8 +220,8 @@ public class MapStage extends GameStage { MapProperties MP = map.getProperties(); if( MP.get("dungeonEffect") != null && !MP.get("dungeonEffect").toString().isEmpty()){ - JSONStringLoader json = new JSONStringLoader(); - effect = json.parse(EffectData.class, map.getProperties().get("dungeonEffect").toString(), ""); + JSONStringLoader J = new JSONStringLoader(); + effect = J.parse(EffectData.class, map.getProperties().get("dungeonEffect").toString(), ""); effectDialog(effect); } if (MP.get("preventEscape") != null) preventEscape = (boolean)MP.get("preventEscape"); @@ -266,7 +266,6 @@ public class MapStage extends GameStage { private void loadObjects(MapLayer layer, String sourceMap) { player.setMoveModifier(2); for (MapObject obj : layer.getObjects()) { - MapProperties prop = obj.getProperties(); Object typeObject = prop.get("type"); if (typeObject != null) { @@ -297,7 +296,12 @@ public class MapStage extends GameStage { case "enemy": Object E = prop.get("enemy"); if(E != null && !E.toString().isEmpty()) { - EnemySprite mob = new EnemySprite(id, WorldData.getEnemy(E.toString())); + EnemyData EN = WorldData.getEnemy(E.toString()); + if(EN == null){ + System.err.printf("Enemy \"%s\" not found.", E.toString()); + break; + } + EnemySprite mob = new EnemySprite(id, EN); Object D = prop.get("dialog"); //Check if the enemy has a dialogue attached to it. if (D != null && !D.toString().isEmpty()) { mob.dialog = new MapDialog(D.toString(), this, mob.getId()); @@ -314,6 +318,7 @@ public class MapStage extends GameStage { if (D != null && !D.toString().isEmpty()) { mob.effect = JSONStringLoader.parse(EffectData.class, D.toString(), ""); } + //TODO: Additional rewards. addMapActor(obj, mob); } break; @@ -321,6 +326,8 @@ public class MapStage extends GameStage { TiledMapTileMapObject obj2 = (TiledMapTileMapObject) obj; DummySprite D = new DummySprite(id, obj2.getTextureRegion(), this); addMapActor(obj, D); + //TODO: Ability to toggle their solid state. + //TODO: Ability to move them (using a sequence such as "UULU" for up, up, left, up). break; case "inn": addMapActor(obj, new OnCollide(new Runnable() { @@ -436,7 +443,8 @@ public class MapStage extends GameStage { return false; } - public boolean lookForID(int id){ + public boolean lookForID(int id){ //Search actor by ID. + for(MapActor A : new Array.ArrayIterator<>(actors)){ if(A.getId() == id) return true; @@ -444,7 +452,7 @@ public class MapStage extends GameStage { return false; } - public EnemySprite getEnemyByID(int id) { + public EnemySprite getEnemyByID(int id) { //Search actor by ID, enemies only. for(MapActor A : new Array.ArrayIterator<>(actors)){ if(A instanceof EnemySprite && A.getId() == id) return ((EnemySprite) A); @@ -492,7 +500,7 @@ public class MapStage extends GameStage { currentMob = mob; if (mob.dialog != null){ //This enemy has something to say. Display a dialog like if it was a DialogActor. resetPosition(); - showDialog(); + //showDialog(); mob.dialog.activate(); } else { //Duel the enemy. beginDuel(mob); @@ -534,7 +542,7 @@ public class MapStage extends GameStage { } }, ScreenUtils.getFrameBufferTexture(), true, false)); } - startPause(0.4f, new Runnable() { + startPause(0.3f, new Runnable() { @Override public void run() { DuelScene S = ((DuelScene) SceneType.DuelScene.instance); @@ -568,7 +576,6 @@ public class MapStage extends GameStage { } public void resetPosition() { - player.setPosition(oldPosition4); stop(); } diff --git a/forge-gui-mobile/src/forge/adventure/util/MapDialog.java b/forge-gui-mobile/src/forge/adventure/util/MapDialog.java index b5e62212b86..55cf33466fd 100644 --- a/forge-gui-mobile/src/forge/adventure/util/MapDialog.java +++ b/forge-gui-mobile/src/forge/adventure/util/MapDialog.java @@ -40,7 +40,6 @@ public class MapDialog { return; } this.data = JSONStringLoader.parse(Array.class, DialogData.class, S, defaultJSON); - } private void loadDialog(DialogData dialog) { //Displays a dialog with dialogue and possible choices. @@ -91,6 +90,13 @@ public class MapDialog { if (E.addItem != null){ //Gives an item to the player. Current.player().addItem(E.addItem); } + if(E.addLife != 0){ //Gives (positive or negative) life to the player. Cannot go over max health. + Current.player().heal(E.addLife); + } + if(E.addGold != 0){ //Gives (positive or negative) gold to the player. + if(E.addGold > 0) Current.player().giveGold(E.addGold); + else Current.player().takeGold(-E.addGold); + } if (E.deleteMapObject != 0){ //Removes a dummy object from the map. if(E.deleteMapObject < 0) stage.deleteObject(parentID); else stage.deleteObject(E.deleteMapObject); @@ -106,6 +112,9 @@ public class MapDialog { Current.player().setColorIdentity(E.setColorIdentity); } //Create map object. + //Toggle dummy object's hitbox. (Like to make a door passable) + //Set world flag. + //Set dungeon flag. } } @@ -123,6 +132,16 @@ public class MapDialog { if(!condition.not) return false; } else if(condition.not) return false; } + if(condition.hasGold != 0){ //Check for at least X gold. + if(player.getGold() < condition.hasGold){ + if(!condition.not) return false; + } else if(condition.not) return false; + } + if(condition.hasLife != 0){ //Check for at least X life.. + if(player.getLife() < condition.hasLife + 1){ + if(!condition.not) return false; + } else if(condition.not) return false; + } if(condition.hasBlessing != null && !condition.hasBlessing.isEmpty()){ //Check for a named blessing. if(!player.hasBlessing(condition.hasBlessing)){ if(!condition.not) return false; diff --git a/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx b/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx index becd63abe59..8f45f3f34a9 100644 --- a/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx +++ b/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx @@ -1,5 +1,5 @@ - + @@ -32,8 +32,7 @@ - - + { @@ -77,12 +76,11 @@ - + - [ @@ -207,5 +205,68 @@ + + + [ + { + "effect":[], + "text":"I have some things to offer for that life you have...", + "condition":[], + "options":[ + { "name":"You are suspicious and have two shadows, I'm out." }, + { + "name":"I'll vanquish you, demon!", + "text": "Oh look we got a tough guy over here!", + "options": [ { "name": "I FEAR NOTHING!!", "effect": [ { "battleWithActorID": -1 } ]} ] + }, + { + "name": "I dig your edge.", + "condition": [ { "colorIdentity": "B", "not": true }, { "hasLife": 2 } ], + "text": "You can be dark and edgy like me. Maybe for some of your life force...", + "options": [ { "name": "I'm doing nothing better with it.", "effect": [ { "setColorIdentity": "B", "addLife": -2 } ]} ] + }, + { + "name": "I dig your edge.", + "condition": [ { "colorIdentity": "B", "not": true }, { "hasLife": 2, "not": true } ], + "text": "You don't have enough life force...come back with more to offer.", + "options": [ { "name": "Aw man..." } ] + }, + { + "name": "Any cool demon deals?", + "condition": [ { "colorIdentity": "B" }, { "hasGold": 200 } ], + "text": "I can offer you this Treasure for the fair price of 200 gold.", + "options": [ + { "name": "This gem has a lot of edge, just like me. Deal!" , "effect": [ { "addGold": -20000, "addItem": "Treasure" } ] }, + { "name": "I'll think about it." } + ] + }, + { + "name":"Got any fancy demon blessing?", + "condition": [ {"colorIdentity": "B"}, { "item": "Treasure" }, { "hasBlessing": "Debug Demon", "not": true } ], + "text": "Give me that Treasure of yours...\n(+1 health, Manasight, move speed 120%, Lord of the Pit starts in play)", + "options": [ + { "name": "That's shady."}, + { + "name": "What can possibly go wrong?", + "effect": [ + { "removeItem": "Treasure", "giveBlessing": { "name": "Debug Demon" , "lifeModifier": 1, "colorView": true, "moveSpeed": 2, "startBattleWithCard": [ "Lord of the Pit" ] } } + ] + } + ] + } + ] + } +] + + + + + + + [ + { "cardName": "Black Lotus", "type":"card", "count":1 } +] + + diff --git a/forge-gui/res/adventure/Shandalar/maps/obj/scroll.tx b/forge-gui/res/adventure/Shandalar/maps/obj/scroll.tx new file mode 100644 index 00000000000..8b317692960 --- /dev/null +++ b/forge-gui/res/adventure/Shandalar/maps/obj/scroll.tx @@ -0,0 +1,10 @@ + + diff --git a/forge-gui/res/adventure/Shandalar/maps/tileset/buildings.png b/forge-gui/res/adventure/Shandalar/maps/tileset/buildings.png index d069b1447526a3a74f55e41442d3a94a2391db11..c590e2df4e9c4830a1e6cf0d1a042c6dde9b0436 100644 GIT binary patch delta 49462 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 diff --git a/forge-gui/res/adventure/Shandalar/maps/tileset/buildings.xcf b/forge-gui/res/adventure/Shandalar/maps/tileset/buildings.xcf index 1cb8d25369694697274d4dcafaa7475521008e76..a2f068736f6640cfa5509fc0d3fac2906bdc394e 100644 GIT binary patch delta 1612 zcmZvbU1$_n6vywqGjr$8Y+~19RAL^|maRUh4?-w4K7^`>;8$rVq?J}ByEt&}@1FlX zch7(C-1+g^+`$`jcYnY~PA@zlRyl2o-tXMb&ZcW&wggiw|G5cM)s(&ATxs1iP4-qF(Xd2Frk@qUb9A$xp+e7Oi7DH zQWYaQZS)Y!MGd?b2+EAREK(7dJhb&LA)}%dju)j#Vl2gc z8JCGlwW839H#~^Qfg_W2E@dxycnQj0DAitq&Q3dD%4jn|XOI`cXg&z?@DkX17kSBB z!FV2CNYY;7GEu2k6lyPp|9DY!E=u{4qH|H6tLR+fG(!`v#=O>6+b_|ZQp#)feBq7y zp6BZ|?%8^mP?2wWW~+_c!miE!W7KBskM&DV_=n5vE%VnhFKX(6|4z3nhur-I zoV5{LbQfInEx02D5B>%AJq3qqz*4JbhSv=034iY)*wO@U-3E4}0q;*EFKh)%c}-Ds zA8d#}82Um!!8andz@X^<0s8qyaA*(sT=&Z`Kza_~h))0*}!k>*w-oLZmHz(N{FZyka$>jDf}H~X+Y zd|p#dxdp!e2iS56?05sr?gM}O8@zQHjPOeA)K9uUvzIjM1^bH+!CiMi|7Y;pB=Fyr znrbo(s(JXQsu_*dX6#el9_soBz(OtfY`UhCEP%6D#{Zu&XW3T}Hb>wQ{E#y+iu}Pv z@bL!ld5@+$bspGo6>ND6+^)bK=fJLB@aPG!KMUTzr~5Pa(K`@^aXa1Nl+F{=j)6_< zz&704MEh~%?Ptrx2_)LDBmWLZp4dMVx&LXIo65vpN%-8`nYO=A+nhpB7!)RjMIkBT PHAUf2xaZP#B9(guVa_y_ delta 1001 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

*ERz4z9d_Grnz>lVMv0zE3D{ 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 ivn!K!b2PL`V*dlrhPvZ0YBV?i0000 Date: Fri, 22 Apr 2022 21:32:00 +0200 Subject: [PATCH 4/9] Big map update 12 Added global quest flags. They are bytes which work as state or progress markers for a given task, they are accessed by key, a string. --- .../src/forge/adventure/data/DialogData.java | 31 +++++--- .../src/forge/adventure/data/EnemyData.java | 4 -- .../src/forge/adventure/data/WorldData.java | 5 -- .../adventure/player/AdventurePlayer.java | 70 ++++++++++++++----- .../stage/ConsoleCommandInterpreter.java | 5 +- .../src/forge/adventure/stage/MapStage.java | 1 + .../src/forge/adventure/stage/WorldStage.java | 2 +- .../src/forge/adventure/util/MapDialog.java | 45 ++++++++++-- .../Shandalar/maps/map/debug_map.tmx | 52 +++++++++++--- 9 files changed, 162 insertions(+), 53 deletions(-) diff --git a/forge-gui-mobile/src/forge/adventure/data/DialogData.java b/forge-gui-mobile/src/forge/adventure/data/DialogData.java index 3a9de3564f1..4f503cb48f7 100644 --- a/forge-gui-mobile/src/forge/adventure/data/DialogData.java +++ b/forge-gui-mobile/src/forge/adventure/data/DialogData.java @@ -13,25 +13,40 @@ public class DialogData { public String loctext; //References a localized string for the text body. public DialogData[] options; // + + static public class ActionData { + static public class QuestFlag{ + public String key; + public int val; + } public String removeItem; //Remove item name from inventory. public String addItem; //Add item name to inventory. public int addLife = 0; //Gives the player X health. Negative to take. - public int addGold = 0; //Gives the player X gold. Negative to take. + public int addGold = 0; //Gives the player X gold. Negative to take. public int deleteMapObject = 0; //Remove ID from the map. -1 for self. public int battleWithActorID = 0; //Start a battle with enemy ID. -1 for self if possible. public EffectData giveBlessing; //Give a blessing to the player. public String setColorIdentity; //Change player's color identity. + public String advanceQuestFlag;//Increase given quest flag by 1. + public QuestFlag setQuestFlag; //Set quest flag {flag ID, value} } static public class ConditionData { + static public class QueryQuestFlag{ + public String key; + public String op; + public int val; + } public String item; - public int flag = 0; //Check for a local dungeon flag. - public int actorID = 0; //Check for an actor ID. - public String hasBlessing = null; //Check for specific blessing, if named. - public int hasGold = 0; //Check for player gold. True if gold is equal or higher than X. - public int hasLife = 0; //Check for player life. True if life is equal or higher than X. - public String colorIdentity = null;//Check for player's current color identity. - public boolean not = false; //Reverse the result of a condition ("actorID":"XX" + "not":true => true if XX is not in the map.) + public int flag = 0; //Check for a local dungeon flag. + public int actorID = 0; //Check for an actor ID. + public String hasBlessing = null; //Check for specific blessing, if named. + public int hasGold = 0; //Check for player gold. True if gold is equal or higher than X. + public int hasLife = 0; //Check for player life. True if life is equal or higher than X. + public String colorIdentity = null; //Check for player's current color identity. + public String checkQuestFlag = null; //Check if a quest flag is not 0. False if equals 0 (not started, not set). + public QueryQuestFlag getQuestFlag = null; //Check for value of a flag { , , } + public boolean not = false; //Reverse the result of a condition ("actorID":"XX" + "not":true => true if XX is not in the map.) } } diff --git a/forge-gui-mobile/src/forge/adventure/data/EnemyData.java b/forge-gui-mobile/src/forge/adventure/data/EnemyData.java index c78e63ce026..22154334a00 100644 --- a/forge-gui-mobile/src/forge/adventure/data/EnemyData.java +++ b/forge-gui-mobile/src/forge/adventure/data/EnemyData.java @@ -1,11 +1,7 @@ package forge.adventure.data; import forge.adventure.util.CardUtil; -import forge.card.ColorSet; import forge.deck.Deck; -import forge.deck.DeckProxy; -import forge.game.GameType; -import forge.model.FModel; /** * Data class that will be used to read Json configuration files diff --git a/forge-gui-mobile/src/forge/adventure/data/WorldData.java b/forge-gui-mobile/src/forge/adventure/data/WorldData.java index 3dbb7654248..908c857fdba 100644 --- a/forge-gui-mobile/src/forge/adventure/data/WorldData.java +++ b/forge-gui-mobile/src/forge/adventure/data/WorldData.java @@ -6,10 +6,6 @@ import com.badlogic.gdx.utils.Json; import forge.adventure.util.Config; import forge.adventure.util.Paths; import forge.adventure.world.BiomeSprites; -import forge.card.ColorSet; -import forge.deck.Deck; -import forge.deck.DeckProxy; -import forge.game.GameType; import java.io.Serializable; import java.util.ArrayList; @@ -90,5 +86,4 @@ public class WorldData implements Serializable { return biomes; } - } \ No newline at end of file diff --git a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java index eb83097dc10..ef951f00fc1 100644 --- a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java +++ b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java @@ -5,10 +5,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Null; import com.google.common.collect.Lists; -import forge.adventure.data.DifficultyData; -import forge.adventure.data.EffectData; -import forge.adventure.data.HeroListData; -import forge.adventure.data.ItemData; +import forge.adventure.data.*; import forge.adventure.util.*; import forge.adventure.world.WorldSave; import forge.deck.CardPool; @@ -40,8 +37,9 @@ public class AdventurePlayer implements Serializable, SaveFileContent { private int maxLife=20; private int life=20; private int selectedDeckIndex=0; + private Map questFlags = new HashMap<>(); private EffectData blessing; //Blessing to apply for next battle. - private PlayerStatistic statistic=new PlayerStatistic(); + private PlayerStatistic statistic = new PlayerStatistic(); private Deck[] decks=new Deck[NUMBER_OF_DECKS]; private final DifficultyData difficultyData=new DifficultyData(); @@ -83,13 +81,14 @@ public class AdventurePlayer implements Serializable, SaveFileContent { heroRace = race; isFemale = !male; name = n; - setColorIdentity(startingColorIdentity + 1); + setColorIdentity(startingColorIdentity + 1); //+1 because index 0 is colorless. statistic.clear(); newCards.clear(); onGoldChangeList.emit(); onLifeTotalChangeList.emit(); blessing = null; inventoryItems.addAll(difficultyData.startItems); + questFlags.clear(); } public void setSelectedDeckSlot(int slot) { @@ -198,19 +197,16 @@ public class AdventurePlayer implements Serializable, SaveFileContent { if(data.containsKey("blessing")) blessing = (EffectData)data.readObject("blessing"); inventoryItems.clear(); equippedItems.clear(); - if(data.containsKey("inventory")) - { + if(data.containsKey("inventory")) { String[] inv=(String[])data.readObject("inventory"); inventoryItems.addAll(inv); } - if(data.containsKey("equippedSlots")&&data.containsKey("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); - for(int i=0;i questFlagsKey = new ArrayList<>(); + ArrayList questFlagsValue = new ArrayList<>(); + for(Map.Entry entry : questFlags.entrySet()){ + questFlagsKey.add(entry.getKey()); + questFlagsValue.add(entry.getValue()); + } + data.storeObject("questFlagsKey", questFlagsKey.toArray(new String[0])); + data.storeObject("questFlagsValue", questFlagsValue.toArray(new Byte[0])); data.storeObject("deckCards",deck.getMain().toCardList("\n").split("\n")); if(deck.get(DeckSection.Sideboard)!=null) @@ -415,7 +428,10 @@ public class AdventurePlayer implements Serializable, SaveFileContent { onBlessing.emit(); } - public void clearBlessing() { blessing = null; } + public void clearBlessing() { + blessing = null; + onBlessing.emit(); + } public @Null EffectData getBlessing(){ return blessing; } @@ -517,4 +533,24 @@ public class AdventurePlayer implements Serializable, SaveFileContent { inventoryItems.add(name); return true; } + + public void setQuestFlag(String key, int value){ + questFlags.put(key, (byte) value); + } + 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){ + return questFlags.get(key) != null; + } + public int getQuestFlag(String key){ + return (int) questFlags.getOrDefault(key, (byte) 0); + } + public void resetQuestFlags(){ + questFlags.clear(); + } } diff --git a/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java b/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java index af4503c581e..981897e11c4 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java +++ b/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java @@ -6,7 +6,6 @@ import forge.StaticData; import forge.adventure.data.EnemyData; import forge.adventure.data.WorldData; import forge.adventure.pointofintrest.PointOfInterest; -import forge.adventure.scene.InventoryScene; import forge.adventure.scene.SceneType; import forge.adventure.util.Current; import forge.card.ColorSet; @@ -180,6 +179,10 @@ public class ConsoleCommandInterpreter { return "Force reload status scenes. Might be unstable."; }); + registerCommand(new String[]{"resetQuests"}, s -> { + Current.player().resetQuestFlags(); + return "All global quest flags have been reset."; + }); registerCommand(new String[]{"dumpEnemyDeckColors"}, s -> { for(EnemyData E : new Array.ArrayIterator<>(WorldData.getAllEnemies())){ Deck D = E.generateDeck(); diff --git a/forge-gui-mobile/src/forge/adventure/stage/MapStage.java b/forge-gui-mobile/src/forge/adventure/stage/MapStage.java index 8766a73ddd7..471341e3de8 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/MapStage.java +++ b/forge-gui-mobile/src/forge/adventure/stage/MapStage.java @@ -319,6 +319,7 @@ public class MapStage extends GameStage { mob.effect = JSONStringLoader.parse(EffectData.class, D.toString(), ""); } //TODO: Additional rewards. + //TODO: Filter by difficulty. (Don't spawn if doesn't match) addMapActor(obj, mob); } break; diff --git a/forge-gui-mobile/src/forge/adventure/stage/WorldStage.java b/forge-gui-mobile/src/forge/adventure/stage/WorldStage.java index 6f4273edacf..86ba3c5b102 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/WorldStage.java +++ b/forge-gui-mobile/src/forge/adventure/stage/WorldStage.java @@ -91,7 +91,7 @@ public class WorldStage extends GameStage implements SaveFileContent { Forge.clearTransitionScreen(); } }, ScreenUtils.getFrameBufferTexture(), true, false)); - startPause(0.5f, new Runnable() { + startPause(0.3f, new Runnable() { @Override public void run() { ((DuelScene) SceneType.DuelScene.instance).setEnemy(currentMob); diff --git a/forge-gui-mobile/src/forge/adventure/util/MapDialog.java b/forge-gui-mobile/src/forge/adventure/util/MapDialog.java index 55cf33466fd..ba1c7ae7f14 100644 --- a/forge-gui-mobile/src/forge/adventure/util/MapDialog.java +++ b/forge-gui-mobile/src/forge/adventure/util/MapDialog.java @@ -84,10 +84,10 @@ public class MapDialog { void setEffects(DialogData.ActionData[] data) { if(data==null) return; for(DialogData.ActionData E:data) { - if (E.removeItem != null){ //Removes an item from the player's inventory. + if(E.removeItem != null){ //Removes an item from the player's inventory. Current.player().removeItem(E.removeItem); } - if (E.addItem != null){ //Gives an item to the player. + if(E.addItem != null){ //Gives an item to the player. Current.player().addItem(E.addItem); } if(E.addLife != 0){ //Gives (positive or negative) life to the player. Cannot go over max health. @@ -97,23 +97,28 @@ public class MapDialog { if(E.addGold > 0) Current.player().giveGold(E.addGold); else Current.player().takeGold(-E.addGold); } - if (E.deleteMapObject != 0){ //Removes a dummy object from the map. + if(E.deleteMapObject != 0){ //Removes a dummy object from the map. if(E.deleteMapObject < 0) stage.deleteObject(parentID); else stage.deleteObject(E.deleteMapObject); } - if (E.battleWithActorID != 0){ //Starts a battle with the given enemy ID. + if(E.battleWithActorID != 0){ //Starts a battle with the given enemy ID. if(E.battleWithActorID < 0) stage.beginDuel(stage.getEnemyByID(parentID)); else stage.beginDuel(stage.getEnemyByID(E.battleWithActorID)); } - if (E.giveBlessing != null) { //Gives a blessing for your next battle. + if(E.giveBlessing != null) { //Gives a blessing for your next battle. Current.player().addBlessing(E.giveBlessing); } - if (E.setColorIdentity != null && !E.setColorIdentity.isEmpty()){ //Sets color identity (use sparingly) + if(E.setColorIdentity != null && !E.setColorIdentity.isEmpty()){ //Sets color identity (use sparingly) Current.player().setColorIdentity(E.setColorIdentity); } //Create map object. //Toggle dummy object's hitbox. (Like to make a door passable) - //Set world flag. + if(E.setQuestFlag != null && !E.setQuestFlag.key.isEmpty()){ //Set a quest to given value. + Current.player().setQuestFlag(E.setQuestFlag.key, E.setQuestFlag.val); + } + if(E.advanceQuestFlag != null && !E.advanceQuestFlag.isEmpty()){ //Increase a given quest flag by 1. + Current.player().advanceQuestFlag(E.advanceQuestFlag); + } //Set dungeon flag. } } @@ -152,6 +157,32 @@ public class MapDialog { if(!condition.not) return false; //Same as above. } else if(condition.not) return false; } + if(condition.getQuestFlag != null){ + String key = condition.getQuestFlag.key; + String cond = condition.getQuestFlag.op; + + int val = condition.getQuestFlag.val; + int QF = player.getQuestFlag(key); + boolean result = false; + if(!player.checkQuestFlag(key)) return false; //If the quest is not ongoing, stop. + + + switch(cond){ + default: case "EQUALS": case"EQUAL": case "=": + if(QF == val) result = true; break; + case "LESSTHAN": case "<": if(QF < val) result = true; break; + case "MORETHAN": case ">": if(QF > val) result = true; break; + case "LE_THAN": case "<=": if(QF <= val) result = true; break; + case "ME_THAN": case ">=": if(QF >= val) result = true; break; + } + if(!result) { if(!condition.not) return false; } + else { if(condition.not) return false; } + } + if(condition.checkQuestFlag != null && !condition.checkQuestFlag.isEmpty()){ + if(!player.checkQuestFlag(condition.checkQuestFlag)){ + if(!condition.not) return false; + } else if(condition.not) return false; + } } return true; } diff --git a/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx b/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx index 8f45f3f34a9..172d9aeaef1 100644 --- a/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx +++ b/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx @@ -77,11 +77,11 @@

- + - + - + [ { @@ -95,7 +95,7 @@ ] - + [ { @@ -121,7 +121,6 @@ [ { "effect":[], - "name":"ABC", "text":"I am an elf. I do elf things like hugging trees and being pretty.", "loctext":"", "condition":[], @@ -130,7 +129,7 @@ { "name":"Fight me, elf!", "text": "Gladly.", - "options": [ { "name": "I FEAR NOTHING!!?", "effect": [ { "battleWithActorID": -1 } ]} ] + "options": [ { "name": "Hey aren't you a bit swole for an elf...?", "effect": [ { "battleWithActorID": -1 } ]} ] }, { "name": "I want to be eco-friendly too.", @@ -182,10 +181,35 @@ "condition": [ { "actorID": 83 } ], "text": "Since you asked nicely, I shall.", "options": [ { "name": "Thanks bro.", "effect": [ { "deleteMapObject": 83 } ]} ] + }, + { + "name": "Got a quest?", + "condition": [ { "checkQuestFlag": "128", "not": true} ], + "text": "Ah, perhaps you can help me. Can you ask the Debug Demon about his favorite color?", + "options": [ + { "name": "That's weird, but sure.", "effect": [ { "setQuestFlag": {"key":"128", "val": 1} } ] }, + { "name": "That guy scares me, I'd rather not." } + ] + }, + { + "name": "About that quest...", + "condition": [ { "getQuestFlag": { "key": "128", "op":"<", "val": 3 } } ], + "text": "Please let me know what the Debug Demon's answer is.", + "options": [ + { "name": "Sure" } + ] + }, + { + "name": "Got it, bro.", + "condition": [ { "getQuestFlag": { "key": "128", "op":"=", "val": 3 } } ], + "text": "Ah. I see. Thank you friend, have this gold for your inconvenience.", + "options": [ + { "name": "Thanks", "effect": [ { "setQuestFlag": {"key":"128", "val": 4}, "addGold": 250 } ] } + ] + } + ] } - ] - } -] + ] { "lifeModifier": 190, "startBattleWithCard": [ "Llanowar Elves", "Llanowar Elves", "Forest", "Forest" ] @@ -253,6 +277,14 @@ ] } ] + }, + { + "name": "Hey what's your favorite color?", + "condition": [ {"getQuestFlag": { "key":"128", "op":"=", "val":1 } } ], + "text": "Why, purple. It is a powerful color.", + "options": [ + { "name": "Thank you Satan.", "effect": [ { "setQuestFlag": { "key":"128", "val":3 } } ] } + ] } ] } @@ -261,7 +293,7 @@ - + [ { "cardName": "Black Lotus", "type":"card", "count":1 } From c8f1ec5e515bb0698cd4b99a4dff4e771263a788 Mon Sep 17 00:00:00 2001 From: Magpie Date: Sat, 23 Apr 2022 00:31:20 +0200 Subject: [PATCH 5/9] Big map update 13 Adds a dialogue marker to enemies that can be talked to. Also enables to enable or disable dialogues entirely conditionally. --- .../forge/adventure/character/EnemySprite.java | 11 +++++++++-- .../src/forge/adventure/stage/MapStage.java | 5 ++--- .../src/forge/adventure/util/MapDialog.java | 12 +++++++++++- .../src/forge/adventure/world/World.java | 10 +++++++++- .../adventure/Shandalar/maps/map/debug_map.tmx | 9 +++++++++ .../res/adventure/Shandalar/ui/sprite_markers.png | Bin 0 -> 627 bytes 6 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 forge-gui/res/adventure/Shandalar/ui/sprite_markers.png diff --git a/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java b/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java index a4d65058e0e..cfb58fc90f1 100644 --- a/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java +++ b/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java @@ -1,7 +1,9 @@ package forge.adventure.character; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Actor; @@ -62,8 +64,8 @@ public class EnemySprite extends CharacterSprite { private void drawColorHints(Batch batch){ int size = Math.min(data.colors.length(), 6); - int DX = Math.round(getX() - 2); - int DY = Math.round(getY()); + float DX = getX() - 2f; + float DY = getY(); for(int i = 0; i < size; i++){ char C = data.colors.toUpperCase().charAt(i); @@ -110,6 +112,11 @@ public class EnemySprite extends CharacterSprite { if(Current.player().hasColorView() && !data.colors.isEmpty()) { drawColorHints(batch); } + if(dialog != null && dialog.canShow()){ //Draw a talk icon on top. + Texture T = Current.world().getGlobalTexture(); + TextureRegion TR = new TextureRegion(T, 0, 0, 16, 16); + batch.draw(TR, getX(), getY() + 16, 16, 16); + } } } diff --git a/forge-gui-mobile/src/forge/adventure/stage/MapStage.java b/forge-gui-mobile/src/forge/adventure/stage/MapStage.java index 471341e3de8..5c872a227fd 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/MapStage.java +++ b/forge-gui-mobile/src/forge/adventure/stage/MapStage.java @@ -499,9 +499,8 @@ public class MapStage extends GameStage { if (actor instanceof EnemySprite) { EnemySprite mob = (EnemySprite) actor; currentMob = mob; - if (mob.dialog != null){ //This enemy has something to say. Display a dialog like if it was a DialogActor. - resetPosition(); - //showDialog(); + resetPosition(); + if(mob.dialog != null && mob.dialog.canShow()){ //This enemy has something to say. Display a dialog like if it was a DialogActor but only if dialogue is possible. mob.dialog.activate(); } else { //Duel the enemy. beginDuel(mob); diff --git a/forge-gui-mobile/src/forge/adventure/util/MapDialog.java b/forge-gui-mobile/src/forge/adventure/util/MapDialog.java index ba1c7ae7f14..e3a45bdc3c8 100644 --- a/forge-gui-mobile/src/forge/adventure/util/MapDialog.java +++ b/forge-gui-mobile/src/forge/adventure/util/MapDialog.java @@ -73,7 +73,7 @@ public class MapDialog { } } - public void activate() { + public void activate() { //Method for actors to show their dialogues. for(DialogData dialog:data) { if(isConditionOk(dialog.condition)) { loadDialog(dialog); @@ -123,6 +123,16 @@ public class MapDialog { } } + public boolean canShow(){ + if( data == null) return false; + for(DialogData dialog:data) { + if(isConditionOk(dialog.condition)) { + return true; + } + } + return false; + } + boolean isConditionOk(DialogData.ConditionData[] data) { if( data==null ) return true; AdventurePlayer player = Current.player(); diff --git a/forge-gui-mobile/src/forge/adventure/world/World.java b/forge-gui-mobile/src/forge/adventure/world/World.java index ab240aa1a51..0c7117c0d86 100644 --- a/forge-gui-mobile/src/forge/adventure/world/World.java +++ b/forge-gui-mobile/src/forge/adventure/world/World.java @@ -3,6 +3,7 @@ package forge.adventure.world; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Actor; @@ -47,6 +48,7 @@ public class World implements Disposable, SaveFileContent { private long seed; private final Random random = MyRandom.getRandom(); private boolean worldDataLoaded=false; + private Texture globalTexture = null; public Random getRandom() { @@ -570,5 +572,11 @@ public class World implements Disposable, SaveFileContent { random.setSeed(seedOffset+seed); } - + public Texture getGlobalTexture() { + if(globalTexture == null){ + globalTexture = new Texture(Config.instance().getFile("ui/sprite_markers.png")); + System.out.print("Loading auxiliary sprites.\n"); + } + return globalTexture; + } } diff --git a/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx b/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx index 172d9aeaef1..83180894b02 100644 --- a/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx +++ b/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx @@ -225,6 +225,15 @@ + [ + { + "text":"...", + "condition":[ { "getQuestFlag": { "key": "128", "op":"<", "val": 3 } } ], + "options":[ + { "name":"???" } + ] + } +] diff --git a/forge-gui/res/adventure/Shandalar/ui/sprite_markers.png b/forge-gui/res/adventure/Shandalar/ui/sprite_markers.png new file mode 100644 index 0000000000000000000000000000000000000000..88d3b758aa478e25dc35687202cd813b8ce14f39 GIT binary patch literal 627 zcmV-(0*w8MP)EX>4Tx04R}tkv&MmKpe$iKcpfRhZYfW$j~}j5EXIMDionYs1;guFuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0sdx{sb+8-P&LcQ zq>@4|zbb@Y5yT)Oh$AR5Q=b#XG(5-GJ$!t6^ClJpv-LQx^h^IF# zo%23%l$9lg_?&pmpbHW|a$R=$jdRIiKhKOB*~~m~lvpTrvE0S1Y^cOj#4$zHDBquR zS>e3JS*_Mt`=0!T;exiZ%ypV0NMR965FtQD9TikzAwjD~iir&ECq4Ybj$b5~Os)zT zITlcZ3d!+<|H1EW&En*Qn-oq0JukNX5eGuMK&xTf-^aGyIspRDz?IhV*P6i0C+Urj z7CQn4wt0S*p< z(Gq2^d%U~1ySIPOwEO!3MrCr9EA+Rd00006VoOIv0GR-x0HVb=3ylB(010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^&cL6%Q~T43z)?02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002u#L_t(Y$L*6b4geqs1F0|O|I4}HrilwO$Sp9Cv?*ZL zG|lfQDi Date: Sat, 23 Apr 2022 01:15:39 +0200 Subject: [PATCH 6/9] Big map update 13.1 * Added console command to change color ID. * Portrait mode status screen * Portrait mode inventory "Delete" -> "Discard" --- .../src/forge/adventure/stage/ConsoleCommandInterpreter.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java b/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java index 981897e11c4..6b773e25f47 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java +++ b/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java @@ -173,6 +173,11 @@ public class ConsoleCommandInterpreter { Current.player().fullHeal(); return "Player life back to "+Current.player().getLife(); }); + registerCommand(new String[]{"setColorID"}, s -> { + if(s.length < 1) return "Please specify color ID: Valid choices: B, G, R, U, W, C. Example:\n\"setColorID G\""; + Current.player().setColorIdentity(s[0]); + return "Player color identity set to " + Current.player().getColorIdentity(); + }); registerCommand(new String[]{"reloadScenes"}, s -> { SceneType.InventoryScene.instance.resLoaded(); SceneType.PlayerStatisticScene.instance.resLoaded(); From 87ad9d2dd5f6d8c5155f3944efbaba9fe18d752a Mon Sep 17 00:00:00 2001 From: Magpie Date: Sat, 23 Apr 2022 02:42:20 +0200 Subject: [PATCH 7/9] Big map update 13.2 Some files left behind. --- .../src/forge/adventure/data/DialogData.java | 3 +- .../adventure/scene/PlayerStatisticScene.java | 1 + .../src/forge/adventure/util/MapDialog.java | 6 ++ .../Shandalar/maps/map/debug_map.tmx | 28 ++++++ .../Shandalar/ui/inventory_portrait.json | 2 +- .../Shandalar/ui/statistic_portrait.json | 87 ++++++++++--------- 6 files changed, 86 insertions(+), 41 deletions(-) diff --git a/forge-gui-mobile/src/forge/adventure/data/DialogData.java b/forge-gui-mobile/src/forge/adventure/data/DialogData.java index 4f503cb48f7..b20c55ab2f5 100644 --- a/forge-gui-mobile/src/forge/adventure/data/DialogData.java +++ b/forge-gui-mobile/src/forge/adventure/data/DialogData.java @@ -28,7 +28,8 @@ public class DialogData { public int battleWithActorID = 0; //Start a battle with enemy ID. -1 for self if possible. public EffectData giveBlessing; //Give a blessing to the player. public String setColorIdentity; //Change player's color identity. - public String advanceQuestFlag;//Increase given quest flag by 1. + public String advanceQuestFlag; //Increase given quest flag by 1. + public EffectData setEffect; //Set or replace current effects on current actor. public QuestFlag setQuestFlag; //Set quest flag {flag ID, value} } diff --git a/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java b/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java index 171edd293f9..68be744d25f 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java @@ -158,6 +158,7 @@ public class PlayerStatisticScene extends UIScene { blessingScroll = Controls.newLabel(""); blessingScroll.setStyle(new Label.LabelStyle(Controls.getBitmapFont("default"), Color.BLACK)); blessingScroll.setAlignment(Align.topLeft); + blessingScroll.setWrap(true); ui.onButtonPress("return", new Runnable() { @Override public void run() { diff --git a/forge-gui-mobile/src/forge/adventure/util/MapDialog.java b/forge-gui-mobile/src/forge/adventure/util/MapDialog.java index e3a45bdc3c8..d1564ebfb85 100644 --- a/forge-gui-mobile/src/forge/adventure/util/MapDialog.java +++ b/forge-gui-mobile/src/forge/adventure/util/MapDialog.java @@ -3,7 +3,9 @@ package forge.adventure.util; import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.utils.Array; import forge.Forge; +import forge.adventure.character.EnemySprite; import forge.adventure.data.DialogData; +import forge.adventure.data.EffectData; import forge.adventure.player.AdventurePlayer; import forge.adventure.stage.MapStage; import forge.util.Localizer; @@ -120,6 +122,10 @@ public class MapDialog { Current.player().advanceQuestFlag(E.advanceQuestFlag); } //Set dungeon flag. + if(E.setEffect != null){ //Replace current effects. + //EnemySprite EN = stage.getEnemyByID(parentID); + //EN.effect = E.setEffect; + } } } diff --git a/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx b/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx index 83180894b02..a86a8acc96c 100644 --- a/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx +++ b/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx @@ -220,6 +220,34 @@ + [ + { + "text": "You...you hurt Grog!\nYou...you filthy swine! I will stop at nothing until I see you defeated!\nGods...anyone! Grant me strength! Grant me REVENGE!!!!", + "condition": [ + { + "actorID": 1111, + "not": true + } + ], + "options": [ + { + "name": "Uh oh.", + "effect": [ + { + "setEffect": { + "lifeModifier": 200, + "startBattleWithCard": [ + "Elesh Norn, Grand Cenobyte", + "Avacyn, Angel of Hope", + "Urabrask the Hidden" + ] + }, "battleWithActorID": -1 + } + ] + } + ] + } +] diff --git a/forge-gui/res/adventure/Shandalar/ui/inventory_portrait.json b/forge-gui/res/adventure/Shandalar/ui/inventory_portrait.json index 6aeab969c15..56109660bde 100644 --- a/forge-gui/res/adventure/Shandalar/ui/inventory_portrait.json +++ b/forge-gui/res/adventure/Shandalar/ui/inventory_portrait.json @@ -87,7 +87,7 @@ { "type": "TextButton", "name": "delete", - "text": "Delete", + "text": "Discard", "width": 80, "height": 30, "x": 8, diff --git a/forge-gui/res/adventure/Shandalar/ui/statistic_portrait.json b/forge-gui/res/adventure/Shandalar/ui/statistic_portrait.json index 09a737bebe0..5ca37dab220 100644 --- a/forge-gui/res/adventure/Shandalar/ui/statistic_portrait.json +++ b/forge-gui/res/adventure/Shandalar/ui/statistic_portrait.json @@ -16,15 +16,15 @@ "x": 4, "y": 4, "width": 262, - "height": 90 + "height": 98 }, { "type": "Scroll", "name": "enemies", "x": 4, - "y": 98, + "y": 106, "width": 262, - "height": 335 + "height": 327 }, { "type": "Image", @@ -36,28 +36,19 @@ }, { "type": "Image", - "name": "avatarBorder", - "image": "ui/avatarhud.png", - "x": 24, - "y": 8, + "name": "colorFrame", + "image": "ui/colorC.png", + "x": 8, + "y": 25, "width": 64, "height": 64 }, - { - "type": "Label", - "name": "playerName", - "x": 34, - "y": 70, - "width": 80, - "height": 24, - "font": "black" - }, { "type": "Label", "name": "totalWins", - "x": 234, - "y": 14, - "width": 40, + "x": 144, + "y": 56, + "width": 26, "height": 24, "font": "black" }, @@ -65,8 +56,8 @@ "type": "Label", "name": "wins", "text": "Win:", - "x": 170, - "y": 14, + "x": 98, + "y": 56, "width": 60, "height": 24, "font": "black" @@ -74,9 +65,9 @@ { "type": "Label", "name": "totalLoss", - "x": 234, - "y": 34, - "width": 40, + "x": 144, + "y": 68, + "width": 26, "height": 24, "font": "black" }, @@ -84,8 +75,8 @@ "type": "Label", "name": "loss", "text": "Loss:", - "x": 170, - "y": 34, + "x": 98, + "y": 68, "width": 60, "height": 24, "font": "black" @@ -93,9 +84,9 @@ { "type": "Label", "name": "lossWinRatio", - "x": 234, - "y": 54, - "width": 40, + "x": 144, + "y": 80, + "width": 26, "height": 24, "font": "black" }, @@ -103,8 +94,8 @@ "type": "Label", "name": "winloss", "text": "Win Loss Ratio:", - "x": 170, - "y": 54, + "x": 98, + "y": 80, "width": 60, "height": 24, "font": "black" @@ -118,12 +109,21 @@ "x": 5, "y": 440 }, + { + "type": "Label", + "name": "playerName", + "x": 98, + "y": 4, + "width": 80, + "height": 24, + "font": "black" + }, { "type": "Image", "name": "lifeIcon", "image": "ui/life.png", - "x": 104, - "y": 40, + "x": 98, + "y": 22, "width": 16, "height": 16 }, @@ -131,8 +131,8 @@ "type": "Image", "name": "goldIcon", "image": "ui/money.png", - "x": 104, - "y": 60, + "x": 98, + "y": 42, "width": 16, "height": 16 }, @@ -142,8 +142,8 @@ "font": "black", "width": 64, "height": 16, - "x": 124, - "y": 40 + "x": 118, + "y": 22 }, { "type": "Label", @@ -151,8 +151,17 @@ "font": "black", "width": 64, "height": 16, - "x": 124, - "y": 60 + "x": 118, + "y": 42 + }, + { + "type": "Scroll", + "name": "blessingInfo", + "style": "nobg", + "x": 170, + "y": 14, + "width": 86, + "height": 80 }, { "type": "Table", From fb50b47fbee681e21c357e5521a69a4f63718c11 Mon Sep 17 00:00:00 2001 From: Magpie Date: Sat, 23 Apr 2022 02:44:58 +0200 Subject: [PATCH 8/9] Big map update 13.3 Some files left behind. --- forge-gui-mobile/src/forge/adventure/util/MapDialog.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/forge-gui-mobile/src/forge/adventure/util/MapDialog.java b/forge-gui-mobile/src/forge/adventure/util/MapDialog.java index d1564ebfb85..1214eec3c44 100644 --- a/forge-gui-mobile/src/forge/adventure/util/MapDialog.java +++ b/forge-gui-mobile/src/forge/adventure/util/MapDialog.java @@ -3,9 +3,7 @@ package forge.adventure.util; import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.utils.Array; import forge.Forge; -import forge.adventure.character.EnemySprite; import forge.adventure.data.DialogData; -import forge.adventure.data.EffectData; import forge.adventure.player.AdventurePlayer; import forge.adventure.stage.MapStage; import forge.util.Localizer; @@ -122,10 +120,10 @@ public class MapDialog { Current.player().advanceQuestFlag(E.advanceQuestFlag); } //Set dungeon flag. - if(E.setEffect != null){ //Replace current effects. +// if(E.setEffect != null){ //Replace current effects. //EnemySprite EN = stage.getEnemyByID(parentID); //EN.effect = E.setEffect; - } +// } } } From 315d889b0de727c8adaa2481d4df3ae099e85637 Mon Sep 17 00:00:00 2001 From: Magpie Date: Sat, 23 Apr 2022 03:01:46 +0200 Subject: [PATCH 9/9] Big map update 14 Allow setting enemy effects through dialogues. To test defeat the left goblin in the debug room. Then talk to his now very angry friend. --- forge-gui-mobile/src/forge/adventure/util/MapDialog.java | 9 +++++---- forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/forge-gui-mobile/src/forge/adventure/util/MapDialog.java b/forge-gui-mobile/src/forge/adventure/util/MapDialog.java index 1214eec3c44..c6eb16c6ece 100644 --- a/forge-gui-mobile/src/forge/adventure/util/MapDialog.java +++ b/forge-gui-mobile/src/forge/adventure/util/MapDialog.java @@ -3,6 +3,7 @@ package forge.adventure.util; import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.utils.Array; import forge.Forge; +import forge.adventure.character.EnemySprite; import forge.adventure.data.DialogData; import forge.adventure.player.AdventurePlayer; import forge.adventure.stage.MapStage; @@ -120,10 +121,10 @@ public class MapDialog { Current.player().advanceQuestFlag(E.advanceQuestFlag); } //Set dungeon flag. -// if(E.setEffect != null){ //Replace current effects. - //EnemySprite EN = stage.getEnemyByID(parentID); - //EN.effect = E.setEffect; -// } + if(E.setEffect != null){ //Replace current effects. + EnemySprite EN = stage.getEnemyByID(parentID); + EN.effect = E.setEffect; + } } } diff --git a/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx b/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx index a86a8acc96c..3609c25b5cf 100644 --- a/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx +++ b/forge-gui/res/adventure/Shandalar/maps/map/debug_map.tmx @@ -225,7 +225,7 @@ "text": "You...you hurt Grog!\nYou...you filthy swine! I will stop at nothing until I see you defeated!\nGods...anyone! Grant me strength! Grant me REVENGE!!!!", "condition": [ { - "actorID": 1111, + "actorID": 82, "not": true } ], @@ -235,11 +235,12 @@ "effect": [ { "setEffect": { - "lifeModifier": 200, + "lifeModifier": 99, "startBattleWithCard": [ - "Elesh Norn, Grand Cenobyte", "Avacyn, Angel of Hope", - "Urabrask the Hidden" + "Urabrask the Hidden", + "Elesh Norn, Grand Cenobite", + "Emrakul, the Aeons Torn" ] }, "battleWithActorID": -1 }