mirror of
https://github.com/Melledy/Nebula.git
synced 2025-12-12 12:24:35 +01:00
Basic implementation of character emblems
This commit is contained in:
@@ -22,6 +22,10 @@ public class GameConstants {
|
||||
public static final int MAX_ENERGY = 240;
|
||||
public static final int ENERGY_REGEN_TIME = 360; // Seconds
|
||||
|
||||
public static final int CHARACTER_MAX_GEMS_PER_SLOT = 4;
|
||||
public static final int CHARACTER_MAX_GEM_PRESETS = 3;
|
||||
public static final int CHARACTER_MAX_GEM_SLOTS = 3;
|
||||
|
||||
public static final int MAX_FORMATIONS = 5;
|
||||
public static final int MAX_SHOWCASE_IDS = 5;
|
||||
|
||||
|
||||
@@ -28,6 +28,12 @@ public class GameData {
|
||||
@Getter private static DataTable<TalentGroupDef> TalentGroupDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<TalentDef> TalentDataTable = new DataTable<>();
|
||||
|
||||
@Getter private static DataTable<CharGemDef> CharGemDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<CharGemSlotControlDef> CharGemSlotControlDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<CharGemAttrGroupDef> CharGemAttrGroupDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<CharGemAttrTypeDef> CharGemAttrTypeDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<CharGemAttrValueDef> CharGemAttrValueDataTable = new DataTable<>();
|
||||
|
||||
@Getter private static DataTable<ChatDef> ChatDataTable = new DataTable<>();
|
||||
|
||||
// Discs
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import emu.nebula.data.ResourceType.LoadPriority;
|
||||
import emu.nebula.util.JsonUtils;
|
||||
import emu.nebula.util.WeightedList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "CharGemAttrGroup.json", loadPriority = LoadPriority.HIGH)
|
||||
public class CharGemAttrGroupDef extends BaseDef {
|
||||
private int GroupId;
|
||||
private int GroupType;
|
||||
private int Weight;
|
||||
private String UniqueAttrNumWeight;
|
||||
|
||||
private transient WeightedList<Integer> uniqueAttrNum;
|
||||
private transient List<CharGemAttrTypeDef> attributeTypes;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return GroupId;
|
||||
}
|
||||
|
||||
public int getRandomUniqueAttrNum() {
|
||||
if (this.uniqueAttrNum == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return this.uniqueAttrNum.next();
|
||||
}
|
||||
|
||||
public CharGemAttrTypeDef getRandomAttributeType(IntList list) {
|
||||
// Setup blacklist to prevent the same attribute from showing up twice
|
||||
var blacklist = new IntOpenHashSet();
|
||||
|
||||
for (int id : list) {
|
||||
var value = GameData.getCharGemAttrValueDataTable().get(id);
|
||||
if (value == null) continue;
|
||||
|
||||
int blacklistId = value.getTypeId();
|
||||
blacklist.add(blacklistId);
|
||||
}
|
||||
|
||||
// Create random generator
|
||||
var random = new WeightedList<CharGemAttrTypeDef>();
|
||||
|
||||
for (var type : this.getAttributeTypes()) {
|
||||
if (blacklist.contains(type.getId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
random.add(100, type);
|
||||
}
|
||||
|
||||
return random.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.uniqueAttrNum = new WeightedList<>();
|
||||
this.attributeTypes = new ObjectArrayList<>();
|
||||
|
||||
if (this.UniqueAttrNumWeight != null) {
|
||||
var json = JsonUtils.decodeMap(this.UniqueAttrNumWeight, Integer.class, Integer.class);
|
||||
|
||||
for (var entry : json.entrySet()) {
|
||||
this.uniqueAttrNum.add(entry.getValue(), entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import emu.nebula.util.WeightedList;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "CharGemAttrType.json")
|
||||
public class CharGemAttrTypeDef extends BaseDef {
|
||||
private int Id;
|
||||
private int GroupId;
|
||||
|
||||
private transient WeightedList<CharGemAttrValueDef> values;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
public CharGemAttrValueDef getRandomValueData() {
|
||||
return this.getValues().next();
|
||||
}
|
||||
|
||||
public int getRandomValue() {
|
||||
return this.getRandomValueData().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.values = new WeightedList<>();
|
||||
|
||||
var data = GameData.getCharGemAttrGroupDataTable().get(this.GroupId);
|
||||
if (data != null) {
|
||||
data.getAttributeTypes().add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import emu.nebula.data.ResourceType.LoadPriority;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "CharGemAttrValue.json", loadPriority = LoadPriority.LOW)
|
||||
public class CharGemAttrValueDef extends BaseDef {
|
||||
private int Id;
|
||||
private int TypeId;
|
||||
private int AttrType;
|
||||
private int AttrTypeFirstSubtype;
|
||||
private int AttrTypeSecondSubtype;
|
||||
private int Rarity;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
var data = GameData.getCharGemAttrTypeDataTable().get(this.TypeId);
|
||||
if (data != null) {
|
||||
data.getValues().add(this.getRarity(), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
24
src/main/java/emu/nebula/data/resources/CharGemDef.java
Normal file
24
src/main/java/emu/nebula/data/resources/CharGemDef.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "CharGem.json")
|
||||
public class CharGemDef extends BaseDef {
|
||||
private int Id;
|
||||
private int GenerateCostTid;
|
||||
private int RefreshCostTid;
|
||||
private int Type;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
public CharGemSlotControlDef getControlData() {
|
||||
return GameData.getCharGemSlotControlDataTable().get(this.Type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import emu.nebula.util.WeightedList;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "CharGemSlotControl.json")
|
||||
public class CharGemSlotControlDef extends BaseDef {
|
||||
private int Id;
|
||||
private int Position;
|
||||
private int MaxAlterNum;
|
||||
private int UnlockLevel;
|
||||
|
||||
private int GeneratenCostQty;
|
||||
private int RefreshCostQty;
|
||||
|
||||
private int UniqueAttrGroupProb;
|
||||
private int UniqueAttrGroupId;
|
||||
private int GuaranteeCount;
|
||||
|
||||
private int[] AttrGroupId;
|
||||
|
||||
private int LockableNum;
|
||||
private int LockItemTid;
|
||||
private int LockItemQty;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
public IntList generateAttributes() {
|
||||
// Generate list of attributes
|
||||
var list = new IntArrayList();
|
||||
|
||||
// Add unique attributes
|
||||
if (this.UniqueAttrGroupId > 0) {
|
||||
var group = GameData.getCharGemAttrGroupDataTable().get(this.UniqueAttrGroupId);
|
||||
int num = group.getRandomUniqueAttrNum();
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
var attributeType = group.getRandomAttributeType(list);
|
||||
list.add(attributeType.getRandomValue());
|
||||
}
|
||||
|
||||
if (list.size() >= 4) {
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
// Get random attributes
|
||||
var random = new WeightedList<CharGemAttrGroupDef>();
|
||||
|
||||
for (var groupId : this.AttrGroupId) {
|
||||
var group = GameData.getCharGemAttrGroupDataTable().get(groupId);
|
||||
if (group == null || group.getWeight() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
random.add(group.getWeight(), group);
|
||||
}
|
||||
|
||||
// Add up to 4 attributes
|
||||
while (list.size() < 4) {
|
||||
var group = random.next();
|
||||
var attributeType = group.getRandomAttributeType(list);
|
||||
list.add(attributeType.getRandomValue());
|
||||
}
|
||||
|
||||
// Complete
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package emu.nebula.data.resources;
|
||||
import java.util.List;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import lombok.Getter;
|
||||
@@ -24,6 +25,8 @@ public class CharacterDef extends BaseDef {
|
||||
private int FragmentsId;
|
||||
private int TransformQty;
|
||||
|
||||
private int[] GemSlots;
|
||||
|
||||
private transient List<ChatDef> chats;
|
||||
|
||||
@Override
|
||||
@@ -39,6 +42,11 @@ public class CharacterDef extends BaseDef {
|
||||
return this.SkillsUpgradeGroup[index];
|
||||
}
|
||||
|
||||
public CharGemDef getCharGemData(int slotId) {
|
||||
int id = this.GemSlots[slotId - 1];
|
||||
return GameData.getCharGemDataTable().get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.chats = new ObjectArrayList<>();
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package emu.nebula.game.character;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.types.Binary;
|
||||
import org.bson.types.ObjectId;
|
||||
@@ -7,6 +10,7 @@ import org.bson.types.ObjectId;
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Id;
|
||||
import dev.morphia.annotations.Indexed;
|
||||
import dev.morphia.annotations.PostLoad;
|
||||
import dev.morphia.annotations.PreLoad;
|
||||
import emu.nebula.GameConstants;
|
||||
import emu.nebula.Nebula;
|
||||
@@ -49,9 +53,14 @@ public class Character implements GameDatabaseObject {
|
||||
private int skin;
|
||||
private int[] skills;
|
||||
private Bitset talents;
|
||||
private CharacterContact contact;
|
||||
private long createTime;
|
||||
|
||||
private int gemPresetIndex;
|
||||
private List<CharacterGemPreset> gemPresets;
|
||||
private CharacterGemSlot[] gemSlots;
|
||||
|
||||
private CharacterContact contact;
|
||||
|
||||
@Deprecated // Morphia only!
|
||||
public Character() {
|
||||
|
||||
@@ -66,12 +75,13 @@ public class Character implements GameDatabaseObject {
|
||||
this.playerUid = player.getUid();
|
||||
this.charId = data.getId();
|
||||
this.data = data;
|
||||
this.createTime = Nebula.getCurrentTime();
|
||||
|
||||
this.level = 1;
|
||||
this.skin = data.getDefaultSkinId();
|
||||
this.skills = new int[] {1, 1, 1, 1, 1};
|
||||
this.talents = new Bitset();
|
||||
this.createTime = Nebula.getCurrentTime();
|
||||
|
||||
this.contact = new CharacterContact(this);
|
||||
}
|
||||
|
||||
@@ -352,6 +362,152 @@ public class Character implements GameDatabaseObject {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Gems
|
||||
|
||||
public boolean hasGemPreset(int index) {
|
||||
return index >= 0 && index < this.getGemPresets().size();
|
||||
}
|
||||
|
||||
public CharacterGemPreset getCurrentGemPreset() {
|
||||
return this.getGemPreset(this.getGemPresetIndex());
|
||||
}
|
||||
|
||||
public CharacterGemPreset getGemPreset(int presetIndex) {
|
||||
while (this.getGemPresetIndex() >= this.getGemPresets().size()) {
|
||||
this.getGemPresets().add(new CharacterGemPreset(this));
|
||||
}
|
||||
|
||||
return this.getGemPresets().get(presetIndex);
|
||||
}
|
||||
|
||||
public boolean setCurrentGemPreset(int index) {
|
||||
// Sanity check
|
||||
if (index < 0 || index >= GameConstants.CHARACTER_MAX_GEM_PRESETS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set current preset and save to database
|
||||
this.gemPresetIndex = index;
|
||||
this.save();
|
||||
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
||||
public CharacterGem getGem(CharacterGemPreset preset, int slotId) {
|
||||
// Get gem index
|
||||
int gemIndex = preset.getGemIndex(slotId - 1);
|
||||
|
||||
if (gemIndex <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get gem slot
|
||||
var slot = this.getGemSlot(slotId);
|
||||
|
||||
if (slot == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get gem from the slot using preset index
|
||||
return slot.getGem(gemIndex);
|
||||
}
|
||||
|
||||
public boolean equipGem(int presetIndex, int slotId, int gemIndex) {
|
||||
// Sanity check
|
||||
if (presetIndex < 0 || presetIndex >= GameConstants.CHARACTER_MAX_GEM_PRESETS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get preset
|
||||
var preset = this.getGemPreset(presetIndex);
|
||||
|
||||
// Set gem index in preset
|
||||
boolean success = preset.setGemIndex(slotId, gemIndex);
|
||||
|
||||
// Save if successful
|
||||
if (success) {
|
||||
this.save();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public boolean hasGemSlot(int slotId) {
|
||||
// Calculate index from slot id
|
||||
int index = slotId - 1;
|
||||
|
||||
// Sanity check
|
||||
if (index < 0 || index >= this.getGemSlots().length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.gemSlots[index] != null;
|
||||
}
|
||||
|
||||
public CharacterGemSlot getGemSlot(int slotId) {
|
||||
// Calculate index from slot id
|
||||
int index = slotId - 1;
|
||||
|
||||
// Sanity check
|
||||
if (index < 0 || index >= this.getGemSlots().length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create gem slot object if it doesnt exist
|
||||
if (this.gemSlots[index] == null) {
|
||||
this.gemSlots[index] = new CharacterGemSlot(slotId);
|
||||
}
|
||||
|
||||
return this.gemSlots[index];
|
||||
}
|
||||
|
||||
public synchronized PlayerChangeInfo generateGem(int slotId) {
|
||||
// Get gem slot
|
||||
var slot = this.getGemSlot(slotId);
|
||||
if (slot == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Skip if slot is full
|
||||
if (slot.isFull()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get gem data
|
||||
var gemData = this.getData().getCharGemData(slotId);
|
||||
var gemControl = gemData.getControlData();
|
||||
|
||||
// Check character level
|
||||
if (this.getLevel() < gemControl.getUnlockLevel()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Make sure the player has the materials to craft the emblem
|
||||
if (!getPlayer().getInventory().hasItem(gemData.getGenerateCostTid(), gemControl.getGeneratenCostQty())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Generate attributes and create gem
|
||||
var attributes = gemControl.generateAttributes();
|
||||
var gem = new CharacterGem(attributes);
|
||||
|
||||
// Add gem to slot
|
||||
slot.getGems().add(gem);
|
||||
|
||||
// Save to database
|
||||
this.save();
|
||||
|
||||
// Consume materials
|
||||
var change = getPlayer().getInventory().removeItem(gemData.getGenerateCostTid(), gemControl.getGeneratenCostQty());
|
||||
|
||||
// Set change info extra info
|
||||
change.setExtraData(gem);
|
||||
|
||||
// Success
|
||||
return change;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
public Char toProto() {
|
||||
@@ -363,24 +519,36 @@ public class Character implements GameDatabaseObject {
|
||||
.setTalentNodes(this.getTalents().toByteArray())
|
||||
.addAllSkillLvs(this.getSkills())
|
||||
.setCreateTime(this.getCreateTime());
|
||||
|
||||
|
||||
// Encode gem presets
|
||||
var gemPresets = proto.getMutableCharGemPresets()
|
||||
.getMutableCharGemPresets();
|
||||
.setInUsePresetIndex(this.getGemPresetIndex())
|
||||
.getMutableCharGemPresets();
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
var preset = CharGemPreset.newInstance()
|
||||
.addAllSlotGem(-1, -1, -1);
|
||||
for (int i = 0; i < GameConstants.CHARACTER_MAX_GEM_PRESETS; i++) {
|
||||
CharGemPreset info = null;
|
||||
|
||||
if (this.hasGemPreset(i)) {
|
||||
info = getGemPresets().get(i).toProto();
|
||||
} else {
|
||||
info = CharGemPreset.newInstance()
|
||||
.addAllSlotGem(-1, -1, -1);
|
||||
}
|
||||
|
||||
gemPresets.add(preset);
|
||||
gemPresets.add(info);
|
||||
}
|
||||
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
var slot = CharGemSlot.newInstance()
|
||||
.setId(i);
|
||||
|
||||
proto.addCharGemSlots(slot);
|
||||
// Encode gems
|
||||
for (int i = 1; i <= GameConstants.CHARACTER_MAX_GEM_SLOTS; i++) {
|
||||
if (this.hasGemSlot(i)) {
|
||||
var slot = this.getGemSlot(i);
|
||||
proto.addCharGemSlots(slot.toProto());
|
||||
} else {
|
||||
proto.addCharGemSlots(CharGemSlot.newInstance().setId(i));
|
||||
}
|
||||
}
|
||||
|
||||
// Affinity quests
|
||||
proto.getMutableAffinityQuests();
|
||||
|
||||
return proto;
|
||||
@@ -394,12 +562,21 @@ public class Character implements GameDatabaseObject {
|
||||
.setTalentNodes(this.getTalents().toByteArray())
|
||||
.addAllSkillLvs(this.getSkills());
|
||||
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
var slot = StarTowerCharGem.newInstance()
|
||||
.setSlotId(i)
|
||||
.addAllAttributes(new int[] {0, 0, 0, 0});
|
||||
// Encode gems
|
||||
var preset = this.getCurrentGemPreset();
|
||||
|
||||
for (int i = 1; i <= preset.getLength(); i++) {
|
||||
var gem = this.getGem(preset, i);
|
||||
var info = StarTowerCharGem.newInstance()
|
||||
.setSlotId(i);
|
||||
|
||||
proto.addGems(slot);
|
||||
if (gem != null) {
|
||||
info.addAllAttributes(gem.getAttributes());
|
||||
} else {
|
||||
info.addAllAttributes(new int[] {0, 0, 0, 0});
|
||||
}
|
||||
|
||||
proto.addGems(info);
|
||||
}
|
||||
|
||||
return proto;
|
||||
@@ -408,11 +585,24 @@ public class Character implements GameDatabaseObject {
|
||||
// Database fix
|
||||
|
||||
@PreLoad
|
||||
public void onLoad(Document doc) {
|
||||
public void preLoad(Document doc) {
|
||||
var talents = doc.get("talents");
|
||||
if (talents != null && talents.getClass() == Binary.class) {
|
||||
doc.remove("talents");
|
||||
this.talents = new Bitset();
|
||||
}
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
public void postLoad() {
|
||||
if (this.gemSlots == null) {
|
||||
// Create gem slots array if it didn't exist
|
||||
this.gemSlots = new CharacterGemSlot[GameConstants.CHARACTER_MAX_GEM_SLOTS];
|
||||
}
|
||||
|
||||
if (this.gemPresets == null) {
|
||||
// Create gem presets list if it didn't exist
|
||||
this.gemPresets = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
39
src/main/java/emu/nebula/game/character/CharacterGem.java
Normal file
39
src/main/java/emu/nebula/game/character/CharacterGem.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package emu.nebula.game.character;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.nebula.proto.Public.CharGem;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Entity(useDiscriminator = false)
|
||||
public class CharacterGem {
|
||||
private boolean locked;
|
||||
private int[] attributes;
|
||||
private int[] alterAttributes;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public CharacterGem() {
|
||||
|
||||
}
|
||||
|
||||
public CharacterGem(IntList attributes) {
|
||||
this.attributes = attributes.toIntArray();
|
||||
this.alterAttributes = new int[4];
|
||||
}
|
||||
|
||||
public void setLocked(boolean locked) {
|
||||
this.locked = locked;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
public CharGem toProto() {
|
||||
var proto = CharGem.newInstance()
|
||||
.setLock(this.isLocked())
|
||||
.addAllAttributes(this.getAttributes())
|
||||
.addAllAlterAttributes(this.getAlterAttributes());
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package emu.nebula.game.character;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.nebula.proto.Public.CharGemPreset;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Entity(useDiscriminator = false)
|
||||
public class CharacterGemPreset {
|
||||
private String name;
|
||||
private int[] gems;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public CharacterGemPreset() {
|
||||
|
||||
}
|
||||
|
||||
public CharacterGemPreset(Character character) {
|
||||
this.gems = new int[] {-1, -1, -1};
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return this.getGems().length;
|
||||
}
|
||||
|
||||
public int getGemIndex(int slotIndex) {
|
||||
if (slotIndex < 0 || slotIndex >= this.getLength()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return this.getGems()[slotIndex];
|
||||
}
|
||||
|
||||
public boolean setGemIndex(int slotId, int gemIndex) {
|
||||
int slotIndex = slotId - 1;
|
||||
|
||||
if (slotIndex < 0 || slotIndex >= this.getLength()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.getGems()[slotIndex] = gemIndex;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
public CharGemPreset toProto() {
|
||||
var proto = CharGemPreset.newInstance()
|
||||
.addAllSlotGem(this.getGems());
|
||||
|
||||
if (this.getName() != null) {
|
||||
proto.setName(this.getName());
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package emu.nebula.game.character;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.nebula.GameConstants;
|
||||
import emu.nebula.proto.Public.CharGemSlot;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Entity(useDiscriminator = false)
|
||||
public class CharacterGemSlot {
|
||||
private int id;
|
||||
private List<CharacterGem> gems;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public CharacterGemSlot() {
|
||||
|
||||
}
|
||||
|
||||
public CharacterGemSlot(int id) {
|
||||
this.id = id;
|
||||
this.gems = new ArrayList<>();
|
||||
}
|
||||
|
||||
public CharacterGem getGem(int gemId) {
|
||||
if (gemId < 0 || gemId >= this.getGems().size()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.getGems().get(gemId);
|
||||
}
|
||||
|
||||
public boolean isFull() {
|
||||
return getGems().size() >= GameConstants.CHARACTER_MAX_GEMS_PER_SLOT;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
public CharGemSlot toProto() {
|
||||
var proto = CharGemSlot.newInstance()
|
||||
.setId(this.getId());
|
||||
|
||||
for (var gem : this.getGems()) {
|
||||
proto.addAlterGems(gem.toProto());
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.CharGemEquipGem.CharGemEquipGemReq;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
@HandlerId(NetMsgId.char_gem_equip_gem_req)
|
||||
public class HandlerCharGemEquipGemReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = CharGemEquipGemReq.parseFrom(message);
|
||||
|
||||
// Get character
|
||||
var character = session.getPlayer().getCharacters().getCharacterById(req.getCharId());
|
||||
|
||||
if (character == null) {
|
||||
return session.encodeMsg(NetMsgId.char_gem_equip_gem_failed_ack);
|
||||
}
|
||||
|
||||
// Equip gem
|
||||
boolean success = character.equipGem(req.getPresetId(), req.getSlotId(), req.getGemIndex());
|
||||
|
||||
if (success == false) {
|
||||
return session.encodeMsg(NetMsgId.char_gem_equip_gem_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.char_gem_equip_gem_succeed_ack);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.CharGemGenerate.CharGemGenerateReq;
|
||||
import emu.nebula.proto.CharGemGenerate.CharGemGenerateResp;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.game.character.CharacterGem;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
@HandlerId(NetMsgId.char_gem_generate_req)
|
||||
public class HandlerCharGemGenerateReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = CharGemGenerateReq.parseFrom(message);
|
||||
|
||||
// Get character
|
||||
var character = session.getPlayer().getCharacters().getCharacterById(req.getCharId());
|
||||
if (character == null) {
|
||||
return session.encodeMsg(NetMsgId.char_gem_generate_failed_ack);
|
||||
}
|
||||
|
||||
// Generate gem
|
||||
var change = character.generateGem(req.getSlotId());
|
||||
|
||||
if (change == null) {
|
||||
return session.encodeMsg(NetMsgId.char_gem_generate_failed_ack);
|
||||
}
|
||||
|
||||
var gem = (CharacterGem) change.getExtraData();
|
||||
|
||||
// Build response
|
||||
var rsp = CharGemGenerateResp.newInstance()
|
||||
.setChangeInfo(change.toProto())
|
||||
.setCharGem(gem.toProto());
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.char_gem_generate_succeed_ack, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.CharGemUsePreset.CharGemUsePresetReq;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
@HandlerId(NetMsgId.char_gem_use_preset_req)
|
||||
public class HandlerCharGemUsePresetReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = CharGemUsePresetReq.parseFrom(message);
|
||||
|
||||
// Get character
|
||||
var character = session.getPlayer().getCharacters().getCharacterById(req.getCharId());
|
||||
|
||||
if (character == null) {
|
||||
return session.encodeMsg(NetMsgId.char_gem_use_preset_failed_ack);
|
||||
}
|
||||
|
||||
// Use preset
|
||||
boolean success = character.setCurrentGemPreset(req.getPresetId());
|
||||
|
||||
if (success == false) {
|
||||
return session.encodeMsg(NetMsgId.char_gem_use_preset_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.char_gem_use_preset_succeed_ack);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user