Basic implementation of character emblems

This commit is contained in:
Melledy
2025-11-16 10:16:07 -08:00
parent f2656903e5
commit 6b699d97ee
15 changed files with 739 additions and 19 deletions
@@ -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);
}
}
}
@@ -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<>();