mirror of
https://github.com/Melledy/Nebula.git
synced 2026-11-04 21:36:51 +01:00
The `!autobuild` (or `!ab`) command allows you to build a record without needing to add every id. Missing trekkers/discs/potentials/melodies will be auto selected by the server. Usage: `!autobuild [character/disc/potential/melody ids...] lv[target record level] s[target record score]` Examples: `!autobuild s99999` = Creates a record with a random main trekker with the max score. `!autobuild 103 lv30` = Creates a record with this trekker at record rank 30. `!autobuild 155 132 107 s25000` = Creates a record with these trekkers with a record score of about 25000. `!autobuild 103 510301 510302 510303 510304 lv20` = Creates a record with this trekker and these potentials at record rank 20. Notes: - Target level overrides target score. So a command of `!autobuild lv30 s1000` would have a record rank of 30 and NOT a score of 1000. - If there is no target level or score, the command will default to a target level of 40. - You can only add trekkers/discs that you own.
186 lines
5.9 KiB
Java
186 lines
5.9 KiB
Java
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;
|
|
|
|
builder.parseItem(id, count);
|
|
}
|
|
|
|
if (args.getMap() != null) {
|
|
for (var entry : args.getMap().int2IntEntrySet()) {
|
|
int id = entry.getIntKey();
|
|
int count = entry.getIntValue();
|
|
|
|
builder.parseItem(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().addBuild(build);
|
|
|
|
// Send package to player
|
|
target.addNextPackage(NetMsgId.st_import_build_notify, build.toProto());
|
|
|
|
// Send result to player
|
|
String result = "Created record for " + target.getName();
|
|
|
|
if (args.getSender() == null) {
|
|
result += " (This command may take time to update on the client)";
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
@Getter
|
|
public 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 parseItem(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 = this.getPlayer().getCharacters().getCharacterById(id);
|
|
if (character == null || !character.getData().isAvailable()) {
|
|
break;
|
|
}
|
|
|
|
this.addCharacter(character);
|
|
}
|
|
case Disc -> {
|
|
var disc = this.getPlayer().getCharacters().getDiscById(id);
|
|
if (disc == null || !disc.getData().isAvailable()) {
|
|
break;
|
|
}
|
|
|
|
this.addDisc(disc);
|
|
}
|
|
case Potential, SpecificPotential -> {
|
|
var potentialData = GameData.getPotentialDataTable().get(id);
|
|
if (potentialData == null) break;
|
|
|
|
int level = Math.min(count, potentialData.getMaxLevel());
|
|
this.getBuild().getPotentials().add(id, level);
|
|
}
|
|
case SubNoteSkill -> {
|
|
this.getBuild().getSubNoteSkills().add(id, count);
|
|
}
|
|
default -> {
|
|
// Ignored
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|