diff --git a/src/main/java/emu/grasscutter/game/player/Player.java b/src/main/java/emu/grasscutter/game/player/Player.java index 8cfb0b360..1c28968b9 100644 --- a/src/main/java/emu/grasscutter/game/player/Player.java +++ b/src/main/java/emu/grasscutter/game/player/Player.java @@ -225,6 +225,7 @@ public class Player { this.unlockedFurnitureSuite = new HashSet<>(); this.activeForges = new ArrayList<>(); this.unlockedRecipies = new HashMap<>(); + this.questGlobalVariables = new HashMap<>(); this.openStates = new HashMap<>(); this.unlockedSceneAreas = new HashMap<>(); this.unlockedScenePoints = new HashMap<>(); @@ -1197,7 +1198,7 @@ public class Player { session.send(new PacketPlayerLevelRewardUpdateNotify(rewardedLevels)); // First notify packets sent - this.hasSentLoginPackets = true; + this.hasSentLoginPackets = true; // Set session state session.setState(SessionState.ACTIVE); diff --git a/src/main/java/emu/grasscutter/game/player/PlayerProgressManager.java b/src/main/java/emu/grasscutter/game/player/PlayerProgressManager.java index 1ad678002..0bc8c79bc 100644 --- a/src/main/java/emu/grasscutter/game/player/PlayerProgressManager.java +++ b/src/main/java/emu/grasscutter/game/player/PlayerProgressManager.java @@ -46,6 +46,7 @@ public class PlayerProgressManager extends BasePlayerDataManager { // that particular statue interactable. this.player.getUnlockedScenePoints(3).add(7); this.player.getUnlockedSceneAreas(3).add(1); + } /****************************************************************************************************************** @@ -61,12 +62,12 @@ public class PlayerProgressManager extends BasePlayerDataManager { // Set of open states that are set per default for all accounts. Can be overwritten by an entry in `map`. public static final Set DEFAULT_OPEN_STATES = GameData.getOpenStateList().stream() - .filter(s -> + .filter(s -> s.isDefaultState() // Actual default-opened states. // All states whose unlock we don't handle correctly yet. || (s.getCond().stream().filter(c -> c.getCondType() == OpenStateCondType.OPEN_STATE_COND_PLAYER_LEVEL).count() == 0) // Always unlock OPEN_STATE_PAIMON, otherwise the player will not have a working chat. - || s.getId() == 1 + || s.getId() == 1 ) .filter(s -> !BLACKLIST_OPEN_STATES.contains(s.getId())) // Filter out states in the blacklist. .map(s -> s.getId()) @@ -119,7 +120,7 @@ public class PlayerProgressManager extends BasePlayerDataManager { // ToDo: Implement. } } - + // Done. If we didn't find any violations, all conditions are met. return true; } @@ -195,14 +196,13 @@ public class PlayerProgressManager extends BasePlayerDataManager { } } - public void unlockTransPoint(int sceneId, int pointId, boolean isStatue) { + public boolean unlockTransPoint(int sceneId, int pointId, boolean isStatue) { // Check whether the unlocked point exists and whether it is still locked. String key = sceneId + "_" + pointId; ScenePointEntry scenePointEntry = GameData.getScenePointEntries().get(key); - + if (scenePointEntry == null || this.player.getUnlockedScenePoints(sceneId).contains(pointId)) { - this.player.sendPacket(new PacketUnlockTransPointRsp(Retcode.RET_FAIL)); - return; + return false; } // Add the point to the list of unlocked points for its scene. @@ -222,7 +222,7 @@ public class PlayerProgressManager extends BasePlayerDataManager { // Send packet. this.player.sendPacket(new PacketScenePointUnlockNotify(sceneId, pointId)); - this.player.sendPacket(new PacketUnlockTransPointRsp(Retcode.RET_SUCC)); + return true; } public void unlockSceneArea(int sceneId, int areaId) { diff --git a/src/main/java/emu/grasscutter/game/quest/GameMainQuest.java b/src/main/java/emu/grasscutter/game/quest/GameMainQuest.java index 9a3963a49..ddf5afa2d 100644 --- a/src/main/java/emu/grasscutter/game/quest/GameMainQuest.java +++ b/src/main/java/emu/grasscutter/game/quest/GameMainQuest.java @@ -194,8 +194,9 @@ public class GameMainQuest { CompiledScript cs = ScriptLoader.getScriptByPath( SCRIPT("Quest/Share/Q" + getParentQuestId() + "ShareConfig." + ScriptLoader.getScriptType())); + //mainQuest 303 doesn't have a ShareConfig if (cs == null) { - Grasscutter.getLogger().error("Couldn't find Q" + getParentQuestId() + "ShareConfig." + ScriptLoader.getScriptType()); + Grasscutter.getLogger().debug("Couldn't find Q" + getParentQuestId() + "ShareConfig." + ScriptLoader.getScriptType()); return; } @@ -283,15 +284,19 @@ public class GameMainQuest { for (GameQuest subQuestWithCond : subQuestsWithCond) { List failCond = subQuestWithCond.getQuestData().getFailCond(); - int[] fail = new int[failCond.size()]; for (int i = 0; i < subQuestWithCond.getQuestData().getFailCond().size(); i++) { QuestData.QuestCondition condition = failCond.get(i); - boolean result = this.getOwner().getServer().getQuestSystem().triggerContent(subQuestWithCond, condition, paramStr, params); - fail[i] = result ? 1 : 0; + if(condition.getType() == condType) { + boolean result = this.getOwner().getServer().getQuestSystem().triggerContent(subQuestWithCond, condition, paramStr, params); + subQuestWithCond.getFailProgressList()[i] = result ? 1 : 0; + if(result) { + getOwner().getSession().send(new PacketQuestProgressUpdateNotify(subQuestWithCond)); + } + } } - boolean shouldFail = LogicType.calculate(subQuestWithCond.getQuestData().getFailCondComb(), fail); + boolean shouldFail = LogicType.calculate(subQuestWithCond.getQuestData().getFailCondComb(), subQuestWithCond.getFailProgressList()); if (shouldFail) { subQuestWithCond.fail(); @@ -314,15 +319,19 @@ public class GameMainQuest { for (GameQuest subQuestWithCond : subQuestsWithCond) { List finishCond = subQuestWithCond.getQuestData().getFinishCond(); - int[] finish = new int[finishCond.size()]; for (int i = 0; i < finishCond.size(); i++) { QuestData.QuestCondition condition = finishCond.get(i); - boolean result = this.getOwner().getServer().getQuestSystem().triggerContent(subQuestWithCond, condition, paramStr, params); - finish[i] = result ? 1 : 0; + if(condition.getType() == condType) { + boolean result = this.getOwner().getServer().getQuestSystem().triggerContent(subQuestWithCond, condition, paramStr, params); + subQuestWithCond.getFinishProgressList()[i] = result ? 1 : 0; + if(result) { + getOwner().getSession().send(new PacketQuestProgressUpdateNotify(subQuestWithCond)); + } + } } - boolean shouldFinish = LogicType.calculate(subQuestWithCond.getQuestData().getFinishCondComb(), finish); + boolean shouldFinish = LogicType.calculate(subQuestWithCond.getQuestData().getFinishCondComb(), subQuestWithCond.getFinishProgressList()); if (shouldFinish) { subQuestWithCond.finish(); diff --git a/src/main/java/emu/grasscutter/game/quest/GameQuest.java b/src/main/java/emu/grasscutter/game/quest/GameQuest.java index 769f94734..91912dce3 100644 --- a/src/main/java/emu/grasscutter/game/quest/GameQuest.java +++ b/src/main/java/emu/grasscutter/game/quest/GameQuest.java @@ -137,13 +137,6 @@ public class GameQuest { this.state = QuestState.QUEST_STATE_FINISHED; this.finishTime = Utils.getCurrentSeconds(); - if (getFinishProgressList() != null) { - Arrays.fill(getFinishProgressList(), 1); - } - - getOwner().getSession().send(new PacketQuestProgressUpdateNotify(this)); - - if (getQuestData().finishParent()) { // This quest finishes the questline - the main quest will also save the quest to db, so we don't have to call save() here getMainQuest().finish(); @@ -169,12 +162,6 @@ public class GameQuest { this.state = QuestState.QUEST_STATE_FAILED; this.finishTime = Utils.getCurrentSeconds(); - if (getFailProgressList() != null) { - Arrays.fill(getFailProgressList(), 1); - } - - getOwner().getSession().send(new PacketQuestProgressUpdateNotify(this)); - getQuestData().getFailExec().forEach(e -> getOwner().getServer().getQuestSystem().triggerExec(this, e, e.getParam())); //Some subQuests have conditions that subQuests fail (even from different MainQuests) getOwner().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_QUEST_STATE_EQUAL, this.subQuestId, this.state.getValue(),0,0,0); diff --git a/src/main/java/emu/grasscutter/game/quest/QuestManager.java b/src/main/java/emu/grasscutter/game/quest/QuestManager.java index 8a62dc022..016e4bc86 100644 --- a/src/main/java/emu/grasscutter/game/quest/QuestManager.java +++ b/src/main/java/emu/grasscutter/game/quest/QuestManager.java @@ -25,8 +25,6 @@ import lombok.Getter; public class QuestManager extends BasePlayerManager { @Getter private final Player player; - @Getter private Map questGlobalVariables; - @Getter private final Int2ObjectMap mainQuests; @Getter private List addToQuestListUpdateNotify; /* @@ -63,7 +61,7 @@ public class QuestManager extends BasePlayerManager { ); */ - + public static long getQuestKey(int mainQuestId){ QuestEncryptionKey questEncryptionKey = GameData.getMainQuestEncryptionMap().get(mainQuestId); return questEncryptionKey != null ? questEncryptionKey.getEncryptionKey() : 0L; @@ -72,7 +70,6 @@ public class QuestManager extends BasePlayerManager { super(player); this.player = player; - this.questGlobalVariables = player.getQuestGlobalVariables(); this.mainQuests = new Int2ObjectOpenHashMap<>(); this.addToQuestListUpdateNotify = new ArrayList<>(); } @@ -81,7 +78,7 @@ public class QuestManager extends BasePlayerManager { List newQuests = this.addMultMainQuests(newPlayerMainQuests); //getPlayer().sendPacket(new PacketServerCondMeetQuestListUpdateNotify(newPlayerServerCondMeetQuestListUpdateNotify)); - getPlayer().sendPacket(new PacketFinishedParentQuestUpdateNotify(newQuests)); + //getPlayer().sendPacket(new PacketFinishedParentQuestUpdateNotify(newQuests)); } @@ -112,24 +109,24 @@ public class QuestManager extends BasePlayerManager { Looking through mainQuests 72201-72208 and 72174, we can infer that a questGlobalVar's default value is 0 */ public Integer getQuestGlobalVarValue(Integer variable) { - return this.questGlobalVariables.getOrDefault(variable,0); + return getPlayer().getQuestGlobalVariables().getOrDefault(variable,0); } public void setQuestGlobalVarValue(Integer variable, Integer value) { - Integer previousValue = this.questGlobalVariables.put(variable,value); + Integer previousValue = getPlayer().getQuestGlobalVariables().put(variable,value); Grasscutter.getLogger().debug("Changed questGlobalVar {} value from {} to {}", variable, previousValue==null ? 0: previousValue, value); } public void incQuestGlobalVarValue(Integer variable, Integer inc) { // - Integer previousValue = this.questGlobalVariables.getOrDefault(variable,0); - this.questGlobalVariables.put(variable,previousValue + inc); + Integer previousValue = getPlayer().getQuestGlobalVariables().getOrDefault(variable,0); + getPlayer().getQuestGlobalVariables().put(variable,previousValue + inc); Grasscutter.getLogger().debug("Incremented questGlobalVar {} value from {} to {}", variable, previousValue, previousValue + inc); } //In MainQuest 998, dec is passed as a positive integer public void decQuestGlobalVarValue(Integer variable, Integer dec) { // - Integer previousValue = this.questGlobalVariables.getOrDefault(variable,0); - this.questGlobalVariables.put(variable,previousValue - dec); + Integer previousValue = getPlayer().getQuestGlobalVariables().getOrDefault(variable,0); + getPlayer().getQuestGlobalVariables().put(variable,previousValue - dec); Grasscutter.getLogger().debug("Decremented questGlobalVar {} value from {} to {}", variable, previousValue, previousValue - dec); } diff --git a/src/main/java/emu/grasscutter/game/quest/content/ContentUnlockTransPoint.java b/src/main/java/emu/grasscutter/game/quest/content/ContentUnlockTransPoint.java index 5ae674c55..fed3b7927 100644 --- a/src/main/java/emu/grasscutter/game/quest/content/ContentUnlockTransPoint.java +++ b/src/main/java/emu/grasscutter/game/quest/content/ContentUnlockTransPoint.java @@ -10,6 +10,6 @@ import emu.grasscutter.game.quest.handlers.QuestBaseHandler; public class ContentUnlockTransPoint extends QuestBaseHandler { @Override public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) { - return true; + return condition.getParam()[0] == params[0] && condition.getParam()[1] == params[1]; } } diff --git a/src/main/java/emu/grasscutter/game/quest/exec/ExecUnlockPoint.java b/src/main/java/emu/grasscutter/game/quest/exec/ExecUnlockPoint.java index 9e0aec8d2..204cc1b44 100644 --- a/src/main/java/emu/grasscutter/game/quest/exec/ExecUnlockPoint.java +++ b/src/main/java/emu/grasscutter/game/quest/exec/ExecUnlockPoint.java @@ -13,7 +13,7 @@ public class ExecUnlockPoint extends QuestExecHandler { // Unlock the trans point for the player. int sceneId = Integer.parseInt(paramStr[0]); int pointId = Integer.parseInt(paramStr[1]); - boolean isStatue = quest.getMainQuestId() == 303; + boolean isStatue = quest.getMainQuestId() == 303 || quest.getMainQuestId() == 352; quest.getOwner().getProgressManager().unlockTransPoint(sceneId, pointId, isStatue); diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerUnlockTransPointReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerUnlockTransPointReq.java index 4a7336d4d..28c6ce4da 100644 --- a/src/main/java/emu/grasscutter/server/packet/recv/HandlerUnlockTransPointReq.java +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerUnlockTransPointReq.java @@ -2,15 +2,18 @@ package emu.grasscutter.server.packet.recv; import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.RetcodeOuterClass; import emu.grasscutter.net.proto.UnlockTransPointReqOuterClass.UnlockTransPointReq; import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketUnlockTransPointRsp; @Opcodes(PacketOpcodes.UnlockTransPointReq) public class HandlerUnlockTransPointReq extends PacketHandler { @Override public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { UnlockTransPointReq req = UnlockTransPointReq.parseFrom(payload); - session.getPlayer().getProgressManager().unlockTransPoint(req.getSceneId(), req.getPointId(), false); + boolean unlocked = session.getPlayer().getProgressManager().unlockTransPoint(req.getSceneId(), req.getPointId(), false); + session.getPlayer().sendPacket(new PacketUnlockTransPointRsp(unlocked ? RetcodeOuterClass.Retcode.RET_SUCC : RetcodeOuterClass.Retcode.RET_FAIL)); } }