Implement assist and display avatars

Support list is not implemented yet
This commit is contained in:
Melledy
2024-05-17 07:36:55 -07:00
parent 8c89e688fd
commit f97bc85400
19 changed files with 4671 additions and 112 deletions

View File

@@ -135,13 +135,17 @@ public final class DatabaseManager {
return getDatastore().find(cls).filter(Filters.eq("_id", uid)).first();
}
public <T> T getObjectByField(Class<T> cls, String filter, String value) {
public <T> T getObjectByField(Class<T> cls, String filter, Object value) {
return getDatastore().find(cls).filter(Filters.eq(filter, value)).first();
}
public <T> T getObjectByField(Class<T> cls, String filter, long value) {
return getDatastore().find(cls).filter(Filters.eq(filter, value)).first();
}
public <T> Stream<T> getObjects(Class<T> cls, String filter, Object value) {
return getDatastore().find(cls).filter(Filters.eq(filter, value)).stream();
}
public <T> Stream<T> getObjects(Class<T> cls, String filter, long value) {
return getDatastore().find(cls).filter(Filters.eq(filter, value)).stream();

View File

@@ -3,27 +3,35 @@ package emu.lunarcore.game.avatar;
import java.util.Iterator;
import java.util.stream.Stream;
import org.bson.types.ObjectId;
import emu.lunarcore.GameConstants;
import emu.lunarcore.LunarCore;
import emu.lunarcore.data.GameData;
import emu.lunarcore.data.excel.AvatarExcel;
import emu.lunarcore.data.excel.HeroExcel;
import emu.lunarcore.game.inventory.GameItem;
import emu.lunarcore.game.player.BasePlayerManager;
import emu.lunarcore.game.player.Player;
import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import lombok.Getter;
@Getter
public class AvatarStorage extends BasePlayerManager implements Iterable<GameAvatar> {
private final Int2ObjectMap<GameAvatar> avatars;
private final Object2ObjectMap<ObjectId, GameAvatar> avatarObjectIdMap;
private final Int2ObjectMap<AvatarHeroPath> heroPaths;
public AvatarStorage(Player player) {
super(player);
this.avatars = new Int2ObjectOpenHashMap<>();
this.avatarObjectIdMap = new Object2ObjectOpenHashMap<>();
this.heroPaths = new Int2ObjectOpenHashMap<>();
}
@@ -32,11 +40,15 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<GameAva
}
public GameAvatar getAvatarById(int id) {
if (this.getHeroPaths().containsKey(id)) {
id = GameConstants.TRAILBLAZER_AVATAR_ID;
return getAvatars().get(id);
}
public GameAvatar getAvatarById(ObjectId id) {
if (id == null) {
return null;
}
return getAvatars().get(id);
return getAvatarObjectIdMap().get(id);
}
public boolean hasAvatar(int id) {
@@ -56,12 +68,15 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<GameAva
// Set owner first
avatar.setOwner(getPlayer());
// Save avatar
avatar.save();
// Put into avatar map
this.avatars.put(avatar.getAvatarId(), avatar);
this.avatarObjectIdMap.put(avatar.getId(), avatar);
// Save to database and send packet
avatar.save();
// Send packet
getPlayer().sendPacket(new PacketPlayerSyncScNotify(avatar));
// Add head icon
@@ -99,7 +114,16 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<GameAva
// Database
public void loadFromDatabase() {
// Load hero paths
// Load hero paths first (Important)
loadHeroPathsFromDatabase();
// Load avatars
Stream<GameAvatar> stream = LunarCore.getGameDatabase().getObjects(GameAvatar.class, "ownerUid", this.getPlayer().getUid());
stream.forEach(this::loadAvatar);
}
private void loadHeroPathsFromDatabase() {
// Get stream from database
Stream<AvatarHeroPath> heroStream = LunarCore.getGameDatabase().getObjects(AvatarHeroPath.class, "ownerUid", this.getPlayer().getUid());
heroStream.forEach(heroPath -> {
@@ -116,35 +140,59 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<GameAva
// Setup hero paths if they dont exist
this.validateHeroPaths();
}
public boolean loadAvatar(GameAvatar avatar) {
// Should never happen
if (avatar.getId() == null) {
return false;
}
// Load avatars
Stream<GameAvatar> stream = LunarCore.getGameDatabase().getObjects(GameAvatar.class, "ownerUid", this.getPlayer().getUid());
stream.forEach(avatar -> {
// Should never happen
if (avatar.getId() == null) {
return;
// Check avatar owner
if (avatar.getOwnerUid() != this.getPlayer().getUid()) {
return false;
}
// Set hero path
if (avatar.isHero()) {
avatar.setHeroPath(getPlayer().getCurHeroPath());
} else {
// Load avatar excel data
AvatarExcel excel = GameData.getAvatarExcelMap().get(avatar.getAvatarId());
if (excel == null) {
return false;
}
// Set hero path
if (avatar.isHero()) {
avatar.setHeroPath(getPlayer().getCurHeroPath());
} else {
// Load avatar excel data
AvatarExcel excel = GameData.getAvatarExcelMap().get(avatar.getAvatarId());
if (excel == null) {
return;
}
// Set ownerships
avatar.setExcel(excel);
}
// Set ownership
avatar.setOwner(getPlayer());
// Set ownerships
avatar.setExcel(excel);
}
// Set ownership
avatar.setOwner(getPlayer());
// Add to avatar storage
this.avatars.put(avatar.getAvatarId(), avatar);
});
// Add to avatar storage
this.avatars.put(avatar.getAvatarId(), avatar);
this.avatarObjectIdMap.put(avatar.getId(), avatar);
// Done
return true;
}
public GameAvatar loadAvatarByObjectId(ObjectId id) {
// Load hero paths first
if (this.getHeroPaths().size() == 0) {
this.loadHeroPathsFromDatabase();
}
// Load avatar
GameAvatar avatar = LunarCore.getGameDatabase().getObjectByField(GameAvatar.class, "_id", id);
if (this.loadAvatar(avatar)) {
// Load items
var stream = LunarCore.getGameDatabase().getObjects(GameItem.class, "equipAvatarId", id);
stream.forEach(this.getPlayer().getInventory()::loadItem);
}
return avatar;
}
}

View File

@@ -16,12 +16,16 @@ import emu.lunarcore.game.player.Player;
import emu.lunarcore.game.player.lineup.PlayerLineup;
import emu.lunarcore.game.scene.Scene;
import emu.lunarcore.game.scene.entity.GameEntity;
import emu.lunarcore.proto.AssistSimpleInfoOuterClass.AssistSimpleInfo;
import emu.lunarcore.proto.AvatarOuterClass.Avatar;
import emu.lunarcore.proto.AvatarSkillTreeOuterClass.AvatarSkillTree;
import emu.lunarcore.proto.AvatarTypeOuterClass.AvatarType;
import emu.lunarcore.proto.BattleAvatarOuterClass.BattleAvatar;
import emu.lunarcore.proto.BattleEquipmentOuterClass.BattleEquipment;
import emu.lunarcore.proto.BattleRelicOuterClass.BattleRelic;
import emu.lunarcore.proto.DisplayAvatarDetailInfoOuterClass.DisplayAvatarDetailInfo;
import emu.lunarcore.proto.DisplayEquipmentInfoOuterClass.DisplayEquipmentInfo;
import emu.lunarcore.proto.DisplayRelicInfoOuterClass.DisplayRelicInfo;
import emu.lunarcore.proto.EquipRelicOuterClass.EquipRelic;
import emu.lunarcore.proto.LineupAvatarOuterClass.LineupAvatar;
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
@@ -237,7 +241,7 @@ public class GameAvatar implements GameEntity {
if (slot == 0) return false;
// Check if other avatars have this item equipped
GameAvatar otherAvatar = getOwner().getAvatarById(item.getEquipAvatar());
GameAvatar otherAvatar = getOwner().getAvatarById(item.getEquipAvatarId());
if (otherAvatar != null) {
// Unequip this item from the other avatar
if (otherAvatar.unequipItem(slot) != null) {
@@ -260,7 +264,7 @@ public class GameAvatar implements GameEntity {
getEquips().put(slot, item);
// Save equip if equipped avatar was changed
if (item.setEquipAvatar(this.getAvatarId())) {
if (item.setEquipAvatar(this)) {
item.save();
}
@@ -274,7 +278,7 @@ public class GameAvatar implements GameEntity {
GameItem item = getEquips().remove(slot);
if (item != null) {
item.setEquipAvatar(0);
item.setEquipAvatar(null);
item.save();
return item;
}
@@ -385,6 +389,61 @@ public class GameAvatar implements GameEntity {
return proto;
}
public DisplayAvatarDetailInfo toDisplayAvatarProto() {
var proto = DisplayAvatarDetailInfo.newInstance()
.setAvatarId(this.getExcel().getAvatarID())
.setLevel(this.getLevel())
.setExp(this.getExp())
.setPromotion(this.getPromotion())
.setRank(this.getRank());
// Skills
for (var skill : getSkills().entrySet()) {
proto.addSkilltreeList(AvatarSkillTree.newInstance().setPointId(skill.getKey()).setLevel(skill.getValue()));
}
// Build equips
for (var equip : this.getEquips().values()) {
if (equip.getItemMainType() == ItemMainType.Relic) {
// Build display relic proto
var relic = DisplayRelicInfo.newInstance()
.setTid(equip.getItemId())
.setLevel(equip.getLevel())
.setExp(equip.getExp())
.setSlot(equip.getEquipSlot())
.setMainAffixId(equip.getMainAffix());
if (equip.getSubAffixes() != null) {
for (var subAffix : equip.getSubAffixes()) {
relic.addSubAffixList(subAffix.toProto());
}
}
proto.addRelicList(relic);
} else if (equip.getItemMainType() == ItemMainType.Equipment) {
// Build display equipment proto
var equipment = DisplayEquipmentInfo.newInstance()
.setTid(equip.getItemId())
.setLevel(equip.getLevel())
.setExp(equip.getExp())
.setPromotion(equip.getPromotion())
.setRank(equip.getRank());
proto.setEquipment(equipment);
}
}
return proto;
}
public AssistSimpleInfo toAssistSimpleProto() {
var proto = AssistSimpleInfo.newInstance()
.setAvatarId(this.getAvatarId())
.setLevel(this.getLevel());
return proto;
}
// Database
public void save() {

View File

@@ -15,6 +15,7 @@ import emu.lunarcore.data.GameDepot;
import emu.lunarcore.data.excel.ItemExcel;
import emu.lunarcore.data.excel.RelicMainAffixExcel;
import emu.lunarcore.data.excel.RelicSubAffixExcel;
import emu.lunarcore.game.avatar.GameAvatar;
import emu.lunarcore.game.enums.AvatarPropertyType;
import emu.lunarcore.game.enums.ItemMainType;
import emu.lunarcore.game.player.Player;
@@ -54,6 +55,7 @@ public class GameItem {
private List<GameItemSubAffix> subAffixes;
private int equipAvatar;
@Indexed private ObjectId equipAvatarId;
@Deprecated
public GameItem() {
@@ -132,7 +134,7 @@ public class GameItem {
}
public boolean isEquipped() {
return this.getEquipAvatar() > 0;
return this.getEquipAvatarId() != null;
}
public boolean isDestroyable() {
@@ -148,14 +150,20 @@ public class GameItem {
return false;
}
public boolean setEquipAvatar(int newEquipAvatar) {
if (this.equipAvatar != newEquipAvatar) {
this.equipAvatar = newEquipAvatar;
public boolean setEquipAvatar(GameAvatar avatar) {
if (avatar == null && this.isEquipped()) {
this.equipAvatarId = null;
this.equipAvatar = 0;
return true;
} else if (this.equipAvatarId != avatar.getId()) {
this.equipAvatarId = avatar.getId();
this.equipAvatar = 0;
return true;
}
return false;
}
// Sub affixes
public void resetSubAffixes() {

View File

@@ -560,44 +560,63 @@ public class Inventory extends BasePlayerManager {
public void loadFromDatabase() {
Stream<GameItem> stream = LunarCore.getGameDatabase().getObjects(GameItem.class, "ownerUid", this.getPlayer().getUid());
stream.forEach(this::loadItem);
}
public boolean loadItem(GameItem item) {
// Should never happen
if (item.getId() == null) {
return false;
}
// Check item owner
if (item.getOwnerUid() != this.getPlayer().getUid()) {
return false;
}
stream.forEach(item -> {
// Should never happen
if (item.getId() == null) {
return;
}
// Load item excel data
ItemExcel excel = GameData.getItemExcelMap().get(item.getItemId());
if (excel == null) {
// Delete item if it has no excel data
item.setCount(0);
item.save();
return false;
}
// Load item excel data
ItemExcel excel = GameData.getItemExcelMap().get(item.getItemId());
if (excel == null) {
// Delete item if it has no excel data
item.setCount(0);
// Set ownerships
item.setExcel(excel);
// Put in inventory
InventoryTab tab = getTabByItemType(item.getExcel().getItemMainType());
putItem(item, tab);
// Equip to a character if possible
if (item.isEquipped() || item.getEquipAvatar() > 0) {
GameAvatar avatar = null;
boolean hasEquipped = false;
if (item.getEquipAvatar() > 0) {
// Legacy equip handler
avatar = getPlayer().getAvatars().getAvatarById(item.getEquipAvatar());
item.setEquipAvatar(avatar);
item.save();
return;
} else {
avatar = getPlayer().getAvatars().getAvatarById(item.getEquipAvatarId());
}
// Set ownerships
item.setExcel(excel);
// Put in inventory
InventoryTab tab = getTabByItemType(item.getExcel().getItemMainType());
putItem(item, tab);
// Equip to a character if possible
if (item.isEquipped()) {
GameAvatar avatar = getPlayer().getAvatarById(item.getEquipAvatar());
boolean hasEquipped = false;
if (avatar != null) {
hasEquipped = avatar.equipItem(item);
}
if (!hasEquipped) {
// Unset equipped flag on item since we couldnt find an avatar to equip it to
item.setEquipAvatar(0);
item.save();
}
// Make sure the avatar that we equipped this item to actually exists
if (avatar != null) {
hasEquipped = avatar.equipItem(item);
}
});
// Unset equipped flag on item since we couldnt find an avatar to equip it to
if (!hasEquipped) {
item.setEquipAvatar(null);
item.save();
}
}
// Done
return true;
}
}

View File

@@ -1,5 +1,10 @@
package emu.lunarcore.game.player;
import java.util.ArrayList;
import java.util.List;
import org.bson.types.ObjectId;
import com.mongodb.client.model.Filters;
import dev.morphia.annotations.Entity;
@@ -48,6 +53,7 @@ import emu.lunarcore.game.scene.SceneBuff;
import emu.lunarcore.game.scene.entity.EntityProp;
import emu.lunarcore.game.scene.entity.GameEntity;
import emu.lunarcore.proto.BoardDataSyncOuterClass.BoardDataSync;
import emu.lunarcore.proto.DisplayAvatarOuterClass.DisplayAvatar;
import emu.lunarcore.proto.FriendOnlineStatusOuterClass.FriendOnlineStatus;
import emu.lunarcore.proto.HeadIconOuterClass.HeadIcon;
import emu.lunarcore.proto.PlatformTypeOuterClass.PlatformType;
@@ -67,6 +73,8 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import lombok.Getter;
import lombok.Setter;
import us.hebi.quickbuf.RepeatedInt;
import us.hebi.quickbuf.RepeatedMessage;
@Entity(value = "players", useDiscriminator = false)
@Getter
@@ -118,6 +126,8 @@ public class Player implements Tickable {
// Database persistent data
private LineupManager lineupManager;
private PlayerGachaInfo gachaInfo;
private List<ObjectId> assistAvatars;
private List<ObjectId> displayAvatars;
// Instances
@Setter private ChallengeInstance challengeInstance;
@@ -138,6 +148,8 @@ public class Player implements Tickable {
this.curBasicType = GameConstants.TRAILBLAZER_AVATAR_ID;
this.gender = PlayerGender.GENDER_MAN;
this.foodBuffs = new Int2ObjectOpenHashMap<>();
this.assistAvatars = new ArrayList<>();
this.displayAvatars = new ArrayList<>();
this.avatars = new AvatarStorage(this);
this.inventory = new Inventory(this);
@@ -324,6 +336,10 @@ public class Player implements Tickable {
return getAvatars().getAvatarById(avatarId);
}
public GameAvatar getAvatarById(ObjectId id) {
return getAvatars().getAvatarById(id);
}
public boolean setHeadIcon(int id) {
if (this.getUnlocks().getHeadIcons().contains(id)) {
this.headIcon = id;
@@ -777,6 +793,54 @@ public class Player implements Tickable {
// Done, return success
return true;
}
public void setAssistAvatars(RepeatedInt avatars) {
// Check size
if (avatars.length() > 3) {
return;
}
// Clear
this.getAssistAvatars().clear();
// Parse list from proto
for (int id : avatars) {
GameAvatar avatar = this.getAvatarById(id);
if (avatar == null) continue;
this.getAssistAvatars().add(avatar.getId());
}
// Save player
this.save();
}
public void setDisplayAvatars(RepeatedMessage<DisplayAvatar> avatars) {
// Check size
if (avatars.length() > 5) {
return;
}
// Clear
this.getDisplayAvatars().clear();
// Parse list from proto
for (int i = 0; i < avatars.length(); i++) {
var info = avatars.get(i);
if (info.getAvatarId() > 0) {
GameAvatar avatar = this.getAvatarById(info.getAvatarId());
if (avatar == null) continue;
this.getDisplayAvatars().add(avatar.getId());
} else {
this.getDisplayAvatars().add(null);
}
}
// Save player
this.save();
}
public void sendMessage(String message) {
var msg = new ChatMessage(GameConstants.SERVER_CONSOLE_UID, this.getUid(), message);
@@ -933,11 +997,45 @@ public class Player implements Tickable {
.setLevel(this.getLevel())
.setWorldLevel(this.getWorldLevel())
.setPlatformType(PlatformType.PC)
.setShowDisplayAvatars(true)
.setHeadIcon(this.getHeadIcon());
proto.getMutableRecordInfo().getMutableCollectionInfo();
proto.getMutableDisplaySettings();
for (int i = 0; i < this.getAssistAvatars().size(); i++) {
ObjectId objectId = this.getAssistAvatars().get(i);
GameAvatar avatar = this.getAvatarById(objectId);
if (avatar == null && this.getSession() == null) {
avatar = this.getAvatars().loadAvatarByObjectId(objectId);
}
if (avatar == null) continue;
var info = avatar.toDisplayAvatarProto();
info.setPos(i);
proto.addAssistAvatarList(info);
}
for (int i = 0; i < this.getDisplayAvatars().size(); i++) {
ObjectId objectId = this.getDisplayAvatars().get(i);
if (objectId == null) continue;
GameAvatar avatar = this.getAvatarById(objectId);
if (avatar == null && this.getSession() == null) {
avatar = this.getAvatars().loadAvatarByObjectId(objectId);
}
if (avatar == null) continue;
var info = avatar.toDisplayAvatarProto();
info.setPos(i);
proto.addDisplayAvatarList(info);
}
return proto;
}
@@ -953,6 +1051,22 @@ public class Player implements Tickable {
.setLastActiveTime(this.getLastActiveTime())
.setHeadIcon(this.getHeadIcon());
for (int i = 0; i < this.getAssistAvatars().size(); i++) {
ObjectId objectId = this.getAssistAvatars().get(i);
GameAvatar avatar = this.getAvatarById(objectId);
if (avatar == null && this.getSession() == null) {
avatar = this.getAvatars().loadAvatarByObjectId(objectId);
}
if (avatar == null) continue;
var info = avatar.toAssistSimpleProto();
info.setPos(i);
proto.addAssistSimpleInfo(info);
}
return proto;
}

View File

@@ -0,0 +1,21 @@
package emu.lunarcore.server.packet.recv;
import emu.lunarcore.proto.SetAssistAvatarCsReqOuterClass.SetAssistAvatarCsReq;
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.PacketSetAssistAvatarScRsp;
@Opcodes(CmdId.SetAssistAvatarCsReq)
public class HandlerSetAssistAvatarCsReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] data) throws Exception {
var req = SetAssistAvatarCsReq.parseFrom(data);
session.getPlayer().setAssistAvatars(req.getAvatarIdList());
session.send(new PacketSetAssistAvatarScRsp(session.getPlayer()));
}
}

View File

@@ -0,0 +1,21 @@
package emu.lunarcore.server.packet.recv;
import emu.lunarcore.proto.SetDisplayAvatarCsReqOuterClass.SetDisplayAvatarCsReq;
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.PacketSetDisplayAvatarScRsp;
@Opcodes(CmdId.SetDisplayAvatarCsReq)
public class HandlerSetDisplayAvatarCsReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] data) throws Exception {
var req = SetDisplayAvatarCsReq.parseFrom(data);
session.getPlayer().setDisplayAvatars(req.getDisplayAvatarList());
session.send(new PacketSetDisplayAvatarScRsp(session.getPlayer()));
}
}

View File

@@ -1,6 +1,7 @@
package emu.lunarcore.server.packet.send;
import emu.lunarcore.game.player.Player;
import emu.lunarcore.proto.DisplayAvatarOuterClass.DisplayAvatar;
import emu.lunarcore.proto.GetPlayerBoardDataScRspOuterClass.GetPlayerBoardDataScRsp;
import emu.lunarcore.proto.HeadIconOuterClass.HeadIcon;
import emu.lunarcore.server.packet.BasePacket;
@@ -15,13 +16,37 @@ public class PacketGetPlayerBoardDataScRsp extends BasePacket {
.setCurrentHeadIconId(player.getHeadIcon())
.setSignature(player.getSignature());
// Set empty display avatars
// Create display avatar object
data.getMutableDisplayAvatarVec();
// Head icons, aka profile pictures
for (int id : player.getUnlocks().getHeadIcons()) {
data.addUnlockedHeadIconList(HeadIcon.newInstance().setId(id));
}
// Assist avatars
for (var objectId : player.getAssistAvatars()) {
var avatar = player.getAvatarById(objectId);
if (avatar == null) continue;
data.addDisplaySupportAvatarVec(avatar.getAvatarId());
}
// Display avatars
for (int i = 0; i < player.getDisplayAvatars().size(); i++) {
var objectId = player.getDisplayAvatars().get(i);
if (objectId == null) continue;
var avatar = player.getAvatarById(objectId);
if (avatar == null) continue;
var info = DisplayAvatar.newInstance()
.setAvatarId(avatar.getAvatarId())
.setPos(i);
data.getMutableDisplayAvatarVec().addDisplayAvatarList(info);
}
this.setData(data);
}
}

View File

@@ -0,0 +1,24 @@
package emu.lunarcore.server.packet.send;
import emu.lunarcore.game.player.Player;
import emu.lunarcore.proto.SetAssistAvatarScRspOuterClass.SetAssistAvatarScRsp;
import emu.lunarcore.server.packet.BasePacket;
import emu.lunarcore.server.packet.CmdId;
public class PacketSetAssistAvatarScRsp extends BasePacket {
public PacketSetAssistAvatarScRsp(Player player) {
super(CmdId.SetAssistAvatarScRsp);
var data = SetAssistAvatarScRsp.newInstance();
for (var objectId : player.getAssistAvatars()) {
var avatar = player.getAvatarById(objectId);
if (avatar == null) continue;
data.addAvatarIdList(avatar.getAvatarId());
}
this.setData(data);
}
}

View File

@@ -0,0 +1,32 @@
package emu.lunarcore.server.packet.send;
import emu.lunarcore.game.player.Player;
import emu.lunarcore.proto.DisplayAvatarOuterClass.DisplayAvatar;
import emu.lunarcore.proto.SetDisplayAvatarScRspOuterClass.SetDisplayAvatarScRsp;
import emu.lunarcore.server.packet.BasePacket;
import emu.lunarcore.server.packet.CmdId;
public class PacketSetDisplayAvatarScRsp extends BasePacket {
public PacketSetDisplayAvatarScRsp(Player player) {
super(CmdId.SetDisplayAvatarScRsp);
var data = SetDisplayAvatarScRsp.newInstance();
for (int i = 0; i < player.getDisplayAvatars().size(); i++) {
var objectId = player.getDisplayAvatars().get(i);
if (objectId == null) continue;
var avatar = player.getAvatarById(objectId);
if (avatar == null) continue;
var info = DisplayAvatar.newInstance()
.setAvatarId(avatar.getAvatarId())
.setPos(i);
data.addDisplayAvatarList(info);
}
this.setData(data);
}
}