mirror of
https://github.com/Melledy/Nebula.git
synced 2025-12-14 13:24:43 +01:00
Implement saving tower records
This commit is contained in:
@@ -134,8 +134,6 @@ public class CharacterStorage extends PlayerManager {
|
|||||||
this.characters.put(character.getCharId(), character);
|
this.characters.put(character.getCharId(), character);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
db.getObjects(GameDisc.class, "playerUid", getPlayerUid()).forEach(disc -> {
|
db.getObjects(GameDisc.class, "playerUid", getPlayerUid()).forEach(disc -> {
|
||||||
// Get data
|
// Get data
|
||||||
var data = GameData.getDiscDataTable().get(disc.getDiscId());
|
var data = GameData.getDiscDataTable().get(disc.getDiscId());
|
||||||
|
|||||||
@@ -44,6 +44,30 @@ public class Formation {
|
|||||||
return this.discIds[i];
|
return this.discIds[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getCharCount() {
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
for (int id : this.getCharIds()) {
|
||||||
|
if (id > 0) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDiscCount() {
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
for (int id : this.getDiscIds()) {
|
||||||
|
if (id > 0) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
// Proto
|
// Proto
|
||||||
|
|
||||||
public FormationInfo toProto() {
|
public FormationInfo toProto() {
|
||||||
|
|||||||
@@ -1,25 +1,38 @@
|
|||||||
package emu.nebula.game.tower;
|
package emu.nebula.game.tower;
|
||||||
|
|
||||||
import dev.morphia.annotations.Entity;
|
import dev.morphia.annotations.Entity;
|
||||||
|
import dev.morphia.annotations.Id;
|
||||||
|
import dev.morphia.annotations.Indexed;
|
||||||
|
import emu.nebula.data.GameData;
|
||||||
|
import emu.nebula.database.GameDatabaseObject;
|
||||||
import emu.nebula.proto.PublicStarTower.BuildPotential;
|
import emu.nebula.proto.PublicStarTower.BuildPotential;
|
||||||
|
import emu.nebula.proto.PublicStarTower.StarTowerBuildBrief;
|
||||||
|
import emu.nebula.proto.PublicStarTower.StarTowerBuildDetail;
|
||||||
import emu.nebula.proto.PublicStarTower.StarTowerBuildInfo;
|
import emu.nebula.proto.PublicStarTower.StarTowerBuildInfo;
|
||||||
import emu.nebula.proto.PublicStarTower.TowerBuildChar;
|
import emu.nebula.proto.PublicStarTower.TowerBuildChar;
|
||||||
|
import emu.nebula.util.Snowflake;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Entity(useDiscriminator = false)
|
@Entity(value = "star_tower_builds", useDiscriminator = false)
|
||||||
public class StarTowerBuild {
|
public class StarTowerBuild implements GameDatabaseObject {
|
||||||
private int id;
|
@Id
|
||||||
|
private int uid;
|
||||||
|
@Indexed
|
||||||
|
private int playerUid;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private boolean lock;
|
private boolean lock;
|
||||||
private boolean preference;
|
private boolean preference;
|
||||||
private int score;
|
private int score;
|
||||||
private int[] charIds;
|
|
||||||
|
private Int2IntMap chars;
|
||||||
private int[] discIds;
|
private int[] discIds;
|
||||||
|
|
||||||
private Int2IntMap potentials;
|
private Int2IntMap potentials;
|
||||||
|
private Int2IntMap subNoteSkills;
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public StarTowerBuild() {
|
public StarTowerBuild() {
|
||||||
@@ -27,59 +40,78 @@ public class StarTowerBuild {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public StarTowerBuild(StarTowerInstance instance) {
|
public StarTowerBuild(StarTowerInstance instance) {
|
||||||
|
this.uid = Snowflake.newUid();
|
||||||
|
this.playerUid = instance.getPlayer().getUid();
|
||||||
this.name = "";
|
this.name = "";
|
||||||
this.potentials = new Int2IntOpenHashMap();
|
this.potentials = new Int2IntOpenHashMap();
|
||||||
|
this.subNoteSkills = new Int2IntOpenHashMap();
|
||||||
|
|
||||||
this.charIds = instance.getChars().stream()
|
// Discs
|
||||||
.filter(c -> c.getId() > 0)
|
|
||||||
.mapToInt(c -> c.getId())
|
|
||||||
.toArray();
|
|
||||||
this.discIds = instance.getDiscs().stream()
|
this.discIds = instance.getDiscs().stream()
|
||||||
.filter(d -> d.getId() > 0)
|
.filter(d -> d.getId() > 0)
|
||||||
.mapToInt(d -> d.getId())
|
.mapToInt(d -> d.getId())
|
||||||
.toArray();
|
.toArray();
|
||||||
|
|
||||||
|
// Characters
|
||||||
|
this.chars = new Int2IntOpenHashMap();
|
||||||
|
|
||||||
|
instance.getChars().stream()
|
||||||
|
.forEach(c -> this.getChars().put(c.getId(), 0));
|
||||||
|
|
||||||
// Add potentials
|
// Add potentials
|
||||||
for (int id : instance.getPotentials()) {
|
for (int id : instance.getPotentials()) {
|
||||||
|
// Add to potential map
|
||||||
this.getPotentials().put(id, instance.getItemCount(id));
|
this.getPotentials().put(id, instance.getItemCount(id));
|
||||||
|
|
||||||
|
// Add to character
|
||||||
|
var potentialData = GameData.getPotentialDataTable().get(id);
|
||||||
|
if (potentialData != null) {
|
||||||
|
int charId = potentialData.getCharId();
|
||||||
|
this.getChars().put(charId, this.getChars().get(charId) + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(StarTowerManager manager) {
|
|
||||||
this.id = manager.getNextBuildId();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proto
|
// Proto
|
||||||
|
|
||||||
public StarTowerBuildInfo toProto() {
|
public StarTowerBuildInfo toProto() {
|
||||||
var proto = StarTowerBuildInfo.newInstance();
|
var proto = StarTowerBuildInfo.newInstance()
|
||||||
|
.setBrief(this.toBriefProto())
|
||||||
// Basic data
|
.setDetail(this.toDetailProto());
|
||||||
proto.getMutableBrief()
|
|
||||||
.setId(this.getId())
|
return proto;
|
||||||
.setName(this.getName())
|
}
|
||||||
.setLock(this.isLock())
|
|
||||||
.setPreference(this.isPreference())
|
public StarTowerBuildBrief toBriefProto() {
|
||||||
.setScore(this.getScore())
|
var proto = StarTowerBuildBrief.newInstance()
|
||||||
.addAllDiscIds(this.getDiscIds());
|
.setId(this.getUid())
|
||||||
|
.setName(this.getName())
|
||||||
|
.setLock(this.isLock())
|
||||||
|
.setPreference(this.isPreference())
|
||||||
|
.setScore(this.getScore())
|
||||||
|
.addAllDiscIds(this.getDiscIds());
|
||||||
|
|
||||||
// Add characters
|
// Add characters
|
||||||
for (int id : charIds) {
|
for (var character : this.getChars().int2IntEntrySet()) {
|
||||||
var charProto = TowerBuildChar.newInstance()
|
var charProto = TowerBuildChar.newInstance()
|
||||||
.setCharId(id);
|
.setCharId(character.getIntKey())
|
||||||
|
.setPotentialCnt(character.getIntValue());
|
||||||
|
|
||||||
proto.getMutableBrief().addChars(charProto);
|
proto.addChars(charProto);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build detail
|
return proto;
|
||||||
var detail = proto.getMutableDetail();
|
}
|
||||||
|
|
||||||
|
public StarTowerBuildDetail toDetailProto() {
|
||||||
|
var proto = StarTowerBuildDetail.newInstance();
|
||||||
|
|
||||||
for (var entry : this.getPotentials().int2IntEntrySet()) {
|
for (var entry : this.getPotentials().int2IntEntrySet()) {
|
||||||
var potential = BuildPotential.newInstance()
|
var potential = BuildPotential.newInstance()
|
||||||
.setPotentialId(entry.getIntKey())
|
.setPotentialId(entry.getIntKey())
|
||||||
.setLevel(entry.getIntValue());
|
.setLevel(entry.getIntValue());
|
||||||
|
|
||||||
detail.getMutablePotentials().add(potential);
|
proto.getMutablePotentials().add(potential);
|
||||||
}
|
}
|
||||||
|
|
||||||
return proto;
|
return proto;
|
||||||
|
|||||||
@@ -2,11 +2,14 @@ package emu.nebula.game.tower;
|
|||||||
|
|
||||||
import dev.morphia.annotations.Entity;
|
import dev.morphia.annotations.Entity;
|
||||||
import dev.morphia.annotations.Id;
|
import dev.morphia.annotations.Id;
|
||||||
|
import emu.nebula.Nebula;
|
||||||
import emu.nebula.data.GameData;
|
import emu.nebula.data.GameData;
|
||||||
import emu.nebula.database.GameDatabaseObject;
|
import emu.nebula.database.GameDatabaseObject;
|
||||||
import emu.nebula.game.player.Player;
|
import emu.nebula.game.player.Player;
|
||||||
import emu.nebula.game.player.PlayerManager;
|
import emu.nebula.game.player.PlayerManager;
|
||||||
import emu.nebula.proto.StarTowerApply.StarTowerApplyReq;
|
import emu.nebula.proto.StarTowerApply.StarTowerApplyReq;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@@ -14,9 +17,10 @@ import lombok.Getter;
|
|||||||
public class StarTowerManager extends PlayerManager implements GameDatabaseObject {
|
public class StarTowerManager extends PlayerManager implements GameDatabaseObject {
|
||||||
@Id
|
@Id
|
||||||
private int uid;
|
private int uid;
|
||||||
private int lastBuildId;
|
|
||||||
|
|
||||||
|
private transient Int2ObjectMap<StarTowerBuild> builds;
|
||||||
private transient StarTowerInstance instance;
|
private transient StarTowerInstance instance;
|
||||||
|
private transient StarTowerBuild lastBuild;
|
||||||
|
|
||||||
@Deprecated // Morphia only
|
@Deprecated // Morphia only
|
||||||
public StarTowerManager() {
|
public StarTowerManager() {
|
||||||
@@ -30,8 +34,12 @@ public class StarTowerManager extends PlayerManager implements GameDatabaseObjec
|
|||||||
this.save();
|
this.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNextBuildId() {
|
public Int2ObjectMap<StarTowerBuild> getBuilds() {
|
||||||
return ++this.lastBuildId;
|
if (this.builds == null) {
|
||||||
|
this.loadFromDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
return builds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StarTowerInstance apply(StarTowerApplyReq req) {
|
public StarTowerInstance apply(StarTowerApplyReq req) {
|
||||||
@@ -47,6 +55,11 @@ public class StarTowerManager extends PlayerManager implements GameDatabaseObjec
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure player has at least 3 chars and 3 discs
|
||||||
|
if (formation.getCharCount() != 3 || formation.getDiscCount() < 3) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Create instance
|
// Create instance
|
||||||
this.instance = new StarTowerInstance(this, data, formation, req);
|
this.instance = new StarTowerInstance(this, data, formation, req);
|
||||||
|
|
||||||
@@ -55,12 +68,57 @@ public class StarTowerManager extends PlayerManager implements GameDatabaseObjec
|
|||||||
}
|
}
|
||||||
|
|
||||||
public StarTowerInstance giveUp() {
|
public StarTowerInstance giveUp() {
|
||||||
|
// Cache instance
|
||||||
var instance = this.instance;
|
var instance = this.instance;
|
||||||
|
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
|
// Set last build
|
||||||
|
this.lastBuild = instance.getBuild();
|
||||||
|
|
||||||
|
// Clear instance
|
||||||
this.instance = null;
|
this.instance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean saveBuild(boolean delete, String name, boolean lock) {
|
||||||
|
// Sanity check
|
||||||
|
if (this.getLastBuild() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache build and clear reference
|
||||||
|
var build = this.lastBuild;
|
||||||
|
this.lastBuild = null;
|
||||||
|
|
||||||
|
// Check if the player wants this build or not
|
||||||
|
if (delete) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check limit
|
||||||
|
if (this.getBuilds().size() >= 50) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to builds
|
||||||
|
this.getBuilds().put(build.getUid(), build);
|
||||||
|
|
||||||
|
// Save build to database
|
||||||
|
build.save();
|
||||||
|
|
||||||
|
//
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Database
|
||||||
|
|
||||||
|
private void loadFromDatabase() {
|
||||||
|
this.builds = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
|
Nebula.getGameDatabase().getObjects(StarTowerBuild.class, "playerUid", getPlayerUid()).forEach(build -> {
|
||||||
|
this.builds.put(build.getUid(), build);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package emu.nebula.server.handlers;
|
|||||||
|
|
||||||
import emu.nebula.net.NetHandler;
|
import emu.nebula.net.NetHandler;
|
||||||
import emu.nebula.net.NetMsgId;
|
import emu.nebula.net.NetMsgId;
|
||||||
|
import emu.nebula.proto.StarTowerBuildBriefListGet.StarTowerBuildBriefListGetResp;
|
||||||
import emu.nebula.net.HandlerId;
|
import emu.nebula.net.HandlerId;
|
||||||
import emu.nebula.net.GameSession;
|
import emu.nebula.net.GameSession;
|
||||||
|
|
||||||
@@ -10,7 +11,17 @@ public class HandlerStarTowerBuildBriefListGetReq extends NetHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||||
return this.encodeMsg(NetMsgId.star_tower_build_brief_list_get_succeed_ack);
|
// Build response
|
||||||
|
var rsp = StarTowerBuildBriefListGetResp.newInstance();
|
||||||
|
|
||||||
|
// Add star tower builds
|
||||||
|
var builds = session.getPlayer().getStarTowerManager().getBuilds().values();
|
||||||
|
for (var build : builds) {
|
||||||
|
rsp.addBriefs(build.toBriefProto());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish
|
||||||
|
return this.encodeMsg(NetMsgId.star_tower_build_brief_list_get_succeed_ack, rsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package emu.nebula.server.handlers;
|
||||||
|
|
||||||
|
import emu.nebula.net.NetHandler;
|
||||||
|
import emu.nebula.net.NetMsgId;
|
||||||
|
import emu.nebula.proto.StarTowerBuildDetailGet.StarTowerBuildDetailGetReq;
|
||||||
|
import emu.nebula.proto.StarTowerBuildDetailGet.StarTowerBuildDetailGetResp;
|
||||||
|
import emu.nebula.net.HandlerId;
|
||||||
|
import emu.nebula.net.GameSession;
|
||||||
|
|
||||||
|
@HandlerId(NetMsgId.star_tower_build_detail_get_req)
|
||||||
|
public class HandlerStarTowerBuildDetailGetReq extends NetHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||||
|
// Parse request
|
||||||
|
var req = StarTowerBuildDetailGetReq.parseFrom(message);
|
||||||
|
|
||||||
|
// Get build
|
||||||
|
int buildId = (int) req.getBuildId();
|
||||||
|
var build = session.getPlayer().getStarTowerManager().getBuilds().get(buildId);
|
||||||
|
|
||||||
|
if (build == null) {
|
||||||
|
return this.encodeMsg(NetMsgId.star_tower_build_detail_get_failed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build response
|
||||||
|
var rsp = StarTowerBuildDetailGetResp.newInstance()
|
||||||
|
.setDetail(build.toDetailProto());
|
||||||
|
|
||||||
|
return this.encodeMsg(NetMsgId.star_tower_build_detail_get_succeed_ack, rsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package emu.nebula.server.handlers;
|
|||||||
import emu.nebula.net.NetHandler;
|
import emu.nebula.net.NetHandler;
|
||||||
import emu.nebula.net.NetMsgId;
|
import emu.nebula.net.NetMsgId;
|
||||||
import emu.nebula.proto.StarTowerBuildWhetherSave.StarTowerBuildWhetherSaveReq;
|
import emu.nebula.proto.StarTowerBuildWhetherSave.StarTowerBuildWhetherSaveReq;
|
||||||
|
import emu.nebula.proto.StarTowerBuildWhetherSave.StarTowerBuildWhetherSaveResp;
|
||||||
import emu.nebula.net.HandlerId;
|
import emu.nebula.net.HandlerId;
|
||||||
import emu.nebula.net.GameSession;
|
import emu.nebula.net.GameSession;
|
||||||
|
|
||||||
@@ -11,10 +12,24 @@ public class HandlerStarTowerBuildWhetherSaveReq extends NetHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||||
|
// Parse request
|
||||||
var req = StarTowerBuildWhetherSaveReq.parseFrom(message);
|
var req = StarTowerBuildWhetherSaveReq.parseFrom(message);
|
||||||
|
|
||||||
// TODO
|
// Save build
|
||||||
return this.encodeMsg(NetMsgId.star_tower_build_whether_save_succeed_ack);
|
boolean result = session.getPlayer().getStarTowerManager().saveBuild(
|
||||||
|
req.getDelete(),
|
||||||
|
req.getBuildName(),
|
||||||
|
req.getLock()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return this.encodeMsg(NetMsgId.star_tower_build_whether_save_failed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build response
|
||||||
|
var rsp = StarTowerBuildWhetherSaveResp.newInstance();
|
||||||
|
|
||||||
|
return this.encodeMsg(NetMsgId.star_tower_build_whether_save_succeed_ack, rsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user