mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-11 00:02:53 +08:00
Continue merging quests
(pt. 2)
This commit is contained in:
parent
97ee71bcf4
commit
644f1b3ab9
@ -25,6 +25,8 @@ public class CommandHelpers {
|
|||||||
public static final Pattern atkRegex = Pattern.compile("atk(\\d+)");
|
public static final Pattern atkRegex = Pattern.compile("atk(\\d+)");
|
||||||
public static final Pattern defRegex = Pattern.compile("def(\\d+)");
|
public static final Pattern defRegex = Pattern.compile("def(\\d+)");
|
||||||
public static final Pattern aiRegex = Pattern.compile("ai(\\d+)");
|
public static final Pattern aiRegex = Pattern.compile("ai(\\d+)");
|
||||||
|
public static final Pattern sceneRegex = Pattern.compile("scene(\\d+)");
|
||||||
|
public static final Pattern suiteRegex = Pattern.compile("suite(\\d+)");
|
||||||
|
|
||||||
public static int matchIntOrNeg(Pattern pattern, String arg) {
|
public static int matchIntOrNeg(Pattern pattern, String arg) {
|
||||||
Matcher match = pattern.matcher(arg);
|
Matcher match = pattern.matcher(arg);
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package emu.grasscutter.command.commands;
|
||||||
|
|
||||||
|
import emu.grasscutter.command.Command;
|
||||||
|
import emu.grasscutter.command.CommandHandler;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketCutsceneBeginNotify;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
|
@Command(
|
||||||
|
label = "cutscene",
|
||||||
|
aliases = {"c"},
|
||||||
|
usage = {"[<cutsceneId>]"},
|
||||||
|
permission = "player.group",
|
||||||
|
permissionTargeted = "player.group.others")
|
||||||
|
public final class CutsceneCommand implements CommandHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||||
|
if (args.isEmpty()) {
|
||||||
|
sendUsageMessage(sender);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
val cutSceneId = Integer.parseInt(args.get(0));
|
||||||
|
targetPlayer.sendPacket(new PacketCutsceneBeginNotify(cutSceneId));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package emu.grasscutter.command.commands;
|
||||||
|
|
||||||
|
import static emu.grasscutter.utils.Language.translate;
|
||||||
|
|
||||||
|
import emu.grasscutter.command.Command;
|
||||||
|
import emu.grasscutter.command.CommandHandler;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketScenePlayerSoundNotify;
|
||||||
|
import emu.grasscutter.utils.Position;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
|
@Command(
|
||||||
|
label = "sound",
|
||||||
|
aliases = {"s", "audio"},
|
||||||
|
usage = {"[<audioname>] [<x><y><z>]"},
|
||||||
|
permission = "player.group",
|
||||||
|
permissionTargeted = "player.group.others")
|
||||||
|
public final class SoundCommand implements CommandHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||||
|
if (args.isEmpty()) {
|
||||||
|
sendUsageMessage(sender);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
val soundName = args.get(0);
|
||||||
|
var playPosition = targetPlayer.getPosition();
|
||||||
|
if (args.size() == 4) {
|
||||||
|
try {
|
||||||
|
float x, y, z;
|
||||||
|
x = Float.parseFloat(args.get(1));
|
||||||
|
y = Float.parseFloat(args.get(2));
|
||||||
|
z = Float.parseFloat(args.get(3));
|
||||||
|
playPosition = new Position(x, y, z);
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
CommandHandler.sendMessage(sender, translate(sender, "commands.execution.argument_error"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (args.size() > 1) {
|
||||||
|
sendUsageMessage(sender);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
targetPlayer
|
||||||
|
.getScene()
|
||||||
|
.broadcastPacket(new PacketScenePlayerSoundNotify(playPosition, soundName, 1));
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,7 @@ import emu.grasscutter.data.excels.world.*;
|
|||||||
import emu.grasscutter.data.server.*;
|
import emu.grasscutter.data.server.*;
|
||||||
import emu.grasscutter.game.dungeons.*;
|
import emu.grasscutter.game.dungeons.*;
|
||||||
import emu.grasscutter.game.quest.*;
|
import emu.grasscutter.game.quest.*;
|
||||||
|
import emu.grasscutter.game.quest.enums.QuestCond;
|
||||||
import emu.grasscutter.game.world.*;
|
import emu.grasscutter.game.world.*;
|
||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
||||||
import it.unimi.dsi.fastutil.ints.*;
|
import it.unimi.dsi.fastutil.ints.*;
|
||||||
@ -611,6 +612,11 @@ public final class GameData {
|
|||||||
return datamap.get(dataId);
|
return datamap.get(dataId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable public static List<QuestData> getQuestDataByConditions(
|
||||||
|
QuestCond questCond, int param0, String questStr) {
|
||||||
|
return beginCondQuestMap.get(QuestData.questConditionKey(questCond, param0, questStr));
|
||||||
|
}
|
||||||
|
|
||||||
public static Int2ObjectMap<AchievementData> getAchievementDataMap() {
|
public static Int2ObjectMap<AchievementData> getAchievementDataMap() {
|
||||||
AchievementData.divideIntoGroups();
|
AchievementData.divideIntoGroups();
|
||||||
return achievementDataMap;
|
return achievementDataMap;
|
||||||
|
@ -5,8 +5,8 @@ import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
|||||||
public class InTimeTrigger extends ChallengeTrigger {
|
public class InTimeTrigger extends ChallengeTrigger {
|
||||||
@Override
|
@Override
|
||||||
public void onCheckTimeout(WorldChallenge challenge) {
|
public void onCheckTimeout(WorldChallenge challenge) {
|
||||||
var current = System.currentTimeMillis();
|
var current = challenge.getScene().getSceneTimeSeconds();
|
||||||
if (current - challenge.getStartedAt() > challenge.getTimeLimit() * 1000L) {
|
if (current - challenge.getStartedAt() > challenge.getTimeLimit()) {
|
||||||
challenge.fail();
|
challenge.fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ 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.EntityAvatar;
|
||||||
import emu.grasscutter.game.entity.GameEntity;
|
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;
|
||||||
@ -44,6 +45,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.QuestCond;
|
||||||
import emu.grasscutter.game.quest.enums.QuestContent;
|
import emu.grasscutter.game.quest.enums.QuestContent;
|
||||||
import emu.grasscutter.game.shop.ShopLimit;
|
import emu.grasscutter.game.shop.ShopLimit;
|
||||||
import emu.grasscutter.game.tower.TowerData;
|
import emu.grasscutter.game.tower.TowerData;
|
||||||
@ -51,20 +53,18 @@ import emu.grasscutter.game.tower.TowerManager;
|
|||||||
import emu.grasscutter.game.world.Scene;
|
import emu.grasscutter.game.world.Scene;
|
||||||
import emu.grasscutter.game.world.World;
|
import emu.grasscutter.game.world.World;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
|
import emu.grasscutter.net.proto.*;
|
||||||
import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry;
|
import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry;
|
||||||
import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult;
|
import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult;
|
||||||
import emu.grasscutter.net.proto.CombatInvokeEntryOuterClass.CombatInvokeEntry;
|
import emu.grasscutter.net.proto.CombatInvokeEntryOuterClass.CombatInvokeEntry;
|
||||||
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
|
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
|
||||||
import emu.grasscutter.net.proto.MpSettingTypeOuterClass.MpSettingType;
|
import emu.grasscutter.net.proto.MpSettingTypeOuterClass.MpSettingType;
|
||||||
import emu.grasscutter.net.proto.OnlinePlayerInfoOuterClass.OnlinePlayerInfo;
|
import emu.grasscutter.net.proto.OnlinePlayerInfoOuterClass.OnlinePlayerInfo;
|
||||||
import emu.grasscutter.net.proto.PlayerApplyEnterMpResultNotifyOuterClass;
|
|
||||||
import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo;
|
import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo;
|
||||||
import emu.grasscutter.net.proto.PlayerWorldLocationInfoOuterClass;
|
|
||||||
import emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture;
|
import emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture;
|
||||||
import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason;
|
import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason;
|
||||||
import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass;
|
|
||||||
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
|
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
|
||||||
import emu.grasscutter.net.proto.SocialShowAvatarInfoOuterClass;
|
import emu.grasscutter.net.proto.TrialAvatarGrantRecordOuterClass.TrialAvatarGrantRecord.GrantReason;
|
||||||
import emu.grasscutter.scripts.data.SceneRegion;
|
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;
|
||||||
@ -88,6 +88,7 @@ import java.time.ZoneId;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
|
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
|
||||||
|
|
||||||
@ -472,6 +473,8 @@ public class Player {
|
|||||||
|
|
||||||
// Handle open state unlocks from level-up.
|
// Handle open state unlocks from level-up.
|
||||||
this.getProgressManager().tryUnlockOpenStates();
|
this.getProgressManager().tryUnlockOpenStates();
|
||||||
|
this.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_PLAYER_LEVEL_UP, level);
|
||||||
|
this.getQuestManager().queueEvent(QuestCond.QUEST_COND_PLAYER_LEVEL_EQUAL_GREATER, level);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -613,7 +616,7 @@ public class Player {
|
|||||||
|
|
||||||
public void onEnterRegion(SceneRegion region) {
|
public void onEnterRegion(SceneRegion region) {
|
||||||
getQuestManager().forEachActiveQuest(quest -> {
|
getQuestManager().forEachActiveQuest(quest -> {
|
||||||
if (quest.getTriggers().containsKey("ENTER_REGION_" + region.config_id)) {
|
if (quest.getTriggerData() != null && quest.getTriggers().containsKey("ENTER_REGION_"+ region.config_id)) {
|
||||||
// If trigger hasn't been fired yet
|
// If trigger hasn't been fired yet
|
||||||
if (!Boolean.TRUE.equals(quest.getTriggers().put("ENTER_REGION_" + region.config_id, true))) {
|
if (!Boolean.TRUE.equals(quest.getTriggers().put("ENTER_REGION_" + region.config_id, true))) {
|
||||||
//getSession().send(new PacketServerCondMeetQuestListUpdateNotify());
|
//getSession().send(new PacketServerCondMeetQuestListUpdateNotify());
|
||||||
@ -824,6 +827,85 @@ public class Player {
|
|||||||
addAvatar(avatar, true);
|
addAvatar(avatar, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addAvatar(int avatarId) {
|
||||||
|
// I dont see why we cant do this lolz
|
||||||
|
addAvatar(new Avatar(avatarId), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getTrialAvatarParam (int trialAvatarId) {
|
||||||
|
if (GameData.getTrialAvatarCustomData().isEmpty()) { // use default data if custom data not available
|
||||||
|
if (GameData.getTrialAvatarDataMap().get(trialAvatarId) == null) return List.of();
|
||||||
|
|
||||||
|
return GameData.getTrialAvatarDataMap().get(trialAvatarId)
|
||||||
|
.getTrialAvatarParamList();
|
||||||
|
}
|
||||||
|
// use custom data
|
||||||
|
if (GameData.getTrialAvatarCustomData().get(trialAvatarId) == null) return List.of();
|
||||||
|
|
||||||
|
var trialCustomParams = GameData.getTrialAvatarCustomData().get(trialAvatarId).getTrialAvatarParamList();
|
||||||
|
return trialCustomParams.isEmpty() ? List.of() : Stream.of(trialCustomParams.get(0).split(";")).map(Integer::parseInt).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addTrialAvatar(int trialAvatarId, GrantReason reason, int questMainId){
|
||||||
|
List<Integer> trialAvatarBasicParam = getTrialAvatarParam(trialAvatarId);
|
||||||
|
if (trialAvatarBasicParam.isEmpty()) return false;
|
||||||
|
|
||||||
|
Avatar avatar = new Avatar(trialAvatarBasicParam.get(0));
|
||||||
|
if (avatar.getAvatarData() == null || !hasSentLoginPackets()) return false;
|
||||||
|
|
||||||
|
avatar.setOwner(this);
|
||||||
|
// Add trial weapons and relics
|
||||||
|
avatar.setTrialAvatarInfo(trialAvatarBasicParam.get(1), trialAvatarId, reason, questMainId);
|
||||||
|
avatar.equipTrialItems();
|
||||||
|
// Recalc stats
|
||||||
|
avatar.recalcStats();
|
||||||
|
|
||||||
|
// Packet, mimic official server behaviour, add to player's bag but not saving to db
|
||||||
|
sendPacket(new PacketAvatarAddNotify(avatar, false));
|
||||||
|
// add to avatar to temporary trial team
|
||||||
|
getTeamManager().addAvatarToTrialTeam(avatar);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addTrialAvatarForQuest(int trialAvatarId, int questMainId) {
|
||||||
|
// TODO: Find method for 'setupTrialAvatarTeamForQuest'.
|
||||||
|
getTeamManager().setupTrialAvatars(true);
|
||||||
|
if (!addTrialAvatar(
|
||||||
|
trialAvatarId,
|
||||||
|
GrantReason.GRANT_REASON_BY_QUEST,
|
||||||
|
questMainId)) return false;
|
||||||
|
getTeamManager().trialAvatarTeamPostUpdate();
|
||||||
|
// Packet, mimic official server behaviour, neccessary to stop player from modifying team
|
||||||
|
sendPacket(new PacketAvatarTeamUpdateNotify(this));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTrialAvatarsForActivity(List<Integer> trialAvatarIds) {
|
||||||
|
getTeamManager().setupTrialAvatars(false);
|
||||||
|
trialAvatarIds.forEach(trialAvatarId -> addTrialAvatar(
|
||||||
|
trialAvatarId,
|
||||||
|
GrantReason.GRANT_REASON_BY_TRIAL_AVATAR_ACTIVITY,
|
||||||
|
0));
|
||||||
|
getTeamManager().trialAvatarTeamPostUpdate(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removeTrialAvatarForQuest(int trialAvatarId) {
|
||||||
|
if (!getTeamManager().isUsingTrialTeam()) return false;
|
||||||
|
|
||||||
|
sendPacket(new PacketAvatarDelNotify(List.of(getTeamManager().getTrialAvatarGuid(trialAvatarId))));
|
||||||
|
getTeamManager().removeTrialAvatarTeam(trialAvatarId);
|
||||||
|
sendPacket(new PacketAvatarTeamUpdateNotify());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeTrialAvatarForActivity() {
|
||||||
|
if (!getTeamManager().isUsingTrialTeam()) return;
|
||||||
|
|
||||||
|
sendPacket(new PacketAvatarDelNotify(getTeamManager().getActiveTeam().stream()
|
||||||
|
.map(x -> x.getAvatar().getGuid()).toList()));
|
||||||
|
getTeamManager().removeTrialAvatarTeam();
|
||||||
|
}
|
||||||
|
|
||||||
public void addFlycloak(int flycloakId) {
|
public void addFlycloak(int flycloakId) {
|
||||||
this.getFlyCloakList().add(flycloakId);
|
this.getFlyCloakList().add(flycloakId);
|
||||||
this.sendPacket(new PacketAvatarGainFlycloakNotify(flycloakId));
|
this.sendPacket(new PacketAvatarGainFlycloakNotify(flycloakId));
|
||||||
@ -834,6 +916,11 @@ public class Player {
|
|||||||
this.sendPacket(new PacketAvatarGainCostumeNotify(costumeId));
|
this.sendPacket(new PacketAvatarGainCostumeNotify(costumeId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addPersonalLine(int personalLineId) {
|
||||||
|
this.getPersonalLineList().add(personalLineId);
|
||||||
|
session.getPlayer().getQuestManager().queueEvent(QuestCond.QUEST_COND_PERSONAL_LINE_UNLOCK, personalLineId);
|
||||||
|
}
|
||||||
|
|
||||||
public void addNameCard(int nameCardId) {
|
public void addNameCard(int nameCardId) {
|
||||||
this.getNameCardList().add(nameCardId);
|
this.getNameCardList().add(nameCardId);
|
||||||
this.sendPacket(new PacketUnlockNameCardNotify(nameCardId));
|
this.sendPacket(new PacketUnlockNameCardNotify(nameCardId));
|
||||||
@ -863,6 +950,46 @@ public class Player {
|
|||||||
this.getServer().getChatSystem().sendPrivateMessageFromServer(getUid(), message.toString());
|
this.getServer().getChatSystem().sendPrivateMessageFromServer(getUid(), message.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAvatarsAbilityForScene(Scene scene) {
|
||||||
|
try {
|
||||||
|
var levelEntityConfig = scene.getSceneData().getLevelEntityConfig();
|
||||||
|
var config = GameData.getConfigLevelEntityDataMap().get(levelEntityConfig);
|
||||||
|
if (config == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Integer> avatarIds = scene.getSceneData().getSpecifiedAvatarList();
|
||||||
|
List<EntityAvatar> specifiedAvatarList = getTeamManager().getActiveTeam();
|
||||||
|
|
||||||
|
if (avatarIds != null && avatarIds.size() > 0){
|
||||||
|
// certain scene could limit specifc avatars' entry
|
||||||
|
specifiedAvatarList.clear();
|
||||||
|
for (int id : avatarIds){
|
||||||
|
var avatar = getAvatars().getAvatarById(id);
|
||||||
|
if (avatar == null){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
specifiedAvatarList.add(new EntityAvatar(scene, avatar));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (EntityAvatar entityAvatar : specifiedAvatarList){
|
||||||
|
var avatarData = entityAvatar.getAvatar().getAvatarData();
|
||||||
|
if (avatarData == null){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
avatarData.buildEmbryo();
|
||||||
|
if (config.getAvatarAbilities() == null){
|
||||||
|
continue; // continue and not break because has to rebuild ability for the next avatar if any
|
||||||
|
}
|
||||||
|
for (var abilities : config.getAvatarAbilities()){
|
||||||
|
avatarData.getAbilities().add(Utils.abilityHash(abilities.getAbilityName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e){
|
||||||
|
Grasscutter.getLogger().error("Error applying level entity config for scene {}", scene.getSceneData().getId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Sends a message to another player.
|
* Sends a message to another player.
|
||||||
*
|
*
|
||||||
@ -982,7 +1109,7 @@ public class Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SocialDetail.Builder social = SocialDetail.newBuilder()
|
return SocialDetail.newBuilder()
|
||||||
.setUid(this.getUid())
|
.setUid(this.getUid())
|
||||||
.setProfilePicture(ProfilePicture.newBuilder().setAvatarId(this.getHeadImage()))
|
.setProfilePicture(ProfilePicture.newBuilder().setAvatarId(this.getHeadImage()))
|
||||||
.setNickname(this.getNickname())
|
.setNickname(this.getNickname())
|
||||||
@ -996,7 +1123,6 @@ public class Player {
|
|||||||
.addAllShowNameCardIdList(this.getShowNameCardInfoList())
|
.addAllShowNameCardIdList(this.getShowNameCardInfoList())
|
||||||
.setFinishAchievementNum(this.getFinishedAchievementNum())
|
.setFinishAchievementNum(this.getFinishedAchievementNum())
|
||||||
.setFriendEnterHomeOptionValue(this.getHome() == null ? 0 : this.getHome().getEnterHomeOption());
|
.setFriendEnterHomeOptionValue(this.getHome() == null ? 0 : this.getHome().getEnterHomeOption());
|
||||||
return social;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFinishedAchievementNum() {
|
public int getFinishedAchievementNum() {
|
||||||
@ -1135,6 +1261,8 @@ public class Player {
|
|||||||
|
|
||||||
// Home resources
|
// Home resources
|
||||||
this.getHome().updateHourlyResources(this);
|
this.getHome().updateHourlyResources(this);
|
||||||
|
|
||||||
|
this.getQuestManager().onTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void doDailyReset() {
|
private synchronized void doDailyReset() {
|
||||||
@ -1200,12 +1328,17 @@ public class Player {
|
|||||||
this.achievements = Achievements.getByPlayer(this);
|
this.achievements = Achievements.getByPlayer(this);
|
||||||
this.getAvatars().loadFromDatabase();
|
this.getAvatars().loadFromDatabase();
|
||||||
this.getInventory().loadFromDatabase();
|
this.getInventory().loadFromDatabase();
|
||||||
this.loadBattlePassManager(); // Call before avatar postLoad to avoid null pointer
|
|
||||||
this.getAvatars().postLoad(); // Needs to be called after inventory is handled
|
|
||||||
|
|
||||||
this.getFriendsList().loadFromDatabase();
|
this.getFriendsList().loadFromDatabase();
|
||||||
this.getMailHandler().loadFromDatabase();
|
this.getMailHandler().loadFromDatabase();
|
||||||
this.getQuestManager().loadFromDatabase();
|
this.getQuestManager().loadFromDatabase();
|
||||||
|
|
||||||
|
this.loadBattlePassManager();
|
||||||
|
this.getAvatars().postLoad(); // Needs to be called after inventory is handled
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPlayerBorn() {
|
||||||
|
getQuestManager().onPlayerBorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onLogin() {
|
public void onLogin() {
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package emu.grasscutter.game.props;
|
package emu.grasscutter.game.props;
|
||||||
|
|
||||||
|
import emu.grasscutter.scripts.constants.IntValueEnum;
|
||||||
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 java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public enum EntityType {
|
public enum EntityType implements IntValueEnum {
|
||||||
None(0),
|
None(0),
|
||||||
Avatar(1),
|
Avatar(1),
|
||||||
Monster(2),
|
Monster(2),
|
||||||
|
@ -16,7 +16,6 @@ import emu.grasscutter.database.DatabaseHelper;
|
|||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.props.ActionReason;
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
import emu.grasscutter.game.quest.enums.*;
|
import emu.grasscutter.game.quest.enums.*;
|
||||||
import emu.grasscutter.game.world.World;
|
|
||||||
import emu.grasscutter.net.proto.ChildQuestOuterClass.ChildQuest;
|
import emu.grasscutter.net.proto.ChildQuestOuterClass.ChildQuest;
|
||||||
import emu.grasscutter.net.proto.ParentQuestOuterClass.ParentQuest;
|
import emu.grasscutter.net.proto.ParentQuestOuterClass.ParentQuest;
|
||||||
import emu.grasscutter.server.packet.send.PacketCodexDataUpdateNotify;
|
import emu.grasscutter.server.packet.send.PacketCodexDataUpdateNotify;
|
||||||
@ -41,7 +40,7 @@ public class GameMainQuest {
|
|||||||
@Getter private int[] questVars;
|
@Getter private int[] questVars;
|
||||||
@Getter private long[] timeVar;
|
@Getter private long[] timeVar;
|
||||||
//QuestUpdateQuestVarReq is sent in two stages...
|
//QuestUpdateQuestVarReq is sent in two stages...
|
||||||
@Getter private List<Integer> questVarsUpdate;
|
private List<Integer> questVarsUpdate;
|
||||||
@Getter private ParentQuestState state;
|
@Getter private ParentQuestState state;
|
||||||
@Getter private boolean isFinished;
|
@Getter private boolean isFinished;
|
||||||
@Getter List<QuestGroupSuite> questGroupSuites;
|
@Getter List<QuestGroupSuite> questGroupSuites;
|
||||||
@ -67,6 +66,13 @@ public class GameMainQuest {
|
|||||||
addAllChildQuests();
|
addAllChildQuests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Integer> getQuestVarsUpdate() {
|
||||||
|
if(questVarsUpdate == null){
|
||||||
|
questVarsUpdate = new ArrayList<>();
|
||||||
|
}
|
||||||
|
return questVarsUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
private void addAllChildQuests() {
|
private void addAllChildQuests() {
|
||||||
List<Integer> subQuestIds = Arrays.stream(GameData.getMainQuestDataMap().get(this.parentQuestId).getSubQuests()).map(SubQuestData::getSubId).toList();
|
List<Integer> subQuestIds = Arrays.stream(GameData.getMainQuestDataMap().get(this.parentQuestId).getSubQuests()).map(SubQuestData::getSubId).toList();
|
||||||
for (Integer subQuestId : subQuestIds) {
|
for (Integer subQuestId : subQuestIds) {
|
||||||
@ -166,10 +172,10 @@ 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(getQuestManager()::startMainQuest);
|
// .forEach(getQuestManager()::startMainQuest);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
//TODO
|
//TODO
|
||||||
public void fail() {}
|
public void fail() {}
|
||||||
@ -181,9 +187,9 @@ public class GameMainQuest {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if(rewindPositions.isEmpty()){
|
// if(rewindPositions.isEmpty()){
|
||||||
addRewindPoints();
|
// this.addRewindPoints();
|
||||||
}*/
|
// }
|
||||||
|
|
||||||
List<Position> posAndRot = new ArrayList<>();
|
List<Position> posAndRot = new ArrayList<>();
|
||||||
if(hasRewindPosition(targetQuest.getSubQuestId(), posAndRot)){
|
if(hasRewindPosition(targetQuest.getSubQuestId(), posAndRot)){
|
||||||
@ -198,8 +204,8 @@ public class GameMainQuest {
|
|||||||
if (hasRewindPosition(quest.getSubQuestId(), posAndRot)) {
|
if (hasRewindPosition(quest.getSubQuestId(), posAndRot)) {
|
||||||
return posAndRot;
|
return posAndRot;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +122,7 @@ public class GameQuest {
|
|||||||
getOwner().getQuestManager().checkQuestAlreadyFullfilled(this);
|
getOwner().getQuestManager().checkQuestAlreadyFullfilled(this);
|
||||||
|
|
||||||
Grasscutter.getLogger().debug("Quest {} is started", subQuestId);
|
Grasscutter.getLogger().debug("Quest {} is started", subQuestId);
|
||||||
|
this.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTriggerNameById(int id) {
|
public String getTriggerNameById(int id) {
|
||||||
@ -226,6 +227,9 @@ public class GameQuest {
|
|||||||
if (getQuestData().getSubId() == 35402) {
|
if (getQuestData().getSubId() == 35402) {
|
||||||
getOwner().getInventory().addItem(1021, 1, ActionReason.QuestItem); // amber item id
|
getOwner().getInventory().addItem(1021, 1, ActionReason.QuestItem); // amber item id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.save();
|
||||||
|
|
||||||
Grasscutter.getLogger().debug("Quest {} is finished", subQuestId);
|
Grasscutter.getLogger().debug("Quest {} is finished", subQuestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,10 +7,7 @@ import emu.grasscutter.data.excels.QuestData;
|
|||||||
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.ParentQuestState;
|
import emu.grasscutter.game.quest.enums.*;
|
||||||
import emu.grasscutter.game.quest.enums.QuestCond;
|
|
||||||
import emu.grasscutter.game.quest.enums.QuestContent;
|
|
||||||
import emu.grasscutter.game.quest.enums.QuestState;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify;
|
import emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
import io.netty.util.concurrent.FastThreadLocalThread;
|
import io.netty.util.concurrent.FastThreadLocalThread;
|
||||||
@ -19,6 +16,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.LinkedBlockingDeque;
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
@ -86,13 +84,17 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
this.mainQuests = new Int2ObjectOpenHashMap<>();
|
this.mainQuests = new Int2ObjectOpenHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO store user value set on enable
|
||||||
|
public boolean isQuestingEnabled() {
|
||||||
|
return Grasscutter.getConfig().server.game.gameOptions.questing;
|
||||||
|
}
|
||||||
|
|
||||||
public void onPlayerBorn() {
|
public void onPlayerBorn() {
|
||||||
// TODO scan the quest and start the quest with acceptCond fulfilled
|
// TODO scan the quest and start the quest with acceptCond fulfilled
|
||||||
// The off send 3 request in that order: 1. FinishedParentQuestNotify, 2. QuestListNotify, 3. ServerCondMeetQuestListUpdateNotify
|
// The off send 3 request in that order: 1. FinishedParentQuestNotify, 2. QuestListNotify, 3. ServerCondMeetQuestListUpdateNotify
|
||||||
|
|
||||||
List<GameMainQuest> newQuests = this.addMultMainQuests(newPlayerMainQuests);
|
if(this.isQuestingEnabled()) {
|
||||||
for (GameMainQuest mainQuest : newQuests) {
|
this.enableQuests();
|
||||||
startMainQuest(mainQuest.getParentQuestId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//getPlayer().sendPacket(new PacketFinishedParentQuestUpdateNotify(newQuests));
|
//getPlayer().sendPacket(new PacketFinishedParentQuestUpdateNotify(newQuests));
|
||||||
@ -117,6 +119,8 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
}
|
}
|
||||||
quest.checkProgress();
|
quest.checkProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player.getActivityManager().triggerActivityConditions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onTick(){
|
public void onTick(){
|
||||||
@ -163,7 +167,8 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void enableQuests() {
|
public void enableQuests() {
|
||||||
onPlayerBorn();
|
this.triggerEvent(QuestCond.QUEST_COND_NONE, null, 0);
|
||||||
|
this.triggerEvent(QuestCond.QUEST_COND_PLAYER_LEVEL_EQUAL_GREATER, null, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -256,6 +261,11 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return addQuest(questConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameQuest addQuest(@Nonnull QuestData questConfig) {
|
||||||
|
|
||||||
// Main quest
|
// Main quest
|
||||||
GameMainQuest mainQuest = this.getMainQuestById(questConfig.getMainId());
|
GameMainQuest mainQuest = this.getMainQuestById(questConfig.getMainId());
|
||||||
|
|
||||||
@ -265,7 +275,7 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sub quest
|
// Sub quest
|
||||||
GameQuest quest = mainQuest.getChildQuestById(questId);
|
GameQuest quest = mainQuest.getChildQuestById(questConfig.getSubId());
|
||||||
|
|
||||||
// Forcefully start
|
// Forcefully start
|
||||||
quest.start();
|
quest.start();
|
||||||
@ -286,13 +296,12 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
.map(MainQuestData.SubQuestData::getSubId)
|
.map(MainQuestData.SubQuestData::getSubId)
|
||||||
.ifPresent(this::addQuest);
|
.ifPresent(this::addQuest);
|
||||||
//TODO find a better way then hardcoding to detect needed required quests
|
//TODO find a better way then hardcoding to detect needed required quests
|
||||||
if(mainQuestId == 355){
|
// if (mainQuestId == 355){
|
||||||
startMainQuest(361);
|
// startMainQuest(361);
|
||||||
startMainQuest(418);
|
// startMainQuest(418);
|
||||||
startMainQuest(423);
|
// startMainQuest(423);
|
||||||
startMainQuest(20509);
|
// startMainQuest(20509);
|
||||||
|
// }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public void queueEvent(QuestCond condType, int... params) {
|
public void queueEvent(QuestCond condType, int... params) {
|
||||||
queueEvent(condType, "", params);
|
queueEvent(condType, "", params);
|
||||||
@ -312,13 +321,42 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
|
|
||||||
public void triggerEvent(QuestCond condType, String paramStr, int... params) {
|
public void triggerEvent(QuestCond condType, String paramStr, int... params) {
|
||||||
Grasscutter.getLogger().debug("Trigger Event {}, {}, {}", condType, paramStr, params);
|
Grasscutter.getLogger().debug("Trigger Event {}, {}, {}", condType, paramStr, params);
|
||||||
List<GameMainQuest> checkMainQuests = this.getMainQuests().values().stream()
|
var potentialQuests = GameData.getQuestDataByConditions(condType, params[0], paramStr);
|
||||||
.filter(i -> i.getState() != ParentQuestState.PARENT_QUEST_STATE_FINISHED)
|
if(potentialQuests == null){
|
||||||
.toList();
|
return;
|
||||||
for (GameMainQuest mainquest : checkMainQuests) {
|
|
||||||
mainquest.tryAcceptSubQuests(condType, paramStr, params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var questSystem = getPlayer().getServer().getQuestSystem();
|
||||||
|
var owner = getPlayer();
|
||||||
|
|
||||||
|
potentialQuests.forEach(questData -> {
|
||||||
|
if(this.wasSubQuestStarted(questData)){
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
val acceptCond = questData.getAcceptCond();
|
||||||
|
int[] accept = new int[acceptCond.size()];
|
||||||
|
for (int i = 0; i < acceptCond.size(); i++) {
|
||||||
|
val condition = acceptCond.get(i);
|
||||||
|
boolean result = questSystem.triggerCondition(owner, questData, condition, paramStr, params);
|
||||||
|
accept[i] = result ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean shouldAccept = LogicType.calculate(questData.getAcceptCondComb(), accept);
|
||||||
|
|
||||||
|
if (shouldAccept){
|
||||||
|
GameQuest quest = owner.getQuestManager().addQuest(questData);
|
||||||
|
Grasscutter.getLogger().debug("Added quest {} result {}", questData.getSubId(), quest !=null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean wasSubQuestStarted(QuestData questData) {
|
||||||
|
var quest = getQuestById(questData.getId());
|
||||||
|
if(quest == null) return false;
|
||||||
|
|
||||||
|
return quest.state != QuestState.QUEST_STATE_UNSTARTED;
|
||||||
|
}
|
||||||
|
|
||||||
public void triggerEvent(QuestContent condType, String paramStr, int... params) {
|
public void triggerEvent(QuestContent condType, String paramStr, int... params) {
|
||||||
Grasscutter.getLogger().debug("Trigger Event {}, {}, {}", condType, paramStr, params);
|
Grasscutter.getLogger().debug("Trigger Event {}, {}, {}", condType, paramStr, params);
|
||||||
List<GameMainQuest> checkMainQuests = this.getMainQuests().values().stream()
|
List<GameMainQuest> checkMainQuests = this.getMainQuests().values().stream()
|
||||||
@ -332,6 +370,7 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO maybe trigger them delayed to allow basic communication finish first
|
* TODO maybe trigger them delayed to allow basic communication finish first
|
||||||
|
* 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 checkQuestAlreadyFullfilled(GameQuest quest){
|
||||||
@ -355,6 +394,7 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
queueEvent(condition.getType(), condition.getParam()[0], condition.getParam()[1]);
|
queueEvent(condition.getType(), condition.getParam()[0], condition.getParam()[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case QUEST_CONTENT_PLAYER_LEVEL_UP -> queueEvent(condition.getType(), player.getLevel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 1);
|
}, 1);
|
||||||
|
@ -11,6 +11,9 @@ public class ContentUnlockTransPoint extends BaseContent {
|
|||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
return condition.getParam()[0] == params[0] && condition.getParam()[1] == params[1];
|
var sceneId = condition.getParam()[0];
|
||||||
|
var scenePointId = condition.getParam()[1];
|
||||||
|
var scenePoints = quest.getOwner().getUnlockedScenePoints().get(sceneId);
|
||||||
|
return scenePoints != null && scenePoints.contains(scenePointId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import emu.grasscutter.game.quest.handlers.QuestExecHandler;
|
|||||||
public class ExecAddCurAvatarEnergy extends QuestExecHandler {
|
public class ExecAddCurAvatarEnergy extends QuestExecHandler {
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) {
|
public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) {
|
||||||
Grasscutter.getLogger().info("Energy refilled");
|
Grasscutter.getLogger().debug("Energy refilled");
|
||||||
return quest.getOwner().getEnergyManager().refillActiveEnergy();
|
return quest.getOwner().getEnergyManager().refillActiveEnergy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,12 +319,14 @@ public class World implements Iterable<Player> {
|
|||||||
var newScene = this.getSceneById(teleportProperties.getSceneId());
|
var newScene = this.getSceneById(teleportProperties.getSceneId());
|
||||||
newScene.addPlayer(player);
|
newScene.addPlayer(player);
|
||||||
player.setAvatarsAbilityForScene(newScene);
|
player.setAvatarsAbilityForScene(newScene);
|
||||||
|
|
||||||
// Dungeon
|
// Dungeon
|
||||||
// Dungeon system is handling this already
|
// Dungeon system is handling this already
|
||||||
// if(dungeonData!=null){
|
// if(dungeonData!=null){
|
||||||
// var dungeonManager = new DungeonManager(newScene, dungeonData);
|
// var dungeonManager = new DungeonManager(newScene, dungeonData);
|
||||||
// dungeonManager.startDungeon();
|
// dungeonManager.startDungeon();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
SceneConfig config = newScene.getScriptManager().getConfig();
|
SceneConfig config = newScene.getScriptManager().getConfig();
|
||||||
if (teleportProperties.getTeleportTo() == null && config != null) {
|
if (teleportProperties.getTeleportTo() == null && config != null) {
|
||||||
if (config.born_pos != null) {
|
if (config.born_pos != null) {
|
||||||
|
@ -15,6 +15,8 @@ import emu.grasscutter.scripts.data.SceneGroup;
|
|||||||
import emu.grasscutter.scripts.data.SceneMonster;
|
import emu.grasscutter.scripts.data.SceneMonster;
|
||||||
import emu.grasscutter.server.game.BaseGameSystem;
|
import emu.grasscutter.server.game.BaseGameSystem;
|
||||||
import emu.grasscutter.server.game.GameServer;
|
import emu.grasscutter.server.game.GameServer;
|
||||||
|
import org.luaj.vm2.LuaError;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -73,9 +75,14 @@ public class WorldDataSystem extends BaseGameSystem {
|
|||||||
private SceneGroup getInvestigationGroup(int sceneId, int groupId) {
|
private SceneGroup getInvestigationGroup(int sceneId, int groupId) {
|
||||||
var key = sceneId + "_" + groupId;
|
var key = sceneId + "_" + groupId;
|
||||||
if (!sceneInvestigationGroupMap.containsKey(key)) {
|
if (!sceneInvestigationGroupMap.containsKey(key)) {
|
||||||
|
try {
|
||||||
var group = SceneGroup.of(groupId).load(sceneId);
|
var group = SceneGroup.of(groupId).load(sceneId);
|
||||||
sceneInvestigationGroupMap.putIfAbsent(key, group);
|
sceneInvestigationGroupMap.putIfAbsent(key, group);
|
||||||
return group;
|
return group;
|
||||||
|
} catch (LuaError luaError) {
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.error("failed to get investigationGroup {} in scene{}:", groupId, sceneId, luaError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return sceneInvestigationGroupMap.get(key);
|
return sceneInvestigationGroupMap.get(key);
|
||||||
}
|
}
|
||||||
|
@ -256,7 +256,7 @@ public class SceneScriptManager {
|
|||||||
return suiteIndex;
|
return suiteIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean refreshGroupSuite(int groupId, int suiteId, GameQuest quest) {
|
public boolean refreshGroupSuite(int groupId, int suiteId) {
|
||||||
var targetGroupInstance = getGroupInstanceById(groupId);
|
var targetGroupInstance = getGroupInstanceById(groupId);
|
||||||
if (targetGroupInstance == null) {
|
if (targetGroupInstance == null) {
|
||||||
getGroupById(
|
getGroupById(
|
||||||
@ -276,9 +276,14 @@ public class SceneScriptManager {
|
|||||||
targetGroupInstance,
|
targetGroupInstance,
|
||||||
suiteId,
|
suiteId,
|
||||||
false); // If suiteId is zero, the value of suiteId changes
|
false); // If suiteId is zero, the value of suiteId changes
|
||||||
quest.getOwner().sendPacket(new PacketGroupSuiteNotify(groupId, suiteId));
|
scene.broadcastPacket(new PacketGroupSuiteNotify(groupId, suiteId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean refreshGroupSuite(int groupId, int suiteId, GameQuest quest) {
|
||||||
|
var result = refreshGroupSuite(groupId, suiteId);
|
||||||
if (suiteId != 0 && quest != null) {
|
if (suiteId != 0 && quest != null) {
|
||||||
quest
|
quest
|
||||||
.getMainQuest()
|
.getMainQuest()
|
||||||
@ -287,7 +292,7 @@ public class SceneScriptManager {
|
|||||||
QuestGroupSuite.of().scene(getScene().getId()).group(groupId).suite(suiteId).build());
|
QuestGroupSuite.of().scene(getScene().getId()).group(groupId).suite(suiteId).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean refreshGroupMonster(int groupId) {
|
public boolean refreshGroupMonster(int groupId) {
|
||||||
@ -449,6 +454,8 @@ public class SceneScriptManager {
|
|||||||
|
|
||||||
// Add all entitites here
|
// Add all entitites here
|
||||||
Set<Integer> vision_levels = new HashSet<>();
|
Set<Integer> vision_levels = new HashSet<>();
|
||||||
|
|
||||||
|
if (group.monsters != null) {
|
||||||
group
|
group
|
||||||
.monsters
|
.monsters
|
||||||
.values()
|
.values()
|
||||||
@ -461,13 +468,19 @@ public class SceneScriptManager {
|
|||||||
m.pos);
|
m.pos);
|
||||||
vision_levels.add(m.vision_level);
|
vision_levels.add(m.vision_level);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.error("group.monsters null for group {}", group.id);
|
||||||
|
}
|
||||||
|
if (group.gadgets != null) {
|
||||||
group
|
group
|
||||||
.gadgets
|
.gadgets
|
||||||
.values()
|
.values()
|
||||||
.forEach(
|
.forEach(
|
||||||
g -> {
|
g -> {
|
||||||
int vision_level =
|
int vision_level =
|
||||||
Math.max(getGadgetVisionLevel(g.gadget_id), g.vision_level);
|
Math.max(
|
||||||
|
getGadgetVisionLevel(g.gadget_id), g.vision_level);
|
||||||
addGridPositionToMap(
|
addGridPositionToMap(
|
||||||
groupPositions.get(vision_level),
|
groupPositions.get(vision_level),
|
||||||
group.id,
|
group.id,
|
||||||
@ -475,6 +488,12 @@ public class SceneScriptManager {
|
|||||||
g.pos);
|
g.pos);
|
||||||
vision_levels.add(vision_level);
|
vision_levels.add(vision_level);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.error("group.gadgets null for group {}", group.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (group.npcs != null) {
|
||||||
group
|
group
|
||||||
.npcs
|
.npcs
|
||||||
.values()
|
.values()
|
||||||
@ -485,6 +504,11 @@ public class SceneScriptManager {
|
|||||||
group.id,
|
group.id,
|
||||||
n.vision_level,
|
n.vision_level,
|
||||||
n.pos));
|
n.pos));
|
||||||
|
} else {
|
||||||
|
Grasscutter.getLogger().error("group.npcs null for group {}", group.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (group.regions != null) {
|
||||||
group
|
group
|
||||||
.regions
|
.regions
|
||||||
.values()
|
.values()
|
||||||
@ -492,6 +516,11 @@ public class SceneScriptManager {
|
|||||||
r ->
|
r ->
|
||||||
addGridPositionToMap(
|
addGridPositionToMap(
|
||||||
groupPositions.get(0), group.id, 0, r.pos));
|
groupPositions.get(0), group.id, 0, r.pos));
|
||||||
|
} else {
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.error("group.regions null for group {}", group.id);
|
||||||
|
}
|
||||||
|
|
||||||
if (group.garbages != null && group.garbages.gadgets != null)
|
if (group.garbages != null && group.garbages.gadgets != null)
|
||||||
group.garbages.gadgets.forEach(
|
group.garbages.gadgets.forEach(
|
||||||
g ->
|
g ->
|
||||||
@ -762,20 +791,21 @@ public class SceneScriptManager {
|
|||||||
int eventType = params.type;
|
int eventType = params.type;
|
||||||
Set<SceneTrigger> relevantTriggers = new HashSet<>();
|
Set<SceneTrigger> relevantTriggers = new HashSet<>();
|
||||||
if (eventType == EventType.EVENT_ENTER_REGION || eventType == EventType.EVENT_LEAVE_REGION) {
|
if (eventType == EventType.EVENT_ENTER_REGION || eventType == EventType.EVENT_LEAVE_REGION) {
|
||||||
List<SceneTrigger> relevantTriggersList =
|
relevantTriggers =
|
||||||
this.getTriggersByEvent(eventType).stream()
|
this.getTriggersByEvent(eventType).stream()
|
||||||
.filter(
|
.filter(
|
||||||
p ->
|
t ->
|
||||||
p.getCondition().contains(String.valueOf(params.param1))
|
t.getCondition().contains(String.valueOf(params.param1))
|
||||||
&& (p.getSource().isEmpty()
|
&& (t.getSource().isEmpty()
|
||||||
|| p.getSource().equals(params.getEventSource())))
|
|| t.getSource().equals(params.getEventSource())))
|
||||||
.toList();
|
.collect(Collectors.toSet());
|
||||||
relevantTriggers = new HashSet<>(relevantTriggersList);
|
|
||||||
} else {
|
} else {
|
||||||
relevantTriggers =
|
relevantTriggers =
|
||||||
this.getTriggersByEvent(eventType).stream()
|
this.getTriggersByEvent(eventType).stream()
|
||||||
.filter(
|
.filter(
|
||||||
t -> params.getGroupId() == 0 || t.getCurrentGroup().id == params.getGroupId())
|
t -> params.getGroupId() == 0 || t.getCurrentGroup().id == params.getGroupId())
|
||||||
|
.filter(
|
||||||
|
t -> (t.getSource().isEmpty() || t.getSource().equals(params.getEventSource())))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
for (SceneTrigger trigger : relevantTriggers) {
|
for (SceneTrigger trigger : relevantTriggers) {
|
||||||
@ -1085,6 +1115,7 @@ public class SceneScriptManager {
|
|||||||
source,
|
source,
|
||||||
groupID,
|
groupID,
|
||||||
trigger.getName());
|
trigger.getName());
|
||||||
|
this.cancelGroupTimerEvent(groupID, source);
|
||||||
var taskIdentifier =
|
var taskIdentifier =
|
||||||
Grasscutter.getGameServer()
|
Grasscutter.getGameServer()
|
||||||
.getScheduler()
|
.getScheduler()
|
||||||
@ -1104,13 +1135,15 @@ public class SceneScriptManager {
|
|||||||
public int cancelGroupTimerEvent(int groupID, String source) {
|
public int cancelGroupTimerEvent(int groupID, String source) {
|
||||||
// TODO test
|
// TODO test
|
||||||
var groupTimers = activeGroupTimers.get(groupID);
|
var groupTimers = activeGroupTimers.get(groupID);
|
||||||
if (groupTimers != null && !groupTimers.isEmpty())
|
if (groupTimers != null && !groupTimers.isEmpty()) {
|
||||||
for (var timer : groupTimers) {
|
for (var timer : new HashSet<>(groupTimers)) {
|
||||||
if (timer.component1().equals(source)) {
|
if (timer.component1().equals(source)) {
|
||||||
Grasscutter.getGameServer().getScheduler().cancelTask(timer.component2());
|
Grasscutter.getGameServer().getScheduler().cancelTask(timer.component2());
|
||||||
|
groupTimers.remove(timer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Grasscutter.getLogger()
|
Grasscutter.getLogger()
|
||||||
.warn("trying to cancel a timer that's not active {} {}", groupID, source);
|
.warn("trying to cancel a timer that's not active {} {}", groupID, source);
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package emu.grasscutter.scripts;
|
package emu.grasscutter.scripts;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.enums.ChallengeEventMarkType;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.enums.FatherChallengeProperty;
|
||||||
|
import emu.grasscutter.game.props.ElementType;
|
||||||
import emu.grasscutter.game.props.EntityType;
|
import emu.grasscutter.game.props.EntityType;
|
||||||
import emu.grasscutter.game.quest.enums.QuestState;
|
import emu.grasscutter.game.quest.enums.QuestState;
|
||||||
import emu.grasscutter.scripts.constants.EventType;
|
import emu.grasscutter.scripts.constants.*;
|
||||||
import emu.grasscutter.scripts.constants.ScriptGadgetState;
|
|
||||||
import emu.grasscutter.scripts.constants.ScriptRegionShape;
|
|
||||||
import emu.grasscutter.scripts.data.SceneMeta;
|
import emu.grasscutter.scripts.data.SceneMeta;
|
||||||
import emu.grasscutter.scripts.serializer.LuaSerializer;
|
import emu.grasscutter.scripts.serializer.LuaSerializer;
|
||||||
import emu.grasscutter.scripts.serializer.Serializer;
|
import emu.grasscutter.scripts.serializer.Serializer;
|
||||||
@ -65,15 +66,14 @@ public class ScriptLoader {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
LuaTable table = new LuaTable();
|
addEnumByIntValue(ctx, EntityType.values(), "EntityType");
|
||||||
Arrays.stream(EntityType.values())
|
addEnumByIntValue(ctx, QuestState.values(), "QuestState");
|
||||||
.forEach(e -> table.set(e.name().toUpperCase(), e.getValue()));
|
addEnumByIntValue(ctx, ElementType.values(), "ElementType");
|
||||||
ctx.globals.set("EntityType", table);
|
|
||||||
|
|
||||||
LuaTable table1 = new LuaTable();
|
addEnumByOrdinal(ctx, GroupKillPolicy.values(), "GroupKillPolicy");
|
||||||
Arrays.stream(QuestState.values())
|
addEnumByOrdinal(ctx, SealBattleType.values(), "SealBattleType");
|
||||||
.forEach(e -> table1.set(e.name().toUpperCase(), e.getValue()));
|
addEnumByOrdinal(ctx, FatherChallengeProperty.values(), "FatherChallengeProperty");
|
||||||
ctx.globals.set("QuestState", table1);
|
addEnumByOrdinal(ctx, ChallengeEventMarkType.values(), "ChallengeEventMarkType");
|
||||||
|
|
||||||
ctx.globals.set(
|
ctx.globals.set(
|
||||||
"EventType",
|
"EventType",
|
||||||
@ -88,6 +88,30 @@ public class ScriptLoader {
|
|||||||
ctx.globals.set("ScriptLib", scriptLibLua);
|
ctx.globals.set("ScriptLib", scriptLibLua);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static <T extends Enum<T>> void addEnumByOrdinal(
|
||||||
|
LuajContext ctx, T[] enumArray, String name) {
|
||||||
|
LuaTable table = new LuaTable();
|
||||||
|
Arrays.stream(enumArray)
|
||||||
|
.forEach(
|
||||||
|
e -> {
|
||||||
|
table.set(e.name(), e.ordinal());
|
||||||
|
table.set(e.name().toUpperCase(), e.ordinal());
|
||||||
|
});
|
||||||
|
ctx.globals.set(name, table);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T extends Enum<T> & IntValueEnum> void addEnumByIntValue(
|
||||||
|
LuajContext ctx, T[] enumArray, String name) {
|
||||||
|
LuaTable table = new LuaTable();
|
||||||
|
Arrays.stream(enumArray)
|
||||||
|
.forEach(
|
||||||
|
e -> {
|
||||||
|
table.set(e.name(), e.getValue());
|
||||||
|
table.set(e.name().toUpperCase(), e.getValue());
|
||||||
|
});
|
||||||
|
ctx.globals.set(name, table);
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> Optional<T> tryGet(SoftReference<T> softReference) {
|
public static <T> Optional<T> tryGet(SoftReference<T> softReference) {
|
||||||
try {
|
try {
|
||||||
return Optional.ofNullable(softReference.get());
|
return Optional.ofNullable(softReference.get());
|
||||||
@ -103,7 +127,7 @@ public class ScriptLoader {
|
|||||||
return sc.get();
|
return sc.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Grasscutter.getLogger().debug("Loading script " + path);
|
// Grasscutter.getLogger().debug("Loading script " + path);
|
||||||
|
|
||||||
File file = new File(path);
|
File file = new File(path);
|
||||||
|
|
||||||
@ -125,7 +149,7 @@ public class ScriptLoader {
|
|||||||
return sc.get();
|
return sc.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Grasscutter.getLogger().debug("Loading script " + path);
|
// Grasscutter.getLogger().debug("Loading script " + path);
|
||||||
final Path scriptPath = FileUtils.getScriptPath(path);
|
final Path scriptPath = FileUtils.getScriptPath(path);
|
||||||
if (!Files.exists(scriptPath)) return null;
|
if (!Files.exists(scriptPath)) return null;
|
||||||
|
|
||||||
|
@ -37,10 +37,11 @@ public class SceneBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(Position pos) {
|
public boolean contains(Position pos) {
|
||||||
return pos.getX() <= this.max.getX()
|
int range = Grasscutter.getConfig().server.game.loadEntitiesForPlayerRange;
|
||||||
&& pos.getX() >= this.min.getX()
|
return pos.getX() <= (this.max.getX() + range)
|
||||||
&& pos.getZ() <= this.max.getZ()
|
&& pos.getX() >= (this.min.getX() - range)
|
||||||
&& pos.getZ() >= this.min.getZ();
|
&& pos.getZ() <= (this.max.getZ() + range)
|
||||||
|
&& pos.getZ() >= (this.min.getZ() - range);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SceneBlock load(int sceneId, Bindings bindings) {
|
public SceneBlock load(int sceneId, Bindings bindings) {
|
||||||
|
@ -4,12 +4,17 @@ import com.esotericsoftware.reflectasm.ConstructorAccess;
|
|||||||
import com.esotericsoftware.reflectasm.MethodAccess;
|
import com.esotericsoftware.reflectasm.MethodAccess;
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.scripts.ScriptUtils;
|
import emu.grasscutter.scripts.ScriptUtils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.FieldDefaults;
|
import lombok.experimental.FieldDefaults;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.luaj.vm2.LuaTable;
|
import org.luaj.vm2.LuaTable;
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
|
|
||||||
@ -28,7 +33,7 @@ public class LuaSerializer implements Serializer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T toObject(Class<T> type, Object obj) {
|
public <T> T toObject(Class<T> type, Object obj) {
|
||||||
return serialize(type, (LuaTable) obj);
|
return serialize(type, null, (LuaTable) obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -52,7 +57,7 @@ public class LuaSerializer implements Serializer {
|
|||||||
T object = null;
|
T object = null;
|
||||||
|
|
||||||
if (keyValue.istable()) {
|
if (keyValue.istable()) {
|
||||||
object = serialize(type, keyValue.checktable());
|
object = serialize(type, null, keyValue.checktable());
|
||||||
} else if (keyValue.isint()) {
|
} else if (keyValue.isint()) {
|
||||||
object = (T) (Integer) keyValue.toint();
|
object = (T) (Integer) keyValue.toint();
|
||||||
} else if (keyValue.isnumber()) {
|
} else if (keyValue.isnumber()) {
|
||||||
@ -95,7 +100,7 @@ public class LuaSerializer implements Serializer {
|
|||||||
T object = null;
|
T object = null;
|
||||||
|
|
||||||
if (keyValue.istable()) {
|
if (keyValue.istable()) {
|
||||||
object = serialize(type, keyValue.checktable());
|
object = serialize(type, null, keyValue.checktable());
|
||||||
} else if (keyValue.isint()) {
|
} else if (keyValue.isint()) {
|
||||||
object = (T) (Integer) keyValue.toint();
|
object = (T) (Integer) keyValue.toint();
|
||||||
} else if (keyValue.isnumber()) {
|
} else if (keyValue.isnumber()) {
|
||||||
@ -122,12 +127,24 @@ public class LuaSerializer implements Serializer {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T serialize(Class<T> type, LuaTable table) {
|
private Class<?> getListType(Class<?> type, @Nullable Field field) {
|
||||||
|
if (field == null) {
|
||||||
|
return type.getTypeParameters()[0].getClass();
|
||||||
|
}
|
||||||
|
Type fieldType = field.getGenericType();
|
||||||
|
if (fieldType instanceof ParameterizedType) {
|
||||||
|
return (Class<?>) ((ParameterizedType) fieldType).getActualTypeArguments()[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T serialize(Class<T> type, @Nullable Field field, LuaTable table) {
|
||||||
T object = null;
|
T object = null;
|
||||||
|
|
||||||
if (type == List.class) {
|
if (type == List.class) {
|
||||||
try {
|
try {
|
||||||
Class<T> listType = (Class<T>) type.getTypeParameters()[0].getClass();
|
Class<?> listType = getListType(type, field);
|
||||||
return (T) serializeList(listType, table);
|
return (T) serializeList(listType, table);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -160,7 +177,9 @@ public class LuaSerializer implements Serializer {
|
|||||||
|
|
||||||
if (keyValue.istable()) {
|
if (keyValue.istable()) {
|
||||||
methodAccess.invoke(
|
methodAccess.invoke(
|
||||||
object, fieldMeta.index, serialize(fieldMeta.getType(), keyValue.checktable()));
|
object,
|
||||||
|
fieldMeta.index,
|
||||||
|
serialize(fieldMeta.getType(), fieldMeta.getField(), keyValue.checktable()));
|
||||||
} else if (fieldMeta.getType().equals(float.class)) {
|
} else if (fieldMeta.getType().equals(float.class)) {
|
||||||
methodAccess.invoke(object, fieldMeta.index, keyValue.tofloat());
|
methodAccess.invoke(object, fieldMeta.index, keyValue.tofloat());
|
||||||
} else if (fieldMeta.getType().equals(int.class)) {
|
} else if (fieldMeta.getType().equals(int.class)) {
|
||||||
@ -206,7 +225,8 @@ public class LuaSerializer implements Serializer {
|
|||||||
var setter = getSetterName(field.getName());
|
var setter = getSetterName(field.getName());
|
||||||
var index = methodAccess.getIndex(setter);
|
var index = methodAccess.getIndex(setter);
|
||||||
fieldMetaMap.put(
|
fieldMetaMap.put(
|
||||||
field.getName(), new FieldMeta(field.getName(), setter, index, field.getType()));
|
field.getName(),
|
||||||
|
new FieldMeta(field.getName(), setter, index, field.getType(), field));
|
||||||
});
|
});
|
||||||
|
|
||||||
Arrays.stream(type.getFields())
|
Arrays.stream(type.getFields())
|
||||||
@ -217,7 +237,8 @@ public class LuaSerializer implements Serializer {
|
|||||||
var setter = getSetterName(field.getName());
|
var setter = getSetterName(field.getName());
|
||||||
var index = methodAccess.getIndex(setter);
|
var index = methodAccess.getIndex(setter);
|
||||||
fieldMetaMap.put(
|
fieldMetaMap.put(
|
||||||
field.getName(), new FieldMeta(field.getName(), setter, index, field.getType()));
|
field.getName(),
|
||||||
|
new FieldMeta(field.getName(), setter, index, field.getType(), field));
|
||||||
});
|
});
|
||||||
|
|
||||||
fieldMetaCache.put(type, fieldMetaMap);
|
fieldMetaCache.put(type, fieldMetaMap);
|
||||||
@ -242,5 +263,6 @@ public class LuaSerializer implements Serializer {
|
|||||||
String setter;
|
String setter;
|
||||||
int index;
|
int index;
|
||||||
Class<?> type;
|
Class<?> type;
|
||||||
|
@Nullable Field field;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ public final class GameServer extends KcpServer {
|
|||||||
|
|
||||||
public void deregisterWorld(World world) {
|
public void deregisterWorld(World world) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
world.save(); //Save the player's world
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
@ -275,5 +275,7 @@ public final class GameServer extends KcpServer {
|
|||||||
for (Player player : list) {
|
for (Player player : list) {
|
||||||
player.getSession().close();
|
player.getSession().close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getWorlds().forEach(World::save);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package emu.grasscutter.server.packet.recv;
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
import emu.grasscutter.game.quest.GameMainQuest;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.net.packet.Opcodes;
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
import emu.grasscutter.net.packet.PacketHandler;
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.QuestUpdateQuestVarReqOuterClass;
|
import emu.grasscutter.net.proto.QuestUpdateQuestVarReqOuterClass.QuestUpdateQuestVarReq;
|
||||||
import emu.grasscutter.net.proto.QuestVarOpOuterClass;
|
import emu.grasscutter.net.proto.QuestVarOpOuterClass.QuestVarOp;
|
||||||
|
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||||
import emu.grasscutter.server.game.GameSession;
|
import emu.grasscutter.server.game.GameSession;
|
||||||
import emu.grasscutter.server.packet.send.PacketQuestUpdateQuestVarRsp;
|
import emu.grasscutter.server.packet.send.PacketQuestUpdateQuestVarRsp;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -17,16 +18,31 @@ public class HandlerQuestUpdateQuestVarReq extends PacketHandler {
|
|||||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
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
|
// Client sends packets. One with the value, and one with the index and the new value to
|
||||||
// set/inc/dec
|
// set/inc/dec
|
||||||
var req = QuestUpdateQuestVarReqOuterClass.QuestUpdateQuestVarReq.parseFrom(payload);
|
var req = QuestUpdateQuestVarReq.parseFrom(payload);
|
||||||
GameMainQuest mainQuest =
|
var questManager = session.getPlayer().getQuestManager();
|
||||||
session.getPlayer().getQuestManager().getMainQuestById(req.getQuestId() / 100);
|
var subQuest = questManager.getQuestById(req.getQuestId());
|
||||||
List<QuestVarOpOuterClass.QuestVarOp> questVars = req.getQuestVarOpListList();
|
var mainQuest = questManager.getMainQuestById(req.getParentQuestId());
|
||||||
if (mainQuest.getQuestVarsUpdate().size() == 0) {
|
if (mainQuest == null && subQuest != null) {
|
||||||
for (QuestVarOpOuterClass.QuestVarOp questVar : questVars) {
|
mainQuest = subQuest.getMainQuest();
|
||||||
mainQuest.getQuestVarsUpdate().add(questVar.getValue());
|
}
|
||||||
|
|
||||||
|
if (mainQuest == null) {
|
||||||
|
session.send(new PacketQuestUpdateQuestVarRsp(req, Retcode.RET_QUEST_NOT_EXIST));
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.debug(
|
||||||
|
"trying to update QuestVar for non existing quest s{} m{}",
|
||||||
|
req.getQuestId(),
|
||||||
|
req.getParentQuestId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<QuestVarOp> questVars = req.getQuestVarOpListList();
|
||||||
|
var questVarUpdate = mainQuest.getQuestVarsUpdate();
|
||||||
|
if (questVarUpdate.size() == 0) {
|
||||||
|
for (var questVar : questVars) {
|
||||||
|
questVarUpdate.add(questVar.getValue());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (QuestVarOpOuterClass.QuestVarOp questVar : questVars) {
|
for (QuestVarOp questVar : questVars) {
|
||||||
if (questVar.getIsAdd()) {
|
if (questVar.getIsAdd()) {
|
||||||
if (questVar.getValue() >= 0) {
|
if (questVar.getValue() >= 0) {
|
||||||
mainQuest.incQuestVar(questVar.getIndex(), questVar.getValue());
|
mainQuest.incQuestVar(questVar.getIndex(), questVar.getValue());
|
||||||
@ -34,12 +50,12 @@ public class HandlerQuestUpdateQuestVarReq extends PacketHandler {
|
|||||||
mainQuest.decQuestVar(questVar.getIndex(), questVar.getValue());
|
mainQuest.decQuestVar(questVar.getIndex(), questVar.getValue());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mainQuest.setQuestVar(questVar.getIndex(), mainQuest.getQuestVarsUpdate().get(0));
|
mainQuest.setQuestVar(questVar.getIndex(), questVarUpdate.get(0));
|
||||||
}
|
}
|
||||||
// remove the first element from the update list
|
// remove the first element from the update list
|
||||||
mainQuest.getQuestVarsUpdate().remove(0);
|
questVarUpdate.remove(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
session.send(new PacketQuestUpdateQuestVarRsp(req.getQuestId()));
|
session.send(new PacketQuestUpdateQuestVarRsp(req));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,22 @@ package emu.grasscutter.server.packet.send;
|
|||||||
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.PlayerEnterDungeonRspOuterClass.PlayerEnterDungeonRsp;
|
import emu.grasscutter.net.proto.PlayerEnterDungeonRspOuterClass.PlayerEnterDungeonRsp;
|
||||||
|
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||||
|
|
||||||
public class PacketPlayerEnterDungeonRsp extends BasePacket {
|
public class PacketPlayerEnterDungeonRsp extends BasePacket {
|
||||||
|
|
||||||
public PacketPlayerEnterDungeonRsp(int pointId, int dungeonId) {
|
public PacketPlayerEnterDungeonRsp(int pointId, int dungeonId, boolean success) {
|
||||||
super(PacketOpcodes.PlayerEnterDungeonRsp);
|
super(PacketOpcodes.PlayerEnterDungeonRsp);
|
||||||
|
|
||||||
PlayerEnterDungeonRsp proto =
|
PlayerEnterDungeonRsp proto =
|
||||||
PlayerEnterDungeonRsp.newBuilder().setPointId(pointId).setDungeonId(dungeonId).build();
|
PlayerEnterDungeonRsp.newBuilder()
|
||||||
|
.setPointId(pointId)
|
||||||
|
.setDungeonId(dungeonId)
|
||||||
|
.setRetcode(
|
||||||
|
success
|
||||||
|
? Retcode.RET_SUCC_VALUE
|
||||||
|
: Retcode.RET_FAIL_VALUE)
|
||||||
|
.build();
|
||||||
|
|
||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ import emu.grasscutter.net.packet.PacketOpcodes;
|
|||||||
import emu.grasscutter.net.proto.PlayerHomeCompInfoNotifyOuterClass;
|
import emu.grasscutter.net.proto.PlayerHomeCompInfoNotifyOuterClass;
|
||||||
import emu.grasscutter.net.proto.PlayerHomeCompInfoOuterClass;
|
import emu.grasscutter.net.proto.PlayerHomeCompInfoOuterClass;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class PacketPlayerHomeCompInfoNotify extends BasePacket {
|
public class PacketPlayerHomeCompInfoNotify extends BasePacket {
|
||||||
|
|
||||||
public PacketPlayerHomeCompInfoNotify(Player player) {
|
public PacketPlayerHomeCompInfoNotify(Player player) {
|
||||||
@ -21,8 +23,7 @@ public class PacketPlayerHomeCompInfoNotify extends BasePacket {
|
|||||||
.setCompInfo(
|
.setCompInfo(
|
||||||
PlayerHomeCompInfoOuterClass.PlayerHomeCompInfo.newBuilder()
|
PlayerHomeCompInfoOuterClass.PlayerHomeCompInfo.newBuilder()
|
||||||
.addAllUnlockedModuleIdList(player.getRealmList())
|
.addAllUnlockedModuleIdList(player.getRealmList())
|
||||||
.addAllSeenModuleIdList(player.getSeenRealmList())
|
.addAllLevelupRewardGotLevelList(List.of(1)) // Hardcoded
|
||||||
.addAllLevelupRewardGotLevelList(player.getHomeRewardedLevels())
|
|
||||||
.setFriendEnterHomeOptionValue(player.getHome().getEnterHomeOption())
|
.setFriendEnterHomeOptionValue(player.getHome().getEnterHomeOption())
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
|
@ -2,12 +2,15 @@ package emu.grasscutter.server.packet.send;
|
|||||||
|
|
||||||
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.PlayerSetPauseRspOuterClass.PlayerSetPauseRsp;
|
||||||
|
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||||
|
|
||||||
public class PacketPlayerSetPauseRsp extends BasePacket {
|
public class PacketPlayerSetPauseRsp extends BasePacket {
|
||||||
|
|
||||||
public PacketPlayerSetPauseRsp(int clientSequence) {
|
public PacketPlayerSetPauseRsp() {
|
||||||
super(PacketOpcodes.PlayerSetPauseRsp);
|
super(PacketOpcodes.PlayerSetPauseRsp);
|
||||||
|
|
||||||
this.buildHeader(clientSequence);
|
this.setData(PlayerSetPauseRsp.newBuilder()
|
||||||
|
.setRetcode(Retcode.RET_SUCC_VALUE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,24 @@ package emu.grasscutter.server.packet.send;
|
|||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
import emu.grasscutter.net.packet.Opcodes;
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
|
import emu.grasscutter.net.proto.QuestUpdateQuestVarReqOuterClass.QuestUpdateQuestVarReq;
|
||||||
import emu.grasscutter.net.proto.QuestUpdateQuestVarRspOuterClass;
|
import emu.grasscutter.net.proto.QuestUpdateQuestVarRspOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||||
|
|
||||||
@Opcodes(PacketOpcodes.QuestUpdateQuestVarReq)
|
@Opcodes(PacketOpcodes.QuestUpdateQuestVarReq)
|
||||||
public class PacketQuestUpdateQuestVarRsp extends BasePacket {
|
public class PacketQuestUpdateQuestVarRsp extends BasePacket {
|
||||||
|
|
||||||
public PacketQuestUpdateQuestVarRsp(int questId) {
|
public PacketQuestUpdateQuestVarRsp(QuestUpdateQuestVarReq req) {
|
||||||
|
this(req, Retcode.RET_SUCC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketQuestUpdateQuestVarRsp(QuestUpdateQuestVarReq req, Retcode retcode) {
|
||||||
super(PacketOpcodes.QuestUpdateQuestVarRsp);
|
super(PacketOpcodes.QuestUpdateQuestVarRsp);
|
||||||
var rsp =
|
var rsp =
|
||||||
QuestUpdateQuestVarRspOuterClass.QuestUpdateQuestVarRsp.newBuilder()
|
QuestUpdateQuestVarRspOuterClass.QuestUpdateQuestVarRsp.newBuilder()
|
||||||
.setQuestId(questId)
|
.setQuestId(req.getQuestId())
|
||||||
|
.setParentQuestId(req.getParentQuestId())
|
||||||
|
.setRetcode(retcode.getNumber())
|
||||||
.build();
|
.build();
|
||||||
this.setData(rsp);
|
this.setData(rsp);
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,7 @@ public class PacketScenePointUnlockNotify extends BasePacket {
|
|||||||
ScenePointUnlockNotify.Builder p =
|
ScenePointUnlockNotify.Builder p =
|
||||||
ScenePointUnlockNotify.newBuilder()
|
ScenePointUnlockNotify.newBuilder()
|
||||||
.setSceneId(sceneId)
|
.setSceneId(sceneId)
|
||||||
.addPointList(pointId)
|
.addPointList(pointId);
|
||||||
.addUnhidePointList(pointId);
|
|
||||||
|
|
||||||
this.setData(p);
|
this.setData(p);
|
||||||
}
|
}
|
||||||
@ -23,8 +22,7 @@ public class PacketScenePointUnlockNotify extends BasePacket {
|
|||||||
ScenePointUnlockNotify.Builder p =
|
ScenePointUnlockNotify.Builder p =
|
||||||
ScenePointUnlockNotify.newBuilder()
|
ScenePointUnlockNotify.newBuilder()
|
||||||
.setSceneId(sceneId)
|
.setSceneId(sceneId)
|
||||||
.addAllPointList(pointIds)
|
.addAllPointList(pointIds);
|
||||||
.addAllUnhidePointList(pointIds);
|
|
||||||
|
|
||||||
this.setData(p);
|
this.setData(p);
|
||||||
}
|
}
|
||||||
|
@ -9,16 +9,7 @@ import emu.grasscutter.net.proto.SceneTimeNotifyOuterClass.SceneTimeNotify;
|
|||||||
public class PacketSceneTimeNotify extends BasePacket {
|
public class PacketSceneTimeNotify extends BasePacket {
|
||||||
|
|
||||||
public PacketSceneTimeNotify(Player player) {
|
public PacketSceneTimeNotify(Player player) {
|
||||||
super(PacketOpcodes.SceneTimeNotify);
|
this(player.getScene());
|
||||||
|
|
||||||
var proto =
|
|
||||||
SceneTimeNotify.newBuilder()
|
|
||||||
.setIsPaused(player.isPaused())
|
|
||||||
.setSceneId(player.getSceneId())
|
|
||||||
.setSceneTime(player.getScene().getSceneTime())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
this.setData(proto);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PacketSceneTimeNotify(Scene scene) {
|
public PacketSceneTimeNotify(Scene scene) {
|
||||||
|
@ -2,6 +2,7 @@ package emu.grasscutter.server.packet.send;
|
|||||||
|
|
||||||
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.RetcodeOuterClass.Retcode;
|
||||||
import emu.grasscutter.net.proto.UnlockPersonalLineRspOuterClass;
|
import emu.grasscutter.net.proto.UnlockPersonalLineRspOuterClass;
|
||||||
|
|
||||||
public class PacketUnlockPersonalLineRsp extends BasePacket {
|
public class PacketUnlockPersonalLineRsp extends BasePacket {
|
||||||
@ -15,4 +16,14 @@ public class PacketUnlockPersonalLineRsp extends BasePacket {
|
|||||||
|
|
||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PacketUnlockPersonalLineRsp(int id, Retcode retCode) {
|
||||||
|
super(PacketOpcodes.UnlockPersonalLineRsp);
|
||||||
|
|
||||||
|
var proto = UnlockPersonalLineRspOuterClass.UnlockPersonalLineRsp.newBuilder();
|
||||||
|
|
||||||
|
proto.setPersonalLineId(id).setRetcode(retCode.getNumber());
|
||||||
|
|
||||||
|
this.setData(proto);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package emu.grasscutter.server.packet.send;
|
|||||||
import emu.grasscutter.game.entity.EntityVehicle;
|
import emu.grasscutter.game.entity.EntityVehicle;
|
||||||
import emu.grasscutter.game.entity.GameEntity;
|
import emu.grasscutter.game.entity.GameEntity;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.game.quest.enums.QuestContent;
|
||||||
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.VehicleInteractRspOuterClass.VehicleInteractRsp;
|
import emu.grasscutter.net.proto.VehicleInteractRspOuterClass.VehicleInteractRsp;
|
||||||
@ -32,6 +33,11 @@ public class PacketVehicleInteractRsp extends BasePacket {
|
|||||||
switch (interactType) {
|
switch (interactType) {
|
||||||
case VEHICLE_INTERACT_TYPE_IN -> {
|
case VEHICLE_INTERACT_TYPE_IN -> {
|
||||||
((EntityVehicle) vehicle).getVehicleMembers().add(vehicleMember);
|
((EntityVehicle) vehicle).getVehicleMembers().add(vehicleMember);
|
||||||
|
player
|
||||||
|
.getQuestManager()
|
||||||
|
.queueEvent(
|
||||||
|
QuestContent.QUEST_CONTENT_ENTER_VEHICLE,
|
||||||
|
((EntityVehicle) vehicle).getGadgetId());
|
||||||
}
|
}
|
||||||
case VEHICLE_INTERACT_TYPE_OUT -> {
|
case VEHICLE_INTERACT_TYPE_OUT -> {
|
||||||
((EntityVehicle) vehicle).getVehicleMembers().remove(vehicleMember);
|
((EntityVehicle) vehicle).getVehicleMembers().remove(vehicleMember);
|
||||||
|
@ -35,10 +35,12 @@ public final class ServerTask implements Runnable {
|
|||||||
* @return True if the task should run, false otherwise.
|
* @return True if the task should run, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean shouldRun() {
|
public boolean shouldRun() {
|
||||||
|
// Increase tick count.
|
||||||
|
var ticks = this.ticks++;
|
||||||
if (this.delay != -1 && this.considerDelay) {
|
if (this.delay != -1 && this.considerDelay) {
|
||||||
this.considerDelay = false;
|
this.considerDelay = false;
|
||||||
return this.ticks == this.delay;
|
return ticks == this.delay;
|
||||||
} else if (this.period != -1) return this.ticks % this.period == 0;
|
} else if (this.period != -1) return ticks % this.period == 0;
|
||||||
else return true;
|
else return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,15 +50,17 @@ public final class ServerTask implements Runnable {
|
|||||||
* @return True if the task should be canceled, false otherwise.
|
* @return True if the task should be canceled, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean shouldCancel() {
|
public boolean shouldCancel() {
|
||||||
return this.period == -1;
|
return this.period == -1 && ticks >= delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Runs the task. */
|
/** Runs the task. */
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Run the runnable.
|
// Run the runnable.
|
||||||
|
try {
|
||||||
this.runnable.run();
|
this.runnable.run();
|
||||||
// Increase tick count.
|
} catch (Exception ex) {
|
||||||
this.ticks++;
|
Grasscutter.getLogger().error("Exception during task: ", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package emu.grasscutter.task;
|
package emu.grasscutter.task;
|
||||||
|
|
||||||
import org.quartz.Job;
|
import org.quartz.*;
|
||||||
import org.quartz.JobExecutionException;
|
|
||||||
import org.quartz.PersistJobDataAfterExecution;
|
|
||||||
|
|
||||||
@PersistJobDataAfterExecution
|
@PersistJobDataAfterExecution
|
||||||
public abstract class TaskHandler implements Job {
|
public abstract class TaskHandler implements Job {
|
||||||
|
@ -137,7 +137,8 @@ public final class Tools {
|
|||||||
itemDataMap.forEach(
|
itemDataMap.forEach(
|
||||||
(id, data) -> {
|
(id, data) -> {
|
||||||
val name = getTextMapKey(data.getNameTextMapHash());
|
val name = getTextMapKey(data.getNameTextMapHash());
|
||||||
if (Objects.requireNonNull(data.getMaterialType()) == MaterialType.MATERIAL_BGM) {
|
switch (data.getMaterialType()) {
|
||||||
|
case MATERIAL_BGM:
|
||||||
val bgmName =
|
val bgmName =
|
||||||
Optional.ofNullable(data.getItemUse())
|
Optional.ofNullable(data.getItemUse())
|
||||||
.map(u -> u.get(0))
|
.map(u -> u.get(0))
|
||||||
@ -151,8 +152,10 @@ public final class Tools {
|
|||||||
h.newTranslatedLine(itemPre.formatted(id) + "{0} - {1}", name, bgmName.get());
|
h.newTranslatedLine(itemPre.formatted(id) + "{0} - {1}", name, bgmName.get());
|
||||||
return;
|
return;
|
||||||
} // Fall-through
|
} // Fall-through
|
||||||
}
|
default:
|
||||||
h.newTranslatedLine(itemPre.formatted(id) + "{0}", name);
|
h.newTranslatedLine(itemPre.formatted(id) + "{0}", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// Monsters
|
// Monsters
|
||||||
h.newSection("Monsters");
|
h.newSection("Monsters");
|
||||||
|
Loading…
Reference in New Issue
Block a user