From fb8a7b904a63dd16cea06df9ef59baff1858350e Mon Sep 17 00:00:00 2001 From: jjayers99 <56438137+jjayers99@users.noreply.github.com> Date: Fri, 14 Apr 2023 22:14:12 -0400 Subject: [PATCH] Adventure quest updates Arena quest stage objectives now available, one quest added. Removed extra trigger for accepting quest in "A Vision of Destruction" offer dialog. Minor dialog enhancements. --- .../forge/adventure/editor/DialogTree.java | 6 +- .../adventure/data/AdventureQuestData.java | 5 +- .../adventure/data/AdventureQuestStage.java | 3 + .../util/AdventureQuestController.java | 12 + .../src/forge/adventure/world/World.java | 9 - .../res/adventure/Shandalar/world/quests.json | 253 ++++++++++++++++-- 6 files changed, 254 insertions(+), 34 deletions(-) diff --git a/forge-adventure/src/main/java/forge/adventure/editor/DialogTree.java b/forge-adventure/src/main/java/forge/adventure/editor/DialogTree.java index 3b90760340a..b553ebdfb00 100644 --- a/forge-adventure/src/main/java/forge/adventure/editor/DialogTree.java +++ b/forge-adventure/src/main/java/forge/adventure/editor/DialogTree.java @@ -10,11 +10,10 @@ import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import java.awt.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class DialogTree extends JPanel { - -// private DefaultMutableTreeNode rootNode; private JTree dialogTree; private JScrollPane scrollPane; @@ -91,7 +90,8 @@ public class DialogTree extends JPanel { DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) dialogTree.getLastSelectedPathComponent(); DialogData parentData = (DialogData) ((DefaultMutableTreeNode)selectedNode.getParent()).getUserObject(); - ((DefaultTreeModel) dialogTree.getModel()).removeNodeFromParent(selectedNode); + parentData.options = Arrays.stream(parentData.options).filter(q -> q != selectedNode.getUserObject()).toArray(DialogData[]::new); + ((DefaultTreeModel) dialogTree.getModel()).removeNodeFromParent(selectedNode); ((DefaultTreeModel) dialogTree.getModel()).reload(); setSelectedData(parentData); diff --git a/forge-gui-mobile/src/forge/adventure/data/AdventureQuestData.java b/forge-gui-mobile/src/forge/adventure/data/AdventureQuestData.java index 103d1e58166..039201b712a 100644 --- a/forge-gui-mobile/src/forge/adventure/data/AdventureQuestData.java +++ b/forge-gui-mobile/src/forge/adventure/data/AdventureQuestData.java @@ -19,8 +19,9 @@ public class AdventureQuestData implements Serializable { private int id; public int getID(){ - if (isTemplate && id < 1) - id = Current.world().getNextQuestId(); + if (isTemplate && id < 1) { + id = AdventureQuestController.instance().getNextQuestID(); + } return id; } public boolean isTemplate = false; diff --git a/forge-gui-mobile/src/forge/adventure/data/AdventureQuestStage.java b/forge-gui-mobile/src/forge/adventure/data/AdventureQuestStage.java index 80ca2dfc075..f7c539d1cdf 100644 --- a/forge-gui-mobile/src/forge/adventure/data/AdventureQuestStage.java +++ b/forge-gui-mobile/src/forge/adventure/data/AdventureQuestStage.java @@ -303,6 +303,9 @@ public class AdventureQuestStage implements Serializable { if (winner){ status = AdventureQuestController.QuestStatus.Complete; } + else { + status = AdventureQuestController.QuestStatus.Failed; + } } } } diff --git a/forge-gui-mobile/src/forge/adventure/util/AdventureQuestController.java b/forge-gui-mobile/src/forge/adventure/util/AdventureQuestController.java index e8d0db215b0..dd8dc874754 100644 --- a/forge-gui-mobile/src/forge/adventure/util/AdventureQuestController.java +++ b/forge-gui-mobile/src/forge/adventure/util/AdventureQuestController.java @@ -58,6 +58,7 @@ public class AdventureQuestController implements Serializable { private Map questAvailability = new HashMap<>(); public PointOfInterest mostRecentPOI; private List enemySpriteList= new ArrayList<>(); + private int nextQuestID = 0; public void showQuestDialogs(GameStage stage) { List finishedQuests = new ArrayList<>(); @@ -203,6 +204,17 @@ public class AdventureQuestController implements Serializable { } } + public int getNextQuestID(){ + if (nextQuestID == 0 && allQuests.size > 0) { + for (int i = 0; i < allQuests.size; i++) { + if (allQuests.get(i).getID() >= nextQuestID){ + nextQuestID = allQuests.get(i).getID() + 1; + } + } + } + return nextQuestID++; + } + public void updateEnteredPOI(PointOfInterest arrivedAt) { for(AdventureQuestData currentQuest : Current.player().getQuests()) { diff --git a/forge-gui-mobile/src/forge/adventure/world/World.java b/forge-gui-mobile/src/forge/adventure/world/World.java index bcff504aed3..4f588b8aae3 100644 --- a/forge-gui-mobile/src/forge/adventure/world/World.java +++ b/forge-gui-mobile/src/forge/adventure/world/World.java @@ -47,7 +47,6 @@ public class World implements Disposable, SaveFileContent { private final Random random = new Random(); private boolean worldDataLoaded = false; private Texture globalTexture = null; - private int nextQuestId; public Random getRandom() { return random; @@ -115,7 +114,6 @@ public class World implements Disposable, SaveFileContent { mapPoiIds = new PointOfInterestMap(getChunkSize(), this.data.tileSize, this.data.width / getChunkSize(), this.data.height / getChunkSize()); mapPoiIds.load(saveFileData.readSubData("mapPoiIds")); seed = saveFileData.readLong("seed"); - nextQuestId = saveFileData.readInt("nextQuestId"); } @Override @@ -131,9 +129,6 @@ public class World implements Disposable, SaveFileContent { data.store("mapObjectIds", mapObjectIds.save()); data.store("mapPoiIds", mapPoiIds.save()); data.store("seed", seed); - data.store("nextQuestId", nextQuestId); - - return data; } @@ -926,8 +921,4 @@ public class World implements Disposable, SaveFileContent { } return globalTexture; } - - public int getNextQuestId() { - return nextQuestId++; - } } diff --git a/forge-gui/res/adventure/Shandalar/world/quests.json b/forge-gui/res/adventure/Shandalar/world/quests.json index 900b50277eb..b6100d1ccaf 100644 --- a/forge-gui/res/adventure/Shandalar/world/quests.json +++ b/forge-gui/res/adventure/Shandalar/world/quests.json @@ -534,7 +534,7 @@ { "id": 2, "name": "Travel", - "description": "Go to the destination town", + "description": "Go to the $(poi_2) to pick up the vendor's merchandise", "mapFlag": "", "mapFlagValue": 1, "count1": 50, @@ -558,7 +558,7 @@ { "id": 3, "name": "Leave", - "description": "Leave town", + "description": "Leave $(poi_2) and take the merchant's supplies back to him", "mapFlag": "", "mapFlagValue": 1, "count1": 50, @@ -665,7 +665,7 @@ { "id": 4, "name": "Travel", - "description": "Return to the vendor", + "description": "Return to $(poi_1)", "mapFlag": "", "mapFlagValue": 1, "here": true, @@ -3703,22 +3703,6 @@ "text": "He shakes his head. \"It is a fight that you would win. But in the process, our village would be lost. We MUST prevent the beast from arriving.\"", "options": [ { - "action": [ - { - "removeItem": "", - "setColorIdentity": "", - "advanceQuestFlag": "", - "advanceMapFlag": "", - "setQuestFlag": { - "key": "" - }, - "setMapFlag": { - "key": "" - }, - "issueQuest": "1", - "POIReference": "" - } - ], "name": "\"How do we do that?\"", "text": "\"Before it comes here, the dragon will attempt to make a home at a $(poi_1) nearby. It will find several unfriendly occupants already there. But if you were to remove them in advance, I believe the creature will nest there and spare our village.\"", "options": [ @@ -5210,7 +5194,7 @@ ] }, { - "id": 201, + "id": 20, "isTemplate": true, "name": "Proving Yourself Worthy", "description": "Defeat 3 $(enemy_1)s", @@ -5778,5 +5762,234 @@ "mountain_town_tribal", "mountain_capital" ] +}, +{ + "id": 23, + "isTemplate": true, + "name": "Heart of a Champion", + "description": "Enter and win an upcoming arena event", + "offerDialog": { + "text": "\"DO YOU HAVE WHAT IT TAKES? ARE YOU THE BEST IN SHANDALAR???\" A young girl yells at the top of her lungs at each passer by in the town. Most people come in to view already covering their ears, having heard this plenty of times before.", + "options": [ + { + "name": "You walk over to her. \"Okay, kid, settle down, I heard you. What's this about?\"", + "text": "She looks surprised, and falls silent for a moment as she tries to remember what to do next. \"I uhhh... ummm...\" She pulls a piece of paper out of her pocket and prepares to read.", + "options": [ + { + "action": [ + { + "removeItem": "", + "setColorIdentity": "", + "advanceQuestFlag": "", + "advanceMapFlag": "", + "setQuestFlag": { + "key": "" + }, + "setMapFlag": { + "key": "" + }, + "issueQuest": "1", + "addMapReputation": -1, + "POIReference": "" + } + ], + "name": "Take the paper from her.", + "text": "\"HEY THAT'S MINE!!!\" She finds her full ear-piercing volume again before pulling it away and reading. \"PROVE YOU'RE THE BEST IN THE ARENA! THE TOURNAMENT BEGINS SOON\"", + "options": [ + { + "action": [ + { + "removeItem": "", + "setColorIdentity": "", + "advanceQuestFlag": "", + "advanceMapFlag": "", + "setQuestFlag": { + "key": "" + }, + "setMapFlag": { + "key": "" + }, + "issueQuest": "1", + "POIReference": "" + } + ], + "name": "\"Okay, sure, going somewhere far away seems good right now.\" (Accept Quest)" + }, + { + "name": "\"No thanks, I think I'll go find somewhere quiet for a while.\" (Decline Quest)" + } + ] + }, + { + "name": "Wait for her to continue.", + "text": "She reads over the paper as if seeing this part of it for the first time. \"It says here... 'Go to... $(poi_1)... and compete for prizes.' Do you know how to get there?\"", + "options": [ + { + "action": [ + { + "removeItem": "", + "setColorIdentity": "", + "advanceQuestFlag": "", + "advanceMapFlag": "", + "setQuestFlag": { + "key": "" + }, + "setMapFlag": { + "key": "" + }, + "issueQuest": "1", + "POIReference": "" + } + ], + "name": "\"Okay, sure, going somewhere far away seems good right now.\" (Accept Quest)" + }, + { + "name": "\"That's a little further than I'm looking to travel right now. But thanks all the same.\" (Decline Quest)", + "text": "She looks at you blankly for a moment, then resumes shouting into the air. \"DO YOU HAVE WHAT IT TAKES? ARE YOU THE BEST IN SHANDALAR???\"", + "options": [ + { + "name": "Cover your ears and move away quickly." + } + ] + } + ] + } + ] + }, + { + "name": "Cover your own ears and keep walking (Decline Quest)" + } + ] + }, + "prologue": {}, + "epilogue": { + "text": "The crowd goes wild as you finish your last opponent. You won't be paying for drinks in the $(poi_1) for quite some time. (+3 reputation in $(poi_1))", + "options": [ + { + "action": [ + { + "grantRewards": [ + { + "type": "shards", + "count": 20 + }, + { + "type": "card", + "count": 2, + "addMaxCount": 2, + "rarity": [ + "Rare", + "Mythic Rare" + ] + }, + { + "type": "gold", + "count": 250 + } + ] + } + ], + "name": "(Complete Quest)" + } + ] + }, + "failureDialog": { + "action": [ + { + "removeItem": "", + "setColorIdentity": "", + "advanceQuestFlag": "", + "advanceMapFlag": "", + "setQuestFlag": { + "key": "" + }, + "setMapFlag": { + "key": "" + }, + "issueQuest": "", + "addMapReputation": -2, + "POIReference": "$(poi_1)" + } + ], + "text": "The $(poi_1) arena is too much for you at the moment, but there's always another day. (-2 reputation in $(poi_1))", + "options": [ + { + "action": [ + { + "removeItem": "", + "setColorIdentity": "", + "advanceQuestFlag": "", + "advanceMapFlag": "", + "setQuestFlag": { + "key": "" + }, + "setMapFlag": { + "key": "" + }, + "issueQuest": "", + "addMapReputation": -2, + "POIReference": "$(poi_1)" + } + ], + "name": "(Quest Failed)" + } + ] + }, + "declinedDialog": { + "text": "Come back tomorrow and perhaps I'll have something that you'll actually be willing to do.", + "options": [ + { + "name": "(Catching the not so subtle hint, you leave.)" + } + ] + }, + "rewardDescription": "Eternal Glory", + "stages": [ + { + "id": 1, + "name": "Travel", + "description": "Make your way to the $(poi_1)", + "mapFlag": "", + "mapFlagValue": 1, + "count1": 60, + "count2": 30, + "POITags": [ + "Capital" + ], + "objective": "Travel", + "prologue": {}, + "epilogue": { + "text": "As you walk through the $(poi_1) gates, you can feel the excitement building, eminating, radiating from the city's arena. Most of the populace is already there or on their way. ", + "options": [ + { + "name": "(continue)", + "text": "The presence of so many powerful spellcasters has the air filled with traces of mana.", + "options": [ + { + "name": "It would be a shame to keep the crowd waiting for their new champion." + } + ] + } + ] + }, + "POIToken": "" + }, + { + "id": 2, + "name": "Arena", + "description": "Prove yourself to be the champion of the $(poi_1) arena", + "mapFlag": "", + "mapFlagValue": 1, + "objective": "Arena", + "prologue": {}, + "epilogue": {}, + "POIToken": "$(poi_1)" + } + ], + "questSourceTags": [ + "waste_town_generic", + "waste_town_identity", + "waste_town_tribal" + ] } ] \ No newline at end of file