mirror of
https://github.com/Melledy/Nebula.git
synced 2026-09-19 17:19:58 +02:00
Implement !build command for creating records
This commit is contained in:
@@ -0,0 +1,179 @@
|
|||||||
|
package emu.nebula.command.commands;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import emu.nebula.command.Command;
|
||||||
|
import emu.nebula.command.CommandArgs;
|
||||||
|
import emu.nebula.command.CommandHandler;
|
||||||
|
import emu.nebula.data.GameData;
|
||||||
|
import emu.nebula.game.character.GameCharacter;
|
||||||
|
import emu.nebula.game.character.GameDisc;
|
||||||
|
import emu.nebula.game.player.Player;
|
||||||
|
import emu.nebula.game.tower.StarTowerBuild;
|
||||||
|
import emu.nebula.net.NetMsgId;
|
||||||
|
import emu.nebula.util.Utils;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Command(
|
||||||
|
label = "build",
|
||||||
|
aliases = {"b", "record", "r"},
|
||||||
|
permission = "player.build",
|
||||||
|
requireTarget = true,
|
||||||
|
desc = "!build [char ids...] [disc ids...] [potential ids...] [melody ids...]"
|
||||||
|
)
|
||||||
|
public class BuildCommand implements CommandHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String execute(CommandArgs args) {
|
||||||
|
// Create record
|
||||||
|
var target = args.getTarget();
|
||||||
|
var builder = new StarTowerBuildData(target);
|
||||||
|
|
||||||
|
// Parse items
|
||||||
|
for (String arg : args.getList()) {
|
||||||
|
int id = Utils.parseSafeInt(arg);
|
||||||
|
int count = 1;
|
||||||
|
|
||||||
|
this.parseItem(builder, id, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.getMap() != null) {
|
||||||
|
for (var entry : args.getMap().int2IntEntrySet()) {
|
||||||
|
int id = entry.getIntKey();
|
||||||
|
int count = entry.getIntValue();
|
||||||
|
|
||||||
|
this.parseItem(builder, id, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if build is valid
|
||||||
|
if (builder.getCharacters().size() != 3) {
|
||||||
|
return "Record must have 3 different characters";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (builder.getDiscs().size() < 3 || builder.getDiscs().size() > 6) {
|
||||||
|
return "Record must have 3-6 different discs";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create record
|
||||||
|
var build = builder.toBuild();
|
||||||
|
|
||||||
|
// Add to star tower manager
|
||||||
|
target.getStarTowerManager().getBuilds().put(build.getUid(), build);
|
||||||
|
|
||||||
|
// Send package to player
|
||||||
|
target.addNextPackage(NetMsgId.st_import_build_notify, build.toProto());
|
||||||
|
|
||||||
|
// Send result to player
|
||||||
|
return "Created record for " + target.getName() + " (This command make take time to update on the client)";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseItem(StarTowerBuildData builder, int id, int count) {
|
||||||
|
// Get item data
|
||||||
|
var itemData = GameData.getItemDataTable().get(id);
|
||||||
|
if (itemData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clamp
|
||||||
|
count = Math.max(count, 1);
|
||||||
|
|
||||||
|
// Parse by item id
|
||||||
|
switch (itemData.getItemSubType()) {
|
||||||
|
case Char -> {
|
||||||
|
var character = builder.getPlayer().getCharacters().getCharacterById(id);
|
||||||
|
if (character == null || !character.getData().isAvailable()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.addCharacter(character);
|
||||||
|
}
|
||||||
|
case Disc -> {
|
||||||
|
var disc = builder.getPlayer().getCharacters().getDiscById(id);
|
||||||
|
if (disc == null || !disc.getData().isAvailable()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.addDisc(disc);
|
||||||
|
}
|
||||||
|
case Potential, SpecificPotential -> {
|
||||||
|
var potentialData = GameData.getPotentialDataTable().get(id);
|
||||||
|
if (potentialData == null) break;
|
||||||
|
|
||||||
|
int level = Math.min(count, potentialData.getMaxLevel());
|
||||||
|
builder.getBuild().getPotentials().add(id, level);
|
||||||
|
}
|
||||||
|
case SubNoteSkill -> {
|
||||||
|
builder.getBuild().getSubNoteSkills().add(id, count);
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
// Ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static class StarTowerBuildData {
|
||||||
|
private Player player;
|
||||||
|
private StarTowerBuild build;
|
||||||
|
private List<GameCharacter> characters;
|
||||||
|
private List<GameDisc> discs;
|
||||||
|
|
||||||
|
public StarTowerBuildData(Player player) {
|
||||||
|
this.player = player;
|
||||||
|
this.build = new StarTowerBuild(player);
|
||||||
|
this.characters = new ArrayList<>();
|
||||||
|
this.discs = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addCharacter(GameCharacter character) {
|
||||||
|
if (this.characters.contains(character)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.characters.add(character);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDisc(GameDisc disc) {
|
||||||
|
if (this.discs.contains(disc)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.discs.add(disc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StarTowerBuild toBuild() {
|
||||||
|
// Set characters and discs
|
||||||
|
build.setChars(this.getCharacters());
|
||||||
|
build.setDiscs(this.getDiscs());
|
||||||
|
|
||||||
|
// Clear character potential cache
|
||||||
|
build.getCharPots().clear();
|
||||||
|
|
||||||
|
for (int charId : build.getCharIds()) {
|
||||||
|
build.getCharPots().put(charId, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add potentials to character potential cache
|
||||||
|
var it = build.getPotentials().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
var potential = it.next();
|
||||||
|
|
||||||
|
var data = GameData.getPotentialDataTable().get(potential.getIntKey());
|
||||||
|
if (data == null || !build.getCharPots().containsKey(data.getCharId())) {
|
||||||
|
it.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
build.getCharPots().add(data.getCharId(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate score
|
||||||
|
build.calculateScore();
|
||||||
|
|
||||||
|
// Return build
|
||||||
|
return build;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,8 @@ public class PotentialDef extends BaseDef {
|
|||||||
private int MaxLevel;
|
private int MaxLevel;
|
||||||
private int[] BuildScore;
|
private int[] BuildScore;
|
||||||
|
|
||||||
|
private String BriefDesc;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return Id;
|
return Id;
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
package emu.nebula.game.tower;
|
package emu.nebula.game.tower;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import dev.morphia.annotations.Entity;
|
import dev.morphia.annotations.Entity;
|
||||||
import dev.morphia.annotations.Id;
|
import dev.morphia.annotations.Id;
|
||||||
import dev.morphia.annotations.Indexed;
|
import dev.morphia.annotations.Indexed;
|
||||||
import emu.nebula.Nebula;
|
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.character.GameCharacter;
|
||||||
|
import emu.nebula.game.character.GameDisc;
|
||||||
import emu.nebula.game.inventory.ItemParamMap;
|
import emu.nebula.game.inventory.ItemParamMap;
|
||||||
|
import emu.nebula.game.player.Player;
|
||||||
import emu.nebula.proto.Public.ItemTpl;
|
import emu.nebula.proto.Public.ItemTpl;
|
||||||
import emu.nebula.proto.PublicStarTower.BuildPotential;
|
import emu.nebula.proto.PublicStarTower.BuildPotential;
|
||||||
import emu.nebula.proto.PublicStarTower.StarTowerBuildBrief;
|
import emu.nebula.proto.PublicStarTower.StarTowerBuildBrief;
|
||||||
@@ -42,18 +47,23 @@ public class StarTowerBuild implements GameDatabaseObject {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public StarTowerBuild(StarTowerGame game) {
|
public StarTowerBuild(Player player) {
|
||||||
this.uid = Snowflake.newUid();
|
this.uid = Snowflake.newUid();
|
||||||
this.playerUid = game.getPlayer().getUid();
|
this.playerUid = player.getUid();
|
||||||
this.name = "";
|
this.name = "";
|
||||||
this.charPots = new ItemParamMap();
|
this.charPots = new ItemParamMap();
|
||||||
this.potentials = new ItemParamMap();
|
this.potentials = new ItemParamMap();
|
||||||
this.subNoteSkills = new ItemParamMap();
|
this.subNoteSkills = new ItemParamMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StarTowerBuild(StarTowerGame game) {
|
||||||
|
// Initialize basic variables
|
||||||
|
this(game.getPlayer());
|
||||||
|
|
||||||
// Characters
|
// Characters
|
||||||
this.charIds = game.getChars().stream()
|
this.charIds = game.getChars().stream()
|
||||||
.filter(d -> d.getId() > 0)
|
.filter(c -> c.getId() > 0)
|
||||||
.mapToInt(d -> d.getId())
|
.mapToInt(c -> c.getId())
|
||||||
.toArray();
|
.toArray();
|
||||||
|
|
||||||
// Discs
|
// Discs
|
||||||
@@ -85,7 +95,19 @@ public class StarTowerBuild implements GameDatabaseObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Caclulate record score and cache it
|
// Caclulate record score and cache it
|
||||||
this.score = this.calculateScore();
|
this.calculateScore();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChars(List<GameCharacter> characters) {
|
||||||
|
this.charIds = characters.stream()
|
||||||
|
.mapToInt(c -> c.getCharId())
|
||||||
|
.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiscs(List<GameDisc> discs) {
|
||||||
|
this.discIds = discs.stream()
|
||||||
|
.mapToInt(d -> d.getDiscId())
|
||||||
|
.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String newName) {
|
public void setName(String newName) {
|
||||||
@@ -109,9 +131,9 @@ public class StarTowerBuild implements GameDatabaseObject {
|
|||||||
|
|
||||||
// Score
|
// Score
|
||||||
|
|
||||||
private int calculateScore() {
|
public int calculateScore() {
|
||||||
// Init score
|
// Clear score
|
||||||
int score = 0;
|
this.score = 0;
|
||||||
|
|
||||||
// Potentials
|
// Potentials
|
||||||
for (var potential : this.getPotentials().int2IntEntrySet()) {
|
for (var potential : this.getPotentials().int2IntEntrySet()) {
|
||||||
@@ -119,16 +141,16 @@ public class StarTowerBuild implements GameDatabaseObject {
|
|||||||
if (data == null) continue;
|
if (data == null) continue;
|
||||||
|
|
||||||
int index = potential.getIntValue() - 1;
|
int index = potential.getIntValue() - 1;
|
||||||
score += data.getBuildScore()[index];
|
this.score += data.getBuildScore()[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sub note skills
|
// Sub note skills
|
||||||
for (var item : this.getSubNoteSkills()) {
|
for (var item : this.getSubNoteSkills()) {
|
||||||
score += item.getIntValue() * 15;
|
this.score += item.getIntValue() * 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete
|
// Complete
|
||||||
return score;
|
return this.score;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proto
|
// Proto
|
||||||
|
|||||||
@@ -17,12 +17,13 @@ import emu.nebula.data.GameData;
|
|||||||
import emu.nebula.data.ResourceType;
|
import emu.nebula.data.ResourceType;
|
||||||
import emu.nebula.data.resources.CharacterDef;
|
import emu.nebula.data.resources.CharacterDef;
|
||||||
import emu.nebula.data.resources.ItemDef;
|
import emu.nebula.data.resources.ItemDef;
|
||||||
|
import emu.nebula.data.resources.PotentialDef;
|
||||||
|
import emu.nebula.game.inventory.ItemType;
|
||||||
|
|
||||||
public class Handbook {
|
public class Handbook {
|
||||||
|
|
||||||
public static void generate() {
|
public static void generate() {
|
||||||
// Temp vars
|
// Temp vars
|
||||||
Map<String, String> languageKey = null;
|
|
||||||
List<Integer> list = null;
|
List<Integer> list = null;
|
||||||
|
|
||||||
// Save to file
|
// Save to file
|
||||||
@@ -41,31 +42,64 @@ public class Handbook {
|
|||||||
writer.println(System.lineSeparator());
|
writer.println(System.lineSeparator());
|
||||||
writer.println("# Characters");
|
writer.println("# Characters");
|
||||||
list = GameData.getCharacterDataTable().keySet().intStream().sorted().boxed().toList();
|
list = GameData.getCharacterDataTable().keySet().intStream().sorted().boxed().toList();
|
||||||
languageKey = loadLanguageKey(CharacterDef.class);
|
var characterLanguageKey = loadLanguageKey(CharacterDef.class);
|
||||||
for (int id : list) {
|
for (int id : list) {
|
||||||
CharacterDef data = GameData.getCharacterDataTable().get(id);
|
CharacterDef data = GameData.getCharacterDataTable().get(id);
|
||||||
writer.print(data.getId());
|
writer.print(data.getId());
|
||||||
writer.print(" : ");
|
writer.print(" : ");
|
||||||
writer.print(languageKey.getOrDefault(data.getName(), data.getName()));
|
writer.print(characterLanguageKey.getOrDefault(data.getName(), data.getName()));
|
||||||
writer.print(" (");
|
writer.print(" (");
|
||||||
writer.print(data.getElementType().toString());
|
writer.print(data.getElementType().toString());
|
||||||
writer.println(")");
|
writer.println(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump characters
|
// Dump items
|
||||||
writer.println(System.lineSeparator());
|
writer.println(System.lineSeparator());
|
||||||
writer.println("# Items");
|
writer.println("# Items");
|
||||||
list = GameData.getItemDataTable().keySet().intStream().sorted().boxed().toList();
|
list = GameData.getItemDataTable().keySet().intStream().sorted().boxed().toList();
|
||||||
languageKey = loadLanguageKey(ItemDef.class);
|
var itemLanguageKey = loadLanguageKey(ItemDef.class);
|
||||||
for (int id : list) {
|
for (int id : list) {
|
||||||
ItemDef data = GameData.getItemDataTable().get(id);
|
ItemDef data = GameData.getItemDataTable().get(id);
|
||||||
writer.print(data.getId());
|
writer.print(data.getId());
|
||||||
writer.print(" : ");
|
writer.print(" : ");
|
||||||
writer.print(languageKey.getOrDefault(data.getTitle(), data.getTitle()));
|
writer.print(itemLanguageKey.getOrDefault(data.getTitle(), data.getTitle()));
|
||||||
|
|
||||||
writer.print(" [");
|
writer.print(" [");
|
||||||
writer.print(data.getItemType());
|
writer.print(data.getItemType());
|
||||||
writer.println("]");
|
writer.print("]");
|
||||||
|
|
||||||
|
if (data.getItemType() == ItemType.Disc) {
|
||||||
|
var discData = GameData.getDiscDataTable().get(id);
|
||||||
|
if (discData != null) {
|
||||||
|
writer.print(" (");
|
||||||
|
writer.print(discData.getElementType().toString());
|
||||||
|
writer.print(")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.println("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump potentials
|
||||||
|
writer.println(System.lineSeparator());
|
||||||
|
writer.println("# Potentials");
|
||||||
|
list = GameData.getPotentialDataTable().keySet().intStream().sorted().boxed().toList();
|
||||||
|
var potentialLanguageKey = loadLanguageKey(PotentialDef.class);
|
||||||
|
for (int id : list) {
|
||||||
|
PotentialDef data = GameData.getPotentialDataTable().get(id);
|
||||||
|
writer.print(data.getId());
|
||||||
|
writer.print(" : ");
|
||||||
|
|
||||||
|
CharacterDef charData = GameData.getCharacterDataTable().get(data.getCharId());
|
||||||
|
writer.print("[");
|
||||||
|
writer.print(characterLanguageKey.getOrDefault(charData.getName(), charData.getName()));
|
||||||
|
writer.print("] ");
|
||||||
|
|
||||||
|
ItemDef itemData = GameData.getItemDataTable().get(id);
|
||||||
|
writer.print(itemLanguageKey.getOrDefault(itemData.getTitle(), itemData.getTitle()));
|
||||||
|
writer.print(" - ");
|
||||||
|
writer.print(potentialLanguageKey.getOrDefault(data.getBriefDesc(), data.getBriefDesc()));
|
||||||
|
writer.println("");
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
Reference in New Issue
Block a user