Modifiable Magic Data in PlayerData tab

This commit is contained in:
Kam committed 2025-03-07 16:00:06 -05:00
1 parent 20e3cdd1f0
commit 382fb0cf9c
12 files changed
+439 -107

No files matched your search

@@ -227,7 +227,8 @@ public class PacketHandler {
REQUEST_PACKET.registerPacket(new PlayerDataGetNamesPacket());
REQUEST_PACKET.registerPacket(new PlayerDataRemovePacket());
REQUEST_PACKET.registerPacket(new PlayerDataGetInfoPacket());
REQUEST_PACKET.registerPacket(new PlayerDataRemoveInfoPacket());
REQUEST_PACKET.registerPacket(new PlayerDataDeleteInfoPacket());
REQUEST_PACKET.registerPacket(new PlayerDataSaveInfoPacket());
REQUEST_PACKET.registerPacket(new PlayerDataMapRegenPacket());
// Main Menu Packets
@@ -334,6 +335,7 @@ public class PacketHandler {
REQUEST_PACKET.registerPacket(new MagicSavePacket());
REQUEST_PACKET.registerPacket(new MagicRemovePacket());
REQUEST_PACKET.registerPacket(new MagicGetPacket());
REQUEST_PACKET.registerPacket(new MagicDataGetPacket());
// Other Packets
REQUEST_PACKET.registerPacket(new IsGuiOpenInform());
@@ -133,7 +133,7 @@ public enum EnumRequestPacket {
PlayerDataInfo,
PlayerDataGetNames,
PlayerDataDelete,
PlayerDataDeleteInfo,
PlayerDataRemove,
PlayerDataMapRegen,
@@ -196,5 +196,7 @@ public enum EnumRequestPacket {
MagicCycleSave,
MagicGetAll,
MagicRemove,
MagicGet, MagicSave
MagicGet,
MagicSave,
PlayerDataSave, MagicDataGet
}
@@ -8,7 +8,10 @@ import kamkeel.npcs.network.PacketHandler;
import kamkeel.npcs.network.enums.EnumDataPacket;
import kamkeel.npcs.util.ByteBufUtils;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import noppes.npcs.client.NoppesUtil;
import noppes.npcs.controllers.data.Magic;
import noppes.npcs.controllers.data.MagicData;
import java.io.IOException;
import java.util.Map;
@@ -30,13 +33,15 @@ public final class PlayerDataInfoPacket extends LargeAbstractPacket {
private Map<String, Integer> bankData;
private Map<String, Integer> factionData;
private MagicData playerMagicData;
public PlayerDataInfoPacket() {}
public PlayerDataInfoPacket(String playerName,
Map<String, Integer> questCategories, Map<String, Integer> questActive, Map<String, Integer> questFinished,
Map<String, Integer> dialogCategories, Map<String, Integer> dialogRead,
Map<String, Integer> transportCategories, Map<String, Integer> transportLocations,
Map<String, Integer> bankData, Map<String, Integer> factionData) {
Map<String, Integer> bankData, Map<String, Integer> factionData, MagicData playerMagicData) {
this.playerName = playerName;
this.questCategories = questCategories;
this.questActive = questActive;
@@ -47,6 +52,7 @@ public final class PlayerDataInfoPacket extends LargeAbstractPacket {
this.transportLocations = transportLocations;
this.bankData = bankData;
this.factionData = factionData;
this.playerMagicData = playerMagicData;
}
@Override
@@ -79,6 +85,10 @@ public final class PlayerDataInfoPacket extends LargeAbstractPacket {
// Write faction data map:
writeMap(buffer, factionData);
NBTTagCompound compound = new NBTTagCompound();
playerMagicData.writeToNBT(compound);
ByteBufUtils.writeNBT(buffer, compound);
byte[] bytes = new byte[buffer.readableBytes()];
buffer.readBytes(bytes);
return bytes;
@@ -0,0 +1,46 @@
package kamkeel.npcs.network.packets.request.magic;
import io.netty.buffer.ByteBuf;
import kamkeel.npcs.network.AbstractPacket;
import kamkeel.npcs.network.PacketChannel;
import kamkeel.npcs.network.PacketHandler;
import kamkeel.npcs.network.enums.EnumRequestPacket;
import kamkeel.npcs.util.ByteBufUtils;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import noppes.npcs.NoppesUtilServer;
import java.io.IOException;
public final class MagicDataGetPacket extends AbstractPacket {
public static final String packetName = "Request|MagicDataGet";
public MagicDataGetPacket() {}
@Override
public Enum getType() {
return EnumRequestPacket.MagicDataGet;
}
@Override
public PacketChannel getChannel() {
return PacketHandler.REQUEST_PACKET;
}
@Override
public boolean needsNPC() {
return true;
}
@Override
public void sendData(ByteBuf out) throws IOException {}
@Override
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
if (!(player instanceof EntityPlayerMP))
return;
// String playerName = ByteBufUtils.readString(in);
// NoppesUtilServer.sendPlayerDataInfo(playerName, (EntityPlayerMP) player);
}
}
@@ -13,16 +13,16 @@ import noppes.npcs.constants.EnumPlayerData;
import java.io.IOException;
public final class PlayerDataRemoveInfoPacket extends AbstractPacket {
public static final String packetName = "Request|PlayerDataRemoveNew";
public final class PlayerDataDeleteInfoPacket extends AbstractPacket {
public static final String packetName = "Request|PlayerDataDeleteInfo";
private String playerName;
private EnumPlayerData tabType;
private int value;
public PlayerDataRemoveInfoPacket() {}
public PlayerDataDeleteInfoPacket() {}
public PlayerDataRemoveInfoPacket(String playerName, EnumPlayerData tabType, int selectedKey) {
public PlayerDataDeleteInfoPacket(String playerName, EnumPlayerData tabType, int selectedKey) {
this.playerName = playerName;
this.tabType = tabType;
this.value = selectedKey;
@@ -30,7 +30,7 @@ public final class PlayerDataRemoveInfoPacket extends AbstractPacket {
@Override
public Enum getType() {
return EnumRequestPacket.PlayerDataDelete;
return EnumRequestPacket.PlayerDataDeleteInfo;
}
@Override
@@ -0,0 +1,58 @@
package kamkeel.npcs.network.packets.request.playerdata;
import io.netty.buffer.ByteBuf;
import kamkeel.npcs.network.AbstractPacket;
import kamkeel.npcs.network.PacketChannel;
import kamkeel.npcs.network.PacketHandler;
import kamkeel.npcs.network.enums.EnumRequestPacket;
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.NoppesUtilServer;
import noppes.npcs.constants.EnumPlayerData;
import java.io.IOException;
public final class PlayerDataSaveInfoPacket extends AbstractPacket {
public static final String packetName = "Request|PlayerDataSave";
private String playerName;
private EnumPlayerData tabType;
private NBTTagCompound value;
public PlayerDataSaveInfoPacket() {}
public PlayerDataSaveInfoPacket(String playerName, EnumPlayerData tabType, NBTTagCompound compound) {
this.playerName = playerName;
this.tabType = tabType;
this.value = compound;
}
@Override
public Enum getType() {
return EnumRequestPacket.PlayerDataSave;
}
@Override
public PacketChannel getChannel() {
return PacketHandler.REQUEST_PACKET;
}
@Override
public void sendData(ByteBuf out) throws IOException {
ByteBufUtils.writeString(out, playerName);
out.writeInt(tabType.ordinal());
ByteBufUtils.writeNBT(out, this.value);
}
@Override
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
if (!(player instanceof EntityPlayerMP))
return;
String playerName = ByteBufUtils.readString(in);
int tabType = in.readInt();
NBTTagCompound value = ByteBufUtils.readNBT(in);
NoppesUtilServer.savePlayerDataInfo(playerName, tabType, value, (EntityPlayerMP) player);
}
}
@@ -590,6 +590,11 @@ public class NoppesUtilServer {
data.factionData.remove(buffer.readInt());
playerdata.save();
}
if(type == EnumPlayerData.Magic){
MagicData data = playerdata.magicData;
data.removeMagic(buffer.readInt());
playerdata.save();
}
if(pl != null) {
SyncController.syncPlayer((EntityPlayerMP) pl);
}
@@ -1081,7 +1086,7 @@ public class NoppesUtilServer {
questCategoriesMap, questActiveMap, questFinishedMap,
dialogCategoriesMap, dialogReadMap,
transportCategoriesMap, transportLocationsMap,
bankMap, factionMap);
bankMap, factionMap, playerdata.magicData);
PacketHandler.Instance.sendToPlayer(packet, player);
}
@@ -1094,6 +1099,7 @@ public class NoppesUtilServer {
* 2: Transport – remove from transports.
* 3: Bank – remove from banks.
* 4: Factions – remove from factionData.
* 5: Magic - remove from magicData.
*
* The selectedKey is expected to be the string representation of the entry's ID.
*/
@@ -1123,10 +1129,45 @@ public class NoppesUtilServer {
if(enumPlayerData == EnumPlayerData.Factions) { // Faction removal
playerdata.factionData.factionData.remove(value);
}
if(enumPlayerData == EnumPlayerData.Magic) { // Faction removal
playerdata.magicData.removeMagic(value);
}
playerdata.save();
if(pl != null) {
SyncController.syncPlayer((EntityPlayerMP) pl);
}
}
/**
* Removes a specific data entry from the player's data.
*
* The tabType parameter is used as follows:
* 0: Quest – remove from both activeQuests and finishedQuests.
* 1: Dialog – remove from dialogsRead.
* 2: Transport – remove from transports.
* 3: Bank – remove from banks.
* 4: Factions – remove from factionData.
*
* The selectedKey is expected to be the string representation of the entry's ID.
*/
public static void savePlayerDataInfo(String playerName, int tabType, NBTTagCompound compound, EntityPlayerMP player) {
EntityPlayer pl = MinecraftServer.getServer().getConfigurationManager().func_152612_a(playerName);
PlayerData playerdata;
EnumPlayerData enumPlayerData = EnumPlayerData.values()[tabType];
if(pl == null)
playerdata = PlayerDataController.Instance.getDataFromUsername(playerName);
else
playerdata = PlayerDataController.Instance.getPlayerData(pl);
if(enumPlayerData == EnumPlayerData.Magic) { // Quest removal
playerdata.magicData.readToNBT(compound);
}
playerdata.save();
if(pl != null) {
SyncController.syncPlayer((EntityPlayerMP) pl);
}
}
}
@@ -21,6 +21,7 @@ import noppes.npcs.client.gui.util.*;
import noppes.npcs.constants.EnumGuiType;
import noppes.npcs.constants.EnumScrollData;
import noppes.npcs.controllers.data.Dialog;
import noppes.npcs.controllers.data.MagicData;
import noppes.npcs.controllers.data.Quest;
import noppes.npcs.controllers.data.SkinOverlay;
import noppes.npcs.entity.EntityNPCInterface;
@@ -252,7 +253,8 @@ public class NoppesUtil {
Map<String, Integer> transportLocations = readMap(data);
Map<String, Integer> bankData = readMap(data);
Map<String, Integer> factionData = readMap(data);
MagicData magicData = new MagicData();
magicData.readToNBT(ByteBufUtils.readNBT(data));
GuiScreen gui = Minecraft.getMinecraft().currentScreen;
if(gui == null)
@@ -271,6 +273,7 @@ public class NoppesUtil {
info.setTransportData(transportCategories, transportLocations);
info.setBankData(bankData);
info.setFactionData(factionData);
info.setMagicData(magicData);
}
}
@@ -1,28 +1,30 @@
package noppes.npcs.client.gui;
import kamkeel.npcs.network.PacketClient;
import kamkeel.npcs.network.packets.request.magic.MagicGetAllPacket;
import kamkeel.npcs.network.packets.request.playerdata.PlayerDataGetInfoPacket;
import kamkeel.npcs.network.packets.request.playerdata.PlayerDataRemoveInfoPacket;
import kamkeel.npcs.network.packets.request.playerdata.PlayerDataDeleteInfoPacket;
import kamkeel.npcs.network.packets.request.playerdata.PlayerDataSaveInfoPacket;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.nbt.NBTTagCompound;
import noppes.npcs.client.CustomNpcResourceListener;
import noppes.npcs.client.gui.util.*;
import noppes.npcs.constants.EnumPlayerData;
import noppes.npcs.constants.EnumScrollData;
import noppes.npcs.controllers.data.MagicData;
import org.lwjgl.opengl.GL11;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import static noppes.npcs.client.gui.player.inventory.GuiCNPCInventory.specialIcons;
public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo, ICustomScrollListener {
public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo, ICustomScrollListener, ITextfieldListener, IScrollData {
////////////////////////////////////////////////////////////////////////////////
// Fields
////////////////////////////////////////////////////////////////////////////////
// Current tab (10=Quest, 11=Dialog, 12=Transport, 13=Bank, 14=Faction)
// Current tab (10=Quest, 11=Dialog, 12=Transport, 13=Bank, 14=Faction, 15=Magic)
private int currentTab = 10;
// View mode: 0 = Categorical (3 or 2 scrolls), 1 = Compact (2 or 1 scroll)
private int viewMode = 0;
@@ -55,9 +57,13 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
private HashMap<String, Integer> bankData = new HashMap<>();
private HashMap<String, Integer> factionData = new HashMap<>();
// ----- NEW: Magic Tab Components (Tab id 15) -----
private GuiCustomScroll magicAllScroll, magicSelectedScroll;
private MagicData magicData;
private HashMap<String, Integer> availableMagicElements = new HashMap<>();
private GuiNpcTextField splitField, damageField;
// ----- Divider & Resizing Variables -----
// In categorical mode for Quest: two dividers (3 scrolls).
// In compact mode for Quest: one divider between two scrolls.
private int dividerOffset1 = 0; // In categorical: width of left scroll; in compact for quests: width of left scroll.
private int dividerOffset2 = 0; // Only used for Quest categorical mode.
private final int dividerWidth = 5;
@@ -87,12 +93,12 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
setBackground("menubg.png");
closeOnEsc = true;
PacketClient.sendClient(new PlayerDataGetInfoPacket(playerName));
PacketClient.sendClient(new MagicGetAllPacket());
}
////////////////////////////////////////////////////////////////////////////////
// Layout Helpers
////////////////////////////////////////////////////////////////////////////////
private int getPaddedLeft() {
return guiLeft + leftPadding;
}
@@ -105,12 +111,10 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
return getPaddedRight() - getPaddedLeft();
}
// Height available for scroll windows.
private int getScrollHeight() {
return ySize - (scrollTopOffset + verticalGapAboveTF + textFieldHeight + verticalGapBelowTF);
}
// Y coordinate for textfields.
private int getTextFieldY() {
return guiTop + scrollTopOffset + getScrollHeight() + verticalGapAboveTF;
}
@@ -118,10 +122,7 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
////////////////////////////////////////////////////////////////////////////////
// Component Setup Helpers
////////////////////////////////////////////////////////////////////////////////
// Create top buttons.
private void setupTopButtons() {
// Show General Display Information
GuiMenuTopButton playerTab = new GuiMenuTopButton(-10, guiLeft + 4, guiTop - 10, playerName);
@@ -130,6 +131,8 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
GuiMenuTopButton btnTransport = new GuiMenuTopButton(12, btnDialog.xPosition + btnDialog.getWidth(), guiTop - 10, "global.transport");
GuiMenuTopButton btnBank = new GuiMenuTopButton(13, btnTransport.xPosition + btnTransport.getWidth(), guiTop - 10, "global.banks");
GuiMenuTopButton btnFaction = new GuiMenuTopButton(14, btnBank.xPosition + btnBank.getWidth(), guiTop - 10, "menu.factions");
GuiMenuTopButton btnMagic = new GuiMenuTopButton(15, btnFaction.xPosition + btnFaction.getWidth(), guiTop - 10, "menu.magics");
// Close button.
GuiMenuTopButton close = new GuiMenuTopButton(-5, guiLeft + xSize - 22, guiTop - 10, "X");
@@ -139,6 +142,7 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
btnTransport.active = (currentTab == 12);
btnBank.active = (currentTab == 13);
btnFaction.active = (currentTab == 14);
btnMagic.active = (currentTab == 15);
addTopButton(playerTab);
addTopButton(btnQuest);
@@ -146,10 +150,10 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
addTopButton(btnTransport);
addTopButton(btnBank);
addTopButton(btnFaction);
addTopButton(btnMagic);
addTopButton(close);
}
// Helper to ensure scroll exists.
private GuiCustomScroll ensureScroll(GuiCustomScroll scroll, int id) {
if (scroll == null) {
scroll = new GuiCustomScroll(this, id, 0);
@@ -157,7 +161,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
return scroll;
}
// Helper to update a text field's position and width.
private void updateComponentPosition(int fieldId, int newX, int newWidth) {
GuiNpcTextField tf = getTextField(fieldId);
if (tf != null) {
@@ -166,7 +169,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
// Helper to update a label's x position.
private void updateLabelPosition(int labelId, int newX) {
GuiNpcLabel lbl = getLabel(labelId);
if (lbl != null) {
@@ -177,7 +179,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
////////////////////////////////////////////////////////////////////////////////
// initGui() & Tab Initialization
////////////////////////////////////////////////////////////////////////////////
@Override
public void initGui() {
super.initGui();
@@ -185,12 +186,11 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
if (currentTab == 10 || currentTab == 11 || currentTab == 12) {
addButton(new GuiToggleButton(20, guiLeft + xSize - 102, guiTop + 10, viewMode == 0));
((GuiToggleButton) getButton(20)).setTextureOff(specialIcons).setTextureOffPos( 16, 0);
((GuiToggleButton) getButton(20)).setIconTexture(specialIcons).setIconPos( 16, 16, 16, 0 );
((GuiToggleButton) getButton(20)).setTextureOff(specialIcons).setTextureOffPos(16, 0);
((GuiToggleButton) getButton(20)).setIconTexture(specialIcons).setIconPos(16, 16, 16, 0);
}
guiTop += 7;
// Initialize components based on current tab.
switch (currentTab) {
case 10:
initQuestTab();
@@ -205,12 +205,17 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
case 14:
initSingleTab();
break;
case 15:
initMagicTab();
if (magicAllScroll != null) {
magicAllScroll.setList(new ArrayList<>(this.availableMagicElements.keySet()));
}
break;
}
// Delete button.
addButton(new GuiNpcButton(30, guiLeft + xSize - 60, guiTop + 10 - 7, 50, 20, "gui.remove"));
if(currentTab != 15)
addButton(new GuiNpcButton(30, guiLeft + xSize - 60, guiTop + 10 - 7, 50, 20, "gui.remove"));
}
// ----- Quest Tab Initialization -----
private void initQuestTab() {
int paddedLeft = getPaddedLeft();
int paddedRight = getPaddedRight();
@@ -222,7 +227,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
dividerOffset1 = (availableWidth - 2 * dividerWidth) / 3;
dividerOffset2 = dividerOffset1 + dividerWidth + (availableWidth - 2 * dividerWidth) / 3;
}
// Quest Category Scroll.
questCatScroll = ensureScroll(questCatScroll, 0);
questCatScroll.guiLeft = paddedLeft;
questCatScroll.guiTop = guiTop + scrollTopOffset;
@@ -233,7 +237,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
addScroll(questCatScroll);
addLabel(new GuiNpcLabel(1000, "Categories", paddedLeft, guiTop + 15, CustomNpcResourceListener.DefaultTextColor));
// Quest Finished Scroll.
questFinishedScroll = ensureScroll(questFinishedScroll, 1);
questFinishedScroll.guiLeft = paddedLeft + dividerOffset1 + dividerWidth;
questFinishedScroll.guiTop = guiTop + scrollTopOffset;
@@ -244,7 +247,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
addScroll(questFinishedScroll);
addLabel(new GuiNpcLabel(1001, "Finished", paddedLeft + dividerOffset1 + dividerWidth, guiTop + 15, CustomNpcResourceListener.DefaultTextColor));
// Quest Active Scroll.
questActiveScroll = ensureScroll(questActiveScroll, 2);
questActiveScroll.guiLeft = paddedLeft + dividerOffset2 + dividerWidth;
questActiveScroll.guiTop = guiTop + scrollTopOffset;
@@ -255,7 +257,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
addScroll(questActiveScroll);
addLabel(new GuiNpcLabel(1002, "Active", paddedLeft + dividerOffset2 + dividerWidth, guiTop + 15, CustomNpcResourceListener.DefaultTextColor));
// Text Fields.
addTextField(new GuiNpcTextField(55, this, fontRendererObj, paddedLeft, getTextFieldY(), dividerOffset1, textFieldHeight, questCatSearch));
addTextField(new GuiNpcTextField(56, this, fontRendererObj, paddedLeft + dividerOffset1 + dividerWidth, getTextFieldY(), dividerOffset2 - dividerOffset1 - dividerWidth, textFieldHeight, questFinishedSearch));
addTextField(new GuiNpcTextField(57, this, fontRendererObj, paddedLeft + dividerOffset2 + dividerWidth, getTextFieldY(), paddedRight - (paddedLeft + dividerOffset2 + dividerWidth), textFieldHeight, questActiveSearch));
@@ -286,13 +287,12 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
// ----- Dialog Tab Initialization -----
private void initDialogTab() {
int paddedLeft = getPaddedLeft();
int availableWidth = getAvailableWidth();
int scrollHeight = getScrollHeight();
if (viewMode == 0) { // Categorical: 2 scrolls.
if (viewMode == 0) {
if (!isResizing) {
dividerOffset1 = (availableWidth - dividerWidth) / 2;
}
@@ -316,7 +316,7 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
addTextField(new GuiNpcTextField(55, this, fontRendererObj, paddedLeft, getTextFieldY(), dividerOffset1, textFieldHeight, dialogCatSearch));
addTextField(new GuiNpcTextField(56, this, fontRendererObj, paddedLeft + dividerOffset1 + dividerWidth, getTextFieldY(), availableWidth - dividerOffset1 - dividerWidth, textFieldHeight, dialogReadSearch));
} else { // Compact: 1 scroll (no divider).
} else {
dialogCompactScroll = ensureScroll(dialogCompactScroll, 5);
dialogCompactScroll.guiLeft = paddedLeft;
dialogCompactScroll.guiTop = guiTop + scrollTopOffset;
@@ -329,13 +329,12 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
// ----- Transport Tab Initialization -----
private void initTransportTab() {
int paddedLeft = getPaddedLeft();
int availableWidth = getAvailableWidth();
int scrollHeight = getScrollHeight();
if (viewMode == 0) { // Categorical: 2 scrolls.
if (viewMode == 0) {
if (!isResizing) {
dividerOffset1 = (availableWidth - dividerWidth) / 2;
}
@@ -359,7 +358,7 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
addTextField(new GuiNpcTextField(60, this, fontRendererObj, paddedLeft, getTextFieldY(), dividerOffset1, textFieldHeight, transCatSearch));
addTextField(new GuiNpcTextField(61, this, fontRendererObj, paddedLeft + dividerOffset1 + dividerWidth, getTextFieldY(), availableWidth - dividerOffset1 - dividerWidth, textFieldHeight, transLocSearch));
} else { // Compact: 1 scroll (no divider).
} else {
transCompactScroll = ensureScroll(transCompactScroll, 5);
transCompactScroll.guiLeft = paddedLeft;
transCompactScroll.guiTop = guiTop + scrollTopOffset;
@@ -372,7 +371,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
// ----- Single Tab Initialization (Bank/Faction) -----
private void initSingleTab() {
int paddedLeft = getPaddedLeft();
int availableWidth = getAvailableWidth();
@@ -395,10 +393,88 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
addTextField(new GuiNpcTextField(70, this, fontRendererObj, paddedLeft, getTextFieldY(), availableWidth, textFieldHeight, singleSearch));
}
private void initMagicTab() {
int paddedLeft = getPaddedLeft();
int availableWidth = getAvailableWidth();
int scrollHeight = getScrollHeight();
int localDividerOffset = (availableWidth - dividerWidth) / 2;
// Left scroll: displays all available magic elements.
magicAllScroll = ensureScroll(magicAllScroll, 100);
magicAllScroll.guiLeft = paddedLeft;
magicAllScroll.guiTop = guiTop + scrollTopOffset;
magicAllScroll.setSize(localDividerOffset - 20, scrollHeight);
magicAllScroll.setList(new ArrayList<>(availableMagicElements.keySet()));
magicAllScroll.selected = -1;
addScroll(magicAllScroll);
addLabel(new GuiNpcLabel(5000, "menu.magics", paddedLeft, guiTop + 15, CustomNpcResourceListener.DefaultTextColor));
// Right scroll: displays currently selected magics (from magicData).
magicSelectedScroll = ensureScroll(magicSelectedScroll, 101);
magicSelectedScroll.guiLeft = 20 + paddedLeft + localDividerOffset + dividerWidth;
magicSelectedScroll.guiTop = guiTop + scrollTopOffset;
magicSelectedScroll.setSize(availableWidth - localDividerOffset - dividerWidth - 20, scrollHeight);
List<String> selectedList = new ArrayList<>();
for (String name : availableMagicElements.keySet()) {
int id = availableMagicElements.get(name);
if (magicData.hasMagic(id)) {
selectedList.add(name);
}
}
magicSelectedScroll.setList(selectedList);
magicSelectedScroll.selected = -1;
addScroll(magicSelectedScroll);
addLabel(new GuiNpcLabel(5001, "Current Magic", paddedLeft + localDividerOffset + dividerWidth + 20, guiTop + 15, CustomNpcResourceListener.DefaultTextColor));
// Arrow buttons for adding and removing magic entries.
int arrowWidth = 30, arrowHeight = 20;
int arrowX = paddedLeft + localDividerOffset + (dividerWidth - arrowWidth) / 2;
int addY = guiTop + scrollTopOffset + scrollHeight / 2 - arrowHeight - 2;
int removeY = guiTop + scrollTopOffset + scrollHeight / 2 + 2;
addButton(new GuiNpcButton(70, arrowX, addY, arrowWidth, arrowHeight, ">"));
addButton(new GuiNpcButton(71, arrowX, removeY, arrowWidth, arrowHeight, "<"));
// Standardize button: evenly distribute 1.0 amongst all selected magics.
int stdWidth = 80, stdHeight = 20;
int stdX = paddedLeft;
int stdY = guiTop + ySize - stdHeight - 6;
addButton(new GuiNpcButton(72, stdX, stdY + 4, stdWidth, stdHeight, "Standardize"));
// If a magic is selected in the right scroll, add text fields for split and damage.
int tfY = getTextFieldY();
addLabel(new GuiNpcLabel(5002, "magic.split", paddedLeft + localDividerOffset + dividerWidth - 60, tfY + 5, CustomNpcResourceListener.DefaultTextColor));
splitField = new GuiNpcTextField(73, this, fontRendererObj, paddedLeft + localDividerOffset + dividerWidth, tfY, 45, textFieldHeight, "");
addLabel(new GuiNpcLabel(5003, "magic.bonus", paddedLeft + localDividerOffset + dividerWidth + 80, tfY + 5, CustomNpcResourceListener.DefaultTextColor));
damageField = new GuiNpcTextField(74, this, fontRendererObj, paddedLeft + localDividerOffset + dividerWidth + 200 - 45, tfY, 45, textFieldHeight, "");
splitField.setFloatsOnly();
damageField.setFloatsOnly();
splitField.setMinMaxDefaultFloat(0, 1000000000, 0);
damageField.setMinMaxDefaultFloat(0, 1000000000, 0);
splitField.enabled = false;
damageField.enabled = false;
addTextField(splitField);
addTextField(damageField);
if(magicSelectedScroll.hasSelected()){
String sel = magicSelectedScroll.getSelected();
int id = availableMagicElements.get(sel);
if (magicData.hasMagic(id)) {
splitField.setText(magicData.getMagicSplit(id) + "");
damageField.setText(magicData.getMagicDamage(id) + "");
splitField.enabled = true;
damageField.enabled = true;
}
}
updateMagicSelectedList();
}
////////////////////////////////////////////////////////////////////////////////
// Drawing Helpers
////////////////////////////////////////////////////////////////////////////////
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
super.drawScreen(mouseX, mouseY, partialTicks);
@@ -415,12 +491,10 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glEnable(GL11.GL_DEPTH_TEST);
// In compact mode for Quests, draw divider between the two scrolls.
if (currentTab == 10 && viewMode != 0 && !hasSubGui()) {
int dividerX = paddedLeft + dividerOffset1;
drawRect(dividerX + widthPadding, guiTop + scrollTopOffset + paddingTopBottom, dividerX + dividerWidth - widthPadding, guiTop + scrollTopOffset + scrollHeight - paddingTopBottom, 0xFF707070);
}
// In categorical mode for Quest, draw both dividers.
if (currentTab == 10 && viewMode == 0 && !hasSubGui()) {
int dividerX1 = paddedLeft + dividerOffset1;
int dividerX2 = paddedLeft + dividerOffset2;
@@ -437,7 +511,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
////////////////////////////////////////////////////////////////////////////////
// Mouse & Resizing Handlers
////////////////////////////////////////////////////////////////////////////////
@Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
int hitMargin = 3;
@@ -447,7 +520,7 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
int availableWidth = getAvailableWidth();
if (!hasSubGui() && mouseY >= regionTop && mouseY <= regionBottom) {
if (viewMode == 0) {
if (currentTab == 10) { // Quest categorical: 3 scrolls.
if (currentTab == 10) {
int dividerX1 = paddedLeft + dividerOffset1;
int dividerX2 = paddedLeft + dividerOffset2;
if (mouseX >= dividerX1 - hitMargin && mouseX <= dividerX1 + dividerWidth + hitMargin) {
@@ -470,8 +543,8 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
return;
}
}
} else { // Compact mode.
if (currentTab == 10) { // Quest compact: 2 scrolls.
} else {
if (currentTab == 10) {
int defaultWidth = (availableWidth - dividerWidth) / 2;
if (!isResizing) dividerOffset1 = defaultWidth;
int dividerX = paddedLeft + dividerOffset1;
@@ -482,7 +555,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
return;
}
}
// Dialog/Transport compact have only one scroll => no divider.
}
}
super.mouseClicked(mouseX, mouseY, mouseButton);
@@ -496,9 +568,8 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
if (isResizing) {
int dx = mouseX - initialDragX;
initialDragX = mouseX;
// Handle Quest tab resizing.
if (currentTab == 10) {
if (viewMode == 0) { // Categorical (3 scrolls)
if (viewMode == 0) {
if (resizingDivider == 1) {
dividerOffset1 += dx;
int maxOffset = dividerOffset2 - dividerWidth - minScrollWidth;
@@ -527,7 +598,7 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
updateLabelPosition(1001, paddedLeft + dividerOffset1 + dividerWidth);
updateLabelPosition(1002, paddedLeft + dividerOffset2 + dividerWidth);
}
} else { // Compact mode for Quests (2 scrolls)
} else {
if (resizingDivider == 1) {
dividerOffset1 += dx;
dividerOffset1 = clamp(dividerOffset1, minScrollWidth, availableWidth - dividerWidth - minScrollWidth);
@@ -541,7 +612,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
} else if ((currentTab == 11 || currentTab == 12) && viewMode == 0) {
// For Dialog and Transport in categorical mode.
dividerOffset1 += dx;
dividerOffset1 = clamp(dividerOffset1, minScrollWidth, availableWidth - minScrollWidth);
if (currentTab == 11) {
@@ -577,7 +647,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
super.mouseMovedOrUp(mouseX, mouseY, state);
}
// Simple clamp helper.
private int clamp(int value, int min, int max) {
if (value < min)
return min;
@@ -589,7 +658,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
////////////////////////////////////////////////////////////////////////////////
// Key & Search Field Handling
////////////////////////////////////////////////////////////////////////////////
@Override
public void keyTyped(char c, int i) {
super.keyTyped(c, i);
@@ -616,7 +684,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
// Update quest search fields (categorical mode).
private void updateQuestSearchField(int catFieldId, int finishedFieldId, int activeFieldId) {
GuiNpcTextField tf = getTextField(catFieldId);
if (tf != null && tf.isFocused()) {
@@ -659,7 +726,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
// Update quest search fields in compact mode.
private void updateQuestSearchFieldCompact(int finishedFieldId, int activeFieldId) {
GuiNpcTextField tf = getTextField(finishedFieldId);
if (tf != null && tf.isFocused()) {
@@ -681,7 +747,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
// Update dialog search fields (categorical).
private void updateDialogSearchField(int catFieldId, int readFieldId) {
GuiNpcTextField tf = getTextField(catFieldId);
if (tf != null && tf.isFocused()) {
@@ -711,7 +776,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
// Update dialog search fields (compact).
private void updateDialogSearchFieldCompact(int fieldId) {
GuiNpcTextField tf = getTextField(fieldId);
if (tf != null && tf.isFocused()) {
@@ -724,7 +788,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
// Update transport search fields (categorical).
private void updateTransportSearchField(int catFieldId, int locFieldId) {
GuiNpcTextField tf = getTextField(catFieldId);
if (tf != null && tf.isFocused()) {
@@ -754,7 +817,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
// Update transport search fields (compact).
private void updateTransportSearchFieldCompact(int fieldId) {
GuiNpcTextField tf = getTextField(fieldId);
if (tf != null && tf.isFocused()) {
@@ -767,7 +829,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
// Update search field for single scroll (Bank/Faction).
private void updateSingleSearchField(int fieldId) {
GuiNpcTextField tf = getTextField(fieldId);
if (tf != null && tf.isFocused()) {
@@ -780,7 +841,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
// Standard filtering helpers.
private List<String> filterList(HashMap<String, Integer> data, String search) {
List<String> list = new ArrayList<>();
for (String key : data.keySet()) {
@@ -808,42 +868,35 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
////////////////////////////////////////////////////////////////////////////////
// Action Handling
////////////////////////////////////////////////////////////////////////////////
@Override
public void actionPerformed(GuiButton button) {
// Close if the "X" button was clicked.
if (button.id == -5) {
close();
return;
}
// Tab switching.
if (button.id >= 10 && button.id <= 14) {
if (button.id >= 10 && button.id <= 15) {
currentTab = button.id;
initGui(); // Reinitialize components using stored data.
initGui();
return;
}
// Mode toggle.
if (button.id == 20) {
viewMode = (viewMode == 0) ? 1 : 0;
initGui();
return;
}
// Delete button.
if (button.id == 30) {
Integer selectedID = null;
EnumPlayerData tabType = null;
// Quest tab
if (currentTab == 10) {
if (viewMode == 0) { // Categorical mode
if (viewMode == 0) {
if (questCatScroll.getSelected() == null)
return;
// Use category + selection key.
if (questActiveScroll.getSelected() != null) {
selectedID = removeSelection(questActiveScroll, questActiveData, questCatScroll.getSelected());
} else if (questFinishedScroll.getSelected() != null) {
selectedID = removeSelection(questFinishedScroll, questFinishedData, questCatScroll.getSelected());
}
} else { // Compact mode: key is just the selection.
} else {
if (questActiveScroll.getSelected() != null) {
selectedID = removeSelection(questActiveScroll, questActiveData, null);
} else if (questFinishedScroll.getSelected() != null) {
@@ -851,9 +904,7 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
tabType = EnumPlayerData.Quest;
}
// Dialog tab
else if (currentTab == 11) {
} else if (currentTab == 11) {
if (viewMode == 0) {
if (dialogReadScroll.getSelected() != null && dialogCatScroll.getSelected() != null) {
selectedID = removeSelection(dialogReadScroll, dialogReadData, dialogCatScroll.getSelected());
@@ -864,9 +915,7 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
tabType = EnumPlayerData.Dialog;
}
// Transport tab
else if (currentTab == 12) {
} else if (currentTab == 12) {
if (viewMode == 0) {
if (transLocScroll.getSelected() != null && transCatScroll.getSelected() != null) {
selectedID = removeSelection(transLocScroll, transLocData, transCatScroll.getSelected());
@@ -877,36 +926,82 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
tabType = EnumPlayerData.Transport;
}
// Bank tab
else if (currentTab == 13) {
} else if (currentTab == 13) {
if (singleScroll.getSelected() != null) {
selectedID = removeSelection(singleScroll, bankData, null);
}
tabType = EnumPlayerData.Bank;
}
// Faction tab
else if (currentTab == 14) {
} else if (currentTab == 14) {
if (singleScroll.getSelected() != null) {
selectedID = removeSelection(singleScroll, factionData, null);
}
tabType = EnumPlayerData.Factions;
}
if (selectedID != null) {
PacketClient.sendClient(new PlayerDataRemoveInfoPacket(playerName, tabType, selectedID));
PacketClient.sendClient(new PlayerDataDeleteInfoPacket(playerName, tabType, selectedID));
}
}
if (currentTab == 15) {
// Add
if (button.id == 70) {
if (magicAllScroll != null && magicAllScroll.getSelected() != null) {
String name = magicAllScroll.getSelected();
int id = availableMagicElements.get(name);
if (!magicData.hasMagic(id)) {
magicData.addMagic(id, 0, 0);
}
updateMagicSelectedList();
}
saveMagicCompound();
} else if (button.id == 71) {
// Remove
if (magicSelectedScroll != null && magicSelectedScroll.getSelected() != null) {
String name = magicSelectedScroll.getSelected();
int id = availableMagicElements.get(name);
if (magicData.hasMagic(id)) {
magicData.removeMagic(id);
PacketClient.sendClient(new PlayerDataDeleteInfoPacket(playerName, EnumPlayerData.Magic, id));
}
updateMagicSelectedList();
if (splitField != null) {
splitField.setText("");
splitField.enabled = false;
}
if (damageField != null) {
damageField.setText("");
damageField.enabled = false;
}
}
} else if (button.id == 72) {
int count = magicData.getMagics().size();
if (count > 0) {
float stdSplit = 1.0f / count;
for (Integer key : magicData.getMagics().keySet()) {
noppes.npcs.controllers.data.MagicEntry entry = magicData.getMagic(key);
if (entry != null) {
entry.split = stdSplit;
}
}
if (magicSelectedScroll != null && magicSelectedScroll.getSelected() != null && splitField != null) {
String name = magicSelectedScroll.getSelected();
int id = availableMagicElements.get(name);
if (magicData.hasMagic(id)) {
splitField.setText(magicData.getMagicSplit(id) + "");
}
}
}
saveMagicCompound();
}
}
super.actionPerformed(button);
}
private void saveMagicCompound(){
NBTTagCompound magicCompound = new NBTTagCompound();
magicData.writeToNBT(magicCompound);
PacketClient.sendClient(new PlayerDataSaveInfoPacket(playerName, EnumPlayerData.Magic, magicCompound));
}
/**
* Helper method that removes the selected entry from a scroll and its backing data.
*
* @param scroll The GuiCustomScroll in question.
* @param data The backing map holding keys and IDs.
* @param prefix If non-null and non-empty, the key is built as "prefix: " + scroll.getSelected(); otherwise,
* scroll.getSelected() is used.
* @return The ID of the removed item, or null if none was found.
*/
private Integer removeSelection(GuiCustomScroll scroll, Map<String, Integer> data, String prefix) {
if (scroll.getSelected() == null) return null;
String key = (prefix == null || prefix.isEmpty()) ? scroll.getSelected() : prefix + ": " + scroll.getSelected();
@@ -922,7 +1017,6 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
////////////////////////////////////////////////////////////////////////////////
// Data Setting Methods (IPlayerDataInfo)
////////////////////////////////////////////////////////////////////////////////
@Override
public void setQuestData(Map<String, Integer> questCategories, Map<String, Integer> questActive, Map<String, Integer> questFinished) {
this.questCatData = new HashMap<>(questCategories);
@@ -967,9 +1061,11 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
}
}
////////////////////////////////////////////////////////////////////////////////
// Custom Scroll Click Handling
////////////////////////////////////////////////////////////////////////////////
@Override
public void setMagicData(MagicData magicData) {
this.magicData = magicData;
updateMagicSelectedList();
}
@Override
public void customScrollClicked(int i, int j, int k, GuiCustomScroll guiCustomScroll) {
@@ -1005,5 +1101,73 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
} else if (guiCustomScroll == questFinishedScroll) {
questActiveScroll.selected = -1;
}
if (guiCustomScroll == magicSelectedScroll) {
if (magicSelectedScroll.getSelected() != null) {
String name = magicSelectedScroll.getSelected();
int id = availableMagicElements.get(name);
if (magicData.hasMagic(id)) {
if (splitField != null) {
splitField.setText(magicData.getMagicSplit(id) + "");
splitField.enabled = true;
}
if (damageField != null) {
damageField.setText(magicData.getMagicDamage(id) + "");
damageField.enabled = true;
}
}
}
}
}
@Override
public void customScrollDoubleClicked(String selection, GuiCustomScroll scroll) {}
@Override
public void unFocused(GuiNpcTextField textField) {
if (currentTab == 15 && magicSelectedScroll != null && magicSelectedScroll.getSelected() != null) {
String name = magicSelectedScroll.getSelected();
int id = availableMagicElements.get(name);
if (magicData.hasMagic(id)) {
if (textField.id == 73) {
try {
float split = Float.parseFloat(textField.getText());
magicData.getMagic(id).split = split;
} catch(NumberFormatException e) { }
} else if (textField.id == 74) {
try {
float dmg = Float.parseFloat(textField.getText());
magicData.getMagic(id).damage = dmg;
} catch(NumberFormatException e) { }
}
}
saveMagicCompound();
}
}
// Helper to update the right scroll list in the Magic Tab.
private void updateMagicSelectedList() {
List<String> selected = new ArrayList<>();
for (String name : availableMagicElements.keySet()) {
int id = availableMagicElements.get(name);
if (magicData.hasMagic(id)) {
selected.add(name);
}
}
if(magicSelectedScroll != null)
magicSelectedScroll.setList(selected);
}
@Override
public void setData(Vector<String> list, HashMap<String, Integer> data, EnumScrollData type) {
if (type == EnumScrollData.MAGIC) {
this.availableMagicElements = new HashMap<>();
for (String name : list) {
int id = data.get(name);
this.availableMagicElements.put(name, id);
}
}
}
@Override
public void setSelected(String selected) {}
}
@@ -1,5 +1,7 @@
package noppes.npcs.client.gui.util;
import noppes.npcs.controllers.data.MagicData;
import java.util.Map;
public interface IPlayerDataInfo {
@@ -8,4 +10,6 @@ public interface IPlayerDataInfo {
void setTransportData(Map<String, Integer> transportCategories, Map<String, Integer> transportLocations);
void setBankData(Map<String, Integer> bankData);
void setFactionData(Map<String, Integer> factionData);
void setMagicData(MagicData magicData);
}
@@ -1,5 +1,5 @@
package noppes.npcs.constants;
public enum EnumPlayerData {
Players,Quest,Dialog,Transport,Bank,Factions
Players,Quest,Dialog,Transport,Bank,Factions,Magic
}