mirror of
https://github.com/Anime-Game-Servers/Grasscutter-Quests.git
synced 2024-12-04 02:31:06 +00:00
Change way that finishProgressList is handled at login (#135)
Some checks failed
Build / Build-Server-Jar (push) Has been cancelled
Some checks failed
Build / Build-Server-Jar (push) Has been cancelled
Quests that have isRewind=False cannot be rewindTargets checkAndUpdateContent saves the quest if Content changed Don't modify finishProgressList if it's from a login
This commit is contained in:
parent
9138b96a94
commit
3932bdead9
@ -4,6 +4,7 @@ import dev.morphia.annotations.Entity;
|
|||||||
import dev.morphia.annotations.Id;
|
import dev.morphia.annotations.Id;
|
||||||
import dev.morphia.annotations.Indexed;
|
import dev.morphia.annotations.Indexed;
|
||||||
import dev.morphia.annotations.Transient;
|
import dev.morphia.annotations.Transient;
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.Loggers;
|
import emu.grasscutter.Loggers;
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.binout.ScriptSceneData;
|
import emu.grasscutter.data.binout.ScriptSceneData;
|
||||||
@ -254,7 +255,7 @@ public class GameMainQuest {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameQuest getRewindTarget(){
|
public GameQuest getHighestActiveQuest() {
|
||||||
var activeQuests = getChildQuests().values().stream()
|
var activeQuests = getChildQuests().values().stream()
|
||||||
.filter(p -> (p.getState() == QuestState.QUEST_STATE_UNFINISHED || p.getState() == QuestState.QUEST_STATE_FINISHED)).toList();
|
.filter(p -> (p.getState() == QuestState.QUEST_STATE_UNFINISHED || p.getState() == QuestState.QUEST_STATE_FINISHED)).toList();
|
||||||
var highestActiveQuest = activeQuests.stream()
|
var highestActiveQuest = activeQuests.stream()
|
||||||
@ -266,7 +267,7 @@ public class GameMainQuest {
|
|||||||
var firstUnstarted = getChildQuests().values().stream()
|
var firstUnstarted = getChildQuests().values().stream()
|
||||||
.filter(q -> q.getQuestData() != null && q.getState().getValue() != QuestState.QUEST_STATE_FINISHED.getValue())
|
.filter(q -> q.getQuestData() != null && q.getState().getValue() != QuestState.QUEST_STATE_FINISHED.getValue())
|
||||||
.min(Comparator.comparingInt(a -> a.getQuestData().getOrder()));
|
.min(Comparator.comparingInt(a -> a.getQuestData().getOrder()));
|
||||||
if(firstUnstarted.isEmpty()){
|
if (firstUnstarted.isEmpty()) {
|
||||||
// all quests are probably finished, do don't rewind and maybe also set the mainquest to finished?
|
// all quests are probably finished, do don't rewind and maybe also set the mainquest to finished?
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -274,14 +275,20 @@ public class GameMainQuest {
|
|||||||
//todo maybe try to accept quests if there is no active quest and no rewind target?
|
//todo maybe try to accept quests if there is no active quest and no rewind target?
|
||||||
//tryAcceptSubQuests(QuestTrigger.QUEST_COND_NONE, "", 0);
|
//tryAcceptSubQuests(QuestTrigger.QUEST_COND_NONE, "", 0);
|
||||||
}
|
}
|
||||||
|
return highestActiveQuest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameQuest getRewindTarget(){
|
||||||
|
var highestActiveQuest = getHighestActiveQuest();
|
||||||
|
|
||||||
var highestOrder = highestActiveQuest.getQuestData().getOrder();
|
var highestOrder = highestActiveQuest.getQuestData().getOrder();
|
||||||
var rewindTarget = getChildQuests().values().stream()
|
var rewindTarget = getChildQuests().values().stream()
|
||||||
.filter(q -> q.getQuestData() != null)
|
.filter(q -> q.getQuestData() != null)
|
||||||
.filter(q -> q.getQuestData().isRewind() && q.getQuestData().getOrder() <= highestOrder)
|
.filter(q -> q.getQuestData().isRewind() && q.getQuestData().getOrder() <= highestOrder)
|
||||||
.max(Comparator.comparingInt(a -> a.getQuestData().getOrder()))
|
.max(Comparator.comparingInt(a -> a.getQuestData().getOrder()))
|
||||||
.orElse(highestActiveQuest);
|
.orElse(null);
|
||||||
|
|
||||||
|
Grasscutter.getLogger().trace("For quest {}, the rewindTarget is {}", this.getParentQuestId(), rewindTarget);
|
||||||
return rewindTarget;
|
return rewindTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,10 +361,10 @@ public class GameMainQuest {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkProgress(){
|
public void checkProgress(boolean shouldReset) {
|
||||||
for (var quest : getChildQuests().values()){
|
for (var quest : getChildQuests().values()){
|
||||||
if(quest.getState() == QuestState.QUEST_STATE_UNFINISHED) {
|
if(quest.getState() == QuestState.QUEST_STATE_UNFINISHED) {
|
||||||
questManager.checkQuestAlreadyFullfilled(quest);
|
questManager.checkQuestAlreadyFulfilled(quest, shouldReset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ public class GameQuest {
|
|||||||
triggerStateEvents();
|
triggerStateEvents();
|
||||||
|
|
||||||
getQuestData().getBeginExec().forEach(e -> getOwner().getServer().getQuestSystem().triggerExec(this, e, e.getParam()));
|
getQuestData().getBeginExec().forEach(e -> getOwner().getServer().getQuestSystem().triggerExec(this, e, e.getParam()));
|
||||||
getOwner().getQuestManager().checkQuestAlreadyFullfilled(this);
|
getOwner().getQuestManager().checkQuestAlreadyFulfilled(this, true);
|
||||||
getOwner().getDungeonEntryManager().checkQuestForDungeonEntryUpdate(this);
|
getOwner().getDungeonEntryManager().checkQuestForDungeonEntryUpdate(this);
|
||||||
|
|
||||||
Grasscutter.getLogger().debug("Quest {} is started", subQuestId);
|
Grasscutter.getLogger().debug("Quest {} is started", subQuestId);
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
package emu.grasscutter.game.quest;
|
package emu.grasscutter.game.quest;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.LinkedBlockingDeque;
|
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.common.quest.SubQuestData;
|
import emu.grasscutter.data.common.quest.SubQuestData;
|
||||||
import emu.grasscutter.database.DatabaseHelper;
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
import emu.grasscutter.game.player.BasePlayerManager;
|
import emu.grasscutter.game.player.BasePlayerManager;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.quest.enums.*;
|
import emu.grasscutter.game.quest.enums.LogicType;
|
||||||
|
import emu.grasscutter.game.quest.enums.ParentQuestState;
|
||||||
|
import emu.grasscutter.game.quest.enums.QuestCond;
|
||||||
|
import emu.grasscutter.game.quest.enums.QuestContent;
|
||||||
import emu.grasscutter.game.world.World;
|
import emu.grasscutter.game.world.World;
|
||||||
import emu.grasscutter.server.packet.send.*;
|
import emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketQuestGlobalVarNotify;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
import io.netty.util.concurrent.FastThreadLocalThread;
|
import io.netty.util.concurrent.FastThreadLocalThread;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
@ -24,6 +22,12 @@ import lombok.val;
|
|||||||
import org.anime_game_servers.core.gi.enums.QuestState;
|
import org.anime_game_servers.core.gi.enums.QuestState;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class QuestManager extends BasePlayerManager {
|
public class QuestManager extends BasePlayerManager {
|
||||||
|
|
||||||
@ -106,18 +110,20 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
public void onLogin() {
|
public void onLogin() {
|
||||||
List<GameMainQuest> activeQuests = getActiveMainQuests();
|
List<GameMainQuest> activeQuests = getActiveMainQuests();
|
||||||
for (GameMainQuest quest : activeQuests) {
|
for (GameMainQuest quest : activeQuests) {
|
||||||
val rewindTarget = quest.getRewindTarget();
|
var rewindTarget = quest.getRewindTarget();
|
||||||
|
if (rewindTarget == null) rewindTarget = quest.getHighestActiveQuest();
|
||||||
|
val finalRewindTarget = rewindTarget;
|
||||||
List<Position> rewindPos = quest.rewind(); // <pos, rotation>
|
List<Position> rewindPos = quest.rewind(); // <pos, rotation>
|
||||||
if (rewindPos != null) {
|
if (rewindPos != null) {
|
||||||
getPlayer().getPosition().set(rewindPos.get(0));
|
getPlayer().getPosition().set(rewindPos.get(0));
|
||||||
getPlayer().getRotation().set(rewindPos.get(1));
|
getPlayer().getRotation().set(rewindPos.get(1));
|
||||||
}
|
}
|
||||||
//execute all the beginExec before the rewind target on UNFINISHED quests on login only
|
//execute all the beginExec before the rewind target on UNFINISHED quests on login only
|
||||||
quest.getChildQuests().values().stream().filter(p -> p.getQuestData().getOrder() < rewindTarget.getQuestData().getOrder()
|
quest.getChildQuests().values().stream().filter(p -> p.getQuestData().getOrder() < finalRewindTarget.getQuestData().getOrder()
|
||||||
&& p.getState().getValue() == QuestState.QUEST_STATE_UNFINISHED.getValue()).forEach(q -> {
|
&& p.getState().getValue() == QuestState.QUEST_STATE_UNFINISHED.getValue()).forEach(q -> {
|
||||||
q.getQuestData().getBeginExec().forEach(e -> getPlayer().getServer().getQuestSystem().triggerExec(q, e, e.getParam()));
|
q.getQuestData().getBeginExec().forEach(e -> getPlayer().getServer().getQuestSystem().triggerExec(q, e, e.getParam()));
|
||||||
});
|
});
|
||||||
quest.checkProgress();
|
quest.checkProgress(false);
|
||||||
}
|
}
|
||||||
player.getActivityManager().triggerActivityConditions();
|
player.getActivityManager().triggerActivityConditions();
|
||||||
}
|
}
|
||||||
@ -301,7 +307,7 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
|
|
||||||
// Forcefully start
|
// Forcefully start
|
||||||
quest.start();
|
quest.start();
|
||||||
checkQuestAlreadyFullfilled(quest);
|
checkQuestAlreadyFulfilled(quest, true);
|
||||||
|
|
||||||
return quest;
|
return quest;
|
||||||
}
|
}
|
||||||
@ -406,7 +412,7 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
* TODO move content checks to use static informations where possible to allow direct already fulfilled checking
|
* TODO move content checks to use static informations where possible to allow direct already fulfilled checking
|
||||||
* @param quest
|
* @param quest
|
||||||
*/
|
*/
|
||||||
public void checkQuestAlreadyFullfilled(GameQuest quest){
|
public void checkQuestAlreadyFulfilled(GameQuest quest, boolean shouldReset) {
|
||||||
Grasscutter.getGameServer().getScheduler().scheduleDelayedTask(() -> {
|
Grasscutter.getGameServer().getScheduler().scheduleDelayedTask(() -> {
|
||||||
val questSystem = getPlayer().getServer().getQuestSystem();
|
val questSystem = getPlayer().getServer().getQuestSystem();
|
||||||
val questData = quest.getQuestData();
|
val questData = quest.getQuestData();
|
||||||
@ -415,13 +421,13 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
val shouldFinish = questSystem.initialCheckContent(quest, quest.getFinishProgressList(), questData.getFinishCond(), questData.getFinishCondComb());
|
val shouldFinish = questSystem.initialCheckContent(quest, quest.getFinishProgressList(), questData.getFinishCond(), questData.getFinishCondComb(), shouldReset);
|
||||||
if (shouldFinish) {
|
if (shouldFinish) {
|
||||||
quest.finish(false);
|
quest.finish(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!questData.getFailCond().isEmpty()) {
|
if(!questData.getFailCond().isEmpty()) {
|
||||||
val shouldFail = questSystem.initialCheckContent(quest, quest.getFailProgressList(), questData.getFailCond(), questData.getFailCondComb());
|
val shouldFail = questSystem.initialCheckContent(quest, quest.getFailProgressList(), questData.getFailCond(), questData.getFailCondComb(), shouldReset);
|
||||||
if (shouldFail) {
|
if (shouldFail) {
|
||||||
quest.fail();
|
quest.fail();
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ public class QuestSystem extends BaseGameSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean initialCheckContent(GameQuest quest, int[] curProgress,
|
public boolean initialCheckContent(GameQuest quest, int[] curProgress,
|
||||||
List<QuestContentCondition> conditions, LogicType logicType){
|
List<QuestContentCondition> conditions, LogicType logicType, boolean shouldReset) {
|
||||||
val owner = quest.getOwner();
|
val owner = quest.getOwner();
|
||||||
var changed = false;
|
var changed = false;
|
||||||
int[] finished = new int[conditions.size()];
|
int[] finished = new int[conditions.size()];
|
||||||
@ -112,17 +112,18 @@ public class QuestSystem extends BaseGameSystem {
|
|||||||
|
|
||||||
val startingProgress = curProgress[i];
|
val startingProgress = curProgress[i];
|
||||||
int result = handler.initialCheck(quest, quest.getQuestData(), condition);
|
int result = handler.initialCheck(quest, quest.getQuestData(), condition);
|
||||||
curProgress[i] = result;
|
if (shouldReset) curProgress[i] = result;
|
||||||
if (startingProgress != result) {
|
if (startingProgress != result) {
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
finished[i] = handler.checkProgress(quest, condition, result) ? 1 : 0;
|
finished[i] = handler.checkProgress(quest, condition, result) ? 1 : 0;
|
||||||
}
|
}
|
||||||
if(changed) {
|
if (changed) {
|
||||||
owner.getSession().send(new PacketQuestProgressUpdateNotify(quest));
|
owner.getSession().send(new PacketQuestProgressUpdateNotify(quest));
|
||||||
}
|
}
|
||||||
return LogicType.calculate(logicType, finished);
|
return LogicType.calculate(logicType, finished);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean checkAndUpdateContent(GameQuest quest, int[] curProgress,
|
public boolean checkAndUpdateContent(GameQuest quest, int[] curProgress,
|
||||||
List<QuestContentCondition> conditions, LogicType logicType,
|
List<QuestContentCondition> conditions, LogicType logicType,
|
||||||
QuestContent condType, String paramStr, int... params){
|
QuestContent condType, String paramStr, int... params){
|
||||||
@ -146,6 +147,7 @@ public class QuestSystem extends BaseGameSystem {
|
|||||||
}
|
}
|
||||||
if(changed) {
|
if(changed) {
|
||||||
owner.getSession().send(new PacketQuestProgressUpdateNotify(quest));
|
owner.getSession().send(new PacketQuestProgressUpdateNotify(quest));
|
||||||
|
quest.save();
|
||||||
}
|
}
|
||||||
return LogicType.calculate(logicType, finished);
|
return LogicType.calculate(logicType, finished);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user