Improve star tower case handling

This commit is contained in:
Melledy
2025-11-19 02:43:48 -08:00
parent 6704be5f98
commit 5c9f434825
5 changed files with 122 additions and 47 deletions

View File

@@ -5,6 +5,7 @@ import java.util.List;
import emu.nebula.data.BaseDef;
import emu.nebula.data.GameData;
import emu.nebula.data.ResourceType;
import emu.nebula.game.character.ElementType;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import lombok.Getter;
@@ -16,6 +17,7 @@ public class CharacterDef extends BaseDef {
private boolean Available;
private String Name;
private int Grade;
private int EET;
private int DefaultSkinId;
private int AdvanceSkinId;
@@ -29,6 +31,7 @@ public class CharacterDef extends BaseDef {
private int[] GemSlots;
private transient ElementType elementType;
private transient List<ChatDef> chats;
@Override
@@ -51,6 +54,7 @@ public class CharacterDef extends BaseDef {
@Override
public void onLoad() {
this.elementType = ElementType.getByValue(this.EET);
this.chats = new ObjectArrayList<>();
}
}

View File

@@ -2,6 +2,7 @@ package emu.nebula.data.resources;
import emu.nebula.data.BaseDef;
import emu.nebula.data.ResourceType;
import emu.nebula.game.character.ElementType;
import lombok.Getter;
@Getter
@@ -10,6 +11,7 @@ public class DiscDef extends BaseDef {
private int Id;
private boolean Visible;
private boolean Available;
private int EET;
private int StrengthenGroupId;
private int PromoteGroupId;
@@ -18,6 +20,8 @@ public class DiscDef extends BaseDef {
private int[] ReadReward;
private int SubNoteSkillGroupId;
private transient ElementType elementType;
@Override
public int getId() {
return Id;
@@ -25,6 +29,6 @@ public class DiscDef extends BaseDef {
@Override
public void onLoad() {
this.elementType = ElementType.getByValue(this.EET);
}
}

View File

@@ -0,0 +1,40 @@
package emu.nebula.game.character;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import lombok.Getter;
@Getter
public enum ElementType {
INHERIT (0),
WIND (1, 90020),
FIRE (2, 90019),
EARTH (3, 90021),
AQUA (4, 90018),
LIGHT (5, 90022),
DARK (6, 90023),
NONE (7);
private final int value;
private final int subNoteSkillItemId;
private final static Int2ObjectMap<ElementType> map = new Int2ObjectOpenHashMap<>();
static {
for (ElementType type : ElementType.values()) {
map.put(type.getValue(), type);
}
}
private ElementType(int value) {
this(value, 0);
}
private ElementType(int value, int subNoteSkillItemId) {
this.value = value;
this.subNoteSkillItemId = subNoteSkillItemId;
}
public static ElementType getByValue(int value) {
return map.get(value);
}
}

View File

@@ -21,6 +21,8 @@ import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp;
import emu.nebula.util.Snowflake;
import emu.nebula.util.Utils;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
@@ -62,16 +64,18 @@ public class StarTowerGame {
// Case
private int lastCaseId = 0;
private int battleCaseIndex = -1;
private int selectorCaseIndex = -1;
private int hawkerCaseIndex = -1;
private List<StarTowerCase> cases;
private Int2IntMap cachedCases;
private int pendingPotentialCases = 0;
// Bag
private ItemParamMap items;
private ItemParamMap res;
private ItemParamMap potentials;
// Sub note skill drop list
private IntList subNoteDropList;
// Cached build
private transient StarTowerBuild build;
private transient ItemParamMap newInfos;
@@ -108,20 +112,31 @@ public class StarTowerGame {
this.charIds = new IntArrayList();
this.cases = new ArrayList<>();
this.cachedCases = new Int2IntOpenHashMap();
this.items = new ItemParamMap();
this.res = new ItemParamMap();
this.potentials = new ItemParamMap();
this.newInfos = new ItemParamMap();
this.subNoteDropList = new IntArrayList();
// Init formation
for (int i = 0; i < 3; i++) {
int id = formation.getCharIdAt(i);
var character = getPlayer().getCharacters().getCharacterById(id);
if (character != null) {
this.chars.add(character.toStarTowerProto());
// Add to character id list
this.charIds.add(id);
// Add sub note skill id to drop list
int subNoteSkill = character.getData().getElementType().getSubNoteSkillItemId();
if (subNoteSkill > 0 && !this.subNoteDropList.contains(subNoteSkill)) {
this.subNoteDropList.add(subNoteSkill);
}
this.chars.add(character.toStarTowerProto());
} else {
this.chars.add(StarTowerChar.newInstance());
}
@@ -146,11 +161,16 @@ public class StarTowerGame {
}
}
// Finish setting up droppable sub note skills
for (int id : COMMON_SUB_NOTE_SKILLS) {
this.subNoteDropList.add(id);
}
// Add cases
this.addCase(new StarTowerCase(CaseType.Battle));
this.addCase(new StarTowerCase(CaseType.SyncHP));
// Debug
// Always keep the door open
var doorCase = this.addCase(new StarTowerCase(CaseType.OpenDoor));
doorCase.setFloorId(this.getStageFloor() + 1);
@@ -195,28 +215,25 @@ public class StarTowerGame {
// Cases
public StarTowerCase getBattleCase() {
if (this.getBattleCaseIndex() < 0 || this.getBattleCaseIndex() >= this.getCases().size()) {
public StarTowerCase getCase(CaseType type) {
// Check if we have any cached case for this case type
if (!this.getCachedCases().containsKey(type.getValue())) {
return null;
}
return this.getCases().get(this.getBattleCaseIndex());
// Get index of cached case
int index = this.getCachedCases().get(type.getValue());
// Sanity check just in case
if (index < 0 || index >= this.getCases().size()) {
return null;
}
return this.getCases().get(index);
}
public StarTowerCase getSelectorCase() {
if (this.getSelectorCaseIndex() < 0 || this.getSelectorCaseIndex() >= this.getCases().size()) {
return null;
}
return this.getCases().get(this.getSelectorCaseIndex());
}
public StarTowerCase getHawkerCase() {
if (this.getHawkerCaseIndex() < 0 || this.getHawkerCaseIndex() >= this.getCases().size()) {
return null;
}
return this.getCases().get(this.getHawkerCaseIndex());
public void cacheCaseIndex(StarTowerCase towerCase) {
this.getCachedCases().put(towerCase.getType().getValue(), this.getCases().size() - 1);
}
public StarTowerCase addCase(StarTowerCase towerCase) {
@@ -235,15 +252,10 @@ public class StarTowerGame {
cases.add(towerCase.toProto());
}
//
if (towerCase.getIds() != null) {
this.selectorCaseIndex = this.getCases().size() - 1;
} else if (towerCase.getType() == CaseType.Battle) {
this.battleCaseIndex = this.getCases().size() - 1;
} else if (towerCase.getType() == CaseType.Hawker) {
this.hawkerCaseIndex = this.getCases().size() - 1;
}
// Cache case index
this.cacheCaseIndex(towerCase);
// Complete
return towerCase;
}
@@ -285,7 +297,7 @@ public class StarTowerGame {
// Add potential
this.getPotentials().put(id, nextLevel);
// Add change
// Add to change info
var info = PotentialInfo.newInstance()
.setTid(id)
.setLevel(count);
@@ -296,7 +308,7 @@ public class StarTowerGame {
// Add to items
this.getItems().add(id, count);
// Add change
// Add to change info
var info = TowerItemInfo.newInstance()
.setTid(id)
.setQty(count);
@@ -310,7 +322,7 @@ public class StarTowerGame {
// Add to res
this.getRes().add(id, count);
// Add change
// Add to change info
var info = TowerResInfo.newInstance()
.setTid(id)
.setQty(count);
@@ -352,7 +364,7 @@ public class StarTowerGame {
private PlayerChangeInfo addRandomSubNoteSkills(PlayerChangeInfo change) {
int count = Utils.randomRange(1, 3);
int id = Utils.randomElement(COMMON_SUB_NOTE_SKILLS);
int id = Utils.randomElement(this.getSubNoteDropList());
this.addItem(id, count, change);
@@ -442,15 +454,20 @@ public class StarTowerGame {
this.addItem(GameConstants.STAR_TOWER_GOLD_ITEM_ID, money, change);
// Create potential selector
int charId = this.getChars().get(battleCount % this.getCharIds().size()).getId();
var potentialCase = this.createPotentialSelector(charId);
// Add potential selectors
this.pendingPotentialCases += 1;
// Add case
this.addCase(rsp.getMutableCases(), potentialCase);
// Handle pending potential selectors
if (this.pendingPotentialCases > 0) {
// Create potential selector
var potentialCase = this.createPotentialSelector(this.getRandomCharId());
this.addCase(rsp.getMutableCases(), potentialCase);
this.pendingPotentialCases--;
}
// Add sub note skills
var battleCase = this.getBattleCase();
var battleCase = this.getCase(CaseType.Battle);
if (battleCase != null) {
int subNoteSkills = battleCase.getSubNoteSkillNum();
this.addRandomSubNoteSkills(subNoteSkills, change);
@@ -472,7 +489,7 @@ public class StarTowerGame {
public StarTowerInteractResp onSelect(StarTowerInteractReq req, StarTowerInteractResp rsp) {
var index = req.getMutableSelectReq().getIndex();
var selectorCase = this.getSelectorCase();
var selectorCase = this.getCase(CaseType.SelectSpecialPotential);
if (selectorCase == null) {
return rsp;
}
@@ -488,6 +505,15 @@ public class StarTowerGame {
// Set change
rsp.setChange(change.toProto());
// Handle pending potential selectors
if (this.pendingPotentialCases > 0) {
// Create potential selector
var potentialCase = this.createPotentialSelector(this.getRandomCharId());
this.addCase(rsp.getMutableCases(), potentialCase);
this.pendingPotentialCases--;
}
return rsp;
}
@@ -527,11 +553,9 @@ public class StarTowerGame {
}
// Clear cases
this.battleCaseIndex = -1;
this.selectorCaseIndex = -1;
this.hawkerCaseIndex = -1;
this.lastCaseId = 0;
this.cases.clear();
this.cachedCases.clear();
// Add cases
var syncHpCase = new StarTowerCase(CaseType.SyncHP);
@@ -587,7 +611,7 @@ public class StarTowerGame {
rsp.getMutableNilResp();
// Get hawker case
var shop = this.getHawkerCase();
var shop = this.getCase(CaseType.Hawker);
if (shop == null || shop.getGoodsList() == null) {
return rsp;
}

View File

@@ -46,7 +46,10 @@ public class Handbook {
CharacterDef data = GameData.getCharacterDataTable().get(id);
writer.print(data.getId());
writer.print(" : ");
writer.println(languageKey.getOrDefault(data.getName(), data.getName()));
writer.print(languageKey.getOrDefault(data.getName(), data.getName()));
writer.print(" (");
writer.print(data.getElementType().toString());
writer.println(")");
}
// Dump characters