2025-02-10 18:33:05 -05:00
|
|
|
package kamkeel.npcs.command;
|
|
|
|
|
|
|
|
|
|
import net.minecraft.command.CommandException;
|
|
|
|
|
import net.minecraft.command.ICommandSender;
|
2025-02-11 22:05:34 -05:00
|
|
|
import noppes.npcs.controllers.CustomEffectController;
|
2025-02-20 21:40:39 -05:00
|
|
|
import noppes.npcs.controllers.PlayerDataController;
|
2025-02-10 18:33:05 -05:00
|
|
|
import noppes.npcs.controllers.data.CustomEffect;
|
|
|
|
|
import noppes.npcs.controllers.data.PlayerData;
|
2025-02-11 22:05:34 -05:00
|
|
|
import noppes.npcs.scripted.event.PlayerEvent.EffectEvent.ExpirationType;
|
2025-02-10 18:33:05 -05:00
|
|
|
|
2025-03-05 23:13:39 -05:00
|
|
|
import java.util.*;
|
2025-02-10 18:33:05 -05:00
|
|
|
|
2025-02-18 16:11:58 -05:00
|
|
|
import static kamkeel.npcs.util.ColorUtil.sendError;
|
|
|
|
|
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
|
|
|
|
|
2025-02-10 18:33:05 -05:00
|
|
|
public class EffectCommand extends CommandKamkeelBase {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getDescription() {
|
|
|
|
|
return "Custom Effect operations";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getCommandName() {
|
|
|
|
|
return "effect";
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-05 23:13:39 -05:00
|
|
|
// List command with pagination
|
|
|
|
|
@SubCommand(desc = "Lists all Effects", usage = "[page]")
|
2025-02-18 16:11:58 -05:00
|
|
|
public void list(ICommandSender sender, String[] args) throws CommandException {
|
2025-02-11 22:05:34 -05:00
|
|
|
CustomEffectController controller = CustomEffectController.getInstance();
|
|
|
|
|
if (controller.indexMapper.isEmpty()) {
|
|
|
|
|
sendError(sender, "No effects found.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-05 23:13:39 -05:00
|
|
|
// Flatten effects into a list
|
|
|
|
|
List<EffectEntry> effectsList = new ArrayList<>();
|
|
|
|
|
for (Map.Entry<Integer, HashMap<Integer, CustomEffect>> entry : controller.indexMapper.entrySet()) {
|
|
|
|
|
int idx = entry.getKey();
|
|
|
|
|
Map<Integer, CustomEffect> effects = entry.getValue();
|
2025-02-11 22:05:34 -05:00
|
|
|
if (effects == null || effects.isEmpty())
|
|
|
|
|
continue;
|
2025-03-05 23:13:39 -05:00
|
|
|
for (Map.Entry<Integer, CustomEffect> effectEntry : effects.entrySet()) {
|
|
|
|
|
int id = effectEntry.getKey();
|
|
|
|
|
CustomEffect effect = effectEntry.getValue();
|
|
|
|
|
effectsList.add(new EffectEntry(idx, id, effect));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Sort by index then by effect ID
|
|
|
|
|
Collections.sort(effectsList, Comparator.comparingInt((EffectEntry e) -> e.index)
|
|
|
|
|
.thenComparingInt(e -> e.id));
|
|
|
|
|
|
|
|
|
|
// Determine page number
|
|
|
|
|
int page = 1;
|
|
|
|
|
if (args.length > 0) {
|
|
|
|
|
try {
|
|
|
|
|
page = Integer.parseInt(args[0]);
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
// default to page 1
|
2025-02-11 22:05:34 -05:00
|
|
|
}
|
|
|
|
|
}
|
2025-03-05 23:13:39 -05:00
|
|
|
int perPage = 10;
|
|
|
|
|
int total = effectsList.size();
|
|
|
|
|
int totalPages = (int) Math.ceil(total / (double) perPage);
|
|
|
|
|
if (page < 1) page = 1;
|
|
|
|
|
if (page > totalPages) page = totalPages;
|
|
|
|
|
int startIndex = (page - 1) * perPage;
|
|
|
|
|
int endIndex = Math.min(startIndex + perPage, total);
|
2025-02-11 22:05:34 -05:00
|
|
|
|
|
|
|
|
sendResult(sender, "--------------------");
|
2025-03-05 23:13:39 -05:00
|
|
|
sendResult(sender, "Effects (Page " + page + "/" + totalPages + "):");
|
|
|
|
|
for (int i = startIndex; i < endIndex; i++) {
|
|
|
|
|
EffectEntry entry = effectsList.get(i);
|
|
|
|
|
sendResult(sender, String.format("\u00a7b%s \u00a77(ID: %d, INDEX: %d)",
|
|
|
|
|
entry.effect.getName(),
|
|
|
|
|
entry.id,
|
|
|
|
|
entry.index));
|
|
|
|
|
}
|
|
|
|
|
sendResult(sender, "--------------------");
|
2025-02-10 18:33:05 -05:00
|
|
|
}
|
|
|
|
|
|
2025-03-05 23:13:39 -05:00
|
|
|
|
2025-02-11 22:05:34 -05:00
|
|
|
// Give effect by name.
|
2025-03-05 23:13:39 -05:00
|
|
|
// Usage: <player> <time> <effectName>
|
|
|
|
|
@SubCommand(desc = "Gives an effect to a player", usage = "<player> <time> <effectName>")
|
2025-02-10 18:33:05 -05:00
|
|
|
public void give(ICommandSender sender, String[] args) throws CommandException {
|
2025-02-11 22:05:34 -05:00
|
|
|
if (args.length < 3) {
|
2025-03-05 23:13:39 -05:00
|
|
|
sendError(sender, "Usage: <player> <time> <effectName>");
|
2025-02-11 22:05:34 -05:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String playername = args[0];
|
|
|
|
|
int time;
|
|
|
|
|
try {
|
|
|
|
|
time = Integer.parseInt(args[1]);
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
sendError(sender, "Invalid time: " + args[1]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-05 23:13:39 -05:00
|
|
|
// Join all remaining arguments as the effect name.
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
for (int i = 2; i < args.length; i++) {
|
|
|
|
|
sb.append(args[i]).append(i < args.length - 1 ? " " : "");
|
|
|
|
|
}
|
|
|
|
|
String effectName = sb.toString();
|
|
|
|
|
|
|
|
|
|
List<EffectEntry> matches = findEffectsByName(effectName);
|
|
|
|
|
if (matches.isEmpty()) {
|
|
|
|
|
sendError(sender, "Unknown effect: " + effectName);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (matches.size() > 1) {
|
|
|
|
|
StringBuilder ambig = new StringBuilder();
|
|
|
|
|
ambig.append("Ambiguous effect name '").append(effectName).append("'. Multiple matches: ");
|
|
|
|
|
for (EffectEntry match : matches) {
|
|
|
|
|
ambig.append(match.effect.getName())
|
|
|
|
|
.append(" (ID: ").append(match.id)
|
|
|
|
|
.append(", INDEX: ").append(match.index)
|
|
|
|
|
.append("), ");
|
2025-02-11 22:05:34 -05:00
|
|
|
}
|
2025-03-05 23:13:39 -05:00
|
|
|
sendError(sender, ambig.substring(0, ambig.length() - 2));
|
|
|
|
|
return;
|
2025-02-11 22:05:34 -05:00
|
|
|
}
|
2025-03-05 23:13:39 -05:00
|
|
|
EffectEntry match = matches.get(0);
|
2025-02-10 18:33:05 -05:00
|
|
|
|
2025-02-11 22:05:34 -05:00
|
|
|
List<PlayerData> players = PlayerDataController.Instance.getPlayersData(sender, playername);
|
|
|
|
|
if (players.isEmpty()) {
|
|
|
|
|
sendError(sender, "Unknown player: " + playername);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-02-10 18:33:05 -05:00
|
|
|
|
2025-02-11 22:05:34 -05:00
|
|
|
for (PlayerData pdata : players) {
|
2025-03-05 23:13:39 -05:00
|
|
|
CustomEffectController.getInstance().applyEffect(pdata.player, match.id, time, (byte) 1, match.index);
|
|
|
|
|
sendResult(sender, String.format("%s §agiven to §7'§b%s§7'", match.effect.getName(), pdata.playername));
|
2025-02-11 22:05:34 -05:00
|
|
|
if (sender != pdata.player) {
|
2025-03-05 23:13:39 -05:00
|
|
|
sendResult(pdata.player, String.format("Effect §7%s §aadded.", match.effect.getName()));
|
2025-02-11 22:05:34 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remove effect by name.
|
2025-03-05 23:13:39 -05:00
|
|
|
// Usage: <player> <effectName>
|
|
|
|
|
@SubCommand(desc = "Removes an effect from a player", usage = "<player> <effectName>")
|
2025-02-10 18:33:05 -05:00
|
|
|
public void remove(ICommandSender sender, String[] args) throws CommandException {
|
2025-02-11 22:05:34 -05:00
|
|
|
if (args.length < 2) {
|
2025-03-05 23:13:39 -05:00
|
|
|
sendError(sender, "Usage: <player> <effectName>");
|
2025-02-11 22:05:34 -05:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String playername = args[0];
|
2025-03-05 23:13:39 -05:00
|
|
|
// Join all remaining arguments as the effect name.
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
for (int i = 1; i < args.length; i++) {
|
|
|
|
|
sb.append(args[i]).append(i < args.length - 1 ? " " : "");
|
|
|
|
|
}
|
|
|
|
|
String effectName = sb.toString();
|
|
|
|
|
|
|
|
|
|
List<EffectEntry> matches = findEffectsByName(effectName);
|
|
|
|
|
if (matches.isEmpty()) {
|
|
|
|
|
sendError(sender, "Unknown effect: " + effectName);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (matches.size() > 1) {
|
|
|
|
|
StringBuilder ambig = new StringBuilder();
|
|
|
|
|
ambig.append("Ambiguous effect name '").append(effectName).append("'. Multiple matches: ");
|
|
|
|
|
for (EffectEntry match : matches) {
|
|
|
|
|
ambig.append(match.effect.getName())
|
|
|
|
|
.append(" (ID: ").append(match.id)
|
|
|
|
|
.append(", INDEX: ").append(match.index)
|
|
|
|
|
.append("), ");
|
2025-02-11 22:05:34 -05:00
|
|
|
}
|
2025-03-05 23:13:39 -05:00
|
|
|
sendError(sender, ambig.substring(0, ambig.length() - 2));
|
|
|
|
|
return;
|
2025-02-11 22:05:34 -05:00
|
|
|
}
|
2025-03-05 23:13:39 -05:00
|
|
|
EffectEntry match = matches.get(0);
|
2025-02-11 22:05:34 -05:00
|
|
|
|
|
|
|
|
List<PlayerData> players = PlayerDataController.Instance.getPlayersData(sender, playername);
|
|
|
|
|
if (players.isEmpty()) {
|
|
|
|
|
sendError(sender, "Unknown player: " + playername);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (PlayerData pdata : players) {
|
2025-03-05 23:13:39 -05:00
|
|
|
CustomEffectController.getInstance().removeEffect(pdata.player, match.id, match.index, ExpirationType.REMOVED);
|
|
|
|
|
sendResult(sender, String.format("Effect %s removed from %s", match.effect.getName(), pdata.playername));
|
2025-02-11 22:05:34 -05:00
|
|
|
}
|
2025-02-10 18:33:05 -05:00
|
|
|
}
|
|
|
|
|
|
2025-02-11 22:05:34 -05:00
|
|
|
// Give effect by ID.
|
|
|
|
|
// Usage: <player> <time> <effectId> [index]
|
|
|
|
|
@SubCommand(desc = "Gives an effect to a player by ID", usage = "<player> <time> <effectId> [index]")
|
2025-02-10 18:33:05 -05:00
|
|
|
public void giveId(ICommandSender sender, String[] args) throws CommandException {
|
2025-02-11 22:05:34 -05:00
|
|
|
if (args.length < 3) {
|
|
|
|
|
sendError(sender, "Usage: <player> <time> <effectId> [index]");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String playername = args[0];
|
|
|
|
|
int time;
|
|
|
|
|
try {
|
|
|
|
|
time = Integer.parseInt(args[1]);
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
sendError(sender, "Invalid time: " + args[1]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int effectId;
|
|
|
|
|
int index = 0;
|
|
|
|
|
try {
|
|
|
|
|
effectId = Integer.parseInt(args[2]);
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
sendError(sender, "Invalid effect ID: " + args[2]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (args.length > 3) {
|
|
|
|
|
try {
|
|
|
|
|
index = Integer.parseInt(args[3]);
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
index = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<PlayerData> players = PlayerDataController.Instance.getPlayersData(sender, playername);
|
|
|
|
|
if (players.isEmpty()) {
|
|
|
|
|
sendError(sender, "Unknown player: " + playername);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CustomEffect effect = CustomEffectController.getInstance().get(effectId, index);
|
|
|
|
|
if (effect == null) {
|
|
|
|
|
sendError(sender, "Unknown effect with ID: " + effectId + " and index " + index);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (PlayerData pdata : players) {
|
|
|
|
|
CustomEffectController.getInstance().applyEffect(pdata.player, effectId, time, (byte) 1, index);
|
|
|
|
|
sendResult(sender, String.format("Effect %d given to %s", effectId, pdata.playername));
|
|
|
|
|
}
|
2025-02-10 18:33:05 -05:00
|
|
|
}
|
|
|
|
|
|
2025-02-11 22:05:34 -05:00
|
|
|
// Remove effect by ID.
|
|
|
|
|
// Usage: <player> <effectId> [index]
|
|
|
|
|
@SubCommand(desc = "Removes an effect from a player by ID", usage = "<player> <effectId> [index]")
|
2025-02-10 18:33:05 -05:00
|
|
|
public void removeId(ICommandSender sender, String[] args) throws CommandException {
|
2025-02-11 22:05:34 -05:00
|
|
|
if (args.length < 2) {
|
|
|
|
|
sendError(sender, "Usage: <player> <effectId> [index]");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String playername = args[0];
|
|
|
|
|
int effectId;
|
|
|
|
|
int index = 0;
|
|
|
|
|
try {
|
|
|
|
|
effectId = Integer.parseInt(args[1]);
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
sendError(sender, "Invalid effect ID: " + args[1]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (args.length > 2) {
|
|
|
|
|
try {
|
|
|
|
|
index = Integer.parseInt(args[2]);
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
index = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<PlayerData> players = PlayerDataController.Instance.getPlayersData(sender, playername);
|
|
|
|
|
if (players.isEmpty()) {
|
|
|
|
|
sendError(sender, "Unknown player: " + playername);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CustomEffect effect = CustomEffectController.getInstance().get(effectId, index);
|
|
|
|
|
if (effect == null) {
|
|
|
|
|
sendError(sender, "Unknown effect with ID: " + effectId + " and index " + index);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (PlayerData pdata : players) {
|
|
|
|
|
CustomEffectController.getInstance().removeEffect(pdata.player, effectId, index, ExpirationType.REMOVED);
|
|
|
|
|
sendResult(sender, String.format("Effect %d removed from %s", effectId, pdata.playername));
|
|
|
|
|
}
|
2025-02-10 18:33:05 -05:00
|
|
|
}
|
2025-03-05 23:13:39 -05:00
|
|
|
|
|
|
|
|
private static class EffectEntry {
|
|
|
|
|
int index;
|
|
|
|
|
int id;
|
|
|
|
|
CustomEffect effect;
|
|
|
|
|
|
|
|
|
|
public EffectEntry(int index, int id, CustomEffect effect) {
|
|
|
|
|
this.index = index;
|
|
|
|
|
this.id = id;
|
|
|
|
|
this.effect = effect;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Helper method to find effects by name.
|
|
|
|
|
private List<EffectEntry> findEffectsByName(String name) {
|
|
|
|
|
List<EffectEntry> matches = new ArrayList<>();
|
|
|
|
|
CustomEffectController controller = CustomEffectController.getInstance();
|
|
|
|
|
for (Map.Entry<Integer, HashMap<Integer, CustomEffect>> entry : controller.indexMapper.entrySet()) {
|
|
|
|
|
int idx = entry.getKey();
|
|
|
|
|
Map<Integer, CustomEffect> effects = entry.getValue();
|
|
|
|
|
if (effects == null) continue;
|
|
|
|
|
for (Map.Entry<Integer, CustomEffect> effectEntry : effects.entrySet()) {
|
|
|
|
|
int id = effectEntry.getKey();
|
|
|
|
|
CustomEffect effect = effectEntry.getValue();
|
|
|
|
|
if (effect.getName().equalsIgnoreCase(name)) {
|
|
|
|
|
List<EffectEntry> exact = new ArrayList<>();
|
|
|
|
|
exact.add(new EffectEntry(idx, id, effect));
|
|
|
|
|
return exact;
|
|
|
|
|
} else if (effect.getName().toLowerCase().contains(name.toLowerCase())) {
|
|
|
|
|
matches.add(new EffectEntry(idx, id, effect));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return matches;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static List<String> getSortedEffectNames() {
|
|
|
|
|
List<EffectEntry> entries = new ArrayList<>();
|
|
|
|
|
CustomEffectController controller = CustomEffectController.getInstance();
|
|
|
|
|
for (Map.Entry<Integer, HashMap<Integer, CustomEffect>> indexEntry : controller.indexMapper.entrySet()) {
|
|
|
|
|
int index = indexEntry.getKey();
|
|
|
|
|
Map<Integer, CustomEffect> effects = indexEntry.getValue();
|
|
|
|
|
if (effects != null) {
|
|
|
|
|
for (Map.Entry<Integer, CustomEffect> effectEntry : effects.entrySet()) {
|
|
|
|
|
int id = effectEntry.getKey();
|
|
|
|
|
CustomEffect effect = effectEntry.getValue();
|
|
|
|
|
entries.add(new EffectEntry(index, id, effect));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Sort entries by index then by effect ID.
|
|
|
|
|
entries.sort(Comparator.comparingInt((EffectEntry e) -> e.index)
|
|
|
|
|
.thenComparingInt(e -> e.id));
|
|
|
|
|
List<String> effectNames = new ArrayList<>();
|
|
|
|
|
for (EffectEntry entry : entries) {
|
|
|
|
|
effectNames.add(entry.effect.getName());
|
|
|
|
|
}
|
|
|
|
|
return effectNames;
|
|
|
|
|
}
|
2025-02-10 18:33:05 -05:00
|
|
|
}
|