mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-10 18:12:53 +08:00
Merge pull request #1553 from akatatsu27/questing
Major quest framework improvements
This commit is contained in:
commit
797afd4ccf
@ -110,6 +110,8 @@ public class GameData {
|
|||||||
@Getter private static final Int2ObjectMap<MusicGameBasicData> musicGameBasicDataMap = new Int2ObjectOpenHashMap<>();
|
@Getter private static final Int2ObjectMap<MusicGameBasicData> musicGameBasicDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
@Getter private static final Int2ObjectMap<PersonalLineData> personalLineDataMap = new Int2ObjectOpenHashMap<>();
|
@Getter private static final Int2ObjectMap<PersonalLineData> personalLineDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
@Getter private static final Int2ObjectMap<ChapterData> chapterDataMap = new Int2ObjectOpenHashMap<>();
|
@Getter private static final Int2ObjectMap<ChapterData> chapterDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
@Getter private static final Int2ObjectMap<TriggerExcelConfigData> triggerExcelConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
@Getter private static final Map<String,ScriptSceneData> scriptSceneDataMap = new HashMap<>();
|
||||||
|
|
||||||
@Getter private static final Int2ObjectMap<OpenStateData> openStateDataMap = new Int2ObjectOpenHashMap<>();
|
@Getter private static final Int2ObjectMap<OpenStateData> openStateDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
@ -117,8 +119,12 @@ public class GameData {
|
|||||||
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
||||||
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
|
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
|
||||||
private static final IntList scenePointIdList = new IntArrayList();
|
private static final IntList scenePointIdList = new IntArrayList();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Getter private static final List<OpenStateData> openStateList = new ArrayList<>();
|
@Getter private static final List<OpenStateData> openStateList = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
public static Int2ObjectMap<?> getMapByResourceDef(Class<?> resourceDefinition) {
|
public static Int2ObjectMap<?> getMapByResourceDef(Class<?> resourceDefinition) {
|
||||||
Int2ObjectMap<?> map = null;
|
Int2ObjectMap<?> map = null;
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ public class ResourceLoader {
|
|||||||
// Load spawn data and quests
|
// Load spawn data and quests
|
||||||
loadSpawnData();
|
loadSpawnData();
|
||||||
loadQuests();
|
loadQuests();
|
||||||
|
loadScriptSceneData();
|
||||||
// Load scene points - must be done AFTER resources are loaded
|
// Load scene points - must be done AFTER resources are loaded
|
||||||
loadScenePoints();
|
loadScenePoints();
|
||||||
// Load default home layout
|
// Load default home layout
|
||||||
@ -432,6 +433,28 @@ public class ResourceLoader {
|
|||||||
Grasscutter.getLogger().debug("Loaded " + GameData.getMainQuestDataMap().size() + " MainQuestDatas.");
|
Grasscutter.getLogger().debug("Loaded " + GameData.getMainQuestDataMap().size() + " MainQuestDatas.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void loadScriptSceneData() {
|
||||||
|
File folder = new File(RESOURCE("ScriptSceneData/"));
|
||||||
|
|
||||||
|
if (!folder.exists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (File file : folder.listFiles()) {
|
||||||
|
ScriptSceneData sceneData;
|
||||||
|
try (FileReader fileReader = new FileReader(file)) {
|
||||||
|
sceneData = Grasscutter.getGsonFactory().fromJson(fileReader, ScriptSceneData.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameData.getScriptSceneDataMap().put(file.getName(), sceneData);
|
||||||
|
}
|
||||||
|
|
||||||
|
Grasscutter.getLogger().debug("Loaded " + GameData.getScriptSceneDataMap().size() + " ScriptSceneDatas.");
|
||||||
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
private static void loadHomeworldDefaultSaveData(){
|
private static void loadHomeworldDefaultSaveData(){
|
||||||
var folder = Files.list(Path.of(RESOURCE("BinOutput/HomeworldDefaultSave"))).toList();
|
var folder = Files.list(Path.of(RESOURCE("BinOutput/HomeworldDefaultSave"))).toList();
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
package emu.grasscutter.data.binout;
|
package emu.grasscutter.data.binout;
|
||||||
|
|
||||||
|
import dev.morphia.annotations.Entity;
|
||||||
import emu.grasscutter.game.quest.enums.QuestType;
|
import emu.grasscutter.game.quest.enums.QuestType;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class MainQuestData {
|
public class MainQuestData {
|
||||||
private int id;
|
private int id;
|
||||||
|
private int ICLLDPJFIMA;
|
||||||
private int series;
|
private int series;
|
||||||
private QuestType type;
|
private QuestType type;
|
||||||
|
|
||||||
@ -13,6 +17,8 @@ public class MainQuestData {
|
|||||||
private int[] rewardIdList;
|
private int[] rewardIdList;
|
||||||
|
|
||||||
private SubQuestData[] subQuests;
|
private SubQuestData[] subQuests;
|
||||||
|
private List<TalkData> talks;
|
||||||
|
private long[] preloadLuaList;
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
@ -41,10 +47,24 @@ public class MainQuestData {
|
|||||||
public SubQuestData[] getSubQuests() {
|
public SubQuestData[] getSubQuests() {
|
||||||
return subQuests;
|
return subQuests;
|
||||||
}
|
}
|
||||||
|
public List<TalkData> getTalks() {
|
||||||
|
return talks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onLoad() {
|
||||||
|
this.talks = talks.stream().filter(Objects::nonNull).toList();
|
||||||
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class SubQuestData {
|
public static class SubQuestData {
|
||||||
private int subId;
|
private int subId;
|
||||||
private int order;
|
private int order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Data @Entity
|
||||||
|
public static class TalkData {
|
||||||
|
private int id;
|
||||||
|
private String heroTalk;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package emu.grasscutter.data.binout;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
import emu.grasscutter.utils.Position;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ScriptSceneData {
|
||||||
|
Map<String,ScriptObject> scriptObjectList;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class ScriptObject {
|
||||||
|
//private SceneGroup groups;
|
||||||
|
@SerializedName("dummy_points")
|
||||||
|
private Map<String, List<Float>> dummyPoints;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -36,10 +36,14 @@ public class QuestData extends GameResource {
|
|||||||
private List<QuestExecParam> beginExec;
|
private List<QuestExecParam> beginExec;
|
||||||
private List<QuestExecParam> finishExec;
|
private List<QuestExecParam> finishExec;
|
||||||
private List<QuestExecParam> failExec;
|
private List<QuestExecParam> failExec;
|
||||||
|
private Guide guide;
|
||||||
|
|
||||||
|
//ResourceLoader not happy if you remove getId() ~~
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return subId;
|
return subId;
|
||||||
}
|
}
|
||||||
|
//Added getSubId() for clarity
|
||||||
|
public int getSubId() {return subId;}
|
||||||
|
|
||||||
public int getMainId() {
|
public int getMainId() {
|
||||||
return mainId;
|
return mainId;
|
||||||
@ -62,7 +66,7 @@ public class QuestData extends GameResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LogicType getAcceptCondComb() {
|
public LogicType getAcceptCondComb() {
|
||||||
return acceptCondComb;
|
return acceptCondComb == null ? LogicType.LOGIC_NONE : acceptCondComb;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<QuestCondition> getAcceptCond() {
|
public List<QuestCondition> getAcceptCond() {
|
||||||
@ -70,7 +74,7 @@ public class QuestData extends GameResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LogicType getFinishCondComb() {
|
public LogicType getFinishCondComb() {
|
||||||
return finishCondComb;
|
return finishCondComb == null ? LogicType.LOGIC_NONE : finishCondComb;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<QuestCondition> getFinishCond() {
|
public List<QuestCondition> getFinishCond() {
|
||||||
@ -78,7 +82,7 @@ public class QuestData extends GameResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LogicType getFailCondComb() {
|
public LogicType getFailCondComb() {
|
||||||
return failCondComb;
|
return failCondComb == null ? LogicType.LOGIC_NONE : failCondComb;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<QuestCondition> getFailCond() {
|
public List<QuestCondition> getFailCond() {
|
||||||
@ -118,4 +122,11 @@ public class QuestData extends GameResource {
|
|||||||
private String count;
|
private String count;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Guide {
|
||||||
|
private String type;
|
||||||
|
private List<String> param;
|
||||||
|
private int guideScene;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
package emu.grasscutter.data.excels;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameResource;
|
||||||
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@ResourceType(name = "TriggerExcelConfigData.json") @Getter
|
||||||
|
public class TriggerExcelConfigData extends GameResource {
|
||||||
|
@Getter private int id;
|
||||||
|
private int sceneId;
|
||||||
|
private int groupId;
|
||||||
|
private String triggerName;
|
||||||
|
}
|
@ -15,6 +15,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
public class EntityRegion extends GameEntity{
|
public class EntityRegion extends GameEntity{
|
||||||
private final Position position;
|
private final Position position;
|
||||||
private boolean hasNewEntities;
|
private boolean hasNewEntities;
|
||||||
|
private boolean entityLeave;
|
||||||
private final Set<Integer> entities; // Ids of entities inside this region
|
private final Set<Integer> entities; // Ids of entities inside this region
|
||||||
private final SceneRegion metaRegion;
|
private final SceneRegion metaRegion;
|
||||||
|
|
||||||
@ -45,10 +46,17 @@ public class EntityRegion extends GameEntity{
|
|||||||
hasNewEntities = false;
|
hasNewEntities = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeEntity(GameEntity entity) {
|
public void removeEntity(int entityId) {
|
||||||
this.getEntities().remove(entity.getId());
|
this.getEntities().remove(entityId);
|
||||||
|
this.entityLeave = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeEntity(GameEntity entity) {
|
||||||
|
this.getEntities().remove(entity.getId());
|
||||||
|
this.entityLeave = true;
|
||||||
|
}
|
||||||
|
public boolean entityLeave() {return this.entityLeave;}
|
||||||
|
public void resetEntityLeave() {this.entityLeave = false;}
|
||||||
@Override
|
@Override
|
||||||
public Int2FloatOpenHashMap getFightProperties() {
|
public Int2FloatOpenHashMap getFightProperties() {
|
||||||
return null;
|
return null;
|
||||||
|
@ -14,12 +14,8 @@ import emu.grasscutter.game.activity.ActivityManager;
|
|||||||
import emu.grasscutter.game.avatar.Avatar;
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
import emu.grasscutter.game.avatar.AvatarStorage;
|
import emu.grasscutter.game.avatar.AvatarStorage;
|
||||||
import emu.grasscutter.game.battlepass.BattlePassManager;
|
import emu.grasscutter.game.battlepass.BattlePassManager;
|
||||||
import emu.grasscutter.game.entity.EntityMonster;
|
import emu.grasscutter.game.entity.*;
|
||||||
import emu.grasscutter.game.entity.EntityVehicle;
|
|
||||||
import emu.grasscutter.game.home.GameHome;
|
import emu.grasscutter.game.home.GameHome;
|
||||||
import emu.grasscutter.game.entity.EntityGadget;
|
|
||||||
import emu.grasscutter.game.entity.EntityItem;
|
|
||||||
import emu.grasscutter.game.entity.GameEntity;
|
|
||||||
import emu.grasscutter.game.expedition.ExpeditionInfo;
|
import emu.grasscutter.game.expedition.ExpeditionInfo;
|
||||||
import emu.grasscutter.game.friends.FriendsList;
|
import emu.grasscutter.game.friends.FriendsList;
|
||||||
import emu.grasscutter.game.friends.PlayerProfile;
|
import emu.grasscutter.game.friends.PlayerProfile;
|
||||||
@ -43,6 +39,7 @@ import emu.grasscutter.game.props.ClimateType;
|
|||||||
import emu.grasscutter.game.props.PlayerProperty;
|
import emu.grasscutter.game.props.PlayerProperty;
|
||||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||||
import emu.grasscutter.game.quest.QuestManager;
|
import emu.grasscutter.game.quest.QuestManager;
|
||||||
|
import emu.grasscutter.game.quest.enums.QuestTrigger;
|
||||||
import emu.grasscutter.game.shop.ShopLimit;
|
import emu.grasscutter.game.shop.ShopLimit;
|
||||||
import emu.grasscutter.game.tower.TowerData;
|
import emu.grasscutter.game.tower.TowerData;
|
||||||
import emu.grasscutter.game.tower.TowerManager;
|
import emu.grasscutter.game.tower.TowerManager;
|
||||||
@ -61,6 +58,7 @@ import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo
|
|||||||
import emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture;
|
import emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture;
|
||||||
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
|
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
|
||||||
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
|
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
|
||||||
|
import emu.grasscutter.scripts.data.SceneRegion;
|
||||||
import emu.grasscutter.server.event.player.PlayerJoinEvent;
|
import emu.grasscutter.server.event.player.PlayerJoinEvent;
|
||||||
import emu.grasscutter.server.event.player.PlayerQuitEvent;
|
import emu.grasscutter.server.event.player.PlayerQuitEvent;
|
||||||
import emu.grasscutter.server.game.GameServer;
|
import emu.grasscutter.server.game.GameServer;
|
||||||
@ -74,6 +72,7 @@ import emu.grasscutter.utils.Utils;
|
|||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
import static emu.grasscutter.config.Configuration.*;
|
import static emu.grasscutter.config.Configuration.*;
|
||||||
|
|
||||||
@ -122,6 +121,7 @@ public class Player {
|
|||||||
@Getter private Map<Long, ExpeditionInfo> expeditionInfo;
|
@Getter private Map<Long, ExpeditionInfo> expeditionInfo;
|
||||||
@Getter private Map<Integer, Integer> unlockedRecipies;
|
@Getter private Map<Integer, Integer> unlockedRecipies;
|
||||||
@Getter private List<ActiveForgeData> activeForges;
|
@Getter private List<ActiveForgeData> activeForges;
|
||||||
|
@Getter private Map<Integer,Integer> questGlobalVariables;
|
||||||
|
|
||||||
@Transient private long nextGuid = 0;
|
@Transient private long nextGuid = 0;
|
||||||
@Transient private int peerId;
|
@Transient private int peerId;
|
||||||
@ -579,6 +579,35 @@ public class Player {
|
|||||||
return towerData;
|
return towerData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setQuestManager(QuestManager questManager) {
|
||||||
|
this.questManager = questManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onEnterRegion(SceneRegion region) {
|
||||||
|
getQuestManager().forEachActiveQuest(quest -> {
|
||||||
|
if(quest.getTriggers().containsKey("ENTER_REGION_"+ String.valueOf(region.config_id))) {
|
||||||
|
// If trigger hasn't been fired yet
|
||||||
|
if(!Boolean.TRUE.equals(quest.getTriggers().put("ENTER_REGION_"+ String.valueOf(region.config_id), true))) {
|
||||||
|
//getSession().send(new PacketServerCondMeetQuestListUpdateNotify());
|
||||||
|
getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_TRIGGER_FIRE, quest.getTriggerData().get("ENTER_REGION_"+ String.valueOf(region.config_id)).getId(),0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onLeaveRegion(SceneRegion region) {
|
||||||
|
getQuestManager().forEachActiveQuest(quest -> {
|
||||||
|
if(quest.getTriggers().containsKey("LEAVE_REGION_"+ String.valueOf(region.config_id))) {
|
||||||
|
// If trigger hasn't been fired yet
|
||||||
|
if(!Boolean.TRUE.equals(quest.getTriggers().put("LEAVE_REGION_"+ String.valueOf(region.config_id), true))) {
|
||||||
|
getSession().send(new PacketServerCondMeetQuestListUpdateNotify());
|
||||||
|
getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_TRIGGER_FIRE, quest.getTriggerData().get("LEAVE_REGION_"+ String.valueOf(region.config_id)).getId(),0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
public PlayerGachaInfo getGachaInfo() {
|
public PlayerGachaInfo getGachaInfo() {
|
||||||
return gachaInfo;
|
return gachaInfo;
|
||||||
}
|
}
|
||||||
@ -1327,6 +1356,11 @@ public class Player {
|
|||||||
// Execute daily reset logic if this is a new day.
|
// Execute daily reset logic if this is a new day.
|
||||||
this.doDailyReset();
|
this.doDailyReset();
|
||||||
|
|
||||||
|
|
||||||
|
// Rewind active quests, and put the player to a rewind position it finds (if any) of an active quest
|
||||||
|
getQuestManager().onLogin();
|
||||||
|
|
||||||
|
|
||||||
// Packets
|
// Packets
|
||||||
session.send(new PacketPlayerDataNotify(this)); // Player data
|
session.send(new PacketPlayerDataNotify(this)); // Player data
|
||||||
session.send(new PacketStoreWeightLimitNotify());
|
session.send(new PacketStoreWeightLimitNotify());
|
||||||
|
@ -2,7 +2,15 @@ package emu.grasscutter.game.quest;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.binout.ScriptSceneData;
|
||||||
|
import emu.grasscutter.data.excels.QuestData;
|
||||||
|
import emu.grasscutter.game.quest.enums.LogicType;
|
||||||
|
import emu.grasscutter.game.quest.enums.QuestTrigger;
|
||||||
|
import emu.grasscutter.scripts.ScriptLoader;
|
||||||
import emu.grasscutter.server.packet.send.PacketCodexDataUpdateNotify;
|
import emu.grasscutter.server.packet.send.PacketCodexDataUpdateNotify;
|
||||||
|
import emu.grasscutter.utils.Position;
|
||||||
|
import lombok.Getter;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
|
|
||||||
import dev.morphia.annotations.Entity;
|
import dev.morphia.annotations.Entity;
|
||||||
@ -11,6 +19,7 @@ import dev.morphia.annotations.Indexed;
|
|||||||
import dev.morphia.annotations.Transient;
|
import dev.morphia.annotations.Transient;
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.binout.MainQuestData;
|
import emu.grasscutter.data.binout.MainQuestData;
|
||||||
|
import emu.grasscutter.data.binout.MainQuestData.*;
|
||||||
import emu.grasscutter.data.excels.RewardData;
|
import emu.grasscutter.data.excels.RewardData;
|
||||||
import emu.grasscutter.database.DatabaseHelper;
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
@ -23,24 +32,33 @@ import emu.grasscutter.net.proto.QuestOuterClass.Quest;
|
|||||||
import emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify;
|
import emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify;
|
||||||
import emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify;
|
import emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify;
|
||||||
import emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify;
|
import emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify;
|
||||||
import emu.grasscutter.utils.Utils;
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import javax.script.Bindings;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import javax.script.CompiledScript;
|
||||||
|
import javax.script.ScriptException;
|
||||||
|
|
||||||
|
import static emu.grasscutter.config.Configuration.SCRIPT;
|
||||||
|
|
||||||
@Entity(value = "quests", useDiscriminator = false)
|
@Entity(value = "quests", useDiscriminator = false)
|
||||||
public class GameMainQuest {
|
public class GameMainQuest {
|
||||||
@Id private ObjectId id;
|
@Id private ObjectId id;
|
||||||
|
@Indexed @Getter private int ownerUid;
|
||||||
|
@Transient @Getter private Player owner;
|
||||||
|
@Transient @Getter private QuestManager questManager;
|
||||||
|
@Getter private Map<Integer, GameQuest> childQuests;
|
||||||
|
@Getter private int parentQuestId;
|
||||||
|
@Getter private int[] questVars;
|
||||||
|
//QuestUpdateQuestVarReq is sent in two stages...
|
||||||
|
@Getter private List<Integer> questVarsUpdate;
|
||||||
|
@Getter private ParentQuestState state;
|
||||||
|
@Getter private boolean isFinished;
|
||||||
|
@Getter List<QuestGroupSuite> questGroupSuites;
|
||||||
|
|
||||||
@Indexed private int ownerUid;
|
@Getter int[] suggestTrackMainQuestList;
|
||||||
@Transient private Player owner;
|
@Getter private Map<Integer,TalkData> talks;
|
||||||
|
//key is subId
|
||||||
private Map<Integer, GameQuest> childQuests;
|
private Map<Integer,Position> rewindPositions;
|
||||||
|
private Map<Integer,Position> rewindRotations;
|
||||||
private int parentQuestId;
|
|
||||||
private int[] questVars;
|
|
||||||
private ParentQuestState state;
|
|
||||||
private boolean isFinished;
|
|
||||||
List<QuestGroupSuite> questGroupSuites;
|
|
||||||
|
|
||||||
@Deprecated // Morphia only. Do not use.
|
@Deprecated // Morphia only. Do not use.
|
||||||
public GameMainQuest() {}
|
public GameMainQuest() {}
|
||||||
@ -48,23 +66,26 @@ public class GameMainQuest {
|
|||||||
public GameMainQuest(Player player, int parentQuestId) {
|
public GameMainQuest(Player player, int parentQuestId) {
|
||||||
this.owner = player;
|
this.owner = player;
|
||||||
this.ownerUid = player.getUid();
|
this.ownerUid = player.getUid();
|
||||||
|
this.questManager = player.getQuestManager();
|
||||||
this.parentQuestId = parentQuestId;
|
this.parentQuestId = parentQuestId;
|
||||||
this.childQuests = new HashMap<>();
|
this.childQuests = new HashMap<>();
|
||||||
this.questVars = new int[5];
|
this.talks = new HashMap<>();
|
||||||
|
//official server always has a list of 5 questVars, with default value 0
|
||||||
|
this.questVars = new int[] {0,0,0,0,0};
|
||||||
this.state = ParentQuestState.PARENT_QUEST_STATE_NONE;
|
this.state = ParentQuestState.PARENT_QUEST_STATE_NONE;
|
||||||
this.questGroupSuites = new ArrayList<>();
|
this.questGroupSuites = new ArrayList<>();
|
||||||
|
this.rewindPositions = new HashMap<>();
|
||||||
|
this.rewindRotations = new HashMap<>();
|
||||||
|
addAllChildQuests();
|
||||||
|
addRewindPoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getParentQuestId() {
|
private void addAllChildQuests() {
|
||||||
return parentQuestId;
|
List<Integer> subQuestIds = Arrays.stream(GameData.getMainQuestDataMap().get(this.parentQuestId).getSubQuests()).map(SubQuestData::getSubId).toList();
|
||||||
|
for (Integer subQuestId : subQuestIds) {
|
||||||
|
QuestData questConfig = GameData.getQuestDataMap().get(subQuestId);
|
||||||
|
this.childQuests.put(subQuestId, new GameQuest(this, questConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getOwnerUid() {
|
|
||||||
return ownerUid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Player getOwner() {
|
|
||||||
return owner;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOwner(Player player) {
|
public void setOwner(Player player) {
|
||||||
@ -72,28 +93,33 @@ public class GameMainQuest {
|
|||||||
this.owner = player;
|
this.owner = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Integer, GameQuest> getChildQuests() {
|
public int getQuestVar(int i) {
|
||||||
return childQuests;
|
return questVars[i];
|
||||||
}
|
}
|
||||||
|
public void setQuestVar(int i, int value) {
|
||||||
|
int previousValue = this.questVars[i];
|
||||||
|
this.questVars[i] = value;
|
||||||
|
Grasscutter.getLogger().debug("questVar {} value changed from {} to {}", i, previousValue, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incQuestVar(int i, int inc) {
|
||||||
|
int previousValue = this.questVars[i];
|
||||||
|
this.questVars[i] += inc;
|
||||||
|
Grasscutter.getLogger().debug("questVar {} value incremented from {} to {}", i, previousValue, previousValue + inc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void decQuestVar(int i, int dec) {
|
||||||
|
int previousValue = this.questVars[i];
|
||||||
|
this.questVars[i] -= dec;
|
||||||
|
Grasscutter.getLogger().debug("questVar {} value decremented from {} to {}", i, previousValue, previousValue - dec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public GameQuest getChildQuestById(int id) {
|
public GameQuest getChildQuestById(int id) {
|
||||||
return this.getChildQuests().get(id);
|
return this.getChildQuests().get(id);
|
||||||
}
|
}
|
||||||
|
public GameQuest getChildQuestByOrder(int order) {
|
||||||
public int[] getQuestVars() {
|
return this.getChildQuests().values().stream().filter(p -> p.getQuestData().getOrder() == order).toList().get(0);
|
||||||
return questVars;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParentQuestState getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFinished() {
|
|
||||||
return isFinished;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<QuestGroupSuite> getQuestGroupSuites() {
|
|
||||||
return questGroupSuites;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finish() {
|
public void finish() {
|
||||||
@ -120,7 +146,191 @@ public class GameMainQuest {
|
|||||||
// handoff main quest
|
// handoff main quest
|
||||||
if(mainQuestData.getSuggestTrackMainQuestList() != null){
|
if(mainQuestData.getSuggestTrackMainQuestList() != null){
|
||||||
Arrays.stream(mainQuestData.getSuggestTrackMainQuestList())
|
Arrays.stream(mainQuestData.getSuggestTrackMainQuestList())
|
||||||
.forEach(getOwner().getQuestManager()::startMainQuest);
|
.forEach(getQuestManager()::startMainQuest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TODO
|
||||||
|
public void fail() {}
|
||||||
|
public void cancel() {}
|
||||||
|
|
||||||
|
// Rewinds to the last finished/unfinished rewind quest, and returns the avatar rewind position (if it exists)
|
||||||
|
public List<Position> rewind() {
|
||||||
|
if(this.questManager == null) {
|
||||||
|
this.questManager = getOwner().getQuestManager();
|
||||||
|
}
|
||||||
|
List<GameQuest> sortedByOrder = new ArrayList<>(getChildQuests().values().stream().filter(q -> q.getQuestData().isRewind()).toList());
|
||||||
|
sortedByOrder.sort((a,b) -> {
|
||||||
|
if( a == b){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return a.getQuestData().getOrder() > b.getQuestData().getOrder() ? 1 : -1;});
|
||||||
|
boolean didRewind = false;
|
||||||
|
for (GameQuest quest : sortedByOrder) {
|
||||||
|
int i = sortedByOrder.indexOf(quest);
|
||||||
|
if( i == sortedByOrder.size()) {
|
||||||
|
didRewind = quest.rewind(null);
|
||||||
|
} else {
|
||||||
|
didRewind = quest.rewind(sortedByOrder.get(i+1));
|
||||||
|
}
|
||||||
|
if(didRewind) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<GameQuest> rewindQuests = getChildQuests().values().stream()
|
||||||
|
.filter(p -> (p.getState() == QuestState.QUEST_STATE_UNFINISHED || p.getState() == QuestState.QUEST_STATE_FINISHED) && p.getQuestData().isRewind()).toList();
|
||||||
|
for (GameQuest quest : rewindQuests) {
|
||||||
|
if(rewindPositions.containsKey(quest.getSubQuestId())) {
|
||||||
|
List<Position> posAndRot = new ArrayList<>();
|
||||||
|
posAndRot.add(0,rewindPositions.get(quest.getSubQuestId()));
|
||||||
|
posAndRot.add(1,rewindRotations.get(quest.getSubQuestId()));
|
||||||
|
return posAndRot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public void addRewindPoints() {
|
||||||
|
Bindings bindings = ScriptLoader.getEngine().createBindings();
|
||||||
|
|
||||||
|
CompiledScript cs = ScriptLoader.getScriptByPath(
|
||||||
|
SCRIPT("Quest/Share/Q" + getParentQuestId() + "ShareConfig." + ScriptLoader.getScriptType()));
|
||||||
|
|
||||||
|
if (cs == null) {
|
||||||
|
Grasscutter.getLogger().error("Couldn't find Q" + getParentQuestId() + "ShareConfig." + ScriptLoader.getScriptType());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Eval script
|
||||||
|
try {
|
||||||
|
cs.eval(bindings);
|
||||||
|
|
||||||
|
var rewindDataMap = ScriptLoader.getSerializer().toMap(RewindData.class, bindings.get("rewind_data"));
|
||||||
|
for(String subId : rewindDataMap.keySet()) {
|
||||||
|
RewindData questRewind = rewindDataMap.get(subId);
|
||||||
|
if(questRewind != null) {
|
||||||
|
RewindData.AvatarData avatarData = questRewind.getAvatar();
|
||||||
|
if(avatarData != null) {
|
||||||
|
String avatarPos = avatarData.getPos();
|
||||||
|
QuestData.Guide guide = GameData.getQuestDataMap().get(Integer.valueOf(subId)).getGuide();
|
||||||
|
if (guide != null) {
|
||||||
|
int sceneId = guide.getGuideScene();
|
||||||
|
ScriptSceneData fullGlobals = GameData.getScriptSceneDataMap().get("flat.luas.scenes.full_globals.lua.json");
|
||||||
|
if(fullGlobals != null) {
|
||||||
|
ScriptSceneData.ScriptObject dummyPointScript = fullGlobals.getScriptObjectList().get(sceneId + "/scene" + sceneId + "_dummy_points.lua");
|
||||||
|
if (dummyPointScript != null) {
|
||||||
|
Map<String, List<Float>> dummyPointMap = dummyPointScript.getDummyPoints();
|
||||||
|
if (dummyPointMap != null) {
|
||||||
|
List<Float> avatarPosPos = dummyPointMap.get(avatarPos + ".pos");
|
||||||
|
if (avatarPosPos != null) {
|
||||||
|
Position pos = new Position(avatarPosPos.get(0),avatarPosPos.get(1),avatarPosPos.get(2));
|
||||||
|
List<Float> avatarPosRot = dummyPointMap.get(avatarPos + ".rot");
|
||||||
|
Position rot = new Position(avatarPosRot.get(0),avatarPosRot.get(1),avatarPosRot.get(2));
|
||||||
|
rewindPositions.put(Integer.valueOf(subId),pos);
|
||||||
|
rewindRotations.put(Integer.valueOf(subId),rot);
|
||||||
|
Grasscutter.getLogger().debug("Succesfully loaded rewind position for subQuest {}",subId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (ScriptException e) {
|
||||||
|
Grasscutter.getLogger().error("An error occurred while loading rewind positions");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tryAcceptSubQuests(QuestTrigger condType, String paramStr, int... params) {
|
||||||
|
try {
|
||||||
|
List<GameQuest> subQuestsWithCond = getChildQuests().values().stream()
|
||||||
|
.filter(p -> p.getState() == QuestState.QUEST_STATE_UNSTARTED)
|
||||||
|
.filter(p -> p.getQuestData().getAcceptCond().stream().anyMatch(q -> q.getType() == condType))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
for (GameQuest subQuestWithCond : subQuestsWithCond) {
|
||||||
|
List<QuestData.QuestCondition> acceptCond = subQuestWithCond.getQuestData().getAcceptCond();
|
||||||
|
int[] accept = new int[acceptCond.size()];
|
||||||
|
|
||||||
|
for (int i = 0; i < subQuestWithCond.getQuestData().getAcceptCond().size(); i++) {
|
||||||
|
QuestData.QuestCondition condition = acceptCond.get(i);
|
||||||
|
boolean result = this.getOwner().getServer().getQuestSystem().triggerCondition(subQuestWithCond, condition, paramStr, params);
|
||||||
|
accept[i] = result ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean shouldAccept = LogicType.calculate(subQuestWithCond.getQuestData().getAcceptCondComb(), accept);
|
||||||
|
|
||||||
|
if (shouldAccept) {
|
||||||
|
subQuestWithCond.start();
|
||||||
|
getQuestManager().getAddToQuestListUpdateNotify().add(subQuestWithCond);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
this.save();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Grasscutter.getLogger().error("An error occurred while trying to accept quest.", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tryFailSubQuests(QuestTrigger condType, String paramStr, int... params) {
|
||||||
|
try {
|
||||||
|
List<GameQuest> subQuestsWithCond = getChildQuests().values().stream()
|
||||||
|
.filter(p -> p.getState() == QuestState.QUEST_STATE_UNFINISHED)
|
||||||
|
.filter(p -> p.getQuestData().getFailCond().stream().anyMatch(q -> q.getType() == condType))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
for (GameQuest subQuestWithCond : subQuestsWithCond) {
|
||||||
|
List<QuestData.QuestCondition> failCond = subQuestWithCond.getQuestData().getFailCond();
|
||||||
|
int[] fail = new int[failCond.size()];
|
||||||
|
|
||||||
|
for (int i = 0; i < subQuestWithCond.getQuestData().getFailCond().size(); i++) {
|
||||||
|
QuestData.QuestCondition condition = failCond.get(i);
|
||||||
|
boolean result = this.getOwner().getServer().getQuestSystem().triggerContent(subQuestWithCond, condition, paramStr, params);
|
||||||
|
fail[i] = result ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean shouldFail = LogicType.calculate(subQuestWithCond.getQuestData().getFailCondComb(), fail);
|
||||||
|
|
||||||
|
if (shouldFail) {
|
||||||
|
subQuestWithCond.fail();
|
||||||
|
getQuestManager().getAddToQuestListUpdateNotify().add(subQuestWithCond);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Grasscutter.getLogger().error("An error occurred while trying to fail quest.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tryFinishSubQuests(QuestTrigger condType, String paramStr, int... params) {
|
||||||
|
try {
|
||||||
|
List<GameQuest> subQuestsWithCond = getChildQuests().values().stream()
|
||||||
|
//There are subQuests with no acceptCond, but can be finished (example: 35104)
|
||||||
|
.filter(p -> p.getState() == QuestState.QUEST_STATE_UNFINISHED && p.getQuestData().getAcceptCond() != null)
|
||||||
|
.filter(p -> p.getQuestData().getFinishCond().stream().anyMatch(q -> q.getType() == condType))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
for (GameQuest subQuestWithCond : subQuestsWithCond) {
|
||||||
|
List<QuestData.QuestCondition> finishCond = subQuestWithCond.getQuestData().getFinishCond();
|
||||||
|
int[] finish = new int[finishCond.size()];
|
||||||
|
|
||||||
|
for (int i = 0; i < subQuestWithCond.getQuestData().getFinishCond().size(); i++) {
|
||||||
|
QuestData.QuestCondition condition = finishCond.get(i);
|
||||||
|
boolean result = this.getOwner().getServer().getQuestSystem().triggerContent(subQuestWithCond, condition, paramStr, params);
|
||||||
|
finish[i] = result ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean shouldFinish = LogicType.calculate(subQuestWithCond.getQuestData().getFinishCondComb(), finish);
|
||||||
|
|
||||||
|
if (shouldFinish) {
|
||||||
|
subQuestWithCond.finish();
|
||||||
|
getQuestManager().getAddToQuestListUpdateNotify().add(subQuestWithCond);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Grasscutter.getLogger().debug("An error occurred while trying to finish quest.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,25 +341,28 @@ public class GameMainQuest {
|
|||||||
public ParentQuest toProto() {
|
public ParentQuest toProto() {
|
||||||
ParentQuest.Builder proto = ParentQuest.newBuilder()
|
ParentQuest.Builder proto = ParentQuest.newBuilder()
|
||||||
.setParentQuestId(getParentQuestId())
|
.setParentQuestId(getParentQuestId())
|
||||||
.setIsFinished(isFinished())
|
.setIsFinished(isFinished());
|
||||||
.setParentQuestState(getState().getValue())
|
|
||||||
.setCutsceneEncryptionKey(QuestManager.getQuestKey(parentQuestId));
|
|
||||||
|
|
||||||
|
|
||||||
|
proto.setParentQuestState(getState().getValue())
|
||||||
|
.setCutsceneEncryptionKey(QuestManager.getQuestKey(parentQuestId));
|
||||||
for (GameQuest quest : this.getChildQuests().values()) {
|
for (GameQuest quest : this.getChildQuests().values()) {
|
||||||
|
if (quest.getState() != QuestState.QUEST_STATE_UNSTARTED) {
|
||||||
ChildQuest childQuest = ChildQuest.newBuilder()
|
ChildQuest childQuest = ChildQuest.newBuilder()
|
||||||
.setQuestId(quest.getQuestId())
|
.setQuestId(quest.getSubQuestId())
|
||||||
.setState(quest.getState().getValue())
|
.setState(quest.getState().getValue())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
proto.addChildQuestList(childQuest);
|
proto.addChildQuestList(childQuest);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (getQuestVars() != null) {
|
|
||||||
for (int i : getQuestVars()) {
|
for (int i : getQuestVars()) {
|
||||||
proto.addQuestVar(i);
|
proto.addQuestVar(i);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return proto.build();
|
return proto.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,51 +4,84 @@ import dev.morphia.annotations.Entity;
|
|||||||
import dev.morphia.annotations.Transient;
|
import dev.morphia.annotations.Transient;
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.binout.MainQuestData;
|
|
||||||
import emu.grasscutter.data.binout.MainQuestData.SubQuestData;
|
|
||||||
import emu.grasscutter.data.excels.ChapterData;
|
import emu.grasscutter.data.excels.ChapterData;
|
||||||
import emu.grasscutter.data.excels.QuestData;
|
import emu.grasscutter.data.excels.QuestData;
|
||||||
import emu.grasscutter.data.excels.QuestData.QuestCondition;
|
import emu.grasscutter.data.excels.TriggerExcelConfigData;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.quest.enums.LogicType;
|
|
||||||
import emu.grasscutter.game.quest.enums.QuestState;
|
import emu.grasscutter.game.quest.enums.QuestState;
|
||||||
import emu.grasscutter.game.quest.enums.QuestTrigger;
|
import emu.grasscutter.game.quest.enums.QuestTrigger;
|
||||||
import emu.grasscutter.net.proto.ChapterStateOuterClass;
|
import emu.grasscutter.net.proto.ChapterStateOuterClass;
|
||||||
import emu.grasscutter.net.proto.QuestOuterClass.Quest;
|
import emu.grasscutter.net.proto.QuestOuterClass.Quest;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
|
||||||
import emu.grasscutter.server.packet.send.PacketChapterStateNotify;
|
import emu.grasscutter.server.packet.send.PacketChapterStateNotify;
|
||||||
import emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify;
|
import emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify;
|
||||||
import emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify;
|
import emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify;
|
||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.script.Bindings;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class GameQuest {
|
public class GameQuest {
|
||||||
@Transient private GameMainQuest mainQuest;
|
@Transient @Getter @Setter private GameMainQuest mainQuest;
|
||||||
@Transient private QuestData questData;
|
@Transient @Getter private QuestData questData;
|
||||||
|
|
||||||
private int questId;
|
@Getter private int subQuestId;
|
||||||
private int mainQuestId;
|
@Getter private int mainQuestId;
|
||||||
|
@Getter @Setter
|
||||||
private QuestState state;
|
private QuestState state;
|
||||||
|
|
||||||
private int startTime;
|
@Getter @Setter private int startTime;
|
||||||
private int acceptTime;
|
@Getter @Setter private int acceptTime;
|
||||||
private int finishTime;
|
@Getter @Setter private int finishTime;
|
||||||
|
|
||||||
private int[] finishProgressList;
|
@Getter private int[] finishProgressList;
|
||||||
private int[] failProgressList;
|
@Getter private int[] failProgressList;
|
||||||
|
@Transient @Getter private Map<String, TriggerExcelConfigData> triggerData;
|
||||||
|
@Getter private Map<String, Boolean> triggers;
|
||||||
|
private transient Bindings bindings;
|
||||||
|
|
||||||
@Deprecated // Morphia only. Do not use.
|
@Deprecated // Morphia only. Do not use.
|
||||||
public GameQuest() {}
|
public GameQuest() {}
|
||||||
|
|
||||||
public GameQuest(GameMainQuest mainQuest, QuestData questData) {
|
public GameQuest(GameMainQuest mainQuest, QuestData questData) {
|
||||||
this.mainQuest = mainQuest;
|
this.mainQuest = mainQuest;
|
||||||
this.questId = questData.getId();
|
this.subQuestId = questData.getId();
|
||||||
this.mainQuestId = questData.getMainId();
|
this.mainQuestId = questData.getMainId();
|
||||||
this.questData = questData;
|
this.questData = questData;
|
||||||
|
this.state = QuestState.QUEST_STATE_UNSTARTED;
|
||||||
|
this.triggerData = new HashMap<>();
|
||||||
|
this.triggers = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
this.acceptTime = Utils.getCurrentSeconds();
|
this.acceptTime = Utils.getCurrentSeconds();
|
||||||
this.startTime = this.acceptTime;
|
this.startTime = this.acceptTime;
|
||||||
this.state = QuestState.QUEST_STATE_UNFINISHED;
|
this.state = QuestState.QUEST_STATE_UNFINISHED;
|
||||||
|
List<QuestData.QuestCondition> triggerCond = questData.getFinishCond().stream()
|
||||||
|
.filter(p -> p.getType() == QuestTrigger.QUEST_CONTENT_TRIGGER_FIRE).toList();
|
||||||
|
if(triggerCond.size() > 0) {
|
||||||
|
for (QuestData.QuestCondition cond : triggerCond) {
|
||||||
|
TriggerExcelConfigData newTrigger = GameData.getTriggerExcelConfigDataMap().get(cond.getParam()[0]);
|
||||||
|
if(newTrigger != null) {
|
||||||
|
if(this.triggerData == null) {
|
||||||
|
this.triggerData = new HashMap<>();
|
||||||
|
}
|
||||||
|
triggerData.put(newTrigger.getTriggerName(), newTrigger);
|
||||||
|
triggers.put(newTrigger.getTriggerName(), false);
|
||||||
|
SceneGroup group = SceneGroup.of(newTrigger.getGroupId()).load(newTrigger.getSceneId());
|
||||||
|
getOwner().getWorld().getSceneById(newTrigger.getSceneId()).loadTriggerFromGroup(group, newTrigger.getTriggerName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (questData.getFinishCond() != null && questData.getAcceptCond().size() != 0) {
|
if (questData.getFinishCond() != null && questData.getFinishCond().size() != 0) {
|
||||||
this.finishProgressList = new int[questData.getFinishCond().size()];
|
this.finishProgressList = new int[questData.getFinishCond().size()];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,95 +89,46 @@ public class GameQuest {
|
|||||||
this.failProgressList = new int[questData.getFailCond().size()];
|
this.failProgressList = new int[questData.getFailCond().size()];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.mainQuest.getChildQuests().put(this.questId, this);
|
getQuestData().getBeginExec().forEach(e -> getOwner().getServer().getQuestSystem().triggerExec(this, e, e.getParam()));
|
||||||
|
|
||||||
this.getData().getBeginExec().forEach(e -> getOwner().getServer().getQuestSystem().triggerExec(this, e, e.getParam()));
|
|
||||||
|
|
||||||
this.getOwner().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_QUEST_STATE_EQUAL, this.questId, this.state.getValue());
|
if (ChapterData.beginQuestChapterMap.containsKey(subQuestId)){
|
||||||
|
|
||||||
if (ChapterData.beginQuestChapterMap.containsKey(questId)) {
|
|
||||||
mainQuest.getOwner().sendPacket(new PacketChapterStateNotify(
|
mainQuest.getOwner().sendPacket(new PacketChapterStateNotify(
|
||||||
ChapterData.beginQuestChapterMap.get(questId).getId(),
|
ChapterData.beginQuestChapterMap.get(subQuestId).getId(),
|
||||||
ChapterStateOuterClass.ChapterState.CHAPTER_STATE_BEGIN
|
ChapterStateOuterClass.ChapterState.CHAPTER_STATE_BEGIN
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Grasscutter.getLogger().debug("Quest {} is started", questId);
|
//Some subQuests and talks become active when some other subQuests are unfinished (even from different MainQuests)
|
||||||
|
this.getOwner().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_QUEST_STATE_EQUAL, this.getSubQuestId(), this.getState().getValue(),0,0,0);
|
||||||
|
this.getOwner().getQuestManager().triggerEvent(QuestTrigger.QUEST_COND_STATE_EQUAL, this.getSubQuestId(), this.getState().getValue(),0,0,0);
|
||||||
|
|
||||||
|
Grasscutter.getLogger().debug("Quest {} is started", subQuestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameMainQuest getMainQuest() {
|
public String getTriggerNameById(int id) {
|
||||||
return mainQuest;
|
TriggerExcelConfigData trigger = GameData.getTriggerExcelConfigDataMap().get(id);
|
||||||
|
if(trigger != null) {
|
||||||
|
String triggerName = trigger.getTriggerName();
|
||||||
|
return triggerName;
|
||||||
}
|
}
|
||||||
|
//return empty string if can't find trigger
|
||||||
public void setMainQuest(GameMainQuest mainQuest) {
|
return "";
|
||||||
this.mainQuest = mainQuest;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player getOwner() {
|
public Player getOwner() {
|
||||||
return getMainQuest().getOwner();
|
return this.getMainQuest().getOwner();
|
||||||
}
|
|
||||||
|
|
||||||
public int getQuestId() {
|
|
||||||
return questId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMainQuestId() {
|
|
||||||
return mainQuestId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public QuestData getData() {
|
|
||||||
return questData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConfig(QuestData config) {
|
public void setConfig(QuestData config) {
|
||||||
if (this.getQuestId() != config.getId()) return;
|
if (getSubQuestId() != config.getId()) return;
|
||||||
this.questData = config;
|
this.questData = 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) {
|
public void setFinishProgress(int index, int value) {
|
||||||
finishProgressList[index] = value;
|
finishProgressList[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getFailProgressList() {
|
|
||||||
return failProgressList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFailProgress(int index, int value) {
|
public void setFailProgress(int index, int value) {
|
||||||
failProgressList[index] = value;
|
failProgressList[index] = value;
|
||||||
}
|
}
|
||||||
@ -153,100 +137,84 @@ public class GameQuest {
|
|||||||
this.state = QuestState.QUEST_STATE_FINISHED;
|
this.state = QuestState.QUEST_STATE_FINISHED;
|
||||||
this.finishTime = Utils.getCurrentSeconds();
|
this.finishTime = Utils.getCurrentSeconds();
|
||||||
|
|
||||||
if (this.getFinishProgressList() != null) {
|
if (getFinishProgressList() != null) {
|
||||||
for (int i = 0 ; i < getFinishProgressList().length; i++) {
|
Arrays.fill(getFinishProgressList(), 1);
|
||||||
getFinishProgressList()[i] = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getOwner().getSession().send(new PacketQuestProgressUpdateNotify(this));
|
getOwner().getSession().send(new PacketQuestProgressUpdateNotify(this));
|
||||||
this.getOwner().getSession().send(new PacketQuestListUpdateNotify(this));
|
|
||||||
|
|
||||||
if (this.getData().finishParent()) {
|
|
||||||
// This quest finishes the questline - the main quest will also save the quest to db so we dont have to call save() here
|
if (getQuestData().finishParent()) {
|
||||||
this.getMainQuest().finish();
|
// This quest finishes the questline - the main quest will also save the quest to db, so we don't have to call save() here
|
||||||
} else {
|
getMainQuest().finish();
|
||||||
// Try and accept other quests if possible
|
|
||||||
this.tryAcceptQuestLine();
|
|
||||||
this.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getData().getFinishExec().forEach(e -> getOwner().getServer().getQuestSystem().triggerExec(this, e, e.getParam()));
|
getQuestData().getFinishExec().forEach(e -> getOwner().getServer().getQuestSystem().triggerExec(this, e, e.getParam()));
|
||||||
|
//Some subQuests have conditions that subQuests are finished (even from different MainQuests)
|
||||||
|
getOwner().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_QUEST_STATE_EQUAL, this.subQuestId, this.state.getValue(),0,0,0);
|
||||||
|
getOwner().getQuestManager().triggerEvent(QuestTrigger.QUEST_COND_STATE_EQUAL, this.subQuestId, this.state.getValue(),0,0,0);
|
||||||
|
|
||||||
this.getOwner().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_QUEST_STATE_EQUAL, this.questId, this.state.getValue());
|
if (ChapterData.endQuestChapterMap.containsKey(subQuestId)){
|
||||||
|
|
||||||
if (ChapterData.endQuestChapterMap.containsKey(questId)) {
|
|
||||||
mainQuest.getOwner().sendPacket(new PacketChapterStateNotify(
|
mainQuest.getOwner().sendPacket(new PacketChapterStateNotify(
|
||||||
ChapterData.endQuestChapterMap.get(questId).getId(),
|
ChapterData.endQuestChapterMap.get(subQuestId).getId(),
|
||||||
ChapterStateOuterClass.ChapterState.CHAPTER_STATE_END
|
ChapterStateOuterClass.ChapterState.CHAPTER_STATE_END
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Grasscutter.getLogger().debug("Quest {} is finished", questId);
|
Grasscutter.getLogger().debug("Quest {} is finished", subQuestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean tryAcceptQuestLine() {
|
|
||||||
try {
|
|
||||||
MainQuestData questConfig = GameData.getMainQuestDataMap().get(this.getMainQuestId());
|
|
||||||
|
|
||||||
for (SubQuestData subQuest : questConfig.getSubQuests()) {
|
|
||||||
GameQuest quest = getMainQuest().getChildQuestById(subQuest.getSubId());
|
|
||||||
|
|
||||||
if (quest == null) {
|
|
||||||
QuestData questData = GameData.getQuestDataMap().get(subQuest.getSubId());
|
|
||||||
|
|
||||||
if (questData == null || questData.getAcceptCond() == null
|
|
||||||
|| questData.getAcceptCond().size() == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int[] accept = new int[questData.getAcceptCond().size()];
|
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
for (int i = 0; i < questData.getAcceptCond().size(); i++) {
|
public void fail() {
|
||||||
QuestCondition condition = questData.getAcceptCond().get(i);
|
this.state = QuestState.QUEST_STATE_FAILED;
|
||||||
boolean result = getOwner().getServer().getQuestSystem().triggerCondition(this, condition,
|
this.finishTime = Utils.getCurrentSeconds();
|
||||||
condition.getParamStr(),
|
|
||||||
condition.getParam());
|
|
||||||
|
|
||||||
accept[i] = result ? 1 : 0;
|
if (getFailProgressList() != null) {
|
||||||
|
Arrays.fill(getFailProgressList(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean shouldAccept = LogicType.calculate(questData.getAcceptCondComb(), accept);
|
getOwner().getSession().send(new PacketQuestProgressUpdateNotify(this));
|
||||||
|
|
||||||
if (shouldAccept) {
|
getQuestData().getFailExec().forEach(e -> getOwner().getServer().getQuestSystem().triggerExec(this, e, e.getParam()));
|
||||||
this.getOwner().getQuestManager().addQuest(questData.getId());
|
//Some subQuests have conditions that subQuests fail (even from different MainQuests)
|
||||||
}
|
getOwner().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_QUEST_STATE_EQUAL, this.subQuestId, this.state.getValue(),0,0,0);
|
||||||
}
|
getOwner().getQuestManager().triggerEvent(QuestTrigger.QUEST_COND_STATE_EQUAL, this.subQuestId, this.state.getValue(),0,0,0);
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Grasscutter.getLogger().error("An error occurred while trying to accept quest.", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
// Return true if ParentQuest should rewind to this childQuest
|
||||||
|
public boolean rewind(GameQuest nextRewind) {
|
||||||
|
if (questData.isRewind()) {
|
||||||
|
if(nextRewind == null) {return true;}
|
||||||
|
// if the next isRewind subQuest is none or unstarted, reset all subQuests with order higher than this one, and restart this quest
|
||||||
|
if(nextRewind.getState() == QuestState.QUEST_STATE_NONE|| nextRewind.getState() == QuestState.QUEST_STATE_UNSTARTED) {
|
||||||
|
getMainQuest().getChildQuests().values().stream().filter(p -> p.getQuestData().getOrder() > this.getQuestData().getOrder()).forEach(q -> q.setState(QuestState.QUEST_STATE_UNSTARTED));
|
||||||
|
this.start();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
getMainQuest().save();
|
getMainQuest().save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Quest toProto() {
|
public Quest toProto() {
|
||||||
Quest.Builder proto = Quest.newBuilder()
|
Quest.Builder proto = Quest.newBuilder()
|
||||||
.setQuestId(this.getQuestId())
|
.setQuestId(getSubQuestId())
|
||||||
.setState(this.getState().getValue())
|
.setState(getState().getValue())
|
||||||
.setParentQuestId(this.getMainQuestId())
|
.setParentQuestId(getMainQuestId())
|
||||||
.setStartTime(this.getStartTime())
|
.setStartTime(getStartTime())
|
||||||
.setStartGameTime(438)
|
.setStartGameTime(438)
|
||||||
.setAcceptTime(this.getAcceptTime());
|
.setAcceptTime(getAcceptTime());
|
||||||
|
|
||||||
if (this.getFinishProgressList() != null) {
|
if (getFinishProgressList() != null) {
|
||||||
for (int i : this.getFinishProgressList()) {
|
for (int i : getFinishProgressList()) {
|
||||||
proto.addFinishProgressList(i);
|
proto.addFinishProgressList(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.getFailProgressList() != null) {
|
if (getFailProgressList() != null) {
|
||||||
for (int i : this.getFailProgressList()) {
|
for (int i : getFailProgressList()) {
|
||||||
proto.addFailProgressList(i);
|
proto.addFailProgressList(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package emu.grasscutter.game.quest;
|
package emu.grasscutter.game.quest;
|
||||||
|
|
||||||
|
import java.beans.Transient;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
@ -15,28 +16,125 @@ import emu.grasscutter.game.quest.enums.QuestTrigger;
|
|||||||
import emu.grasscutter.game.quest.enums.LogicType;
|
import emu.grasscutter.game.quest.enums.LogicType;
|
||||||
import emu.grasscutter.game.quest.enums.QuestState;
|
import emu.grasscutter.game.quest.enums.QuestState;
|
||||||
import emu.grasscutter.server.packet.send.*;
|
import emu.grasscutter.server.packet.send.*;
|
||||||
|
import emu.grasscutter.utils.Position;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import jdk.jshell.spi.ExecutionControl;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
public class QuestManager extends BasePlayerManager {
|
public class QuestManager extends BasePlayerManager {
|
||||||
private final Int2ObjectMap<GameMainQuest> quests;
|
|
||||||
|
@Getter private final Player player;
|
||||||
|
@Getter private Map<Integer,Integer> questGlobalVariables;
|
||||||
|
|
||||||
|
@Getter private final Int2ObjectMap<GameMainQuest> mainQuests;
|
||||||
|
@Getter private List<GameQuest> addToQuestListUpdateNotify;
|
||||||
|
/*
|
||||||
|
On SetPlayerBornDataReq, the server sends FinishedParentQuestNotify, with this exact
|
||||||
|
parentQuestList. Captured on Game version 2.7
|
||||||
|
Note: quest 40063 is already set to finished, with childQuest 4006406's state set to 3
|
||||||
|
*/
|
||||||
|
|
||||||
|
private static Set<Integer> newPlayerMainQuests = Set.of(303,318,348,349,350,351,416,500,
|
||||||
|
501,502,503,504,505,506,507,508,509,20000,20507,20509,21004,21005,21010,21011,21016,21017,
|
||||||
|
21020,21021,21025,40063,70121,70124,70511,71010,71012,71013,71015,71016,71017,71555);
|
||||||
|
|
||||||
|
/*
|
||||||
|
On SetPlayerBornDataReq, the server sends ServerCondMeetQuestListUpdateNotify, with this exact
|
||||||
|
addQuestIdList. Captured on Game version 2.7
|
||||||
|
Total of 161...
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
private static Set<Integer> newPlayerServerCondMeetQuestListUpdateNotify = Set.of(3100101, 7104405, 2201601,
|
||||||
|
7100801, 1907002, 7293301, 7193801, 7293401, 7193901, 7091001, 7190501, 7090901, 7190401, 7090801, 7190301,
|
||||||
|
7195301, 7294801, 7195201, 7293001, 7094001, 7193501, 7293501, 7194001, 7293701, 7194201, 7194301, 7293801,
|
||||||
|
7194901, 7194101, 7195001, 7294501, 7294101, 7194601, 7294301, 7194801, 7091301, 7290301, 2102401, 7216801,
|
||||||
|
7190201, 7090701, 7093801, 7193301, 7292801, 7227828, 7093901, 7193401, 7292901, 7093701, 7193201, 7292701,
|
||||||
|
7082402, 7093601, 7292601, 7193101, 2102301, 7093501, 7292501, 7193001, 7093401, 7292401, 7192901, 7093301,
|
||||||
|
7292301, 7192801, 7294201, 7194701, 2100301, 7093201, 7212402, 7292201, 7192701, 7280001, 7293901, 7194401,
|
||||||
|
7093101, 7212302, 7292101, 7192601, 7093001, 7292001, 7192501, 7216001, 7195101, 7294601, 2100900, 7092901,
|
||||||
|
7291901, 7192401, 7092801, 7291801, 7192301, 2101501, 7092701, 7291701, 7192201, 7106401, 2100716, 7091801,
|
||||||
|
7290801, 7191301, 7293201, 7193701, 7094201, 7294001, 7194501, 2102290, 7227829, 7193601, 7094101, 7091401,
|
||||||
|
7290401, 7190901, 7106605, 7291601, 7192101, 7092601, 7291501, 7192001, 7092501, 7291401, 7191901, 7092401,
|
||||||
|
7291301, 7191801, 7092301, 7211402, 7291201, 7191701, 7092201, 7291101, 7191601, 7092101, 7291001, 7191501,
|
||||||
|
7092001, 7290901, 7191401, 7091901, 7290701, 7191201, 7091701, 7290601, 7191101, 7091601, 7290501, 7191001,
|
||||||
|
7091501, 7290201, 7190701, 7091201, 7190601, 7091101, 7190101, 7090601, 7090501, 7090401, 7010701, 7090301,
|
||||||
|
7090201, 7010103, 7090101
|
||||||
|
);
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
public static long getQuestKey(int mainQuestId){
|
public static long getQuestKey(int mainQuestId){
|
||||||
QuestEncryptionKey questEncryptionKey = GameData.getMainQuestEncryptionMap().get(mainQuestId);
|
QuestEncryptionKey questEncryptionKey = GameData.getMainQuestEncryptionMap().get(mainQuestId);
|
||||||
return questEncryptionKey != null ? questEncryptionKey.getEncryptionKey() : 0L;
|
return questEncryptionKey != null ? questEncryptionKey.getEncryptionKey() : 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
public QuestManager(Player player) {
|
public QuestManager(Player player) {
|
||||||
|
|
||||||
super(player);
|
super(player);
|
||||||
this.quests = new Int2ObjectOpenHashMap<>();
|
this.player = player;
|
||||||
|
this.questGlobalVariables = player.getQuestGlobalVariables();
|
||||||
|
this.mainQuests = new Int2ObjectOpenHashMap<>();
|
||||||
|
this.addToQuestListUpdateNotify = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Int2ObjectMap<GameMainQuest> getQuests() {
|
public void onNewPlayerCreate() {
|
||||||
return quests;
|
|
||||||
|
List<GameMainQuest> newQuests = this.addMultMainQuests(newPlayerMainQuests);
|
||||||
|
//getPlayer().sendPacket(new PacketServerCondMeetQuestListUpdateNotify(newPlayerServerCondMeetQuestListUpdateNotify));
|
||||||
|
getPlayer().sendPacket(new PacketFinishedParentQuestUpdateNotify(newQuests));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onLogin() {
|
||||||
|
|
||||||
|
List<GameMainQuest> activeQuests = getActiveMainQuests();
|
||||||
|
for(GameMainQuest quest : activeQuests) {
|
||||||
|
List<Position> rewindPos = quest.rewind(); // <pos, rotation>
|
||||||
|
if(rewindPos != null) {
|
||||||
|
getPlayer().getPosition().set(rewindPos.get(0));
|
||||||
|
getPlayer().getRotation().set(rewindPos.get(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<GameMainQuest> addMultMainQuests(Set<Integer> mainQuestIds) {
|
||||||
|
List<GameMainQuest> newQuests = new ArrayList<>();
|
||||||
|
for(Integer id : mainQuestIds) {
|
||||||
|
getMainQuests().put(id.intValue(),new GameMainQuest(this.player, id));
|
||||||
|
getMainQuestById(id).save();
|
||||||
|
newQuests.add(getMainQuestById(id));
|
||||||
|
}
|
||||||
|
return newQuests;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Looking through mainQuests 72201-72208 and 72174, we can infer that a questGlobalVar's default value is 0
|
||||||
|
*/
|
||||||
|
public Integer getQuestGlobalVarValue(Integer variable) {
|
||||||
|
return this.questGlobalVariables.getOrDefault(variable,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuestGlobalVarValue(Integer variable, Integer value) {
|
||||||
|
Integer previousValue = this.questGlobalVariables.put(variable,value);
|
||||||
|
Grasscutter.getLogger().debug("Changed questGlobalVar {} value from {} to {}", variable, previousValue==null ? 0: previousValue, value);
|
||||||
|
}
|
||||||
|
public void incQuestGlobalVarValue(Integer variable, Integer inc) {
|
||||||
|
//
|
||||||
|
Integer previousValue = this.questGlobalVariables.getOrDefault(variable,0);
|
||||||
|
this.questGlobalVariables.put(variable,previousValue + inc);
|
||||||
|
Grasscutter.getLogger().debug("Incremented questGlobalVar {} value from {} to {}", variable, previousValue, previousValue + inc);
|
||||||
|
}
|
||||||
|
//In MainQuest 998, dec is passed as a positive integer
|
||||||
|
public void decQuestGlobalVarValue(Integer variable, Integer dec) {
|
||||||
|
//
|
||||||
|
Integer previousValue = this.questGlobalVariables.getOrDefault(variable,0);
|
||||||
|
this.questGlobalVariables.put(variable,previousValue - dec);
|
||||||
|
Grasscutter.getLogger().debug("Decremented questGlobalVar {} value from {} to {}", variable, previousValue, previousValue - dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameMainQuest getMainQuestById(int mainQuestId) {
|
public GameMainQuest getMainQuestById(int mainQuestId) {
|
||||||
return getQuests().get(mainQuestId);
|
return getMainQuests().get(mainQuestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameQuest getQuestById(int questId) {
|
public GameQuest getQuestById(int questId) {
|
||||||
@ -45,7 +143,7 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameMainQuest mainQuest = getQuests().get(questConfig.getMainId());
|
GameMainQuest mainQuest = getMainQuests().get(questConfig.getMainId());
|
||||||
|
|
||||||
if (mainQuest == null) {
|
if (mainQuest == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -55,7 +153,7 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void forEachQuest(Consumer<GameQuest> callback) {
|
public void forEachQuest(Consumer<GameQuest> callback) {
|
||||||
for (GameMainQuest mainQuest : getQuests().values()) {
|
for (GameMainQuest mainQuest : getMainQuests().values()) {
|
||||||
for (GameQuest quest : mainQuest.getChildQuests().values()) {
|
for (GameQuest quest : mainQuest.getChildQuests().values()) {
|
||||||
callback.accept(quest);
|
callback.accept(quest);
|
||||||
}
|
}
|
||||||
@ -63,14 +161,14 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void forEachMainQuest(Consumer<GameMainQuest> callback) {
|
public void forEachMainQuest(Consumer<GameMainQuest> callback) {
|
||||||
for (GameMainQuest mainQuest : getQuests().values()) {
|
for (GameMainQuest mainQuest : getMainQuests().values()) {
|
||||||
callback.accept(mainQuest);
|
callback.accept(mainQuest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
public void forEachActiveQuest(Consumer<GameQuest> callback) {
|
public void forEachActiveQuest(Consumer<GameQuest> callback) {
|
||||||
for (GameMainQuest mainQuest : getQuests().values()) {
|
for (GameMainQuest mainQuest : getMainQuests().values()) {
|
||||||
for (GameQuest quest : mainQuest.getChildQuests().values()) {
|
for (GameQuest quest : mainQuest.getChildQuests().values()) {
|
||||||
if (quest.getState() != QuestState.QUEST_STATE_FINISHED) {
|
if (quest.getState() != QuestState.QUEST_STATE_FINISHED) {
|
||||||
callback.accept(quest);
|
callback.accept(quest);
|
||||||
@ -81,7 +179,7 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
|
|
||||||
public GameMainQuest addMainQuest(QuestData questConfig) {
|
public GameMainQuest addMainQuest(QuestData questConfig) {
|
||||||
GameMainQuest mainQuest = new GameMainQuest(getPlayer(), questConfig.getMainId());
|
GameMainQuest mainQuest = new GameMainQuest(getPlayer(), questConfig.getMainId());
|
||||||
getQuests().put(mainQuest.getParentQuestId(), mainQuest);
|
getMainQuests().put(mainQuest.getParentQuestId(), mainQuest);
|
||||||
|
|
||||||
getPlayer().sendPacket(new PacketFinishedParentQuestUpdateNotify(mainQuest));
|
getPlayer().sendPacket(new PacketFinishedParentQuestUpdateNotify(mainQuest));
|
||||||
|
|
||||||
@ -105,18 +203,16 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
// Sub quest
|
// Sub quest
|
||||||
GameQuest quest = mainQuest.getChildQuestById(questId);
|
GameQuest quest = mainQuest.getChildQuestById(questId);
|
||||||
|
|
||||||
if (quest != null) {
|
// Forcefully start
|
||||||
return null;
|
quest.start();
|
||||||
}
|
|
||||||
|
|
||||||
// Create
|
|
||||||
quest = new GameQuest(mainQuest, questConfig);
|
|
||||||
|
|
||||||
// Save main quest
|
// Save main quest
|
||||||
mainQuest.save();
|
mainQuest.save();
|
||||||
|
|
||||||
// Send packet
|
// Send packet
|
||||||
getPlayer().sendPacket(new PacketQuestListUpdateNotify(quest));
|
getPlayer().sendPacket(new PacketQuestListUpdateNotify(mainQuest.getChildQuests().values().stream()
|
||||||
|
.filter(p -> p.getState() != QuestState.QUEST_STATE_UNSTARTED)
|
||||||
|
.toList()));
|
||||||
|
|
||||||
return quest;
|
return quest;
|
||||||
}
|
}
|
||||||
@ -136,55 +232,81 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
triggerEvent(condType, "", params);
|
triggerEvent(condType, "", params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO
|
||||||
public void triggerEvent(QuestTrigger condType, String paramStr, int... params) {
|
public void triggerEvent(QuestTrigger condType, String paramStr, int... params) {
|
||||||
Grasscutter.getLogger().debug("Trigger Event {}, {}, {}", condType, paramStr, params);
|
Grasscutter.getLogger().debug("Trigger Event {}, {}, {}", condType, paramStr, params);
|
||||||
Set<GameQuest> changedQuests = new HashSet<>();
|
List<GameMainQuest> checkMainQuests = this.getMainQuests().values().stream()
|
||||||
|
.filter(i -> i.getState() != ParentQuestState.PARENT_QUEST_STATE_FINISHED)
|
||||||
|
.toList();
|
||||||
|
switch(condType){
|
||||||
|
//accept Conds
|
||||||
|
case QUEST_COND_STATE_EQUAL:
|
||||||
|
case QUEST_COND_STATE_NOT_EQUAL:
|
||||||
|
case QUEST_COND_COMPLETE_TALK:
|
||||||
|
case QUEST_COND_LUA_NOTIFY:
|
||||||
|
case QUEST_COND_QUEST_VAR_EQUAL:
|
||||||
|
case QUEST_COND_QUEST_VAR_GREATER:
|
||||||
|
case QUEST_COND_QUEST_VAR_LESS:
|
||||||
|
case QUEST_COND_PLAYER_LEVEL_EQUAL_GREATER:
|
||||||
|
case QUEST_COND_QUEST_GLOBAL_VAR_EQUAL:
|
||||||
|
case QUEST_COND_QUEST_GLOBAL_VAR_GREATER:
|
||||||
|
case QUEST_COND_QUEST_GLOBAL_VAR_LESS:
|
||||||
|
for (GameMainQuest mainquest : checkMainQuests) {
|
||||||
|
mainquest.tryAcceptSubQuests(condType, paramStr, params);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
this.forEachActiveQuest(quest -> {
|
//fail Conds
|
||||||
QuestData data = quest.getData();
|
case QUEST_CONTENT_NOT_FINISH_PLOT:
|
||||||
|
for (GameMainQuest mainquest : checkMainQuests) {
|
||||||
|
mainquest.tryFailSubQuests(condType, paramStr, params);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
//finish Conds
|
||||||
|
case QUEST_CONTENT_COMPLETE_TALK:
|
||||||
|
case QUEST_CONTENT_FINISH_PLOT:
|
||||||
|
case QUEST_CONTENT_COMPLETE_ANY_TALK:
|
||||||
|
case QUEST_CONTENT_LUA_NOTIFY:
|
||||||
|
case QUEST_CONTENT_QUEST_VAR_EQUAL:
|
||||||
|
case QUEST_CONTENT_QUEST_VAR_GREATER:
|
||||||
|
case QUEST_CONTENT_QUEST_VAR_LESS:
|
||||||
|
case QUEST_CONTENT_ENTER_DUNGEON:
|
||||||
|
case QUEST_CONTENT_ENTER_ROOM:
|
||||||
|
case QUEST_CONTENT_INTERACT_GADGET:
|
||||||
|
case QUEST_CONTENT_TRIGGER_FIRE:
|
||||||
|
case QUEST_CONTENT_UNLOCK_TRANS_POINT:
|
||||||
|
for (GameMainQuest mainQuest : checkMainQuests) {
|
||||||
|
mainQuest.tryFinishSubQuests(condType, paramStr, params);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
for (int i = 0; i < data.getFinishCond().size(); i++) {
|
//finish Or Fail Conds
|
||||||
if (quest.getFinishProgressList() == null
|
case QUEST_CONTENT_GAME_TIME_TICK:
|
||||||
|| quest.getFinishProgressList().length == 0
|
case QUEST_CONTENT_QUEST_STATE_EQUAL:
|
||||||
|| quest.getFinishProgressList()[i] == 1) {
|
case QUEST_CONTENT_ADD_QUEST_PROGRESS:
|
||||||
continue;
|
case QUEST_CONTENT_LEAVE_SCENE:
|
||||||
|
for (GameMainQuest mainQuest : checkMainQuests) {
|
||||||
|
mainQuest.tryFailSubQuests(condType, paramStr, params);
|
||||||
|
mainQuest.tryFinishSubQuests(condType, paramStr, params);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
//QUEST_EXEC are handled directly by each subQuest
|
||||||
|
|
||||||
|
//Unused
|
||||||
|
case QUEST_CONTENT_QUEST_STATE_NOT_EQUAL:
|
||||||
|
case QUEST_COND_PLAYER_CHOOSE_MALE:
|
||||||
|
default:
|
||||||
|
Grasscutter.getLogger().error("Unhandled QuestTrigger {}", condType);
|
||||||
|
}
|
||||||
|
if(this.addToQuestListUpdateNotify.size() != 0){
|
||||||
|
this.getPlayer().getSession().send(new PacketQuestListUpdateNotify(this.addToQuestListUpdateNotify));
|
||||||
|
this.addToQuestListUpdateNotify.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QuestCondition condition = data.getFinishCond().get(i);
|
|
||||||
|
|
||||||
if (condition.getType() != condType) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean result = getPlayer().getServer().getQuestSystem().triggerContent(quest, condition, paramStr, params);
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
quest.getFinishProgressList()[i] = 1;
|
|
||||||
|
|
||||||
changedQuests.add(quest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for (GameQuest quest : changedQuests) {
|
|
||||||
LogicType logicType = quest.getData().getFailCondComb();
|
|
||||||
int[] progress = quest.getFinishProgressList();
|
|
||||||
|
|
||||||
// Handle logical comb
|
|
||||||
boolean finish = LogicType.calculate(logicType, progress);
|
|
||||||
|
|
||||||
// Finish
|
|
||||||
if (finish) {
|
|
||||||
quest.finish();
|
|
||||||
} else {
|
|
||||||
getPlayer().sendPacket(new PacketQuestProgressUpdateNotify(quest));
|
|
||||||
quest.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<QuestGroupSuite> getSceneGroupSuite(int sceneId) {
|
public List<QuestGroupSuite> getSceneGroupSuite(int sceneId) {
|
||||||
return getQuests().values().stream()
|
return getMainQuests().values().stream()
|
||||||
.filter(i -> i.getState() != ParentQuestState.PARENT_QUEST_STATE_FINISHED)
|
.filter(i -> i.getState() != ParentQuestState.PARENT_QUEST_STATE_FINISHED)
|
||||||
.map(GameMainQuest::getQuestGroupSuites)
|
.map(GameMainQuest::getQuestGroupSuites)
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
@ -200,10 +322,14 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
|
|
||||||
for (GameQuest quest : mainQuest.getChildQuests().values()) {
|
for (GameQuest quest : mainQuest.getChildQuests().values()) {
|
||||||
quest.setMainQuest(mainQuest);
|
quest.setMainQuest(mainQuest);
|
||||||
quest.setConfig(GameData.getQuestDataMap().get(quest.getQuestId()));
|
quest.setConfig(GameData.getQuestDataMap().get(quest.getSubQuestId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getQuests().put(mainQuest.getParentQuestId(), mainQuest);
|
this.getMainQuests().put(mainQuest.getParentQuestId(), mainQuest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<GameMainQuest> getActiveMainQuests() {
|
||||||
|
return getMainQuests().values().stream().filter(p -> !p.isFinished()).toList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,8 +65,8 @@ public class QuestSystem extends BaseGameSystem {
|
|||||||
public boolean triggerCondition(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
public boolean triggerCondition(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
||||||
QuestBaseHandler handler = condHandlers.get(condition.getType().getValue());
|
QuestBaseHandler handler = condHandlers.get(condition.getType().getValue());
|
||||||
|
|
||||||
if (handler == null || quest.getData() == null) {
|
if (handler == null || quest.getQuestData() == null) {
|
||||||
Grasscutter.getLogger().debug("Could not trigger condition {} at {}", condition.getType().getValue(), quest.getData());
|
Grasscutter.getLogger().debug("Could not trigger condition {} at {}", condition.getType().getValue(), quest.getQuestData());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,8 +76,8 @@ public class QuestSystem extends BaseGameSystem {
|
|||||||
public boolean triggerContent(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
public boolean triggerContent(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
||||||
QuestBaseHandler handler = contHandlers.get(condition.getType().getValue());
|
QuestBaseHandler handler = contHandlers.get(condition.getType().getValue());
|
||||||
|
|
||||||
if (handler == null || quest.getData() == null) {
|
if (handler == null || quest.getQuestData() == null) {
|
||||||
Grasscutter.getLogger().debug("Could not trigger content {} at {}", condition.getType().getValue(), quest.getData());
|
Grasscutter.getLogger().debug("Could not trigger content {} at {}", condition.getType().getValue(), quest.getQuestData());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,8 +87,8 @@ public class QuestSystem extends BaseGameSystem {
|
|||||||
public boolean triggerExec(GameQuest quest, QuestExecParam execParam, String... params) {
|
public boolean triggerExec(GameQuest quest, QuestExecParam execParam, String... params) {
|
||||||
QuestExecHandler handler = execHandlers.get(execParam.getType().getValue());
|
QuestExecHandler handler = execHandlers.get(execParam.getType().getValue());
|
||||||
|
|
||||||
if (handler == null || quest.getData() == null) {
|
if (handler == null || quest.getQuestData() == null) {
|
||||||
Grasscutter.getLogger().debug("Could not trigger exec {} at {}", execParam.getType().getValue(), quest.getData());
|
Grasscutter.getLogger().debug("Could not trigger exec {} at {}", execParam.getType().getValue(), quest.getQuestData());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
src/main/java/emu/grasscutter/game/quest/RewindData.java
Normal file
28
src/main/java/emu/grasscutter/game/quest/RewindData.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package emu.grasscutter.game.quest;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
@Data
|
||||||
|
public class RewindData {
|
||||||
|
AvatarData avatar;
|
||||||
|
List<Npc> npcs;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class AvatarData {
|
||||||
|
@Getter private String pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
private static class Npc {
|
||||||
|
private String script;
|
||||||
|
private int room_id;
|
||||||
|
private int data_index;
|
||||||
|
private int id;
|
||||||
|
private String pos;
|
||||||
|
private int scene_id;
|
||||||
|
private String alias;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
package emu.grasscutter.game.quest.conditions;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.GameData;
|
||||||
|
import emu.grasscutter.data.binout.MainQuestData;
|
||||||
|
import emu.grasscutter.data.excels.QuestData;
|
||||||
|
import emu.grasscutter.game.quest.GameMainQuest;
|
||||||
|
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_COND_COMPLETE_TALK)
|
||||||
|
public class ConditionCompleteTalk extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
GameMainQuest checkMainQuest = quest.getOwner().getQuestManager().getMainQuestById(condition.getParam()[0]/100);
|
||||||
|
if (checkMainQuest == null || GameData.getMainQuestDataMap().get(checkMainQuest.getParentQuestId()).getTalks() == null) {
|
||||||
|
Grasscutter.getLogger().debug("Warning: mainQuest {} hasn't been started yet, or has no talks", condition.getParam()[0]/100);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
MainQuestData.TalkData talkData = checkMainQuest.getTalks().get(Integer.valueOf(params[0]));
|
||||||
|
return talkData != null || checkMainQuest.getChildQuestById(params[0]) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -8,7 +8,7 @@ import emu.grasscutter.game.quest.handlers.QuestBaseHandler;
|
|||||||
|
|
||||||
@QuestValue(QuestTrigger.QUEST_COND_LUA_NOTIFY)
|
@QuestValue(QuestTrigger.QUEST_COND_LUA_NOTIFY)
|
||||||
public class ConditionLuaNotify extends QuestBaseHandler {
|
public class ConditionLuaNotify extends QuestBaseHandler {
|
||||||
|
//Wrong implementation. Example: 7010226 has no paramStr
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
||||||
return condition.getParam()[0] == Integer.parseInt(paramStr);
|
return condition.getParam()[0] == Integer.parseInt(paramStr);
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package emu.grasscutter.game.quest.conditions;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.excels.QuestData;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
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_COND_QUEST_GLOBAL_VAR_EQUAL)
|
||||||
|
public class ConditionQuestGlobalVarEqual extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
Integer questGlobalVarValue = quest.getMainQuest().getQuestManager().getQuestGlobalVarValue(Integer.valueOf(params[0]));
|
||||||
|
Grasscutter.getLogger().debug("questGlobarVar {} : {}", params[0],questGlobalVarValue);
|
||||||
|
return questGlobalVarValue.intValue() == params[1];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package emu.grasscutter.game.quest.conditions;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.excels.QuestData;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
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_COND_QUEST_GLOBAL_VAR_GREATER)
|
||||||
|
public class ConditionQuestGlobalVarGreater extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
Integer questGlobalVarValue = quest.getMainQuest().getQuestManager().getQuestGlobalVarValue(Integer.valueOf(params[0]));
|
||||||
|
Grasscutter.getLogger().debug("questGlobarVar {} : {}", params[0],questGlobalVarValue);
|
||||||
|
return questGlobalVarValue.intValue() > params[1];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package emu.grasscutter.game.quest.conditions;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.excels.QuestData;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
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_COND_QUEST_GLOBAL_VAR_LESS)
|
||||||
|
public class ConditionQuestGlobalVarLess extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
Integer questGlobalVarValue = quest.getMainQuest().getQuestManager().getQuestGlobalVarValue(Integer.valueOf(params[0]));
|
||||||
|
Grasscutter.getLogger().debug("questGlobarVar {} : {}", params[0],questGlobalVarValue);
|
||||||
|
return questGlobalVarValue.intValue() < params[1];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package emu.grasscutter.game.quest.conditions;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.excels.QuestData;
|
||||||
|
import emu.grasscutter.game.quest.GameMainQuest;
|
||||||
|
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_COND_QUEST_VAR_EQUAL)
|
||||||
|
public class ConditionQuestVarEqual extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
int questVarValue = quest.getMainQuest().getQuestVars()[params[0]];
|
||||||
|
Grasscutter.getLogger().debug("questVar {} : {}", params[0],questVarValue);
|
||||||
|
return questVarValue == params[1];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package emu.grasscutter.game.quest.conditions;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.excels.QuestData;
|
||||||
|
import emu.grasscutter.game.quest.GameMainQuest;
|
||||||
|
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_COND_QUEST_VAR_GREATER)
|
||||||
|
public class ConditionQuestVarGreater extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
int questVarValue = quest.getMainQuest().getQuestVars()[params[0]];
|
||||||
|
Grasscutter.getLogger().debug("questVar {} : {}", params[0],questVarValue);
|
||||||
|
return questVarValue > params[1];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package emu.grasscutter.game.quest.conditions;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.excels.QuestData;
|
||||||
|
import emu.grasscutter.game.quest.GameMainQuest;
|
||||||
|
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_COND_QUEST_VAR_LESS)
|
||||||
|
public class ConditionQuestVarLess extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
int questVarValue = quest.getMainQuest().getQuestVars()[params[0]];
|
||||||
|
Grasscutter.getLogger().debug("questVar {} : {}", params[0],questVarValue);
|
||||||
|
return questVarValue < params[1];
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package emu.grasscutter.game.quest.conditions;
|
package emu.grasscutter.game.quest.conditions;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.game.quest.QuestValue;
|
import emu.grasscutter.game.quest.QuestValue;
|
||||||
import emu.grasscutter.data.excels.QuestData.QuestCondition;
|
import emu.grasscutter.data.excels.QuestData.QuestCondition;
|
||||||
import emu.grasscutter.game.quest.GameQuest;
|
import emu.grasscutter.game.quest.GameQuest;
|
||||||
@ -11,13 +12,16 @@ public class ConditionStateEqual extends QuestBaseHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
||||||
GameQuest checkQuest = quest.getOwner().getQuestManager().getQuestById(params[0]);
|
GameQuest checkQuest = quest.getOwner().getQuestManager().getQuestById(condition.getParam()[0]);
|
||||||
|
if (checkQuest == null) {
|
||||||
if (checkQuest != null) {
|
/*
|
||||||
return checkQuest.getState().getValue() == params[1];
|
Will spam the console
|
||||||
}
|
//Grasscutter.getLogger().debug("Warning: quest {} hasn't been started yet!", condition.getParam()[0]);
|
||||||
|
|
||||||
|
*/
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return checkQuest.getState().getValue() == condition.getParam()[1];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package emu.grasscutter.game.quest.conditions;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
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.QuestBaseHandler;
|
||||||
|
|
||||||
|
@QuestValue(QuestTrigger.QUEST_COND_STATE_NOT_EQUAL)
|
||||||
|
public class ConditionStateNotEqual extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
GameQuest checkQuest = quest.getOwner().getQuestManager().getQuestById(condition.getParam()[0]);
|
||||||
|
if (checkQuest == null) {
|
||||||
|
/*
|
||||||
|
Will spam the console
|
||||||
|
//Grasscutter.getLogger().debug("Warning: quest {} hasn't been started yet!", condition.getParam()[0]);
|
||||||
|
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return checkQuest.getState().getValue() != condition.getParam()[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -11,7 +11,12 @@ public class ContentAddQuestProgress extends QuestBaseHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
||||||
return condition.getParam()[0] == params[0];
|
/*
|
||||||
|
//paramStr is a lua group, params[0] may also be a lua group!
|
||||||
|
questid = xxxxxx lua group = xxxxxxyy
|
||||||
|
count seems relevant only for lua group
|
||||||
|
*/
|
||||||
|
return condition.getParam()[0] == params[0]; //missing params[1], paramStr, and count
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package emu.grasscutter.game.quest.content;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.binout.MainQuestData;
|
||||||
|
import emu.grasscutter.data.excels.QuestData;
|
||||||
|
import emu.grasscutter.game.quest.GameMainQuest;
|
||||||
|
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_COMPLETE_ANY_TALK)
|
||||||
|
public class ContentCompleteAnyTalk extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
GameMainQuest checkMainQuest = quest.getOwner().getQuestManager().getMainQuestById(params[0]/100);
|
||||||
|
if (checkMainQuest == null) {return false;}
|
||||||
|
MainQuestData.TalkData talkData = checkMainQuest.getTalks().get(Integer.valueOf(paramStr));
|
||||||
|
return talkData == null || condition.getParamStr().contains(paramStr) || checkMainQuest.getChildQuestById(params[0]) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,10 @@
|
|||||||
package emu.grasscutter.game.quest.content;
|
package emu.grasscutter.game.quest.content;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.binout.MainQuestData;
|
||||||
|
import emu.grasscutter.game.quest.GameMainQuest;
|
||||||
|
import emu.grasscutter.game.quest.GameQuest;
|
||||||
import emu.grasscutter.game.quest.QuestValue;
|
import emu.grasscutter.game.quest.QuestValue;
|
||||||
import emu.grasscutter.data.excels.QuestData.QuestCondition;
|
import emu.grasscutter.data.excels.QuestData.QuestCondition;
|
||||||
import emu.grasscutter.game.quest.GameQuest;
|
|
||||||
import emu.grasscutter.game.quest.enums.QuestTrigger;
|
import emu.grasscutter.game.quest.enums.QuestTrigger;
|
||||||
import emu.grasscutter.game.quest.handlers.QuestBaseHandler;
|
import emu.grasscutter.game.quest.handlers.QuestBaseHandler;
|
||||||
|
|
||||||
@ -11,7 +13,9 @@ public class ContentCompleteTalk extends QuestBaseHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
||||||
return condition.getParam()[0] == params[0];
|
GameMainQuest checkMainQuest = quest.getOwner().getQuestManager().getMainQuestById(params[0]/100);
|
||||||
|
if (checkMainQuest == null) {return false;}
|
||||||
|
MainQuestData.TalkData talkData = checkMainQuest.getTalks().get(Integer.valueOf(params[0]));
|
||||||
|
return talkData == null || condition.getParamStr().contains(paramStr) || checkMainQuest.getChildQuestById(params[0]) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ public class ContentEnterDungeon extends QuestBaseHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, 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]; //missing params[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package emu.grasscutter.game.quest.content;
|
package emu.grasscutter.game.quest.content;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.binout.MainQuestData;
|
||||||
|
import emu.grasscutter.game.quest.GameMainQuest;
|
||||||
import emu.grasscutter.game.quest.QuestValue;
|
import emu.grasscutter.game.quest.QuestValue;
|
||||||
import emu.grasscutter.data.excels.QuestData.QuestCondition;
|
import emu.grasscutter.data.excels.QuestData.QuestCondition;
|
||||||
import emu.grasscutter.game.quest.GameQuest;
|
import emu.grasscutter.game.quest.GameQuest;
|
||||||
@ -11,7 +13,9 @@ public class ContentFinishPlot extends QuestBaseHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
||||||
return condition.getParam()[0] == params[0];
|
MainQuestData.TalkData talkData = quest.getMainQuest().getTalks().get(Integer.valueOf(params[0]));
|
||||||
|
GameQuest subQuest = quest.getMainQuest().getChildQuestById(params[0]);
|
||||||
|
return talkData != null || subQuest != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
package emu.grasscutter.game.quest.content;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.excels.QuestData.QuestCondition;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
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_LEAVE_SCENE)
|
||||||
|
public class ContentLeaveScene extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
||||||
|
return quest.getOwner().getScene().getPrevScene() == params[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package emu.grasscutter.game.quest.content;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.binout.MainQuestData;
|
||||||
|
import emu.grasscutter.data.excels.QuestData;
|
||||||
|
import emu.grasscutter.game.quest.GameMainQuest;
|
||||||
|
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_NOT_FINISH_PLOT)
|
||||||
|
public class ContentNotFinishPlot extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
GameMainQuest checkMainQuest = quest.getOwner().getQuestManager().getMainQuestById(params[0]/100);
|
||||||
|
if (checkMainQuest == null) {return false;}
|
||||||
|
MainQuestData.TalkData talkData = checkMainQuest.getTalks().get(Integer.valueOf(params[0]));
|
||||||
|
return talkData == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -11,13 +11,9 @@ public class ContentQuestStateEqual extends QuestBaseHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
public boolean execute(GameQuest quest, QuestCondition condition, String paramStr, int... params) {
|
||||||
GameQuest checkQuest = quest.getOwner().getQuestManager().getQuestById(params[0]);
|
GameQuest checkQuest = quest.getOwner().getQuestManager().getQuestById(condition.getParam()[0]);
|
||||||
|
if (checkQuest == null) {return false;}
|
||||||
if (checkQuest != null) {
|
|
||||||
return checkQuest.getState().getValue() == params[1];
|
return checkQuest.getState().getValue() == params[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package emu.grasscutter.game.quest.content;
|
||||||
|
|
||||||
|
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.QuestBaseHandler;
|
||||||
|
|
||||||
|
@QuestValue(QuestTrigger.QUEST_CONTENT_QUEST_STATE_NOT_EQUAL)
|
||||||
|
public class ContentQuestStateNotEqual extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package emu.grasscutter.game.quest.content;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
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.QuestBaseHandler;
|
||||||
|
|
||||||
|
@QuestValue(QuestTrigger.QUEST_CONTENT_QUEST_VAR_EQUAL)
|
||||||
|
public class ContentQuestVarEqual extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
int questVarValue = quest.getMainQuest().getQuestVars()[params[0]];
|
||||||
|
Grasscutter.getLogger().debug("questVar {} : {}", params[0],questVarValue);
|
||||||
|
return questVarValue == params[1];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package emu.grasscutter.game.quest.content;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
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.QuestBaseHandler;
|
||||||
|
|
||||||
|
@QuestValue(QuestTrigger.QUEST_CONTENT_QUEST_VAR_GREATER)
|
||||||
|
public class ContentQuestVarGreater extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
int questVarValue = quest.getMainQuest().getQuestVars()[params[0]];
|
||||||
|
Grasscutter.getLogger().debug("questVar {} : {}", params[0],questVarValue);
|
||||||
|
return questVarValue > params[1];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package emu.grasscutter.game.quest.content;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
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.QuestBaseHandler;
|
||||||
|
|
||||||
|
@QuestValue(QuestTrigger.QUEST_CONTENT_QUEST_VAR_LESS)
|
||||||
|
public class ContentQuestVarLess extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
int questVarValue = quest.getMainQuest().getQuestVars()[params[0]];
|
||||||
|
Grasscutter.getLogger().debug("questVar {} : {}", params[0],questVarValue);
|
||||||
|
return questVarValue < params[1];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package emu.grasscutter.game.quest.content;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.GameData;
|
||||||
|
import emu.grasscutter.data.excels.QuestData;
|
||||||
|
import emu.grasscutter.data.excels.TriggerExcelConfigData;
|
||||||
|
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_TRIGGER_FIRE)
|
||||||
|
public class ContentTriggerFire extends QuestBaseHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
if(quest.getTriggers().containsKey(quest.getTriggerNameById(params[0]))) {
|
||||||
|
//We don't want to put a new key here
|
||||||
|
return quest.getTriggers().get(quest.getTriggerNameById(params[0]));
|
||||||
|
} else {
|
||||||
|
Grasscutter.getLogger().error("quest {} doesn't have trigger {}", quest.getSubQuestId(), params[0]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package emu.grasscutter.game.quest.content;
|
||||||
|
|
||||||
|
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.QuestBaseHandler;
|
||||||
|
|
||||||
|
@QuestValue(QuestTrigger.QUEST_CONTENT_UNLOCK_TRANS_POINT)
|
||||||
|
public class ContentUnlockTransPoint extends QuestBaseHandler {
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestCondition condition, String paramStr, int... params) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,14 @@ public enum QuestState {
|
|||||||
QUEST_STATE_UNSTARTED (1),
|
QUEST_STATE_UNSTARTED (1),
|
||||||
QUEST_STATE_UNFINISHED (2),
|
QUEST_STATE_UNFINISHED (2),
|
||||||
QUEST_STATE_FINISHED (3),
|
QUEST_STATE_FINISHED (3),
|
||||||
QUEST_STATE_FAILED (4);
|
QUEST_STATE_FAILED (4),
|
||||||
|
|
||||||
|
// Used by lua
|
||||||
|
NONE (0),
|
||||||
|
UNSTARTED(1),
|
||||||
|
UNFINISHED(2),
|
||||||
|
FINISHED(3),
|
||||||
|
FAILED(4);
|
||||||
|
|
||||||
private final int value;
|
private final int value;
|
||||||
|
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
@QuestValue(QuestTrigger.QUEST_EXEC_DEC_QUEST_GLOBAL_VAR)
|
||||||
|
public class ExecDecQuestGlobalVar extends QuestExecHandler {
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) {
|
||||||
|
quest.getOwner().getQuestManager().decQuestGlobalVarValue(Integer.valueOf(paramStr[0]),Integer.valueOf(paramStr[1]));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
@QuestValue(QuestTrigger.QUEST_EXEC_DEC_QUEST_VAR)
|
||||||
|
public class ExecDecQuestVar extends QuestExecHandler {
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) {
|
||||||
|
quest.getMainQuest().decQuestVar(Integer.parseInt(paramStr[0]), Integer.parseInt(paramStr[1]));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
@QuestValue(QuestTrigger.QUEST_EXEC_INC_QUEST_GLOBAL_VAR)
|
||||||
|
public class ExecIncQuestGlobalVar extends QuestExecHandler {
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) {
|
||||||
|
quest.getOwner().getQuestManager().incQuestGlobalVarValue(Integer.valueOf(paramStr[0]),Integer.valueOf(paramStr[1]));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
@QuestValue(QuestTrigger.QUEST_EXEC_INC_QUEST_VAR)
|
||||||
|
public class ExecIncQuestVar extends QuestExecHandler {
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) {
|
||||||
|
quest.getMainQuest().incQuestVar(Integer.parseInt(paramStr[0]), Integer.parseInt(paramStr[1]));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
@QuestValue(QuestTrigger.QUEST_EXEC_SET_QUEST_GLOBAL_VAR)
|
||||||
|
public class ExecSetQuestGlobalVar extends QuestExecHandler {
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) {
|
||||||
|
quest.getOwner().getQuestManager().setQuestGlobalVarValue(Integer.valueOf(paramStr[0]),Integer.valueOf(paramStr[1]));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
@QuestValue(QuestTrigger.QUEST_EXEC_SET_QUEST_VAR)
|
||||||
|
public class ExecSetQuestVar extends QuestExecHandler {
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) {
|
||||||
|
quest.getMainQuest().setQuestVar(Integer.parseInt(paramStr[0]), Integer.parseInt(paramStr[1]));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -630,6 +630,12 @@ public class Scene {
|
|||||||
onLoadGroup(groups);
|
onLoadGroup(groups);
|
||||||
Grasscutter.getLogger().info("Scene {} Block {} loaded.", this.getId(), block.id);
|
Grasscutter.getLogger().info("Scene {} Block {} loaded.", this.getId(), block.id);
|
||||||
}
|
}
|
||||||
|
public void loadTriggerFromGroup(SceneGroup group, String triggerName) {
|
||||||
|
//Load triggers and regions
|
||||||
|
getScriptManager().registerTrigger(group.triggers.values().stream().filter(p -> p.name.contains(triggerName)).toList());
|
||||||
|
group.regions.values().stream().filter(q -> q.config_id == Integer.parseInt(triggerName.substring(13))).map(region -> new EntityRegion(this, region))
|
||||||
|
.forEach(getScriptManager()::registerRegion);
|
||||||
|
}
|
||||||
|
|
||||||
public void onLoadGroup(List<SceneGroup> groups) {
|
public void onLoadGroup(List<SceneGroup> groups) {
|
||||||
if (groups == null || groups.isEmpty()) {
|
if (groups == null || groups.isEmpty()) {
|
||||||
|
@ -92,6 +92,7 @@ public class SceneScriptManager {
|
|||||||
}
|
}
|
||||||
public void registerTrigger(SceneTrigger trigger) {
|
public void registerTrigger(SceneTrigger trigger) {
|
||||||
getTriggersByEvent(trigger.event).add(trigger);
|
getTriggersByEvent(trigger.event).add(trigger);
|
||||||
|
Grasscutter.getLogger().debug("Registered trigger {}", trigger.name);
|
||||||
}
|
}
|
||||||
public void deregisterTrigger(List<SceneTrigger> triggers) {
|
public void deregisterTrigger(List<SceneTrigger> triggers) {
|
||||||
triggers.forEach(this::deregisterTrigger);
|
triggers.forEach(this::deregisterTrigger);
|
||||||
@ -122,6 +123,7 @@ public class SceneScriptManager {
|
|||||||
|
|
||||||
public void registerRegion(EntityRegion region) {
|
public void registerRegion(EntityRegion region) {
|
||||||
regions.put(region.getId(), region);
|
regions.put(region.getId(), region);
|
||||||
|
Grasscutter.getLogger().debug("Registered region {} from group {}", region.getMetaRegion().config_id, region.getGroupId());
|
||||||
}
|
}
|
||||||
public void registerRegionInGroupSuite(SceneGroup group, SceneSuite suite){
|
public void registerRegionInGroupSuite(SceneGroup group, SceneSuite suite){
|
||||||
suite.sceneRegions.stream().map(region -> new EntityRegion(this.getScene(), region))
|
suite.sceneRegions.stream().map(region -> new EntityRegion(this.getScene(), region))
|
||||||
@ -195,9 +197,30 @@ public class SceneScriptManager {
|
|||||||
.filter(e -> e.getEntityType() == EntityType.Avatar.getValue() && region.getMetaRegion().contains(e.getPosition()))
|
.filter(e -> e.getEntityType() == EntityType.Avatar.getValue() && region.getMetaRegion().contains(e.getPosition()))
|
||||||
.forEach(region::addEntity);
|
.forEach(region::addEntity);
|
||||||
|
|
||||||
|
var players = region.getScene().getPlayers();
|
||||||
|
int targetID = 0;
|
||||||
|
if(players.size() > 0)
|
||||||
|
targetID = players.get(0).getUid();
|
||||||
|
|
||||||
if (region.hasNewEntities()) {
|
if (region.hasNewEntities()) {
|
||||||
|
Grasscutter.getLogger().trace("Call EVENT_ENTER_REGION_{}",region.getMetaRegion().config_id);
|
||||||
callEvent(EventType.EVENT_ENTER_REGION, new ScriptArgs(region.getConfigId())
|
callEvent(EventType.EVENT_ENTER_REGION, new ScriptArgs(region.getConfigId())
|
||||||
.setSourceEntityId(region.getId())
|
.setSourceEntityId(region.getId())
|
||||||
|
.setTargetEntityId(targetID)
|
||||||
|
);
|
||||||
|
|
||||||
|
region.resetNewEntities();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int entityId : region.getEntities()) {
|
||||||
|
if(!region.getMetaRegion().contains(getScene().getEntityById(entityId).getPosition())) {
|
||||||
|
region.removeEntity(entityId);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (region.entityLeave()) {
|
||||||
|
callEvent(EventType.EVENT_LEAVE_REGION, new ScriptArgs(region.getConfigId())
|
||||||
|
.setSourceEntityId(region.getId())
|
||||||
.setTargetEntityId(region.getFirstEntityId())
|
.setTargetEntityId(region.getFirstEntityId())
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -287,21 +310,35 @@ public class SceneScriptManager {
|
|||||||
|
|
||||||
private void realCallEvent(int eventType, ScriptArgs params) {
|
private void realCallEvent(int eventType, ScriptArgs params) {
|
||||||
try {
|
try {
|
||||||
ScriptLoader.getScriptLib().setSceneScriptManager(this);
|
Set<SceneTrigger> relevantTriggers = new HashSet<>();
|
||||||
for (SceneTrigger trigger : this.getTriggersByEvent(eventType)) {
|
if(eventType == EventType.EVENT_ENTER_REGION || eventType == EventType.EVENT_LEAVE_REGION) {
|
||||||
|
List<SceneTrigger> relevantTriggersList = this.getTriggersByEvent(eventType).stream()
|
||||||
|
.filter(p -> p.condition.contains(String.valueOf(params.param1))).toList();
|
||||||
|
relevantTriggers = new HashSet<>(relevantTriggersList);
|
||||||
|
} else {relevantTriggers = this.getTriggersByEvent(eventType);}
|
||||||
|
for (SceneTrigger trigger : relevantTriggers) {
|
||||||
try {
|
try {
|
||||||
ScriptLoader.getScriptLib().setCurrentGroup(trigger.currentGroup);
|
ScriptLoader.getScriptLib().setCurrentGroup(trigger.currentGroup);
|
||||||
|
LuaValue ret = this.callScriptFunc(trigger.condition, trigger.currentGroup, params);
|
||||||
LuaValue ret = callScriptFunc(trigger.condition, trigger.currentGroup, params);
|
Grasscutter.getLogger().trace("Call Condition Trigger {}, [{},{},{}]", trigger.condition, params.param1, params.source_eid, params.target_eid);
|
||||||
Grasscutter.getLogger().trace("Call Condition Trigger {}", trigger.condition);
|
|
||||||
|
|
||||||
if (ret.isboolean() && ret.checkboolean()) {
|
if (ret.isboolean() && ret.checkboolean()) {
|
||||||
// the SetGroupVariableValueByGroup in tower need the param to record the first stage time
|
// the SetGroupVariableValueByGroup in tower need the param to record the first stage time
|
||||||
callScriptFunc(trigger.action, trigger.currentGroup, params);
|
this.callScriptFunc(trigger.action, trigger.currentGroup, params);
|
||||||
Grasscutter.getLogger().trace("Call Action Trigger {}", trigger.action);
|
Grasscutter.getLogger().trace("Call Action Trigger {}", trigger.action);
|
||||||
|
if (trigger.event == EventType.EVENT_ENTER_REGION) {
|
||||||
|
EntityRegion region = this.regions.values().stream().filter(p -> p.getConfigId() == params.param1).toList().get(0);
|
||||||
|
getScene().getPlayers().forEach(p -> p.onEnterRegion(region.getMetaRegion()));
|
||||||
|
deregisterRegion(region.getMetaRegion());
|
||||||
|
} else if (trigger.event == EventType.EVENT_LEAVE_REGION) {
|
||||||
|
EntityRegion region = this.regions.values().stream().filter(p -> p.getConfigId() == params.param1).toList().get(0);
|
||||||
|
getScene().getPlayers().forEach(p -> p.onLeaveRegion(region.getMetaRegion()));
|
||||||
|
deregisterRegion(region.getMetaRegion());
|
||||||
}
|
}
|
||||||
//TODO some ret may not bool
|
deregisterTrigger(trigger);
|
||||||
|
} else {
|
||||||
|
Grasscutter.getLogger().debug("Condition Trigger {} returned {}", trigger.condition, ret);
|
||||||
|
}
|
||||||
|
//TODO some ret do not bool
|
||||||
}finally {
|
}finally {
|
||||||
ScriptLoader.getScriptLib().removeCurrentGroup();
|
ScriptLoader.getScriptLib().removeCurrentGroup();
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,8 @@ public class SceneRegion {
|
|||||||
var x = Math.pow(pos.getX() - position.getX(), 2);
|
var x = Math.pow(pos.getX() - position.getX(), 2);
|
||||||
var y = Math.pow(pos.getY() - position.getY(), 2);
|
var y = Math.pow(pos.getY() - position.getY(), 2);
|
||||||
var z = Math.pow(pos.getZ() - position.getZ(), 2);
|
var z = Math.pow(pos.getZ() - position.getZ(), 2);
|
||||||
return x + y + z <= (radius ^ 2);
|
// ^ means XOR in java!
|
||||||
|
return x + y + z <= (radius*radius);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,54 @@ public class LuaSerializer implements Serializer {
|
|||||||
return serialize(type, (LuaTable) obj);
|
return serialize(type, (LuaTable) obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Map<String, T> toMap(Class<T> type, Object obj) {
|
||||||
|
return serializeMap(type, (LuaTable) obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> Map<String,T> serializeMap(Class<T> type, LuaTable table) {
|
||||||
|
Map<String,T> map = new HashMap<>();
|
||||||
|
|
||||||
|
if (table == null) {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
LuaValue[] keys = table.keys();
|
||||||
|
for (LuaValue k : keys) {
|
||||||
|
try {
|
||||||
|
LuaValue keyValue = table.get(k);
|
||||||
|
|
||||||
|
T object = null;
|
||||||
|
|
||||||
|
if (keyValue.istable()) {
|
||||||
|
object = serialize(type, keyValue.checktable());
|
||||||
|
} else if (keyValue.isint()) {
|
||||||
|
object = (T) (Integer) keyValue.toint();
|
||||||
|
} else if (keyValue.isnumber()) {
|
||||||
|
object = (T) (Float) keyValue.tofloat(); // terrible...
|
||||||
|
} else if (keyValue.isstring()) {
|
||||||
|
object = (T) keyValue.tojstring();
|
||||||
|
} else if (keyValue.isboolean()) {
|
||||||
|
object = (T) (Boolean) keyValue.toboolean();
|
||||||
|
} else {
|
||||||
|
object = (T) keyValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object != null) {
|
||||||
|
map.put(String.valueOf(k),object);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
public <T> List<T> serializeList(Class<T> type, LuaTable table) {
|
public <T> List<T> serializeList(Class<T> type, LuaTable table) {
|
||||||
List<T> list = new ArrayList<>();
|
List<T> list = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package emu.grasscutter.scripts.serializer;
|
package emu.grasscutter.scripts.serializer;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.luaj.vm2.LuaTable;
|
|
||||||
|
|
||||||
public interface Serializer {
|
public interface Serializer {
|
||||||
|
|
||||||
public <T> List<T> toList(Class<T> type, Object obj);
|
public <T> List<T> toList(Class<T> type, Object obj);
|
||||||
|
|
||||||
public <T> T toObject(Class<T> type, Object obj);
|
public <T> T toObject(Class<T> type, Object obj);
|
||||||
|
|
||||||
|
public <T> Map<String,T> toMap(Class<T> type, Object obj);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package emu.grasscutter.server.packet.recv;
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameData;
|
||||||
|
import emu.grasscutter.data.excels.QuestData;
|
||||||
|
import emu.grasscutter.game.quest.GameQuest;
|
||||||
import emu.grasscutter.game.quest.enums.QuestTrigger;
|
import emu.grasscutter.game.quest.enums.QuestTrigger;
|
||||||
import emu.grasscutter.net.packet.Opcodes;
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
import emu.grasscutter.net.packet.PacketHandler;
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
@ -7,6 +10,9 @@ import emu.grasscutter.net.packet.PacketOpcodes;
|
|||||||
import emu.grasscutter.net.proto.AddQuestContentProgressReqOuterClass;
|
import emu.grasscutter.net.proto.AddQuestContentProgressReqOuterClass;
|
||||||
import emu.grasscutter.server.game.GameSession;
|
import emu.grasscutter.server.game.GameSession;
|
||||||
import emu.grasscutter.server.packet.send.PacketAddQuestContentProgressRsp;
|
import emu.grasscutter.server.packet.send.PacketAddQuestContentProgressRsp;
|
||||||
|
import emu.grasscutter.data.excels.QuestData.QuestCondition;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@Opcodes(PacketOpcodes.AddQuestContentProgressReq)
|
@Opcodes(PacketOpcodes.AddQuestContentProgressReq)
|
||||||
public class HandlerAddQuestContentProgressReq extends PacketHandler {
|
public class HandlerAddQuestContentProgressReq extends PacketHandler {
|
||||||
@ -14,9 +20,14 @@ public class HandlerAddQuestContentProgressReq 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 {
|
||||||
var req = AddQuestContentProgressReqOuterClass.AddQuestContentProgressReq.parseFrom(payload);
|
var req = AddQuestContentProgressReqOuterClass.AddQuestContentProgressReq.parseFrom(payload);
|
||||||
|
//Find all conditions in quest that are the same as the given one
|
||||||
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.getContentTriggerByValue(req.getContentType()), req.getParam());
|
Stream<QuestCondition> finishCond = GameData.getQuestDataMap().get(req.getParam()).getFinishCond().stream();
|
||||||
|
Stream<QuestCondition> acceptCond = GameData.getQuestDataMap().get(req.getParam()).getAcceptCond().stream();
|
||||||
|
Stream<QuestCondition> failCond = GameData.getQuestDataMap().get(req.getParam()).getFailCond().stream();
|
||||||
|
List<QuestCondition> allCondMatch = Stream.concat(Stream.concat(acceptCond,failCond),finishCond).filter(p -> p.getType().getValue() == req.getContentType()).toList();
|
||||||
|
for(QuestCondition cond : allCondMatch ) {
|
||||||
|
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.getContentTriggerByValue(req.getContentType()), cond.getParam());
|
||||||
|
}
|
||||||
session.send(new PacketAddQuestContentProgressRsp(req.getContentType()));
|
session.send(new PacketAddQuestContentProgressRsp(req.getContentType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package emu.grasscutter.server.packet.recv;
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.game.player.Player.SceneLoadState;
|
import emu.grasscutter.game.player.Player.SceneLoadState;
|
||||||
|
import emu.grasscutter.game.quest.QuestGroupSuite;
|
||||||
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.packet.PacketHandler;
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
@ -16,7 +18,7 @@ public class HandlerEnterSceneDoneReq extends PacketHandler {
|
|||||||
session.getPlayer().setSceneLoadState(SceneLoadState.LOADED);
|
session.getPlayer().setSceneLoadState(SceneLoadState.LOADED);
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
session.send(new PacketEnterSceneDoneRsp(session.getPlayer()));
|
|
||||||
session.send(new PacketPlayerTimeNotify(session.getPlayer())); // Probably not the right place
|
session.send(new PacketPlayerTimeNotify(session.getPlayer())); // Probably not the right place
|
||||||
|
|
||||||
// Spawn player in world
|
// Spawn player in world
|
||||||
@ -35,11 +37,15 @@ public class HandlerEnterSceneDoneReq extends PacketHandler {
|
|||||||
|
|
||||||
// notify client to load the npc for quest
|
// notify client to load the npc for quest
|
||||||
var questGroupSuites = session.getPlayer().getQuestManager().getSceneGroupSuite(session.getPlayer().getSceneId());
|
var questGroupSuites = session.getPlayer().getQuestManager().getSceneGroupSuite(session.getPlayer().getSceneId());
|
||||||
|
|
||||||
session.getPlayer().getScene().loadGroupForQuest(questGroupSuites);
|
session.getPlayer().getScene().loadGroupForQuest(questGroupSuites);
|
||||||
|
Grasscutter.getLogger().debug("Loaded Scene {} Quest(s) Groupsuite(s): {}", session.getPlayer().getSceneId(), questGroupSuites);
|
||||||
session.send(new PacketGroupSuiteNotify(questGroupSuites));
|
session.send(new PacketGroupSuiteNotify(questGroupSuites));
|
||||||
|
|
||||||
// Reset timer for sending player locations
|
// Reset timer for sending player locations
|
||||||
session.getPlayer().resetSendPlayerLocTime();
|
session.getPlayer().resetSendPlayerLocTime();
|
||||||
|
//Rsp
|
||||||
|
session.send(new PacketEnterSceneDoneRsp(session.getPlayer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package emu.grasscutter.server.packet.recv;
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameData;
|
||||||
|
import emu.grasscutter.data.binout.MainQuestData;
|
||||||
import emu.grasscutter.game.inventory.GameItem;
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
|
import emu.grasscutter.game.quest.GameMainQuest;
|
||||||
|
import emu.grasscutter.game.quest.enums.ParentQuestState;
|
||||||
import emu.grasscutter.game.quest.enums.QuestTrigger;
|
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;
|
||||||
@ -15,10 +19,22 @@ public class HandlerNpcTalkReq 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 {
|
||||||
NpcTalkReq req = NpcTalkReq.parseFrom(payload);
|
NpcTalkReq req = NpcTalkReq.parseFrom(payload);
|
||||||
|
//Check if mainQuest exists
|
||||||
|
int talkId = req.getTalkId();
|
||||||
|
//remove last 2 digits to get a mainQuestId
|
||||||
|
int mainQuestId = talkId/100;
|
||||||
|
MainQuestData mainQuestData = GameData.getMainQuestDataMap().get(mainQuestId);
|
||||||
|
if(mainQuestData != null) {
|
||||||
|
MainQuestData.TalkData talk = mainQuestData.getTalks().stream().filter(p -> p.getId() == talkId).toList().get(0);
|
||||||
|
if(talk != null) {
|
||||||
|
//talk is finished
|
||||||
|
session.getPlayer().getQuestManager().getMainQuestById(mainQuestId).getTalks().put(Integer.valueOf(talkId),talk);
|
||||||
|
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_COMPLETE_ANY_TALK,String.valueOf(req.getTalkId()), 0, 0);
|
||||||
// Why are there 2 quest triggers that do the same thing...
|
// Why are there 2 quest triggers that do the same thing...
|
||||||
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_COMPLETE_TALK, req.getTalkId());
|
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_COMPLETE_TALK, req.getTalkId(),0);
|
||||||
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_FINISH_PLOT, req.getTalkId());
|
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_FINISH_PLOT, req.getTalkId(),0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
session.send(new PacketNpcTalkRsp(req.getNpcEntityId(), req.getTalkId(), req.getEntityId()));
|
session.send(new PacketNpcTalkRsp(req.getNpcEntityId(), req.getTalkId(), req.getEntityId()));
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ public class HandlerPersonalLineAllDataReq 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 {
|
||||||
session.send(new PacketPersonalLineAllDataRsp(session.getPlayer().getQuestManager().getQuests().values()));
|
session.send(new PacketPersonalLineAllDataRsp(session.getPlayer().getQuestManager().getMainQuests().values()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ public class HandlerPostEnterSceneReq 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 {
|
||||||
if(session.getPlayer().getScene().getSceneType() == SceneType.SCENE_ROOM){
|
if(session.getPlayer().getScene().getSceneType() == SceneType.SCENE_ROOM){
|
||||||
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_ENTER_ROOM, session.getPlayer().getSceneId());
|
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_ENTER_ROOM, session.getPlayer().getSceneId(),0);
|
||||||
}
|
}
|
||||||
|
|
||||||
session.send(new PacketPostEnterSceneRsp(session.getPlayer()));
|
session.send(new PacketPostEnterSceneRsp(session.getPlayer()));
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.quest.GameMainQuest;
|
||||||
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
|
import emu.grasscutter.net.proto.PacketHeadOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.PlayerSetPauseReqOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.QuestUpdateQuestVarReqOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.QuestVarOpOuterClass;
|
||||||
|
import emu.grasscutter.server.game.GameSession;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketPlayerSetPauseRsp;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketQuestUpdateQuestVarRsp;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Opcodes(PacketOpcodes.QuestUpdateQuestVarReq)
|
||||||
|
public class HandlerQuestUpdateQuestVarReq extends PacketHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||||
|
//Client sends packets. One with the value, and one with the index and the new value to set/inc/dec
|
||||||
|
var req = QuestUpdateQuestVarReqOuterClass.QuestUpdateQuestVarReq.parseFrom(payload);
|
||||||
|
GameMainQuest mainQuest = session.getPlayer().getQuestManager().getMainQuestById(req.getQuestId()/100);
|
||||||
|
List<QuestVarOpOuterClass.QuestVarOp> questVars = req.getQuestVarOpListList();
|
||||||
|
if (mainQuest.getQuestVarsUpdate().size() == 0) {
|
||||||
|
for (QuestVarOpOuterClass.QuestVarOp questVar : questVars) {
|
||||||
|
mainQuest.getQuestVarsUpdate().add(questVar.getValue());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (QuestVarOpOuterClass.QuestVarOp questVar : questVars) {
|
||||||
|
if (questVar.getIsAdd()) {
|
||||||
|
if (questVar.getValue() >= 0) {
|
||||||
|
mainQuest.incQuestVar(questVar.getIndex(), questVar.getValue());
|
||||||
|
} else {
|
||||||
|
mainQuest.decQuestVar(questVar.getIndex(), questVar.getValue());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mainQuest.setQuestVar(questVar.getIndex(), mainQuest.getQuestVarsUpdate().get(0));
|
||||||
|
}
|
||||||
|
//remove the first element from the update list
|
||||||
|
mainQuest.getQuestVarsUpdate().remove(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
session.send(new PacketQuestUpdateQuestVarRsp(req.getQuestId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,6 +2,7 @@ package emu.grasscutter.server.packet.send;
|
|||||||
|
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.quest.GameMainQuest;
|
import emu.grasscutter.game.quest.GameMainQuest;
|
||||||
|
import emu.grasscutter.game.quest.enums.ParentQuestState;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.FinishedParentQuestNotifyOuterClass.FinishedParentQuestNotify;
|
import emu.grasscutter.net.proto.FinishedParentQuestNotifyOuterClass.FinishedParentQuestNotify;
|
||||||
@ -13,8 +14,11 @@ public class PacketFinishedParentQuestNotify extends BasePacket {
|
|||||||
|
|
||||||
FinishedParentQuestNotify.Builder proto = FinishedParentQuestNotify.newBuilder();
|
FinishedParentQuestNotify.Builder proto = FinishedParentQuestNotify.newBuilder();
|
||||||
|
|
||||||
for (GameMainQuest mainQuest : player.getQuestManager().getQuests().values()) {
|
for (GameMainQuest mainQuest : player.getQuestManager().getMainQuests().values()) {
|
||||||
|
//Canceled Quests do not appear in this packet
|
||||||
|
if(mainQuest.getState() != ParentQuestState.PARENT_QUEST_STATE_CANCELED) {
|
||||||
proto.addParentQuestList(mainQuest.toProto());
|
proto.addParentQuestList(mainQuest.toProto());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
|
@ -5,6 +5,8 @@ import emu.grasscutter.net.packet.BasePacket;
|
|||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.FinishedParentQuestUpdateNotifyOuterClass.FinishedParentQuestUpdateNotify;
|
import emu.grasscutter.net.proto.FinishedParentQuestUpdateNotifyOuterClass.FinishedParentQuestUpdateNotify;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class PacketFinishedParentQuestUpdateNotify extends BasePacket {
|
public class PacketFinishedParentQuestUpdateNotify extends BasePacket {
|
||||||
|
|
||||||
public PacketFinishedParentQuestUpdateNotify(GameMainQuest quest) {
|
public PacketFinishedParentQuestUpdateNotify(GameMainQuest quest) {
|
||||||
@ -16,4 +18,16 @@ public class PacketFinishedParentQuestUpdateNotify extends BasePacket {
|
|||||||
|
|
||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PacketFinishedParentQuestUpdateNotify(List<GameMainQuest> quests) {
|
||||||
|
super(PacketOpcodes.FinishedParentQuestUpdateNotify);
|
||||||
|
|
||||||
|
var proto = FinishedParentQuestUpdateNotify.newBuilder();
|
||||||
|
|
||||||
|
for(GameMainQuest mainQuest : quests) {
|
||||||
|
proto.addParentQuestList(mainQuest.toProto());
|
||||||
|
}
|
||||||
|
proto.build();
|
||||||
|
this.setData(proto);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ public class PacketPersonalLineAllDataRsp extends BasePacket {
|
|||||||
.map(GameMainQuest::getChildQuests)
|
.map(GameMainQuest::getChildQuests)
|
||||||
.map(Map::values)
|
.map(Map::values)
|
||||||
.flatMap(Collection::stream)
|
.flatMap(Collection::stream)
|
||||||
.map(GameQuest::getQuestId)
|
.map(GameQuest::getSubQuestId)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
GameData.getPersonalLineDataMap().values().stream()
|
GameData.getPersonalLineDataMap().values().stream()
|
||||||
|
@ -3,6 +3,7 @@ package emu.grasscutter.server.packet.send;
|
|||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.quest.GameMainQuest;
|
import emu.grasscutter.game.quest.GameMainQuest;
|
||||||
import emu.grasscutter.game.quest.QuestManager;
|
import emu.grasscutter.game.quest.QuestManager;
|
||||||
|
import emu.grasscutter.game.quest.enums.QuestState;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.QuestListNotifyOuterClass.QuestListNotify;
|
import emu.grasscutter.net.proto.QuestListNotifyOuterClass.QuestListNotify;
|
||||||
@ -15,7 +16,9 @@ public class PacketQuestListNotify extends BasePacket {
|
|||||||
QuestListNotify.Builder proto = QuestListNotify.newBuilder();
|
QuestListNotify.Builder proto = QuestListNotify.newBuilder();
|
||||||
|
|
||||||
player.getQuestManager().forEachQuest(quest -> {
|
player.getQuestManager().forEachQuest(quest -> {
|
||||||
|
if(quest.getState() != QuestState.QUEST_STATE_UNSTARTED) {
|
||||||
proto.addQuestList(quest.toProto());
|
proto.addQuestList(quest.toProto());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
|
@ -6,6 +6,8 @@ import emu.grasscutter.net.packet.BasePacket;
|
|||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.QuestListUpdateNotifyOuterClass.QuestListUpdateNotify;
|
import emu.grasscutter.net.proto.QuestListUpdateNotifyOuterClass.QuestListUpdateNotify;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class PacketQuestListUpdateNotify extends BasePacket {
|
public class PacketQuestListUpdateNotify extends BasePacket {
|
||||||
|
|
||||||
public PacketQuestListUpdateNotify(GameQuest quest) {
|
public PacketQuestListUpdateNotify(GameQuest quest) {
|
||||||
@ -17,4 +19,15 @@ public class PacketQuestListUpdateNotify extends BasePacket {
|
|||||||
|
|
||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PacketQuestListUpdateNotify(List<GameQuest> quests) {
|
||||||
|
super(PacketOpcodes.QuestListUpdateNotify);
|
||||||
|
var proto = QuestListUpdateNotify.newBuilder();
|
||||||
|
for(GameQuest quest : quests) {
|
||||||
|
proto.addQuestList(quest.toProto());
|
||||||
|
}
|
||||||
|
proto.build();
|
||||||
|
|
||||||
|
this.setData(proto);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ public class PacketQuestProgressUpdateNotify extends BasePacket {
|
|||||||
public PacketQuestProgressUpdateNotify(GameQuest quest) {
|
public PacketQuestProgressUpdateNotify(GameQuest quest) {
|
||||||
super(PacketOpcodes.QuestProgressUpdateNotify);
|
super(PacketOpcodes.QuestProgressUpdateNotify);
|
||||||
|
|
||||||
QuestProgressUpdateNotify.Builder proto = QuestProgressUpdateNotify.newBuilder().setQuestId(quest.getQuestId());
|
QuestProgressUpdateNotify.Builder proto = QuestProgressUpdateNotify.newBuilder().setQuestId(quest.getSubQuestId());
|
||||||
|
|
||||||
if (quest.getFinishProgressList() != null) {
|
if (quest.getFinishProgressList() != null) {
|
||||||
for (int i : quest.getFinishProgressList()) {
|
for (int i : quest.getFinishProgressList()) {
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
|
import emu.grasscutter.net.proto.QuestUpdateQuestVarReqOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.QuestUpdateQuestVarRspOuterClass;
|
||||||
|
|
||||||
|
@Opcodes(PacketOpcodes.QuestUpdateQuestVarReq)
|
||||||
|
public class PacketQuestUpdateQuestVarRsp extends BasePacket {
|
||||||
|
|
||||||
|
|
||||||
|
public PacketQuestUpdateQuestVarRsp(int questId) {
|
||||||
|
super(PacketOpcodes.QuestUpdateQuestVarRsp);
|
||||||
|
var rsp = QuestUpdateQuestVarRspOuterClass.QuestUpdateQuestVarRsp.newBuilder()
|
||||||
|
.setQuestId(questId).build();
|
||||||
|
this.setData(rsp);
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,9 @@ import emu.grasscutter.net.packet.BasePacket;
|
|||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.ServerCondMeetQuestListUpdateNotifyOuterClass.ServerCondMeetQuestListUpdateNotify;
|
import emu.grasscutter.net.proto.ServerCondMeetQuestListUpdateNotifyOuterClass.ServerCondMeetQuestListUpdateNotify;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class PacketServerCondMeetQuestListUpdateNotify extends BasePacket {
|
public class PacketServerCondMeetQuestListUpdateNotify extends BasePacket {
|
||||||
|
|
||||||
public PacketServerCondMeetQuestListUpdateNotify(Player player) {
|
public PacketServerCondMeetQuestListUpdateNotify(Player player) {
|
||||||
@ -24,12 +27,23 @@ public class PacketServerCondMeetQuestListUpdateNotify extends BasePacket {
|
|||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PacketServerCondMeetQuestListUpdateNotify(GameQuest quest) {
|
public PacketServerCondMeetQuestListUpdateNotify(List<GameQuest> quests) {
|
||||||
super(PacketOpcodes.ServerCondMeetQuestListUpdateNotify);
|
super(PacketOpcodes.ServerCondMeetQuestListUpdateNotify);
|
||||||
|
|
||||||
ServerCondMeetQuestListUpdateNotify proto = ServerCondMeetQuestListUpdateNotify.newBuilder()
|
ServerCondMeetQuestListUpdateNotify.Builder proto = ServerCondMeetQuestListUpdateNotify.newBuilder();
|
||||||
//.addAddQuestIdList(quest.getQuestId())
|
for (GameQuest quest : quests) {
|
||||||
.build();
|
proto.addAddQuestIdList(quest.getSubQuestId());
|
||||||
|
}
|
||||||
|
proto.build();
|
||||||
|
|
||||||
|
this.setData(proto);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketServerCondMeetQuestListUpdateNotify() {
|
||||||
|
super(PacketOpcodes.ServerCondMeetQuestListUpdateNotify);
|
||||||
|
|
||||||
|
ServerCondMeetQuestListUpdateNotify.Builder proto = ServerCondMeetQuestListUpdateNotify.newBuilder();
|
||||||
|
proto.build();
|
||||||
|
|
||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user