mirror of
https://github.com/Anime-Game-Servers/Grasscutter-Quests.git
synced 2024-11-27 06:20:37 +00:00
Refactored Trial Avatar relevant code (#68)
* Moved trial avatar to a separate class for easier management * Mainly refactored team manager. Moved the response packets to their handler so that the functions in team manager is more reusable. * Refactored adding and removing TrialAvatar for dungeons/activity. Have the TrialAvatars added through their corresponding handler if not specifically called by enter dungeon request. * Added interfaces for both original excels and custom data, so that it can perform polymorphic calls. * Added implementation for Element trial dungeon. It is impossible to complete though. Since challenges are practically broken * Moved around some stuff so that the addition and removal of the trial avatars for quest and dungeons work well.
This commit is contained in:
parent
151a325506
commit
72874edddc
@ -28,26 +28,26 @@ public final class TeamCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
switch (args.get(0)) {
|
||||
case "add":
|
||||
case "add" -> {
|
||||
if (!addCommand(sender, targetPlayer, args)) return;
|
||||
break;
|
||||
|
||||
case "remove":
|
||||
}
|
||||
case "remove" -> {
|
||||
if (!removeCommand(sender, targetPlayer, args)) return;
|
||||
break;
|
||||
|
||||
case "set":
|
||||
}
|
||||
case "set" -> {
|
||||
if (!setCommand(sender, targetPlayer, args)) return;
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
default -> {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_usage");
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
targetPlayer.getTeamManager().updateTeamEntities(
|
||||
new PacketChangeMpTeamAvatarRsp(targetPlayer, targetPlayer.getTeamManager().getCurrentTeamInfo()));
|
||||
targetPlayer.getTeamManager().updateTeamEntities(true);
|
||||
// TODO might not be wise since no request is sent
|
||||
targetPlayer.sendPacket(new PacketChangeMpTeamAvatarRsp(targetPlayer, targetPlayer.getTeamManager().getCurrentTeamInfo()));
|
||||
|
||||
}
|
||||
|
||||
private boolean addCommand(Player sender, Player targetPlayer, List<String> args) {
|
||||
@ -112,7 +112,6 @@ public final class TeamCommand implements CommandHandler {
|
||||
indexes.add(currentTeamAvatars.get(avatarIndex - 1));
|
||||
} catch (Exception e) {
|
||||
ignoreList.add(avatarIndex);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +97,7 @@ public class GameData {
|
||||
@Getter private static final Int2ObjectMap<CompoundData> compoundDataMap=new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<DungeonElementChallengeData> dungeonElementChallengeDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<DungeonEntryData> dungeonEntryDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<EnvAnimalGatherConfigData> envAnimalGatherConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<EquipAffixData> equipAffixDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
@ -712,7 +712,7 @@ public class ResourceLoader {
|
||||
|
||||
private static void loadTrialAvatarCustomData() {
|
||||
try {
|
||||
String pathName = "CustomResources/TrialAvatarExcels/";
|
||||
String pathName = "TrialAvatar/";
|
||||
try {
|
||||
JsonUtils.loadToList(
|
||||
getResourcePath(pathName + "TrialAvatarActivityDataExcelConfigData.json"),
|
||||
@ -735,9 +735,8 @@ public class ResourceLoader {
|
||||
Grasscutter.getLogger().debug("Loaded trial activity schedule custom data.");
|
||||
try {
|
||||
JsonUtils.loadToList(
|
||||
getResourcePath(pathName + "TrialAvatarData.json"),
|
||||
getResourcePath(pathName + "TrialAvatarCustomConfigData.json"),
|
||||
TrialAvatarCustomData.class).forEach(instance -> {
|
||||
instance.onLoad();
|
||||
GameData.getTrialAvatarCustomData()
|
||||
.put(instance.getTrialAvatarId(), instance);
|
||||
});
|
||||
|
@ -0,0 +1,9 @@
|
||||
package emu.grasscutter.data.common;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BaseTrialAvatarData {
|
||||
List<Integer> getTrialAvatarParamList();
|
||||
List<Integer> getTrialAvatarWeaponList();
|
||||
int getTrialSkillDepotId();
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package emu.grasscutter.data.common;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BaseTrialAvatarTemplateData {
|
||||
int getTrialAvatarSkillLevel();
|
||||
List<Integer> getTrialReliquaryList();
|
||||
}
|
@ -1,16 +1,16 @@
|
||||
package emu.grasscutter.data.custom;
|
||||
|
||||
import emu.grasscutter.data.common.BaseTrialAvatarData;
|
||||
import emu.grasscutter.data.common.BaseTrialAvatarTemplateData;
|
||||
import lombok.*;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class TrialAvatarCustomData {
|
||||
public class TrialAvatarCustomData implements BaseTrialAvatarData, BaseTrialAvatarTemplateData {
|
||||
private int trialAvatarId;
|
||||
private List<String> trialAvatarParamList;
|
||||
private int coreProudSkillLevel;
|
||||
private int skillDepotId;
|
||||
|
||||
public void onLoad() {
|
||||
this.trialAvatarParamList = trialAvatarParamList.stream().filter(x -> !x.isBlank()).toList();
|
||||
}
|
||||
private List<Integer> trialAvatarParamList;
|
||||
private List<Integer> trialAvatarWeaponList;
|
||||
private List<Integer> trialReliquaryList;
|
||||
private int trialSkillDepotId;
|
||||
private int trialAvatarSkillLevel;
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Data
|
||||
@ResourceType(name = "DungeonElementChallengeExcelConfigData.json")
|
||||
public class DungeonElementChallengeData extends GameResource {
|
||||
private int dungeonId;
|
||||
private List<Integer> trialAvatarId;
|
||||
private int tutorialId;
|
||||
|
||||
public int getId() {
|
||||
return dungeonId;
|
||||
}
|
||||
}
|
@ -2,18 +2,25 @@ package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.BaseTrialAvatarData;
|
||||
import lombok.*;
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = "TrialAvatarExcelConfigData.json")
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@Data
|
||||
public class TrialAvatarData extends GameResource {
|
||||
public class TrialAvatarData extends GameResource implements BaseTrialAvatarData {
|
||||
private int trialAvatarId;
|
||||
private List<Integer> trialAvatarParamList;
|
||||
private int trialSkillDepotId;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return trialAvatarId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getTrialAvatarWeaponList() {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,14 @@ package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.BaseTrialAvatarTemplateData;
|
||||
import lombok.*;
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = "TrialAvatarTemplateExcelConfigData.json")
|
||||
@ResourceType(name = "TrialAvatarTemplateExcelConfigData.json")
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@Data
|
||||
public class TrialAvatarTemplateData extends GameResource {
|
||||
public class TrialAvatarTemplateData extends GameResource implements BaseTrialAvatarTemplateData {
|
||||
private int TrialAvatarLevel;
|
||||
private List<Integer> TrialReliquaryList;
|
||||
private int TrialAvatarSkillLevel;
|
||||
|
@ -6,7 +6,6 @@ import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.RewardData;
|
||||
import emu.grasscutter.game.activity.ActivityWatcher;
|
||||
import emu.grasscutter.game.activity.DefaultWatcher;
|
||||
import emu.grasscutter.game.dungeons.DungeonTrialTeam;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
@ -23,41 +22,36 @@ import emu.grasscutter.utils.JsonUtils;
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
import lombok.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@GameActivity(ActivityType.NEW_ACTIVITY_TRIAL_AVATAR)
|
||||
public class TrialAvatarActivityHandler extends ActivityHandler {
|
||||
@Getter @Setter private int selectedTrialAvatarIndex;
|
||||
|
||||
@Override
|
||||
public void onInitPlayerActivityData(PlayerActivityData playerActivityData) {
|
||||
public void onInitPlayerActivityData(@NotNull PlayerActivityData playerActivityData) {
|
||||
TrialAvatarPlayerData trialAvatarPlayerData = TrialAvatarPlayerData.create(getActivityConfigItem().getScheduleId());
|
||||
|
||||
playerActivityData.setDetail(trialAvatarPlayerData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProtoBuild(PlayerActivityData playerActivityData, ActivityInfo.Builder activityInfo) {
|
||||
public void onProtoBuild(PlayerActivityData playerActivityData, @NotNull ActivityInfo.Builder activityInfo) {
|
||||
TrialAvatarPlayerData trialAvatarPlayerData = getTrialAvatarPlayerData(playerActivityData);
|
||||
|
||||
activityInfo.setTrialAvatarInfo(trialAvatarPlayerData.toProto());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initWatchers(Map<WatcherTriggerType, ConstructorAccess<?>> activityWatcherTypeMap) {
|
||||
public void initWatchers(@NotNull Map<WatcherTriggerType, ConstructorAccess<?>> activityWatcherTypeMap) {
|
||||
var watcherType = activityWatcherTypeMap.get(WatcherTriggerType.TRIGGER_FINISH_CHALLENGE);
|
||||
ActivityWatcher watcher;
|
||||
if(watcherType != null){
|
||||
watcher = (ActivityWatcher) watcherType.newInstance();
|
||||
}else{
|
||||
watcher = new DefaultWatcher();
|
||||
}
|
||||
|
||||
ActivityWatcher watcher = watcherType == null ? new DefaultWatcher() : (ActivityWatcher) watcherType.newInstance();
|
||||
watcher.setActivityHandler(this);
|
||||
getWatchersMap().computeIfAbsent(WatcherTriggerType.TRIGGER_FINISH_CHALLENGE, k -> new ArrayList<>());
|
||||
getWatchersMap().get(WatcherTriggerType.TRIGGER_FINISH_CHALLENGE).add(watcher);
|
||||
}
|
||||
|
||||
public TrialAvatarPlayerData getTrialAvatarPlayerData(PlayerActivityData playerActivityData) {
|
||||
public TrialAvatarPlayerData getTrialAvatarPlayerData(@NotNull PlayerActivityData playerActivityData) {
|
||||
if (playerActivityData.getDetail() == null || playerActivityData.getDetail().isBlank()) {
|
||||
onInitPlayerActivityData(playerActivityData);
|
||||
playerActivityData.save();
|
||||
@ -68,49 +62,37 @@ public class TrialAvatarActivityHandler extends ActivityHandler {
|
||||
|
||||
public int getTrialActivityDungeonId(int trialAvatarIndexId) {
|
||||
val data = GameData.getTrialAvatarActivityDataByAvatarIndex(trialAvatarIndexId);
|
||||
return data!=null ? data.getDungeonId() : -1;
|
||||
return data != null ? data.getDungeonId() : -1;
|
||||
}
|
||||
|
||||
public List<String> getTriggerParamList() {
|
||||
val data = GameData.getTrialAvatarActivityDataByAvatarIndex(getSelectedTrialAvatarIndex());
|
||||
return data!=null ? data.getTriggerConfig().getParamList() : Collections.emptyList();
|
||||
return data != null ? data.getTriggerConfig().getParamList() : Collections.emptyList();
|
||||
}
|
||||
|
||||
public boolean enterTrialDungeon(Player player, int trialAvatarIndexId, int enterPointId) {
|
||||
public boolean enterTrialDungeon(@NotNull Player player, int trialAvatarIndexId, int enterPointId) {
|
||||
// TODO, not sure if this will cause problem in MP, since we are entering trial activity dungeon
|
||||
player.sendPacket(new PacketScenePlayerLocationNotify(player.getScene())); // official does send this
|
||||
|
||||
if (!player.getServer().getDungeonSystem().enterDungeon(
|
||||
player,
|
||||
enterPointId,
|
||||
getTrialActivityDungeonId(trialAvatarIndexId))) return false;
|
||||
player,
|
||||
enterPointId,
|
||||
getTrialActivityDungeonId(trialAvatarIndexId))) return false;
|
||||
|
||||
setSelectedTrialAvatarIndex(trialAvatarIndexId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<Integer> getBattleAvatarsList() {
|
||||
val activityData = GameData.getTrialAvatarActivityDataByAvatarIndex(getSelectedTrialAvatarIndex());
|
||||
if (activityData == null || activityData.getBattleAvatarsList().isBlank()) return List.of();
|
||||
|
||||
return Stream.of(activityData.getBattleAvatarsList().split(",")).map(Integer::parseInt).toList();
|
||||
}
|
||||
|
||||
public DungeonTrialTeam getTrialAvatarDungeonTeam(){
|
||||
List<Integer> battleAvatarsList = getBattleAvatarsList();
|
||||
if (battleAvatarsList.isEmpty()) return null;
|
||||
|
||||
return new DungeonTrialTeam(battleAvatarsList, GrantReason.GRANT_REASON_BY_TRIAL_AVATAR_ACTIVITY);
|
||||
}
|
||||
|
||||
public void unsetTrialAvatarTeam(Player player) {
|
||||
if (getSelectedTrialAvatarIndex() <= 0) return;
|
||||
player.removeTrialAvatarForActivity();
|
||||
setSelectedTrialAvatarIndex(0);
|
||||
}
|
||||
|
||||
public boolean getReward(Player player, int trialAvatarIndexId) {
|
||||
val playerActivityData = player.getActivityManager().getPlayerActivityDataByActivityType(ActivityType.NEW_ACTIVITY_TRIAL_AVATAR);
|
||||
public boolean getReward(@NotNull Player player, int trialAvatarIndexId) {
|
||||
val playerActivityData = player.getActivityManager()
|
||||
.getPlayerActivityDataByActivityType(ActivityType.NEW_ACTIVITY_TRIAL_AVATAR);
|
||||
|
||||
if(playerActivityData.isEmpty()){
|
||||
return false;
|
||||
|
@ -34,9 +34,6 @@ import emu.grasscutter.net.proto.FetterDataOuterClass.FetterData;
|
||||
import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass;
|
||||
import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass.ShowAvatarInfo;
|
||||
import emu.grasscutter.net.proto.ShowEquipOuterClass.ShowEquip;
|
||||
import emu.grasscutter.net.proto.TrialAvatarInfoOuterClass.TrialAvatarInfo;
|
||||
import emu.grasscutter.net.proto.TrialAvatarGrantRecordOuterClass.TrialAvatarGrantRecord;
|
||||
import emu.grasscutter.net.proto.TrialAvatarGrantRecordOuterClass.TrialAvatarGrantRecord.GrantReason;
|
||||
import emu.grasscutter.server.packet.send.*;
|
||||
import emu.grasscutter.utils.ProtoHelper;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
@ -89,15 +86,6 @@ public class Avatar {
|
||||
@Getter @Setter private int nameCardRewardId;
|
||||
@Getter @Setter private int nameCardId;
|
||||
|
||||
// trial avatar property
|
||||
@Getter @Setter private int trialAvatarId = 0;
|
||||
// cannot store to db if grant reason is not integer
|
||||
@Getter @Setter private int grantReason = GrantReason.GRANT_REASON_INVALID.getNumber();
|
||||
@Getter @Setter private int fromParentQuestId = 0;
|
||||
// so far no outer class or prop value has information of this, but from packet i sniff
|
||||
// 1 = normal, 2 = trial avatar
|
||||
@Getter @Setter private int avatarType = 1;
|
||||
|
||||
@Deprecated // Do not use. Morhpia only!
|
||||
public Avatar() {
|
||||
this.equips = new Int2ObjectOpenHashMap<>();
|
||||
@ -841,11 +829,11 @@ public class Avatar {
|
||||
}
|
||||
|
||||
public void save() {
|
||||
if (getTrialAvatarId() > 0) return; // dont save trial avatar
|
||||
if (this instanceof TrialAvatar) return;
|
||||
DatabaseHelper.saveAvatar(this);
|
||||
}
|
||||
|
||||
public AvatarInfo toProto() {
|
||||
public AvatarInfo.Builder protoBuilder() {
|
||||
int fetterLevel = this.getFetterLevel();
|
||||
AvatarFetterInfo.Builder avatarFetter = AvatarFetterInfo.newBuilder()
|
||||
.setExpLevel(fetterLevel);
|
||||
@ -873,17 +861,15 @@ public class Avatar {
|
||||
.putAllSkillLevelMap(this.getSkillLevelMap())
|
||||
.addAllInherentProudSkillList(this.getProudSkillList())
|
||||
.putAllProudSkillExtraLevelMap(getProudSkillBonusMap())
|
||||
.setAvatarType(this.getAvatarType())
|
||||
.setAvatarType(1)
|
||||
.setBornTime(this.getBornTime())
|
||||
.setWearingFlycloakId(this.getFlyCloak())
|
||||
.setCostumeId(this.getCostume())
|
||||
.setIsFocus(false);
|
||||
|
||||
if (this.getAvatarType() == 1){
|
||||
avatarInfo.setFetterInfo(avatarFetter);
|
||||
if (this.getPlayer().getNameCardList().contains(this.getNameCardId())) {
|
||||
avatarFetter.addRewardedFetterLevelList(10);
|
||||
}
|
||||
avatarInfo.setFetterInfo(avatarFetter);
|
||||
if (this.getPlayer().getNameCardList().contains(this.getNameCardId())) {
|
||||
avatarFetter.addRewardedFetterLevelList(10);
|
||||
}
|
||||
|
||||
this.getSkillExtraChargeMap().forEach((skillId, count) ->
|
||||
@ -897,8 +883,11 @@ public class Avatar {
|
||||
avatarInfo.putPropMap(PlayerProperty.PROP_SATIATION_VAL.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_SATIATION_VAL, 0));
|
||||
avatarInfo.putPropMap(PlayerProperty.PROP_SATIATION_PENALTY_TIME.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_SATIATION_PENALTY_TIME, 0));
|
||||
|
||||
avatarInfo.setTrialAvatarInfo(trialAvatarInfoProto());
|
||||
return avatarInfo.build();
|
||||
return avatarInfo;
|
||||
}
|
||||
|
||||
public AvatarInfo toProto() {
|
||||
return this.protoBuilder().build();
|
||||
}
|
||||
|
||||
// used only in character showcase
|
||||
@ -941,129 +930,6 @@ public class Avatar {
|
||||
return showAvatarInfo.build();
|
||||
}
|
||||
|
||||
public void setTrialAvatarInfo(int avatarLevel, int trialAvatarId, GrantReason grantReason, int fromParentQuestId){
|
||||
this.setLevel(avatarLevel);
|
||||
this.setPromoteLevel(getMinPromoteLevel(avatarLevel));
|
||||
this.setTrialAvatarId(trialAvatarId);
|
||||
this.setGrantReason(grantReason.getNumber());
|
||||
this.setFromParentQuestId(fromParentQuestId);
|
||||
this.setAvatarType(2);
|
||||
this.setTrialSkillLevel();
|
||||
this.setTrialItems();
|
||||
}
|
||||
|
||||
private int getTrialAvatarTemplateLevel(){
|
||||
return getLevel() <= 9 ? 1 :
|
||||
(int) (Math.floor(getLevel() / 10f) * 10); // round trial level to fit template levels
|
||||
}
|
||||
|
||||
public int getTrialSkillLevel() {
|
||||
if (GameData.getTrialAvatarCustomData().isEmpty()) { // use default data if custom data not available
|
||||
int trialAvatarTemplateLevel = getTrialAvatarTemplateLevel(); // round trial level to fit template levels
|
||||
|
||||
TrialAvatarTemplateData templateData = GameData.getTrialAvatarTemplateDataMap().get(trialAvatarTemplateLevel);
|
||||
return templateData == null ? 1 : templateData.getTrialAvatarSkillLevel();
|
||||
}
|
||||
if (GameData.getTrialAvatarCustomData().get(getTrialAvatarId()) == null) return 1;
|
||||
|
||||
return GameData.getTrialAvatarCustomData().get(getTrialAvatarId()).getCoreProudSkillLevel(); // enhanced version of weapon
|
||||
}
|
||||
|
||||
public void setTrialSkillLevel() {
|
||||
getSkillLevelMap().keySet().stream().forEach(skill -> setSkillLevel(skill, getTrialSkillLevel()));
|
||||
}
|
||||
|
||||
public int getTrialWeaponId() {
|
||||
if (GameData.getTrialAvatarCustomData().isEmpty()) { // use default data if custom data not available
|
||||
if (GameData.getTrialAvatarDataMap().get(getTrialAvatarId()) == null)
|
||||
return getAvatarData().getInitialWeapon();
|
||||
|
||||
return GameData.getItemDataMap().get(getAvatarData().getInitialWeapon()+100) == null ?
|
||||
getAvatarData().getInitialWeapon() :
|
||||
getAvatarData().getInitialWeapon()+100; // enhanced version of weapon
|
||||
}
|
||||
// use custom data
|
||||
if (GameData.getTrialAvatarCustomData().get(getTrialAvatarId()) == null) return 0;
|
||||
|
||||
val trialCustomParams = GameData.getTrialAvatarCustomData().get(trialAvatarId).getTrialAvatarParamList();
|
||||
return trialCustomParams.size() < 2 ? getAvatarData().getInitialWeapon() :
|
||||
Integer.parseInt(trialCustomParams.get(1).split(";")[0]);
|
||||
}
|
||||
|
||||
public List<Integer> getTrialReliquary() {
|
||||
if (!GameData.getTrialAvatarCustomData().isEmpty()) {
|
||||
// try using custom data
|
||||
if (GameData.getTrialAvatarCustomData().get(getTrialAvatarId()) != null) {
|
||||
val trialCustomParams = GameData.getTrialAvatarCustomData().get(getTrialAvatarId()).getTrialAvatarParamList();
|
||||
if (trialCustomParams.size() > 2) {
|
||||
return Stream.of(trialCustomParams.get(2).split(";")).map(Integer::parseInt).toList();
|
||||
}
|
||||
}
|
||||
}
|
||||
int trialAvatarTemplateLevel = getTrialAvatarTemplateLevel();
|
||||
|
||||
TrialAvatarTemplateData templateData = GameData.getTrialAvatarTemplateDataMap().get(trialAvatarTemplateLevel);
|
||||
return templateData == null ? List.of() : templateData.getTrialReliquaryList();
|
||||
}
|
||||
|
||||
public void setTrialItems(){
|
||||
// add enhanced verion of trial weapon
|
||||
GameItem weapon = new GameItem(getTrialWeaponId());
|
||||
weapon.setLevel(getLevel());
|
||||
weapon.setExp(0);
|
||||
weapon.setPromoteLevel(getMinPromoteLevel(getLevel()));
|
||||
getEquips().put(weapon.getEquipSlot(), weapon);
|
||||
|
||||
// add Trial Artifacts
|
||||
getTrialReliquary().forEach(id -> {
|
||||
TrialReliquaryData reliquaryData = GameData.getTrialReliquaryDataMap().get(id);
|
||||
if (reliquaryData == null) return;
|
||||
|
||||
GameItem relic = new GameItem(reliquaryData.getReliquaryId());
|
||||
relic.setLevel(reliquaryData.getLevel());
|
||||
relic.setMainPropId(reliquaryData.getMainPropId());
|
||||
relic.getAppendPropIdList().addAll(reliquaryData.getAppendPropList());
|
||||
getEquips().put(relic.getEquipSlot(), relic);
|
||||
});
|
||||
|
||||
// add costume if any (ambor, rosiaria, mona, Jean)
|
||||
GameData.getAvatarCostumeDataItemIdMap().values().stream().forEach(costumeData -> {
|
||||
if (costumeData.getCharacterId() != getAvatarId()) return;
|
||||
setCostume(costumeData.getId());
|
||||
});
|
||||
}
|
||||
|
||||
public void equipTrialItems(){
|
||||
getEquips().forEach((itemEquipTypeValues, item) -> {
|
||||
item.setEquipCharacter(getAvatarId());
|
||||
item.setOwner(getPlayer());
|
||||
if (item.getItemData().getEquipType() == EquipType.EQUIP_WEAPON && getPlayer().getWorld() != null) {
|
||||
item.setWeaponEntityId(this.getPlayer().getWorld().getNextEntityId(EntityIdType.WEAPON));
|
||||
getPlayer().sendPacket(new PacketAvatarEquipChangeNotify(this, item));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public TrialAvatarInfo trialAvatarInfoProto(){
|
||||
TrialAvatarInfo.Builder trialAvatar = TrialAvatarInfo.newBuilder()
|
||||
.setTrialAvatarId(this.getTrialAvatarId())
|
||||
.setGrantRecord(TrialAvatarGrantRecord.newBuilder()
|
||||
.setGrantReason(this.getGrantReason())
|
||||
.setFromParentQuestId(this.getFromParentQuestId()));
|
||||
|
||||
if (this.getTrialAvatarId() > 0){ // if it is actual trial avatar
|
||||
// add artifacts or wepon for trial character
|
||||
int itemCount = 0;
|
||||
for (GameItem item : this.getEquips().values()) {
|
||||
trialAvatar.addTrialEquipList(itemCount, item.toProto());
|
||||
itemCount++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return trialAvatar.build();
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
private void onLoad() {
|
||||
|
||||
|
@ -17,10 +17,11 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
|
||||
public class AvatarStorage extends BasePlayerManager implements Iterable<Avatar> {
|
||||
private final Int2ObjectMap<Avatar> avatars;
|
||||
private final Long2ObjectMap<Avatar> avatarsGuid;
|
||||
@Getter private final Long2ObjectMap<Avatar> avatarsGuid;
|
||||
|
||||
public AvatarStorage(Player player) {
|
||||
super(player);
|
||||
@ -49,7 +50,12 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<Avatar>
|
||||
}
|
||||
|
||||
public boolean addAvatar(Avatar avatar) {
|
||||
if (avatar.getAvatarData() == null || this.hasAvatar(avatar.getAvatarId())) {
|
||||
// Only both avatar id and guid existed would not pass the key
|
||||
// i.e. both id and guid existed = normal character in bag
|
||||
// id existed but not guid (before adding) = trial avatars
|
||||
if (avatar.getAvatarData() == null ||
|
||||
(this.hasAvatar(avatar.getAvatarId())
|
||||
&& this.getAvatarsGuid().containsKey(avatar.getGuid()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -57,7 +63,11 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<Avatar>
|
||||
avatar.setOwner(getPlayer());
|
||||
|
||||
// Put into maps
|
||||
this.avatars.put(avatar.getAvatarId(), avatar);
|
||||
if (!(avatar instanceof TrialAvatar)) {
|
||||
// Don't need to replace with new avatar using
|
||||
// avatar id if it is trial avatars
|
||||
this.avatars.put(avatar.getAvatarId(), avatar);
|
||||
}
|
||||
this.avatarsGuid.put(avatar.getGuid(), avatar);
|
||||
|
||||
avatar.save();
|
||||
@ -65,6 +75,15 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<Avatar>
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean removeAvatarByGuid(long guid) {
|
||||
// the only ones removable are trial avatars, which only guid are used in adding
|
||||
if (this.getAvatarsGuid().containsKey(guid)) {
|
||||
return false;
|
||||
}
|
||||
this.avatarsGuid.remove(guid);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addStartingWeapon(Avatar avatar) {
|
||||
// Make sure avatar owner is this player
|
||||
if (avatar.getPlayer() != this.getPlayer()) {
|
||||
|
154
src/main/java/emu/grasscutter/game/avatar/TrialAvatar.java
Normal file
154
src/main/java/emu/grasscutter/game/avatar/TrialAvatar.java
Normal file
@ -0,0 +1,154 @@
|
||||
package emu.grasscutter.game.avatar;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.common.BaseTrialAvatarData;
|
||||
import emu.grasscutter.data.common.BaseTrialAvatarTemplateData;
|
||||
import emu.grasscutter.data.excels.AvatarCostumeData;
|
||||
import emu.grasscutter.data.excels.TrialReliquaryData;
|
||||
import emu.grasscutter.game.inventory.EquipType;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.props.EntityIdType;
|
||||
import emu.grasscutter.net.proto.AvatarInfoOuterClass;
|
||||
import emu.grasscutter.net.proto.TrialAvatarGrantRecordOuterClass.TrialAvatarGrantRecord;
|
||||
import emu.grasscutter.net.proto.TrialAvatarGrantRecordOuterClass.TrialAvatarGrantRecord.GrantReason;
|
||||
import emu.grasscutter.net.proto.TrialAvatarInfoOuterClass.TrialAvatarInfo;
|
||||
import emu.grasscutter.server.packet.send.PacketAvatarEquipChangeNotify;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.val;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class TrialAvatar extends Avatar{
|
||||
// trial avatar property
|
||||
@Getter @Setter private int trialAvatarId = 0;
|
||||
// cannot store to db if grant reason is not integer
|
||||
@Getter @Setter private int grantReason = GrantReason.GRANT_REASON_INVALID.getNumber();
|
||||
@Getter @Setter private int fromParentQuestId = 0;
|
||||
// so far no outer class or prop value has information of this, but from packet I sniff
|
||||
// 1 = normal, 2 = trial avatar
|
||||
@Getter private final int avatarType = 2;
|
||||
|
||||
public TrialAvatar(@NotNull List<Integer> trialAvatarParam, int trialAvatarId, @NotNull GrantReason grantReason, int fromParentQuestId) {
|
||||
super(trialAvatarParam.get(0));
|
||||
this.setLevel(trialAvatarParam.get(1));
|
||||
this.setPromoteLevel(getMinPromoteLevel(trialAvatarParam.get(1)));
|
||||
this.setTrialAvatarId(trialAvatarId);
|
||||
this.setGrantReason(grantReason.getNumber());
|
||||
this.setFromParentQuestId(fromParentQuestId);
|
||||
this.setTrialSkillLevel();
|
||||
this.setTrialItems();
|
||||
}
|
||||
|
||||
public static boolean useCustomData() {
|
||||
return !(GameData.getTrialAvatarCustomData() == null || GameData.getTrialAvatarCustomData().isEmpty());
|
||||
}
|
||||
|
||||
public static List<Integer> getTrialAvatarParam(int trialAvatarId) {
|
||||
val trialData = TrialAvatar.useCustomData() ? GameData.getTrialAvatarCustomData() : GameData.getTrialAvatarDataMap();
|
||||
BaseTrialAvatarData trialAvatarData = trialData.get(trialAvatarId);
|
||||
return (trialAvatarData == null) ? List.of() : trialAvatarData.getTrialAvatarParamList();
|
||||
}
|
||||
|
||||
private int getTrialAvatarTemplateLevel(){
|
||||
return GameData.getTrialAvatarTemplateDataMap().keySet().stream()
|
||||
.min(Comparator.comparingInt(value -> Math.abs(value - getLevel())))
|
||||
.stream().findFirst().orElse(0);
|
||||
}
|
||||
|
||||
public int getTrialSkillLevel() {
|
||||
val trialData = useCustomData() ? GameData.getTrialAvatarCustomData() : GameData.getTrialAvatarTemplateDataMap();
|
||||
int skillOrId = useCustomData() ? getTrialAvatarId() : getTrialAvatarTemplateLevel();
|
||||
BaseTrialAvatarTemplateData trialAvatarData = trialData.get(skillOrId);
|
||||
return (trialAvatarData == null) ? 1 : trialAvatarData.getTrialAvatarSkillLevel();
|
||||
}
|
||||
|
||||
public void setTrialSkillLevel() {
|
||||
getSkillLevelMap().keySet().forEach(skill -> setSkillLevel(skill, getTrialSkillLevel()));
|
||||
}
|
||||
|
||||
public int getTrialWeaponId() {
|
||||
val trialData = useCustomData() ? GameData.getTrialAvatarCustomData() : GameData.getTrialAvatarDataMap();
|
||||
BaseTrialAvatarData trialAvatarData = trialData.get(getTrialAvatarId());
|
||||
|
||||
return (trialAvatarData == null || trialAvatarData.getTrialAvatarWeaponList().size() < 1) ?
|
||||
getAvatarData().getInitialWeapon() + 100 : trialAvatarData.getTrialAvatarWeaponList().get(0);
|
||||
}
|
||||
|
||||
public List<Integer> getTrialReliquary() {
|
||||
val trialData = useCustomData() ? GameData.getTrialAvatarCustomData() : GameData.getTrialAvatarTemplateDataMap();
|
||||
int skillOrId = useCustomData() ? getTrialAvatarId() : getTrialAvatarTemplateLevel();
|
||||
BaseTrialAvatarTemplateData trialAvatarData = trialData.get(skillOrId);
|
||||
|
||||
return (trialAvatarData == null || trialAvatarData.getTrialReliquaryList().isEmpty()) ?
|
||||
GameData.getTrialAvatarTemplateDataMap().get(getTrialAvatarTemplateLevel()).getTrialReliquaryList() :
|
||||
trialAvatarData.getTrialReliquaryList();
|
||||
}
|
||||
|
||||
public void setTrialItems(){
|
||||
// add enhanced version of trial weapon
|
||||
GameItem weapon = new GameItem(getTrialWeaponId());
|
||||
weapon.setLevel(getLevel());
|
||||
weapon.setExp(0);
|
||||
Grasscutter.getLogger().info("Min promote level: {}", getMinPromoteLevel(getLevel()));
|
||||
weapon.setPromoteLevel(getMinPromoteLevel(getLevel()));
|
||||
getEquips().put(weapon.getEquipSlot(), weapon);
|
||||
|
||||
// add Trial Artifacts
|
||||
getTrialReliquary().forEach(id -> {
|
||||
TrialReliquaryData reliquaryData = GameData.getTrialReliquaryDataMap().get(id.intValue());
|
||||
if (reliquaryData == null) return;
|
||||
|
||||
GameItem relic = new GameItem(reliquaryData.getReliquaryId());
|
||||
relic.setLevel(reliquaryData.getLevel());
|
||||
relic.setMainPropId(reliquaryData.getMainPropId());
|
||||
relic.getAppendPropIdList().addAll(reliquaryData.getAppendPropList());
|
||||
getEquips().put(relic.getEquipSlot(), relic);
|
||||
});
|
||||
|
||||
// add costume if any (Amber, Rosaria, Mona, Jean)
|
||||
this.setCostume(GameData.getAvatarCostumeDataItemIdMap().values()
|
||||
.stream().map(AvatarCostumeData::getCharacterId)
|
||||
.filter(characterId -> characterId == this.getAvatarId())
|
||||
.findAny().orElse(0));
|
||||
}
|
||||
|
||||
public void equipTrialItems(){
|
||||
getEquips().forEach((itemEquipTypeValues, item) -> {
|
||||
item.setEquipCharacter(getAvatarId());
|
||||
item.setOwner(getPlayer());
|
||||
if (item.getItemData().getEquipType() == EquipType.EQUIP_WEAPON && getPlayer().getWorld() != null) {
|
||||
item.setWeaponEntityId(this.getPlayer().getWorld().getNextEntityId(EntityIdType.WEAPON));
|
||||
getPlayer().sendPacket(new PacketAvatarEquipChangeNotify(this, item));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public TrialAvatarInfo trialAvatarInfoProto(){
|
||||
TrialAvatarInfo.Builder trialAvatar = TrialAvatarInfo.newBuilder()
|
||||
.setTrialAvatarId(this.getTrialAvatarId())
|
||||
.setGrantRecord(TrialAvatarGrantRecord.newBuilder()
|
||||
.setGrantReason(this.getGrantReason())
|
||||
.setFromParentQuestId(this.getFromParentQuestId()));
|
||||
|
||||
if (this.getTrialAvatarId() > 0){ // if it is actual trial avatar
|
||||
// add artifacts and weapon for trial character
|
||||
AtomicInteger itemCount = new AtomicInteger();
|
||||
this.getEquips().values().forEach(item ->
|
||||
trialAvatar.addTrialEquipList(itemCount.getAndIncrement(), item.toProto()));
|
||||
}
|
||||
|
||||
return trialAvatar.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AvatarInfoOuterClass.AvatarInfo.Builder protoBuilder() {
|
||||
return super.protoBuilder()
|
||||
.setAvatarType(getAvatarType())
|
||||
.setTrialAvatarInfo(this.trialAvatarInfoProto());
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.game.quest.enums.LogicType;
|
||||
import emu.grasscutter.game.quest.enums.QuestContent;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.net.proto.TrialAvatarGrantRecordOuterClass.TrialAvatarGrantRecord.GrantReason;
|
||||
import emu.grasscutter.scripts.constants.EventType;
|
||||
import emu.grasscutter.scripts.data.ScriptArgs;
|
||||
import emu.grasscutter.server.packet.send.PacketDungeonWayPointNotify;
|
||||
@ -52,8 +53,6 @@ public class DungeonManager {
|
||||
private int newestWayPoint = 0;
|
||||
@Getter private int startSceneTime = 0;
|
||||
|
||||
DungeonTrialTeam trialTeam = null;
|
||||
|
||||
public DungeonManager(@NonNull Scene scene, @NonNull DungeonData dungeonData) {
|
||||
this.scene = scene;
|
||||
this.dungeonData = dungeonData;
|
||||
@ -229,32 +228,31 @@ public class DungeonManager {
|
||||
if (getDungeonData() == null) return;
|
||||
|
||||
switch (getDungeonData().getType()) {
|
||||
// case DUNGEON_PLOT is handled by quest execs
|
||||
// case DUNGEON_PLOT is handled by quest execs
|
||||
case DUNGEON_ACTIVITY -> {
|
||||
switch (getDungeonData().getPlayType()) {
|
||||
case DUNGEON_PLAY_TYPE_TRIAL_AVATAR -> {
|
||||
val activityHandler = player.getActivityManager()
|
||||
.getActivityHandlerAs(ActivityType.NEW_ACTIVITY_TRIAL_AVATAR, TrialAvatarActivityHandler.class);
|
||||
activityHandler.ifPresent(trialAvatarActivityHandler ->
|
||||
this.trialTeam = trialAvatarActivityHandler.getTrialAvatarDungeonTeam());
|
||||
player.getActivityManager().getActivityHandlerAs(
|
||||
ActivityType.NEW_ACTIVITY_TRIAL_AVATAR, TrialAvatarActivityHandler.class)
|
||||
.ifPresent(handler -> player.addTrialAvatarsForDungeon(
|
||||
handler.getBattleAvatarsList(), GrantReason.GRANT_REASON_BY_TRIAL_AVATAR_ACTIVITY));
|
||||
}
|
||||
case DUNGEON_PLAY_TYPE_MIST_TRIAL -> {} // TODO
|
||||
}
|
||||
}
|
||||
case DUNGEON_ELEMENT_CHALLENGE -> {} // TODO
|
||||
case DUNGEON_ELEMENT_CHALLENGE -> {
|
||||
Optional.ofNullable(GameData.getDungeonElementChallengeDataMap().get(getDungeonData().getId()))
|
||||
.ifPresent(elementDungeonData -> {
|
||||
player.addTrialAvatarsForDungeon(elementDungeonData.getTrialAvatarId(),
|
||||
GrantReason.GRANT_REASON_BY_DUNGEON_ELEMENT_CHALLENGE);
|
||||
});
|
||||
}
|
||||
}
|
||||
if(this.trialTeam != null) {
|
||||
player.addTrialAvatarsForActivity(trialTeam.trialAvatarIds);
|
||||
if (player.getTeamManager().isUseTrialTeam()){
|
||||
player.getTeamManager().updateTeamEntities(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void unsetTrialTeam(Player player){
|
||||
if(this.trialTeam==null){
|
||||
return;
|
||||
}
|
||||
player.removeTrialAvatarForActivity();
|
||||
this.trialTeam = null;
|
||||
}
|
||||
|
||||
public void startDungeon() {
|
||||
this.startSceneTime = scene.getSceneTimeSeconds();
|
||||
scene.getPlayers().forEach(p -> {
|
||||
|
@ -147,14 +147,11 @@ public class DungeonSystem extends BaseGameSystem {
|
||||
if(!dungeonManager.isFinishedSuccessfully()){
|
||||
dungeonManager.quitDungeon();
|
||||
}
|
||||
|
||||
dungeonManager.unsetTrialTeam(player);
|
||||
}
|
||||
// clean temp team if it has
|
||||
player.getTeamManager().cleanTemporaryTeam();
|
||||
player.getTowerManager().clearEntry();
|
||||
|
||||
|
||||
// Transfer player back to world
|
||||
player.getWorld().transferPlayerToScene(player, prevScene, prevPos);
|
||||
}
|
||||
|
@ -1,14 +0,0 @@
|
||||
package emu.grasscutter.game.dungeons;
|
||||
|
||||
import emu.grasscutter.net.proto.TrialAvatarGrantRecordOuterClass.TrialAvatarGrantRecord;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class DungeonTrialTeam {
|
||||
List<Integer> trialAvatarIds;
|
||||
TrialAvatarGrantRecord.GrantReason grantReason;
|
||||
}
|
@ -54,12 +54,13 @@ public class EntityAvatar extends GameEntity {
|
||||
super(scene);
|
||||
this.avatar = avatar;
|
||||
this.avatar.setCurrentEnergy();
|
||||
if (scene != null)
|
||||
if (scene != null) {
|
||||
this.id = getScene().getWorld().getNextEntityId(EntityIdType.AVATAR);
|
||||
|
||||
GameItem weapon = this.getAvatar().getWeapon();
|
||||
if (weapon != null) {
|
||||
weapon.setWeaponEntityId(getScene().getWorld().getNextEntityId(EntityIdType.WEAPON));
|
||||
GameItem weapon = this.getAvatar().getWeapon();
|
||||
if (weapon != null) {
|
||||
weapon.setWeaponEntityId(getScene().getWorld().getNextEntityId(EntityIdType.WEAPON));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ import dev.morphia.annotations.*;
|
||||
import emu.grasscutter.GameConstants;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.binout.AbilityData;
|
||||
import emu.grasscutter.data.binout.config.ConfigLevelEntity;
|
||||
import emu.grasscutter.data.binout.config.fields.ConfigAbilityData;
|
||||
import emu.grasscutter.data.excels.*;
|
||||
@ -15,6 +14,7 @@ import emu.grasscutter.game.ability.AbilityManager;
|
||||
import emu.grasscutter.game.activity.ActivityManager;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.avatar.AvatarStorage;
|
||||
import emu.grasscutter.game.avatar.TrialAvatar;
|
||||
import emu.grasscutter.game.battlepass.BattlePassManager;
|
||||
import emu.grasscutter.game.entity.EntityAvatar;
|
||||
import emu.grasscutter.game.entity.GameEntity;
|
||||
@ -81,13 +81,13 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.val;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
@ -832,38 +832,25 @@ public class Player {
|
||||
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();
|
||||
|
||||
val 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);
|
||||
List<Integer> trialAvatarBasicParam = TrialAvatar.getTrialAvatarParam(trialAvatarId);
|
||||
if (trialAvatarBasicParam.isEmpty()) return false;
|
||||
|
||||
Avatar avatar = new Avatar(trialAvatarBasicParam.get(0));
|
||||
if (avatar.getAvatarData() == null || !hasSentLoginPackets()) return false;
|
||||
TrialAvatar trialAvatar = new TrialAvatar(trialAvatarBasicParam, trialAvatarId, reason, questMainId);
|
||||
if (trialAvatar.getAvatarData() == null || !hasSentLoginPackets()) return false;
|
||||
|
||||
avatar.setOwner(this);
|
||||
// Add trial weapons and relics
|
||||
avatar.setTrialAvatarInfo(trialAvatarBasicParam.get(1), trialAvatarId, reason, questMainId);
|
||||
avatar.equipTrialItems();
|
||||
// add trial avatar to storage
|
||||
boolean result = this.getAvatars().addAvatar(trialAvatar);
|
||||
if (!result) return false;
|
||||
|
||||
trialAvatar.equipTrialItems();
|
||||
// Recalc stats
|
||||
avatar.recalcStats();
|
||||
trialAvatar.recalcStats();
|
||||
|
||||
// Packet, mimic official server behaviour, add to player's bag but not saving to db
|
||||
sendPacket(new PacketAvatarAddNotify(avatar, false));
|
||||
sendPacket(new PacketAvatarAddNotify(trialAvatar, false));
|
||||
// add to avatar to temporary trial team
|
||||
getTeamManager().addAvatarToTrialTeam(avatar);
|
||||
getTeamManager().addAvatarToTrialTeam(trialAvatar);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -873,36 +860,52 @@ public class Player {
|
||||
trialAvatarId,
|
||||
GrantReason.GRANT_REASON_BY_QUEST,
|
||||
questMainId)) return false;
|
||||
getTeamManager().trialAvatarTeamPostUpdate();
|
||||
// Packet, mimic official server behaviour, neccessary to stop player from modifying team
|
||||
// Packet, mimic official server behaviour, necessary to stop player from modifying team
|
||||
sendPacket(new PacketAvatarTeamUpdateNotify(this));
|
||||
|
||||
getTeamManager().updateTeamEntities(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addTrialAvatarsForActivity(List<Integer> trialAvatarIds) {
|
||||
getTeamManager().setupTrialAvatarTeamForActivity();
|
||||
trialAvatarIds.forEach(trialAvatarId -> addTrialAvatar(
|
||||
trialAvatarId,
|
||||
GrantReason.GRANT_REASON_BY_TRIAL_AVATAR_ACTIVITY,
|
||||
0));
|
||||
getTeamManager().trialAvatarTeamPostUpdate(0);
|
||||
public void addTrialAvatarsForDungeon(@NotNull List<Integer> trialAvatarIds, GrantReason reason) {
|
||||
getTeamManager().setupTrialAvatarTeamForDungeon();
|
||||
trialAvatarIds.forEach(trialAvatarId -> addTrialAvatar(trialAvatarId, reason, 0));
|
||||
}
|
||||
|
||||
public boolean removeTrialAvatarForQuest(int trialAvatarId) {
|
||||
if (!getTeamManager().isUseTrialTeam()) return false;
|
||||
|
||||
sendPacket(new PacketAvatarDelNotify(List.of(getTeamManager().getTrialAvatarGuid(trialAvatarId))));
|
||||
getTeamManager().removeTrialAvatarTeamForQuest(trialAvatarId);
|
||||
List<Integer> trialAvatarBasicParam = TrialAvatar.getTrialAvatarParam(trialAvatarId);
|
||||
if (trialAvatarBasicParam.isEmpty()) return false;
|
||||
|
||||
// allows player to modify team again
|
||||
sendPacket(new PacketAvatarTeamUpdateNotify());
|
||||
|
||||
long trialAvatarGuid = getTeamManager().getEntityGuids().get(trialAvatarBasicParam.get(0));
|
||||
|
||||
// remove trial avatar from storage
|
||||
this.getAvatars().removeAvatarByGuid(trialAvatarGuid);
|
||||
|
||||
// remove trial avatar entities
|
||||
getTeamManager().removeTrialAvatarTeam();
|
||||
|
||||
// send remove packets
|
||||
sendPacket(new PacketAvatarDelNotify(List.of(trialAvatarGuid)));
|
||||
return true;
|
||||
}
|
||||
|
||||
public void removeTrialAvatarForActivity() {
|
||||
public void removeTrialAvatarForDungeon() {
|
||||
if (!getTeamManager().isUseTrialTeam()) return;
|
||||
List<Long> tempGuids = getTeamManager().getEntityGuids().values().stream().toList();
|
||||
|
||||
sendPacket(new PacketAvatarDelNotify(getTeamManager().getActiveTeam().stream()
|
||||
.map(x -> x.getAvatar().getGuid()).toList()));
|
||||
getTeamManager().removeTrialAvatarTeamForActivity();
|
||||
// remove trial avatar from storage
|
||||
tempGuids.forEach(guid -> this.getAvatars().removeAvatarByGuid(guid));
|
||||
|
||||
// remove trial avatar entities
|
||||
getTeamManager().removeTrialAvatarTeam();
|
||||
|
||||
// send remove packets
|
||||
sendPacket(new PacketAvatarDelNotify(tempGuids));
|
||||
}
|
||||
|
||||
public void addFlycloak(int flycloakId) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,6 @@ import emu.grasscutter.game.entity.*;
|
||||
import emu.grasscutter.game.entity.gadget.GadgetWorktop;
|
||||
import emu.grasscutter.game.managers.blossom.BlossomManager;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.player.TeamInfo;
|
||||
import emu.grasscutter.game.props.*;
|
||||
import emu.grasscutter.game.quest.QuestGroupSuite;
|
||||
import emu.grasscutter.game.world.data.TeleportProperties;
|
||||
@ -29,7 +28,6 @@ import emu.grasscutter.scripts.SceneIndexManager;
|
||||
import emu.grasscutter.scripts.SceneScriptManager;
|
||||
import emu.grasscutter.scripts.constants.EventType;
|
||||
import emu.grasscutter.scripts.data.SceneBlock;
|
||||
import emu.grasscutter.scripts.data.SceneGadget;
|
||||
import emu.grasscutter.scripts.data.SceneGroup;
|
||||
import emu.grasscutter.scripts.data.ScriptArgs;
|
||||
import emu.grasscutter.server.event.player.PlayerTeleportEvent;
|
||||
@ -40,6 +38,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.val;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ -197,7 +196,7 @@ public class Scene {
|
||||
player.setScene(null);
|
||||
|
||||
// Remove player avatars
|
||||
this.removePlayerAvatars(player);
|
||||
this.removePlayerAvatars(player);
|
||||
|
||||
// Remove player gadgets
|
||||
for (EntityBaseGadget gadget : player.getTeamManager().getGadgets()) {
|
||||
@ -212,34 +211,18 @@ public class Scene {
|
||||
this.saveGroups();
|
||||
}
|
||||
|
||||
private void setupPlayerAvatars(Player player) {
|
||||
private void setupPlayerAvatars(@NotNull Player player) {
|
||||
// Clear entities from old team
|
||||
player.getTeamManager().getActiveTeam().clear();
|
||||
|
||||
// Add new entities for player
|
||||
TeamInfo teamInfo = player.getTeamManager().getCurrentTeamInfo();
|
||||
for (int avatarId : teamInfo.getAvatars()) {
|
||||
Avatar avatar = player.getAvatars().getAvatarById(avatarId);
|
||||
if (avatar == null) {
|
||||
if (player.getTeamManager().isUseTrialTeam()) {
|
||||
avatar = player.getTeamManager().getTrialAvatars().get(avatarId);
|
||||
}
|
||||
if (avatar == null) continue;
|
||||
}
|
||||
player.getTeamManager().getActiveTeam().add(new EntityAvatar(player.getScene(), avatar));
|
||||
}
|
||||
|
||||
// Limit character index in case its out of bounds
|
||||
if (player.getTeamManager().getCurrentCharacterIndex() >= player.getTeamManager().getActiveTeam().size() || player.getTeamManager().getCurrentCharacterIndex() < 0) {
|
||||
player.getTeamManager().setCurrentCharacterIndex(player.getTeamManager().getCurrentCharacterIndex() - 1);
|
||||
}
|
||||
List<EntityAvatar> activeTeam = player.getTeamManager().getActiveTeam();
|
||||
activeTeam.clear();
|
||||
Optional.ofNullable(player.getTeamManager().getCurrentTeamInfo())
|
||||
.ifPresent(info -> info.getAvatars().forEach(avatarId -> activeTeam.add(
|
||||
new EntityAvatar(player.getScene(), player.getAvatars().getAvatarById(avatarId))
|
||||
)));
|
||||
}
|
||||
|
||||
private synchronized void removePlayerAvatars(Player player) {
|
||||
var team = player.getTeamManager().getActiveTeam();
|
||||
// removeEntities(team, VisionType.VISION_TYPE_REMOVE); // List<SubType> isn't cool apparently :(
|
||||
team.forEach(e -> removeEntity(e, VisionType.VISION_TYPE_REMOVE));
|
||||
team.clear();
|
||||
private synchronized void removePlayerAvatars(@NotNull Player player) {
|
||||
removeEntities(player.getTeamManager().getActiveTeam(), VisionType.VISION_TYPE_MISS);
|
||||
}
|
||||
|
||||
public void spawnPlayer(Player player) {
|
||||
@ -321,9 +304,9 @@ public class Scene {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeEntities(List<GameEntity> entity, VisionType visionType) {
|
||||
public synchronized void removeEntities(List<? extends GameEntity> entity, VisionType visionType) {
|
||||
var toRemove = entity.stream()
|
||||
.filter(e -> e != null)
|
||||
.filter(Objects::nonNull)
|
||||
.map(this::removeEntityDirectly)
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
@ -363,6 +346,11 @@ public class Scene {
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
// if (target instanceof EntityMonster monsterTarget) {
|
||||
// monsterTarget.damage(result.getDamage(), result.getAttackerId(), attackType,
|
||||
// ElementReactionType.getTypeByValue(result.getAmplifyReactionType()));
|
||||
// return;
|
||||
// }
|
||||
target.damage(result.getDamage(), result.getAttackerId(), attackType);
|
||||
}
|
||||
|
||||
|
@ -340,7 +340,7 @@ public class World implements Iterable<Player> {
|
||||
// Update team of all players since max players has been changed - Probably not the best way to do it
|
||||
if (this.isMultiplayer()) {
|
||||
player.getTeamManager().getMpTeam().copyFrom(player.getTeamManager().getMpTeam(), player.getTeamManager().getMaxTeamSize());
|
||||
player.getTeamManager().updateTeamEntities(null);
|
||||
player.getTeamManager().updateTeamEntities(true);
|
||||
}
|
||||
|
||||
// Don't send packets if player is loading into the scene
|
||||
|
@ -3,12 +3,21 @@ package emu.grasscutter.server.packet.recv;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketAddCustomTeamRsp;
|
||||
import emu.grasscutter.server.packet.send.PacketCustomTeamListNotify;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@Opcodes(PacketOpcodes.AddCustomTeamReq)
|
||||
public class HandlerAddCustomTeamReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.getPlayer().getTeamManager().addNewCustomTeam();
|
||||
public void handle(@NotNull GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
boolean result = session.getPlayer().getTeamManager().addNewCustomTeam();
|
||||
// Send packets.
|
||||
if (result) {
|
||||
session.getPlayer().sendPacket(new PacketCustomTeamListNotify(session.getPlayer()));
|
||||
}
|
||||
session.getPlayer().sendPacket(new PacketAddCustomTeamRsp(result ? Retcode.RET_SUCC : Retcode.RET_FAIL));
|
||||
}
|
||||
}
|
||||
|
@ -5,15 +5,19 @@ import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AvatarDieAnimationEndReqOuterClass.AvatarDieAnimationEndReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketAvatarDieAnimationEndRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.AvatarDieAnimationEndReq)
|
||||
public class HandlerAvatarDieAnimationEndReq extends PacketHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AvatarDieAnimationEndReq req = AvatarDieAnimationEndReq.parseFrom(payload);
|
||||
|
||||
|
||||
// TODO There is also reborn pos being sent, which might be helpful
|
||||
session.getPlayer().getTeamManager().onAvatarDie(req.getDieGuid());
|
||||
// Response packet
|
||||
session.getPlayer().sendPacket(new PacketAvatarDieAnimationEndRsp(req.getDieGuid(), req.getSkillId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,15 +5,19 @@ import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChangeAvatarReqOuterClass.ChangeAvatarReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketChangeAvatarRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.ChangeAvatarReq)
|
||||
public class HandlerChangeAvatarReq extends PacketHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ChangeAvatarReq req = ChangeAvatarReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getTeamManager().changeAvatar(req.getGuid());
|
||||
|
||||
session.getPlayer().sendPacket(new PacketChangeAvatarRsp(
|
||||
session.getPlayer().getTeamManager().changeAvatar(req.getGuid()),
|
||||
req.getGuid()
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,16 +4,22 @@ import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChangeMpTeamAvatarReqOuterClass.ChangeMpTeamAvatarReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketChangeMpTeamAvatarRsp;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@Opcodes(PacketOpcodes.ChangeMpTeamAvatarReq)
|
||||
public class HandlerChangeMpTeamAvatarReq extends PacketHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
public void handle(@NotNull GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ChangeMpTeamAvatarReq req = ChangeMpTeamAvatarReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getTeamManager().setupMpTeam(req.getAvatarGuidListList());
|
||||
|
||||
boolean result = session.getPlayer().getTeamManager().setupMpTeam(req.getAvatarGuidListList(), req.getCurAvatarGuid());
|
||||
new PacketChangeMpTeamAvatarRsp(
|
||||
result ? Retcode.RET_SUCC_VALUE : Retcode.RET_FAIL_VALUE,
|
||||
req.getAvatarGuidListList(), req.getCurAvatarGuid());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,16 +4,23 @@ import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChangeTeamNameReqOuterClass.ChangeTeamNameReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketChangeTeamNameRsp;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@Opcodes(PacketOpcodes.ChangeTeamNameReq)
|
||||
public class HandlerChangeTeamNameReq extends PacketHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
public void handle(@NotNull GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ChangeTeamNameReq req = ChangeTeamNameReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getTeamManager().setTeamName(req.getTeamId(), req.getTeamName());
|
||||
|
||||
boolean result = session.getPlayer().getTeamManager().setTeamName(req.getTeamId(), req.getTeamName());
|
||||
|
||||
session.getPlayer().sendPacket(new PacketChangeTeamNameRsp(
|
||||
result ? Retcode.RET_SUCC_VALUE : Retcode.RET_FAIL_VALUE,
|
||||
req.getTeamId(), req.getTeamName()));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,16 +4,23 @@ import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChooseCurAvatarTeamReqOuterClass.ChooseCurAvatarTeamReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketChooseCurAvatarTeamRsp;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@Opcodes(PacketOpcodes.ChooseCurAvatarTeamReq)
|
||||
public class HandlerChooseCurAvatarTeamReq extends PacketHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
public void handle(@NotNull GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ChooseCurAvatarTeamReq req = ChooseCurAvatarTeamReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getTeamManager().setCurrentTeam(req.getTeamId());
|
||||
|
||||
boolean result = session.getPlayer().getTeamManager().setCurrentTeam(req.getTeamId());
|
||||
session.getPlayer().sendPacket(new PacketChooseCurAvatarTeamRsp(
|
||||
result ? Retcode.RET_SUCC_VALUE : Retcode.RET_FAIL_VALUE,
|
||||
req.getTeamId()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,9 +9,11 @@ import emu.grasscutter.server.packet.send.PacketEnterSceneReadyRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.EnterSceneReadyReq)
|
||||
public class HandlerEnterSceneReadyReq extends PacketHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) {
|
||||
// This is how official behaves, don't remove, not sure if tower team also behaves the same way
|
||||
session.getPlayer().removeTrialAvatarForDungeon();
|
||||
session.send(new PacketEnterScenePeerNotify(session.getPlayer()));
|
||||
session.send(new PacketEnterSceneReadyRsp(session.getPlayer()));
|
||||
}
|
||||
|
@ -4,13 +4,25 @@ import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketCustomTeamListNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketRemoveCustomTeamRsp;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@Opcodes(PacketOpcodes.RemoveCustomTeamReq)
|
||||
public class HandlerRemoveCustomTeamReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
public void handle(@NotNull GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
RemoveCustomTeamReq req = RemoveCustomTeamReq.parseFrom(payload);
|
||||
session.getPlayer().getTeamManager().removeCustomTeam(req.getId());
|
||||
boolean result = session.getPlayer().getTeamManager().removeCustomTeam(req.getId());
|
||||
|
||||
// Send packets.
|
||||
if (result) {
|
||||
session.getPlayer().sendPacket(new PacketCustomTeamListNotify(session.getPlayer()));
|
||||
}
|
||||
session.getPlayer().sendPacket(new PacketRemoveCustomTeamRsp(
|
||||
result ? Retcode.RET_SUCC : Retcode.RET_FAIL,
|
||||
req.getId()));
|
||||
}
|
||||
}
|
||||
|
@ -2,18 +2,26 @@ package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||
import emu.grasscutter.net.proto.SetUpAvatarTeamReqOuterClass.SetUpAvatarTeamReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketSetUpAvatarTeamRsp;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@Opcodes(PacketOpcodes.SetUpAvatarTeamReq)
|
||||
public class HandlerSetUpAvatarTeamReq extends PacketHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
public void handle(@NotNull GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
SetUpAvatarTeamReq req = SetUpAvatarTeamReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getTeamManager().setupAvatarTeam(req.getTeamId(), req.getAvatarTeamGuidListList());
|
||||
|
||||
boolean result = session.getPlayer().getTeamManager().setupAvatarTeam(
|
||||
req.getTeamId(), req.getAvatarTeamGuidListList(), req.getCurAvatarGuid());
|
||||
|
||||
session.getPlayer().sendPacket(new PacketSetUpAvatarTeamRsp(
|
||||
req.getTeamId(), req.getCurAvatarGuid(), req.getAvatarTeamGuidListList(),
|
||||
result ? Retcode.RET_SUCC_VALUE : Retcode.RET_FAIL_VALUE));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,18 +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.ChangeAvatarRspOuterClass.ChangeAvatarRsp;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass;
|
||||
|
||||
public class PacketChangeAvatarRsp extends BasePacket {
|
||||
|
||||
public PacketChangeAvatarRsp(long guid) {
|
||||
|
||||
public PacketChangeAvatarRsp(int ret, long guid) {
|
||||
super(PacketOpcodes.ChangeAvatarRsp);
|
||||
|
||||
ChangeAvatarRsp p = ChangeAvatarRsp.newBuilder()
|
||||
.setRetcode(RetcodeOuterClass.Retcode.RET_SUCC_VALUE)
|
||||
.setRetcode(ret)
|
||||
.setCurGuid(guid)
|
||||
.build();
|
||||
|
||||
|
||||
this.setData(p);
|
||||
}
|
||||
}
|
||||
|
@ -6,18 +6,31 @@ import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChangeMpTeamAvatarRspOuterClass.ChangeMpTeamAvatarRsp;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PacketChangeMpTeamAvatarRsp extends BasePacket {
|
||||
|
||||
|
||||
public PacketChangeMpTeamAvatarRsp(Player player, TeamInfo teamInfo) {
|
||||
super(PacketOpcodes.ChangeMpTeamAvatarRsp);
|
||||
|
||||
|
||||
ChangeMpTeamAvatarRsp.Builder proto = ChangeMpTeamAvatarRsp.newBuilder()
|
||||
.setCurAvatarGuid(player.getTeamManager().getCurrentCharacterGuid());
|
||||
|
||||
|
||||
for (int avatarId : teamInfo.getAvatars()) {
|
||||
proto.addAvatarGuidList(player.getAvatars().getAvatarById(avatarId).getGuid());
|
||||
}
|
||||
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public PacketChangeMpTeamAvatarRsp(int retVal, List<Long> guidList, long guid) {
|
||||
super(PacketOpcodes.ChangeMpTeamAvatarRsp);
|
||||
|
||||
ChangeMpTeamAvatarRsp.Builder proto = ChangeMpTeamAvatarRsp.newBuilder()
|
||||
.setCurAvatarGuid(guid)
|
||||
.addAllAvatarGuidList(guidList)
|
||||
.setRetcode(retVal);
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
|
@ -5,15 +5,16 @@ import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChangeTeamNameRspOuterClass.ChangeTeamNameRsp;
|
||||
|
||||
public class PacketChangeTeamNameRsp extends BasePacket {
|
||||
|
||||
public PacketChangeTeamNameRsp(int teamId, String teamName) {
|
||||
|
||||
public PacketChangeTeamNameRsp(int ret, int teamId, String teamName) {
|
||||
super(PacketOpcodes.ChangeTeamNameRsp);
|
||||
|
||||
ChangeTeamNameRsp proto = ChangeTeamNameRsp.newBuilder()
|
||||
.setTeamId(teamId)
|
||||
.setTeamName(teamName)
|
||||
.setRetcode(ret)
|
||||
.build();
|
||||
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
|
@ -5,14 +5,15 @@ import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.ChooseCurAvatarTeamRspOuterClass.ChooseCurAvatarTeamRsp;
|
||||
|
||||
public class PacketChooseCurAvatarTeamRsp extends BasePacket {
|
||||
|
||||
public PacketChooseCurAvatarTeamRsp(int teamId) {
|
||||
|
||||
public PacketChooseCurAvatarTeamRsp(int retVal, int teamId) {
|
||||
super(PacketOpcodes.ChooseCurAvatarTeamRsp);
|
||||
|
||||
ChooseCurAvatarTeamRsp proto = ChooseCurAvatarTeamRsp.newBuilder()
|
||||
.setCurTeamId(teamId)
|
||||
.build();
|
||||
|
||||
.setCurTeamId(teamId)
|
||||
.setRetcode(retVal)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,21 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.player.TeamInfo;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SetUpAvatarTeamRspOuterClass.SetUpAvatarTeamRsp;
|
||||
|
||||
public class PacketSetUpAvatarTeamRsp extends BasePacket {
|
||||
|
||||
public PacketSetUpAvatarTeamRsp(Player player, int teamId, TeamInfo teamInfo) {
|
||||
super(PacketOpcodes.SetUpAvatarTeamRsp);
|
||||
import java.util.Collection;
|
||||
|
||||
SetUpAvatarTeamRsp.Builder proto = SetUpAvatarTeamRsp.newBuilder()
|
||||
.setTeamId(teamId)
|
||||
.setCurAvatarGuid(player.getTeamManager().getCurrentCharacterGuid());
|
||||
|
||||
for (int avatarId : teamInfo.getAvatars()) {
|
||||
proto.addAvatarTeamGuidList(player.getAvatars().getAvatarById(avatarId).getGuid());
|
||||
}
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
public class PacketSetUpAvatarTeamRsp extends BasePacket {
|
||||
public PacketSetUpAvatarTeamRsp(int teamId, long guid, Collection<Long> guidList, int retVal) {
|
||||
super(PacketOpcodes.SetUpAvatarTeamRsp);
|
||||
|
||||
SetUpAvatarTeamRsp.Builder proto = SetUpAvatarTeamRsp.newBuilder()
|
||||
.setTeamId(teamId)
|
||||
.setCurAvatarGuid(guid)
|
||||
.addAllAvatarTeamGuidList(guidList)
|
||||
.setRetcode(retVal);
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user