Fix disc secondary skills

This commit is contained in:
Melledy
2025-12-04 16:25:18 -08:00
parent be84e0f406
commit c19aa5d0a1
5 changed files with 156 additions and 3 deletions

View File

@@ -52,6 +52,8 @@ public class GameData {
@Getter private static DataTable<DiscPromoteDef> DiscPromoteDataTable = new DataTable<>();
@Getter private static DataTable<DiscPromoteLimitDef> DiscPromoteLimitDataTable = new DataTable<>();
@Getter private static DataTable<SecondarySkillDef> SecondarySkillDataTable = new DataTable<>();
// Items
@Getter private static DataTable<ItemDef> ItemDataTable = new DataTable<>();
@Getter private static DataTable<ProductionDef> ProductionDataTable = new DataTable<>();

View File

@@ -18,6 +18,9 @@ public class DiscDef extends BaseDef {
private int TransformItemId;
private int[] MaxStarTransformItem;
private int[] ReadReward;
private int SecondarySkillGroupId1;
private int SecondarySkillGroupId2;
private int SubNoteSkillGroupId;
private transient ElementType elementType;

View File

@@ -0,0 +1,61 @@
package emu.nebula.data.resources;
import java.util.ArrayList;
import java.util.List;
import emu.nebula.data.BaseDef;
import emu.nebula.data.ResourceType;
import emu.nebula.game.inventory.ItemParamMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import lombok.Getter;
@Getter
@ResourceType(name = "SecondarySkill.json")
public class SecondarySkillDef extends BaseDef {
private int Id;
private int GroupId;
private int Score;
private String NeedSubNoteSkills;
private transient ItemParamMap reqSubNotes;
@Getter
private static transient Int2ObjectMap<List<SecondarySkillDef>> groups = new Int2ObjectOpenHashMap<>();
@Override
public int getId() {
return Id;
}
public boolean match(ItemParamMap subNotes) {
for (var item : this.reqSubNotes) {
int reqId = item.getIntKey();
int reqCount = item.getIntValue();
int curCount = subNotes.get(reqId);
if (curCount < reqCount) {
return false;
}
}
return true;
}
@Override
public void onLoad() {
// Setup required subnotes
this.reqSubNotes = ItemParamMap.fromJsonString(this.NeedSubNoteSkills);
// Add to group cache
var group = groups.computeIfAbsent(this.GroupId, id -> new ArrayList<>());
group.add(this);
// Clear to save memory
this.NeedSubNoteSkills = null;
}
public static List<SecondarySkillDef> getGroup(int id) {
return groups.get(id);
}
}

View File

@@ -7,6 +7,7 @@ import dev.morphia.annotations.Id;
import dev.morphia.annotations.Indexed;
import emu.nebula.Nebula;
import emu.nebula.data.GameData;
import emu.nebula.data.resources.SecondarySkillDef;
import emu.nebula.database.GameDatabaseObject;
import emu.nebula.game.character.GameCharacter;
import emu.nebula.game.character.GameDisc;
@@ -19,7 +20,8 @@ import emu.nebula.proto.PublicStarTower.StarTowerBuildDetail;
import emu.nebula.proto.PublicStarTower.StarTowerBuildInfo;
import emu.nebula.proto.PublicStarTower.TowerBuildChar;
import emu.nebula.util.Snowflake;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import lombok.Getter;
@Getter
@@ -42,6 +44,8 @@ public class StarTowerBuild implements GameDatabaseObject {
private ItemParamMap potentials;
private ItemParamMap subNoteSkills;
private IntList secondarySkills;
@Deprecated
public StarTowerBuild() {
@@ -54,6 +58,7 @@ public class StarTowerBuild implements GameDatabaseObject {
this.charPots = new ItemParamMap();
this.potentials = new ItemParamMap();
this.subNoteSkills = new ItemParamMap();
this.secondarySkills = new IntArrayList();
}
public StarTowerBuild(StarTowerGame game) {
@@ -129,13 +134,70 @@ public class StarTowerBuild implements GameDatabaseObject {
Nebula.getGameDatabase().update(this, this.getUid(), "preference", this.isPreference());
}
// Secondary skills
private void calculateSecondarySkills() {
// Reset active secondary skills
if (this.secondarySkills == null) {
this.secondarySkills = new IntArrayList();
} else {
this.secondarySkills.clear();
}
// Get first 3 discs
for (int i = 0; i < 3; i++) {
// Disc id
int discId = this.getDiscIds()[i];
// Get disc data
var data = GameData.getDiscDataTable().get(discId);
if (data == null) continue;
// Add secondary skills
int s1= this.getSecondarySkill(data.getSecondarySkillGroupId1());
if (s1 > 0) {
this.getSecondarySkills().add(s1);
}
int s2 = this.getSecondarySkill(data.getSecondarySkillGroupId2());
if (s2 > 0) {
this.getSecondarySkills().add(s2);
}
}
}
private int getSecondarySkill(int groupId) {
// Check group id
if (groupId <= 0) {
return 0;
}
// Get group
var group = SecondarySkillDef.getGroup(groupId);
if (group == null) {
return 0;
}
// Reverse iterator to try and match highest secondary skill first
for (int i = group.size() - 1; i >= 0; i--) {
var data = group.get(i);
if (data.match(this.getSubNoteSkills())) {
return data.getId();
}
}
// Failure
return 0;
}
// Score
public int calculateScore() {
// Clear score
this.score = 0;
// Potentials
// Add score from potentials
for (var potential : this.getPotentials().int2IntEntrySet()) {
var data = GameData.getPotentialDataTable().get(potential.getIntKey());
if (data == null) continue;
@@ -143,11 +205,22 @@ public class StarTowerBuild implements GameDatabaseObject {
this.score += data.getBuildScore(potential.getIntValue());
}
// Sub note skills
// Add score from sub note skills
for (var item : this.getSubNoteSkills()) {
this.score += item.getIntValue() * 15;
}
// Calculate secondary skills
this.calculateSecondarySkills();
// Add score from secondary skills
for (int id : this.getSecondarySkills()) {
var data = GameData.getSecondarySkillDataTable().get(id);
if (data == null) continue;
this.score += data.getScore();
}
// Complete
return this.score;
}
@@ -204,6 +277,11 @@ public class StarTowerBuild implements GameDatabaseObject {
proto.addSubNoteSkills(skill);
}
// Secondary skills
for (int id : this.getSecondarySkills()) {
proto.addActiveSecondaryIds(id);
}
return proto;
}

View File

@@ -327,9 +327,18 @@ public class StarTowerManager extends PlayerManager {
// Database
public void loadFromDatabase() {
// Init builds
this.builds = new Long2ObjectOpenHashMap<>();
// Load builds with the current player's uid
Nebula.getGameDatabase().getObjects(StarTowerBuild.class, "playerUid", getPlayerUid()).forEach(build -> {
// Fix outdated builds
if (build.getSecondarySkills() == null) {
build.calculateScore();
build.save();
}
// Add build
this.builds.put(build.getUid(), build);
});
}