[Breaking] Rewrite parts of the avatar system to allow the main character to change paths properly

This commit is contained in:
Melledy
2023-09-28 04:38:33 -07:00
parent b9fcebb401
commit 4a513890c5
15 changed files with 334 additions and 47 deletions

View File

@@ -12,6 +12,7 @@ public class GameConstants {
// Game // Game
public static final int HOME_PLANE_ID = 10000; public static final int HOME_PLANE_ID = 10000;
public static final String DEFAULT_NAME = "Trailblazer"; public static final String DEFAULT_NAME = "Trailblazer";
public static final int TRAILBLAZER_AVATAR_ID = 8001;
public static final int MAX_TRAILBLAZER_LEVEL = 70; public static final int MAX_TRAILBLAZER_LEVEL = 70;
public static final int MAX_STAMINA = 240; public static final int MAX_STAMINA = 240;
public static final int MAX_AVATARS_IN_TEAM = 4; public static final int MAX_AVATARS_IN_TEAM = 4;

View File

@@ -24,6 +24,7 @@ public class GameData {
@Getter private static Int2ObjectMap<NpcMonsterExcel> npcMonsterExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap<NpcMonsterExcel> npcMonsterExcelMap = new Int2ObjectOpenHashMap<>();
@Getter private static Int2ObjectMap<StageExcel> stageExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap<StageExcel> stageExcelMap = new Int2ObjectOpenHashMap<>();
@Getter private static Int2ObjectMap<MapEntranceExcel> mapEntranceExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap<MapEntranceExcel> mapEntranceExcelMap = new Int2ObjectOpenHashMap<>();
@Getter private static Int2ObjectMap<HeroExcel> heroExcelMap = new Int2ObjectOpenHashMap<>();
private static Int2ObjectMap<AvatarPromotionExcel> avatarPromotionExcelMap = new Int2ObjectOpenHashMap<>(); private static Int2ObjectMap<AvatarPromotionExcel> avatarPromotionExcelMap = new Int2ObjectOpenHashMap<>();
private static Int2ObjectMap<AvatarSkillTreeExcel> avatarSkillTreeExcelMap = new Int2ObjectOpenHashMap<>(); private static Int2ObjectMap<AvatarSkillTreeExcel> avatarSkillTreeExcelMap = new Int2ObjectOpenHashMap<>();

View File

@@ -0,0 +1,19 @@
package emu.lunarcore.data.excel;
import emu.lunarcore.data.GameResource;
import emu.lunarcore.data.ResourceType;
import emu.lunarcore.game.player.PlayerGender;
import lombok.Getter;
@Getter
@ResourceType(name = {"HeroConfig.json"})
public class HeroExcel extends GameResource {
private int HeroAvatarID;
private PlayerGender Gender;
@Override
public int getId() {
return HeroAvatarID;
}
}

View File

@@ -0,0 +1,18 @@
package emu.lunarcore.game.avatar;
import dev.morphia.annotations.Entity;
import lombok.Getter;
import lombok.Setter;
@Entity(useDiscriminator = false)
public class AvatarRank {
@Getter @Setter
private int value;
/**
* A helper class that contains information about an avatar's rank.
*/
public AvatarRank() {
}
}

View File

@@ -6,22 +6,24 @@ import java.util.stream.Stream;
import emu.lunarcore.LunarRail; import emu.lunarcore.LunarRail;
import emu.lunarcore.data.GameData; import emu.lunarcore.data.GameData;
import emu.lunarcore.data.excel.AvatarExcel; import emu.lunarcore.data.excel.AvatarExcel;
import emu.lunarcore.data.excel.HeroExcel;
import emu.lunarcore.game.player.BasePlayerManager; import emu.lunarcore.game.player.BasePlayerManager;
import emu.lunarcore.game.player.Player; import emu.lunarcore.game.player.Player;
import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify; import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import lombok.Getter;
@Getter
public class AvatarStorage extends BasePlayerManager implements Iterable<GameAvatar> { public class AvatarStorage extends BasePlayerManager implements Iterable<GameAvatar> {
private final Int2ObjectMap<GameAvatar> avatars; private final Int2ObjectMap<GameAvatar> avatars;
private final Int2ObjectMap<HeroPath> heroPaths;
public AvatarStorage(Player player) { public AvatarStorage(Player player) {
super(player); super(player);
this.avatars = new Int2ObjectOpenHashMap<>(); this.avatars = new Int2ObjectOpenHashMap<>();
} this.heroPaths = new Int2ObjectOpenHashMap<>();
public Int2ObjectMap<GameAvatar> getAvatars() {
return avatars;
} }
public int getAvatarCount() { public int getAvatarCount() {
@@ -57,8 +59,24 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<GameAva
return true; return true;
} }
public void recalcAvatarStats() { public HeroPath getHeroPathById(int id) {
//this.getAvatars().values().stream().forEach(GameAvatar::recalcStats); return getHeroPaths().get(id);
}
/**
* Updates hero types for players. Will create hero types if they dont exist already.
*/
public void setupHeroPaths() {
for (HeroExcel heroExcel : GameData.getHeroExcelMap().values()) {
if (getHeroPaths().containsKey(heroExcel.getId())) continue;
AvatarExcel excel = GameData.getAvatarExcelMap().get(heroExcel.getId());
if (excel == null) continue;
HeroPath path = new HeroPath(getPlayer(), excel);
path.save();
getHeroPaths().put(path.getId(), path);
}
} }
@Override @Override
@@ -69,6 +87,22 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<GameAva
// Database // Database
public void loadFromDatabase() { public void loadFromDatabase() {
// Load hero paths
Stream<HeroPath> heroStream = LunarRail.getGameDatabase().getObjects(HeroPath.class, "ownerUid", this.getPlayer().getUid());
heroStream.forEach(heroPath -> {
// Load avatar excel data
AvatarExcel excel = GameData.getAvatarExcelMap().get(heroPath.getId());
if (excel == null) {
return;
}
heroPath.setExcel(excel);
this.heroPaths.put(heroPath.getId(), heroPath);
});
// Load avatars
Stream<GameAvatar> stream = LunarRail.getGameDatabase().getObjects(GameAvatar.class, "ownerUid", this.getPlayer().getUid()); Stream<GameAvatar> stream = LunarRail.getGameDatabase().getObjects(GameAvatar.class, "ownerUid", this.getPlayer().getUid());
stream.forEach(avatar -> { stream.forEach(avatar -> {
@@ -77,14 +111,21 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<GameAva
return; return;
} }
// Load avatar excel data // Set hero path
AvatarExcel excel = GameData.getAvatarExcelMap().get(avatar.getAvatarId()); if (avatar.isHero()) {
if (excel == null) { avatar.setHeroPath(getPlayer().getCurHeroPath());
return; } else {
// Load avatar excel data
AvatarExcel excel = GameData.getAvatarExcelMap().get(avatar.getAvatarId());
if (excel == null) {
return;
}
// Set ownerships
avatar.setExcel(excel);
} }
// Set ownerships // Set ownership
avatar.setExcel(excel);
avatar.setOwner(getPlayer()); avatar.setOwner(getPlayer());
// Add to avatar storage // Add to avatar storage

View File

@@ -42,25 +42,26 @@ public class GameAvatar implements GameEntity {
@Indexed @Getter private int ownerUid; // Uid of player that this avatar belongs to @Indexed @Getter private int ownerUid; // Uid of player that this avatar belongs to
private transient Player owner; private transient Player owner;
private transient AvatarExcel excel; @Setter private transient AvatarExcel excel;
private int avatarId; // Id of avatar private int avatarId; // Id of avatar
@Setter private int level; @Setter private int level;
@Setter private int exp; @Setter private int exp;
@Setter private int promotion; @Setter private int promotion;
@Setter private int rank; // Eidolons private AvatarRank rank; // Eidolons - We use an object for this so we can sync it easily with hero paths
private Map<Integer, Integer> skills;
private int currentHp; private int currentHp;
private int currentSp; private int currentSp;
private Map<Integer, Integer> skills;
private transient int entityId; private transient int entityId;
private transient Int2ObjectMap<GameItem> equips; private transient Int2ObjectMap<GameItem> equips;
private transient HeroPath heroPath;
@Deprecated // Morphia only @Deprecated // Morphia only
public GameAvatar() { public GameAvatar() {
this.equips = new Int2ObjectOpenHashMap<>(); this.equips = new Int2ObjectOpenHashMap<>();
this.level = 1;
this.currentHp = 10000; this.currentHp = 10000;
this.currentSp = 0; this.currentSp = 0;
} }
@@ -74,16 +75,21 @@ public class GameAvatar implements GameEntity {
this(); this();
this.excel = excel; this.excel = excel;
this.avatarId = excel.getId(); this.avatarId = excel.getId();
this.level = 1;
// Set default skills // Set defaults
this.rank = new AvatarRank();
this.skills = new HashMap<>(); this.skills = new HashMap<>();
// Add skills
for (var skillTree : excel.getDefaultSkillTrees()) { for (var skillTree : excel.getDefaultSkillTrees()) {
this.skills.put(skillTree.getPointID(), skillTree.getLevel()); this.skills.put(skillTree.getPointID(), skillTree.getLevel());
} }
}
// Set stats public GameAvatar(HeroPath path) {
this.currentHp = 10000; this();
this.avatarId = GameConstants.TRAILBLAZER_AVATAR_ID;
this.setHeroPath(path);
} }
public void setOwner(Player player) { public void setOwner(Player player) {
@@ -91,15 +97,15 @@ public class GameAvatar implements GameEntity {
this.ownerUid = player.getUid(); this.ownerUid = player.getUid();
} }
public void setExcel(AvatarExcel excel) {
this.excel = excel;
}
@Override @Override
public void setEntityId(int entityId) { public void setEntityId(int entityId) {
this.entityId = entityId; this.entityId = entityId;
} }
public boolean isHero() {
return GameData.getHeroExcelMap().containsKey(this.getAvatarId());
}
public int getMaxSp() { public int getMaxSp() {
return this.getExcel().getMaxSp(); return this.getExcel().getMaxSp();
} }
@@ -112,6 +118,27 @@ public class GameAvatar implements GameEntity {
this.currentSp = Math.max(Math.min(amount, getMaxSp()), 0); this.currentSp = Math.max(Math.min(amount, getMaxSp()), 0);
} }
public int getRank() {
return this.rank.getValue();
}
public void setRank(int rank) {
this.rank.setValue(rank);
}
public void setHeroPath(HeroPath heroPath) {
// Clear prev set hero path from avatar
if (this.getHeroPath() != null) {
this.getHeroPath().setAvatar(null);
}
this.rank = heroPath.getRank();
this.skills = heroPath.getSkills();
this.excel = heroPath.getExcel();
this.heroPath = heroPath;
this.heroPath.setAvatar(this);
}
// Equips // Equips
public GameItem getEquipBySlot(int slot) { public GameItem getEquipBySlot(int slot) {
@@ -271,6 +298,11 @@ public class GameAvatar implements GameEntity {
// Database // Database
public void save() { public void save() {
// Save avatar
LunarRail.getGameDatabase().save(this); LunarRail.getGameDatabase().save(this);
// Save hero path
if (this.getHeroPath() != null) {
this.getHeroPath().save();
}
} }
} }

View File

@@ -0,0 +1,67 @@
package emu.lunarcore.game.avatar;
import java.util.HashMap;
import java.util.Map;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import dev.morphia.annotations.Indexed;
import emu.lunarcore.LunarRail;
import emu.lunarcore.data.excel.AvatarExcel;
import emu.lunarcore.game.player.Player;
import emu.lunarcore.proto.AvatarSkillTreeOuterClass.AvatarSkillTree;
import emu.lunarcore.proto.HeroBasicTypeInfoOuterClass.HeroBasicTypeInfo;
import lombok.Getter;
import lombok.Setter;
@Getter
@Entity(value = "heroPaths", useDiscriminator = false)
public class HeroPath {
@Id
private int id; // Equivalent to HeroBaseType
@Indexed
private int ownerUid;
private AvatarRank rank;
private Map<Integer, Integer> skills;
@Setter private transient GameAvatar avatar;
@Setter private transient AvatarExcel excel;
@Deprecated // Morphia only!
public HeroPath() {
}
public HeroPath(Player player, AvatarExcel excel) {
// Set excel avatar id as id
this.id = excel.getId();
this.ownerUid = player.getUid();
this.excel = excel;
// Set defaults
this.rank = new AvatarRank();
this.skills = new HashMap<>();
// Add skills
for (var skillTree : excel.getDefaultSkillTrees()) {
this.skills.put(skillTree.getPointID(), skillTree.getLevel());
}
}
public HeroBasicTypeInfo toProto() {
var proto = HeroBasicTypeInfo.newInstance()
.setBasicTypeValue(this.getId())
.setRank(this.getRank().getValue());
for (var skill : getSkills().entrySet()) {
proto.addSkillTreeList(AvatarSkillTree.newInstance().setPointId(skill.getKey()).setLevel(skill.getValue()));
}
return proto;
}
public void save() {
LunarRail.getGameDatabase().save(this);
}
}

View File

@@ -14,6 +14,7 @@ import emu.lunarcore.data.excel.MapEntranceExcel;
import emu.lunarcore.game.account.Account; import emu.lunarcore.game.account.Account;
import emu.lunarcore.game.avatar.AvatarStorage; import emu.lunarcore.game.avatar.AvatarStorage;
import emu.lunarcore.game.avatar.GameAvatar; import emu.lunarcore.game.avatar.GameAvatar;
import emu.lunarcore.game.avatar.HeroPath;
import emu.lunarcore.game.battle.Battle; import emu.lunarcore.game.battle.Battle;
import emu.lunarcore.game.gacha.PlayerGachaInfo; import emu.lunarcore.game.gacha.PlayerGachaInfo;
import emu.lunarcore.game.inventory.Inventory; import emu.lunarcore.game.inventory.Inventory;
@@ -26,6 +27,7 @@ import emu.lunarcore.server.packet.SessionState;
import emu.lunarcore.server.packet.send.PacketEnterSceneByServerScNotify; import emu.lunarcore.server.packet.send.PacketEnterSceneByServerScNotify;
import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify; import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify;
import emu.lunarcore.server.packet.send.PacketRevcMsgScNotify; import emu.lunarcore.server.packet.send.PacketRevcMsgScNotify;
import emu.lunarcore.server.packet.send.PacketSetHeroBasicTypeScRsp;
import emu.lunarcore.util.Position; import emu.lunarcore.util.Position;
import lombok.Getter; import lombok.Getter;
@@ -39,7 +41,9 @@ public class Player {
@Indexed private String accountUid; @Indexed private String accountUid;
private String name; private String name;
private String signature; private String signature;
private PlayerGender gender;
private int birthday; private int birthday;
private int curBasicType;
private int level; private int level;
private int exp; private int exp;
@@ -66,6 +70,8 @@ public class Player {
@Deprecated // Morphia only @Deprecated // Morphia only
public Player() { public Player() {
this.curBasicType = 8001;
this.gender = PlayerGender.GENDER_MAN;
this.avatars = new AvatarStorage(this); this.avatars = new AvatarStorage(this);
this.inventory = new Inventory(this); this.inventory = new Inventory(this);
} }
@@ -90,9 +96,12 @@ public class Player {
// Setup uid // Setup uid
this.initUid(); this.initUid();
// Setup hero paths
this.getAvatars().setupHeroPaths();
// Give us a starter character. // Give us a starter character.
// TODO script tutorial // TODO script tutorial
GameAvatar avatar = new GameAvatar(8001); GameAvatar avatar = new GameAvatar(this.getCurHeroPath());
this.getAvatars().addAvatar(avatar); this.getAvatars().addAvatar(avatar);
this.getLineupManager().getCurrentLineup().getAvatars().add(8001); this.getLineupManager().getCurrentLineup().getAvatars().add(8001);
@@ -147,6 +156,11 @@ public class Player {
} }
public GameAvatar getAvatarById(int avatarId) { public GameAvatar getAvatarById(int avatarId) {
// Check if we are trying to retrieve the hero character
if (GameData.getHeroExcelMap().containsKey(avatarId)) {
avatarId = GameConstants.TRAILBLAZER_AVATAR_ID;
}
return getAvatars().getAvatarById(avatarId); return getAvatars().getAvatarById(avatarId);
} }
@@ -209,6 +223,22 @@ public class Player {
return this.exp - GameData.getPlayerExpRequired(this.level); return this.exp - GameData.getPlayerExpRequired(this.level);
} }
public HeroPath getCurHeroPath() {
return this.getAvatars().getHeroPathById(this.getCurBasicType());
}
public void setHeroBasicType(int heroType) {
HeroPath path = this.getAvatars().getHeroPathById(heroType);
if (path == null) return;
GameAvatar mainCharacter = this.getAvatarById(GameConstants.TRAILBLAZER_AVATAR_ID);
if (mainCharacter == null) return;
// Set new hero and cur basic type
mainCharacter.setHeroPath(path);
this.curBasicType = heroType;
}
public boolean isInBattle() { public boolean isInBattle() {
return this.battle != null; return this.battle != null;
} }
@@ -294,10 +324,10 @@ public class Player {
// Load avatars and inventory first // Load avatars and inventory first
this.getAvatars().loadFromDatabase(); this.getAvatars().loadFromDatabase();
this.getInventory().loadFromDatabase(); this.getInventory().loadFromDatabase();
this.getAvatars().recalcAvatarStats(); // Recalc stats after items have loaded for the avatars
// Load Etc // Load Etc
this.getLineupManager().validate(this); this.getLineupManager().validate(this);
this.getAvatars().setupHeroPaths();
// Enter scene (should happen after everything else loads) // Enter scene (should happen after everything else loads)
this.loadScene(planeId, floorId, entryId); this.loadScene(planeId, floorId, entryId);
@@ -316,5 +346,4 @@ public class Player {
return proto; return proto;
} }
} }

View File

@@ -0,0 +1,21 @@
package emu.lunarcore.game.player;
import dev.morphia.annotations.Entity;
import lombok.Getter;
@Entity(useDiscriminator = false)
public enum PlayerGender {
GENDER_NONE (0),
GENDER_MAN (1),
GENDER_WOMAN (2);
@Getter
private final int val;
/**
* Official name: GenderType
*/
private PlayerGender(int val) {
this.val = val;
}
}

View File

@@ -143,7 +143,7 @@ public class InventoryService extends BaseGameService {
int nextLevel = avatar.getSkills().getOrDefault(pointId, 0) + 1; int nextLevel = avatar.getSkills().getOrDefault(pointId, 0) + 1;
AvatarSkillTreeExcel skillTree = GameData.getAvatarSkillTreeExcel(pointId, nextLevel); AvatarSkillTreeExcel skillTree = GameData.getAvatarSkillTreeExcel(pointId, nextLevel);
if (skillTree == null || skillTree.getAvatarID() != avatarId) return; if (skillTree == null || skillTree.getAvatarID() != avatar.getExcel().getAvatarID()) return;
// Verify items // Verify items
for (ItemParam param : skillTree.getMaterialList()) { for (ItemParam param : skillTree.getMaterialList()) {
@@ -171,7 +171,12 @@ public class InventoryService extends BaseGameService {
player.save(); player.save();
// Send packets // Send packets
player.sendPacket(new PacketPlayerSyncScNotify(avatar)); if (avatar.getHeroPath() != null) {
player.sendPacket(new PacketPlayerSyncScNotify(avatar.getHeroPath()));
} else {
player.sendPacket(new PacketPlayerSyncScNotify(avatar));
}
player.sendPacket(new PacketUnlockSkilltreeScRsp(avatarId, pointId, nextLevel)); player.sendPacket(new PacketUnlockSkilltreeScRsp(avatarId, pointId, nextLevel));
} }
@@ -200,7 +205,12 @@ public class InventoryService extends BaseGameService {
avatar.save(); avatar.save();
// Send packets // Send packets
player.sendPacket(new PacketPlayerSyncScNotify(avatar)); if (avatar.getHeroPath() != null) {
player.sendPacket(new PacketPlayerSyncScNotify(avatar.getHeroPath()));
} else {
player.sendPacket(new PacketPlayerSyncScNotify(avatar));
}
player.sendPacket(new BasePacket(CmdId.RankUpAvatarScRsp)); player.sendPacket(new BasePacket(CmdId.RankUpAvatarScRsp));
} }

View File

@@ -11,7 +11,7 @@ public class HandlerGetHeroBasicTypeInfoCsReq extends PacketHandler {
@Override @Override
public void handle(GameSession session, byte[] header, byte[] data) throws Exception { public void handle(GameSession session, byte[] header, byte[] data) throws Exception {
session.send(new PacketGetHeroBasicTypeInfoScRsp()); session.send(new PacketGetHeroBasicTypeInfoScRsp(session.getPlayer()));
} }
} }

View File

@@ -0,0 +1,21 @@
package emu.lunarcore.server.packet.recv;
import emu.lunarcore.proto.SetHeroBasicTypeCsReqOuterClass.SetHeroBasicTypeCsReq;
import emu.lunarcore.server.game.GameSession;
import emu.lunarcore.server.packet.CmdId;
import emu.lunarcore.server.packet.Opcodes;
import emu.lunarcore.server.packet.PacketHandler;
import emu.lunarcore.server.packet.send.PacketSetHeroBasicTypeScRsp;
@Opcodes(CmdId.SetHeroBasicTypeCsReq)
public class HandlerSetHeroBasicTypeCsReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] data) throws Exception {
var req = SetHeroBasicTypeCsReq.parseFrom(data);
session.getPlayer().setHeroBasicType(req.getBasicTypeValue());
session.send(new PacketSetHeroBasicTypeScRsp(session.getPlayer()));
}
}

View File

@@ -1,24 +1,23 @@
package emu.lunarcore.server.packet.send; package emu.lunarcore.server.packet.send;
import emu.lunarcore.proto.GenderOuterClass.Gender; import emu.lunarcore.game.avatar.HeroPath;
import emu.lunarcore.game.player.Player;
import emu.lunarcore.proto.GetHeroBasicTypeInfoScRspOuterClass.GetHeroBasicTypeInfoScRsp; import emu.lunarcore.proto.GetHeroBasicTypeInfoScRspOuterClass.GetHeroBasicTypeInfoScRsp;
import emu.lunarcore.proto.HeroBasicTypeInfoOuterClass.HeroBasicTypeInfo;
import emu.lunarcore.proto.HeroBasicTypeOuterClass.HeroBasicType;
import emu.lunarcore.server.packet.BasePacket; import emu.lunarcore.server.packet.BasePacket;
import emu.lunarcore.server.packet.CmdId; import emu.lunarcore.server.packet.CmdId;
public class PacketGetHeroBasicTypeInfoScRsp extends BasePacket { public class PacketGetHeroBasicTypeInfoScRsp extends BasePacket {
public PacketGetHeroBasicTypeInfoScRsp() { public PacketGetHeroBasicTypeInfoScRsp(Player player) {
super(CmdId.GetHeroBasicTypeInfoScRsp); super(CmdId.GetHeroBasicTypeInfoScRsp);
var heroBasicType = HeroBasicTypeInfo.newInstance()
.setBasicType(HeroBasicType.BoyWarrior);
var data = GetHeroBasicTypeInfoScRsp.newInstance() var data = GetHeroBasicTypeInfoScRsp.newInstance()
.setGender(Gender.GenderMan) .setGenderValue(player.getGender().getVal())
.setCurBasicType(HeroBasicType.BoyWarrior) .setCurBasicTypeValue(player.getCurBasicType());
.addBasicTypeInfoList(heroBasicType);
for (HeroPath path : player.getAvatars().getHeroPaths().values()) {
data.addAllBasicTypeInfoList(path.toProto());
}
this.setData(data); this.setData(data);
} }

View File

@@ -3,6 +3,7 @@ package emu.lunarcore.server.packet.send;
import java.util.Collection; import java.util.Collection;
import emu.lunarcore.game.avatar.GameAvatar; import emu.lunarcore.game.avatar.GameAvatar;
import emu.lunarcore.game.avatar.HeroPath;
import emu.lunarcore.game.inventory.GameItem; import emu.lunarcore.game.inventory.GameItem;
import emu.lunarcore.game.player.Player; import emu.lunarcore.game.player.Player;
import emu.lunarcore.proto.AvatarSyncOuterClass.AvatarSync; import emu.lunarcore.proto.AvatarSyncOuterClass.AvatarSync;
@@ -98,4 +99,13 @@ public class PacketPlayerSyncScNotify extends BasePacket {
} }
} }
} }
public PacketPlayerSyncScNotify(HeroPath heroPath) {
this();
var data = PlayerSyncScNotify.newInstance()
.addBasicTypeInfoList(heroPath.toProto());
this.setData(data);
}
} }

View File

@@ -0,0 +1,18 @@
package emu.lunarcore.server.packet.send;
import emu.lunarcore.game.player.Player;
import emu.lunarcore.proto.SetHeroBasicTypeScRspOuterClass.SetHeroBasicTypeScRsp;
import emu.lunarcore.server.packet.BasePacket;
import emu.lunarcore.server.packet.CmdId;
public class PacketSetHeroBasicTypeScRsp extends BasePacket {
public PacketSetHeroBasicTypeScRsp(Player player) {
super(CmdId.SetHeroBasicTypeScRsp);
var data = SetHeroBasicTypeScRsp.newInstance()
.setBasicTypeValue(player.getCurBasicType());
this.setData(data);
}
}