Implement !disc command and improve !giveall to apply properties

This commit is contained in:
Melledy
2025-11-18 03:12:10 -08:00
parent 6ac782e25c
commit 05555c684e
4 changed files with 161 additions and 17 deletions

View File

@@ -4,6 +4,7 @@ import java.util.List;
import emu.nebula.Nebula;
import emu.nebula.game.character.GameCharacter;
import emu.nebula.game.character.GameDisc;
import emu.nebula.game.player.Player;
import emu.nebula.util.Utils;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
@@ -54,7 +55,7 @@ public class CommandArgs {
} else if (arg.startsWith("a")) { // Advance
this.advance = Utils.parseSafeInt(arg.substring(1));
it.remove();
} else if (arg.startsWith("t")) { // Talents
} else if (arg.startsWith("t") || arg.startsWith("c")) { // Talents/Crescendo
this.talent = Utils.parseSafeInt(arg.substring(1));
it.remove();
} else if (arg.startsWith("s")) { // Skill
@@ -136,15 +137,19 @@ public class CommandArgs {
boolean hasChanged = false;
// Try to set level
if (this.getLevel() > 0 && character.getLevel() != this.getLevel()) {
character.setLevel(Math.min(this.getLevel(), 90));
int level = Math.min(this.getLevel(), 90);
if (level > 0 && character.getLevel() != level) {
character.setLevel(level);
character.setAdvance(Utils.getMinAdvanceForLevel(character.getLevel()));
hasChanged = true;
}
// Try to set advance (ascension level)
if (this.getAdvance() >= 0 && character.getAdvance() != this.getAdvance()) {
character.setAdvance(Math.min(this.getAdvance(), 8));
int advance = Math.min(this.getAdvance(), 8);
if (advance >= 0 && character.getAdvance() != advance) {
character.setAdvance(advance);
hasChanged = true;
}
@@ -188,4 +193,40 @@ public class CommandArgs {
return hasChanged;
}
/**
* Changes the properties of an disc based on the arguments provided
* @param disc The targeted disc to change
* @return A boolean of whether or not any changes were made to the disc
*/
public boolean setProperties(GameDisc disc) {
boolean hasChanged = false;
// Try to set level
int level = Math.min(this.getLevel(), 90);
if (level > 0 && disc.getLevel() != level) {
disc.setLevel(level);
disc.setPhase(Utils.getMinAdvanceForLevel(disc.getLevel()));
hasChanged = true;
}
// Try to set advance (ascension level)
int promotion = Math.min(this.getAdvance(), 8);
if (promotion >= 0 && disc.getPhase() != promotion) {
disc.setPhase(promotion);
hasChanged = true;
}
// Calculate how many talent stars we want to set
int star = Math.min(this.getTalent(), 5);
if (star >= 0 && disc.getStar() != star) {
disc.setStar(star);
hasChanged = true;
}
return hasChanged;
}
}

View File

@@ -0,0 +1,82 @@
package emu.nebula.command.commands;
import emu.nebula.util.Utils;
import emu.nebula.game.character.GameDisc;
import emu.nebula.net.NetMsgId;
import java.util.ArrayList;
import java.util.HashSet;
import emu.nebula.command.Command;
import emu.nebula.command.CommandArgs;
import emu.nebula.command.CommandHandler;
@Command(
label = "disc",
aliases = {"d"},
permission = "player.character",
requireTarget = true,
desc = "!d [all | {discId}] lv(level) a(ascension) c(crescendo level)"
)
public class DiscCommand implements CommandHandler {
@Override
public void execute(CommandArgs args) {
// Init
var player = args.getTarget();
var discs = new HashSet<GameDisc>();
// Parse args
for (String arg : args.getList()) {
// Lowercase
arg = arg.toLowerCase();
// Handle all discs
if (arg.equals("all")) {
discs.addAll(player.getCharacters().getDiscCollection());
continue;
}
// Parse disc id
int charId = Utils.parseSafeInt(arg);
var disc = player.getCharacters().getDiscById(charId);
if (disc == null) {
continue;
}
discs.add(disc);
}
// Sanity check
if (discs.isEmpty()) {
return;
}
// List of modified characters that we send to the client for updates
var modified = new ArrayList<GameDisc>();
// Modify characters
for (var disc : discs) {
// Apply changes
boolean changed = args.setProperties(disc);
if (changed) {
// Save to database
disc.save();
// Add to modified list
modified.add(disc);
}
}
if (modified.isEmpty()) {
return;
}
// Encode and send
for (var disc : modified) {
player.addNextPackage(NetMsgId.disc_reset_notify, disc.toProto());
}
}
}

View File

@@ -19,7 +19,7 @@ import emu.nebula.net.NetMsgId;
aliases = {"ga"},
permission = "player.give",
requireTarget = true,
desc = "!ga [characters | discs | materials]. Gives the targeted player items."
desc = "!ga [characters | discs | materials] lv(level) t(talent/crescendo level) s(skill level). Gives the targeted player items."
)
public class GiveAllCommand implements CommandHandler {
private static Set<ItemSubType> MATERIAL_ITEM_SUBTYPES = Set.of(
@@ -35,12 +35,15 @@ public class GiveAllCommand implements CommandHandler {
Player target = args.getTarget();
String type = args.get(0).toLowerCase();
var items = new ItemParamMap();
var change = new PlayerChangeInfo();
switch (type) {
default -> args.sendMessage("Error: Invalid type");
case "m", "materials", "mats" -> {
// Create items map
var items = new ItemParamMap();
// Check sub type
for (ItemDef data : GameData.getItemDataTable()) {
if (!MATERIAL_ITEM_SUBTYPES.contains(data.getItemSubType())) {
@@ -78,12 +81,15 @@ public class GiveAllCommand implements CommandHandler {
continue;
}
// Add
items.add(data.getId(), 1);
// Add to player
var disc = target.getCharacters().addDisc(data.getId());
// Set properties
args.setProperties(disc);
// Add to change info
change.add(disc.toProto());
}
// Add to target's inventory
target.getInventory().addItems(items, change);
// Send message
args.sendMessage("Giving " + target.getName() + " all discs");
@@ -101,12 +107,15 @@ public class GiveAllCommand implements CommandHandler {
continue;
}
// Add
items.add(data.getId(), 1);
// Add to player
var character = target.getCharacters().addCharacter(data.getId());
// Set properties
args.setProperties(character);
// Add to change info
change.add(character.toProto());
}
// Add to target's inventory
target.getInventory().addItems(items, change);
// Send message
args.sendMessage("Giving " + target.getName() + " all characters");

View File

@@ -70,6 +70,18 @@ public class GameDisc implements GameDatabaseObject {
}
}
public void setLevel(int level) {
this.level = level;
}
public void setPhase(int phase) {
this.phase = phase;
}
public void setStar(int star) {
this.star = star;
}
public SubNoteSkillPromoteGroupDef getSubNoteSkillDef() {
int id = (this.getData().getSubNoteSkillGroupId() * 100) + this.getPhase();
return GameData.getSubNoteSkillPromoteGroupDataTable().get(id);