mirror of
https://github.com/Melledy/Nebula.git
synced 2025-12-13 12:54: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<CharacterSkillUpgradeDef> CharacterSkillUpgradeDataTable = new DataTable<>();
|
||||||
@Getter private static DataTable<CharacterUpgradeDef> CharacterUpgradeDataTable = new DataTable<>();
|
@Getter private static DataTable<CharacterUpgradeDef> CharacterUpgradeDataTable = new DataTable<>();
|
||||||
@Getter private static DataTable<CharItemExpDef> CharItemExpDataTable = 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<TalentGroupDef> TalentGroupDataTable = new DataTable<>();
|
||||||
@Getter private static DataTable<TalentDef> TalentDataTable = new DataTable<>();
|
@Getter private static DataTable<TalentDef> TalentDataTable = new DataTable<>();
|
||||||
|
|
||||||
|
|||||||
@@ -9,14 +9,17 @@ import lombok.Getter;
|
|||||||
public class CharacterDef extends BaseDef {
|
public class CharacterDef extends BaseDef {
|
||||||
private int Id;
|
private int Id;
|
||||||
private String Name;
|
private String Name;
|
||||||
private boolean Available;
|
|
||||||
private int Grade;
|
private int Grade;
|
||||||
|
|
||||||
private int DefaultSkinId;
|
private int DefaultSkinId;
|
||||||
private int AdvanceSkinId;
|
private int AdvanceSkinId;
|
||||||
|
private int AdvanceSkinUnlockLevel;
|
||||||
|
|
||||||
private int AdvanceGroup;
|
private int AdvanceGroup;
|
||||||
|
private int[] SkillsUpgradeGroup;
|
||||||
|
|
||||||
private int FragmentsId;
|
private int FragmentsId;
|
||||||
private int TransformQty;
|
private int TransformQty;
|
||||||
private int[] SkillsUpgradeGroup;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getId() {
|
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() {
|
public int getId() {
|
||||||
return Id;
|
return Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -289,6 +289,51 @@ public class Character implements GameDatabaseObject {
|
|||||||
return changes.setSuccess(true);
|
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
|
// Proto
|
||||||
|
|
||||||
public Char toProto() {
|
public Char toProto() {
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ public class CharacterStorage extends PlayerManager {
|
|||||||
public HandbookInfo getCharacterHandbook() {
|
public HandbookInfo getCharacterHandbook() {
|
||||||
var bitset = new Bitset();
|
var bitset = new Bitset();
|
||||||
|
|
||||||
for (var character : this.getCharacterCollection()) {
|
for (var skinId : getPlayer().getInventory().getAllSkinIds()) {
|
||||||
// Get handbook
|
// Get handbook data
|
||||||
var data = GameData.getHandbookDataTable().get(400000 + character.getSkin());
|
var data = GameData.getHandbookDataTable().get(400000 + skinId);
|
||||||
if (data == null) continue;
|
if (data == null) continue;
|
||||||
|
|
||||||
// Set flag
|
// Set flag
|
||||||
|
|||||||
@@ -2,9 +2,12 @@ package emu.nebula.game.inventory;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import dev.morphia.annotations.Entity;
|
||||||
|
import dev.morphia.annotations.Id;
|
||||||
import emu.nebula.GameConstants;
|
import emu.nebula.GameConstants;
|
||||||
import emu.nebula.Nebula;
|
import emu.nebula.Nebula;
|
||||||
import emu.nebula.data.GameData;
|
import emu.nebula.data.GameData;
|
||||||
|
import emu.nebula.database.GameDatabaseObject;
|
||||||
import emu.nebula.game.player.PlayerManager;
|
import emu.nebula.game.player.PlayerManager;
|
||||||
import emu.nebula.proto.Public.Item;
|
import emu.nebula.proto.Public.Item;
|
||||||
import emu.nebula.proto.Public.Res;
|
import emu.nebula.proto.Public.Res;
|
||||||
@@ -12,20 +15,73 @@ import emu.nebula.game.player.Player;
|
|||||||
import emu.nebula.game.player.PlayerChangeInfo;
|
import emu.nebula.game.player.PlayerChangeInfo;
|
||||||
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 it.unimi.dsi.fastutil.ints.IntCollection;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class Inventory extends PlayerManager {
|
@Entity(value = "inventory", useDiscriminator = false)
|
||||||
private final Int2ObjectMap<GameResource> resources;
|
public class Inventory extends PlayerManager implements GameDatabaseObject {
|
||||||
private final Int2ObjectMap<GameItem> items;
|
@Id
|
||||||
|
private int uid;
|
||||||
|
|
||||||
public Inventory(Player player) {
|
// Database persistent data
|
||||||
super(player);
|
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.resources = new Int2ObjectOpenHashMap<>();
|
||||||
this.items = 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
|
// Resources
|
||||||
|
|
||||||
public synchronized int getResourceCount(int id) {
|
public synchronized int getResourceCount(int id) {
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ public enum ItemType {
|
|||||||
WorldRankExp (5),
|
WorldRankExp (5),
|
||||||
RogueItem (6),
|
RogueItem (6),
|
||||||
Disc (7),
|
Disc (7),
|
||||||
Equipment (8),
|
Equipment (9),
|
||||||
CharacterSkin (9),
|
CharacterSkin (10),
|
||||||
MonthlyCard (10),
|
MonthlyCard (11),
|
||||||
Title (11),
|
Title (12),
|
||||||
Honor (12),
|
Honor (13),
|
||||||
HeadItem (13);
|
HeadItem (14);
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final int value;
|
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.WorldClass;
|
||||||
import emu.nebula.proto.Public.Title;
|
import emu.nebula.proto.Public.Title;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import us.hebi.quickbuf.RepeatedInt;
|
import us.hebi.quickbuf.RepeatedInt;
|
||||||
|
|
||||||
@@ -56,22 +53,19 @@ public class Player implements GameDatabaseObject {
|
|||||||
private int titleSuffix;
|
private int titleSuffix;
|
||||||
private int level;
|
private int level;
|
||||||
private int exp;
|
private int exp;
|
||||||
|
private int[] boards;
|
||||||
|
|
||||||
private int energy;
|
private int energy;
|
||||||
private long energyLastUpdate;
|
private long energyLastUpdate;
|
||||||
|
|
||||||
private int[] boards;
|
|
||||||
private IntSet headIcons;
|
|
||||||
private IntSet titles;
|
|
||||||
|
|
||||||
private long createTime;
|
private long createTime;
|
||||||
|
|
||||||
// Managers
|
// Managers
|
||||||
private final transient CharacterStorage characters;
|
private final transient CharacterStorage characters;
|
||||||
private final transient Inventory inventory;
|
|
||||||
private transient GachaManager gachaManager;
|
private transient GachaManager gachaManager;
|
||||||
|
|
||||||
// Referenced data
|
// Referenced data
|
||||||
|
private transient Inventory inventory;
|
||||||
private transient FormationManager formations;
|
private transient FormationManager formations;
|
||||||
private transient Mailbox mailbox;
|
private transient Mailbox mailbox;
|
||||||
private transient StarTowerManager starTowerManager;
|
private transient StarTowerManager starTowerManager;
|
||||||
@@ -82,7 +76,6 @@ public class Player implements GameDatabaseObject {
|
|||||||
public Player() {
|
public Player() {
|
||||||
this.sessions = new HashSet<>();
|
this.sessions = new HashSet<>();
|
||||||
this.characters = new CharacterStorage(this);
|
this.characters = new CharacterStorage(this);
|
||||||
this.inventory = new Inventory(this);
|
|
||||||
this.gachaManager = new GachaManager(this);
|
this.gachaManager = new GachaManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,8 +103,9 @@ public class Player implements GameDatabaseObject {
|
|||||||
this.energy = 240;
|
this.energy = 240;
|
||||||
this.energyLastUpdate = this.createTime;
|
this.energyLastUpdate = this.createTime;
|
||||||
this.boards = new int[] {410301};
|
this.boards = new int[] {410301};
|
||||||
this.headIcons = new IntOpenHashSet();
|
|
||||||
this.titles = new IntOpenHashSet();
|
// Setup inventory
|
||||||
|
this.inventory = new Inventory(this);
|
||||||
|
|
||||||
// Add starter characters
|
// Add starter characters
|
||||||
this.getCharacters().addCharacter(103);
|
this.getCharacters().addCharacter(103);
|
||||||
@@ -123,10 +117,6 @@ public class Player implements GameDatabaseObject {
|
|||||||
this.getCharacters().addDisc(211005);
|
this.getCharacters().addDisc(211005);
|
||||||
this.getCharacters().addDisc(211007);
|
this.getCharacters().addDisc(211007);
|
||||||
this.getCharacters().addDisc(211008);
|
this.getCharacters().addDisc(211008);
|
||||||
|
|
||||||
// Add titles
|
|
||||||
this.getTitles().add(this.getTitlePrefix());
|
|
||||||
this.getTitles().add(this.getTitleSuffix());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Account getAccount() {
|
public Account getAccount() {
|
||||||
@@ -190,7 +180,7 @@ public class Player implements GameDatabaseObject {
|
|||||||
|
|
||||||
public boolean editTitle(int prefix, int suffix) {
|
public boolean editTitle(int prefix, int suffix) {
|
||||||
// Check to make sure we own these titles
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,6 +394,11 @@ public class Player implements GameDatabaseObject {
|
|||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
// Load from database
|
// Load from database
|
||||||
this.getCharacters().loadFromDatabase();
|
this.getCharacters().loadFromDatabase();
|
||||||
|
|
||||||
|
// Load inventory first
|
||||||
|
if (this.inventory == null) {
|
||||||
|
this.inventory = this.loadManagerFromDatabase(Inventory.class);
|
||||||
|
}
|
||||||
this.getInventory().loadFromDatabase();
|
this.getInventory().loadFromDatabase();
|
||||||
|
|
||||||
// Load referenced classes
|
// Load referenced classes
|
||||||
@@ -501,7 +496,7 @@ public class Player implements GameDatabaseObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add titles
|
// Add titles
|
||||||
for (int titleId : this.getTitles()) {
|
for (int titleId : this.getInventory().getTitles()) {
|
||||||
var titleProto = Title.newInstance()
|
var titleProto = Title.newInstance()
|
||||||
.setTitleId(titleId);
|
.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