Added a filter to browse through abilities from different mods

This commit is contained in:
Vidal committed 2026-02-04 06:18:00 -03:00
1 parent ad4033ed62
commit 2c3ca1b5ed
3 files changed
+150 -18

No files matched your search

+70 -10
View File
@@ -5,45 +5,92 @@ import kamkeel.npcs.controllers.data.ability.AbilityController;
import noppes.npcs.LogWriter;
import noppes.npcs.controllers.AnimationController;
import noppes.npcs.controllers.data.Animation;
import noppes.npcs.controllers.data.BuiltInAnimation;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.*;
import java.util.function.Supplier;
public class Register<T> {
public static final Map<String, List<String>> REGISTERED_NAMESPACES = new LinkedHashMap<>();
private final String registryKey;
protected final String namespace;
protected final Map<String, Supplier<T>> entries = new LinkedHashMap<>();
public Register(String registryKey, String namespace) {
private Register(String registryKey, String namespace) {
this.registryKey = registryKey;
this.namespace = namespace;
}
public T register(String factoryName, Supplier<T> factory) {
entries.put(registryKey + "." + namespace + ":" + factoryName, factory);
entries.put(registryKey + "." + namespace + "." + factoryName, factory);
return factory.get();
}
public static boolean isEmpty(String registryKey) {
if (REGISTERED_NAMESPACES.isEmpty()) return true;
if (REGISTERED_NAMESPACES.get(registryKey).isEmpty()) return true;
return false;
}
public List<T> catalogue() {
List<T> list = new ArrayList<>();
for (String regKey : REGISTERED_NAMESPACES.keySet()) {
List<String> nameSp = REGISTERED_NAMESPACES.get(regKey);
for (String name : nameSp) {
List<T> nameSpContent = catalogue(regKey, name);
list.addAll(nameSpContent);
}
}
return list;
}
public List<T> catalogue(String namespace) {
return catalogue(registryKey, namespace);
}
public List<T> catalogue(String registryKey, String namespace) {
List<T> list = new ArrayList<>();
for (Map.Entry<String, Supplier<T>> entry : entries.entrySet()) {
if (entry.getKey().startsWith(registryKey + "." + namespace + ":"))
list.add(entry.getValue().get());
}
return list;
}
public static class Abilities extends Register<Ability> {
public Abilities(String namespace) {
private Abilities(String namespace) {
super("ability", namespace);
}
public void register() {
for (Map.Entry<String, Supplier<Ability>> entry : entries.entrySet()) {
AbilityController.Instance.registerType(entry.getKey(), entry.getValue());
AbilityController.Instance.registerType(entry.getValue().get().getTypeId(), entry.getValue());
}
}
public static Register.Abilities create(String namespace) {
if (!REGISTERED_NAMESPACES.containsKey("ability"))
REGISTERED_NAMESPACES.put("ability", new ArrayList<>());
if (REGISTERED_NAMESPACES.get("ability").contains(namespace)) {
LogWriter.error("REGISTER ABILITIES: Namespace " + namespace + " already registered!");
}
REGISTERED_NAMESPACES.get("ability").add(namespace);
return new Register.Abilities(namespace);
}
}
public static class Animations extends Register<Animation> {
private final Class<?> modClass;
private final String animationsPath;
public Animations(Class<?> modClass, String animationsPath, String namespace) {
super("ability", namespace);
private Animations(Class<?> modClass, String animationsPath, String namespace) {
super("animation", namespace);
this.animationsPath = animationsPath;
this.modClass = modClass;
}
@@ -57,12 +104,25 @@ public class Register<T> {
try {
String path = "/assets/" + namespace + "/" + animationsPath;
for (Map.Entry<String, Supplier<Animation>> entry : entries.entrySet()) {
String name = entry.getKey().substring(entry.getKey().indexOf(":") + 1);
String name = entry.getKey().substring(entry.getKey().indexOf(namespace + ".") + 1);
AnimationController.Instance.loadBuiltInAnimation(modClass, path, name);
}
} catch (Exception e) {
LogWriter.error("Error scanning built-in animations folder", e);
}
}
public static Register.Animations create(Class<?> modClass, String animationsPath, String namespace) {
if (!REGISTERED_NAMESPACES.containsKey("animation"))
REGISTERED_NAMESPACES.put("animation", new ArrayList<>());
if (REGISTERED_NAMESPACES.get("animation").contains(namespace)) {
LogWriter.error("REGISTER ANIMATIONS: Namespace " + namespace + " already registered!");
}
REGISTERED_NAMESPACES.get("animation").add(namespace);
return new Register.Animations(modClass, animationsPath, namespace);
}
}
}
@@ -2,6 +2,7 @@ package noppes.npcs;
import io.netty.buffer.ByteBuf;
import kamkeel.npcs.controllers.SyncController;
import kamkeel.npcs.controllers.data.ability.AbilityController;
import kamkeel.npcs.network.PacketHandler;
import kamkeel.npcs.network.packets.data.ParticlePacket;
import kamkeel.npcs.network.packets.data.PlayerDataInfoPacket;
@@ -775,7 +776,7 @@ public class NoppesUtilServer {
public static void sendAbilityTypesInfo(EntityPlayerMP player) {
HashMap<String, Integer> map = new HashMap<String, Integer>();
kamkeel.npcs.controllers.data.ability.AbilityController controller = kamkeel.npcs.controllers.data.ability.AbilityController.Instance;
AbilityController controller = AbilityController.Instance;
if (controller != null) {
int index = 0;
for (String typeId : controller.getTypes()) {
@@ -8,6 +8,7 @@ import kamkeel.npcs.network.packets.request.ability.AbilitiesGetAllPacket;
import kamkeel.npcs.network.packets.request.ability.AbilitiesNpcGetPacket;
import kamkeel.npcs.network.packets.request.ability.AbilitiesNpcSavePacket;
import kamkeel.npcs.network.packets.request.ability.CustomAbilitySavePacket;
import kamkeel.npcs.util.Register;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.resources.I18n;
import net.minecraft.nbt.NBTTagCompound;
@@ -27,11 +28,7 @@ import noppes.npcs.client.gui.util.SubGuiInterface;
import noppes.npcs.constants.EnumScrollData;
import noppes.npcs.entity.EntityNPCInterface;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.Vector;
import java.util.*;
/**
* GUI for managing NPC abilities.
@@ -44,6 +41,7 @@ public class GuiNPCAbilities extends GuiNPCInterface2 implements IScrollData, IC
// All available ability types (typeId -> index)
private final HashMap<String, Integer> allAbilityTypes = new HashMap<>();
private final HashMap<String, Integer> filteredAbilityTypes = new HashMap<>();
// Display name to typeId mapping for the available types scroll
private final HashMap<String, String> displayNameToTypeId = new HashMap<>();
@@ -59,12 +57,35 @@ public class GuiNPCAbilities extends GuiNPCInterface2 implements IScrollData, IC
private String search = "";
private int selectedAbilityIndex = -1;
public static int modIndex = 0;
public static ScrollType scrollType = ScrollType.CNPC;
public GuiNPCAbilities(EntityNPCInterface npc) {
super(npc);
PacketClient.sendClient(new AbilitiesGetAllPacket());
PacketClient.sendClient(new AbilitiesNpcGetPacket());
}
public enum ScrollType {
CNPC,
MODDED,
ALL;
@Override
public String toString() {
switch (this) {
case CNPC: return "CustomNPCs";
case MODDED:
if (Register.isEmpty("ability"))
return "modded";
return Register.REGISTERED_NAMESPACES.get("ability").get(modIndex);
case ALL: return "filter.all";
default: return name();
}
}
}
@Override
public void initGui() {
super.initGui();
@@ -94,13 +115,15 @@ public class GuiNPCAbilities extends GuiNPCInterface2 implements IScrollData, IC
addLabel(new GuiNpcLabel(1, "ability.availableTypes", guiLeft + 5, y));
if (availableTypesScroll == null) {
availableTypesScroll = new GuiCustomScroll(this, 0);
availableTypesScroll.setSize(140, 130);
availableTypesScroll.setSize(140, 103);
}
availableTypesScroll.guiLeft = guiLeft + 5;
availableTypesScroll.guiTop = y + 12;
availableTypesScroll.setList(getFilteredTypeList());
addScroll(availableTypesScroll);
addButton(new GuiNpcButton(50, guiLeft + 5, y + 120, 140, 20, scrollType.toString()));
// Search bar for types
addTextField(new GuiNpcTextField(4, this, fontRendererObj, guiLeft + 5, y + 145, 140, 18, search));
@@ -275,6 +298,27 @@ public class GuiNPCAbilities extends GuiNPCInterface2 implements IScrollData, IC
return;
}
if (id == 50) {
if (scrollType != ScrollType.MODDED) {
ScrollType[] values = ScrollType.values();
scrollType = values[(scrollType.ordinal() + 1) % values.length];
} else {
List<String> list = Register.REGISTERED_NAMESPACES.get("ability");
if (list != null && !list.isEmpty()) {
modIndex = (modIndex + 1) % list.size();
} else {
modIndex = 0;
scrollType = ScrollType.ALL;
}
}
Map<String, Integer> dummyMap = new HashMap<>(allAbilityTypes);
filteredAbilityTypes.clear();
filteredAbilityTypes.putAll(getFilteredData(dummyMap));
}
initGui();
}
@@ -283,6 +327,8 @@ public class GuiNPCAbilities extends GuiNPCInterface2 implements IScrollData, IC
if (type == EnumScrollData.ABILITY_TYPES) {
allAbilityTypes.clear();
allAbilityTypes.putAll(data);
filteredAbilityTypes.putAll(getFilteredData(allAbilityTypes));
if (availableTypesScroll != null) {
availableTypesScroll.setList(getFilteredTypeList());
}
@@ -341,10 +387,35 @@ public class GuiNPCAbilities extends GuiNPCInterface2 implements IScrollData, IC
}
}
private HashMap<String, Integer> getFilteredData(Map<String, Integer> data) {
HashMap<String, Integer> filteredData = new HashMap<>();
if (scrollType == ScrollType.CNPC) {
data.entrySet().stream()
.filter(e -> e.getKey().startsWith("ability.cnpc."))
.forEach(e -> filteredData.put(e.getKey(), e.getValue()));
} else if (scrollType == ScrollType.MODDED) {
if (!Register.isEmpty("ability")) {
List<String> registerList = Register.REGISTERED_NAMESPACES.get("ability");
if (!registerList.isEmpty()) {
String namespace = registerList.get(modIndex);
data.entrySet().stream()
.filter(e -> e.getKey().startsWith("ability." + namespace + "."))
.forEach(e -> filteredData.put(e.getKey(), e.getValue()));
}
}
} else {
filteredData.putAll(data);
}
return filteredData;
}
private List<String> getFilteredTypeList() {
List<String> list = new ArrayList<>();
displayNameToTypeId.clear();
for (String typeId : allAbilityTypes.keySet()) {
for (String typeId : filteredAbilityTypes.keySet()) {
String displayName = I18n.format(typeId);
// Search matches either the display name or the typeId
if (search.isEmpty() || displayName.toLowerCase().contains(search) || typeId.toLowerCase().contains(search)) {