From 9b507a6ec37477feffe58a07c80eede7af50cb96 Mon Sep 17 00:00:00 2001 From: KingRainbow44 Date: Sat, 29 Apr 2023 21:35:49 -0400 Subject: [PATCH] Add support for legacy and newer quest excels --- .../grasscutter/config/ConfigContainer.java | 22 ++++++++- .../emu/grasscutter/game/player/Player.java | 2 +- .../game/player/PlayerProgressManager.java | 2 +- .../grasscutter/game/quest/QuestManager.java | 45 +++++++++++++++---- .../recv/HandlerSetPlayerBornDataReq.java | 2 +- 5 files changed, 60 insertions(+), 13 deletions(-) diff --git a/src/main/java/emu/grasscutter/config/ConfigContainer.java b/src/main/java/emu/grasscutter/config/ConfigContainer.java index 3f3b361a9..66b755bf7 100644 --- a/src/main/java/emu/grasscutter/config/ConfigContainer.java +++ b/src/main/java/emu/grasscutter/config/ConfigContainer.java @@ -2,6 +2,7 @@ package emu.grasscutter.config; import ch.qos.logback.classic.Level; import com.google.gson.JsonObject; +import com.google.gson.annotations.SerializedName; import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter.ServerDebugMode; import emu.grasscutter.Grasscutter.ServerRunMode; @@ -20,8 +21,14 @@ import static emu.grasscutter.Grasscutter.config; * *when your JVM fails* */ public class ConfigContainer { + /* + * Configuration changes: + * Version 5 - 'questing' has been changed from a boolean + * to a container of options ('questOptions'). + * This field will be removed in future versions. + */ private static int version() { - return 4; + return 5; } /** @@ -238,7 +245,11 @@ public class ConfigContainer { public boolean staminaUsage = true; public boolean energyUsage = true; public boolean fishhookTeleport = true; - public boolean questing = true; + @SerializedName("questOptions") + public Questing questing = new Questing(); + @Deprecated(forRemoval = true) + @SerializedName("questing") + public boolean questingEnabled = true; public ResinOptions resinOptions = new ResinOptions(); public Rates rates = new Rates(); @@ -266,6 +277,13 @@ public class ConfigContainer { public int cap = 160; public int rechargeTime = 480; } + + public static class Questing { + /* Should questing behavior be used? */ + public boolean enabled = true; + /* Are older resources being used? */ + public boolean legacyResources = false; + } } public static class VisionOptions { diff --git a/src/main/java/emu/grasscutter/game/player/Player.java b/src/main/java/emu/grasscutter/game/player/Player.java index 7354574a4..41fa751b8 100644 --- a/src/main/java/emu/grasscutter/game/player/Player.java +++ b/src/main/java/emu/grasscutter/game/player/Player.java @@ -513,7 +513,7 @@ public class Player { * Applies the properties to the player. */ private void applyProperties() { - var withQuesting = GAME_OPTIONS.questing; + var withQuesting = GAME_OPTIONS.questing.enabled; this.setOrFetch(PlayerProperty.PROP_PLAYER_LEVEL, 1); this.setOrFetch(PlayerProperty.PROP_IS_SPRING_AUTO_USE, 1); diff --git a/src/main/java/emu/grasscutter/game/player/PlayerProgressManager.java b/src/main/java/emu/grasscutter/game/player/PlayerProgressManager.java index 54d0b64dc..9f570db9b 100644 --- a/src/main/java/emu/grasscutter/game/player/PlayerProgressManager.java +++ b/src/main/java/emu/grasscutter/game/player/PlayerProgressManager.java @@ -77,7 +77,7 @@ public final class PlayerProgressManager extends BasePlayerDataManager { // Add statue quests if necessary. this.addStatueQuestsOnLogin(); - if (!GAME_OPTIONS.questing) { + if (!GAME_OPTIONS.questing.enabled) { // Auto-unlock the first statue and map area. this.player.getUnlockedScenePoints(3).add(7); this.player.getUnlockedSceneAreas(3).add(1); diff --git a/src/main/java/emu/grasscutter/game/quest/QuestManager.java b/src/main/java/emu/grasscutter/game/quest/QuestManager.java index 3d314e292..d5322747d 100644 --- a/src/main/java/emu/grasscutter/game/quest/QuestManager.java +++ b/src/main/java/emu/grasscutter/game/quest/QuestManager.java @@ -26,6 +26,8 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; +import static emu.grasscutter.config.Configuration.GAME_OPTIONS; + public class QuestManager extends BasePlayerManager { @Getter private final Player player; @@ -39,6 +41,26 @@ public class QuestManager extends BasePlayerManager { eventExecutor = new ThreadPoolExecutor(4, 4, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1000), FastThreadLocalThread::new, new ThreadPoolExecutor.AbortPolicy()); + + var options = GAME_OPTIONS.questing; + if (options.enabled) { + if (options.legacyResources) { + Grasscutter.getLogger().debug("You have 'legacyResources' enabled."); + Grasscutter.getLogger().debug("This assumes you are using older (3.2) QuestExcelConfigData and MainQuestExcelConfigData."); + Grasscutter.getLogger().debug("The game will *break* if you are not using these older excels."); + Grasscutter.getLogger().debug("Questing should feel more natural in this mode."); + } else { + Grasscutter.getLogger().debug("You have 'legacyResources' disabled."); + Grasscutter.getLogger().debug("This should be enabled if you are using 3.3 or newer resources."); + Grasscutter.getLogger().debug("The game can potentially encounter issues in this mode."); + } + } + + //noinspection removal + if (GAME_OPTIONS.questingEnabled) { + Grasscutter.getLogger().warn("Please upgrade your configuration. 'questing' is being deprecated in favor of 'questOptions'."); + Grasscutter.getLogger().info("To remove this message until removal, use 'questingEnabled' instead of 'questOptions.enabled'."); + } } /* On SetPlayerBornDataReq, the server sends FinishedParentQuestNotify, with this exact @@ -79,30 +101,37 @@ public class QuestManager extends BasePlayerManager { QuestEncryptionKey questEncryptionKey = GameData.getMainQuestEncryptionMap().get(mainQuestId); return questEncryptionKey != null ? questEncryptionKey.getEncryptionKey() : 0L; } - public QuestManager(Player player) { + public QuestManager(Player player) { super(player); + this.player = player; this.mainQuests = new Int2ObjectOpenHashMap<>(); } // TODO store user value set on enable public boolean isQuestingEnabled() { - return Grasscutter.getConfig().server.game.gameOptions.questing; + return GAME_OPTIONS.questing.enabled; } public void onPlayerBorn() { // TODO scan the quest and start the quest with acceptCond fulfilled - // The off send 3 request in that order: 1. FinishedParentQuestNotify, 2. QuestListNotify, 3. ServerCondMeetQuestListUpdateNotify + // The off send 3 request in that order: + // 1. FinishedParentQuestNotify + // 2. QuestListNotify + // 3. ServerCondMeetQuestListUpdateNotify if (this.isQuestingEnabled()) { - // this.enableQuests(); - this.addQuest(35104); + if (GAME_OPTIONS.questing.legacyResources) { + this.enableQuests(); // This assumes 3.2 resources, where all conditions are known. + } else { + this.addQuest(35104); // This assumes resources greater than 3.2, where quests might have unknown conditions. + } } - //getPlayer().sendPacket(new PacketFinishedParentQuestUpdateNotify(newQuests)); - //getPlayer().sendPacket(new PacketQuestListNotify(subQuests)); - //getPlayer().sendPacket(new PacketServerCondMeetQuestListUpdateNotify(newPlayerServerCondMeetQuestListUpdateNotify)); + // this.getPlayer().sendPacket(new PacketFinishedParentQuestUpdateNotify(newQuests)); + // this.getPlayer().sendPacket(new PacketQuestListNotify(subQuests)); + // this.getPlayer().sendPacket(new PacketServerCondMeetQuestListUpdateNotify(newPlayerServerCondMeetQuestListUpdateNotify)); } public void onLogin() { diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerSetPlayerBornDataReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerSetPlayerBornDataReq.java index b0efc4140..e1c61b046 100644 --- a/src/main/java/emu/grasscutter/server/packet/recv/HandlerSetPlayerBornDataReq.java +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerSetPlayerBornDataReq.java @@ -53,7 +53,7 @@ public class HandlerSetPlayerBornDataReq extends PacketHandler { Avatar mainCharacter = new Avatar(avatarId); // Check if the default Anemo skill should be given. - if (!GAME_OPTIONS.questing) { + if (!GAME_OPTIONS.questing.enabled) { mainCharacter.setSkillDepotData( GameData.getAvatarSkillDepotDataMap().get(startingSkillDepot)); }