Commit f4770cf2 authored by Melledy's avatar Melledy Committed by GitHub
Browse files

Merge pull request #816 from Grasscutters/dev-quests

Implement quests
parents 891c70e5 cbd46e92
package emu.grasscutter.game.quest.enums;
import java.util.Arrays;
public enum LogicType {
LOGIC_NONE (0),
LOGIC_AND (1),
LOGIC_OR (2),
LOGIC_NOT (3),
LOGIC_A_AND_ETCOR (4),
LOGIC_A_AND_B_AND_ETCOR (5),
LOGIC_A_OR_ETCAND (6),
LOGIC_A_OR_B_OR_ETCAND (7),
LOGIC_A_AND_B_OR_ETCAND (8);
private final int value;
LogicType(int id) {
this.value = id;
}
public int getValue() {
return value;
}
public static boolean calculate(LogicType logicType, int[] progress) {
if (logicType == null) {
return progress[0] == 1;
}
switch (logicType) {
case LOGIC_AND -> {
return Arrays.stream(progress).allMatch(i -> i == 1);
}
case LOGIC_OR -> {
return Arrays.stream(progress).anyMatch(i -> i == 1);
}
default -> {
return Arrays.stream(progress).anyMatch(i -> i == 1);
}
}
}
}
package emu.grasscutter.game.quest.enums;
public enum ParentQuestState {
PARENT_QUEST_STATE_NONE (0),
PARENT_QUEST_STATE_FINISHED (1),
PARENT_QUEST_STATE_FAILED (2),
PARENT_QUEST_STATE_CANCELED (3);
private final int value;
ParentQuestState(int id) {
this.value = id;
}
public int getValue() {
return value;
}
}
package emu.grasscutter.game.quest.enums;
public enum QuestGuideType {
QUEST_GUIDE_NONE (0),
QUEST_GUIDE_LOCATION (1),
QUEST_GUIDE_NPC (2);
private final int value;
QuestGuideType(int id) {
this.value = id;
}
public int getValue() {
return value;
}
}
package emu.grasscutter.game.quest.enums;
public enum QuestShowType {
QUEST_SHOW (0),
QUEST_HIDDEN (1);
private final int value;
QuestShowType(int id) {
this.value = id;
}
public int getValue() {
return value;
}
}
package emu.grasscutter.game.quest.enums;
public enum QuestState {
QUEST_STATE_NONE (0),
QUEST_STATE_UNSTARTED (1),
QUEST_STATE_UNFINISHED (2),
QUEST_STATE_FINISHED (3),
QUEST_STATE_FAILED (4);
private final int value;
QuestState(int id) {
this.value = id;
}
public int getValue() {
return value;
}
}
package emu.grasscutter.game.quest.enums;
public enum QuestTrigger {
QUEST_COND_NONE (0),
QUEST_COND_STATE_EQUAL (1),
QUEST_COND_STATE_NOT_EQUAL (2),
QUEST_COND_PACK_HAVE_ITEM (3),
QUEST_COND_AVATAR_ELEMENT_EQUAL (4),
QUEST_COND_AVATAR_ELEMENT_NOT_EQUAL (5),
QUEST_COND_AVATAR_CAN_CHANGE_ELEMENT (6),
QUEST_COND_CITY_LEVEL_EQUAL_GREATER (7),
QUEST_COND_ITEM_NUM_LESS_THAN (8),
QUEST_COND_DAILY_TASK_START (9),
QUEST_COND_OPEN_STATE_EQUAL (10),
QUEST_COND_DAILY_TASK_OPEN (11),
QUEST_COND_DAILY_TASK_REWARD_CAN_GET (12),
QUEST_COND_DAILY_TASK_REWARD_RECEIVED (13),
QUEST_COND_PLAYER_LEVEL_REWARD_CAN_GET (14),
QUEST_COND_EXPLORATION_REWARD_CAN_GET (15),
QUEST_COND_IS_WORLD_OWNER (16),
QUEST_COND_PLAYER_LEVEL_EQUAL_GREATER (17),
QUEST_COND_SCENE_AREA_UNLOCKED (18),
QUEST_COND_ITEM_GIVING_ACTIVED (19),
QUEST_COND_ITEM_GIVING_FINISHED (20),
QUEST_COND_IS_DAYTIME (21),
QUEST_COND_CURRENT_AVATAR (22),
QUEST_COND_CURRENT_AREA (23),
QUEST_COND_QUEST_VAR_EQUAL (24),
QUEST_COND_QUEST_VAR_GREATER (25),
QUEST_COND_QUEST_VAR_LESS (26),
QUEST_COND_FORGE_HAVE_FINISH (27),
QUEST_COND_DAILY_TASK_IN_PROGRESS (28),
QUEST_COND_DAILY_TASK_FINISHED (29),
QUEST_COND_ACTIVITY_COND (30),
QUEST_COND_ACTIVITY_OPEN (31),
QUEST_COND_DAILY_TASK_VAR_GT (32),
QUEST_COND_DAILY_TASK_VAR_EQ (33),
QUEST_COND_DAILY_TASK_VAR_LT (34),
QUEST_COND_BARGAIN_ITEM_GT (35),
QUEST_COND_BARGAIN_ITEM_EQ (36),
QUEST_COND_BARGAIN_ITEM_LT (37),
QUEST_COND_COMPLETE_TALK (38),
QUEST_COND_NOT_HAVE_BLOSSOM_TALK (39),
QUEST_COND_IS_CUR_BLOSSOM_TALK (40),
QUEST_COND_QUEST_NOT_RECEIVE (41),
QUEST_COND_QUEST_SERVER_COND_VALID (42),
QUEST_COND_ACTIVITY_CLIENT_COND (43),
QUEST_COND_QUEST_GLOBAL_VAR_EQUAL (44),
QUEST_COND_QUEST_GLOBAL_VAR_GREATER (45),
QUEST_COND_QUEST_GLOBAL_VAR_LESS (46),
QUEST_COND_PERSONAL_LINE_UNLOCK (47),
QUEST_COND_CITY_REPUTATION_REQUEST (48),
QUEST_COND_MAIN_COOP_START (49),
QUEST_COND_MAIN_COOP_ENTER_SAVE_POINT (50),
QUEST_COND_CITY_REPUTATION_LEVEL (51),
QUEST_COND_CITY_REPUTATION_UNLOCK (52),
QUEST_COND_LUA_NOTIFY (53),
QUEST_COND_CUR_CLIMATE (54),
QUEST_COND_ACTIVITY_END (55),
QUEST_COND_COOP_POINT_RUNNING (56),
QUEST_COND_GADGET_TALK_STATE_EQUAL (57),
QUEST_COND_AVATAR_FETTER_GT (58),
QUEST_COND_AVATAR_FETTER_EQ (59),
QUEST_COND_AVATAR_FETTER_LT (60),
QUEST_COND_NEW_HOMEWORLD_MOUDLE_UNLOCK (61),
QUEST_COND_NEW_HOMEWORLD_LEVEL_REWARD (62),
QUEST_COND_NEW_HOMEWORLD_MAKE_FINISH (63),
QUEST_COND_HOMEWORLD_NPC_EVENT (64),
QUEST_COND_TIME_VAR_GT_EQ (65),
QUEST_COND_TIME_VAR_PASS_DAY (66),
QUEST_COND_HOMEWORLD_NPC_NEW_TALK (67),
QUEST_COND_PLAYER_CHOOSE_MALE (68),
QUEST_COND_HISTORY_GOT_ANY_ITEM (69),
QUEST_COND_LEARNED_RECIPE (70),
QUEST_COND_LUNARITE_REGION_UNLOCKED (71),
QUEST_COND_LUNARITE_HAS_REGION_HINT_COUNT (72),
QUEST_COND_LUNARITE_COLLECT_FINISH (73),
QUEST_COND_LUNARITE_MARK_ALL_FINISH (74),
QUEST_COND_NEW_HOMEWORLD_SHOP_ITEM (75),
QUEST_COND_SCENE_POINT_UNLOCK (76),
QUEST_COND_SCENE_LEVEL_TAG_EQ (77),
QUEST_CONTENT_NONE (0),
QUEST_CONTENT_KILL_MONSTER (1),
QUEST_CONTENT_COMPLETE_TALK (2),
QUEST_CONTENT_MONSTER_DIE (3),
QUEST_CONTENT_FINISH_PLOT (4),
QUEST_CONTENT_OBTAIN_ITEM (5),
QUEST_CONTENT_TRIGGER_FIRE (6),
QUEST_CONTENT_CLEAR_GROUP_MONSTER (7),
QUEST_CONTENT_NOT_FINISH_PLOT (8),
QUEST_CONTENT_ENTER_DUNGEON (9),
QUEST_CONTENT_ENTER_MY_WORLD (10),
QUEST_CONTENT_FINISH_DUNGEON (11),
QUEST_CONTENT_DESTROY_GADGET (12),
QUEST_CONTENT_OBTAIN_MATERIAL_WITH_SUBTYPE (13),
QUEST_CONTENT_NICK_NAME (14),
QUEST_CONTENT_WORKTOP_SELECT (15),
QUEST_CONTENT_SEAL_BATTLE_RESULT (16),
QUEST_CONTENT_ENTER_ROOM (17),
QUEST_CONTENT_GAME_TIME_TICK (18),
QUEST_CONTENT_FAIL_DUNGEON (19),
QUEST_CONTENT_LUA_NOTIFY (20),
QUEST_CONTENT_TEAM_DEAD (21),
QUEST_CONTENT_COMPLETE_ANY_TALK (22),
QUEST_CONTENT_UNLOCK_TRANS_POINT (23),
QUEST_CONTENT_ADD_QUEST_PROGRESS (24),
QUEST_CONTENT_INTERACT_GADGET (25),
QUEST_CONTENT_DAILY_TASK_COMP_FINISH (26),
QUEST_CONTENT_FINISH_ITEM_GIVING (27),
QUEST_CONTENT_SKILL (107),
QUEST_CONTENT_CITY_LEVEL_UP (109),
QUEST_CONTENT_PATTERN_GROUP_CLEAR_MONSTER (110),
QUEST_CONTENT_ITEM_LESS_THAN (111),
QUEST_CONTENT_PLAYER_LEVEL_UP (112),
QUEST_CONTENT_DUNGEON_OPEN_STATUE (113),
QUEST_CONTENT_UNLOCK_AREA (114),
QUEST_CONTENT_OPEN_CHEST_WITH_GADGET_ID (115),
QUEST_CONTENT_UNLOCK_TRANS_POINT_WITH_TYPE (116),
QUEST_CONTENT_FINISH_DAILY_DUNGEON (117),
QUEST_CONTENT_FINISH_WEEKLY_DUNGEON (118),
QUEST_CONTENT_QUEST_VAR_EQUAL (119),
QUEST_CONTENT_QUEST_VAR_GREATER (120),
QUEST_CONTENT_QUEST_VAR_LESS (121),
QUEST_CONTENT_OBTAIN_VARIOUS_ITEM (122),
QUEST_CONTENT_FINISH_TOWER_LEVEL (123),
QUEST_CONTENT_BARGAIN_SUCC (124),
QUEST_CONTENT_BARGAIN_FAIL (125),
QUEST_CONTENT_ITEM_LESS_THAN_BARGAIN (126),
QUEST_CONTENT_ACTIVITY_TRIGGER_FAILED (127),
QUEST_CONTENT_MAIN_COOP_ENTER_SAVE_POINT (128),
QUEST_CONTENT_ANY_MANUAL_TRANSPORT (129),
QUEST_CONTENT_USE_ITEM (130),
QUEST_CONTENT_MAIN_COOP_ENTER_ANY_SAVE_POINT (131),
QUEST_CONTENT_ENTER_MY_HOME_WORLD (132),
QUEST_CONTENT_ENTER_MY_WORLD_SCENE (133),
QUEST_CONTENT_TIME_VAR_GT_EQ (134),
QUEST_CONTENT_TIME_VAR_PASS_DAY (135),
QUEST_CONTENT_QUEST_STATE_EQUAL (136),
QUEST_CONTENT_QUEST_STATE_NOT_EQUAL (137),
QUEST_CONTENT_UNLOCKED_RECIPE (138),
QUEST_CONTENT_NOT_UNLOCKED_RECIPE (139),
QUEST_CONTENT_FISHING_SUCC (140),
QUEST_CONTENT_ENTER_ROGUE_DUNGEON (141),
QUEST_CONTENT_USE_WIDGET (142),
QUEST_CONTENT_CAPTURE_SUCC (143),
QUEST_CONTENT_CAPTURE_USE_CAPTURETAG_LIST (144),
QUEST_CONTENT_CAPTURE_USE_MATERIAL_LIST (145),
QUEST_CONTENT_ENTER_VEHICLE (147),
QUEST_CONTENT_SCENE_LEVEL_TAG_EQ (148),
QUEST_CONTENT_LEAVE_SCENE (149),
QUEST_CONTENT_LEAVE_SCENE_RANGE (150),
QUEST_CONTENT_IRODORI_FINISH_FLOWER_COMBINATION (151),
QUEST_CONTENT_IRODORI_POETRY_REACH_MIN_PROGRESS (152),
QUEST_CONTENT_IRODORI_POETRY_FINISH_FILL_POETRY (153),
QUEST_EXEC_NONE (0),
QUEST_EXEC_DEL_PACK_ITEM (1),
QUEST_EXEC_UNLOCK_POINT (2),
QUEST_EXEC_UNLOCK_AREA (3),
QUEST_EXEC_UNLOCK_FORCE (4),
QUEST_EXEC_LOCK_FORCE (5),
QUEST_EXEC_CHANGE_AVATAR_ELEMET (6),
QUEST_EXEC_REFRESH_GROUP_MONSTER (7),
QUEST_EXEC_SET_IS_FLYABLE (8),
QUEST_EXEC_SET_IS_WEATHER_LOCKED (9),
QUEST_EXEC_SET_IS_GAME_TIME_LOCKED (10),
QUEST_EXEC_SET_IS_TRANSFERABLE (11),
QUEST_EXEC_GRANT_TRIAL_AVATAR (12),
QUEST_EXEC_OPEN_BORED (13),
QUEST_EXEC_ROLLBACK_QUEST (14),
QUEST_EXEC_NOTIFY_GROUP_LUA (15),
QUEST_EXEC_SET_OPEN_STATE (16),
QUEST_EXEC_LOCK_POINT (17),
QUEST_EXEC_DEL_PACK_ITEM_BATCH (18),
QUEST_EXEC_REFRESH_GROUP_SUITE (19),
QUEST_EXEC_REMOVE_TRIAL_AVATAR (20),
QUEST_EXEC_SET_GAME_TIME (21),
QUEST_EXEC_SET_WEATHER_GADGET (22),
QUEST_EXEC_ADD_QUEST_PROGRESS (23),
QUEST_EXEC_NOTIFY_DAILY_TASK (24),
QUEST_EXEC_CREATE_PATTERN_GROUP (25),
QUEST_EXEC_REMOVE_PATTERN_GROUP (26),
QUEST_EXEC_REFRESH_GROUP_SUITE_RANDOM (27),
QUEST_EXEC_ACTIVE_ITEM_GIVING (28),
QUEST_EXEC_DEL_ALL_SPECIFIC_PACK_ITEM (29),
QUEST_EXEC_ROLLBACK_PARENT_QUEST (30),
QUEST_EXEC_LOCK_AVATAR_TEAM (31),
QUEST_EXEC_UNLOCK_AVATAR_TEAM (32),
QUEST_EXEC_UPDATE_PARENT_QUEST_REWARD_INDEX (33),
QUEST_EXEC_SET_DAILY_TASK_VAR (34),
QUEST_EXEC_INC_DAILY_TASK_VAR (35),
QUEST_EXEC_DEC_DAILY_TASK_VAR (36),
QUEST_EXEC_ACTIVE_ACTIVITY_COND_STATE (37),
QUEST_EXEC_INACTIVE_ACTIVITY_COND_STATE (38),
QUEST_EXEC_ADD_CUR_AVATAR_ENERGY (39),
QUEST_EXEC_START_BARGAIN (41),
QUEST_EXEC_STOP_BARGAIN (42),
QUEST_EXEC_SET_QUEST_GLOBAL_VAR (43),
QUEST_EXEC_INC_QUEST_GLOBAL_VAR (44),
QUEST_EXEC_DEC_QUEST_GLOBAL_VAR (45),
QUEST_EXEC_REGISTER_DYNAMIC_GROUP (46),
QUEST_EXEC_UNREGISTER_DYNAMIC_GROUP (47),
QUEST_EXEC_SET_QUEST_VAR (48),
QUEST_EXEC_INC_QUEST_VAR (49),
QUEST_EXEC_DEC_QUEST_VAR (50),
QUEST_EXEC_RANDOM_QUEST_VAR (51),
QUEST_EXEC_ACTIVATE_SCANNING_PIC (52),
QUEST_EXEC_RELOAD_SCENE_TAG (53),
QUEST_EXEC_REGISTER_DYNAMIC_GROUP_ONLY (54),
QUEST_EXEC_CHANGE_SKILL_DEPOT (55),
QUEST_EXEC_ADD_SCENE_TAG (56),
QUEST_EXEC_DEL_SCENE_TAG (57),
QUEST_EXEC_INIT_TIME_VAR (58),
QUEST_EXEC_CLEAR_TIME_VAR (59),
QUEST_EXEC_MODIFY_CLIMATE_AREA (60),
QUEST_EXEC_GRANT_TRIAL_AVATAR_AND_LOCK_TEAM (61),
QUEST_EXEC_CHANGE_MAP_AREA_STATE (62),
QUEST_EXEC_DEACTIVE_ITEM_GIVING (63),
QUEST_EXEC_CHANGE_SCENE_LEVEL_TAG (64),
QUEST_EXEC_UNLOCK_PLAYER_WORLD_SCENE (65),
QUEST_EXEC_LOCK_PLAYER_WORLD_SCENE (66),
QUEST_EXEC_FAIL_MAINCOOP (67),
QUEST_EXEC_MODIFY_WEATHER_AREA (68);
private final int value;
QuestTrigger(int id) {
this.value = id;
}
public int getValue() {
return value;
}
}
package emu.grasscutter.game.quest.enums;
public enum QuestType {
AQ (0),
FQ (1),
LQ (2),
EQ (3),
DQ (4),
IQ (5),
VQ (6),
WQ (7);
private final int value;
QuestType(int id) {
this.value = id;
}
public int getValue() {
return value;
}
}
package emu.grasscutter.game.quest.enums;
public enum ShowQuestGuideType {
QUEST_GUIDE_ITEM_ENABLE (0),
QUEST_GUIDE_ITEM_DISABLE (1),
QUEST_GUIDE_ITEM_MOVE_HIDE (2);
private final int value;
ShowQuestGuideType(int id) {
this.value = id;
}
public int getValue() {
return value;
}
}
package emu.grasscutter.game.quest.handlers;
import emu.grasscutter.data.def.QuestData.QuestCondition;
import emu.grasscutter.game.quest.GameQuest;
public abstract class QuestBaseHandler {
public abstract boolean execute(GameQuest quest, QuestCondition condition, int... params);
}
...@@ -14,6 +14,8 @@ import emu.grasscutter.game.managers.ChatManager; ...@@ -14,6 +14,8 @@ import emu.grasscutter.game.managers.ChatManager;
import emu.grasscutter.game.managers.InventoryManager; import emu.grasscutter.game.managers.InventoryManager;
import emu.grasscutter.game.managers.MultiplayerManager; import emu.grasscutter.game.managers.MultiplayerManager;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.quest.ServerQuestHandler;
import emu.grasscutter.game.quest.handlers.QuestBaseHandler;
import emu.grasscutter.game.shop.ShopManager; import emu.grasscutter.game.shop.ShopManager;
import emu.grasscutter.game.tower.TowerScheduleManager; import emu.grasscutter.game.tower.TowerScheduleManager;
import emu.grasscutter.game.world.World; import emu.grasscutter.game.world.World;
...@@ -37,6 +39,7 @@ import static emu.grasscutter.Configuration.*; ...@@ -37,6 +39,7 @@ import static emu.grasscutter.Configuration.*;
public final class GameServer extends KcpServer { public final class GameServer extends KcpServer {
private final InetSocketAddress address; private final InetSocketAddress address;
private final GameServerPacketHandler packetHandler; private final GameServerPacketHandler packetHandler;
private final ServerQuestHandler questHandler;
private final Map<Integer, Player> players; private final Map<Integer, Player> players;
private final Set<World> worlds; private final Set<World> worlds;
...@@ -68,6 +71,7 @@ public final class GameServer extends KcpServer { ...@@ -68,6 +71,7 @@ public final class GameServer extends KcpServer {
this.setServerInitializer(new GameServerInitializer(this)); this.setServerInitializer(new GameServerInitializer(this));
this.address = address; this.address = address;
this.packetHandler = new GameServerPacketHandler(PacketHandler.class); this.packetHandler = new GameServerPacketHandler(PacketHandler.class);
this.questHandler = new ServerQuestHandler();
this.players = new ConcurrentHashMap<>(); this.players = new ConcurrentHashMap<>();
this.worlds = Collections.synchronizedSet(new HashSet<>()); this.worlds = Collections.synchronizedSet(new HashSet<>());
...@@ -91,6 +95,10 @@ public final class GameServer extends KcpServer { ...@@ -91,6 +95,10 @@ public final class GameServer extends KcpServer {
return packetHandler; return packetHandler;
} }
public ServerQuestHandler getQuestHandler() {
return questHandler;
}
public Map<Integer, Player> getPlayers() { public Map<Integer, Player> getPlayers() {
return players; return players;
} }
......
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
import emu.grasscutter.game.inventory.GameItem; import emu.grasscutter.game.inventory.GameItem;
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.NpcTalkReqOuterClass.NpcTalkReq; import emu.grasscutter.net.proto.NpcTalkReqOuterClass.NpcTalkReq;
...@@ -15,6 +16,8 @@ public class HandlerNpcTalkReq extends PacketHandler { ...@@ -15,6 +16,8 @@ public class HandlerNpcTalkReq extends PacketHandler {
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
NpcTalkReq req = NpcTalkReq.parseFrom(payload); NpcTalkReq req = NpcTalkReq.parseFrom(payload);
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_COMPLETE_TALK, req.getTalkId());
session.send(new PacketNpcTalkRsp(req.getNpcEntityId(), req.getTalkId(), req.getEntityId())); session.send(new PacketNpcTalkRsp(req.getNpcEntityId(), req.getTalkId(), req.getEntityId()));
} }
......
package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.FinishedParentQuestNotifyOuterClass.FinishedParentQuestNotify;
public class PacketFinishedParentQuestNotify extends BasePacket {
public PacketFinishedParentQuestNotify(Player player) {
super(PacketOpcodes.FinishedParentQuestNotify, true);
FinishedParentQuestNotify.Builder proto = FinishedParentQuestNotify.newBuilder();
for (GameMainQuest mainQuest : player.getQuestManager().getQuests().values()) {
proto.addParentQuestList(mainQuest.toProto());
}
this.setData(proto);
}
}
package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.FinishedParentQuestUpdateNotifyOuterClass.FinishedParentQuestUpdateNotify;
public class PacketFinishedParentQuestUpdateNotify extends BasePacket {
public PacketFinishedParentQuestUpdateNotify(GameMainQuest quest) {
super(PacketOpcodes.FinishedParentQuestUpdateNotify);
FinishedParentQuestUpdateNotify proto = FinishedParentQuestUpdateNotify.newBuilder()
.addParentQuestList(quest.toProto())
.build();
this.setData(proto);
}
}
package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.game.quest.QuestManager;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.QuestListNotifyOuterClass.QuestListNotify;
public class PacketQuestListNotify extends BasePacket {
public PacketQuestListNotify(Player player) {
super(PacketOpcodes.QuestListNotify, true);
QuestListNotify.Builder proto = QuestListNotify.newBuilder();
player.getQuestManager().forEachQuest(quest -> {
proto.addQuestList(quest.toProto());
});
this.setData(proto);
}
}
package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.game.quest.GameQuest;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.QuestListUpdateNotifyOuterClass.QuestListUpdateNotify;
public class PacketQuestListUpdateNotify extends BasePacket {
public PacketQuestListUpdateNotify(GameQuest quest) {
super(PacketOpcodes.QuestListUpdateNotify);
QuestListUpdateNotify proto = QuestListUpdateNotify.newBuilder()
.addQuestList(quest.toProto())
.build();
this.setData(proto);
}
}
package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.game.quest.GameQuest;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.QuestProgressUpdateNotifyOuterClass.QuestProgressUpdateNotify;
public class PacketQuestProgressUpdateNotify extends BasePacket {
public PacketQuestProgressUpdateNotify(GameQuest quest) {
super(PacketOpcodes.QuestProgressUpdateNotify);
QuestProgressUpdateNotify.Builder proto = QuestProgressUpdateNotify.newBuilder().setQuestId(quest.getQuestId());
if (quest.getFinishProgressList() != null) {
for (int i : quest.getFinishProgressList()) {
proto.addFinishProgressList(i);
}
}
if (quest.getFailProgressList() != null) {
for (int i : quest.getFailProgressList()) {
proto.addFailProgressList(i);
}
}
this.setData(proto);
}
}
package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.quest.GameQuest;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.ServerCondMeetQuestListUpdateNotifyOuterClass.ServerCondMeetQuestListUpdateNotify;
public class PacketServerCondMeetQuestListUpdateNotify extends BasePacket {
public PacketServerCondMeetQuestListUpdateNotify(Player player) {
super(PacketOpcodes.ServerCondMeetQuestListUpdateNotify);
ServerCondMeetQuestListUpdateNotify.Builder proto = ServerCondMeetQuestListUpdateNotify.newBuilder();
player.getQuestManager().forEachQuest(quest -> {
if (quest.getState().getValue() <= 2) {
proto.addAddQuestIdList(quest.getQuestId());
}
});
this.setData(proto);
}
public PacketServerCondMeetQuestListUpdateNotify(GameQuest quest) {
super(PacketOpcodes.ServerCondMeetQuestListUpdateNotify);
ServerCondMeetQuestListUpdateNotify proto = ServerCondMeetQuestListUpdateNotify.newBuilder()
.addAddQuestIdList(quest.getQuestId())
.build();
this.setData(proto);
}
}
...@@ -19,9 +19,11 @@ import emu.grasscutter.command.Command; ...@@ -19,9 +19,11 @@ import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandMap; import emu.grasscutter.command.CommandMap;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.ResourceLoader; import emu.grasscutter.data.ResourceLoader;
import emu.grasscutter.data.custom.MainQuestData;
import emu.grasscutter.data.def.AvatarData; import emu.grasscutter.data.def.AvatarData;
import emu.grasscutter.data.def.ItemData; import emu.grasscutter.data.def.ItemData;
import emu.grasscutter.data.def.MonsterData; import emu.grasscutter.data.def.MonsterData;
import emu.grasscutter.data.def.QuestData;
import emu.grasscutter.data.def.SceneData; import emu.grasscutter.data.def.SceneData;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
...@@ -88,7 +90,7 @@ public final class Tools { ...@@ -88,7 +90,7 @@ public final class Tools {
final class ToolsWithLanguageOption { final class ToolsWithLanguageOption {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public static void createGmHandbook(String language) throws Exception { public static void createGmHandbook(String language) throws Exception {
ResourceLoader.loadResources(); ResourceLoader.loadAll();
Map<Long, String> map; Map<Long, String> map;
try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(RESOURCE("TextMap/TextMap"+language+".json"))), StandardCharsets.UTF_8)) { try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(RESOURCE("TextMap/TextMap"+language+".json"))), StandardCharsets.UTF_8)) {
...@@ -150,6 +152,18 @@ final class ToolsWithLanguageOption { ...@@ -150,6 +152,18 @@ final class ToolsWithLanguageOption {
writer.println(); writer.println();
writer.println("// Quests");
list = new ArrayList<>(GameData.getQuestDataMap().keySet());
Collections.sort(list);
for (Integer id : list) {
QuestData data = GameData.getQuestDataMap().get(id);
MainQuestData mainQuest = GameData.getMainQuestDataMap().get(data.getMainId());
writer.println(data.getId() + " : " + map.get(mainQuest.getTitleTextMapHash()) + " - " + map.get(data.getDescTextMapHash()));
}
writer.println();
writer.println("// Monsters"); writer.println("// Monsters");
list = new ArrayList<>(GameData.getMonsterDataMap().keySet()); list = new ArrayList<>(GameData.getMonsterDataMap().keySet());
Collections.sort(list); Collections.sort(list);
......
...@@ -215,6 +215,14 @@ ...@@ -215,6 +215,14 @@
"success": "Coordinates: %s, %s, %s\nScene id: %s", "success": "Coordinates: %s, %s, %s\nScene id: %s",
"description": "Get coordinates." "description": "Get coordinates."
}, },
"quest": {
"description": "Add or finish quests",
"usage": "quest <add|finish> [quest id]",
"added": "Quest %s added",
"finished": "Finished quest %s",
"not_found": "Quest not found",
"invalid_id": "Invalid quest id"
},
"reload": { "reload": {
"reload_start": "Reloading config.", "reload_start": "Reloading config.",
"reload_done": "Reload complete.", "reload_done": "Reload complete.",
......
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