Implement !autobuild command

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.
This commit is contained in:
Melledy committed 2025-12-20 04:20:34 -08:00
1 parent b5fde4433d
commit 53839b48ca
7 files changed
+537 -75

No files matched your search

@@ -35,7 +35,7 @@ public class BuildCommand implements CommandHandler {
int id = Utils.parseSafeInt(arg);
int count = 1;
this.parseItem(builder, id, count);
builder.parseItem(id, count);
}
if (args.getMap() != null) {
@@ -43,7 +43,7 @@ public class BuildCommand implements CommandHandler {
int id = entry.getIntKey();
int count = entry.getIntValue();
this.parseItem(builder, id, count);
builder.parseItem(id, count);
}
}
@@ -66,55 +66,17 @@ public class BuildCommand implements CommandHandler {
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;
String result = "Created record for " + target.getName();
if (args.getSender() == null) {
result += " (This command may take time to update on the client)";
}
// 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
}
}
return result;
}
@Getter
private static class StarTowerBuildData {
public static class StarTowerBuildData {
private Player player;
private StarTowerBuild build;
private List<GameCharacter> characters;
@@ -127,6 +89,50 @@ public class BuildCommand implements CommandHandler {
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;