Commit 91000821 authored by Akka's avatar Akka Committed by Luke H-W
Browse files

quest fix & personal line impl

parent 7bae35f5
...@@ -10,8 +10,8 @@ import emu.grasscutter.game.quest.handlers.QuestBaseHandler; ...@@ -10,8 +10,8 @@ import emu.grasscutter.game.quest.handlers.QuestBaseHandler;
public class ContentEnterDungeon extends QuestBaseHandler { public class ContentEnterDungeon extends QuestBaseHandler {
@Override @Override
public boolean execute(GameQuest quest, QuestCondition condition, int... params) { public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
return condition.getParam()[0] == params[0]; return condition.getParam()[0] == params[0];
} }
} }
package emu.grasscutter.game.quest.content;
import emu.grasscutter.data.excels.QuestData.QuestCondition;
import emu.grasscutter.game.quest.GameQuest;
import emu.grasscutter.game.quest.QuestValue;
import emu.grasscutter.game.quest.enums.QuestTrigger;
import emu.grasscutter.game.quest.handlers.QuestBaseHandler;
@QuestValue(QuestTrigger.QUEST_CONTENT_ENTER_ROOM)
public class ContentEnterRoom extends QuestBaseHandler {
@Override
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
return condition.getParam()[0] == params[0];
}
}
...@@ -10,8 +10,8 @@ import emu.grasscutter.game.quest.handlers.QuestBaseHandler; ...@@ -10,8 +10,8 @@ import emu.grasscutter.game.quest.handlers.QuestBaseHandler;
public class ContentFinishPlot extends QuestBaseHandler { public class ContentFinishPlot extends QuestBaseHandler {
@Override @Override
public boolean execute(GameQuest quest, QuestCondition condition, int... params) { public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
return condition.getParam()[0] == params[0]; return condition.getParam()[0] == params[0];
} }
} }
package emu.grasscutter.game.quest.content;
import emu.grasscutter.data.excels.QuestData.QuestCondition;
import emu.grasscutter.game.quest.GameQuest;
import emu.grasscutter.game.quest.QuestValue;
import emu.grasscutter.game.quest.enums.QuestTrigger;
import emu.grasscutter.game.quest.handlers.QuestBaseHandler;
@QuestValue(QuestTrigger.QUEST_CONTENT_GAME_TIME_TICK)
public class ContentGameTimeTick extends QuestBaseHandler {
@Override
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
var range = condition.getParamStr().split(",");
var min = Math.min(Integer.parseInt(range[0]), Integer.parseInt(range[1]));
var max = Math.max(Integer.parseInt(range[0]), Integer.parseInt(range[1]));
// params[0] is clock, params[1] is day
return params[0] >= min && params[0] <= max &&
params[1] >= condition.getParam()[0];
}
}
package emu.grasscutter.game.quest.content;
import emu.grasscutter.data.excels.QuestData.QuestCondition;
import emu.grasscutter.game.quest.GameQuest;
import emu.grasscutter.game.quest.QuestValue;
import emu.grasscutter.game.quest.enums.QuestTrigger;
import emu.grasscutter.game.quest.handlers.QuestBaseHandler;
@QuestValue(QuestTrigger.QUEST_CONTENT_INTERACT_GADGET)
public class ContentInteractGadget extends QuestBaseHandler {
@Override
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
return params[0] == condition.getParam()[0];
}
}
package emu.grasscutter.game.quest.content;
import emu.grasscutter.data.excels.QuestData.QuestCondition;
import emu.grasscutter.game.quest.GameQuest;
import emu.grasscutter.game.quest.QuestValue;
import emu.grasscutter.game.quest.enums.QuestTrigger;
import emu.grasscutter.game.quest.handlers.QuestBaseHandler;
@QuestValue(QuestTrigger.QUEST_CONTENT_LUA_NOTIFY)
public class ContentLuaNotify extends QuestBaseHandler {
@Override
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
return condition.getParamStr().equals(paramStr);
}
}
package emu.grasscutter.game.quest.content;
import emu.grasscutter.data.excels.QuestData.QuestCondition;
import emu.grasscutter.game.quest.GameQuest;
import emu.grasscutter.game.quest.QuestValue;
import emu.grasscutter.game.quest.enums.QuestTrigger;
import emu.grasscutter.game.quest.handlers.QuestBaseHandler;
@QuestValue(QuestTrigger.QUEST_CONTENT_QUEST_STATE_EQUAL)
public class ContentQuestStateEqual extends QuestBaseHandler {
@Override
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
GameQuest checkQuest = quest.getOwner().getQuestManager().getQuestById(params[0]);
if (checkQuest != null) {
return checkQuest.getState().getValue() == params[1];
}
return false;
}
}
package emu.grasscutter.game.quest.enums; package emu.grasscutter.game.quest.enums;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
public enum QuestTrigger { public enum QuestTrigger {
QUEST_COND_NONE (0), QUEST_COND_NONE (0),
QUEST_COND_STATE_EQUAL (1), QUEST_COND_STATE_EQUAL (1),
...@@ -79,7 +86,7 @@ public enum QuestTrigger { ...@@ -79,7 +86,7 @@ public enum QuestTrigger {
QUEST_COND_NEW_HOMEWORLD_SHOP_ITEM (75), QUEST_COND_NEW_HOMEWORLD_SHOP_ITEM (75),
QUEST_COND_SCENE_POINT_UNLOCK (76), QUEST_COND_SCENE_POINT_UNLOCK (76),
QUEST_COND_SCENE_LEVEL_TAG_EQ (77), QUEST_COND_SCENE_LEVEL_TAG_EQ (77),
QUEST_CONTENT_NONE (0), QUEST_CONTENT_NONE (0),
QUEST_CONTENT_KILL_MONSTER (1), QUEST_CONTENT_KILL_MONSTER (1),
QUEST_CONTENT_COMPLETE_TALK (2), QUEST_CONTENT_COMPLETE_TALK (2),
...@@ -153,7 +160,7 @@ public enum QuestTrigger { ...@@ -153,7 +160,7 @@ public enum QuestTrigger {
QUEST_CONTENT_IRODORI_FINISH_FLOWER_COMBINATION (151), QUEST_CONTENT_IRODORI_FINISH_FLOWER_COMBINATION (151),
QUEST_CONTENT_IRODORI_POETRY_REACH_MIN_PROGRESS (152), QUEST_CONTENT_IRODORI_POETRY_REACH_MIN_PROGRESS (152),
QUEST_CONTENT_IRODORI_POETRY_FINISH_FILL_POETRY (153), QUEST_CONTENT_IRODORI_POETRY_FINISH_FILL_POETRY (153),
QUEST_EXEC_NONE (0), QUEST_EXEC_NONE (0),
QUEST_EXEC_DEL_PACK_ITEM (1), QUEST_EXEC_DEL_PACK_ITEM (1),
QUEST_EXEC_UNLOCK_POINT (2), QUEST_EXEC_UNLOCK_POINT (2),
...@@ -222,9 +229,9 @@ public enum QuestTrigger { ...@@ -222,9 +229,9 @@ public enum QuestTrigger {
QUEST_EXEC_LOCK_PLAYER_WORLD_SCENE (66), QUEST_EXEC_LOCK_PLAYER_WORLD_SCENE (66),
QUEST_EXEC_FAIL_MAINCOOP (67), QUEST_EXEC_FAIL_MAINCOOP (67),
QUEST_EXEC_MODIFY_WEATHER_AREA (68); QUEST_EXEC_MODIFY_WEATHER_AREA (68);
private final int value; private final int value;
QuestTrigger(int id) { QuestTrigger(int id) {
this.value = id; this.value = id;
} }
...@@ -232,4 +239,24 @@ public enum QuestTrigger { ...@@ -232,4 +239,24 @@ public enum QuestTrigger {
public int getValue() { public int getValue() {
return value; return value;
} }
private static final Int2ObjectMap<QuestTrigger> contentMap = new Int2ObjectOpenHashMap<>();
private static final Map<String, QuestTrigger> contentStringMap = new HashMap<>();
static {
Stream.of(values())
.filter(e -> e.name().startsWith("QUEST_CONTENT_"))
.forEach(e -> {
contentMap.put(e.getValue(), e);
contentStringMap.put(e.name(), e);
});
}
public static QuestTrigger getContentTriggerByValue(int value) {
return contentMap.getOrDefault(value, QUEST_CONTENT_NONE);
}
public static QuestTrigger getContentTriggerByName(String name) {
return contentStringMap.getOrDefault(name, QUEST_CONTENT_NONE);
}
} }
package emu.grasscutter.game.quest.exec;
import emu.grasscutter.data.excels.QuestData;
import emu.grasscutter.game.quest.GameQuest;
import emu.grasscutter.game.quest.QuestValue;
import emu.grasscutter.game.quest.enums.QuestTrigger;
import emu.grasscutter.game.quest.handlers.QuestExecHandler;
import java.util.Arrays;
@QuestValue(QuestTrigger.QUEST_EXEC_ADD_QUEST_PROGRESS)
public class ExecAddQuestProgress extends QuestExecHandler {
@Override
public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) {
var param = Arrays.stream(paramStr)
.filter(i -> !i.isBlank())
.mapToInt(Integer::parseInt)
.toArray();
quest.getOwner().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_ADD_QUEST_PROGRESS, param);
return true;
}
}
package emu.grasscutter.game.quest.exec;
import emu.grasscutter.data.excels.QuestData;
import emu.grasscutter.game.quest.GameQuest;
import emu.grasscutter.game.quest.QuestGroupSuite;
import emu.grasscutter.game.quest.QuestValue;
import emu.grasscutter.game.quest.enums.QuestState;
import emu.grasscutter.game.quest.enums.QuestTrigger;
import emu.grasscutter.game.quest.handlers.QuestExecHandler;
import emu.grasscutter.scripts.constants.EventType;
import emu.grasscutter.scripts.data.ScriptArgs;
import emu.grasscutter.server.packet.send.PacketGroupSuiteNotify;
@QuestValue(QuestTrigger.QUEST_EXEC_NOTIFY_GROUP_LUA)
public class ExecNotifyGroupLua extends QuestExecHandler {
@Override
public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) {
var sceneId = Integer.parseInt(paramStr[0]);
var groupId = Integer.parseInt(paramStr[1]);
var scriptManager = quest.getOwner().getScene().getScriptManager();
if(quest.getOwner().getScene().getId() == sceneId){
scriptManager.callEvent(
quest.getState() == QuestState.QUEST_STATE_FINISHED ?
EventType.EVENT_QUEST_FINISH : EventType.EVENT_QUEST_START
, new ScriptArgs());
}
return true;
}
}
package emu.grasscutter.game.quest.exec;
import emu.grasscutter.data.excels.QuestData;
import emu.grasscutter.game.quest.GameQuest;
import emu.grasscutter.game.quest.QuestGroupSuite;
import emu.grasscutter.game.quest.QuestValue;
import emu.grasscutter.game.quest.enums.QuestTrigger;
import emu.grasscutter.game.quest.handlers.QuestExecHandler;
import emu.grasscutter.server.packet.send.PacketGroupSuiteNotify;
import java.util.Arrays;
@QuestValue(QuestTrigger.QUEST_EXEC_REFRESH_GROUP_SUITE)
public class ExecRefreshGroupSuite extends QuestExecHandler {
@Override
public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) {
var sceneId = Integer.parseInt(paramStr[0]);
var groupId = Integer.parseInt(paramStr[1].split(",")[0]);
var suiteId = Integer.parseInt(paramStr[1].split(",")[1]);
var scriptManager = quest.getOwner().getScene().getScriptManager();
quest.getMainQuest().getQuestGroupSuites().add(QuestGroupSuite.of()
.scene(sceneId)
.group(groupId)
.suite(suiteId)
.build());
// refresh immediately if player is in this scene
if(quest.getOwner().getScene().getId() == sceneId){
scriptManager.refreshGroup(scriptManager.getGroupById(groupId), suiteId);
quest.getOwner().sendPacket(new PacketGroupSuiteNotify(groupId, suiteId));
}
return true;
}
}
...@@ -4,7 +4,7 @@ import emu.grasscutter.data.excels.QuestData.QuestCondition; ...@@ -4,7 +4,7 @@ import emu.grasscutter.data.excels.QuestData.QuestCondition;
import emu.grasscutter.game.quest.GameQuest; import emu.grasscutter.game.quest.GameQuest;
public abstract class QuestBaseHandler { public abstract class QuestBaseHandler {
public abstract boolean execute(GameQuest quest, QuestCondition condition, int... params); public abstract boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params);
} }
package emu.grasscutter.game.quest.handlers;
import emu.grasscutter.data.excels.QuestData;
import emu.grasscutter.game.quest.GameQuest;
public abstract class QuestExecHandler {
public abstract boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr);
}
...@@ -13,6 +13,7 @@ import emu.grasscutter.game.props.ClimateType; ...@@ -13,6 +13,7 @@ import emu.grasscutter.game.props.ClimateType;
import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.LifeState; import emu.grasscutter.game.props.LifeState;
import emu.grasscutter.game.props.SceneType; import emu.grasscutter.game.props.SceneType;
import emu.grasscutter.game.quest.QuestGroupSuite;
import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry; import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
import emu.grasscutter.game.dungeons.challenge.WorldChallenge; import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
import emu.grasscutter.net.packet.BasePacket; import emu.grasscutter.net.packet.BasePacket;
...@@ -798,4 +799,22 @@ public class Scene { ...@@ -798,4 +799,22 @@ public class Scene {
} }
return npcList; return npcList;
} }
public void loadGroupForQuest(List<QuestGroupSuite> sceneGroupSuite) {
if(!scriptManager.isInit()){
return;
}
sceneGroupSuite.forEach(i -> {
var group = scriptManager.getGroupById(i.getGroup());
if(group == null){
return;
}
var suite = group.getSuiteByIndex(i.getSuite());
if(suite == null){
return;
}
scriptManager.addGroupSuite(group, suite);
});
}
} }
...@@ -482,6 +482,11 @@ public class ScriptLib { ...@@ -482,6 +482,11 @@ public class ScriptLib {
logger.debug("[LUA] Call AddQuestProgress with {}", logger.debug("[LUA] Call AddQuestProgress with {}",
var1); var1);
for(var player : getSceneScriptManager().getScene().getPlayers()){
player.getQuestManager().triggerEvent(QuestTrigger.QUEST_COND_LUA_NOTIFY, var1);
player.getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_LUA_NOTIFY, var1);
}
return 0; return 0;
} }
......
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.game.quest.enums.QuestTrigger;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.AddQuestContentProgressReqOuterClass;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketAddQuestContentProgressRsp;
@Opcodes(PacketOpcodes.AddQuestContentProgressReq)
public class HandlerAddQuestContentProgressReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var req = AddQuestContentProgressReqOuterClass.AddQuestContentProgressReq.parseFrom(payload);
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.getContentTriggerByValue(req.getContentType()), req.getParam());
session.send(new PacketAddQuestContentProgressRsp(req.getContentType()));
}
}
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
import emu.grasscutter.game.quest.enums.QuestTrigger;
import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.ChangeGameTimeReqOuterClass.ChangeGameTimeReq; import emu.grasscutter.net.proto.ChangeGameTimeReqOuterClass.ChangeGameTimeReq;
...@@ -9,12 +10,15 @@ import emu.grasscutter.server.packet.send.PacketChangeGameTimeRsp; ...@@ -9,12 +10,15 @@ import emu.grasscutter.server.packet.send.PacketChangeGameTimeRsp;
@Opcodes(PacketOpcodes.ChangeGameTimeReq) @Opcodes(PacketOpcodes.ChangeGameTimeReq)
public class HandlerChangeGameTimeReq extends PacketHandler { public class HandlerChangeGameTimeReq extends PacketHandler {
@Override @Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
ChangeGameTimeReq req = ChangeGameTimeReq.parseFrom(payload); ChangeGameTimeReq req = ChangeGameTimeReq.parseFrom(payload);
session.getPlayer().getScene().changeTime(req.getGameTime()); session.getPlayer().getScene().changeTime(req.getGameTime());
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_GAME_TIME_TICK,
req.getGameTime() / 60 , // hours
req.getExtraDays()); //days
session.getPlayer().sendPacket(new PacketChangeGameTimeRsp(session.getPlayer())); session.getPlayer().sendPacket(new PacketChangeGameTimeRsp(session.getPlayer()));
} }
......
...@@ -32,6 +32,12 @@ public class HandlerEnterSceneDoneReq extends PacketHandler { ...@@ -32,6 +32,12 @@ public class HandlerEnterSceneDoneReq extends PacketHandler {
// spawn NPC // spawn NPC
session.getPlayer().getScene().loadNpcForPlayerEnter(session.getPlayer()); session.getPlayer().getScene().loadNpcForPlayerEnter(session.getPlayer());
// notify client to load the npc for quest
var questGroupSuites = session.getPlayer().getQuestManager().getSceneGroupSuite(session.getPlayer().getSceneId());
session.getPlayer().getScene().loadGroupForQuest(questGroupSuites);
session.send(new PacketGroupSuiteNotify(questGroupSuites));
// Reset timer for sending player locations // Reset timer for sending player locations
session.getPlayer().resetSendPlayerLocTime(); session.getPlayer().resetSendPlayerLocTime();
} }
......
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.EvtEntityRenderersChangedNotifyOuterClass;
import emu.grasscutter.net.proto.ForwardTypeOuterClass;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketEvtEntityRenderersChangedNotify;
import emu.grasscutter.server.packet.send.PacketWorldPlayerLocationNotify;
@Opcodes(PacketOpcodes.EvtEntityRenderersChangedNotify)
public class HandlerEvtEntityRenderersChangedNotify extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var req = EvtEntityRenderersChangedNotifyOuterClass.EvtEntityRenderersChangedNotify.parseFrom(payload);
switch (req.getForwardType()) {
case FORWARD_TYPE_TO_ALL ->
session.getPlayer().getScene().broadcastPacket(new PacketEvtEntityRenderersChangedNotify(req));
case FORWARD_TYPE_TO_ALL_EXCEPT_CUR ->
session.getPlayer().getScene().broadcastPacketToOthers(session.getPlayer(), new PacketEvtEntityRenderersChangedNotify(req));
case FORWARD_TYPE_TO_HOST ->
session.getPlayer().getScene().getWorld().getHost().sendPacket(new PacketEvtEntityRenderersChangedNotify(req));
}
}
}
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
import emu.grasscutter.game.quest.enums.QuestTrigger;
import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq; import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
...@@ -8,11 +9,12 @@ import emu.grasscutter.server.game.GameSession; ...@@ -8,11 +9,12 @@ import emu.grasscutter.server.game.GameSession;
@Opcodes(PacketOpcodes.GadgetInteractReq) @Opcodes(PacketOpcodes.GadgetInteractReq)
public class HandlerGadgetInteractReq extends PacketHandler { public class HandlerGadgetInteractReq extends PacketHandler {
@Override @Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
GadgetInteractReq req = GadgetInteractReq.parseFrom(payload); GadgetInteractReq req = GadgetInteractReq.parseFrom(payload);
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_INTERACT_GADGET, req.getGadgetId());
session.getPlayer().interactWith(req.getGadgetEntityId(), req); session.getPlayer().interactWith(req.getGadgetEntityId(), req);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment