mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2026-02-07 02:26:43 +01:00
@@ -6,6 +6,7 @@ import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.GameQuest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Command(
|
||||
@@ -63,22 +64,15 @@ public final class QuestCommand implements CommandHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(
|
||||
sender,
|
||||
"commands.quest.running",
|
||||
questId,
|
||||
translate(
|
||||
sender,
|
||||
switch (quest.state) {
|
||||
case QUEST_STATE_NONE, NONE -> "commands.quest.state.none";
|
||||
case QUEST_STATE_UNSTARTED, UNSTARTED -> "commands.quest.state.unstarted";
|
||||
case QUEST_STATE_UNFINISHED, UNFINISHED -> "commands.quest.state.unfinished";
|
||||
case QUEST_STATE_FINISHED, FINISHED -> "commands.quest.state.finished";
|
||||
case QUEST_STATE_FAILED, FAILED -> "commands.quest.state.failed";
|
||||
}),
|
||||
quest.getState().getValue()));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.quest.running",
|
||||
questId, translate(sender, switch(quest.state) {
|
||||
case QUEST_STATE_NONE, NONE -> "commands.quest.state.none";
|
||||
case QUEST_STATE_UNSTARTED, UNSTARTED -> "commands.quest.state.unstarted";
|
||||
case QUEST_STATE_UNFINISHED, UNFINISHED -> "commands.quest.state.unfinished";
|
||||
case QUEST_STATE_FINISHED, FINISHED -> "commands.quest.state.finished";
|
||||
case QUEST_STATE_FAILED, FAILED -> "commands.quest.state.failed";
|
||||
}), quest.getState().getValue())
|
||||
);
|
||||
}
|
||||
case "talking" -> {
|
||||
var mainQuest = targetPlayer.getQuestManager().getMainQuestByTalkId(questId);
|
||||
@@ -88,24 +82,17 @@ public final class QuestCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
var talk = mainQuest.getTalks().get(questId);
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(
|
||||
sender,
|
||||
"commands.quest.talking",
|
||||
questId,
|
||||
talk == null
|
||||
? translate(sender, "commands.quest.state.not_exists")
|
||||
: translate(sender, "commands.quest.state.exists"),
|
||||
mainQuest.getParentQuestId(),
|
||||
mainQuest.getState().getValue()));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.quest.talking",
|
||||
questId, talk == null ?
|
||||
translate(sender, "commands.quest.state.not_exists") :
|
||||
translate(sender, "commands.quest.state.exists"),
|
||||
mainQuest.getParentQuestId(), mainQuest.getState().getValue()));
|
||||
}
|
||||
case "dungeons" -> {
|
||||
var dungeons = targetPlayer.getPlayerProgress().getCompletedDungeons();
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
"Dungeons completed: "
|
||||
+ String.join(", ", dungeons.intStream().mapToObj(String::valueOf).toList()));
|
||||
CommandHandler.sendMessage(sender, "Dungeons completed: " +
|
||||
String.join(", ", dungeons.intStream()
|
||||
.mapToObj(String::valueOf).toList()));
|
||||
}
|
||||
case "debug" -> {
|
||||
var loggedQuests = targetPlayer.getQuestManager().getLoggedQuests();
|
||||
@@ -114,10 +101,8 @@ public final class QuestCommand implements CommandHandler {
|
||||
if (shouldAdd) loggedQuests.add(questId);
|
||||
else loggedQuests.remove(questId);
|
||||
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
"Quest %s will %s."
|
||||
.formatted(questId, shouldAdd ? "now be logged" : "no longer be logged"));
|
||||
CommandHandler.sendMessage(sender, "Quest %s will %s."
|
||||
.formatted(questId, shouldAdd ? "now be logged" : "no longer be logged"));
|
||||
}
|
||||
case "triggers" -> {
|
||||
var quest = targetPlayer.getQuestManager().getQuestById(questId);
|
||||
@@ -126,10 +111,8 @@ public final class QuestCommand implements CommandHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
"Triggers registered for %s: %s."
|
||||
.formatted(questId, String.join(", ", quest.getTriggers().keySet())));
|
||||
CommandHandler.sendMessage(sender, "Triggers registered for %s: %s."
|
||||
.formatted(questId, String.join(", ", quest.getTriggers().keySet())));
|
||||
}
|
||||
default -> this.sendUsageMessage(sender);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
@@ -9,10 +14,6 @@ import emu.grasscutter.game.tower.TowerLevelRecord;
|
||||
import emu.grasscutter.server.packet.send.PacketOpenStateChangeNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneAreaUnlockNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketScenePointUnlockNotify;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
@Command(
|
||||
label = "setProp",
|
||||
|
||||
@@ -297,11 +297,12 @@ public final class GameData {
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<QuestData> questDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<QuestData> questDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<QuestGlobalVarData> questGlobalVarDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<ReliquaryAffixData> reliquaryAffixDataMap =
|
||||
@@ -323,11 +324,12 @@ public final class GameData {
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<SceneData> sceneDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
private static final Int2ObjectMap<SceneData> sceneDataMap =
|
||||
new Int2ObjectLinkedOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<TalkConfigData> talkConfigDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<TowerFloorData> towerFloorDataMap =
|
||||
|
||||
@@ -490,16 +490,14 @@ public final class ResourceLoader {
|
||||
|
||||
private static void loadQuests() {
|
||||
try (var files = Files.list(getResourcePath("BinOutput/Quest/"))) {
|
||||
files.forEach(
|
||||
path -> {
|
||||
try {
|
||||
val mainQuest = JsonUtils.loadToClass(path, MainQuestData.class);
|
||||
GameData.getMainQuestDataMap().put(mainQuest.getId(), mainQuest);
|
||||
files.forEach(path -> {
|
||||
try {
|
||||
val mainQuest = JsonUtils.loadToClass(path, MainQuestData.class);
|
||||
GameData.getMainQuestDataMap().put(mainQuest.getId(), mainQuest);
|
||||
|
||||
mainQuest.onLoad(); // Load the quest data.
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
});
|
||||
mainQuest.onLoad(); // Load the quest data.
|
||||
} catch (IOException ignored) { }
|
||||
});
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().error("Quest data missing");
|
||||
return;
|
||||
|
||||
@@ -3,10 +3,12 @@ package emu.grasscutter.data.binout;
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.quest.enums.QuestType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
public class MainQuestData {
|
||||
@@ -59,20 +61,19 @@ public class MainQuestData {
|
||||
if (this.talks == null) this.talks = new ArrayList<>();
|
||||
if (this.subQuests == null) this.subQuests = new SubQuestData[0];
|
||||
|
||||
this.talks = this.talks.stream().filter(Objects::nonNull).toList();
|
||||
this.talks = this.talks.stream()
|
||||
.filter(Objects::nonNull).toList();
|
||||
// Apply talk data to the quest talk map.
|
||||
this.talks.forEach(talkData -> GameData.getQuestTalkMap().put(talkData.getId(), this.getId()));
|
||||
this.talks.forEach(talkData -> GameData.getQuestTalkMap().put(
|
||||
talkData.getId(), this.getId()));
|
||||
// Apply additional sub-quest data to sub-quests.
|
||||
Arrays.stream(this.subQuests)
|
||||
.forEach(
|
||||
quest -> {
|
||||
var questData = GameData.getQuestDataMap().get(quest.getSubId());
|
||||
if (questData != null) questData.applyFrom(quest);
|
||||
});
|
||||
Arrays.stream(this.subQuests).forEach(quest -> {
|
||||
var questData = GameData.getQuestDataMap().get(quest.getSubId());
|
||||
if (questData != null) questData.applyFrom(quest);
|
||||
});
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class SubQuestData {
|
||||
@Data public static class SubQuestData {
|
||||
private int subId;
|
||||
private int order;
|
||||
private boolean isMpBlock;
|
||||
|
||||
@@ -9,12 +9,13 @@ import lombok.Getter;
|
||||
@Getter
|
||||
@ResourceType(name = "ChapterExcelConfigData.json")
|
||||
public class ChapterData extends GameResource {
|
||||
@Getter private static final Map<Integer, ChapterData> beginQuestChapterMap = new HashMap<>();
|
||||
@Getter private static final Map<Integer, ChapterData> endQuestChapterMap = new HashMap<>();
|
||||
@Getter private static final Map<Integer, ChapterData> beginQuestChapterMap
|
||||
= new HashMap<>();
|
||||
@Getter private static final Map<Integer, ChapterData> endQuestChapterMap
|
||||
= new HashMap<>();
|
||||
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private int beginQuestId;
|
||||
private int endQuestId;
|
||||
private int needPlayerLevel;
|
||||
|
||||
@@ -1,49 +1,37 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.talk.TalkExec;
|
||||
import java.util.List;
|
||||
import lombok.*;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = "TalkExcelConfigData.json")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@Data
|
||||
public final class TalkConfigData extends GameResource {
|
||||
@SerializedName(
|
||||
value = "id",
|
||||
alternate = {"_id"})
|
||||
@SerializedName(value="id", alternate={"_id"})
|
||||
private int id;
|
||||
|
||||
@SerializedName(
|
||||
value = "finishExec",
|
||||
alternate = {"_finishExec"})
|
||||
@SerializedName(value="finishExec", alternate={"_finishExec"})
|
||||
private List<TalkExecParam> finishExec;
|
||||
|
||||
@SerializedName(
|
||||
value = "questId",
|
||||
alternate = {"_questId"})
|
||||
@SerializedName(value="questId", alternate={"_questId"})
|
||||
private int questId;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.finishExec =
|
||||
this.finishExec == null
|
||||
? List.of()
|
||||
: this.finishExec.stream().filter(x -> x.getType() != null).toList();
|
||||
this.finishExec = this.finishExec == null ? List.of() :
|
||||
this.finishExec.stream()
|
||||
.filter(x -> x.getType() != null)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class TalkExecParam {
|
||||
@SerializedName(
|
||||
value = "type",
|
||||
alternate = {"_type"})
|
||||
@SerializedName(value="type", alternate={"_type"})
|
||||
private TalkExec type;
|
||||
|
||||
@SerializedName(
|
||||
value = "param",
|
||||
alternate = {"_param"})
|
||||
@SerializedName(value="param", alternate={"_param"})
|
||||
private String[] param;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import lombok.*;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@ResourceType(name = "QuestGlobalVarConfigData.json")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public final class QuestGlobalVarData extends GameResource {
|
||||
|
||||
@@ -273,9 +273,8 @@ public final class DungeonManager {
|
||||
public void finishDungeon() {
|
||||
// Mark the dungeon has completed for the players.
|
||||
var dungeonId = this.getDungeonData().getId();
|
||||
this.getScene()
|
||||
.getPlayers()
|
||||
.forEach(player -> player.getPlayerProgress().markDungeonAsComplete(dungeonId));
|
||||
this.getScene().getPlayers().forEach(player -> player
|
||||
.getPlayerProgress().markDungeonAsComplete(dungeonId));
|
||||
|
||||
notifyEndDungeon(true);
|
||||
endDungeon(BaseDungeonResult.DungeonEndReason.COMPLETED);
|
||||
@@ -288,8 +287,8 @@ public final class DungeonManager {
|
||||
p -> {
|
||||
// Trigger the fail event if needed.
|
||||
if (!successfully) {
|
||||
p.getQuestManager()
|
||||
.queueEvent(QuestContent.QUEST_CONTENT_FAIL_DUNGEON, dungeonData.getId());
|
||||
p.getQuestManager().queueEvent(
|
||||
QuestContent.QUEST_CONTENT_FAIL_DUNGEON, dungeonData.getId());
|
||||
}
|
||||
|
||||
// Battle pass trigger
|
||||
|
||||
@@ -16,6 +16,7 @@ import emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@@ -108,18 +109,14 @@ public class WorldChallenge {
|
||||
var eventSource = new AtomicReference<>("");
|
||||
// TODO: This is a hack to get the event source.
|
||||
// This should be properly implemented.
|
||||
scriptManager
|
||||
.getTriggersByEvent(EventType.EVENT_CHALLENGE_SUCCESS)
|
||||
.forEach(
|
||||
trigger -> {
|
||||
if (trigger.currentGroup.id == this.getGroup().id) {
|
||||
eventSource.set(trigger.getSource());
|
||||
}
|
||||
});
|
||||
scriptManager.callEvent(
|
||||
new ScriptArgs(this.getGroup().id, EventType.EVENT_CHALLENGE_SUCCESS)
|
||||
.setParam2(finishedTime)
|
||||
.setEventSource(eventSource.get()));
|
||||
scriptManager.getTriggersByEvent(EventType.EVENT_CHALLENGE_SUCCESS)
|
||||
.forEach(trigger -> {
|
||||
if (trigger.currentGroup.id == this.getGroup().id) {
|
||||
eventSource.set(trigger.getSource());
|
||||
}
|
||||
});
|
||||
scriptManager.callEvent(new ScriptArgs(this.getGroup().id, EventType.EVENT_CHALLENGE_SUCCESS)
|
||||
.setParam2(finishedTime).setEventSource(eventSource.get()));
|
||||
|
||||
this.getScene()
|
||||
.triggerDungeonEvent(
|
||||
@@ -140,18 +137,15 @@ public class WorldChallenge {
|
||||
// TODO: This is a hack to get the event source.
|
||||
// This should be properly implemented.
|
||||
var scriptManager = this.getScene().getScriptManager();
|
||||
scriptManager
|
||||
.getTriggersByEvent(EventType.EVENT_CHALLENGE_FAIL)
|
||||
.forEach(
|
||||
trigger -> {
|
||||
if (trigger.currentGroup.id == this.getGroup().id) {
|
||||
eventSource.set(trigger.getSource());
|
||||
}
|
||||
});
|
||||
scriptManager.getTriggersByEvent(EventType.EVENT_CHALLENGE_FAIL)
|
||||
.forEach(trigger -> {
|
||||
if (trigger.currentGroup.id == this.getGroup().id) {
|
||||
eventSource.set(trigger.getSource());
|
||||
}
|
||||
});
|
||||
|
||||
scriptManager.callEvent(
|
||||
new ScriptArgs(this.getGroup().id, EventType.EVENT_CHALLENGE_FAIL)
|
||||
.setEventSource(eventSource.get()));
|
||||
scriptManager.callEvent(new ScriptArgs(this.getGroup().id, EventType.EVENT_CHALLENGE_FAIL)
|
||||
.setEventSource(eventSource.get()));
|
||||
challengeTriggers.forEach(t -> t.onFinish(this));
|
||||
}
|
||||
|
||||
|
||||
@@ -66,8 +66,7 @@ public class EntityAvatar extends GameEntity {
|
||||
weapon.setWeaponEntityId(world.getNextEntityId(EntityIdType.WEAPON));
|
||||
}
|
||||
} else {
|
||||
Grasscutter.getLogger()
|
||||
.error("Unable to create EntityAvatar instance; provided scene is null.");
|
||||
Grasscutter.getLogger().error("Unable to create EntityAvatar instance; provided scene is null.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,12 +51,13 @@ public final class GadgetWorktop extends GadgetContent {
|
||||
if (options == null) return;
|
||||
|
||||
try {
|
||||
var worktop = WorktopInfo.newBuilder().addAllOptionList(options).build();
|
||||
var worktop = WorktopInfo.newBuilder()
|
||||
.addAllOptionList(options).build();
|
||||
gadgetInfo.setWorktop(worktop);
|
||||
} catch (NullPointerException ignored) {
|
||||
// "this.wrapped" is null.
|
||||
gadgetInfo.setWorktop(
|
||||
WorktopInfo.newBuilder().addAllOptionList(Collections.emptyList()).build());
|
||||
gadgetInfo.setWorktop(WorktopInfo.newBuilder()
|
||||
.addAllOptionList(Collections.emptyList()).build());
|
||||
Grasscutter.getLogger().warn("GadgetWorktop.onBuildProto: this.wrapped is null");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,9 @@ import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.game.quest.enums.QuestContent;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
@@ -38,27 +39,28 @@ public class PlayerProgress {
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a dungeon as completed. Triggers the quest event.
|
||||
* Marks a dungeon as completed.
|
||||
* Triggers the quest event.
|
||||
*
|
||||
* @param dungeonId The dungeon which was completed.
|
||||
*/
|
||||
public void markDungeonAsComplete(int dungeonId) {
|
||||
if (this.getCompletedDungeons().contains(dungeonId)) return;
|
||||
if (this.getCompletedDungeons().contains(dungeonId))
|
||||
return;
|
||||
|
||||
// Mark the dungeon as completed.
|
||||
this.getCompletedDungeons().add(dungeonId);
|
||||
// Trigger the completion event.
|
||||
if (this.getPlayer() != null) {
|
||||
this.getPlayer()
|
||||
.getQuestManager()
|
||||
.queueEvent(QuestContent.QUEST_CONTENT_FINISH_DUNGEON, dungeonId);
|
||||
this.getPlayer().getQuestManager().queueEvent(
|
||||
QuestContent.QUEST_CONTENT_FINISH_DUNGEON, dungeonId
|
||||
);
|
||||
} else {
|
||||
Grasscutter.getLogger()
|
||||
.warn("Unable to execute 'QUEST_CONTENT_FINISH_DUNGEON'. The player is null.");
|
||||
Grasscutter.getLogger().warn("Unable to execute 'QUEST_CONTENT_FINISH_DUNGEON'. The player is null.");
|
||||
}
|
||||
|
||||
Grasscutter.getLogger()
|
||||
.debug("Dungeon {} has been marked complete for {}.", dungeonId, this.getPlayer().getUid());
|
||||
Grasscutter.getLogger().debug("Dungeon {} has been marked complete for {}.",
|
||||
dungeonId, this.getPlayer().getUid());
|
||||
}
|
||||
|
||||
public boolean hasPlayerObtainedItemHistorically(int itemId) {
|
||||
|
||||
@@ -132,7 +132,8 @@ public final class TeamManager extends BasePlayerDataManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the active team. If there are errors with the team, they can be fixed.
|
||||
* Returns the active team.
|
||||
* If there are errors with the team, they can be fixed.
|
||||
*
|
||||
* @param fix If true, the team will be fixed.
|
||||
* @return The active team.
|
||||
@@ -557,32 +558,27 @@ public final class TeamManager extends BasePlayerDataManager {
|
||||
this.trialAvatarTeam = new TeamInfo();
|
||||
|
||||
// Remove the avatars from the team.
|
||||
this.getActiveTeam()
|
||||
.forEach(
|
||||
avatarEntity ->
|
||||
scene.removeEntity(
|
||||
avatarEntity, VisionTypeOuterClass.VisionType.VISION_TYPE_REMOVE));
|
||||
this.getActiveTeam().forEach(avatarEntity -> scene
|
||||
.removeEntity(avatarEntity, VisionTypeOuterClass.VisionType.VISION_TYPE_REMOVE));
|
||||
|
||||
if (isTeam) {
|
||||
this.getActiveTeam().clear();
|
||||
this.getTrialAvatars().clear();
|
||||
} else {
|
||||
trialAvatarIds.forEach(
|
||||
trialAvatarId -> {
|
||||
this.getActiveTeam().removeIf(x -> x.getAvatar().getTrialAvatarId() == trialAvatarId);
|
||||
this.getTrialAvatars().values().removeIf(x -> x.getTrialAvatarId() == trialAvatarId);
|
||||
});
|
||||
trialAvatarId -> {
|
||||
this.getActiveTeam().removeIf(x -> x.getAvatar().getTrialAvatarId() == trialAvatarId);
|
||||
this.getTrialAvatars().values().removeIf(x -> x.getTrialAvatarId() == trialAvatarId);
|
||||
});
|
||||
}
|
||||
|
||||
// Re-add the avatars to the team.
|
||||
if (isTeam) {
|
||||
// Restores all avatars from the player's avatar storage.
|
||||
this.getCurrentTeamInfo()
|
||||
.getAvatars()
|
||||
.forEach(
|
||||
avatarId ->
|
||||
this.getActiveTeam()
|
||||
.add(new EntityAvatar(scene, player.getAvatars().getAvatarById(avatarId))));
|
||||
this.getCurrentTeamInfo().getAvatars().forEach(avatarId ->
|
||||
this.getActiveTeam().add(new EntityAvatar(
|
||||
scene, player.getAvatars().getAvatarById(avatarId)
|
||||
)));
|
||||
} else {
|
||||
// Restores all avatars from the player's avatar storage.
|
||||
// If the avatar is already in the team, it will not be added.
|
||||
@@ -590,9 +586,9 @@ public final class TeamManager extends BasePlayerDataManager {
|
||||
for (var index = 0; index < avatars.size() - 1; index++) {
|
||||
var avatar = avatars.get(index);
|
||||
if (this.getActiveTeam().stream()
|
||||
.map(entity -> entity.getAvatar().getAvatarId())
|
||||
.toList()
|
||||
.contains(avatar)) continue;
|
||||
.map(entity -> entity.getAvatar().getAvatarId())
|
||||
.toList()
|
||||
.contains(avatar)) continue;
|
||||
|
||||
// Check if the player owns the avatar.
|
||||
var avatarData = player.getAvatars().getAvatarById(avatar);
|
||||
@@ -1127,9 +1123,9 @@ public final class TeamManager extends BasePlayerDataManager {
|
||||
throw new IllegalStateException("Player is not using trial team.");
|
||||
|
||||
this.getPlayer()
|
||||
.sendPacket(
|
||||
new PacketAvatarDelNotify(
|
||||
trialAvatarIds.stream().map(this::getTrialAvatarGuid).toList()));
|
||||
.sendPacket(
|
||||
new PacketAvatarDelNotify(
|
||||
trialAvatarIds.stream().map(this::getTrialAvatarGuid).toList()));
|
||||
this.removeTrialAvatarTeam(trialAvatarIds);
|
||||
|
||||
// Update the team.
|
||||
|
||||
@@ -10,8 +10,8 @@ import emu.grasscutter.data.binout.MainQuestData;
|
||||
import emu.grasscutter.data.binout.MainQuestData.SubQuestData;
|
||||
import emu.grasscutter.data.binout.MainQuestData.TalkData;
|
||||
import emu.grasscutter.data.binout.ScriptSceneData;
|
||||
import emu.grasscutter.data.excels.RewardData;
|
||||
import emu.grasscutter.data.excels.quest.QuestData;
|
||||
import emu.grasscutter.data.excels.RewardData;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
@@ -26,6 +26,7 @@ import emu.grasscutter.utils.ConversionUtils;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.val;
|
||||
import org.bson.types.ObjectId;
|
||||
@@ -138,8 +139,7 @@ public class GameMainQuest {
|
||||
questManager.queueEvent(QuestContent.QUEST_CONTENT_QUEST_VAR_GREATER, index, value);
|
||||
questManager.queueEvent(QuestContent.QUEST_CONTENT_QUEST_VAR_LESS, index, value);
|
||||
|
||||
this.getOwner()
|
||||
.sendPacket(new PacketQuestUpdateQuestVarNotify(this.getParentQuestId(), this.questVars));
|
||||
this.getOwner().sendPacket(new PacketQuestUpdateQuestVarNotify(this.getParentQuestId(), this.questVars));
|
||||
}
|
||||
|
||||
public GameQuest getChildQuestById(int id) {
|
||||
@@ -158,10 +158,7 @@ public class GameMainQuest {
|
||||
// when auto finishing all child quests with QUEST_STATE_UNFINISHED (below)
|
||||
synchronized (this) {
|
||||
if (this.isFinished || this.state == ParentQuestState.PARENT_QUEST_STATE_FINISHED) {
|
||||
Grasscutter.getLogger()
|
||||
.debug(
|
||||
"Skip main quest {} finishing because it's already finished",
|
||||
this.getParentQuestId());
|
||||
Grasscutter.getLogger().debug("Skip main quest {} finishing because it's already finished",this.getParentQuestId());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -181,7 +178,7 @@ public class GameMainQuest {
|
||||
* new MainQuest 355 but if 35312 is not completed after the completion
|
||||
* of the main quest 353 - the character will not be able to leave place
|
||||
* (return again and again)
|
||||
*/
|
||||
*/
|
||||
this.getChildQuests().values().stream()
|
||||
.filter(p -> p.state != QuestState.QUEST_STATE_FINISHED)
|
||||
.forEach(GameQuest::finish);
|
||||
@@ -503,16 +500,9 @@ public class GameMainQuest {
|
||||
subQuestWithCond.getFinishProgressList());
|
||||
|
||||
if (this.getQuestManager().getLoggedQuests().contains(subQuestWithCond.getSubQuestId())) {
|
||||
Grasscutter.getLogger()
|
||||
.debug(
|
||||
">>> Quest {} will be {} as a result of content trigger {} ({}, {}).",
|
||||
subQuestWithCond.getSubQuestId(),
|
||||
shouldFinish ? "finished" : "not finished",
|
||||
condType.name(),
|
||||
paramStr,
|
||||
Arrays.stream(params)
|
||||
.mapToObj(String::valueOf)
|
||||
.collect(Collectors.joining(", ")));
|
||||
Grasscutter.getLogger().debug(">>> Quest {} will be {} as a result of content trigger {} ({}, {}).",
|
||||
subQuestWithCond.getSubQuestId(), shouldFinish ? "finished" : "not finished", condType.name(), paramStr,
|
||||
Arrays.stream(params).mapToObj(String::valueOf).collect(Collectors.joining(", ")));
|
||||
}
|
||||
|
||||
if (shouldFinish) subQuestWithCond.finish();
|
||||
|
||||
@@ -5,8 +5,8 @@ import dev.morphia.annotations.Transient;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.ChapterData;
|
||||
import emu.grasscutter.data.excels.TriggerExcelConfigData;
|
||||
import emu.grasscutter.data.excels.quest.QuestData;
|
||||
import emu.grasscutter.data.excels.TriggerExcelConfigData;
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
@@ -76,7 +76,8 @@ public class GameQuest {
|
||||
.toList();
|
||||
if (triggerCond.size() > 0) {
|
||||
for (val cond : triggerCond) {
|
||||
var newTrigger = GameData.getTriggerExcelConfigDataMap().get(cond.getParam()[0]);
|
||||
var newTrigger = GameData.getTriggerExcelConfigDataMap()
|
||||
.get(cond.getParam()[0]);
|
||||
if (newTrigger != null) {
|
||||
if (this.triggerData == null) {
|
||||
this.triggerData = new HashMap<>();
|
||||
@@ -84,7 +85,8 @@ public class GameQuest {
|
||||
|
||||
triggerData.put(newTrigger.getTriggerName(), newTrigger);
|
||||
triggers.put(newTrigger.getTriggerName(), false);
|
||||
var group = SceneGroup.of(newTrigger.getGroupId()).load(newTrigger.getSceneId());
|
||||
var group = SceneGroup.of(newTrigger.getGroupId())
|
||||
.load(newTrigger.getSceneId());
|
||||
this.getOwner()
|
||||
.getWorld()
|
||||
.getSceneById(newTrigger.getSceneId())
|
||||
@@ -109,7 +111,8 @@ public class GameQuest {
|
||||
|
||||
this.getQuestData()
|
||||
.getBeginExec()
|
||||
.forEach(e -> getOwner().getServer().getQuestSystem().triggerExec(this, e, e.getParam()));
|
||||
.forEach(e -> getOwner().getServer().getQuestSystem()
|
||||
.triggerExec(this, e, e.getParam()));
|
||||
this.getOwner().getQuestManager().checkQuestAlreadyFullfilled(this);
|
||||
|
||||
Grasscutter.getLogger().debug("Quest {} is started", subQuestId);
|
||||
@@ -117,8 +120,11 @@ public class GameQuest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers events: 'QUEST_COND_STATE_EQUAL', 'QUEST_COND_STATE_NOT_EQUAL',
|
||||
* 'QUEST_CONTENT_QUEST_STATE_EQUAL', 'QUEST_CONTENT_QUEST_STATE_NOT_EQUAL'
|
||||
* Triggers events:
|
||||
* 'QUEST_COND_STATE_EQUAL',
|
||||
* 'QUEST_COND_STATE_NOT_EQUAL',
|
||||
* 'QUEST_CONTENT_QUEST_STATE_EQUAL',
|
||||
* 'QUEST_CONTENT_QUEST_STATE_NOT_EQUAL'
|
||||
*/
|
||||
public void triggerStateEvents() {
|
||||
var questManager = this.getOwner().getQuestManager();
|
||||
@@ -128,8 +134,7 @@ public class GameQuest {
|
||||
questManager.queueEvent(QuestCond.QUEST_COND_STATE_EQUAL, questId, state, 0, 0, 0);
|
||||
questManager.queueEvent(QuestCond.QUEST_COND_STATE_NOT_EQUAL, questId, state, 0, 0, 0);
|
||||
questManager.queueEvent(QuestContent.QUEST_CONTENT_QUEST_STATE_EQUAL, questId, state, 0, 0, 0);
|
||||
questManager.queueEvent(
|
||||
QuestContent.QUEST_CONTENT_QUEST_STATE_NOT_EQUAL, questId, state, 0, 0, 0);
|
||||
questManager.queueEvent(QuestContent.QUEST_CONTENT_QUEST_STATE_NOT_EQUAL, questId, state, 0, 0, 0);
|
||||
}
|
||||
|
||||
public String getTriggerNameById(int id) {
|
||||
|
||||
@@ -20,6 +20,7 @@ public class ConditionStateNotEqual extends BaseCondition {
|
||||
var questStateValue = condition.getParam()[1];
|
||||
var checkQuest = owner.getQuestManager().getQuestById(questId);
|
||||
|
||||
return checkQuest != null && checkQuest.getState().getValue() != questStateValue;
|
||||
return checkQuest != null &&
|
||||
checkQuest.getState().getValue() != questStateValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,8 @@ public class ContentCompleteAnyTalk extends BaseContent {
|
||||
public boolean execute(
|
||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||
return Stream.of(condition.getParamStr().split(","))
|
||||
.mapToInt(Integer::parseInt)
|
||||
.anyMatch(
|
||||
talkId ->
|
||||
GameData.getTalkConfigDataMap().get(params[0]) != null && talkId == params[0]);
|
||||
.mapToInt(Integer::parseInt)
|
||||
.anyMatch(talkId -> GameData.getTalkConfigDataMap()
|
||||
.get(params[0]) != null && talkId == params[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.quest.QuestData;
|
||||
import emu.grasscutter.game.quest.GameQuest;
|
||||
import emu.grasscutter.game.quest.QuestValueContent;
|
||||
import lombok.val;
|
||||
|
||||
@QuestValueContent(QUEST_CONTENT_COMPLETE_TALK)
|
||||
public class ContentCompleteTalk extends BaseContent {
|
||||
@@ -13,7 +14,7 @@ public class ContentCompleteTalk extends BaseContent {
|
||||
@Override
|
||||
public boolean execute(
|
||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||
return condition.getParam()[0] == params[0]
|
||||
&& GameData.getTalkConfigDataMap().get(condition.getParam()[0]) != null;
|
||||
return condition.getParam()[0] == params[0] &&
|
||||
GameData.getTalkConfigDataMap().get(condition.getParam()[0]) != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ public class ContentFinishDungeon extends BaseContent {
|
||||
public boolean execute(
|
||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||
var dungeonId = condition.getParam()[0];
|
||||
return quest.getOwner().getPlayerProgress().getCompletedDungeons().contains(dungeonId);
|
||||
return quest.getOwner().getPlayerProgress()
|
||||
.getCompletedDungeons().contains(dungeonId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ public class ContentTriggerFire extends BaseContent {
|
||||
return quest.getTriggers().get(quest.getTriggerNameById(params[0]));
|
||||
} else {
|
||||
Grasscutter.getLogger()
|
||||
.debug("Quest {} doesn't have trigger {} registered.", quest.getSubQuestId(), params[0]);
|
||||
.debug("Quest {} doesn't have trigger {} registered.",
|
||||
quest.getSubQuestId(), params[0]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,7 @@ public class ExecRemoveTrialAvatar extends QuestExecHandler {
|
||||
return true;
|
||||
} catch (IllegalStateException ignored) {
|
||||
// The player does not have any trial avatars equipped.
|
||||
Grasscutter.getLogger()
|
||||
.warn("Attempted to remove trial avatars from player with none equipped.");
|
||||
Grasscutter.getLogger().warn("Attempted to remove trial avatars from player with none equipped.");
|
||||
return true;
|
||||
} catch (RuntimeException exception) {
|
||||
exception.printStackTrace();
|
||||
|
||||
@@ -2,11 +2,12 @@ package emu.grasscutter.game.talk;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum TalkExec {
|
||||
@@ -31,12 +32,11 @@ public enum TalkExec {
|
||||
|
||||
static {
|
||||
Stream.of(TalkExec.values())
|
||||
.filter(e -> e.name().startsWith("TALK_EXEC_"))
|
||||
.forEach(
|
||||
entry -> {
|
||||
execMap.put(entry.getValue(), entry);
|
||||
execStringMap.put(entry.name(), entry);
|
||||
});
|
||||
.filter(e -> e.name().startsWith("TALK_EXEC_"))
|
||||
.forEach(entry -> {
|
||||
execMap.put(entry.getValue(), entry);
|
||||
execStringMap.put(entry.name(), entry);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
package emu.grasscutter.game.talk;
|
||||
|
||||
import static emu.grasscutter.game.quest.enums.QuestCond.QUEST_COND_COMPLETE_TALK;
|
||||
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_ANY_TALK;
|
||||
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_TALK;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.binout.MainQuestData.TalkData;
|
||||
import emu.grasscutter.game.player.BasePlayerManager;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_ANY_TALK;
|
||||
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_TALK;
|
||||
import static emu.grasscutter.game.quest.enums.QuestCond.QUEST_COND_COMPLETE_TALK;
|
||||
|
||||
public final class TalkManager extends BasePlayerManager {
|
||||
public TalkManager(@NonNull Player player) {
|
||||
super(player);
|
||||
@@ -26,11 +27,8 @@ public final class TalkManager extends BasePlayerManager {
|
||||
|
||||
var player = this.getPlayer();
|
||||
// Execute the talk action on associated handlers.
|
||||
talkData
|
||||
.getFinishExec()
|
||||
.forEach(
|
||||
e ->
|
||||
this.getPlayer().getServer().getTalkSystem().triggerExec(getPlayer(), talkData, e));
|
||||
talkData.getFinishExec().forEach(e -> this.getPlayer().getServer()
|
||||
.getTalkSystem().triggerExec(getPlayer(), talkData, e));
|
||||
|
||||
// Invoke the talking events for quests.
|
||||
var questManager = player.getQuestManager();
|
||||
@@ -45,7 +43,8 @@ public final class TalkManager extends BasePlayerManager {
|
||||
public void saveTalkToQuest(int talkId, int mainQuestId) {
|
||||
// TODO, problem with this is that some talks for activity also have
|
||||
// quest id, which isn't present in QuestExcels
|
||||
var mainQuest = this.getPlayer().getQuestManager().getMainQuestById(mainQuestId);
|
||||
var mainQuest = this.getPlayer().getQuestManager()
|
||||
.getMainQuestById(mainQuestId);
|
||||
if (mainQuest == null) return;
|
||||
|
||||
mainQuest.getTalks().put(talkId, new TalkData(talkId, ""));
|
||||
|
||||
@@ -11,13 +11,15 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
public final class TalkSystem extends BaseGameSystem {
|
||||
private final Int2ObjectMap<TalkExecHandler> execHandlers = new Int2ObjectOpenHashMap<>();
|
||||
private final Int2ObjectMap<TalkExecHandler> execHandlers
|
||||
= new Int2ObjectOpenHashMap<>();
|
||||
|
||||
public TalkSystem(GameServer server) {
|
||||
super(server);
|
||||
|
||||
this.registerHandlers(
|
||||
this.execHandlers, "emu.grasscutter.game.talk.exec", TalkExecHandler.class);
|
||||
this.registerHandlers(this.execHandlers,
|
||||
"emu.grasscutter.game.talk.exec",
|
||||
TalkExecHandler.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,8 +46,7 @@ public final class TalkSystem extends BaseGameSystem {
|
||||
*/
|
||||
public <T> void registerTalkHandler(Int2ObjectMap<T> map, Class<? extends T> handlerClass) {
|
||||
try {
|
||||
var value = 0;
|
||||
if (handlerClass.isAnnotationPresent(TalkValueExec.class)) {
|
||||
var value = 0; if (handlerClass.isAnnotationPresent(TalkValueExec.class)) {
|
||||
TalkValueExec opcode = handlerClass.getAnnotation(TalkValueExec.class);
|
||||
value = opcode.value().getValue();
|
||||
} else {
|
||||
@@ -69,11 +70,8 @@ public final class TalkSystem extends BaseGameSystem {
|
||||
public void triggerExec(Player player, TalkConfigData talkData, TalkExecParam execParam) {
|
||||
var handler = this.execHandlers.get(execParam.getType().getValue());
|
||||
if (handler == null) {
|
||||
Grasscutter.getLogger()
|
||||
.debug(
|
||||
"Could not execute talk handlers for {} ({}).",
|
||||
talkData.getId(),
|
||||
execParam.getType().getValue());
|
||||
Grasscutter.getLogger().debug("Could not execute talk handlers for {} ({}).",
|
||||
talkData.getId(), execParam.getType().getValue());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@ public final class ExecDecQuestGlobalVar extends TalkExecHandler {
|
||||
public void execute(Player player, TalkConfigData talkData, TalkExecParam execParam) {
|
||||
if (execParam.getParam().length < 2) return;
|
||||
|
||||
player
|
||||
.getQuestManager()
|
||||
.decQuestGlobalVarValue(
|
||||
Integer.parseInt(execParam.getParam()[0]), Integer.parseInt(execParam.getParam()[1]));
|
||||
player.getQuestManager().decQuestGlobalVarValue(
|
||||
Integer.parseInt(execParam.getParam()[0]),
|
||||
Integer.parseInt(execParam.getParam()[1])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,14 @@ public final class ExecDecQuestVar extends TalkExecHandler {
|
||||
public void execute(Player player, TalkConfigData talkData, TalkExecParam execParam) {
|
||||
if (execParam.getParam().length < 3) return;
|
||||
|
||||
GameMainQuest mainQuest =
|
||||
player.getQuestManager().getMainQuestById(Integer.parseInt(execParam.getParam()[2]));
|
||||
GameMainQuest mainQuest = player.getQuestManager().getMainQuestById(
|
||||
Integer.parseInt(execParam.getParam()[2])
|
||||
);
|
||||
if (mainQuest == null) return;
|
||||
|
||||
mainQuest.decQuestVar(
|
||||
Integer.parseInt(execParam.getParam()[0]), Integer.parseInt(execParam.getParam()[1]));
|
||||
Integer.parseInt(execParam.getParam()[0]),
|
||||
Integer.parseInt(execParam.getParam()[1])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ public final class ExecIncQuestGlobalVar extends TalkExecHandler {
|
||||
public void execute(Player player, TalkConfigData talkData, TalkExecParam execParam) {
|
||||
if (execParam.getParam().length < 2) return;
|
||||
|
||||
player
|
||||
.getQuestManager()
|
||||
.incQuestGlobalVarValue(
|
||||
Integer.parseInt(execParam.getParam()[0]), Integer.parseInt(execParam.getParam()[1]));
|
||||
player.getQuestManager().incQuestGlobalVarValue(
|
||||
Integer.parseInt(execParam.getParam()[0]),
|
||||
Integer.parseInt(execParam.getParam()[1])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,14 @@ public final class ExecIncQuestVar extends TalkExecHandler {
|
||||
public void execute(Player player, TalkConfigData talkData, TalkExecParam execParam) {
|
||||
if (execParam.getParam().length < 3) return;
|
||||
|
||||
GameMainQuest mainQuest =
|
||||
player.getQuestManager().getMainQuestById(Integer.parseInt(execParam.getParam()[2]));
|
||||
GameMainQuest mainQuest = player.getQuestManager().getMainQuestById(
|
||||
Integer.parseInt(execParam.getParam()[2])
|
||||
);
|
||||
if (mainQuest == null) return;
|
||||
|
||||
mainQuest.incQuestVar(
|
||||
Integer.parseInt(execParam.getParam()[0]), Integer.parseInt(execParam.getParam()[1]));
|
||||
Integer.parseInt(execParam.getParam()[0]),
|
||||
Integer.parseInt(execParam.getParam()[1])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ public final class ExecSetQuestGlobalVar extends TalkExecHandler {
|
||||
public void execute(Player player, TalkConfigData talkData, TalkExecParam execParam) {
|
||||
if (execParam.getParam().length < 2) return;
|
||||
|
||||
player
|
||||
.getQuestManager()
|
||||
.setQuestGlobalVarValue(
|
||||
Integer.parseInt(execParam.getParam()[0]), Integer.parseInt(execParam.getParam()[1]));
|
||||
player.getQuestManager().setQuestGlobalVarValue(
|
||||
Integer.parseInt(execParam.getParam()[0]),
|
||||
Integer.parseInt(execParam.getParam()[1])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package emu.grasscutter.game.talk.exec;
|
||||
import emu.grasscutter.data.excels.TalkConfigData;
|
||||
import emu.grasscutter.data.excels.TalkConfigData.TalkExecParam;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.GameMainQuest;
|
||||
import emu.grasscutter.game.talk.TalkExec;
|
||||
import emu.grasscutter.game.talk.TalkExecHandler;
|
||||
import emu.grasscutter.game.talk.TalkValueExec;
|
||||
@@ -13,11 +14,14 @@ public final class ExecSetQuestVar extends TalkExecHandler {
|
||||
public void execute(Player player, TalkConfigData talkData, TalkExecParam execParam) {
|
||||
if (execParam.getParam().length < 3) return;
|
||||
|
||||
var mainQuest =
|
||||
player.getQuestManager().getMainQuestById(Integer.parseInt(execParam.getParam()[2]));
|
||||
var mainQuest = player.getQuestManager().getMainQuestById(
|
||||
Integer.parseInt(execParam.getParam()[2])
|
||||
);
|
||||
if (mainQuest == null) return;
|
||||
|
||||
mainQuest.setQuestVar(
|
||||
Integer.parseInt(execParam.getParam()[0]), Integer.parseInt(execParam.getParam()[1]));
|
||||
Integer.parseInt(execParam.getParam()[0]),
|
||||
Integer.parseInt(execParam.getParam()[1])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package emu.grasscutter.game.talk.exec;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.binout.ScriptSceneData;
|
||||
import emu.grasscutter.data.excels.TalkConfigData;
|
||||
import emu.grasscutter.data.excels.TalkConfigData.TalkExecParam;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
@@ -16,30 +17,23 @@ public final class ExecTransSceneDummyPoint extends TalkExecHandler {
|
||||
// param[0] == sceneid, param[1] == position
|
||||
if (execParam.getParam().length < 2) return;
|
||||
|
||||
var fullGlobals =
|
||||
GameData.getScriptSceneDataMap().get("flat.luas.scenes.full_globals.lua.json");
|
||||
var fullGlobals = GameData.getScriptSceneDataMap().get("flat.luas.scenes.full_globals.lua.json");
|
||||
if (fullGlobals == null) return;
|
||||
|
||||
var dummyPointScript =
|
||||
fullGlobals
|
||||
.getScriptObjectList()
|
||||
.get(
|
||||
execParam.getParam()[0] + "/scene" + execParam.getParam()[0] + "_dummy_points.lua");
|
||||
var dummyPointScript = fullGlobals.getScriptObjectList()
|
||||
.get(execParam.getParam()[0] + "/scene" + execParam.getParam()[0] + "_dummy_points.lua");
|
||||
if (dummyPointScript == null) return;
|
||||
|
||||
var dummyPointMap = dummyPointScript.getDummyPoints();
|
||||
if (dummyPointMap == null) return;
|
||||
|
||||
var transmitPosPos = dummyPointMap.get(execParam.getParam()[1] + ".pos");
|
||||
// List<Float> transmitPosRot = dummyPointMap.get(e.getParam()[1] + ".rot"); would be useful
|
||||
// when transportation consider rotation
|
||||
// List<Float> transmitPosRot = dummyPointMap.get(e.getParam()[1] + ".rot"); would be useful when transportation consider rotation
|
||||
if (transmitPosPos == null || transmitPosPos.isEmpty()) return;
|
||||
|
||||
player
|
||||
.getWorld()
|
||||
.transferPlayerToScene(
|
||||
player,
|
||||
Integer.parseInt(execParam.getParam()[0]),
|
||||
new Position(transmitPosPos.get(0), transmitPosPos.get(1), transmitPosPos.get(2)));
|
||||
player.getWorld().transferPlayerToScene(
|
||||
player,
|
||||
Integer.parseInt(execParam.getParam()[0]),
|
||||
new Position(transmitPosPos.get(0), transmitPosPos.get(1), transmitPosPos.get(2)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -795,7 +795,7 @@ public final class Scene {
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized void checkGroups() {
|
||||
public void checkGroups() {
|
||||
Set<Integer> visible =
|
||||
this.players.stream()
|
||||
.map(player -> this.getPlayerActiveGroups(player))
|
||||
@@ -833,7 +833,7 @@ public final class Scene {
|
||||
this.getScriptManager().loadBlockFromScript(block);
|
||||
scriptManager.getLoadedGroupSetPerBlock().put(block.id, new HashSet<>());
|
||||
|
||||
Grasscutter.getLogger().debug("Scene {} Block {} loaded.", this.getId(), block.id);
|
||||
Grasscutter.getLogger().trace("Scene {} Block {} loaded.", this.getId(), block.id);
|
||||
}
|
||||
|
||||
public int loadDynamicGroup(int group_id) {
|
||||
@@ -963,7 +963,7 @@ public final class Scene {
|
||||
groupInstance = cachedInstance;
|
||||
}
|
||||
|
||||
// Load garbages
|
||||
/* Don't load garbages
|
||||
var garbageGadgets = group.getGarbageGadgets();
|
||||
|
||||
if (garbageGadgets != null) {
|
||||
@@ -973,7 +973,7 @@ public final class Scene {
|
||||
.filter(Objects::nonNull)
|
||||
.toList());
|
||||
}
|
||||
|
||||
*/
|
||||
// Load suites
|
||||
// int suite = group.findInitSuiteIndex(0);
|
||||
this.getScriptManager()
|
||||
@@ -1014,7 +1014,7 @@ public final class Scene {
|
||||
|
||||
if (this.scriptManager.getLoadedGroupSetPerBlock().get(block.id).isEmpty()) {
|
||||
this.scriptManager.getLoadedGroupSetPerBlock().remove(block.id);
|
||||
Grasscutter.getLogger().debug("Scene {} Block {} is unloaded.", this.getId(), block.id);
|
||||
Grasscutter.getLogger().trace("Scene {} Block {} is unloaded.", this.getId(), block.id);
|
||||
}
|
||||
|
||||
this.broadcastPacket(new PacketGroupUnloadNotify(List.of(group_id)));
|
||||
|
||||
@@ -53,15 +53,14 @@ public class PacketOpcodesUtils {
|
||||
public static void dumpPacketIds() {
|
||||
try (var writer = new FileWriter("./PacketIds_" + GameConstants.VERSION + ".json")) {
|
||||
// Create sorted tree map
|
||||
var packetIds =
|
||||
opcodeMap.int2ObjectEntrySet().stream()
|
||||
.filter(e -> e.getIntKey() > 0)
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
Int2ObjectMap.Entry::getIntKey,
|
||||
Int2ObjectMap.Entry::getValue,
|
||||
(k, v) -> v,
|
||||
TreeMap::new));
|
||||
var packetIds = opcodeMap.int2ObjectEntrySet().stream()
|
||||
.filter(e -> e.getIntKey() > 0)
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
Int2ObjectMap.Entry::getIntKey,
|
||||
Int2ObjectMap.Entry::getValue,
|
||||
(k, v) -> v,
|
||||
TreeMap::new));
|
||||
// Write to file
|
||||
writer.write(JsonUtils.encode(packetIds));
|
||||
Grasscutter.getLogger().info("Dumped packet IDs.");
|
||||
|
||||
@@ -171,10 +171,8 @@ public final class SceneGroup {
|
||||
.error(
|
||||
"An error occurred while loading group " + this.id + " in scene " + sceneId + ".", e);
|
||||
} catch (LuaError luaError) {
|
||||
Grasscutter.getLogger()
|
||||
.error(
|
||||
"An error occurred while loading group %s in scene %s.".formatted(this.id, sceneId),
|
||||
luaError);
|
||||
Grasscutter.getLogger().error("An error occurred while loading group %s in scene %s."
|
||||
.formatted(this.id, sceneId), luaError);
|
||||
}
|
||||
|
||||
Grasscutter.getLogger().trace("Successfully loaded group {} in scene {}.", this.id, sceneId);
|
||||
|
||||
@@ -114,7 +114,8 @@ public final class RegionHandler implements Router {
|
||||
customConfig.addProperty("sdkenv", "2");
|
||||
customConfig.addProperty("checkdevice", "false");
|
||||
customConfig.addProperty("loadPatch", "false");
|
||||
customConfig.addProperty("showexception", String.valueOf(showExceptions));
|
||||
customConfig.addProperty("showexception",
|
||||
String.valueOf(showExceptions));
|
||||
customConfig.addProperty("regionConfig", "pm|fk|add");
|
||||
customConfig.addProperty("downloadMode", "0");
|
||||
customConfig.add("coverSwitch", hiddenIcons);
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.binout.MainQuestData;
|
||||
import emu.grasscutter.data.binout.MainQuestData.TalkData;
|
||||
import emu.grasscutter.game.quest.enums.QuestCond;
|
||||
import emu.grasscutter.game.quest.enums.QuestContent;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
|
||||
@@ -3,6 +3,7 @@ package emu.grasscutter.server.packet.recv;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.PacketHeadOuterClass.PacketHead;
|
||||
import emu.grasscutter.net.proto.PlayerSetPauseReqOuterClass.PlayerSetPauseReq;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerSetPauseRsp;
|
||||
|
||||
@@ -5,9 +5,11 @@ import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.QuestUpdateQuestVarReqOuterClass.QuestUpdateQuestVarReq;
|
||||
import emu.grasscutter.net.proto.QuestVarOpOuterClass.QuestVarOp;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketQuestUpdateQuestVarRsp;
|
||||
import java.util.List;
|
||||
|
||||
@Opcodes(PacketOpcodes.QuestUpdateQuestVarReq)
|
||||
public class HandlerQuestUpdateQuestVarReq extends PacketHandler {
|
||||
|
||||
@@ -10,6 +10,7 @@ public class PacketPlayerSetPauseRsp extends BasePacket {
|
||||
public PacketPlayerSetPauseRsp() {
|
||||
super(PacketOpcodes.PlayerSetPauseRsp);
|
||||
|
||||
this.setData(PlayerSetPauseRsp.newBuilder().setRetcode(Retcode.RET_SUCC_VALUE));
|
||||
this.setData(PlayerSetPauseRsp.newBuilder()
|
||||
.setRetcode(Retcode.RET_SUCC_VALUE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,21 +6,18 @@ import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.QuestGlobalVarNotifyOuterClass.QuestGlobalVarNotify;
|
||||
import emu.grasscutter.net.proto.QuestGlobalVarOuterClass.QuestGlobalVar;
|
||||
|
||||
|
||||
public final class PacketQuestGlobalVarNotify extends BasePacket {
|
||||
public PacketQuestGlobalVarNotify(Player player) {
|
||||
super(PacketOpcodes.QuestGlobalVarNotify);
|
||||
|
||||
this.setData(
|
||||
QuestGlobalVarNotify.newBuilder()
|
||||
.addAllVarList(
|
||||
player.getQuestGlobalVariables().entrySet().stream()
|
||||
.map(
|
||||
entry ->
|
||||
QuestGlobalVar.newBuilder()
|
||||
.setKey(entry.getKey())
|
||||
.setValue(entry.getValue())
|
||||
.build())
|
||||
.toList())
|
||||
.build());
|
||||
this.setData(QuestGlobalVarNotify.newBuilder()
|
||||
.addAllVarList(player.getQuestGlobalVariables().entrySet().stream()
|
||||
.map(entry -> QuestGlobalVar.newBuilder()
|
||||
.setKey(entry.getKey())
|
||||
.setValue(entry.getValue())
|
||||
.build())
|
||||
.toList())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,16 +3,17 @@ package emu.grasscutter.server.packet.send;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.QuestUpdateQuestVarNotifyOuterClass.QuestUpdateQuestVarNotify;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class PacketQuestUpdateQuestVarNotify extends BasePacket {
|
||||
public PacketQuestUpdateQuestVarNotify(int mainQuestId, int... questVars) {
|
||||
super(PacketOpcodes.QuestUpdateQuestVarNotify);
|
||||
|
||||
this.setData(
|
||||
QuestUpdateQuestVarNotify.newBuilder()
|
||||
.setParentQuestId(mainQuestId)
|
||||
.addAllQuestVar(IntStream.of(questVars).boxed().toList())
|
||||
.build());
|
||||
this.setData(QuestUpdateQuestVarNotify.newBuilder()
|
||||
.setParentQuestId(mainQuestId)
|
||||
.addAllQuestVar(IntStream.of(questVars)
|
||||
.boxed().toList())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,24 +11,25 @@ public class PacketSceneTeamUpdateNotify extends BasePacket {
|
||||
public PacketSceneTeamUpdateNotify(Player player) {
|
||||
super(PacketOpcodes.SceneTeamUpdateNotify);
|
||||
|
||||
var proto = SceneTeamUpdateNotify.newBuilder().setIsInMp(player.getWorld().isMultiplayer());
|
||||
var proto = SceneTeamUpdateNotify.newBuilder()
|
||||
.setIsInMp(player.getWorld().isMultiplayer());
|
||||
|
||||
for (var p : player.getWorld().getPlayers()) {
|
||||
for (var entityAvatar : p.getTeamManager().getActiveTeam(true)) {
|
||||
var avatarProto =
|
||||
SceneTeamAvatar.newBuilder()
|
||||
.setPlayerUid(p.getUid())
|
||||
.setAvatarGuid(entityAvatar.getAvatar().getGuid())
|
||||
.setSceneId(p.getSceneId())
|
||||
.setEntityId(entityAvatar.getId())
|
||||
.setSceneEntityInfo(entityAvatar.toProto())
|
||||
.setWeaponGuid(entityAvatar.getAvatar().getWeapon().getGuid())
|
||||
.setWeaponEntityId(entityAvatar.getWeaponEntityId())
|
||||
.setIsPlayerCurAvatar(p.getTeamManager().getCurrentAvatarEntity() == entityAvatar)
|
||||
.setIsOnScene(p.getTeamManager().getCurrentAvatarEntity() == entityAvatar)
|
||||
.setAvatarAbilityInfo(AbilitySyncStateInfo.newBuilder())
|
||||
.setWeaponAbilityInfo(AbilitySyncStateInfo.newBuilder())
|
||||
.setAbilityControlBlock(entityAvatar.getAbilityControlBlock());
|
||||
SceneTeamAvatar.newBuilder()
|
||||
.setPlayerUid(p.getUid())
|
||||
.setAvatarGuid(entityAvatar.getAvatar().getGuid())
|
||||
.setSceneId(p.getSceneId())
|
||||
.setEntityId(entityAvatar.getId())
|
||||
.setSceneEntityInfo(entityAvatar.toProto())
|
||||
.setWeaponGuid(entityAvatar.getAvatar().getWeapon().getGuid())
|
||||
.setWeaponEntityId(entityAvatar.getWeaponEntityId())
|
||||
.setIsPlayerCurAvatar(p.getTeamManager().getCurrentAvatarEntity() == entityAvatar)
|
||||
.setIsOnScene(p.getTeamManager().getCurrentAvatarEntity() == entityAvatar)
|
||||
.setAvatarAbilityInfo(AbilitySyncStateInfo.newBuilder())
|
||||
.setWeaponAbilityInfo(AbilitySyncStateInfo.newBuilder())
|
||||
.setAbilityControlBlock(entityAvatar.getAbilityControlBlock());
|
||||
|
||||
if (player.getWorld().isMultiplayer()) {
|
||||
avatarProto.setAvatarInfo(entityAvatar.getAvatar().toProto());
|
||||
|
||||
@@ -41,7 +41,11 @@ public final class GridPosition implements Serializable {
|
||||
|
||||
@SneakyThrows
|
||||
public GridPosition(String str) {
|
||||
var listOfParams = str.replace(" ", "").replace("(", "").replace(")", "").split(",");
|
||||
var listOfParams = str
|
||||
.replace(" ", "")
|
||||
.replace("(", "")
|
||||
.replace(")", "")
|
||||
.split(",");
|
||||
if (listOfParams.length != 3)
|
||||
throw new IOException("invalid size on GridPosition definition - ");
|
||||
try {
|
||||
|
||||
@@ -90,14 +90,20 @@ public class JsonAdapters {
|
||||
|
||||
// GridPosition follows the format of: (x, y, z).
|
||||
// Flatten to (x,y,z) for easier parsing.
|
||||
var str = in.nextString().replace("(", "").replace(")", "").replace(" ", "");
|
||||
var str = in.nextString()
|
||||
.replace("(", "")
|
||||
.replace(")", "")
|
||||
.replace(" ", "");
|
||||
var split = str.split(",");
|
||||
|
||||
if (split.length != 3)
|
||||
throw new IOException("Invalid GridPosition definition - " + in.peek().name());
|
||||
|
||||
return new GridPosition(
|
||||
Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]));
|
||||
Integer.parseInt(split[0]),
|
||||
Integer.parseInt(split[1]),
|
||||
Integer.parseInt(split[2])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,13 +22,13 @@ import java.util.Map;
|
||||
public final class JsonUtils {
|
||||
static final Gson gson =
|
||||
new GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(DynamicFloat.class, new DynamicFloatAdapter())
|
||||
.registerTypeAdapter(IntList.class, new IntListAdapter())
|
||||
.registerTypeAdapter(Position.class, new PositionAdapter())
|
||||
.registerTypeAdapter(GridPosition.class, new GridPositionAdapter())
|
||||
.registerTypeAdapterFactory(new EnumTypeAdapterFactory())
|
||||
.create();
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(DynamicFloat.class, new DynamicFloatAdapter())
|
||||
.registerTypeAdapter(IntList.class, new IntListAdapter())
|
||||
.registerTypeAdapter(Position.class, new PositionAdapter())
|
||||
.registerTypeAdapter(GridPosition.class, new GridPositionAdapter())
|
||||
.registerTypeAdapterFactory(new EnumTypeAdapterFactory())
|
||||
.create();
|
||||
|
||||
/*
|
||||
* Encode an object to a JSON string
|
||||
|
||||
Reference in New Issue
Block a user