mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-23 07:10:46 +00:00
Implement quests
This commit is contained in:
parent
ef9d63f1dd
commit
285405cee4
9
proto/ChildQuest.proto
Normal file
9
proto/ChildQuest.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message ChildQuest {
|
||||
uint32 quest_id = 1;
|
||||
uint32 state = 2;
|
||||
uint32 quest_config_id = 3;
|
||||
}
|
8
proto/CutSceneBeginNotify.proto
Normal file
8
proto/CutSceneBeginNotify.proto
Normal file
@ -0,0 +1,8 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message CutSceneBeginNotify {
|
||||
uint32 cutscene_id = 1;
|
||||
bool is_wait_others = 2;
|
||||
}
|
8
proto/CutSceneEndNotify.proto
Normal file
8
proto/CutSceneEndNotify.proto
Normal file
@ -0,0 +1,8 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message CutSceneEndNotify {
|
||||
int32 retcode = 1;
|
||||
uint32 cutscene_id = 2;
|
||||
}
|
7
proto/CutSceneFinishNotify.proto
Normal file
7
proto/CutSceneFinishNotify.proto
Normal file
@ -0,0 +1,7 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message CutSceneFinishNotify {
|
||||
uint32 cutscene_id = 1;
|
||||
}
|
9
proto/FinishedParentQuestNotify.proto
Normal file
9
proto/FinishedParentQuestNotify.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
import "ParentQuest.proto";
|
||||
|
||||
message FinishedParentQuestNotify {
|
||||
repeated ParentQuest parent_quest_list = 1;
|
||||
}
|
9
proto/FinishedParentQuestUpdateNotify.proto
Normal file
9
proto/FinishedParentQuestUpdateNotify.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
import "ParentQuest.proto";
|
||||
|
||||
message FinishedParentQuestUpdateNotify {
|
||||
repeated ParentQuest parent_quest_list = 1;
|
||||
}
|
18
proto/ParentQuest.proto
Normal file
18
proto/ParentQuest.proto
Normal file
@ -0,0 +1,18 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
import "ParentQuestRandomInfo.proto";
|
||||
import "ChildQuest.proto";
|
||||
|
||||
message ParentQuest {
|
||||
uint32 parent_quest_id = 1;
|
||||
repeated ChildQuest child_quest_list = 2;
|
||||
bool is_finished = 3;
|
||||
bool is_random = 4;
|
||||
ParentQuestRandomInfo random_info = 5;
|
||||
repeated int32 quest_var = 6;
|
||||
uint32 parent_quest_state = 7;
|
||||
uint32 quest_var_seq = 8;
|
||||
map<uint32, uint32> time_var_map = 9;
|
||||
}
|
9
proto/ParentQuestRandomInfo.proto
Normal file
9
proto/ParentQuestRandomInfo.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message ParentQuestRandomInfo {
|
||||
uint32 entrance_id = 1;
|
||||
uint32 template_id = 2;
|
||||
repeated uint32 factor_list = 3;
|
||||
}
|
20
proto/Quest.proto
Normal file
20
proto/Quest.proto
Normal file
@ -0,0 +1,20 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message Quest {
|
||||
uint32 quest_id = 1;
|
||||
uint32 state = 2;
|
||||
uint32 start_time = 4;
|
||||
bool is_random = 5;
|
||||
uint32 parent_quest_id = 6;
|
||||
uint32 quest_config_id = 7;
|
||||
uint32 start_game_time = 8;
|
||||
uint32 accept_time = 9;
|
||||
repeated uint32 lacked_npc_list = 10;
|
||||
repeated uint32 finish_progress_list = 11;
|
||||
repeated uint32 fail_progress_list = 12;
|
||||
map<uint32, uint32> lacked_npc_map = 13;
|
||||
repeated uint32 lacked_place_list = 14;
|
||||
map<uint32, uint32> lacked_place_map = 15;
|
||||
}
|
7
proto/QuestDelNotify.proto
Normal file
7
proto/QuestDelNotify.proto
Normal file
@ -0,0 +1,7 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message QuestDelNotify {
|
||||
uint32 quest_id = 1;
|
||||
}
|
8
proto/QuestGlobalVar.proto
Normal file
8
proto/QuestGlobalVar.proto
Normal file
@ -0,0 +1,8 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message QuestGlobalVar {
|
||||
uint32 key = 1;
|
||||
int32 value = 2;
|
||||
}
|
9
proto/QuestGlobalVarNotify.proto
Normal file
9
proto/QuestGlobalVarNotify.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
import "QuestGlobalVar.proto";
|
||||
|
||||
message QuestGlobalVarNotify {
|
||||
repeated QuestGlobalVar var_list = 1;
|
||||
}
|
9
proto/QuestListNotify.proto
Normal file
9
proto/QuestListNotify.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
import "Quest.proto";
|
||||
|
||||
message QuestListNotify {
|
||||
repeated Quest quest_list = 1;
|
||||
}
|
9
proto/QuestListUpdateNotify.proto
Normal file
9
proto/QuestListUpdateNotify.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
import "Quest.proto";
|
||||
|
||||
message QuestListUpdateNotify {
|
||||
repeated Quest quest_list = 1;
|
||||
}
|
9
proto/QuestProgressUpdateNotify.proto
Normal file
9
proto/QuestProgressUpdateNotify.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message QuestProgressUpdateNotify {
|
||||
uint32 quest_id = 1;
|
||||
repeated uint32 finish_progress_list = 2;
|
||||
repeated uint32 fail_progress_list = 3;
|
||||
}
|
9
proto/QuestUpdateQuestVarNotify.proto
Normal file
9
proto/QuestUpdateQuestVarNotify.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message QuestUpdateQuestVarNotify {
|
||||
uint32 parent_quest_id = 1;
|
||||
repeated int32 quest_var = 2;
|
||||
uint32 parent_quest_var_seq = 3;
|
||||
}
|
12
proto/QuestUpdateQuestVarReq.proto
Normal file
12
proto/QuestUpdateQuestVarReq.proto
Normal file
@ -0,0 +1,12 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
import "QuestVarOp.proto";
|
||||
|
||||
message QuestUpdateQuestVarReq {
|
||||
uint32 quest_id = 1;
|
||||
repeated QuestVarOp quest_var_op_list = 2;
|
||||
uint32 parent_quest_id = 3;
|
||||
uint32 parent_quest_var_seq = 4;
|
||||
}
|
10
proto/QuestUpdateQuestVarRsp.proto
Normal file
10
proto/QuestUpdateQuestVarRsp.proto
Normal file
@ -0,0 +1,10 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message QuestUpdateQuestVarRsp {
|
||||
int32 retcode = 1;
|
||||
uint32 quest_id = 2;
|
||||
uint32 parent_quest_id = 3;
|
||||
uint32 parent_quest_var_seq = 4;
|
||||
}
|
9
proto/QuestVarOp.proto
Normal file
9
proto/QuestVarOp.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message QuestVarOp {
|
||||
uint32 index = 1;
|
||||
int32 value = 2;
|
||||
bool is_add = 3;
|
||||
}
|
8
proto/ServerCondMeetQuestListUpdateNotify.proto
Normal file
8
proto/ServerCondMeetQuestListUpdateNotify.proto
Normal file
@ -0,0 +1,8 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "emu.grasscutter.net.proto";
|
||||
|
||||
message ServerCondMeetQuestListUpdateNotify {
|
||||
repeated uint32 add_quest_id_list = 1;
|
||||
repeated uint32 del_quest_id_list = 2;
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.GameQuest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "quest", usage = "quest <add|finish> [quest id]", permission = "player.quest", permissionTargeted = "player.quest.others", description = "commands.quest.description")
|
||||
public final class QuestCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.size() != 2) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.quest.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
String cmd = args.get(0).toLowerCase();
|
||||
int questId;
|
||||
|
||||
try {
|
||||
questId = Integer.parseInt(args.get(1));
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.quest.invalid_id"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case "add" -> {
|
||||
GameQuest quest = sender.getQuestManager().addQuest(questId);
|
||||
|
||||
if (quest != null) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.quest.added", questId));
|
||||
return;
|
||||
}
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.quest.not_found"));
|
||||
}
|
||||
case "finish" -> {
|
||||
GameQuest quest = sender.getQuestManager().getQuestById(questId);
|
||||
|
||||
if (quest == null) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.quest.not_found"));
|
||||
return;
|
||||
}
|
||||
|
||||
quest.finish();
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.quest.finished", questId));
|
||||
}
|
||||
default -> {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.quest.usage"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ import emu.grasscutter.data.custom.AbilityEmbryoEntry;
|
||||
import emu.grasscutter.data.custom.AbilityModifier;
|
||||
import emu.grasscutter.data.custom.AbilityModifierEntry;
|
||||
import emu.grasscutter.data.custom.OpenConfigEntry;
|
||||
import emu.grasscutter.data.custom.QuestConfig;
|
||||
import emu.grasscutter.data.custom.ScenePointEntry;
|
||||
import emu.grasscutter.data.def.*;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
|
||||
@ -27,6 +28,7 @@ public class GameData {
|
||||
private static final Map<String, AbilityModifierEntry> abilityModifiers = new HashMap<>();
|
||||
private static final Map<String, OpenConfigEntry> openConfigEntries = new HashMap<>();
|
||||
private static final Map<String, ScenePointEntry> scenePointEntries = new HashMap<>();
|
||||
private static final Int2ObjectMap<QuestConfig> questConfigs = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
// ExcelConfigs
|
||||
private static final Int2ObjectMap<PlayerLevelData> playerLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@ -122,6 +124,10 @@ public class GameData {
|
||||
return getScenePointEntries().get(sceneId + "_" + pointId);
|
||||
}
|
||||
|
||||
public static Int2ObjectMap<QuestConfig> getQuestConfigs() {
|
||||
return questConfigs;
|
||||
}
|
||||
|
||||
public static Int2ObjectMap<AvatarData> getAvatarDataMap() {
|
||||
return avatarDataMap;
|
||||
}
|
||||
|
@ -24,6 +24,9 @@ import emu.grasscutter.data.custom.AbilityModifier.AbilityModifierAction;
|
||||
import emu.grasscutter.data.custom.AbilityModifier.AbilityModifierActionType;
|
||||
import emu.grasscutter.data.custom.AbilityModifierEntry;
|
||||
import emu.grasscutter.data.custom.OpenConfigEntry;
|
||||
import emu.grasscutter.data.custom.QuestConfig;
|
||||
import emu.grasscutter.data.custom.QuestConfigData;
|
||||
import emu.grasscutter.data.custom.QuestConfigData.SubQuestConfigData;
|
||||
import emu.grasscutter.data.custom.ScenePointEntry;
|
||||
import emu.grasscutter.game.world.SpawnDataEntry;
|
||||
import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
|
||||
@ -57,8 +60,9 @@ public class ResourceLoader {
|
||||
loadResources();
|
||||
// Process into depots
|
||||
GameDepot.load();
|
||||
// Load spawn data
|
||||
// Load spawn data and quests
|
||||
loadSpawnData();
|
||||
loadQuests();
|
||||
// Load scene points - must be done AFTER resources are loaded
|
||||
loadScenePoints();
|
||||
// Custom - TODO move this somewhere else
|
||||
@ -396,6 +400,34 @@ public class ResourceLoader {
|
||||
GameData.getOpenConfigEntries().put(entry.getName(), entry);
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadQuests() {
|
||||
File folder = new File(Grasscutter.getConfig().RESOURCE_FOLDER + "BinOutput/Quest/");
|
||||
|
||||
if (!folder.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (File file : folder.listFiles()) {
|
||||
QuestConfigData mainQuest = null;
|
||||
|
||||
try (FileReader fileReader = new FileReader(file)) {
|
||||
mainQuest = Grasscutter.getGsonFactory().fromJson(fileReader, QuestConfigData.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mainQuest.getSubQuests() != null) {
|
||||
for (SubQuestConfigData subQuest : mainQuest.getSubQuests()) {
|
||||
QuestConfig quest = new QuestConfig(mainQuest, subQuest);
|
||||
GameData.getQuestConfigs().put(quest.getId(), quest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Grasscutter.getLogger().info("Loaded " + GameData.getQuestConfigs().size() + " Quest Configs");
|
||||
}
|
||||
|
||||
// BinOutput configs
|
||||
|
||||
|
25
src/main/java/emu/grasscutter/data/custom/QuestConfig.java
Normal file
25
src/main/java/emu/grasscutter/data/custom/QuestConfig.java
Normal file
@ -0,0 +1,25 @@
|
||||
package emu.grasscutter.data.custom;
|
||||
|
||||
import emu.grasscutter.data.custom.QuestConfigData.SubQuestConfigData;
|
||||
|
||||
public class QuestConfig {
|
||||
private final QuestConfigData mainQuest;
|
||||
private final SubQuestConfigData subQuest;
|
||||
|
||||
public QuestConfig(QuestConfigData mainQuest, SubQuestConfigData subQuest) {
|
||||
this.mainQuest = mainQuest;
|
||||
this.subQuest = subQuest;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return subQuest.getSubId();
|
||||
}
|
||||
|
||||
public QuestConfigData getMainQuest() {
|
||||
return mainQuest;
|
||||
}
|
||||
|
||||
public SubQuestConfigData getSubQuest() {
|
||||
return subQuest;
|
||||
}
|
||||
}
|
104
src/main/java/emu/grasscutter/data/custom/QuestConfigData.java
Normal file
104
src/main/java/emu/grasscutter/data/custom/QuestConfigData.java
Normal file
@ -0,0 +1,104 @@
|
||||
package emu.grasscutter.data.custom;
|
||||
|
||||
import emu.grasscutter.game.quest.enums.LogicType;
|
||||
import emu.grasscutter.game.quest.enums.QuestCondType;
|
||||
import emu.grasscutter.game.quest.enums.QuestType;
|
||||
|
||||
public class QuestConfigData {
|
||||
private int id;
|
||||
private int series;
|
||||
private QuestType type;
|
||||
|
||||
private long titleTextMapHash;
|
||||
private int[] suggestTrackMainQuestList;
|
||||
private int[] rewardIdList;
|
||||
|
||||
private SubQuestConfigData[] subQuests;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getSeries() {
|
||||
return series;
|
||||
}
|
||||
|
||||
public QuestType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public long getTitleTextMapHash() {
|
||||
return titleTextMapHash;
|
||||
}
|
||||
|
||||
public int[] getSuggestTrackMainQuestList() {
|
||||
return suggestTrackMainQuestList;
|
||||
}
|
||||
|
||||
public int[] getRewardIdList() {
|
||||
return rewardIdList;
|
||||
}
|
||||
|
||||
public SubQuestConfigData[] getSubQuests() {
|
||||
return subQuests;
|
||||
}
|
||||
|
||||
public class SubQuestConfigData {
|
||||
private int subId;
|
||||
private int mainId;
|
||||
|
||||
private LogicType acceptCondComb;
|
||||
private QuestCondition[] acceptCond;
|
||||
|
||||
private LogicType finishCondComb;
|
||||
private QuestCondition[] finishCond;
|
||||
|
||||
private LogicType failCondComb;
|
||||
private QuestCondition[] failCond;
|
||||
|
||||
public int getSubId() {
|
||||
return subId;
|
||||
}
|
||||
|
||||
public int getMainId() {
|
||||
return mainId;
|
||||
}
|
||||
|
||||
public LogicType getAcceptCondComb() {
|
||||
return acceptCondComb;
|
||||
}
|
||||
|
||||
public QuestCondition[] getAcceptCond() {
|
||||
return acceptCond;
|
||||
}
|
||||
|
||||
public LogicType getFinishCondComb() {
|
||||
return finishCondComb;
|
||||
}
|
||||
|
||||
public QuestCondition[] getFinishCond() {
|
||||
return finishCond;
|
||||
}
|
||||
|
||||
public LogicType getFailCondComb() {
|
||||
return failCondComb;
|
||||
}
|
||||
|
||||
public QuestCondition[] getFailCond() {
|
||||
return failCond;
|
||||
}
|
||||
}
|
||||
|
||||
public class QuestCondition {
|
||||
private QuestCondType type;
|
||||
private int[] param;
|
||||
|
||||
public QuestCondType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int[] getParam() {
|
||||
return param;
|
||||
}
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ import emu.grasscutter.game.gacha.GachaRecord;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.mail.Mail;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.GameMainQuest;
|
||||
|
||||
import static com.mongodb.client.model.Filters.eq;
|
||||
|
||||
@ -111,6 +112,8 @@ public final class DatabaseHelper {
|
||||
DatabaseManager.getDatabase().getCollection("gachas").deleteMany(eq("ownerId", target.getPlayerUid()));
|
||||
// Delete GameItem.class data
|
||||
DatabaseManager.getDatabase().getCollection("items").deleteMany(eq("ownerId", target.getPlayerUid()));
|
||||
// Delete GameMainQuest.class data
|
||||
DatabaseManager.getDatabase().getCollection("quests").deleteMany(eq("ownerUid", target.getPlayerUid()));
|
||||
|
||||
// Delete friendships.
|
||||
// Here, we need to make sure to not only delete the deleted account's friendships,
|
||||
@ -260,4 +263,16 @@ public final class DatabaseHelper {
|
||||
DeleteResult result = DatabaseManager.getDatastore().delete(mail);
|
||||
return result.wasAcknowledged();
|
||||
}
|
||||
|
||||
public static List<GameMainQuest> getAllQuests(Player player) {
|
||||
return DatabaseManager.getDatastore().find(GameMainQuest.class).filter(Filters.eq("ownerUid", player.getUid())).stream().toList();
|
||||
}
|
||||
|
||||
public static void saveQuest(GameMainQuest quest) {
|
||||
DatabaseManager.getDatastore().save(quest);
|
||||
}
|
||||
|
||||
public static boolean deleteQuest(GameMainQuest quest) {
|
||||
return DatabaseManager.getDatastore().delete(quest).wasAcknowledged();
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ import emu.grasscutter.game.gacha.GachaRecord;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.mail.Mail;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.GameMainQuest;
|
||||
import emu.grasscutter.game.quest.GameQuest;
|
||||
|
||||
public final class DatabaseManager {
|
||||
|
||||
@ -30,7 +32,8 @@ public final class DatabaseManager {
|
||||
private static Datastore dispatchDatastore;
|
||||
|
||||
private static final Class<?>[] mappedClasses = new Class<?>[] {
|
||||
DatabaseCounter.class, Account.class, Player.class, Avatar.class, GameItem.class, Friendship.class, GachaRecord.class, Mail.class
|
||||
DatabaseCounter.class, Account.class, Player.class, Avatar.class, GameItem.class, Friendship.class,
|
||||
GachaRecord.class, Mail.class, GameMainQuest.class
|
||||
};
|
||||
|
||||
public static Datastore getDatastore() {
|
||||
|
@ -29,6 +29,9 @@ import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.EntityType;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.props.SceneType;
|
||||
import emu.grasscutter.game.quest.GameMainQuest;
|
||||
import emu.grasscutter.game.quest.GameQuest;
|
||||
import emu.grasscutter.game.quest.QuestManager;
|
||||
import emu.grasscutter.game.shop.ShopLimit;
|
||||
import emu.grasscutter.game.managers.MapMarkManager.*;
|
||||
import emu.grasscutter.game.tower.TowerManager;
|
||||
@ -91,6 +94,7 @@ public class Player {
|
||||
@Transient private MailHandler mailHandler;
|
||||
@Transient private MessageHandler messageHandler;
|
||||
@Transient private AbilityManager abilityManager;
|
||||
@Transient private QuestManager questManager;
|
||||
|
||||
@Transient private SotSManager sotsManager;
|
||||
|
||||
@ -145,6 +149,7 @@ public class Player {
|
||||
this.mailHandler = new MailHandler(this);
|
||||
this.towerManager = new TowerManager(this);
|
||||
this.abilityManager = new AbilityManager(this);
|
||||
this.setQuestManager(new QuestManager(this));
|
||||
this.pos = new Position();
|
||||
this.rotation = new Position();
|
||||
this.properties = new HashMap<>();
|
||||
@ -409,6 +414,14 @@ public class Player {
|
||||
return towerManager;
|
||||
}
|
||||
|
||||
public QuestManager getQuestManager() {
|
||||
return questManager;
|
||||
}
|
||||
|
||||
public void setQuestManager(QuestManager questManager) {
|
||||
this.questManager = questManager;
|
||||
}
|
||||
|
||||
public PlayerGachaInfo getGachaInfo() {
|
||||
return gachaInfo;
|
||||
}
|
||||
@ -883,9 +896,7 @@ public class Player {
|
||||
}
|
||||
|
||||
public void sendPacket(BasePacket packet) {
|
||||
if (this.hasSentAvatarDataNotify) {
|
||||
this.getSession().send(packet);
|
||||
}
|
||||
this.getSession().send(packet);
|
||||
}
|
||||
|
||||
public OnlinePlayerInfo getOnlinePlayerInfo() {
|
||||
@ -1118,7 +1129,23 @@ public class Player {
|
||||
|
||||
this.getFriendsList().loadFromDatabase();
|
||||
this.getMailHandler().loadFromDatabase();
|
||||
this.getQuestManager().loadFromDatabase();
|
||||
|
||||
// Quest - Commented out because a problem is caused if you log out while this quest is active
|
||||
/*
|
||||
if (getQuestManager().getMainQuestById(351) == null) {
|
||||
GameQuest quest = getQuestManager().addQuest(35104);
|
||||
if (quest != null) {
|
||||
quest.finish();
|
||||
}
|
||||
|
||||
getQuestManager().addQuest(35101);
|
||||
|
||||
this.setSceneId(3);
|
||||
this.getPos().set(GameConstants.START_POSITION);
|
||||
}
|
||||
*/
|
||||
|
||||
// Create world
|
||||
World world = new World(this);
|
||||
world.addPlayer(this);
|
||||
@ -1138,7 +1165,10 @@ public class Player {
|
||||
session.send(new PacketStoreWeightLimitNotify());
|
||||
session.send(new PacketPlayerStoreNotify(this));
|
||||
session.send(new PacketAvatarDataNotify(this));
|
||||
|
||||
session.send(new PacketFinishedParentQuestNotify(this));
|
||||
session.send(new PacketQuestListNotify(this));
|
||||
session.send(new PacketServerCondMeetQuestListUpdateNotify(this));
|
||||
|
||||
getTodayMoonCard(); // The timer works at 0:0, some users log in after that, use this method to check if they have received a reward today or not. If not, send the reward.
|
||||
|
||||
session.send(new PacketPlayerEnterSceneNotify(this)); // Enter game world
|
||||
|
124
src/main/java/emu/grasscutter/game/quest/GameMainQuest.java
Normal file
124
src/main/java/emu/grasscutter/game/quest/GameMainQuest.java
Normal file
@ -0,0 +1,124 @@
|
||||
package emu.grasscutter.game.quest;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Id;
|
||||
import dev.morphia.annotations.Indexed;
|
||||
import dev.morphia.annotations.Transient;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.custom.QuestConfig;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.enums.ParentQuestState;
|
||||
import emu.grasscutter.game.quest.enums.QuestState;
|
||||
import emu.grasscutter.net.proto.ChildQuestOuterClass.ChildQuest;
|
||||
import emu.grasscutter.net.proto.ParentQuestOuterClass.ParentQuest;
|
||||
import emu.grasscutter.net.proto.QuestOuterClass.Quest;
|
||||
import emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
@Entity(value = "quests", useDiscriminator = false)
|
||||
public class GameMainQuest {
|
||||
@Id private ObjectId id;
|
||||
|
||||
@Indexed private int ownerUid;
|
||||
@Transient private Player owner;
|
||||
|
||||
private Map<Integer, GameQuest> childQuests;
|
||||
|
||||
private int parentQuestId;
|
||||
private int[] questVars;
|
||||
private ParentQuestState state;
|
||||
private boolean isFinished;
|
||||
|
||||
@Deprecated // Morphia only. Do not use.
|
||||
public GameMainQuest() {}
|
||||
|
||||
public GameMainQuest(Player player, int parentQuestId) {
|
||||
this.owner = player;
|
||||
this.ownerUid = player.getUid();
|
||||
this.parentQuestId = parentQuestId;
|
||||
this.childQuests = new HashMap<>();
|
||||
this.questVars = new int[5];
|
||||
this.state = ParentQuestState.PARENT_QUEST_STATE_NONE;
|
||||
}
|
||||
|
||||
public int getParentQuestId() {
|
||||
return parentQuestId;
|
||||
}
|
||||
|
||||
public int getOwnerUid() {
|
||||
return ownerUid;
|
||||
}
|
||||
|
||||
public Player getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setOwner(Player player) {
|
||||
if (player.getUid() != this.getOwnerUid()) return;
|
||||
this.owner = player;
|
||||
}
|
||||
|
||||
public Map<Integer, GameQuest> getChildQuests() {
|
||||
return childQuests;
|
||||
}
|
||||
|
||||
public GameQuest getChildQuestById(int id) {
|
||||
return this.getChildQuests().get(id);
|
||||
}
|
||||
|
||||
public int[] getQuestVars() {
|
||||
return questVars;
|
||||
}
|
||||
|
||||
public ParentQuestState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return isFinished;
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
this.isFinished = true;
|
||||
this.state = ParentQuestState.PARENT_QUEST_STATE_FINISHED;
|
||||
this.getOwner().getSession().send(new PacketFinishedParentQuestUpdateNotify(this));
|
||||
}
|
||||
|
||||
public void save() {
|
||||
DatabaseHelper.saveQuest(this);
|
||||
}
|
||||
|
||||
public ParentQuest toProto() {
|
||||
ParentQuest.Builder proto = ParentQuest.newBuilder()
|
||||
.setParentQuestId(getParentQuestId())
|
||||
.setIsFinished(isFinished())
|
||||
.setParentQuestState(getState().getValue());
|
||||
|
||||
for (GameQuest quest : this.getChildQuests().values()) {
|
||||
ChildQuest childQuest = ChildQuest.newBuilder()
|
||||
.setQuestId(quest.getQuestId())
|
||||
.setState(quest.getState().getValue())
|
||||
.build();
|
||||
|
||||
proto.addChildQuestList(childQuest);
|
||||
}
|
||||
|
||||
if (getQuestVars() != null) {
|
||||
for (int i : getQuestVars()) {
|
||||
proto.addQuestVar(i);
|
||||
}
|
||||
}
|
||||
|
||||
return proto.build();
|
||||
}
|
||||
}
|
188
src/main/java/emu/grasscutter/game/quest/GameQuest.java
Normal file
188
src/main/java/emu/grasscutter/game/quest/GameQuest.java
Normal file
@ -0,0 +1,188 @@
|
||||
package emu.grasscutter.game.quest;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Transient;
|
||||
import emu.grasscutter.data.custom.QuestConfig;
|
||||
import emu.grasscutter.data.custom.QuestConfigData.SubQuestConfigData;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.enums.QuestState;
|
||||
import emu.grasscutter.net.proto.QuestOuterClass.Quest;
|
||||
import emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
|
||||
@Entity
|
||||
public class GameQuest {
|
||||
@Transient private GameMainQuest mainQuest;
|
||||
@Transient private QuestConfig config;
|
||||
|
||||
private int questId;
|
||||
private int mainQuestId;
|
||||
private QuestState state;
|
||||
|
||||
private int startTime;
|
||||
private int acceptTime;
|
||||
private int finishTime;
|
||||
|
||||
private int[] finishProgressList;
|
||||
private int[] failProgressList;
|
||||
|
||||
@Deprecated // Morphia only. Do not use.
|
||||
public GameQuest() {}
|
||||
|
||||
public GameQuest(GameMainQuest mainQuest, QuestConfig config) {
|
||||
this.mainQuest = mainQuest;
|
||||
this.questId = config.getId();
|
||||
this.mainQuestId = config.getMainQuest().getId();
|
||||
this.config = config;
|
||||
this.acceptTime = Utils.getCurrentSeconds();
|
||||
this.startTime = this.acceptTime;
|
||||
this.state = QuestState.QUEST_STATE_UNFINISHED;
|
||||
|
||||
if (config.getSubQuest().getFinishCond() != null) {
|
||||
this.finishProgressList = new int[config.getSubQuest().getFinishCond().length];
|
||||
}
|
||||
|
||||
if (config.getSubQuest().getFailCond() != null) {
|
||||
this.failProgressList = new int[config.getSubQuest().getFailCond().length];
|
||||
}
|
||||
|
||||
this.mainQuest.getChildQuests().put(this.questId, this);
|
||||
}
|
||||
|
||||
public GameMainQuest getMainQuest() {
|
||||
return mainQuest;
|
||||
}
|
||||
|
||||
public void setMainQuest(GameMainQuest mainQuest) {
|
||||
this.mainQuest = mainQuest;
|
||||
}
|
||||
|
||||
public Player getOwner() {
|
||||
return getMainQuest().getOwner();
|
||||
}
|
||||
|
||||
public int getQuestId() {
|
||||
return questId;
|
||||
}
|
||||
|
||||
public int getMainQuestId() {
|
||||
return mainQuestId;
|
||||
}
|
||||
|
||||
public QuestConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public void setConfig(QuestConfig config) {
|
||||
if (this.getQuestId() != config.getId()) return;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public QuestState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(QuestState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public int getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(int startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public int getAcceptTime() {
|
||||
return acceptTime;
|
||||
}
|
||||
|
||||
public void setAcceptTime(int acceptTime) {
|
||||
this.acceptTime = acceptTime;
|
||||
}
|
||||
|
||||
public int getFinishTime() {
|
||||
return finishTime;
|
||||
}
|
||||
|
||||
public void setFinishTime(int finishTime) {
|
||||
this.finishTime = finishTime;
|
||||
}
|
||||
|
||||
public int[] getFinishProgressList() {
|
||||
return finishProgressList;
|
||||
}
|
||||
|
||||
public void setFinishProgress(int index, int value) {
|
||||
finishProgressList[index] = value;
|
||||
}
|
||||
|
||||
public int[] getFailProgressList() {
|
||||
return failProgressList;
|
||||
}
|
||||
|
||||
public void setFailProgress(int index, int value) {
|
||||
failProgressList[index] = value;
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
this.state = QuestState.QUEST_STATE_FINISHED;
|
||||
this.finishTime = Utils.getCurrentSeconds();
|
||||
|
||||
if (this.getFinishProgressList() != null) {
|
||||
for (int i = 0 ; i < getFinishProgressList().length; i++) {
|
||||
getFinishProgressList()[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
this.getOwner().getSession().send(new PacketQuestProgressUpdateNotify(this));
|
||||
|
||||
// Finish main quest if all child quests are done
|
||||
this.tryFinishMainQuest();
|
||||
this.save();
|
||||
}
|
||||
|
||||
public boolean tryFinishMainQuest() {
|
||||
try {
|
||||
SubQuestConfigData subQuestData = getConfig().getMainQuest().getSubQuests()[getConfig().getMainQuest().getSubQuests().length - 1];
|
||||
|
||||
if (subQuestData.getSubId() == this.getQuestId()) {
|
||||
getMainQuest().finish();
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void save() {
|
||||
getMainQuest().save();
|
||||
}
|
||||
|
||||
public Quest toProto() {
|
||||
Quest.Builder proto = Quest.newBuilder()
|
||||
.setQuestId(this.getQuestId())
|
||||
.setState(this.getState().getValue())
|
||||
.setParentQuestId(this.getMainQuestId())
|
||||
.setStartTime(this.getStartTime())
|
||||
.setStartGameTime(438)
|
||||
.setAcceptTime(this.getAcceptTime());
|
||||
|
||||
if (this.getFinishProgressList() != null) {
|
||||
for (int i : this.getFinishProgressList()) {
|
||||
proto.addFinishProgressList(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getFailProgressList() != null) {
|
||||
for (int i : this.getFailProgressList()) {
|
||||
proto.addFailProgressList(i);
|
||||
}
|
||||
}
|
||||
|
||||
return proto.build();
|
||||
}
|
||||
}
|
119
src/main/java/emu/grasscutter/game/quest/QuestManager.java
Normal file
119
src/main/java/emu/grasscutter/game/quest/QuestManager.java
Normal file
@ -0,0 +1,119 @@
|
||||
package emu.grasscutter.game.quest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.custom.QuestConfig;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.enums.QuestState;
|
||||
import emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketServerCondMeetQuestListUpdateNotify;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
public class QuestManager {
|
||||
private final Player player;
|
||||
private final Int2ObjectMap<GameMainQuest> quests;
|
||||
|
||||
public QuestManager(Player player) {
|
||||
this.player = player;
|
||||
this.quests = new Int2ObjectOpenHashMap<>();
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public Int2ObjectMap<GameMainQuest> getQuests() {
|
||||
return quests;
|
||||
}
|
||||
|
||||
public GameMainQuest getMainQuestById(int mainQuestId) {
|
||||
return getQuests().get(mainQuestId);
|
||||
}
|
||||
|
||||
public GameQuest getQuestById(int questId) {
|
||||
QuestConfig questConfig = GameData.getQuestConfigs().get(questId);
|
||||
if (questConfig == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
GameMainQuest mainQuest = getQuests().get(questConfig.getMainQuest().getId());
|
||||
|
||||
if (mainQuest == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return mainQuest.getChildQuests().get(questId);
|
||||
}
|
||||
|
||||
public void forEachQuest(Consumer<GameQuest> callback) {
|
||||
for (GameMainQuest mainQuest : getQuests().values()) {
|
||||
for (GameQuest quest : mainQuest.getChildQuests().values()) {
|
||||
callback.accept(quest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GameMainQuest addMainQuest(QuestConfig questConfig) {
|
||||
GameMainQuest mainQuest = new GameMainQuest(getPlayer(), questConfig.getMainQuest().getId());
|
||||
getQuests().put(mainQuest.getParentQuestId(), mainQuest);
|
||||
|
||||
getPlayer().sendPacket(new PacketFinishedParentQuestUpdateNotify(mainQuest));
|
||||
|
||||
return mainQuest;
|
||||
}
|
||||
|
||||
public GameQuest addQuest(int questId) {
|
||||
QuestConfig questConfig = GameData.getQuestConfigs().get(questId);
|
||||
if (questConfig == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Main quest
|
||||
GameMainQuest mainQuest = this.getMainQuestById(questConfig.getMainQuest().getId());
|
||||
|
||||
// Create main quest if it doesnt exist
|
||||
if (mainQuest == null) {
|
||||
mainQuest = addMainQuest(questConfig);
|
||||
}
|
||||
|
||||
// Sub quest
|
||||
GameQuest quest = mainQuest.getChildQuestById(questId);
|
||||
|
||||
if (quest != null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create
|
||||
quest = new GameQuest(mainQuest, questConfig);
|
||||
|
||||
// Save main quest
|
||||
mainQuest.save();
|
||||
|
||||
// Send packet
|
||||
getPlayer().sendPacket(new PacketServerCondMeetQuestListUpdateNotify(quest));
|
||||
getPlayer().sendPacket(new PacketQuestListUpdateNotify(quest));
|
||||
|
||||
return quest;
|
||||
}
|
||||
|
||||
public void loadFromDatabase() {
|
||||
List<GameMainQuest> quests = DatabaseHelper.getAllQuests(getPlayer());
|
||||
|
||||
for (GameMainQuest mainQuest : quests) {
|
||||
mainQuest.setOwner(this.getPlayer());
|
||||
|
||||
for (GameQuest quest : mainQuest.getChildQuests().values()) {
|
||||
quest.setMainQuest(mainQuest);
|
||||
quest.setConfig(GameData.getQuestConfigs().get(quest.getQuestId()));
|
||||
}
|
||||
|
||||
this.getQuests().put(mainQuest.getParentQuestId(), mainQuest);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package emu.grasscutter.game.quest.enums;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
package emu.grasscutter.game.quest.enums;
|
||||
|
||||
public enum QuestCondType {
|
||||
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);
|
||||
|
||||
private final int value;
|
||||
|
||||
QuestCondType(int id) {
|
||||
this.value = id;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package emu.grasscutter.game.quest.enums;
|
||||
|
||||
public enum QuestExecType {
|
||||
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;
|
||||
|
||||
QuestExecType(int id) {
|
||||
this.value = id;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
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);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
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);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
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);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
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);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
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);
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.custom.QuestConfig;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
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.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);
|
||||
}
|
||||
}
|
@ -210,6 +210,14 @@
|
||||
"success": "Coordinates: %s, %s, %s\nScene id: %s",
|
||||
"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_start": "Reloading config.",
|
||||
"reload_done": "Reload complete.",
|
||||
|
Loading…
Reference in New Issue
Block a user