mirror of
https://github.com/Melledy/Nebula.git
synced 2025-12-12 20:34:36 +01:00
Refactor inventory system
This commit is contained in:
@@ -23,6 +23,7 @@ public class GameData {
|
||||
@Getter private static DataTable<CharacterSkillUpgradeDef> CharacterSkillUpgradeDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<CharacterUpgradeDef> CharacterUpgradeDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<CharItemExpDef> CharItemExpDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<CharacterSkinDef> CharacterSkinDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<TalentGroupDef> TalentGroupDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<TalentDef> TalentDataTable = new DataTable<>();
|
||||
|
||||
|
||||
@@ -9,14 +9,17 @@ import lombok.Getter;
|
||||
public class CharacterDef extends BaseDef {
|
||||
private int Id;
|
||||
private String Name;
|
||||
private boolean Available;
|
||||
private int Grade;
|
||||
|
||||
private int DefaultSkinId;
|
||||
private int AdvanceSkinId;
|
||||
private int AdvanceSkinUnlockLevel;
|
||||
|
||||
private int AdvanceGroup;
|
||||
private int[] SkillsUpgradeGroup;
|
||||
|
||||
private int FragmentsId;
|
||||
private int TransformQty;
|
||||
private int[] SkillsUpgradeGroup;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "CharacterSkin.json")
|
||||
public class CharacterSkinDef extends BaseDef {
|
||||
private int Id;
|
||||
private int CharId;
|
||||
private int Type;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,4 @@ public class HandbookDef extends BaseDef {
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,6 +289,51 @@ public class Character implements GameDatabaseObject {
|
||||
return changes.setSuccess(true);
|
||||
}
|
||||
|
||||
public boolean setSkin(int skinId) {
|
||||
// Sanity check
|
||||
if (this.skin == skinId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
var skinData = GameData.getCharacterSkinDataTable().get(skinId);
|
||||
if (skinData == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure we have the skin
|
||||
if (skinData.getCharId() != this.getCharId()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (skinData.getType()) {
|
||||
case 1:
|
||||
// Default skin, always allow
|
||||
break;
|
||||
case 2:
|
||||
// Ascension skin, only allow if the character has the right ascension level
|
||||
if (this.getAdvance() < this.getData().getAdvanceSkinUnlockLevel()) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Extra skin, only allow if we have the skin unlocked
|
||||
if (!getPlayer().getInventory().getExtraSkins().contains(skinId)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Set skin
|
||||
this.skin = skinId;
|
||||
|
||||
// Save
|
||||
this.save();
|
||||
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
public Char toProto() {
|
||||
|
||||
@@ -73,9 +73,9 @@ public class CharacterStorage extends PlayerManager {
|
||||
public HandbookInfo getCharacterHandbook() {
|
||||
var bitset = new Bitset();
|
||||
|
||||
for (var character : this.getCharacterCollection()) {
|
||||
// Get handbook
|
||||
var data = GameData.getHandbookDataTable().get(400000 + character.getSkin());
|
||||
for (var skinId : getPlayer().getInventory().getAllSkinIds()) {
|
||||
// Get handbook data
|
||||
var data = GameData.getHandbookDataTable().get(400000 + skinId);
|
||||
if (data == null) continue;
|
||||
|
||||
// Set flag
|
||||
|
||||
@@ -2,9 +2,12 @@ package emu.nebula.game.inventory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Id;
|
||||
import emu.nebula.GameConstants;
|
||||
import emu.nebula.Nebula;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.database.GameDatabaseObject;
|
||||
import emu.nebula.game.player.PlayerManager;
|
||||
import emu.nebula.proto.Public.Item;
|
||||
import emu.nebula.proto.Public.Res;
|
||||
@@ -12,20 +15,73 @@ import emu.nebula.game.player.Player;
|
||||
import emu.nebula.game.player.PlayerChangeInfo;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntCollection;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class Inventory extends PlayerManager {
|
||||
private final Int2ObjectMap<GameResource> resources;
|
||||
private final Int2ObjectMap<GameItem> items;
|
||||
@Entity(value = "inventory", useDiscriminator = false)
|
||||
public class Inventory extends PlayerManager implements GameDatabaseObject {
|
||||
@Id
|
||||
private int uid;
|
||||
|
||||
public Inventory(Player player) {
|
||||
super(player);
|
||||
|
||||
// Database persistent data
|
||||
private IntSet extraSkins;
|
||||
private IntSet headIcons;
|
||||
private IntSet titles;
|
||||
|
||||
// Items/resources
|
||||
private transient Int2ObjectMap<GameResource> resources;
|
||||
private transient Int2ObjectMap<GameItem> items;
|
||||
|
||||
public Inventory() {
|
||||
this.resources = new Int2ObjectOpenHashMap<>();
|
||||
this.items = new Int2ObjectOpenHashMap<>();
|
||||
}
|
||||
|
||||
public Inventory(Player player) {
|
||||
this();
|
||||
this.setPlayer(player);
|
||||
this.uid = player.getUid();
|
||||
|
||||
// Setup
|
||||
this.extraSkins = new IntOpenHashSet();
|
||||
this.headIcons = new IntOpenHashSet();
|
||||
this.titles = new IntOpenHashSet();
|
||||
|
||||
// Add titles directly
|
||||
this.getTitles().add(player.getTitlePrefix());
|
||||
this.getTitles().add(player.getTitleSuffix());
|
||||
|
||||
// Save to database
|
||||
this.save();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public IntCollection getAllSkinIds() {
|
||||
// Setup int collection
|
||||
var skins = new IntOpenHashSet();
|
||||
|
||||
// Add character skins
|
||||
for (var character : getPlayer().getCharacters().getCharacterCollection()) {
|
||||
// Add default skin id
|
||||
skins.add(character.getData().getDefaultSkinId());
|
||||
|
||||
// Add advance skin
|
||||
if (character.getAdvance() >= character.getData().getAdvanceSkinUnlockLevel()) {
|
||||
skins.add(character.getData().getAdvanceSkinId());
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, add extra skins
|
||||
skins.addAll(this.getExtraSkins());
|
||||
|
||||
// Complete and return
|
||||
return skins;
|
||||
}
|
||||
|
||||
// Resources
|
||||
|
||||
public synchronized int getResourceCount(int id) {
|
||||
|
||||
@@ -12,12 +12,12 @@ public enum ItemType {
|
||||
WorldRankExp (5),
|
||||
RogueItem (6),
|
||||
Disc (7),
|
||||
Equipment (8),
|
||||
CharacterSkin (9),
|
||||
MonthlyCard (10),
|
||||
Title (11),
|
||||
Honor (12),
|
||||
HeadItem (13);
|
||||
Equipment (9),
|
||||
CharacterSkin (10),
|
||||
MonthlyCard (11),
|
||||
Title (12),
|
||||
Honor (13),
|
||||
HeadItem (14);
|
||||
|
||||
@Getter
|
||||
private final int value;
|
||||
|
||||
@@ -31,9 +31,6 @@ import emu.nebula.proto.Public.Story;
|
||||
import emu.nebula.proto.Public.WorldClass;
|
||||
import emu.nebula.proto.Public.Title;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
|
||||
import lombok.Getter;
|
||||
import us.hebi.quickbuf.RepeatedInt;
|
||||
|
||||
@@ -56,22 +53,19 @@ public class Player implements GameDatabaseObject {
|
||||
private int titleSuffix;
|
||||
private int level;
|
||||
private int exp;
|
||||
private int[] boards;
|
||||
|
||||
private int energy;
|
||||
private long energyLastUpdate;
|
||||
|
||||
private int[] boards;
|
||||
private IntSet headIcons;
|
||||
private IntSet titles;
|
||||
|
||||
private long createTime;
|
||||
|
||||
// Managers
|
||||
private final transient CharacterStorage characters;
|
||||
private final transient Inventory inventory;
|
||||
private transient GachaManager gachaManager;
|
||||
|
||||
// Referenced data
|
||||
private transient Inventory inventory;
|
||||
private transient FormationManager formations;
|
||||
private transient Mailbox mailbox;
|
||||
private transient StarTowerManager starTowerManager;
|
||||
@@ -82,7 +76,6 @@ public class Player implements GameDatabaseObject {
|
||||
public Player() {
|
||||
this.sessions = new HashSet<>();
|
||||
this.characters = new CharacterStorage(this);
|
||||
this.inventory = new Inventory(this);
|
||||
this.gachaManager = new GachaManager(this);
|
||||
}
|
||||
|
||||
@@ -110,8 +103,9 @@ public class Player implements GameDatabaseObject {
|
||||
this.energy = 240;
|
||||
this.energyLastUpdate = this.createTime;
|
||||
this.boards = new int[] {410301};
|
||||
this.headIcons = new IntOpenHashSet();
|
||||
this.titles = new IntOpenHashSet();
|
||||
|
||||
// Setup inventory
|
||||
this.inventory = new Inventory(this);
|
||||
|
||||
// Add starter characters
|
||||
this.getCharacters().addCharacter(103);
|
||||
@@ -123,10 +117,6 @@ public class Player implements GameDatabaseObject {
|
||||
this.getCharacters().addDisc(211005);
|
||||
this.getCharacters().addDisc(211007);
|
||||
this.getCharacters().addDisc(211008);
|
||||
|
||||
// Add titles
|
||||
this.getTitles().add(this.getTitlePrefix());
|
||||
this.getTitles().add(this.getTitleSuffix());
|
||||
}
|
||||
|
||||
public Account getAccount() {
|
||||
@@ -190,7 +180,7 @@ public class Player implements GameDatabaseObject {
|
||||
|
||||
public boolean editTitle(int prefix, int suffix) {
|
||||
// Check to make sure we own these titles
|
||||
if (!getTitles().contains(prefix) || !getTitles().contains(suffix)) {
|
||||
if (!getInventory().getTitles().contains(prefix) || !getInventory().getTitles().contains(suffix)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -404,6 +394,11 @@ public class Player implements GameDatabaseObject {
|
||||
public void onLoad() {
|
||||
// Load from database
|
||||
this.getCharacters().loadFromDatabase();
|
||||
|
||||
// Load inventory first
|
||||
if (this.inventory == null) {
|
||||
this.inventory = this.loadManagerFromDatabase(Inventory.class);
|
||||
}
|
||||
this.getInventory().loadFromDatabase();
|
||||
|
||||
// Load referenced classes
|
||||
@@ -501,7 +496,7 @@ public class Player implements GameDatabaseObject {
|
||||
}
|
||||
|
||||
// Add titles
|
||||
for (int titleId : this.getTitles()) {
|
||||
for (int titleId : this.getInventory().getTitles()) {
|
||||
var titleProto = Title.newInstance()
|
||||
.setTitleId(titleId);
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.CharSkinSet.CharSkinSetReq;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
@HandlerId(NetMsgId.char_skin_set_req)
|
||||
public class HandlerCharSkinSetReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = CharSkinSetReq.parseFrom(message);
|
||||
|
||||
// Get character
|
||||
var character = session.getPlayer().getCharacters().getCharacterById(req.getCharId());
|
||||
if (character == null) {
|
||||
return session.encodeMsg(NetMsgId.char_skin_set_failed_ack);
|
||||
}
|
||||
|
||||
// Set skin
|
||||
var result = character.setSkin(req.getSkinId());
|
||||
if (!result) {
|
||||
return session.encodeMsg(NetMsgId.char_skin_set_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.char_skin_set_succeed_ack);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user