mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 15:27:29 +00:00
Merge branch 'cloner_tabs' into dev
This commit is contained in:
commit
db7ae16ee9
35 files changed
+3311
-318
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 884 KiB |
+1
-1
Submodule src/api updated: 29ad8637d6...3f8ccc087f.
@@ -13,6 +13,7 @@ import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import noppes.npcs.controllers.ServerCloneController;
|
||||
import noppes.npcs.controllers.data.CloneFolder;
|
||||
import noppes.npcs.entity.EntityNPCInterface;
|
||||
|
||||
import java.util.List;
|
||||
@@ -35,20 +36,24 @@ public class CloneCommand extends CommandKamkeelBase {
|
||||
|
||||
@SubCommand(
|
||||
desc = "Add NPC(s) to clone storage",
|
||||
usage = "<npc> <tab> [clonedname]",
|
||||
usage = "<npc> <tab|folder> [clonedname]",
|
||||
permission = 4
|
||||
)
|
||||
public void add(ICommandSender sender, String[] args) {
|
||||
int tab = 0;
|
||||
int tab = -1;
|
||||
String folder = null;
|
||||
try {
|
||||
tab = Integer.parseInt(args[1]);
|
||||
if (tab < 0 || tab > 15) {
|
||||
if (tab < 1 || tab > 15) {
|
||||
sendError(sender, "Tab must be within 1-15");
|
||||
return;
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
sendError(sender, String.format("Tab is not a number: %s", args[1]));
|
||||
return;
|
||||
folder = args[1];
|
||||
if (ServerCloneController.Instance == null || !ServerCloneController.Instance.hasFolder(folder)) {
|
||||
sendError(sender, String.format("Unknown folder: %s", folder));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int x = sender.getPlayerCoordinates().posX;
|
||||
@@ -64,32 +69,47 @@ public class CloneCommand extends CommandKamkeelBase {
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
if (!npc.writeToNBTOptional(compound))
|
||||
return;
|
||||
ServerCloneController.Instance.addClone(compound, name, tab);
|
||||
sendResult(sender, String.format("Added NPC \u00A7e%s\u00A77 to Tab \u00A7b%d\u00A77", name, tab));
|
||||
if (folder != null) {
|
||||
ServerCloneController.Instance.addClone(compound, name, folder);
|
||||
sendResult(sender, String.format("Added NPC \u00A7e%s\u00A77 to Folder \u00A7b%s\u00A77", name, folder));
|
||||
} else {
|
||||
ServerCloneController.Instance.addClone(compound, name, tab);
|
||||
sendResult(sender, String.format("Added NPC \u00A7e%s\u00A77 to Tab \u00A7b%d\u00A77", name, tab));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "List NPC from clone storage",
|
||||
usage = "<tab>",
|
||||
usage = "<tab|folder>",
|
||||
permission = 2
|
||||
)
|
||||
public void list(ICommandSender sender, String[] args) {
|
||||
sendMessage(sender, "--- Stored NPCs --- (server side)");
|
||||
int tab = 0;
|
||||
int tab = -1;
|
||||
String folder = null;
|
||||
try {
|
||||
tab = Integer.parseInt(args[1]);
|
||||
if (tab < 0 || tab > 15) {
|
||||
if (tab < 1 || tab > 15) {
|
||||
sendError(sender, "Tab must be within 1-15");
|
||||
return;
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
sendError(sender, String.format("Tab is not a number: %s", args[1]));
|
||||
return;
|
||||
folder = args[1];
|
||||
if (ServerCloneController.Instance == null || !ServerCloneController.Instance.hasFolder(folder)) {
|
||||
sendError(sender, String.format("Unknown folder: %s", folder));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (String name : ServerCloneController.Instance.getClones(tab)) {
|
||||
List<String> clones;
|
||||
if (folder != null) {
|
||||
clones = ServerCloneController.Instance.getClones(folder);
|
||||
} else {
|
||||
clones = ServerCloneController.Instance.getClones(tab);
|
||||
}
|
||||
for (String name : clones) {
|
||||
sendMessage(sender, name);
|
||||
}
|
||||
sendMessage(sender, "------------------------------------");
|
||||
@@ -97,59 +117,75 @@ public class CloneCommand extends CommandKamkeelBase {
|
||||
|
||||
@SubCommand(
|
||||
desc = "Remove NPC from clone storage",
|
||||
usage = "<name> <tab>",
|
||||
usage = "<name> <tab|folder>",
|
||||
permission = 4
|
||||
)
|
||||
public void del(ICommandSender sender, String[] args) throws CommandException {
|
||||
String nametodel = args[0];
|
||||
int tab = 0;
|
||||
int tab = -1;
|
||||
String folder = null;
|
||||
try {
|
||||
tab = Integer.parseInt(args[1]);
|
||||
if (tab < 0 || tab > 15) {
|
||||
sendError(sender, String.format("Tab must be within 1-15"));
|
||||
if (tab < 1 || tab > 15) {
|
||||
sendError(sender, "Tab must be within 1-15");
|
||||
return;
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
sendError(sender, String.format("Tab is not a number: %s", args[1]));
|
||||
return;
|
||||
}
|
||||
|
||||
boolean deleted = false;
|
||||
for (String name : ServerCloneController.Instance.getClones(tab)) {
|
||||
if (nametodel.equalsIgnoreCase(name)) {
|
||||
ServerCloneController.Instance.removeClone(name, tab);
|
||||
deleted = true;
|
||||
break;
|
||||
folder = args[1];
|
||||
if (ServerCloneController.Instance == null || !ServerCloneController.Instance.hasFolder(folder)) {
|
||||
sendError(sender, String.format("Unknown folder: %s", folder));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!ServerCloneController.Instance.removeClone(nametodel, tab)) {
|
||||
|
||||
boolean success;
|
||||
if (folder != null) {
|
||||
success = ServerCloneController.Instance.removeClone(nametodel, folder);
|
||||
} else {
|
||||
success = ServerCloneController.Instance.removeClone(nametodel, tab);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
sendError(sender, String.format("NPC '%s' was not found", nametodel));
|
||||
} else {
|
||||
sendResult(sender, String.format("Removed NPC \u00A7e%s\u00A77 from Tab \u00A7b%d\u00A77", nametodel, tab));
|
||||
if (folder != null) {
|
||||
sendResult(sender, String.format("Removed NPC \u00A7e%s\u00A77 from Folder \u00A7b%s\u00A77", nametodel, folder));
|
||||
} else {
|
||||
sendResult(sender, String.format("Removed NPC \u00A7e%s\u00A77 from Tab \u00A7b%d\u00A77", nametodel, tab));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Spawn cloned NPC",
|
||||
usage = "<name> <tab> [[world:]x,y,z]] [newname]",
|
||||
usage = "<name> <tab|folder> [[world:]x,y,z]] [newname]",
|
||||
permission = 2
|
||||
)
|
||||
public void spawn(ICommandSender sender, String[] args) throws CommandException {
|
||||
String name = args[0].replaceAll("%", " "); // if name of npc separed by space, user must use % in place of space
|
||||
int tab = 0;
|
||||
int tab = -1;
|
||||
String folder = null;
|
||||
try {
|
||||
tab = Integer.parseInt(args[1]);
|
||||
if (tab < 0 || tab > 15) {
|
||||
sendError(sender, String.format("Tab must be within 1-15"));
|
||||
if (tab < 1 || tab > 15) {
|
||||
sendError(sender, "Tab must be within 1-15");
|
||||
return;
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
sendError(sender, String.format("Tab is not a number: %s", args[1]));
|
||||
return;
|
||||
folder = args[1];
|
||||
if (ServerCloneController.Instance == null || !ServerCloneController.Instance.hasFolder(folder)) {
|
||||
sendError(sender, String.format("Unknown folder: %s", folder));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String newname = null;
|
||||
NBTTagCompound compound = ServerCloneController.Instance.getCloneData(sender, name, tab);
|
||||
NBTTagCompound compound;
|
||||
if (folder != null) {
|
||||
compound = ServerCloneController.Instance.getCloneData(sender, name, folder);
|
||||
} else {
|
||||
compound = ServerCloneController.Instance.getCloneData(sender, name, tab);
|
||||
}
|
||||
if (compound == null) {
|
||||
sendError(sender, "Unknown npc");
|
||||
return;
|
||||
@@ -211,22 +247,26 @@ public class CloneCommand extends CommandKamkeelBase {
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Spawn cloned NPC",
|
||||
usage = "<name> <tab> [[world:]x,y,z]] [newname]",
|
||||
desc = "Spawn cloned NPC in a grid",
|
||||
usage = "<name> <tab|folder> <width> <height> [[world:]x,y,z]] [newname]",
|
||||
permission = 2
|
||||
)
|
||||
public void grid(ICommandSender sender, String[] args) throws CommandException {
|
||||
String name = args[0].replaceAll("%", " "); // if name of npc separed by space, user must use % in place of space
|
||||
int tab = 0;
|
||||
int tab = -1;
|
||||
String folder = null;
|
||||
try {
|
||||
tab = Integer.parseInt(args[1]);
|
||||
if (tab < 0 || tab > 15) {
|
||||
sendError(sender, String.format("Tab must be within 1-15"));
|
||||
if (tab < 1 || tab > 15) {
|
||||
sendError(sender, "Tab must be within 1-15");
|
||||
return;
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
sendError(sender, String.format("Tab is not a number: %s", args[1]));
|
||||
return;
|
||||
folder = args[1];
|
||||
if (ServerCloneController.Instance == null || !ServerCloneController.Instance.hasFolder(folder)) {
|
||||
sendError(sender, String.format("Unknown folder: %s", folder));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int width, height;
|
||||
@@ -238,9 +278,13 @@ public class CloneCommand extends CommandKamkeelBase {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String newname = null;
|
||||
NBTTagCompound compound = ServerCloneController.Instance.getCloneData(sender, name, tab);
|
||||
NBTTagCompound compound;
|
||||
if (folder != null) {
|
||||
compound = ServerCloneController.Instance.getCloneData(sender, name, folder);
|
||||
} else {
|
||||
compound = ServerCloneController.Instance.getCloneData(sender, name, tab);
|
||||
}
|
||||
if (compound == null) {
|
||||
sendError(sender, "Unknown npc");
|
||||
return;
|
||||
@@ -317,6 +361,163 @@ public class CloneCommand extends CommandKamkeelBase {
|
||||
return;
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "List all custom clone folders",
|
||||
usage = "",
|
||||
permission = 2
|
||||
)
|
||||
public void listfolders(ICommandSender sender, String[] args) {
|
||||
if (ServerCloneController.Instance == null) {
|
||||
sendError(sender, "Folder system not initialized");
|
||||
return;
|
||||
}
|
||||
sendMessage(sender, "--- Clone Folders ---");
|
||||
for (CloneFolder f : ServerCloneController.Instance.getFolderList()) {
|
||||
sendMessage(sender, f.name);
|
||||
}
|
||||
sendMessage(sender, "------------------------------------");
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Create a custom clone folder",
|
||||
usage = "<name>",
|
||||
permission = 4
|
||||
)
|
||||
public void createfolder(ICommandSender sender, String[] args) {
|
||||
if (ServerCloneController.Instance == null) {
|
||||
sendError(sender, "Folder system not initialized");
|
||||
return;
|
||||
}
|
||||
String name = args[0];
|
||||
if (!CloneFolder.isValidName(name)) {
|
||||
sendError(sender, String.format("Invalid folder name: %s", name));
|
||||
return;
|
||||
}
|
||||
if (ServerCloneController.Instance.hasFolder(name)) {
|
||||
sendError(sender, String.format("Folder '%s' already exists", name));
|
||||
return;
|
||||
}
|
||||
CloneFolder created = ServerCloneController.Instance.createFolder(name);
|
||||
if (created != null) {
|
||||
sendResult(sender, String.format("Created folder \u00A7b%s", name));
|
||||
} else {
|
||||
sendError(sender, String.format("Failed to create folder '%s'", name));
|
||||
}
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Rename a custom clone folder",
|
||||
usage = "<oldname> <newname>",
|
||||
permission = 4
|
||||
)
|
||||
public void renamefolder(ICommandSender sender, String[] args) {
|
||||
if (ServerCloneController.Instance == null) {
|
||||
sendError(sender, "Folder system not initialized");
|
||||
return;
|
||||
}
|
||||
String oldName = args[0];
|
||||
String newName = args[1];
|
||||
if (!ServerCloneController.Instance.hasFolder(oldName)) {
|
||||
sendError(sender, String.format("Unknown folder: %s", oldName));
|
||||
return;
|
||||
}
|
||||
if (!CloneFolder.isValidName(newName)) {
|
||||
sendError(sender, String.format("Invalid folder name: %s", newName));
|
||||
return;
|
||||
}
|
||||
if (ServerCloneController.Instance.renameFolder(oldName, newName)) {
|
||||
sendResult(sender, String.format("Renamed folder \u00A7b%s\u00A77 to \u00A7b%s", oldName, newName));
|
||||
} else {
|
||||
sendError(sender, String.format("Failed to rename folder '%s'", oldName));
|
||||
}
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Delete an empty custom clone folder",
|
||||
usage = "<name>",
|
||||
permission = 4
|
||||
)
|
||||
public void deletefolder(ICommandSender sender, String[] args) {
|
||||
if (ServerCloneController.Instance == null) {
|
||||
sendError(sender, "Folder system not initialized");
|
||||
return;
|
||||
}
|
||||
String name = args[0];
|
||||
if (!ServerCloneController.Instance.hasFolder(name)) {
|
||||
sendError(sender, String.format("Unknown folder: %s", name));
|
||||
return;
|
||||
}
|
||||
if (ServerCloneController.Instance.deleteFolder(name)) {
|
||||
sendResult(sender, String.format("Deleted folder \u00A7b%s", name));
|
||||
} else {
|
||||
sendError(sender, String.format("Failed to delete folder '%s' (folder must be empty)", name));
|
||||
}
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Move a clone between tabs/folders",
|
||||
usage = "<clonename> <from_tab|folder> <to_tab|folder>",
|
||||
permission = 4
|
||||
)
|
||||
public void move(ICommandSender sender, String[] args) {
|
||||
if (ServerCloneController.Instance == null) {
|
||||
sendError(sender, "Folder system not initialized");
|
||||
return;
|
||||
}
|
||||
String cloneName = args[0];
|
||||
|
||||
int fromTab = -1;
|
||||
String fromFolder = null;
|
||||
try {
|
||||
fromTab = Integer.parseInt(args[1]);
|
||||
if (fromTab < 1 || fromTab > 15) {
|
||||
sendError(sender, "Source tab must be within 1-15");
|
||||
return;
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
fromFolder = args[1];
|
||||
if (!ServerCloneController.Instance.hasFolder(fromFolder)) {
|
||||
sendError(sender, String.format("Unknown source folder: %s", fromFolder));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int toTab = -1;
|
||||
String toFolder = null;
|
||||
try {
|
||||
toTab = Integer.parseInt(args[2]);
|
||||
if (toTab < 1 || toTab > 15) {
|
||||
sendError(sender, "Destination tab must be within 1-15");
|
||||
return;
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
toFolder = args[2];
|
||||
if (!ServerCloneController.Instance.hasFolder(toFolder)) {
|
||||
sendError(sender, String.format("Unknown destination folder: %s", toFolder));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
boolean success;
|
||||
if (fromFolder != null && toFolder != null) {
|
||||
success = ServerCloneController.Instance.moveClone(cloneName, fromFolder, toFolder);
|
||||
} else if (fromFolder != null) {
|
||||
success = ServerCloneController.Instance.moveClone(cloneName, fromFolder, toTab);
|
||||
} else if (toFolder != null) {
|
||||
success = ServerCloneController.Instance.moveClone(cloneName, fromTab, toFolder);
|
||||
} else {
|
||||
success = ServerCloneController.Instance.moveClone(cloneName, fromTab, toTab);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
String from = fromFolder != null ? fromFolder : String.valueOf(fromTab);
|
||||
String to = toFolder != null ? toFolder : String.valueOf(toTab);
|
||||
sendResult(sender, String.format("Moved \u00A7e%s\u00A77 from \u00A7b%s\u00A77 to \u00A7b%s", cloneName, from, to));
|
||||
} else {
|
||||
sendError(sender, String.format("Failed to move '%s'", cloneName));
|
||||
}
|
||||
}
|
||||
|
||||
public World getWorld(String t) {
|
||||
WorldServer[] ws = MinecraftServer.getServer().worldServers;
|
||||
for (WorldServer w : ws) {
|
||||
|
||||
@@ -108,6 +108,9 @@ import kamkeel.npcs.network.packets.request.bank.BankSavePacket;
|
||||
import kamkeel.npcs.network.packets.request.bank.BanksGetPacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneAllTagsPacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneAllTagsShortPacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneFolderCrudPacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneFolderListPacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneMovePacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneListPacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.ClonePreSavePacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneRemovePacket;
|
||||
@@ -325,6 +328,9 @@ public class PacketHandler {
|
||||
REQUEST_PACKET.registerPacket(new CloneTagListPacket());
|
||||
REQUEST_PACKET.registerPacket(new CloneAllTagsPacket());
|
||||
REQUEST_PACKET.registerPacket(new CloneAllTagsShortPacket());
|
||||
REQUEST_PACKET.registerPacket(new CloneFolderListPacket());
|
||||
REQUEST_PACKET.registerPacket(new CloneFolderCrudPacket());
|
||||
REQUEST_PACKET.registerPacket(new CloneMovePacket());
|
||||
|
||||
|
||||
// Linked Packets
|
||||
|
||||
@@ -163,6 +163,9 @@ public enum EnumRequestPacket {
|
||||
CloneAllTags,
|
||||
CloneAllTagsShort,
|
||||
ClonePreSave,
|
||||
CloneFolderList,
|
||||
CloneFolderCrud,
|
||||
CloneMove,
|
||||
|
||||
EventScript,
|
||||
PlayerScript,
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package kamkeel.npcs.network.packets.request.clone;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import kamkeel.npcs.network.AbstractPacket;
|
||||
import kamkeel.npcs.network.PacketChannel;
|
||||
import kamkeel.npcs.network.PacketHandler;
|
||||
import kamkeel.npcs.network.PacketUtil;
|
||||
import kamkeel.npcs.network.enums.EnumItemPacketType;
|
||||
import kamkeel.npcs.network.enums.EnumRequestPacket;
|
||||
import kamkeel.npcs.network.packets.data.large.GuiDataPacket;
|
||||
import kamkeel.npcs.util.ByteBufUtils;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import noppes.npcs.CustomNpcsPermissions;
|
||||
import noppes.npcs.controllers.ServerCloneController;
|
||||
import noppes.npcs.controllers.data.CloneFolder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class CloneFolderCrudPacket extends AbstractPacket {
|
||||
public static String packetName = "Request|CloneFolderCrud";
|
||||
|
||||
public static final byte ACTION_CREATE = 0;
|
||||
public static final byte ACTION_RENAME = 1;
|
||||
public static final byte ACTION_DELETE = 2;
|
||||
|
||||
private byte action;
|
||||
private String name;
|
||||
private String newName;
|
||||
|
||||
public CloneFolderCrudPacket() {
|
||||
}
|
||||
|
||||
public CloneFolderCrudPacket(byte action, String name) {
|
||||
this.action = action;
|
||||
this.name = name;
|
||||
this.newName = "";
|
||||
}
|
||||
|
||||
public CloneFolderCrudPacket(byte action, String name, String newName) {
|
||||
this.action = action;
|
||||
this.name = name;
|
||||
this.newName = newName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enum getType() {
|
||||
return EnumRequestPacket.CloneFolderCrud;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketChannel getChannel() {
|
||||
return PacketHandler.REQUEST_PACKET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomNpcsPermissions.Permission getPermission() {
|
||||
return CustomNpcsPermissions.NPC_CLONE;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
out.writeByte(action);
|
||||
ByteBufUtils.writeString(out, name);
|
||||
if (action == ACTION_RENAME) {
|
||||
ByteBufUtils.writeString(out, newName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
|
||||
if (!(player instanceof EntityPlayerMP))
|
||||
return;
|
||||
if (!PacketUtil.verifyItemPacket(packetName, player, EnumItemPacketType.CLONER))
|
||||
return;
|
||||
|
||||
byte action = in.readByte();
|
||||
String name = ByteBufUtils.readString(in);
|
||||
|
||||
boolean success = false;
|
||||
switch (action) {
|
||||
case ACTION_CREATE:
|
||||
if (CloneFolder.isValidName(name))
|
||||
success = ServerCloneController.Instance.createFolder(name) != null;
|
||||
break;
|
||||
case ACTION_RENAME:
|
||||
String newName = ByteBufUtils.readString(in);
|
||||
if (CloneFolder.isValidName(newName))
|
||||
success = ServerCloneController.Instance.renameFolder(name, newName);
|
||||
break;
|
||||
case ACTION_DELETE:
|
||||
success = ServerCloneController.Instance.deleteFolder(name);
|
||||
break;
|
||||
}
|
||||
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
compound.setBoolean("Success", success);
|
||||
NBTTagList folderList = new NBTTagList();
|
||||
for (CloneFolder folder : ServerCloneController.Instance.getFolderList()) {
|
||||
folderList.appendTag(folder.writeNBT(new NBTTagCompound()));
|
||||
}
|
||||
compound.setTag("CloneFolders", folderList);
|
||||
|
||||
GuiDataPacket.sendGuiData((EntityPlayerMP) player, compound);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package kamkeel.npcs.network.packets.request.clone;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import kamkeel.npcs.network.AbstractPacket;
|
||||
import kamkeel.npcs.network.PacketChannel;
|
||||
import kamkeel.npcs.network.PacketHandler;
|
||||
import kamkeel.npcs.network.PacketUtil;
|
||||
import kamkeel.npcs.network.enums.EnumItemPacketType;
|
||||
import kamkeel.npcs.network.enums.EnumRequestPacket;
|
||||
import kamkeel.npcs.network.packets.data.large.GuiDataPacket;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import noppes.npcs.controllers.ServerCloneController;
|
||||
import noppes.npcs.controllers.data.CloneFolder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class CloneFolderListPacket extends AbstractPacket {
|
||||
public static String packetName = "Request|CloneFolderList";
|
||||
|
||||
public CloneFolderListPacket() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enum getType() {
|
||||
return EnumRequestPacket.CloneFolderList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketChannel getChannel() {
|
||||
return PacketHandler.REQUEST_PACKET;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
|
||||
if (!(player instanceof EntityPlayerMP))
|
||||
return;
|
||||
if (!PacketUtil.verifyItemPacket(packetName, player, EnumItemPacketType.CLONER))
|
||||
return;
|
||||
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
NBTTagList folderList = new NBTTagList();
|
||||
for (CloneFolder folder : ServerCloneController.Instance.getFolderList()) {
|
||||
folderList.appendTag(folder.writeNBT(new NBTTagCompound()));
|
||||
}
|
||||
compound.setTag("CloneFolders", folderList);
|
||||
|
||||
GuiDataPacket.sendGuiData((EntityPlayerMP) player, compound);
|
||||
}
|
||||
}
|
||||
@@ -23,9 +23,16 @@ public final class CloneListPacket extends AbstractPacket {
|
||||
public static String packetName = "Request|CloneList";
|
||||
|
||||
private int tab;
|
||||
private String folderName;
|
||||
|
||||
public CloneListPacket(int tab) {
|
||||
this.tab = tab;
|
||||
this.folderName = null;
|
||||
}
|
||||
|
||||
public CloneListPacket(String folderName) {
|
||||
this.tab = -1;
|
||||
this.folderName = folderName;
|
||||
}
|
||||
|
||||
public CloneListPacket() {
|
||||
@@ -45,6 +52,9 @@ public final class CloneListPacket extends AbstractPacket {
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
out.writeInt(tab);
|
||||
if (tab == -1) {
|
||||
kamkeel.npcs.util.ByteBufUtils.writeString(out, folderName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,14 +64,26 @@ public final class CloneListPacket extends AbstractPacket {
|
||||
if (!PacketUtil.verifyItemPacket(packetName, player, EnumItemPacketType.MOUNTER, EnumItemPacketType.CLONER))
|
||||
return;
|
||||
|
||||
NBTTagList list = new NBTTagList();
|
||||
int tab = in.readInt();
|
||||
for (String name : ServerCloneController.Instance.getClones(tab))
|
||||
list.appendTag(new NBTTagString(name));
|
||||
String folder = null;
|
||||
if (tab == -1) {
|
||||
folder = kamkeel.npcs.util.ByteBufUtils.readString(in);
|
||||
}
|
||||
|
||||
NBTTagList list = new NBTTagList();
|
||||
NBTTagList listDate = new NBTTagList();
|
||||
for (String name : ServerCloneController.Instance.getClonesDate(tab))
|
||||
listDate.appendTag(new NBTTagString(name));
|
||||
|
||||
if (folder != null) {
|
||||
for (String name : ServerCloneController.Instance.getClones(folder))
|
||||
list.appendTag(new NBTTagString(name));
|
||||
for (String name : ServerCloneController.Instance.getClonesDate(folder))
|
||||
listDate.appendTag(new NBTTagString(name));
|
||||
} else {
|
||||
for (String name : ServerCloneController.Instance.getClones(tab))
|
||||
list.appendTag(new NBTTagString(name));
|
||||
for (String name : ServerCloneController.Instance.getClonesDate(tab))
|
||||
listDate.appendTag(new NBTTagString(name));
|
||||
}
|
||||
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
compound.setTag("List", list);
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package kamkeel.npcs.network.packets.request.clone;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import kamkeel.npcs.network.AbstractPacket;
|
||||
import kamkeel.npcs.network.PacketChannel;
|
||||
import kamkeel.npcs.network.PacketHandler;
|
||||
import kamkeel.npcs.network.PacketUtil;
|
||||
import kamkeel.npcs.network.enums.EnumItemPacketType;
|
||||
import kamkeel.npcs.network.enums.EnumRequestPacket;
|
||||
import kamkeel.npcs.network.packets.data.large.GuiDataPacket;
|
||||
import kamkeel.npcs.util.ByteBufUtils;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import noppes.npcs.CustomNpcsPermissions;
|
||||
import noppes.npcs.controllers.ServerCloneController;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class CloneMovePacket extends AbstractPacket {
|
||||
public static String packetName = "Request|CloneMove";
|
||||
|
||||
private String cloneName;
|
||||
private int fromTab;
|
||||
private String fromFolder;
|
||||
private int toTab;
|
||||
private String toFolder;
|
||||
|
||||
public CloneMovePacket() {
|
||||
}
|
||||
|
||||
public CloneMovePacket(String cloneName, int fromTab, String fromFolder, int toTab, String toFolder) {
|
||||
this.cloneName = cloneName;
|
||||
this.fromTab = fromTab;
|
||||
this.fromFolder = fromFolder;
|
||||
this.toTab = toTab;
|
||||
this.toFolder = toFolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enum getType() {
|
||||
return EnumRequestPacket.CloneMove;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketChannel getChannel() {
|
||||
return PacketHandler.REQUEST_PACKET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomNpcsPermissions.Permission getPermission() {
|
||||
return CustomNpcsPermissions.NPC_CLONE;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
ByteBufUtils.writeString(out, cloneName);
|
||||
out.writeInt(fromTab);
|
||||
ByteBufUtils.writeString(out, fromFolder != null ? fromFolder : "");
|
||||
out.writeInt(toTab);
|
||||
ByteBufUtils.writeString(out, toFolder != null ? toFolder : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
|
||||
if (!(player instanceof EntityPlayerMP))
|
||||
return;
|
||||
if (!PacketUtil.verifyItemPacket(packetName, player, EnumItemPacketType.CLONER))
|
||||
return;
|
||||
|
||||
String cloneName = ByteBufUtils.readString(in);
|
||||
int fromTab = in.readInt();
|
||||
String fromFolder = ByteBufUtils.readString(in);
|
||||
if (fromFolder.isEmpty()) fromFolder = null;
|
||||
int toTab = in.readInt();
|
||||
String toFolder = ByteBufUtils.readString(in);
|
||||
if (toFolder.isEmpty()) toFolder = null;
|
||||
|
||||
boolean success = false;
|
||||
if (fromFolder != null && toFolder != null) {
|
||||
success = ServerCloneController.Instance.moveClone(cloneName, fromFolder, toFolder);
|
||||
} else if (fromFolder != null) {
|
||||
success = ServerCloneController.Instance.moveClone(cloneName, fromFolder, toTab);
|
||||
} else if (toFolder != null) {
|
||||
success = ServerCloneController.Instance.moveClone(cloneName, fromTab, toFolder);
|
||||
} else {
|
||||
success = ServerCloneController.Instance.moveClone(cloneName, fromTab, toTab);
|
||||
}
|
||||
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
compound.setBoolean("MoveSuccess", success);
|
||||
GuiDataPacket.sendGuiData((EntityPlayerMP) player, compound);
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ public final class ClonePreSavePacket extends AbstractPacket {
|
||||
|
||||
private String name;
|
||||
private int tab;
|
||||
private String folderName;
|
||||
|
||||
public ClonePreSavePacket() {
|
||||
}
|
||||
@@ -31,6 +32,13 @@ public final class ClonePreSavePacket extends AbstractPacket {
|
||||
public ClonePreSavePacket(String name, int tab) {
|
||||
this.name = name;
|
||||
this.tab = tab;
|
||||
this.folderName = null;
|
||||
}
|
||||
|
||||
public ClonePreSavePacket(String name, String folderName) {
|
||||
this.name = name;
|
||||
this.tab = -1;
|
||||
this.folderName = folderName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,6 +61,9 @@ public final class ClonePreSavePacket extends AbstractPacket {
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
ByteBufUtils.writeString(out, this.name);
|
||||
out.writeInt(tab);
|
||||
if (tab == -1) {
|
||||
ByteBufUtils.writeString(out, this.folderName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,7 +73,15 @@ public final class ClonePreSavePacket extends AbstractPacket {
|
||||
if (!PacketUtil.verifyItemPacket(packetName, player, EnumItemPacketType.CLONER))
|
||||
return;
|
||||
|
||||
boolean bo = ServerCloneController.Instance.getCloneData(null, ByteBufUtils.readString(in), in.readInt()) != null;
|
||||
String name = ByteBufUtils.readString(in);
|
||||
int tab = in.readInt();
|
||||
boolean bo;
|
||||
if (tab == -1) {
|
||||
String folder = ByteBufUtils.readString(in);
|
||||
bo = ServerCloneController.Instance.getCloneData(null, name, folder) != null;
|
||||
} else {
|
||||
bo = ServerCloneController.Instance.getCloneData(null, name, tab) != null;
|
||||
}
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
compound.setBoolean("NameExists", bo);
|
||||
GuiDataPacket.sendGuiData((EntityPlayerMP) player, compound);
|
||||
|
||||
@@ -25,6 +25,7 @@ public final class CloneRemovePacket extends AbstractPacket {
|
||||
public static String packetName = "Request|CloneRemove";
|
||||
|
||||
private int tab;
|
||||
private String folderName;
|
||||
private String name;
|
||||
|
||||
public CloneRemovePacket() {
|
||||
@@ -32,6 +33,13 @@ public final class CloneRemovePacket extends AbstractPacket {
|
||||
|
||||
public CloneRemovePacket(int tab, String name) {
|
||||
this.tab = tab;
|
||||
this.folderName = null;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public CloneRemovePacket(String folderName, String name) {
|
||||
this.tab = -1;
|
||||
this.folderName = folderName;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@@ -54,6 +62,9 @@ public final class CloneRemovePacket extends AbstractPacket {
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
out.writeInt(tab);
|
||||
if (tab == -1) {
|
||||
ByteBufUtils.writeString(out, this.folderName);
|
||||
}
|
||||
ByteBufUtils.writeString(out, this.name);
|
||||
}
|
||||
|
||||
@@ -65,16 +76,28 @@ public final class CloneRemovePacket extends AbstractPacket {
|
||||
return;
|
||||
|
||||
int tab = in.readInt();
|
||||
ServerCloneController.Instance.removeClone(ByteBufUtils.readString(in), tab);
|
||||
String folder = null;
|
||||
if (tab == -1) {
|
||||
folder = ByteBufUtils.readString(in);
|
||||
}
|
||||
String cloneName = ByteBufUtils.readString(in);
|
||||
|
||||
NBTTagList list = new NBTTagList();
|
||||
|
||||
for (String name : ServerCloneController.Instance.getClones(tab))
|
||||
list.appendTag(new NBTTagString(name));
|
||||
|
||||
NBTTagList listDate = new NBTTagList();
|
||||
for (String name : ServerCloneController.Instance.getClonesDate(tab))
|
||||
listDate.appendTag(new NBTTagString(name));
|
||||
|
||||
if (folder != null) {
|
||||
ServerCloneController.Instance.removeClone(cloneName, folder);
|
||||
for (String name : ServerCloneController.Instance.getClones(folder))
|
||||
list.appendTag(new NBTTagString(name));
|
||||
for (String name : ServerCloneController.Instance.getClonesDate(folder))
|
||||
listDate.appendTag(new NBTTagString(name));
|
||||
} else {
|
||||
ServerCloneController.Instance.removeClone(cloneName, tab);
|
||||
for (String name : ServerCloneController.Instance.getClones(tab))
|
||||
list.appendTag(new NBTTagString(name));
|
||||
for (String name : ServerCloneController.Instance.getClonesDate(tab))
|
||||
listDate.appendTag(new NBTTagString(name));
|
||||
}
|
||||
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
compound.setTag("List", list);
|
||||
|
||||
@@ -25,6 +25,7 @@ public final class CloneSavePacket extends AbstractPacket {
|
||||
|
||||
private String name;
|
||||
private int tab;
|
||||
private String folderName;
|
||||
private NBTTagCompound tagExtra;
|
||||
private NBTTagCompound tagCompound;
|
||||
|
||||
@@ -34,6 +35,15 @@ public final class CloneSavePacket extends AbstractPacket {
|
||||
public CloneSavePacket(String name, int tab, NBTTagCompound tagExtra, NBTTagCompound tagCompound) {
|
||||
this.name = name;
|
||||
this.tab = tab;
|
||||
this.folderName = null;
|
||||
this.tagExtra = tagExtra;
|
||||
this.tagCompound = tagCompound;
|
||||
}
|
||||
|
||||
public CloneSavePacket(String name, String folderName, NBTTagCompound tagExtra, NBTTagCompound tagCompound) {
|
||||
this.name = name;
|
||||
this.tab = -1;
|
||||
this.folderName = folderName;
|
||||
this.tagExtra = tagExtra;
|
||||
this.tagCompound = tagCompound;
|
||||
}
|
||||
@@ -58,6 +68,9 @@ public final class CloneSavePacket extends AbstractPacket {
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
ByteBufUtils.writeString(out, this.name);
|
||||
out.writeInt(tab);
|
||||
if (tab == -1) {
|
||||
ByteBufUtils.writeString(out, this.folderName);
|
||||
}
|
||||
ByteBufUtils.writeNBT(out, this.tagExtra);
|
||||
ByteBufUtils.writeNBT(out, this.tagCompound);
|
||||
}
|
||||
@@ -75,11 +88,20 @@ public final class CloneSavePacket extends AbstractPacket {
|
||||
|
||||
String name = ByteBufUtils.readString(in);
|
||||
int tab = in.readInt();
|
||||
String folder = null;
|
||||
if (tab == -1) {
|
||||
folder = ByteBufUtils.readString(in);
|
||||
}
|
||||
NBTTagCompound tagExtra = ByteBufUtils.readNBT(in);
|
||||
NBTTagCompound tagCompound = ByteBufUtils.readNBT(in);
|
||||
|
||||
NBTTagList tagList = tagCompound.getTagList("TagUUIDs", 8);
|
||||
data.cloned.setTag("TagUUIDs", tagList);
|
||||
ServerCloneController.Instance.addClone(data.cloned, name, tab, tagExtra);
|
||||
|
||||
if (folder != null) {
|
||||
ServerCloneController.Instance.addClone(data.cloned, name, folder, tagExtra);
|
||||
} else {
|
||||
ServerCloneController.Instance.addClone(data.cloned, name, tab, tagExtra);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import kamkeel.npcs.network.packets.data.large.GuiDataPacket;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import kamkeel.npcs.util.ByteBufUtils;
|
||||
import noppes.npcs.controllers.ServerTagMapController;
|
||||
import noppes.npcs.controllers.data.TagMap;
|
||||
|
||||
@@ -22,9 +23,16 @@ public final class CloneTagListPacket extends AbstractPacket {
|
||||
public static String packetName = "Request|CloneTagList";
|
||||
|
||||
private int tab;
|
||||
private String folderName;
|
||||
|
||||
public CloneTagListPacket(int tab) {
|
||||
this.tab = tab;
|
||||
this.folderName = null;
|
||||
}
|
||||
|
||||
public CloneTagListPacket(String folderName) {
|
||||
this.tab = -1;
|
||||
this.folderName = folderName;
|
||||
}
|
||||
|
||||
public CloneTagListPacket() {
|
||||
@@ -44,6 +52,9 @@ public final class CloneTagListPacket extends AbstractPacket {
|
||||
@Override
|
||||
public void sendData(ByteBuf out) throws IOException {
|
||||
out.writeInt(tab);
|
||||
if (tab == -1) {
|
||||
ByteBufUtils.writeString(out, folderName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,7 +65,13 @@ public final class CloneTagListPacket extends AbstractPacket {
|
||||
return;
|
||||
|
||||
int tab = in.readInt();
|
||||
TagMap tagMap = ServerTagMapController.Instance.getTagMap(tab);
|
||||
TagMap tagMap;
|
||||
if (tab == -1) {
|
||||
String folder = ByteBufUtils.readString(in);
|
||||
tagMap = ServerTagMapController.Instance.getTagMap(folder);
|
||||
} else {
|
||||
tagMap = ServerTagMapController.Instance.getTagMap(tab);
|
||||
}
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
compound.setTag("CloneTags", tagMap.writeNBT());
|
||||
GuiDataPacket.sendGuiData((EntityPlayerMP) player, compound);
|
||||
|
||||
@@ -31,6 +31,7 @@ public class MobSpawnerPacket extends AbstractPacket {
|
||||
|
||||
private String selectedName;
|
||||
private int tab;
|
||||
private String folderName;
|
||||
|
||||
private NBTTagCompound compound;
|
||||
|
||||
@@ -44,6 +45,17 @@ public class MobSpawnerPacket extends AbstractPacket {
|
||||
this.posz = posz;
|
||||
this.selectedName = selectedName;
|
||||
this.tab = tab;
|
||||
this.folderName = null;
|
||||
}
|
||||
|
||||
public MobSpawnerPacket(Action type, int posX, int posY, int posz, String selectedName, String folderName) {
|
||||
this.type = type;
|
||||
this.posX = posX;
|
||||
this.posY = posY;
|
||||
this.posz = posz;
|
||||
this.selectedName = selectedName;
|
||||
this.tab = -1;
|
||||
this.folderName = folderName;
|
||||
}
|
||||
|
||||
public MobSpawnerPacket(Action type, int posX, int posY, int posz, NBTTagCompound compound) {
|
||||
@@ -58,6 +70,10 @@ public class MobSpawnerPacket extends AbstractPacket {
|
||||
PacketClient.sendClient(new MobSpawnerPacket(Action.Server, x, y, z, name, tab));
|
||||
}
|
||||
|
||||
public static void ServerFolder(int x, int y, int z, String name, String folderName) {
|
||||
PacketClient.sendClient(new MobSpawnerPacket(Action.Server, x, y, z, name, folderName));
|
||||
}
|
||||
|
||||
public static void Client(int x, int y, int z, NBTTagCompound compound) {
|
||||
PacketClient.sendClient(new MobSpawnerPacket(Action.Client, x, y, z, compound));
|
||||
}
|
||||
@@ -88,6 +104,9 @@ public class MobSpawnerPacket extends AbstractPacket {
|
||||
if (type == Action.Server) {
|
||||
ByteBufUtils.writeString(out, this.selectedName);
|
||||
out.writeInt(this.tab);
|
||||
if (this.tab == -1) {
|
||||
ByteBufUtils.writeString(out, this.folderName);
|
||||
}
|
||||
} else {
|
||||
ByteBufUtils.writeNBT(out, this.compound);
|
||||
}
|
||||
@@ -107,10 +126,18 @@ public class MobSpawnerPacket extends AbstractPacket {
|
||||
int z = in.readInt();
|
||||
NBTTagCompound compound;
|
||||
|
||||
if (requestedAction == Action.Server)
|
||||
compound = ServerCloneController.Instance.getCloneData(player, ByteBufUtils.readString(in), in.readInt());
|
||||
else
|
||||
if (requestedAction == Action.Server) {
|
||||
String name = ByteBufUtils.readString(in);
|
||||
int tab = in.readInt();
|
||||
if (tab == -1) {
|
||||
String folder = ByteBufUtils.readString(in);
|
||||
compound = ServerCloneController.Instance.getCloneData(player, name, folder);
|
||||
} else {
|
||||
compound = ServerCloneController.Instance.getCloneData(player, name, tab);
|
||||
}
|
||||
} else {
|
||||
compound = ByteBufUtils.readNBT(in);
|
||||
}
|
||||
|
||||
if (!ConfigScript.canScript(player, CustomNpcsPermissions.SCRIPT)) {
|
||||
return;
|
||||
|
||||
@@ -37,6 +37,7 @@ public class SpawnMobPacket extends AbstractPacket {
|
||||
|
||||
private String selectedName;
|
||||
private int tab;
|
||||
private String folderName;
|
||||
|
||||
private NBTTagCompound compound;
|
||||
|
||||
@@ -50,6 +51,17 @@ public class SpawnMobPacket extends AbstractPacket {
|
||||
this.posz = posz;
|
||||
this.selectedName = selectedName;
|
||||
this.tab = tab;
|
||||
this.folderName = null;
|
||||
}
|
||||
|
||||
public SpawnMobPacket(Action type, int posX, int posY, int posz, String selectedName, String folderName) {
|
||||
this.type = type;
|
||||
this.posX = posX;
|
||||
this.posY = posY;
|
||||
this.posz = posz;
|
||||
this.selectedName = selectedName;
|
||||
this.tab = -1;
|
||||
this.folderName = folderName;
|
||||
}
|
||||
|
||||
public SpawnMobPacket(Action type, int posX, int posY, int posz, NBTTagCompound compound) {
|
||||
@@ -64,6 +76,10 @@ public class SpawnMobPacket extends AbstractPacket {
|
||||
PacketClient.sendClient(new SpawnMobPacket(Action.Server, x, y, z, name, tab));
|
||||
}
|
||||
|
||||
public static void ServerFolder(int x, int y, int z, String name, String folderName) {
|
||||
PacketClient.sendClient(new SpawnMobPacket(Action.Server, x, y, z, name, folderName));
|
||||
}
|
||||
|
||||
public static void Client(int x, int y, int z, NBTTagCompound compound) {
|
||||
PacketClient.sendClient(new SpawnMobPacket(Action.Client, x, y, z, compound));
|
||||
}
|
||||
@@ -94,6 +110,9 @@ public class SpawnMobPacket extends AbstractPacket {
|
||||
if (type == Action.Server) {
|
||||
ByteBufUtils.writeString(out, this.selectedName);
|
||||
out.writeInt(this.tab);
|
||||
if (this.tab == -1) {
|
||||
ByteBufUtils.writeString(out, this.folderName);
|
||||
}
|
||||
} else {
|
||||
ByteBufUtils.writeNBT(out, this.compound);
|
||||
}
|
||||
@@ -113,10 +132,18 @@ public class SpawnMobPacket extends AbstractPacket {
|
||||
int z = in.readInt();
|
||||
NBTTagCompound compound;
|
||||
|
||||
if (requestedAction == Action.Server)
|
||||
compound = ServerCloneController.Instance.getCloneData(player, ByteBufUtils.readString(in), in.readInt());
|
||||
else
|
||||
if (requestedAction == Action.Server) {
|
||||
String name = ByteBufUtils.readString(in);
|
||||
int tab = in.readInt();
|
||||
if (tab == -1) {
|
||||
String folder = ByteBufUtils.readString(in);
|
||||
compound = ServerCloneController.Instance.getCloneData(player, name, folder);
|
||||
} else {
|
||||
compound = ServerCloneController.Instance.getCloneData(player, name, tab);
|
||||
}
|
||||
} else {
|
||||
compound = ByteBufUtils.readNBT(in);
|
||||
}
|
||||
|
||||
if (compound == null)
|
||||
return;
|
||||
|
||||
@@ -76,6 +76,7 @@ import noppes.npcs.client.gui.GuiBorderBlock;
|
||||
import noppes.npcs.client.gui.GuiMerchantAdd;
|
||||
import noppes.npcs.client.gui.GuiNpcDimension;
|
||||
import noppes.npcs.client.gui.GuiNpcMobSpawner;
|
||||
import noppes.npcs.client.gui.GuiNpcMobSpawnerFullscreen;
|
||||
import noppes.npcs.client.gui.GuiNpcMobSpawnerMounter;
|
||||
import noppes.npcs.client.gui.GuiNpcPather;
|
||||
import noppes.npcs.client.gui.GuiNpcRedstoneBlock;
|
||||
@@ -334,7 +335,6 @@ public class ClientProxy extends CommonProxy {
|
||||
|
||||
ClientCloneController.Instance = new ClientCloneController();
|
||||
ClientTagMapController.Instance = new ClientTagMapController();
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(new ClientEventHandler());
|
||||
|
||||
// Telegraph rendering system
|
||||
@@ -603,7 +603,9 @@ public class ClientProxy extends CommonProxy {
|
||||
return new GuiNpcRedstoneBlock(x, y, z);
|
||||
|
||||
else if (gui == EnumGuiType.Cloner)
|
||||
return new GuiNpcMobSpawner(x, y, z);
|
||||
return GuiNpcMobSpawner.isFullscreen
|
||||
? new GuiNpcMobSpawnerFullscreen(x, y, z)
|
||||
: new GuiNpcMobSpawner(x, y, z);
|
||||
|
||||
else if (gui == EnumGuiType.MobSpawnerMounter)
|
||||
return new GuiNpcMobSpawnerMounter(x, y, z);
|
||||
|
||||
@@ -41,6 +41,26 @@ public class ClientCloneController extends ServerCloneController {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addToTagMap(NBTTagCompound nbttagcompound, String name, String folderName) {
|
||||
HashSet<UUID> tagUUIDs = new HashSet<>();
|
||||
if (nbttagcompound.hasKey("TagUUIDs")) {
|
||||
NBTTagList nbtTagList = nbttagcompound.getTagList("TagUUIDs", 8);
|
||||
for (int i = 0; i < nbtTagList.tagCount(); i++) {
|
||||
tagUUIDs.add(UUID.fromString(nbtTagList.getStringTagAt(i)));
|
||||
}
|
||||
}
|
||||
|
||||
TagMap tagMap = ClientTagMapController.Instance.getTagMap(folderName);
|
||||
if (!tagUUIDs.isEmpty()) {
|
||||
tagMap.putClone(name, tagUUIDs);
|
||||
} else {
|
||||
tagMap.removeClone(name);
|
||||
}
|
||||
ClientTagMapController.Instance.saveTagMap(tagMap);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFromTagMap(String name, int tab) {
|
||||
TagMap tagMap = ClientTagMapController.Instance.getTagMap(tab);
|
||||
@@ -51,4 +71,43 @@ public class ClientCloneController extends ServerCloneController {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFromTagMap(String name, String folderName) {
|
||||
TagMap tagMap = ClientTagMapController.Instance.getTagMap(folderName);
|
||||
if (tagMap.removeClone(name)) {
|
||||
ClientTagMapController.Instance.saveTagMap(tagMap);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HashSet<UUID> getTagUUIDsFromTab(String cloneName, int tab) {
|
||||
TagMap tagMap = ClientTagMapController.Instance.getTagMap(tab);
|
||||
HashSet<UUID> uuids = tagMap.getUUIDs(cloneName);
|
||||
return uuids != null ? new HashSet<>(uuids) : new HashSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HashSet<UUID> getTagUUIDsFromFolder(String cloneName, String folderName) {
|
||||
TagMap tagMap = ClientTagMapController.Instance.getTagMap(folderName);
|
||||
HashSet<UUID> uuids = tagMap.getUUIDs(cloneName);
|
||||
return uuids != null ? new HashSet<>(uuids) : new HashSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setTagUUIDsForTab(String cloneName, int tab, HashSet<UUID> tagUUIDs) {
|
||||
if (tagUUIDs == null || tagUUIDs.isEmpty()) return;
|
||||
TagMap tagMap = ClientTagMapController.Instance.getTagMap(tab);
|
||||
tagMap.putClone(cloneName, tagUUIDs);
|
||||
ClientTagMapController.Instance.saveTagMap(tagMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setTagUUIDsForFolder(String cloneName, String folderName, HashSet<UUID> tagUUIDs) {
|
||||
if (tagUUIDs == null || tagUUIDs.isEmpty()) return;
|
||||
TagMap tagMap = ClientTagMapController.Instance.getTagMap(folderName);
|
||||
tagMap.putClone(cloneName, tagUUIDs);
|
||||
ClientTagMapController.Instance.saveTagMap(tagMap);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package noppes.npcs.client.gui;
|
||||
|
||||
import kamkeel.npcs.network.PacketClient;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneAllTagsPacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneFolderListPacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneListPacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneRemovePacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneTagListPacket;
|
||||
@@ -26,6 +27,8 @@ import noppes.npcs.client.gui.util.GuiNPCInterface;
|
||||
import noppes.npcs.client.gui.util.GuiNpcButton;
|
||||
import noppes.npcs.client.gui.util.GuiNpcLabel;
|
||||
import noppes.npcs.client.gui.util.GuiNpcTextField;
|
||||
import noppes.npcs.client.gui.util.IClonerGui;
|
||||
import noppes.npcs.client.gui.util.ICustomScrollListener;
|
||||
import noppes.npcs.client.gui.util.IGuiData;
|
||||
import noppes.npcs.controllers.data.Tag;
|
||||
import noppes.npcs.controllers.data.TagMap;
|
||||
@@ -38,52 +41,84 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData {
|
||||
public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData, ICustomScrollListener, IClonerGui {
|
||||
|
||||
// ==================== STATIC STATE (persists across GUI opens, shared with fullscreen) ====================
|
||||
public static boolean isFullscreen = false;
|
||||
public static int activeTab = 1;
|
||||
public static String activeFolder = null;
|
||||
public static int showingClones = 0; // 0=Clones, 1=Entities, 2=Server, 3=Filters
|
||||
public static String search = "";
|
||||
public static String tagSearch = "";
|
||||
|
||||
public static HashMap<UUID, Tag> tags = new HashMap<>();
|
||||
public static HashMap<String, UUID> tagNames = new HashMap<>();
|
||||
public static HashSet<String> tagFilters = new HashSet<>();
|
||||
public static byte displayTags = 0;
|
||||
|
||||
// 0 - Any, 1 - All, 2 - Not Any, 3 - Not All
|
||||
public static byte filterCondition = 0;
|
||||
|
||||
public static byte ascending = 0;
|
||||
|
||||
// 0 - By Name, 1 - By Date
|
||||
public static byte sortType = 0;
|
||||
|
||||
public TagMap tagMap;
|
||||
// Scroll position preservation (shared with fullscreen)
|
||||
public static int savedContentScrollY = 0;
|
||||
public static int savedNavScrollY = 0;
|
||||
|
||||
// ==================== INSTANCE STATE ====================
|
||||
public TagMap tagMap;
|
||||
private final GuiCustomScrollCloner scroll = new GuiCustomScrollCloner(this, 0);
|
||||
private final GuiCustomScroll filterScroll = new GuiCustomScroll(this, 1);
|
||||
|
||||
private int posX, posY, posZ;
|
||||
|
||||
public int posX, posY, posZ;
|
||||
private List<String> list;
|
||||
private List<String> rawList;
|
||||
private List<String> tagList;
|
||||
|
||||
private static int showingClones = 0;
|
||||
|
||||
private static String search = "";
|
||||
private static String tagSearch = "";
|
||||
|
||||
private int activeTab = 1;
|
||||
|
||||
// ==================== CONSTRUCTOR ====================
|
||||
public GuiNpcMobSpawner(int i, int j, int k) {
|
||||
super();
|
||||
xSize = 354;
|
||||
posX = i;
|
||||
posY = j;
|
||||
posZ = k;
|
||||
|
||||
this.closeOnEsc = true;
|
||||
|
||||
closeOnEsc = true;
|
||||
xSize = 354;
|
||||
setBackground("menubg.png");
|
||||
PacketClient.sendClient(new CloneAllTagsPacket());
|
||||
if (showingClones == 2) {
|
||||
PacketClient.sendClient(new CloneFolderListPacket());
|
||||
}
|
||||
|
||||
// Minimized view doesn't support folders — ensure we're on a tab
|
||||
if (activeFolder != null) {
|
||||
if (activeTab < 1 || activeTab > 15) {
|
||||
activeTab = 1;
|
||||
}
|
||||
activeFolder = null;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== IClonerGui ====================
|
||||
@Override
|
||||
public int getShowingClones() {
|
||||
return showingClones;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<UUID, Tag> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TagMap getTagMap() {
|
||||
return tagMap;
|
||||
}
|
||||
|
||||
// ==================== INIT GUI ====================
|
||||
public void initGui() {
|
||||
// Save scroll position before clear
|
||||
savedContentScrollY = scroll.scrollY;
|
||||
|
||||
super.initGui();
|
||||
guiTop += 10;
|
||||
guiLeft += 30;
|
||||
@@ -92,6 +127,7 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData {
|
||||
scroll.setSize(293, 188);
|
||||
scroll.guiLeft = guiLeft + 4;
|
||||
scroll.guiTop = guiTop + 26;
|
||||
|
||||
filterScroll.clear();
|
||||
filterScroll.setSize(140, 166);
|
||||
filterScroll.guiLeft = guiLeft + 4;
|
||||
@@ -99,112 +135,133 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData {
|
||||
filterScroll.multipleSelection = true;
|
||||
filterScroll.setSelectedList(tagFilters);
|
||||
|
||||
GuiMenuTopButton button;
|
||||
addTopButton(button = new GuiMenuTopButton(3, guiLeft + 4, guiTop - 17, "spawner.clones"));
|
||||
button.active = showingClones == 0;
|
||||
addTopButton(button = new GuiMenuTopButton(5, button, "gui.server"));
|
||||
button.active = showingClones == 2;
|
||||
addTopButton(button = new GuiMenuTopButton(4, button, "spawner.entities"));
|
||||
button.active = showingClones == 1;
|
||||
addTopButton(button = new GuiMenuTopButton(16, guiLeft + (xSize - 67), guiTop - 17, "gui.filters"));
|
||||
button.active = showingClones == 3;
|
||||
addTopButton(button = new GuiMenuTopButton(17, guiLeft + (xSize - 22), guiTop - 17, "X"));
|
||||
// Top buttons — build right-to-left to avoid overlap
|
||||
GuiMenuTopButton closeBtn = new GuiMenuTopButton(17, guiLeft + (xSize - 22), guiTop - 17, "X");
|
||||
addTopButton(closeBtn);
|
||||
|
||||
// Position "+" dynamically to the left of "X"
|
||||
int plusX = closeBtn.xPosition - (fontRendererObj.getStringWidth("+") + 12) - 2;
|
||||
GuiMenuTopButton fullscreenBtn = new GuiMenuTopButton(61, plusX, guiTop - 17, "+");
|
||||
addTopButton(fullscreenBtn);
|
||||
|
||||
// Position "Filters" dynamically to the left of "+"
|
||||
int filterBtnW = fontRendererObj.getStringWidth(StatCollector.translateToLocal("gui.filters")) + 12;
|
||||
int filterX = fullscreenBtn.xPosition - filterBtnW - 2;
|
||||
GuiMenuTopButton filterBtn = new GuiMenuTopButton(16, filterX, guiTop - 17, "gui.filters");
|
||||
filterBtn.active = showingClones == 3;
|
||||
addTopButton(filterBtn);
|
||||
|
||||
// Mode buttons from left
|
||||
GuiMenuTopButton btn;
|
||||
addTopButton(btn = new GuiMenuTopButton(3, guiLeft + 4, guiTop - 17, "spawner.clones"));
|
||||
btn.active = showingClones == 0;
|
||||
addTopButton(btn = new GuiMenuTopButton(5, btn, "gui.server"));
|
||||
btn.active = showingClones == 2;
|
||||
addTopButton(btn = new GuiMenuTopButton(4, btn, "spawner.entities"));
|
||||
btn.active = showingClones == 1;
|
||||
|
||||
if (showingClones < 3) {
|
||||
addScroll(scroll);
|
||||
addTextField(new GuiNpcTextField(1, this, fontRendererObj, guiLeft + 4, guiTop + 4, 293, 20, search));
|
||||
|
||||
addButton(new GuiNpcButton(1, guiLeft + 298, guiTop + 6, 52, 20, "item.monsterPlacer.name"));
|
||||
addButton(new GuiNpcButton(2, guiLeft + 298, guiTop + 140, 52, 20, "spawner.mobspawner"));
|
||||
|
||||
if (showingClones == 0 || showingClones == 2) {
|
||||
|
||||
addSideButton(new GuiMenuSideButton(21, guiLeft - 70, this.guiTop + 2, 70, 22, "1"));
|
||||
addSideButton(new GuiMenuSideButton(22, guiLeft - 70, this.guiTop + 23, 70, 22, "2"));
|
||||
addSideButton(new GuiMenuSideButton(23, guiLeft - 70, this.guiTop + 44, 70, 22, "3"));
|
||||
addSideButton(new GuiMenuSideButton(24, guiLeft - 70, this.guiTop + 65, 70, 22, "4"));
|
||||
addSideButton(new GuiMenuSideButton(25, guiLeft - 70, this.guiTop + 86, 70, 22, "5"));
|
||||
addSideButton(new GuiMenuSideButton(26, guiLeft - 70, this.guiTop + 107, 35, 22, "6"));
|
||||
addSideButton(new GuiMenuSideButton(27, guiLeft - 35, this.guiTop + 107, 35, 22, "7"));
|
||||
addSideButton(new GuiMenuSideButton(28, guiLeft - 70, this.guiTop + 128, 35, 22, "8"));
|
||||
addSideButton(new GuiMenuSideButton(29, guiLeft - 35, this.guiTop + 128, 35, 22, "9"));
|
||||
addSideButton(new GuiMenuSideButton(30, guiLeft - 70, this.guiTop + 149, 35, 22, "10"));
|
||||
addSideButton(new GuiMenuSideButton(31, guiLeft - 35, this.guiTop + 149, 35, 22, "11"));
|
||||
addSideButton(new GuiMenuSideButton(32, guiLeft - 70, this.guiTop + 170, 35, 22, "12"));
|
||||
addSideButton(new GuiMenuSideButton(33, guiLeft - 35, this.guiTop + 170, 35, 22, "13"));
|
||||
addSideButton(new GuiMenuSideButton(34, guiLeft - 70, this.guiTop + 191, 35, 22, "14"));
|
||||
addSideButton(new GuiMenuSideButton(35, guiLeft - 35, this.guiTop + 191, 35, 22, "15"));
|
||||
|
||||
addButton(new GuiNpcButton(6, guiLeft + 298, guiTop + 190, 52, 20, "gui.remove"));
|
||||
|
||||
getSideButton(20 + activeTab).active = true;
|
||||
initTabSideButtons();
|
||||
showClones();
|
||||
|
||||
// Restore scroll position
|
||||
scroll.scrollY = Math.min(savedContentScrollY, Math.max(0, scroll.maxScrollY));
|
||||
} else {
|
||||
showEntities();
|
||||
scroll.scrollY = Math.min(savedContentScrollY, Math.max(0, scroll.maxScrollY));
|
||||
}
|
||||
} else {
|
||||
// Show Filters
|
||||
addLabel(new GuiNpcLabel(1, StatCollector.translateToLocal("cloner.tagFilters"), guiLeft + 7, guiTop + 7));
|
||||
addScroll(filterScroll);
|
||||
addTextField(new GuiNpcTextField(2, this, fontRendererObj, guiLeft + 4, guiTop + 190, 140, 20, tagSearch));
|
||||
|
||||
addLabel(new GuiNpcLabel(2, StatCollector.translateToLocal("cloner.tagVisibility"), guiLeft + 150, guiTop + 27));
|
||||
addButton(new GuiNpcButton(12, guiLeft + 215, guiTop + 20, new String[]{"display.show", "display.all", "display.hide"}, displayTags));
|
||||
|
||||
addLabel(new GuiNpcLabel(3, StatCollector.translateToLocal("filter.contains"), guiLeft + 150, guiTop + 50));
|
||||
addButton(new GuiNpcButton(13, guiLeft + 215, guiTop + 43, new String[]{"filter.any", "filter.all", "filter.notany", "filter.notall"}, filterCondition));
|
||||
|
||||
addButton(new GuiNpcButton(11, guiLeft + 150, guiTop + 66, 130, 20, "gui.deselectAll"));
|
||||
|
||||
|
||||
addLabel(new GuiNpcLabel(4, StatCollector.translateToLocal("cloner.order"), guiLeft + 150, guiTop + 112));
|
||||
addButton(new GuiNpcButton(14, guiLeft + 215, guiTop + 105, new String[]{"cloner.ascending", "cloner.descending"}, ascending));
|
||||
|
||||
addLabel(new GuiNpcLabel(5, StatCollector.translateToLocal("cloner.type"), guiLeft + 150, guiTop + 135));
|
||||
addButton(new GuiNpcButton(15, guiLeft + 215, guiTop + 128, new String[]{"cloner.name", "cloner.date"}, sortType));
|
||||
|
||||
|
||||
getButton(12).width = 65;
|
||||
getButton(12).height = 20;
|
||||
|
||||
getButton(13).width = 65;
|
||||
getButton(13).height = 20;
|
||||
|
||||
getButton(14).width = 65;
|
||||
getButton(14).height = 20;
|
||||
|
||||
getButton(15).width = 65;
|
||||
getButton(15).height = 20;
|
||||
|
||||
showFilters();
|
||||
showFiltersPage();
|
||||
}
|
||||
}
|
||||
|
||||
public int getShowingClones() {
|
||||
return showingClones;
|
||||
private void initTabSideButtons() {
|
||||
// Tabs 1-5: full width (70px)
|
||||
addSideButton(new GuiMenuSideButton(21, guiLeft - 70, guiTop + 2, 70, 22, "1"));
|
||||
addSideButton(new GuiMenuSideButton(22, guiLeft - 70, guiTop + 23, 70, 22, "2"));
|
||||
addSideButton(new GuiMenuSideButton(23, guiLeft - 70, guiTop + 44, 70, 22, "3"));
|
||||
addSideButton(new GuiMenuSideButton(24, guiLeft - 70, guiTop + 65, 70, 22, "4"));
|
||||
addSideButton(new GuiMenuSideButton(25, guiLeft - 70, guiTop + 86, 70, 22, "5"));
|
||||
// Tabs 6-15: half width (35px), 2-column grid
|
||||
addSideButton(new GuiMenuSideButton(26, guiLeft - 70, guiTop + 107, 35, 22, "6"));
|
||||
addSideButton(new GuiMenuSideButton(27, guiLeft - 35, guiTop + 107, 35, 22, "7"));
|
||||
addSideButton(new GuiMenuSideButton(28, guiLeft - 70, guiTop + 128, 35, 22, "8"));
|
||||
addSideButton(new GuiMenuSideButton(29, guiLeft - 35, guiTop + 128, 35, 22, "9"));
|
||||
addSideButton(new GuiMenuSideButton(30, guiLeft - 70, guiTop + 149, 35, 22, "10"));
|
||||
addSideButton(new GuiMenuSideButton(31, guiLeft - 35, guiTop + 149, 35, 22, "11"));
|
||||
addSideButton(new GuiMenuSideButton(32, guiLeft - 70, guiTop + 170, 35, 22, "12"));
|
||||
addSideButton(new GuiMenuSideButton(33, guiLeft - 35, guiTop + 170, 35, 22, "13"));
|
||||
addSideButton(new GuiMenuSideButton(34, guiLeft - 70, guiTop + 191, 35, 22, "14"));
|
||||
addSideButton(new GuiMenuSideButton(35, guiLeft - 35, guiTop + 191, 35, 22, "15"));
|
||||
|
||||
if (activeTab >= 1 && activeTab <= 15) {
|
||||
GuiMenuSideButton active = getSideButton(20 + activeTab);
|
||||
if (active != null) active.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void showFilters() {
|
||||
// ==================== FILTERS PAGE ====================
|
||||
private void showFiltersPage() {
|
||||
int baseY = guiTop;
|
||||
|
||||
addLabel(new GuiNpcLabel(1, StatCollector.translateToLocal("cloner.tagFilters"),
|
||||
guiLeft + 7, baseY + 7));
|
||||
|
||||
filterScroll.clear();
|
||||
filterScroll.setSize(140, 166);
|
||||
filterScroll.guiLeft = guiLeft + 4;
|
||||
filterScroll.guiTop = baseY + 19;
|
||||
filterScroll.multipleSelection = true;
|
||||
filterScroll.setSelectedList(tagFilters);
|
||||
addScroll(filterScroll);
|
||||
|
||||
addTextField(new GuiNpcTextField(2, this, fontRendererObj,
|
||||
guiLeft + 4, baseY + 190, 140, 20, tagSearch));
|
||||
|
||||
addLabel(new GuiNpcLabel(2, StatCollector.translateToLocal("cloner.tagVisibility"),
|
||||
guiLeft + 150, baseY + 27));
|
||||
addButton(new GuiNpcButton(12, guiLeft + 215, baseY + 20,
|
||||
new String[]{"display.show", "display.all", "display.hide"}, displayTags));
|
||||
|
||||
addLabel(new GuiNpcLabel(3, StatCollector.translateToLocal("filter.contains"),
|
||||
guiLeft + 150, baseY + 50));
|
||||
addButton(new GuiNpcButton(13, guiLeft + 215, baseY + 43,
|
||||
new String[]{"filter.any", "filter.all", "filter.notany", "filter.notall"}, filterCondition));
|
||||
|
||||
addButton(new GuiNpcButton(11, guiLeft + 150, baseY + 66, 130, 20, "gui.deselectAll"));
|
||||
|
||||
addLabel(new GuiNpcLabel(4, StatCollector.translateToLocal("cloner.order"),
|
||||
guiLeft + 150, baseY + 112));
|
||||
addButton(new GuiNpcButton(14, guiLeft + 215, baseY + 105,
|
||||
new String[]{"cloner.ascending", "cloner.descending"}, ascending));
|
||||
|
||||
addLabel(new GuiNpcLabel(5, StatCollector.translateToLocal("cloner.type"),
|
||||
guiLeft + 150, baseY + 135));
|
||||
addButton(new GuiNpcButton(15, guiLeft + 215, baseY + 128,
|
||||
new String[]{"cloner.name", "cloner.date"}, sortType));
|
||||
|
||||
getButton(12).width = 65;
|
||||
getButton(12).height = 20;
|
||||
getButton(13).width = 65;
|
||||
getButton(13).height = 20;
|
||||
getButton(14).width = 65;
|
||||
getButton(14).height = 20;
|
||||
getButton(15).width = 65;
|
||||
getButton(15).height = 20;
|
||||
|
||||
filterScroll.setList(getTagList());
|
||||
}
|
||||
|
||||
private void showEntities() {
|
||||
Map<?, ?> data = EntityList.stringToClassMapping;
|
||||
ArrayList<String> list = new ArrayList<String>();
|
||||
for (Object name : data.keySet()) {
|
||||
Class<?> c = (Class<?>) data.get(name);
|
||||
try {
|
||||
if (EntityLiving.class.isAssignableFrom(c) && c.getConstructor(new Class[]{World.class}) != null && !Modifier.isAbstract(c.getModifiers()))
|
||||
list.add(name.toString());
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
}
|
||||
}
|
||||
this.list = list;
|
||||
this.rawList = new ArrayList<String>(this.list);
|
||||
scroll.setList(getSearchList(), ascending == 0, sortType == 0);
|
||||
}
|
||||
|
||||
// ==================== CLONE / ENTITY DISPLAY ====================
|
||||
private void showClones() {
|
||||
if (showingClones == 2) {
|
||||
PacketClient.sendClient(new CloneTagListPacket(activeTab));
|
||||
@@ -219,16 +276,41 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData {
|
||||
}
|
||||
|
||||
this.tagMap = ClientTagMapController.Instance.getTagMap(activeTab);
|
||||
populateRawListWithTags();
|
||||
scroll.setList(getSearchList(), ascending == 0, sortType == 0);
|
||||
}
|
||||
|
||||
private void showEntities() {
|
||||
Map<?, ?> data = EntityList.stringToClassMapping;
|
||||
ArrayList<String> list = new ArrayList<String>();
|
||||
for (Object name : data.keySet()) {
|
||||
Class<?> c = (Class<?>) data.get(name);
|
||||
try {
|
||||
if (EntityLiving.class.isAssignableFrom(c)
|
||||
&& c.getConstructor(new Class[]{World.class}) != null
|
||||
&& !Modifier.isAbstract(c.getModifiers()))
|
||||
list.add(name.toString());
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
}
|
||||
}
|
||||
this.list = list;
|
||||
this.rawList = new ArrayList<String>(this.list);
|
||||
scroll.setList(getSearchList(), ascending == 0, sortType == 0);
|
||||
}
|
||||
|
||||
private void populateRawListWithTags() {
|
||||
this.rawList = new ArrayList<>(this.list);
|
||||
if (this.tagMap != null) {
|
||||
if (GuiNpcMobSpawner.displayTags == 0 || GuiNpcMobSpawner.displayTags == 1) {
|
||||
if (displayTags == 0 || displayTags == 1) {
|
||||
for (int i = 0; i < this.list.size(); i++) {
|
||||
StringBuilder npcName = new StringBuilder(list.get(i));
|
||||
if (this.tagMap.hasClone(list.get(i))) {
|
||||
for (UUID tagUUID : this.tagMap.getUUIDsList(list.get(i))) {
|
||||
Tag tag = tags.get(tagUUID);
|
||||
if (tag != null) {
|
||||
if (GuiNpcMobSpawner.displayTags == 1 || !tag.getIsHidden()) {
|
||||
if (displayTags == 1 || !tag.getIsHidden()) {
|
||||
npcName.append(" [" + tag.name + "]");
|
||||
}
|
||||
}
|
||||
@@ -238,27 +320,26 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scroll.setList(getSearchList(), ascending == 0, sortType == 0);
|
||||
}
|
||||
|
||||
public void keyTyped(char c, int i) {
|
||||
super.keyTyped(c, i);
|
||||
if (getTextField(1) != null) {
|
||||
if (search.equals(getTextField(1).getText()))
|
||||
return;
|
||||
search = getTextField(1).getText().toLowerCase();
|
||||
scroll.setList(getSearchList(), ascending == 0, sortType == 0);
|
||||
}
|
||||
if (getTextField(2) != null) {
|
||||
if (tagSearch.equals(getTextField(2).getText()))
|
||||
return;
|
||||
tagSearch = getTextField(2).getText().toLowerCase();
|
||||
filterScroll.setList(getTagList());
|
||||
}
|
||||
private NBTTagCompound getCompound() {
|
||||
String sel = scroll.getSelected();
|
||||
if (sel == null)
|
||||
return null;
|
||||
|
||||
if (showingClones == 0) {
|
||||
return ClientCloneController.Instance.getCloneData(player, sel, activeTab);
|
||||
} else {
|
||||
Entity entity = EntityList.createEntityByName(sel, Minecraft.getMinecraft().theWorld);
|
||||
if (entity == null)
|
||||
return null;
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
entity.writeToNBTOptional(compound);
|
||||
return compound;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== SEARCH / FILTER ====================
|
||||
private List<String> getSearchList() {
|
||||
if (this.list == null) {
|
||||
this.list = new ArrayList<String>();
|
||||
@@ -269,10 +350,8 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData {
|
||||
|
||||
// No Filters - or - Entities
|
||||
if (tagFilters.size() == 0 || showingClones == 1) {
|
||||
// No Search
|
||||
if (search.isEmpty())
|
||||
return new ArrayList<String>(this.list);
|
||||
// Yes Search
|
||||
else {
|
||||
List<String> list = new ArrayList<String>();
|
||||
for (int i = 0; i < this.list.size(); i++) {
|
||||
@@ -284,10 +363,7 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
//// WITH FILTERS
|
||||
|
||||
// No Search
|
||||
// With Filters
|
||||
if (search.isEmpty()) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
for (String name : this.list) {
|
||||
@@ -300,7 +376,6 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData {
|
||||
return list;
|
||||
}
|
||||
|
||||
// Yes Search
|
||||
List<String> list = new ArrayList<String>();
|
||||
for (int i = 0; i < this.list.size(); i++) {
|
||||
if (this.rawList.get(i).toLowerCase().contains(search)) {
|
||||
@@ -311,7 +386,6 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return list;
|
||||
}
|
||||
@@ -346,7 +420,6 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return conditionMet;
|
||||
}
|
||||
|
||||
@@ -354,10 +427,8 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData {
|
||||
if (this.tagList == null) {
|
||||
this.tagList = new ArrayList<String>();
|
||||
}
|
||||
// No Search // No Filters - or - Entities
|
||||
if (tagSearch.isEmpty())
|
||||
return new ArrayList<String>(tagNames.keySet());
|
||||
// Yes Search // No Filters - or - Entities
|
||||
|
||||
List<String> list = new ArrayList<String>();
|
||||
for (String name : this.tagList) {
|
||||
@@ -367,125 +438,162 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData {
|
||||
return list;
|
||||
}
|
||||
|
||||
private NBTTagCompound getCompound() {
|
||||
String sel = scroll.getSelected();
|
||||
if (sel == null)
|
||||
return null;
|
||||
|
||||
if (showingClones == 0) {
|
||||
return ClientCloneController.Instance.getCloneData(player, sel, activeTab);
|
||||
} else {
|
||||
Entity entity = EntityList.createEntityByName(sel, Minecraft.getMinecraft().theWorld);
|
||||
if (entity == null)
|
||||
return null;
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
entity.writeToNBTOptional(compound);
|
||||
return compound;
|
||||
}
|
||||
// ==================== MOUSE / KEYBOARD EVENTS ====================
|
||||
@Override
|
||||
public void customScrollClicked(int i, int j, int k, GuiCustomScroll guiCustomScroll) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customScrollDoubleClicked(String selection, GuiCustomScroll guiCustomScroll) {
|
||||
}
|
||||
|
||||
public void keyTyped(char c, int i) {
|
||||
super.keyTyped(c, i);
|
||||
|
||||
GuiNpcTextField searchField = getTextField(1);
|
||||
if (searchField != null) {
|
||||
String newText = searchField.getText().toLowerCase();
|
||||
if (!search.equals(newText)) {
|
||||
search = newText;
|
||||
scroll.setList(getSearchList(), ascending == 0, sortType == 0);
|
||||
}
|
||||
}
|
||||
|
||||
GuiNpcTextField tagSearchField = getTextField(2);
|
||||
if (tagSearchField != null) {
|
||||
String newText = tagSearchField.getText().toLowerCase();
|
||||
if (!tagSearch.equals(newText)) {
|
||||
tagSearch = newText;
|
||||
filterScroll.setList(getTagList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== BUTTON ACTIONS ====================
|
||||
@Override
|
||||
protected void actionPerformed(GuiButton guibutton) {
|
||||
int id = guibutton.id;
|
||||
if (id == 0) {
|
||||
close();
|
||||
}
|
||||
if (id == 1) {
|
||||
if (showingClones == 2) {
|
||||
String sel = scroll.getSelected();
|
||||
if (sel == null)
|
||||
return;
|
||||
SpawnMobPacket.Server(posX, posY, posZ, sel, activeTab);
|
||||
close();
|
||||
} else {
|
||||
NBTTagCompound compound = getCompound();
|
||||
if (compound == null)
|
||||
return;
|
||||
SpawnMobPacket.Client(posX, posY, posZ, compound);
|
||||
close();
|
||||
}
|
||||
}
|
||||
if (id == 2) {
|
||||
if (showingClones == 2) {
|
||||
String sel = scroll.getSelected();
|
||||
if (sel == null)
|
||||
return;
|
||||
MobSpawnerPacket.Server(posX, posY, posZ, sel, activeTab);
|
||||
close();
|
||||
} else {
|
||||
NBTTagCompound compound = getCompound();
|
||||
if (compound == null)
|
||||
return;
|
||||
MobSpawnerPacket.Client(posX, posY, posZ, compound);
|
||||
close();
|
||||
|
||||
}
|
||||
// Tab side buttons (IDs 21-35)
|
||||
if (id >= 21 && id <= 35) {
|
||||
activeTab = id - 20;
|
||||
activeFolder = null;
|
||||
initGui();
|
||||
return;
|
||||
}
|
||||
|
||||
// Mode buttons
|
||||
if (id == 3) {
|
||||
savedContentScrollY = 0;
|
||||
showingClones = 0;
|
||||
initGui();
|
||||
}
|
||||
if (id == 4) {
|
||||
savedContentScrollY = 0;
|
||||
showingClones = 1;
|
||||
initGui();
|
||||
}
|
||||
if (id == 5) {
|
||||
savedContentScrollY = 0;
|
||||
showingClones = 2;
|
||||
PacketClient.sendClient(new CloneFolderListPacket());
|
||||
initGui();
|
||||
}
|
||||
if (id == 16) {
|
||||
savedContentScrollY = 0;
|
||||
showingClones = 3;
|
||||
initGui();
|
||||
}
|
||||
if (id == 17) {
|
||||
close();
|
||||
}
|
||||
|
||||
// Open fullscreen GUI
|
||||
if (id == 61) {
|
||||
isFullscreen = true;
|
||||
Minecraft.getMinecraft().displayGuiScreen(
|
||||
new GuiNpcMobSpawnerFullscreen(posX, posY, posZ));
|
||||
}
|
||||
|
||||
// Spawn
|
||||
if (id == 1) {
|
||||
if (showingClones == 2) {
|
||||
String sel = scroll.getSelected();
|
||||
if (sel == null) return;
|
||||
SpawnMobPacket.Server(posX, posY, posZ, sel, activeTab);
|
||||
close();
|
||||
} else {
|
||||
NBTTagCompound compound = getCompound();
|
||||
if (compound == null) return;
|
||||
SpawnMobPacket.Client(posX, posY, posZ, compound);
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
// Mob Spawner
|
||||
if (id == 2) {
|
||||
if (showingClones == 2) {
|
||||
String sel = scroll.getSelected();
|
||||
if (sel == null) return;
|
||||
MobSpawnerPacket.Server(posX, posY, posZ, sel, activeTab);
|
||||
close();
|
||||
} else {
|
||||
NBTTagCompound compound = getCompound();
|
||||
if (compound == null) return;
|
||||
MobSpawnerPacket.Client(posX, posY, posZ, compound);
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
// Remove
|
||||
if (id == 6) {
|
||||
if (scroll.getSelected() != null) {
|
||||
int prevSelected = scroll.selected;
|
||||
if (showingClones == 2) {
|
||||
PacketClient.sendClient(new CloneRemovePacket(activeTab, scroll.getSelected()));
|
||||
return;
|
||||
}
|
||||
ClientCloneController.Instance.removeClone(scroll.getSelected(), activeTab);
|
||||
scroll.selected = -1;
|
||||
initGui();
|
||||
if (scroll.list != null && !scroll.list.isEmpty()) {
|
||||
scroll.selected = Math.min(prevSelected, scroll.list.size() - 1);
|
||||
} else {
|
||||
scroll.selected = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter controls
|
||||
if (id == 11) {
|
||||
tagFilters = new HashSet<>();
|
||||
filterScroll.setSelectedList(tagFilters);
|
||||
initGui();
|
||||
}
|
||||
if (id == 12) {
|
||||
GuiNpcButton button = (GuiNpcButton) guibutton;
|
||||
displayTags = (byte) button.getValue();
|
||||
displayTags = (byte) ((GuiNpcButton) guibutton).getValue();
|
||||
}
|
||||
if (id == 13) {
|
||||
GuiNpcButton button = (GuiNpcButton) guibutton;
|
||||
filterCondition = (byte) button.getValue();
|
||||
filterCondition = (byte) ((GuiNpcButton) guibutton).getValue();
|
||||
}
|
||||
if (id == 14) {
|
||||
GuiNpcButton button = (GuiNpcButton) guibutton;
|
||||
ascending = (byte) button.getValue();
|
||||
ascending = (byte) ((GuiNpcButton) guibutton).getValue();
|
||||
}
|
||||
if (id == 15) {
|
||||
GuiNpcButton button = (GuiNpcButton) guibutton;
|
||||
sortType = (byte) button.getValue();
|
||||
}
|
||||
if (id > 20) {
|
||||
activeTab = id - 20;
|
||||
initGui();
|
||||
sortType = (byte) ((GuiNpcButton) guibutton).getValue();
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== DATA FROM SERVER ====================
|
||||
@Override
|
||||
public void save() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGuiData(NBTTagCompound compound) {
|
||||
if (compound.hasKey("CloneTags")) {
|
||||
if (compound.hasKey("CloneFolders")) {
|
||||
// Minimized doesn't use folders, but still handle the packet
|
||||
initGui();
|
||||
} else if (compound.hasKey("CloneTags")) {
|
||||
this.tagMap = new TagMap(activeTab);
|
||||
NBTTagCompound cloneTags = compound.getCompoundTag("CloneTags");
|
||||
this.tagMap.readNBT(cloneTags);
|
||||
@@ -521,29 +629,8 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData {
|
||||
}
|
||||
|
||||
this.list = list;
|
||||
|
||||
this.rawList = new ArrayList<String>(this.list);
|
||||
if (this.tagMap != null) {
|
||||
if (GuiNpcMobSpawner.displayTags == 0 || GuiNpcMobSpawner.displayTags == 1) {
|
||||
for (int i = 0; i < this.list.size(); i++) {
|
||||
StringBuilder npcName = new StringBuilder(list.get(i));
|
||||
if (this.tagMap.hasClone(list.get(i))) {
|
||||
for (UUID tagUUID : this.tagMap.getUUIDsList(list.get(i))) {
|
||||
Tag tag = tags.get(tagUUID);
|
||||
if (tag != null) {
|
||||
if (GuiNpcMobSpawner.displayTags == 1 || !tag.getIsHidden()) {
|
||||
npcName.append(" [" + tag.name + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.rawList.set(i, npcName.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
populateRawListWithTags();
|
||||
scroll.setList(getSearchList(), ascending == 0, sortType == 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package noppes.npcs.client.gui;
|
||||
|
||||
import kamkeel.npcs.network.PacketClient;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneAllTagsShortPacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneFolderListPacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.ClonePreSavePacket;
|
||||
import kamkeel.npcs.network.packets.request.clone.CloneSavePacket;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -22,12 +23,14 @@ import noppes.npcs.client.gui.util.GuiNpcTextField;
|
||||
import noppes.npcs.client.gui.util.IGuiData;
|
||||
import noppes.npcs.client.gui.util.ISubGuiListener;
|
||||
import noppes.npcs.client.gui.util.SubGuiInterface;
|
||||
import noppes.npcs.controllers.data.CloneFolder;
|
||||
import noppes.npcs.controllers.data.Tag;
|
||||
import noppes.npcs.entity.EntityNPCInterface;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCallback, IGuiData, ISubGuiListener {
|
||||
@@ -35,9 +38,16 @@ public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCall
|
||||
private Entity toClone;
|
||||
private NBTTagCompound compound;
|
||||
private static boolean serverSide = false;
|
||||
private static int saveMode = 0; // 0=Tab, 1=Folder
|
||||
private static int tab = 1;
|
||||
private static String folder = null;
|
||||
public boolean isNPC = false;
|
||||
|
||||
// Client-side folder names
|
||||
private ArrayList<String> clientFolderNames = new ArrayList<>();
|
||||
// Server-side folder names (populated via CloneFolderListPacket)
|
||||
private static ArrayList<String> serverFolderNames = new ArrayList<>();
|
||||
|
||||
// Selected Tags to Add
|
||||
public static NBTTagList tagsCompound;
|
||||
public static HashSet<String> addTags;
|
||||
@@ -68,6 +78,37 @@ public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCall
|
||||
if (isNPC) {
|
||||
PacketClient.sendClient(new CloneAllTagsShortPacket());
|
||||
}
|
||||
|
||||
buildClientFolderNames();
|
||||
|
||||
// Request server folders if in server mode
|
||||
if (serverSide) {
|
||||
PacketClient.sendClient(new CloneFolderListPacket());
|
||||
}
|
||||
|
||||
// Validate saved folder selection
|
||||
validateFolder();
|
||||
}
|
||||
|
||||
private void buildClientFolderNames() {
|
||||
clientFolderNames.clear();
|
||||
if (ClientCloneController.Instance != null) {
|
||||
for (CloneFolder f : ClientCloneController.Instance.getFolderList()) {
|
||||
clientFolderNames.add(f.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getActiveFolderList() {
|
||||
return serverSide ? serverFolderNames : clientFolderNames;
|
||||
}
|
||||
|
||||
private void validateFolder() {
|
||||
if (saveMode == 1 && folder != null) {
|
||||
if (!getActiveFolderList().contains(folder)) {
|
||||
folder = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,61 +118,138 @@ public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCall
|
||||
addLabel(new GuiNpcLabel(0, "Save as", guiLeft + 4, guiTop + 6));
|
||||
addTextField(new GuiNpcTextField(0, this, fontRendererObj, guiLeft + 4, guiTop + 18, 200, 20, name));
|
||||
|
||||
// Tab/Folder toggle
|
||||
addButton(new GuiNpcButton(6, guiLeft + 4, guiTop + 45, 50, 20,
|
||||
new String[]{"Tab", "Folder"}, saveMode));
|
||||
|
||||
addLabel(new GuiNpcLabel(1, "Tab", guiLeft + 10, guiTop + 50));
|
||||
addButton(new GuiButtonBiDirectional(2, guiLeft + 40, guiTop + 45, 60, 20, new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"}, tab - 1));
|
||||
// Destination selector based on saveMode
|
||||
if (saveMode == 0) {
|
||||
// Tab selector: 1-15
|
||||
String[] tabLabels = new String[15];
|
||||
for (int i = 0; i < 15; i++) tabLabels[i] = String.valueOf(i + 1);
|
||||
int selectedTab = (tab >= 1 && tab <= 15) ? tab - 1 : 0;
|
||||
addButton(new GuiButtonBiDirectional(2, guiLeft + 56, guiTop + 45, 90, 20, tabLabels, selectedTab));
|
||||
} else {
|
||||
// Folder selector button — opens SubGuiFolderSelect
|
||||
String btnText = folder != null ? folder : "Select a Folder";
|
||||
addButton(new GuiNpcButton(2, guiLeft + 56, guiTop + 45, 148, 20, btnText));
|
||||
}
|
||||
|
||||
addButton(new GuiNpcButton(3, guiLeft + 4, guiTop + 95, new String[]{"Client side", "Server side"}, serverSide ? 1 : 0));
|
||||
addLabel(new GuiNpcLabel(1, "Tab", guiLeft + 10, guiTop + 50));
|
||||
|
||||
addButton(new GuiNpcButton(0, guiLeft + 4, guiTop + 70, 80, 20, "gui.save"));
|
||||
// Save / Cancel
|
||||
GuiNpcButton saveBtn = new GuiNpcButton(0, guiLeft + 4, guiTop + 70, 80, 20, "gui.save");
|
||||
if (saveMode == 1 && folder == null) {
|
||||
saveBtn.enabled = false;
|
||||
}
|
||||
addButton(saveBtn);
|
||||
addButton(new GuiNpcButton(1, guiLeft + 86, guiTop + 70, 80, 20, "gui.cancel"));
|
||||
|
||||
// Client / Server toggle
|
||||
addButton(new GuiNpcButton(3, guiLeft + 4, guiTop + 95, new String[]{"Client side", "Server side"}, serverSide ? 1 : 0));
|
||||
|
||||
if (isNPC) {
|
||||
addButton(new GuiNpcButton(4, guiLeft + 4, guiTop + 120, 99, 20, "cloner.wandTags"));
|
||||
addButton(new GuiNpcButton(5, guiLeft + 106, guiTop + 120, 99, 20, "cloner.npcTags"));
|
||||
if (addTags.size() > 0) {
|
||||
addLabel(new GuiNpcLabel(6, "cloner.wandtagsapplied", guiLeft + 10, guiTop + 160));
|
||||
addLabel(new GuiNpcLabel(8, "cloner.wandtagsapplied", guiLeft + 10, guiTop + 160));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDestinationFromSelector() {
|
||||
if (saveMode == 0) {
|
||||
GuiNpcButton selector = getButton(2);
|
||||
if (selector == null) return;
|
||||
tab = selector.getValue() + 1;
|
||||
folder = null;
|
||||
}
|
||||
// In folder mode, folder is already set via SubGuiFolderSelect
|
||||
}
|
||||
|
||||
public void buttonEvent(GuiButton guibutton) {
|
||||
int id = guibutton.id;
|
||||
|
||||
// Save
|
||||
if (id == 0) {
|
||||
updateDestinationFromSelector();
|
||||
String name = getTextField(0).getText();
|
||||
if (name.isEmpty())
|
||||
return;
|
||||
int tab = ((GuiNpcButton) guibutton).getValue() + 1;
|
||||
|
||||
if (saveMode == 1 && folder == null)
|
||||
return;
|
||||
|
||||
if (!serverSide) {
|
||||
if (ClientCloneController.Instance.getCloneData(null, name, tab) != null)
|
||||
boolean exists;
|
||||
if (saveMode == 1 && folder != null && ClientCloneController.Instance != null) {
|
||||
exists = ClientCloneController.Instance.getCloneData(null, name, folder) != null;
|
||||
} else {
|
||||
exists = ClientCloneController.Instance.getCloneData(null, name, tab) != null;
|
||||
}
|
||||
if (exists)
|
||||
displayGuiScreen(new GuiYesNo(this, "Warning", "You are about to overwrite a clone", 1));
|
||||
else
|
||||
confirmClicked(true, 0);
|
||||
} else
|
||||
PacketClient.sendClient(new ClonePreSavePacket(name, tab));
|
||||
} else {
|
||||
if (saveMode == 1 && folder != null) {
|
||||
PacketClient.sendClient(new ClonePreSavePacket(name, folder));
|
||||
} else {
|
||||
PacketClient.sendClient(new ClonePreSavePacket(name, tab));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel
|
||||
if (id == 1) {
|
||||
close();
|
||||
}
|
||||
|
||||
// Destination selector
|
||||
if (id == 2) {
|
||||
tab = ((GuiNpcButton) guibutton).getValue() + 1;
|
||||
if (saveMode == 0) {
|
||||
// Tab mode — update from BiDirectional
|
||||
updateDestinationFromSelector();
|
||||
} else {
|
||||
// Folder mode — open folder selector Sub GUI
|
||||
List<String> folders = getActiveFolderList();
|
||||
setSubGui(new SubGuiFolderSelect(folders, folder));
|
||||
}
|
||||
}
|
||||
|
||||
// Client / Server toggle
|
||||
if (id == 3) {
|
||||
boolean wasServerSide = serverSide;
|
||||
serverSide = ((GuiNpcButton) guibutton).getValue() == 1;
|
||||
|
||||
if (serverSide && !wasServerSide) {
|
||||
// Switching to server mode — request fresh folder list
|
||||
PacketClient.sendClient(new CloneFolderListPacket());
|
||||
}
|
||||
|
||||
// Validate folder exists on the new side
|
||||
validateFolder();
|
||||
initGui();
|
||||
}
|
||||
|
||||
// Wand Tags
|
||||
if (id == 4) {
|
||||
if (isNPC) {
|
||||
this.setSubGui(new SubGuiClonerQuickTags(this));
|
||||
}
|
||||
}
|
||||
|
||||
// NPC Tags
|
||||
if (id == 5) {
|
||||
if (isNPC) {
|
||||
this.setSubGui(new SubGuiClonerNPCTags((EntityNPCInterface) toClone, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tab/Folder mode toggle
|
||||
if (id == 6) {
|
||||
saveMode = ((GuiNpcButton) guibutton).getValue();
|
||||
initGui();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void confirmClicked(boolean confirm, int id) {
|
||||
@@ -145,13 +263,21 @@ public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCall
|
||||
if (isNPC) {
|
||||
compound.setTag("TagUUIDs", tagsCompound);
|
||||
}
|
||||
ClientCloneController.Instance.addClone(compound, name, tab, extraTags);
|
||||
if (saveMode == 1 && folder != null && ClientCloneController.Instance != null) {
|
||||
ClientCloneController.Instance.addClone(compound, name, folder, extraTags);
|
||||
} else {
|
||||
ClientCloneController.Instance.addClone(compound, name, tab, extraTags);
|
||||
}
|
||||
} else {
|
||||
NBTTagCompound compounder = new NBTTagCompound();
|
||||
if (isNPC) {
|
||||
compounder.setTag("TagUUIDs", tagsCompound);
|
||||
}
|
||||
PacketClient.sendClient(new CloneSavePacket(name, tab, extraTags, compounder));
|
||||
if (saveMode == 1 && folder != null) {
|
||||
PacketClient.sendClient(new CloneSavePacket(name, folder, extraTags, compounder));
|
||||
} else {
|
||||
PacketClient.sendClient(new CloneSavePacket(name, tab, extraTags, compounder));
|
||||
}
|
||||
}
|
||||
|
||||
close();
|
||||
@@ -159,7 +285,6 @@ public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCall
|
||||
displayGuiScreen(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
}
|
||||
@@ -171,6 +296,17 @@ public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCall
|
||||
displayGuiScreen(new GuiYesNo(this, "Warning", "You are about to overwrite a clone", 1));
|
||||
else
|
||||
confirmClicked(true, 0);
|
||||
} else if (compound.hasKey("CloneFolders")) {
|
||||
// Server folder list arrived
|
||||
NBTTagList folderList = compound.getTagList("CloneFolders", 10);
|
||||
serverFolderNames.clear();
|
||||
for (int i = 0; i < folderList.tagCount(); i++) {
|
||||
CloneFolder f = new CloneFolder();
|
||||
f.readNBT(folderList.getCompoundTagAt(i));
|
||||
serverFolderNames.add(f.name);
|
||||
}
|
||||
validateFolder();
|
||||
initGui();
|
||||
} else if (compound.hasKey("ShortTags")) {
|
||||
NBTTagList validTags = compound.getTagList("ShortTags", 10);
|
||||
tagMap.clear();
|
||||
@@ -193,6 +329,12 @@ public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCall
|
||||
|
||||
@Override
|
||||
public void subGuiClosed(SubGuiInterface subgui) {
|
||||
if (subgui instanceof SubGuiFolderSelect) {
|
||||
SubGuiFolderSelect sel = (SubGuiFolderSelect) subgui;
|
||||
if (sel.selectedFolder != null) {
|
||||
folder = sel.selectedFolder;
|
||||
}
|
||||
}
|
||||
initGui();
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,67 @@
|
||||
package noppes.npcs.client.gui;
|
||||
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import noppes.npcs.client.gui.util.GuiNpcButton;
|
||||
import noppes.npcs.client.gui.util.GuiNpcLabel;
|
||||
import noppes.npcs.client.gui.util.GuiNpcTextField;
|
||||
import noppes.npcs.client.gui.util.SubGuiInterface;
|
||||
import noppes.npcs.controllers.data.CloneFolder;
|
||||
|
||||
public class SubGuiCloneFolderName extends SubGuiInterface {
|
||||
private String originalName;
|
||||
public boolean cancelled = true;
|
||||
private String folderName = "";
|
||||
|
||||
public SubGuiCloneFolderName(String existingName) {
|
||||
this.originalName = existingName;
|
||||
this.folderName = existingName;
|
||||
xSize = 200;
|
||||
ySize = 80;
|
||||
this.closeOnEsc = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
super.initGui();
|
||||
|
||||
String title = isRename() ? "Rename Folder" : "New Folder";
|
||||
addLabel(new GuiNpcLabel(0, title, guiLeft + 5, guiTop + 5));
|
||||
addTextField(new GuiNpcTextField(0, this, fontRendererObj, guiLeft + 5, guiTop + 20, 190, 20, folderName));
|
||||
|
||||
addButton(new GuiNpcButton(0, guiLeft + 5, guiTop + 50, 90, 20, "gui.done"));
|
||||
addButton(new GuiNpcButton(1, guiLeft + 100, guiTop + 50, 90, 20, "gui.cancel"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(GuiButton guibutton) {
|
||||
if (guibutton.id == 0) {
|
||||
// Done
|
||||
folderName = getTextField(0).getText().trim();
|
||||
if (CloneFolder.isValidName(folderName)) {
|
||||
cancelled = false;
|
||||
close();
|
||||
}
|
||||
}
|
||||
if (guibutton.id == 1) {
|
||||
// Cancel
|
||||
cancelled = true;
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRename() {
|
||||
return originalName != null && !originalName.isEmpty();
|
||||
}
|
||||
|
||||
public String getFolderName() {
|
||||
return folderName;
|
||||
}
|
||||
|
||||
public String getOriginalName() {
|
||||
return originalName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package noppes.npcs.client.gui;
|
||||
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import noppes.npcs.client.gui.util.GuiCustomScroll;
|
||||
import noppes.npcs.client.gui.util.GuiNpcButton;
|
||||
import noppes.npcs.client.gui.util.ICustomScrollListener;
|
||||
import noppes.npcs.client.gui.util.SubGuiInterface;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SubGuiFolderSelect extends SubGuiInterface implements ICustomScrollListener {
|
||||
|
||||
public String selectedFolder;
|
||||
private final List<String> folderList;
|
||||
private GuiCustomScroll folderScroll;
|
||||
|
||||
public SubGuiFolderSelect(List<String> folders, String currentSelection) {
|
||||
this.folderList = new ArrayList<>(folders);
|
||||
this.selectedFolder = currentSelection;
|
||||
setBackground("menubg.png");
|
||||
xSize = 200;
|
||||
ySize = 220;
|
||||
closeOnEsc = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
super.initGui();
|
||||
|
||||
folderScroll = new GuiCustomScroll(this, 0);
|
||||
folderScroll.setSize(xSize - 8, ySize - 50);
|
||||
folderScroll.guiLeft = guiLeft + 4;
|
||||
folderScroll.guiTop = guiTop + 4;
|
||||
folderScroll.setList(new ArrayList<>(folderList));
|
||||
if (selectedFolder != null) {
|
||||
folderScroll.setSelected(selectedFolder);
|
||||
}
|
||||
addScroll(folderScroll);
|
||||
|
||||
int btnW = (xSize - 12) / 2;
|
||||
addButton(new GuiNpcButton(0, guiLeft + 4, guiTop + ySize - 44, btnW, 20, "gui.done"));
|
||||
addButton(new GuiNpcButton(1, guiLeft + 4 + btnW + 4, guiTop + ySize - 44, btnW, 20, "gui.cancel"));
|
||||
|
||||
getButton(0).enabled = folderScroll.hasSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customScrollClicked(int i, int j, int k, GuiCustomScroll guiCustomScroll) {
|
||||
getButton(0).enabled = folderScroll.hasSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customScrollDoubleClicked(String selection, GuiCustomScroll guiCustomScroll) {
|
||||
selectedFolder = selection;
|
||||
close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(GuiButton guibutton) {
|
||||
if (guibutton.id == 0) {
|
||||
selectedFolder = folderScroll.getSelected();
|
||||
close();
|
||||
}
|
||||
if (guibutton.id == 1) {
|
||||
selectedFolder = null;
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package noppes.npcs.client.gui;
|
||||
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import noppes.npcs.client.gui.util.GuiNpcButton;
|
||||
import noppes.npcs.client.gui.util.GuiNpcLabel;
|
||||
import noppes.npcs.client.gui.util.SubGuiInterface;
|
||||
|
||||
public class SubGuiMoveConfirm extends SubGuiInterface {
|
||||
public boolean confirmed = false;
|
||||
|
||||
private final int count;
|
||||
public final int destTab;
|
||||
public final String destFolder;
|
||||
|
||||
public SubGuiMoveConfirm(int count, int destTab, String destFolder) {
|
||||
this.count = count;
|
||||
this.destTab = destTab;
|
||||
this.destFolder = destFolder;
|
||||
xSize = 220;
|
||||
ySize = 90;
|
||||
closeOnEsc = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
super.initGui();
|
||||
|
||||
String line1 = "Move " + count + " clone" + (count != 1 ? "s" : "") + " to:";
|
||||
addLabel(new GuiNpcLabel(0, line1, guiLeft + 10, guiTop + 10, 0xFFFFFF));
|
||||
|
||||
String dest;
|
||||
if (destFolder != null) {
|
||||
dest = "Folder: \"" + destFolder + "\"";
|
||||
} else {
|
||||
dest = "Tab: " + destTab;
|
||||
}
|
||||
addLabel(new GuiNpcLabel(1, " " + dest, guiLeft + 10, guiTop + 25, 0xFFFFFF));
|
||||
|
||||
addButton(new GuiNpcButton(0, guiLeft + 10, guiTop + 55, 95, 20, "gui.yes"));
|
||||
addButton(new GuiNpcButton(1, guiLeft + 115, guiTop + 55, 95, 20, "gui.cancel"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(GuiButton guibutton) {
|
||||
if (guibutton.id == 0) {
|
||||
confirmed = true;
|
||||
close();
|
||||
}
|
||||
if (guibutton.id == 1) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
}
|
||||
}
|
||||
@@ -367,6 +367,13 @@ public class GuiCustomScroll extends GuiScreen {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setSelectable(boolean selectable) {
|
||||
this.selectable = selectable;
|
||||
if (!selectable) {
|
||||
hover = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isMouseOver(int x, int y) {
|
||||
return x >= this.guiLeft && x <= this.guiLeft + this.xSize && y >= this.guiTop && y <= this.guiTop + this.ySize;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package noppes.npcs.client.gui.util;
|
||||
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import noppes.npcs.client.gui.GuiNpcMobSpawner;
|
||||
import noppes.npcs.controllers.data.Tag;
|
||||
@@ -7,10 +8,10 @@ import noppes.npcs.controllers.data.Tag;
|
||||
import java.util.UUID;
|
||||
|
||||
public class GuiCustomScrollCloner extends GuiCustomScroll {
|
||||
private final GuiNpcMobSpawner parent;
|
||||
private final IClonerGui parent;
|
||||
|
||||
public GuiCustomScrollCloner(GuiNpcMobSpawner parent, int id) {
|
||||
super(parent, id);
|
||||
public GuiCustomScrollCloner(IClonerGui parent, int id) {
|
||||
super((GuiScreen) parent, id);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@@ -38,24 +39,25 @@ public class GuiCustomScrollCloner extends GuiCustomScroll {
|
||||
text += "...";
|
||||
} else
|
||||
text = displayString;
|
||||
if ((multipleSelection && selectedList.contains(text)) || (!multipleSelection && selected == i)) {
|
||||
int itemColor = this.colors.getOrDefault(list.get(i), 0xffffff);
|
||||
if ((multipleSelection && selectedList.contains(list.get(i))) || (!multipleSelection && selected == i)) {
|
||||
drawVerticalLine(j - 2, k - 4, k + 10, 0xffffffff);
|
||||
drawVerticalLine(j + xSize - 18 + xOffset, k - 4, k + 10, 0xffffffff);
|
||||
drawHorizontalLine(j - 2, j + xSize - 18 + xOffset, k - 3, 0xffffffff);
|
||||
drawHorizontalLine(j - 2, j + xSize - 18 + xOffset, k + 10, 0xffffffff);
|
||||
fontRendererObj.drawString(text, j, k, this.colors.getOrDefault(text, 0xffffff));
|
||||
fontRendererObj.drawString(text, j, k, itemColor);
|
||||
} else if (i == hover) {
|
||||
fontRendererObj.drawString(text, j, k, 0x00ff00);
|
||||
} else {
|
||||
fontRendererObj.drawString(text, j, k, this.colors.getOrDefault(text, 0xffffff));
|
||||
fontRendererObj.drawString(text, j, k, itemColor);
|
||||
}
|
||||
|
||||
if ((this.parent.getShowingClones() == 0 || this.parent.getShowingClones() == 2) && this.parent.tagMap != null) {
|
||||
if ((parent.getShowingClones() == 0 || parent.getShowingClones() == 2) && parent.getTagMap() != null) {
|
||||
int tagStartX = j + fontRendererObj.getStringWidth(displayString) + 3;
|
||||
if (GuiNpcMobSpawner.displayTags == 0 || GuiNpcMobSpawner.displayTags == 1) {
|
||||
if (this.parent.tagMap.hasClone(list.get(i))) {
|
||||
for (UUID tagUUID : this.parent.tagMap.getUUIDsList(list.get(i))) {
|
||||
Tag tag = this.parent.tags.get(tagUUID);
|
||||
if (parent.getTagMap().hasClone(list.get(i))) {
|
||||
for (UUID tagUUID : parent.getTagMap().getUUIDsList(list.get(i))) {
|
||||
Tag tag = parent.getTags().get(tagUUID);
|
||||
if (tag != null) {
|
||||
if (GuiNpcMobSpawner.displayTags == 1 || !tag.getIsHidden()) {
|
||||
fontRendererObj.drawString("[" + tag.name + "]", tagStartX, k, tag.color);
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
package noppes.npcs.client.gui.util;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GuiCustomScrollIcons extends GuiCustomScroll {
|
||||
public static final int ICON_NONE = 0;
|
||||
public static final int ICON_TAB = 1;
|
||||
public static final int ICON_FOLDER = 2;
|
||||
|
||||
private static final ResourceLocation TAB_TEXTURE = new ResourceLocation("customnpcs", "textures/gui/cloner/tab.png");
|
||||
private static final ResourceLocation FOLDER_TEXTURE = new ResourceLocation("customnpcs", "textures/gui/cloner/folder.png");
|
||||
|
||||
private static final int ICON_RENDER_SIZE = 10;
|
||||
private static final int ICON_PADDING = 14;
|
||||
|
||||
private List<Integer> iconTypes = new ArrayList<>();
|
||||
|
||||
public GuiCustomScrollIcons(GuiScreen parent, int id) {
|
||||
super(parent, id);
|
||||
}
|
||||
|
||||
public void setListWithIcons(List<String> names, List<Integer> icons) {
|
||||
this.setUnsortedList(names);
|
||||
this.iconTypes = new ArrayList<>(icons);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawItems() {
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
int j = 4;
|
||||
int k = (14 * i + 4) - scrollY;
|
||||
if (k >= 4 && k + 12 < ySize) {
|
||||
int xOffset = scrollHeight < ySize - 8 ? 0 : 10;
|
||||
|
||||
int iconType = (i < iconTypes.size()) ? iconTypes.get(i) : ICON_NONE;
|
||||
int textX = j;
|
||||
if (iconType != ICON_NONE) {
|
||||
textX = j + ICON_PADDING;
|
||||
}
|
||||
|
||||
// Draw icon texture
|
||||
if (iconType == ICON_FOLDER || iconType == ICON_TAB) {
|
||||
ResourceLocation tex = (iconType == ICON_FOLDER) ? FOLDER_TEXTURE : TAB_TEXTURE;
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
mc.getTextureManager().bindTexture(tex);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
drawFullTexture(j, k - 1, ICON_RENDER_SIZE, ICON_RENDER_SIZE);
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
}
|
||||
|
||||
// Draw text
|
||||
String displayString = StatCollector.translateToLocal(list.get(i));
|
||||
String text = "";
|
||||
float maxWidth = (xSize + xOffset - 8 - (iconType != ICON_NONE ? ICON_PADDING : 0)) * 0.8f;
|
||||
if (fontRendererObj.getStringWidth(displayString) > maxWidth) {
|
||||
for (int h = 0; h < displayString.length(); h++) {
|
||||
char c = displayString.charAt(h);
|
||||
text += c;
|
||||
if (fontRendererObj.getStringWidth(text) > maxWidth)
|
||||
break;
|
||||
}
|
||||
if (displayString.length() > text.length())
|
||||
text += "...";
|
||||
} else {
|
||||
text = displayString;
|
||||
}
|
||||
|
||||
int itemColor = this.colors.getOrDefault(list.get(i), 0xffffff);
|
||||
|
||||
if ((multipleSelection && selectedList.contains(list.get(i))) || (!multipleSelection && selected == i)) {
|
||||
drawVerticalLine(j - 2, k - 4, k + 10, 0xffffffff);
|
||||
drawVerticalLine(j + xSize - 18 + xOffset, k - 4, k + 10, 0xffffffff);
|
||||
drawHorizontalLine(j - 2, j + xSize - 18 + xOffset, k - 3, 0xffffffff);
|
||||
drawHorizontalLine(j - 2, j + xSize - 18 + xOffset, k + 10, 0xffffffff);
|
||||
fontRendererObj.drawString(text, textX, k, itemColor);
|
||||
} else if (i == hover) {
|
||||
fontRendererObj.drawString(text, textX, k, 0x00ff00);
|
||||
} else {
|
||||
fontRendererObj.drawString(text, textX, k, itemColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a full texture (UV 0,0 to 1,1) scaled to the given width/height.
|
||||
* Works with any texture size (not just 256x256).
|
||||
*/
|
||||
private void drawFullTexture(int x, int y, int w, int h) {
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.addVertexWithUV(x, y + h, 0, 0, 1);
|
||||
tessellator.addVertexWithUV(x + w, y + h, 0, 1, 1);
|
||||
tessellator.addVertexWithUV(x + w, y, 0, 1, 0);
|
||||
tessellator.addVertexWithUV(x, y, 0, 0, 0);
|
||||
tessellator.draw();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
package noppes.npcs.client.gui.util;
|
||||
|
||||
/**
|
||||
* Abstract base class for fullscreen directory-browsing GUIs.
|
||||
* Provides a configurable three-panel layout (left nav, center content, right actions)
|
||||
* with percentage-based sizing, panel backgrounds/borders, and an optional resizable divider.
|
||||
*
|
||||
* Subclasses override abstract hooks to populate each panel region.
|
||||
* Designed for reuse across Cloner, Quest Manager, Dialog Manager, etc.
|
||||
*/
|
||||
public abstract class GuiDirectory extends GuiNPCInterface implements ICustomScrollListener, ISubGuiListener {
|
||||
|
||||
// ===== LAYOUT CONFIG (subclasses may override in constructor) =====
|
||||
protected float leftPanelPercent = 0.20f;
|
||||
protected float rightPanelPercent = 0.10f;
|
||||
protected int minLeftPanelW = 80;
|
||||
protected int minRightPanelW = 40;
|
||||
protected int minCenterW = 100;
|
||||
|
||||
// ===== LAYOUT CONSTANTS =====
|
||||
protected int pad = 10;
|
||||
protected int topBarH = 24;
|
||||
protected int gap = 4;
|
||||
protected int btnH = 20;
|
||||
|
||||
// ===== PANEL COLORS =====
|
||||
protected int panelBg = 0xC0101010;
|
||||
protected int panelBorder = 0xFF333333;
|
||||
protected int topBarBg = 0xC0181818;
|
||||
|
||||
// ===== COMPUTED LAYOUT (populated by computeLayout) =====
|
||||
protected int originX, originY, usableW, usableH;
|
||||
protected int leftPanelW, rightPanelW;
|
||||
protected int contentX, contentY, contentW, contentH;
|
||||
protected int rightX;
|
||||
|
||||
// ===== OPTIONAL RESIZABLE DIVIDER (between left and center) =====
|
||||
protected boolean enableDivider = false;
|
||||
protected int dividerWidth = 5;
|
||||
protected int dividerLineHeight = 20;
|
||||
protected int minDividerPanelW = 50;
|
||||
private int dividerOffset;
|
||||
private boolean isDragging = false;
|
||||
private int dragStartX;
|
||||
|
||||
// ===== CONSTRUCTOR =====
|
||||
public GuiDirectory() {
|
||||
super();
|
||||
closeOnEsc = true;
|
||||
drawDefaultBackground = true;
|
||||
}
|
||||
|
||||
// ===== LAYOUT COMPUTATION =====
|
||||
protected void computeLayout() {
|
||||
originX = pad;
|
||||
originY = pad;
|
||||
usableW = width - 2 * pad;
|
||||
usableH = height - 2 * pad;
|
||||
|
||||
leftPanelW = Math.max(minLeftPanelW, (int)(usableW * leftPanelPercent));
|
||||
rightPanelW = Math.max(minRightPanelW, (int)(usableW * rightPanelPercent));
|
||||
|
||||
if (rightPanelPercent <= 0) {
|
||||
rightPanelW = 0;
|
||||
}
|
||||
|
||||
int gapCount = rightPanelW > 0 ? 3 : 2;
|
||||
contentW = usableW - leftPanelW - rightPanelW - gapCount * gap;
|
||||
if (contentW < minCenterW) {
|
||||
contentW = minCenterW;
|
||||
}
|
||||
|
||||
contentX = originX + leftPanelW + gap;
|
||||
contentY = originY + topBarH + gap;
|
||||
contentH = usableH - topBarH - gap;
|
||||
rightX = contentX + contentW + gap;
|
||||
|
||||
if (enableDivider && dividerOffset == 0) {
|
||||
dividerOffset = leftPanelW;
|
||||
}
|
||||
}
|
||||
|
||||
// ===== INIT GUI =====
|
||||
@Override
|
||||
public void initGui() {
|
||||
super.initGui();
|
||||
computeLayout();
|
||||
initTopBar(originY + 2);
|
||||
initLeftPanel();
|
||||
initCenterPanel();
|
||||
if (rightPanelW > 0) {
|
||||
initRightPanel(contentY + 4);
|
||||
}
|
||||
}
|
||||
|
||||
// ===== DRAWING =====
|
||||
@Override
|
||||
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
|
||||
drawTopBar();
|
||||
drawPanels();
|
||||
if (enableDivider) {
|
||||
drawDivider(mouseX, mouseY);
|
||||
}
|
||||
super.drawScreen(mouseX, mouseY, partialTicks);
|
||||
drawOverlay(mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
protected void drawTopBar() {
|
||||
GuiUtil.drawRectD(originX, originY, originX + usableW, originY + topBarH, topBarBg);
|
||||
}
|
||||
|
||||
protected void drawPanels() {
|
||||
// Left nav panel border
|
||||
GuiUtil.drawRectD(originX - 1, contentY - 1, originX + leftPanelW + 1, originY + usableH + 1, panelBorder);
|
||||
|
||||
// Right action panel border (if present)
|
||||
if (rightPanelW > 0) {
|
||||
GuiUtil.drawRectD(rightX - 1, contentY - 1, rightX + rightPanelW + 1, originY + usableH + 1, panelBorder);
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawDivider(int mouseX, int mouseY) {
|
||||
if (!enableDivider) return;
|
||||
int divX = originX + dividerOffset;
|
||||
int regionTop = contentY;
|
||||
int regionHeight = contentH;
|
||||
int handleTop = regionTop + (regionHeight - dividerLineHeight) / 2;
|
||||
drawRect(divX + 1, handleTop, divX + dividerWidth - 1, handleTop + dividerLineHeight, 0xFF707070);
|
||||
}
|
||||
|
||||
/** Override for extra drawing after super.drawScreen (e.g. status text) */
|
||||
protected void drawOverlay(int mouseX, int mouseY, float partialTicks) {
|
||||
}
|
||||
|
||||
// ===== DIVIDER MOUSE HANDLING =====
|
||||
@Override
|
||||
public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
|
||||
if (enableDivider && !hasSubGui()) {
|
||||
int divX = originX + dividerOffset;
|
||||
int regionTop = contentY;
|
||||
int handleTop = regionTop + (contentH - dividerLineHeight) / 2;
|
||||
int handleBottom = handleTop + dividerLineHeight;
|
||||
if (mouseX >= divX && mouseX <= divX + dividerWidth &&
|
||||
mouseY >= handleTop && mouseY <= handleBottom) {
|
||||
isDragging = true;
|
||||
resizingActive = true;
|
||||
dragStartX = mouseX;
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) {
|
||||
if (isDragging) {
|
||||
int dx = mouseX - dragStartX;
|
||||
dragStartX = mouseX;
|
||||
dividerOffset += dx;
|
||||
|
||||
int maxOffset = (usableW - (rightPanelW > 0 ? rightPanelW + gap : 0)) - dividerWidth - minDividerPanelW;
|
||||
dividerOffset = Math.max(minDividerPanelW, Math.min(dividerOffset, maxOffset));
|
||||
|
||||
onDividerMoved(dividerOffset);
|
||||
return;
|
||||
}
|
||||
super.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseMovedOrUp(int mouseX, int mouseY, int state) {
|
||||
if (isDragging) {
|
||||
isDragging = false;
|
||||
resizingActive = false;
|
||||
return;
|
||||
}
|
||||
super.mouseMovedOrUp(mouseX, mouseY, state);
|
||||
}
|
||||
|
||||
/** Called when divider is dragged. Override to update scroll sizes. */
|
||||
protected void onDividerMoved(int newOffset) {
|
||||
}
|
||||
|
||||
// Accessors for divider offset
|
||||
protected int getDividerOffset() {
|
||||
return dividerOffset;
|
||||
}
|
||||
|
||||
protected void setDividerOffset(int offset) {
|
||||
this.dividerOffset = offset;
|
||||
}
|
||||
|
||||
// ===== ABSTRACT HOOKS (subclass must implement) =====
|
||||
|
||||
/** Populate top bar buttons. topBtnY is the y-coordinate for the button row. */
|
||||
protected abstract void initTopBar(int topBtnY);
|
||||
|
||||
/** Populate the left navigation panel (scrolls, search fields, buttons). */
|
||||
protected abstract void initLeftPanel();
|
||||
|
||||
/** Populate the center content panel (main scroll list). */
|
||||
protected abstract void initCenterPanel();
|
||||
|
||||
/** Populate the right action panel. startY is the first button y-coordinate. */
|
||||
protected abstract void initRightPanel(int startY);
|
||||
}
|
||||
@@ -15,6 +15,7 @@ public class GuiMenuSideButton extends GuiNpcButton {
|
||||
|
||||
public boolean active;
|
||||
public boolean rightSided;
|
||||
public int textColor = -1;
|
||||
public ItemStack renderStack;
|
||||
public ResourceLocation renderResource;
|
||||
public int renderIconPosX = 0;
|
||||
@@ -96,13 +97,15 @@ public class GuiMenuSideButton extends GuiNpcButton {
|
||||
text += "...";
|
||||
} else
|
||||
text = displayString;
|
||||
if (active) {
|
||||
drawCenteredString(fontrenderer, text, xPosition + width / 2, yPosition + (height - 8) / 2, 0xffffa0);
|
||||
} else if (field_146123_n) {
|
||||
drawCenteredString(fontrenderer, text, xPosition + width / 2, yPosition + (height - 8) / 2, 0xffffa0);
|
||||
int color;
|
||||
if (textColor != -1) {
|
||||
color = textColor;
|
||||
} else if (active || field_146123_n) {
|
||||
color = 0xffffa0;
|
||||
} else {
|
||||
drawCenteredString(fontrenderer, text, xPosition + width / 2, yPosition + (height - 8) / 2, 0xe0e0e0);
|
||||
color = 0xe0e0e0;
|
||||
}
|
||||
drawCenteredString(fontrenderer, text, xPosition + width / 2, yPosition + (height - 8) / 2, color);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package noppes.npcs.client.gui.util;
|
||||
|
||||
import noppes.npcs.controllers.data.Tag;
|
||||
import noppes.npcs.controllers.data.TagMap;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface IClonerGui {
|
||||
int getShowingClones();
|
||||
HashMap<UUID, Tag> getTags();
|
||||
TagMap getTagMap();
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import noppes.npcs.api.IPos;
|
||||
import noppes.npcs.api.IWorld;
|
||||
import noppes.npcs.api.entity.IEntity;
|
||||
import noppes.npcs.api.handler.ICloneHandler;
|
||||
import noppes.npcs.controllers.data.CloneFolder;
|
||||
import noppes.npcs.controllers.data.TagMap;
|
||||
import noppes.npcs.scripted.CustomNPCsException;
|
||||
import noppes.npcs.scripted.NpcAPI;
|
||||
@@ -27,6 +28,7 @@ import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@@ -34,8 +36,11 @@ import java.util.UUID;
|
||||
public class ServerCloneController implements ICloneHandler {
|
||||
public static ServerCloneController Instance;
|
||||
|
||||
protected Map<String, CloneFolder> folders = new LinkedHashMap<>();
|
||||
|
||||
public ServerCloneController() {
|
||||
loadClones();
|
||||
loadFolders();
|
||||
}
|
||||
|
||||
private void loadClones() {
|
||||
@@ -103,6 +108,8 @@ public class ServerCloneController implements ICloneHandler {
|
||||
return clones;
|
||||
}
|
||||
|
||||
// ==================== Tab-Based Clone Operations ====================
|
||||
|
||||
public NBTTagCompound getCloneData(ICommandSender player, String name, int tab) {
|
||||
File file = new File(new File(getDir(), tab + ""), name + ".json");
|
||||
if (!file.exists()) {
|
||||
@@ -194,6 +201,250 @@ public class ServerCloneController implements ICloneHandler {
|
||||
return name;
|
||||
}
|
||||
|
||||
// ==================== Folder Registry ====================
|
||||
|
||||
public void loadFolders() {
|
||||
folders.clear();
|
||||
File dir = getDir();
|
||||
File[] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
List<File> folderDirs = new ArrayList<>();
|
||||
for (File f : files) {
|
||||
if (!f.isDirectory()) continue;
|
||||
String name = f.getName();
|
||||
if (name.startsWith("___")) continue;
|
||||
try {
|
||||
Integer.parseInt(name);
|
||||
continue;
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
folderDirs.add(f);
|
||||
}
|
||||
folderDirs.sort(Comparator.comparing(File::getName));
|
||||
for (File f : folderDirs) {
|
||||
CloneFolder folder = new CloneFolder(f.getName());
|
||||
folder.createdDate = f.lastModified();
|
||||
folders.put(f.getName(), folder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<CloneFolder> getFolderList() {
|
||||
return new ArrayList<>(folders.values());
|
||||
}
|
||||
|
||||
public List<String> getFolderNames() {
|
||||
return new ArrayList<>(folders.keySet());
|
||||
}
|
||||
|
||||
public boolean hasFolder(String name) {
|
||||
return folders.containsKey(name);
|
||||
}
|
||||
|
||||
// ==================== Folder CRUD ====================
|
||||
|
||||
public CloneFolder createFolder(String name) {
|
||||
if (!CloneFolder.isValidName(name) || folders.containsKey(name)) {
|
||||
return null;
|
||||
}
|
||||
CloneFolder folder = new CloneFolder(name);
|
||||
File dir = getFolderDir(name);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdir();
|
||||
}
|
||||
folders.put(name, folder);
|
||||
return folder;
|
||||
}
|
||||
|
||||
public boolean renameFolder(String oldName, String newName) {
|
||||
if (!folders.containsKey(oldName) || !CloneFolder.isValidName(newName) || folders.containsKey(newName)) {
|
||||
return false;
|
||||
}
|
||||
CloneFolder folder = folders.get(oldName);
|
||||
File oldDir = getFolderDir(oldName);
|
||||
File newDir = new File(getDir(), newName);
|
||||
if (!oldDir.renameTo(newDir)) {
|
||||
return false;
|
||||
}
|
||||
folders.remove(oldName);
|
||||
folder.name = newName;
|
||||
folders.put(newName, folder);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean deleteFolder(String name) {
|
||||
if (!folders.containsKey(name)) {
|
||||
return false;
|
||||
}
|
||||
List<String> clones = getClones(name);
|
||||
if (!clones.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
File dir = getFolderDir(name);
|
||||
if (dir.exists()) {
|
||||
File tagMapFile = new File(dir, "___tagmap.dat");
|
||||
if (tagMapFile.exists()) tagMapFile.delete();
|
||||
File tagMapOld = new File(dir, "___tagmap.dat_old");
|
||||
if (tagMapOld.exists()) tagMapOld.delete();
|
||||
File tagMapNew = new File(dir, "___tagmap.dat_new");
|
||||
if (tagMapNew.exists()) tagMapNew.delete();
|
||||
dir.delete();
|
||||
}
|
||||
folders.remove(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ==================== Folder-Based Clone Operations ====================
|
||||
|
||||
public File getFolderDir(String folderName) {
|
||||
return new File(getDir(), folderName);
|
||||
}
|
||||
|
||||
public List<String> getClones(String folderName) {
|
||||
List<String> list = new ArrayList<>();
|
||||
File dir = getFolderDir(folderName);
|
||||
if (!dir.exists() || !dir.isDirectory())
|
||||
return list;
|
||||
for (String file : dir.list()) {
|
||||
if (file.endsWith(".json"))
|
||||
list.add(file.substring(0, file.length() - 5));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<String> getClonesDate(String folderName) {
|
||||
List<String> list = new ArrayList<>();
|
||||
File dir = getFolderDir(folderName);
|
||||
if (!dir.exists() || !dir.isDirectory())
|
||||
return list;
|
||||
File[] files = dir.listFiles();
|
||||
if (files == null) return list;
|
||||
Arrays.sort(files, new Comparator<File>() {
|
||||
public int compare(File f1, File f2) {
|
||||
return Long.compare(f1.lastModified(), f2.lastModified());
|
||||
}
|
||||
});
|
||||
for (File file : files) {
|
||||
String fileName = file.getName();
|
||||
if (fileName.endsWith(".json"))
|
||||
list.add(fileName.substring(0, fileName.length() - 5));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public NBTTagCompound getCloneData(ICommandSender player, String name, String folderName) {
|
||||
File file = new File(getFolderDir(folderName), name + ".json");
|
||||
if (!file.exists()) {
|
||||
if (player != null)
|
||||
player.addChatMessage(new ChatComponentText("Could not find clone file"));
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return NBTJsonUtil.LoadFile(file);
|
||||
} catch (Exception e) {
|
||||
LogWriter.error("Error loading: " + file.getAbsolutePath(), e);
|
||||
if (player != null)
|
||||
player.addChatMessage(new ChatComponentText(e.getMessage()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void saveClone(String folderName, String name, NBTTagCompound compound) {
|
||||
try {
|
||||
File dir = getFolderDir(folderName);
|
||||
if (!dir.exists()) dir.mkdir();
|
||||
String filename = name + ".json";
|
||||
File file = new File(dir, filename + "_new");
|
||||
File file2 = new File(dir, filename);
|
||||
NBTJsonUtil.SaveFile(file, compound);
|
||||
addToTagMap(compound, name, folderName);
|
||||
if (file2.exists()) {
|
||||
file2.delete();
|
||||
}
|
||||
file.renameTo(file2);
|
||||
} catch (Exception e) {
|
||||
LogWriter.except(e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean removeClone(String name, String folderName) {
|
||||
File file = new File(getFolderDir(folderName), name + ".json");
|
||||
if (!file.exists())
|
||||
return false;
|
||||
file.delete();
|
||||
removeFromTagMap(name, folderName);
|
||||
return true;
|
||||
}
|
||||
|
||||
public String addClone(NBTTagCompound nbttagcompound, String name, String folderName) {
|
||||
cleanTags(nbttagcompound);
|
||||
saveClone(folderName, name, nbttagcompound);
|
||||
return name;
|
||||
}
|
||||
|
||||
public String addClone(NBTTagCompound nbttagcompound, String name, String folderName, NBTTagCompound tempTags) {
|
||||
cleanTagList(nbttagcompound, tempTags);
|
||||
cleanTags(nbttagcompound);
|
||||
saveClone(folderName, name, nbttagcompound);
|
||||
return name;
|
||||
}
|
||||
|
||||
// ==================== Move Operations ====================
|
||||
|
||||
public boolean moveClone(String cloneName, int fromTab, String toFolder) {
|
||||
NBTTagCompound data = getCloneData(null, cloneName, fromTab);
|
||||
if (data == null) return false;
|
||||
|
||||
HashSet<UUID> tagUUIDs = getTagUUIDsFromTab(cloneName, fromTab);
|
||||
|
||||
saveClone(toFolder, cloneName, data);
|
||||
setTagUUIDsForFolder(cloneName, toFolder, tagUUIDs);
|
||||
|
||||
removeClone(cloneName, fromTab);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean moveClone(String cloneName, String fromFolder, int toTab) {
|
||||
NBTTagCompound data = getCloneData(null, cloneName, fromFolder);
|
||||
if (data == null) return false;
|
||||
|
||||
HashSet<UUID> tagUUIDs = getTagUUIDsFromFolder(cloneName, fromFolder);
|
||||
|
||||
saveClone(toTab, cloneName, data);
|
||||
setTagUUIDsForTab(cloneName, toTab, tagUUIDs);
|
||||
|
||||
removeClone(cloneName, fromFolder);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean moveClone(String cloneName, String fromFolder, String toFolder) {
|
||||
NBTTagCompound data = getCloneData(null, cloneName, fromFolder);
|
||||
if (data == null) return false;
|
||||
|
||||
HashSet<UUID> tagUUIDs = getTagUUIDsFromFolder(cloneName, fromFolder);
|
||||
|
||||
saveClone(toFolder, cloneName, data);
|
||||
setTagUUIDsForFolder(cloneName, toFolder, tagUUIDs);
|
||||
|
||||
removeClone(cloneName, fromFolder);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean moveClone(String cloneName, int fromTab, int toTab) {
|
||||
NBTTagCompound data = getCloneData(null, cloneName, fromTab);
|
||||
if (data == null) return false;
|
||||
|
||||
HashSet<UUID> tagUUIDs = getTagUUIDsFromTab(cloneName, fromTab);
|
||||
|
||||
saveClone(toTab, cloneName, data);
|
||||
setTagUUIDsForTab(cloneName, toTab, tagUUIDs);
|
||||
|
||||
removeClone(cloneName, fromTab);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ==================== Tag Utilities ====================
|
||||
|
||||
public NBTTagCompound cleanTagList(NBTTagCompound nbttagcompound, NBTTagCompound tempTags) {
|
||||
HashSet<UUID> tagUUIDs = new HashSet<UUID>();
|
||||
if (nbttagcompound.hasKey("TagUUIDs")) {
|
||||
@@ -243,6 +494,25 @@ public class ServerCloneController implements ICloneHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean addToTagMap(NBTTagCompound nbttagcompound, String name, String folderName) {
|
||||
HashSet<UUID> tagUUIDs = new HashSet<>();
|
||||
if (nbttagcompound.hasKey("TagUUIDs")) {
|
||||
NBTTagList nbtTagList = nbttagcompound.getTagList("TagUUIDs", 8);
|
||||
for (int i = 0; i < nbtTagList.tagCount(); i++) {
|
||||
tagUUIDs.add(UUID.fromString(nbtTagList.getStringTagAt(i)));
|
||||
}
|
||||
}
|
||||
|
||||
TagMap tagMap = ServerTagMapController.Instance.getTagMap(folderName);
|
||||
if (!tagUUIDs.isEmpty()) {
|
||||
tagMap.putClone(name, tagUUIDs);
|
||||
} else {
|
||||
tagMap.removeClone(name);
|
||||
}
|
||||
ServerTagMapController.Instance.saveTagMap(tagMap);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean removeFromTagMap(String name, int tab) {
|
||||
TagMap tagMap = ServerTagMapController.Instance.getTagMap(tab);
|
||||
if (tagMap.removeClone(name)) {
|
||||
@@ -252,6 +522,41 @@ public class ServerCloneController implements ICloneHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean removeFromTagMap(String name, String folderName) {
|
||||
TagMap tagMap = ServerTagMapController.Instance.getTagMap(folderName);
|
||||
if (tagMap.removeClone(name)) {
|
||||
ServerTagMapController.Instance.saveTagMap(tagMap);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected HashSet<UUID> getTagUUIDsFromTab(String cloneName, int tab) {
|
||||
TagMap tagMap = ServerTagMapController.Instance.getTagMap(tab);
|
||||
HashSet<UUID> uuids = tagMap.getUUIDs(cloneName);
|
||||
return uuids != null ? new HashSet<>(uuids) : new HashSet<>();
|
||||
}
|
||||
|
||||
protected HashSet<UUID> getTagUUIDsFromFolder(String cloneName, String folderName) {
|
||||
TagMap tagMap = ServerTagMapController.Instance.getTagMap(folderName);
|
||||
HashSet<UUID> uuids = tagMap.getUUIDs(cloneName);
|
||||
return uuids != null ? new HashSet<>(uuids) : new HashSet<>();
|
||||
}
|
||||
|
||||
protected void setTagUUIDsForTab(String cloneName, int tab, HashSet<UUID> tagUUIDs) {
|
||||
if (tagUUIDs == null || tagUUIDs.isEmpty()) return;
|
||||
TagMap tagMap = ServerTagMapController.Instance.getTagMap(tab);
|
||||
tagMap.putClone(cloneName, tagUUIDs);
|
||||
ServerTagMapController.Instance.saveTagMap(tagMap);
|
||||
}
|
||||
|
||||
protected void setTagUUIDsForFolder(String cloneName, String folderName, HashSet<UUID> tagUUIDs) {
|
||||
if (tagUUIDs == null || tagUUIDs.isEmpty()) return;
|
||||
TagMap tagMap = ServerTagMapController.Instance.getTagMap(folderName);
|
||||
tagMap.putClone(cloneName, tagUUIDs);
|
||||
ServerTagMapController.Instance.saveTagMap(tagMap);
|
||||
}
|
||||
|
||||
public void cleanTags(NBTTagCompound nbttagcompound) {
|
||||
if (nbttagcompound.hasKey("ItemGiverId"))
|
||||
nbttagcompound.setInteger("ItemGiverId", 0);
|
||||
@@ -288,6 +593,8 @@ public class ServerCloneController implements ICloneHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== API Methods (ICloneHandler) ====================
|
||||
|
||||
public IEntity spawn(double x, double y, double z, int tab, String name, IWorld world, boolean ignoreProtection) {
|
||||
NBTTagCompound compound = this.getCloneData((ICommandSender) null, name, tab);
|
||||
if (compound == null) {
|
||||
@@ -327,7 +634,7 @@ public class ServerCloneController implements ICloneHandler {
|
||||
for (File file : dir.listFiles()) {
|
||||
if (file.getName().endsWith(".json")) {
|
||||
NBTTagCompound compound = NBTJsonUtil.LoadFile(file);
|
||||
Instance.cleanTags(compound);
|
||||
cleanTags(compound);
|
||||
Entity entity = EntityList.createEntityFromNBT(compound, world.getMCWorld());
|
||||
arrayList.add(entity == null ? null : NpcAPI.Instance().getIEntity(entity));
|
||||
}
|
||||
@@ -343,7 +650,7 @@ public class ServerCloneController implements ICloneHandler {
|
||||
if (compound == null) {
|
||||
throw new CustomNPCsException("Unknown clone tab:" + tab + " name:" + name, new Object[0]);
|
||||
} else {
|
||||
Instance.cleanTags(compound);
|
||||
cleanTags(compound);
|
||||
Entity entity = EntityList.createEntityFromNBT(compound, world.getMCWorld());
|
||||
return entity == null ? null : NpcAPI.Instance().getIEntity(entity);
|
||||
}
|
||||
@@ -354,7 +661,6 @@ public class ServerCloneController implements ICloneHandler {
|
||||
return compound != null;
|
||||
}
|
||||
|
||||
|
||||
public void set(int tab, String name, IEntity entity) {
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
if (!entity.getMCEntity().writeMountToNBT(compound))
|
||||
@@ -367,4 +673,85 @@ public class ServerCloneController implements ICloneHandler {
|
||||
public void remove(int tab, String name) {
|
||||
this.removeClone(name, tab);
|
||||
}
|
||||
|
||||
// --- Folder API Methods ---
|
||||
|
||||
public String[] getFolders() {
|
||||
return getFolderNames().toArray(new String[0]);
|
||||
}
|
||||
|
||||
public IEntity spawn(double x, double y, double z, String folderName, String name, IWorld world, boolean ignoreProtection) {
|
||||
NBTTagCompound compound = getCloneData(null, name, folderName);
|
||||
if (compound == null) {
|
||||
throw new CustomNPCsException("Unknown clone folder:" + folderName + " name:" + name, new Object[0]);
|
||||
}
|
||||
Entity entity;
|
||||
if (!ignoreProtection) {
|
||||
entity = NoppesUtilServer.spawnCloneWithProtection(compound, (int) x, (int) y, (int) z, world.getMCWorld());
|
||||
} else {
|
||||
entity = NoppesUtilServer.spawnClone(compound, (int) x, (int) y, (int) z, world.getMCWorld());
|
||||
}
|
||||
return entity == null ? null : NpcAPI.Instance().getIEntity(entity);
|
||||
}
|
||||
|
||||
public IEntity spawn(IPos pos, String folderName, String name, IWorld world, boolean ignoreProtection) {
|
||||
return this.spawn(pos.getX(), pos.getY(), pos.getZ(), folderName, name, world, ignoreProtection);
|
||||
}
|
||||
|
||||
public IEntity spawn(double x, double y, double z, String folderName, String name, IWorld world) {
|
||||
return spawn(x, y, z, folderName, name, world, true);
|
||||
}
|
||||
|
||||
public IEntity spawn(IPos pos, String folderName, String name, IWorld world) {
|
||||
return this.spawn(pos.getX(), pos.getY(), pos.getZ(), folderName, name, world);
|
||||
}
|
||||
|
||||
public IEntity[] getFolder(String folderName, IWorld world) {
|
||||
File dir = getFolderDir(folderName);
|
||||
if (!dir.exists() || !dir.isDirectory() || dir.listFiles() == null) {
|
||||
return new IEntity[]{};
|
||||
}
|
||||
|
||||
ArrayList<IEntity> arrayList = new ArrayList<>();
|
||||
try {
|
||||
for (File file : dir.listFiles()) {
|
||||
if (file.getName().endsWith(".json")) {
|
||||
NBTTagCompound compound = NBTJsonUtil.LoadFile(file);
|
||||
cleanTags(compound);
|
||||
Entity entity = EntityList.createEntityFromNBT(compound, world.getMCWorld());
|
||||
arrayList.add(entity == null ? null : NpcAPI.Instance().getIEntity(entity));
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return arrayList.toArray(new IEntity[]{});
|
||||
}
|
||||
|
||||
public IEntity get(String folderName, String name, IWorld world) {
|
||||
NBTTagCompound compound = getCloneData(null, name, folderName);
|
||||
if (compound == null) {
|
||||
throw new CustomNPCsException("Unknown clone folder:" + folderName + " name:" + name, new Object[0]);
|
||||
}
|
||||
cleanTags(compound);
|
||||
Entity entity = EntityList.createEntityFromNBT(compound, world.getMCWorld());
|
||||
return entity == null ? null : NpcAPI.Instance().getIEntity(entity);
|
||||
}
|
||||
|
||||
public boolean has(String folderName, String name) {
|
||||
NBTTagCompound compound = getCloneData(null, name, folderName);
|
||||
return compound != null;
|
||||
}
|
||||
|
||||
public void set(String folderName, String name, IEntity entity) {
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
if (!entity.getMCEntity().writeMountToNBT(compound))
|
||||
throw new CustomNPCsException("Cannot save dead entities", new Object[0]);
|
||||
|
||||
this.cleanTags(compound);
|
||||
this.saveClone(folderName, name, compound);
|
||||
}
|
||||
|
||||
public void remove(String folderName, String name) {
|
||||
this.removeClone(name, folderName);
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,13 @@ public class ServerTagMapController {
|
||||
return dir;
|
||||
}
|
||||
|
||||
public File getCloneFolderDir(String folderName) {
|
||||
File dir = new File(getDir(), folderName);
|
||||
if (!dir.exists())
|
||||
dir.mkdir();
|
||||
return dir;
|
||||
}
|
||||
|
||||
public TagMap getTagMap(int tab) {
|
||||
this.tagMap = new TagMap(tab);
|
||||
try {
|
||||
@@ -65,9 +72,33 @@ public class ServerTagMapController {
|
||||
this.tagMap.readNBT(nbtCompound);
|
||||
}
|
||||
|
||||
public TagMap getTagMap(String folderName) {
|
||||
this.tagMap = new TagMap(folderName);
|
||||
try {
|
||||
File file = new File(getCloneFolderDir(folderName), "___tagmap.dat");
|
||||
if (file.exists()) {
|
||||
loadTagMapFile(file);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
File file = new File(getCloneFolderDir(folderName), "___tagmap.dat_old");
|
||||
if (file.exists()) {
|
||||
loadTagMapFile(file);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
return this.tagMap;
|
||||
}
|
||||
|
||||
public void saveTagMap(TagMap tagMap) {
|
||||
try {
|
||||
File saveDir = getCloneTabDir(tagMap.cloneTab);
|
||||
File saveDir;
|
||||
if (tagMap.cloneFolder != null) {
|
||||
saveDir = getCloneFolderDir(tagMap.cloneFolder);
|
||||
} else {
|
||||
saveDir = getCloneTabDir(tagMap.cloneTab);
|
||||
}
|
||||
File file = new File(saveDir, "___tagmap.dat_new");
|
||||
File file1 = new File(saveDir, "___tagmap.dat_old");
|
||||
File file2 = new File(saveDir, "___tagmap.dat");
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package noppes.npcs.controllers.data;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public class CloneFolder {
|
||||
public String name;
|
||||
public long createdDate;
|
||||
|
||||
public CloneFolder() {
|
||||
this.name = "";
|
||||
this.createdDate = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public CloneFolder(String name) {
|
||||
this.name = name;
|
||||
this.createdDate = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void readNBT(NBTTagCompound compound) {
|
||||
name = compound.getString("Name");
|
||||
createdDate = compound.getLong("Created");
|
||||
}
|
||||
|
||||
public NBTTagCompound writeNBT(NBTTagCompound compound) {
|
||||
compound.setString("Name", name);
|
||||
compound.setLong("Created", createdDate);
|
||||
return compound;
|
||||
}
|
||||
|
||||
public static boolean isValidName(String name) {
|
||||
if (name == null || name.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (name.length() > 32) {
|
||||
return false;
|
||||
}
|
||||
if (!name.equals(name.trim())) {
|
||||
return false;
|
||||
}
|
||||
if (name.equals(".") || name.equals("..")) {
|
||||
return false;
|
||||
}
|
||||
if (name.startsWith("___")) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Integer.parseInt(name);
|
||||
return false;
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
for (char c : name.toCharArray()) {
|
||||
if (c == '/' || c == '\\' || c == ':' || c == '*' || c == '?' || c == '"' || c == '<' || c == '>' || c == '|') {
|
||||
return false;
|
||||
}
|
||||
if (c < 32) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -13,10 +13,18 @@ import java.util.UUID;
|
||||
|
||||
public class TagMap {
|
||||
public int cloneTab;
|
||||
public String cloneFolder;
|
||||
public HashMap<String, HashSet<UUID>> tagMap;
|
||||
|
||||
public TagMap(int tab) {
|
||||
this.cloneTab = tab;
|
||||
this.cloneFolder = null;
|
||||
this.tagMap = new HashMap<String, HashSet<UUID>>();
|
||||
}
|
||||
|
||||
public TagMap(String folder) {
|
||||
this.cloneTab = -1;
|
||||
this.cloneFolder = folder;
|
||||
this.tagMap = new HashMap<String, HashSet<UUID>>();
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 924 B |
Binary file not shown.
|
After Width: | Height: | Size: 932 B |
Reference in new issue
Block a user