From 6b63d89d5545da3b5edd964960e2b39b15bc316e Mon Sep 17 00:00:00 2001 From: Kam Date: Mon, 7 Jul 2025 05:22:49 -0400 Subject: [PATCH 1/8] Reset player GUI state on respawn --- src/main/java/noppes/npcs/ServerEventsHandler.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/noppes/npcs/ServerEventsHandler.java b/src/main/java/noppes/npcs/ServerEventsHandler.java index f8333cc2b..5b98bdca4 100644 --- a/src/main/java/noppes/npcs/ServerEventsHandler.java +++ b/src/main/java/noppes/npcs/ServerEventsHandler.java @@ -285,6 +285,16 @@ public class ServerEventsHandler { } } + @SubscribeEvent + public void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) { + if (event.player == null || event.player.worldObj == null || event.player.worldObj.isRemote) + return; + + PlayerData data = PlayerData.get(event.player); + data.setGUIOpen(false); + data.editingNpc = null; + } + private void doExcalibur(EntityPlayer player, EntityLivingBase entity) { ItemStack item = player.getCurrentEquippedItem(); if (item == null || item.getItem() != CustomItems.excalibur) From ce0f5b7a78f09880b06b011ec6ae7fd79cd9175c Mon Sep 17 00:00:00 2001 From: Kam Date: Mon, 7 Jul 2025 05:37:31 -0400 Subject: [PATCH 2/8] Improve biome detection imports --- .../npcs/client/gui/SubGuiNpcBiomes.java | 19 +++++++++++++++++++ .../java/noppes/npcs/scripted/NpcAPI.java | 10 ++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcBiomes.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcBiomes.java index 76b5d8150..8c262cb79 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiNpcBiomes.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiNpcBiomes.java @@ -2,6 +2,7 @@ package noppes.npcs.client.gui; import net.minecraft.client.gui.GuiButton; import net.minecraft.world.biome.BiomeGenBase; +import net.minecraftforge.common.BiomeDictionary; import noppes.npcs.client.gui.util.GuiCustomScroll; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.GuiNpcLabel; @@ -9,7 +10,9 @@ import noppes.npcs.client.gui.util.SubGuiInterface; import noppes.npcs.controllers.data.SpawnData; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class SubGuiNpcBiomes extends SubGuiInterface { private SpawnData data; @@ -45,7 +48,15 @@ public class SubGuiNpcBiomes extends SubGuiInterface { addLabel(new GuiNpcLabel(2, "spawning.spawningBiomes", guiLeft + 200, guiTop + 4)); List biomes = new ArrayList(); + Set allBiomes = new HashSet(); + for (BiomeDictionary.Type type : BiomeDictionary.Type.values()) { + allBiomes.addAll(BiomeDictionary.getBiomesForType(type)); + } for (BiomeGenBase base : BiomeGenBase.getBiomeGenArray()) { + if (base != null) + allBiomes.add(base); + } + for (BiomeGenBase base : allBiomes) { if (base != null && base.biomeName != null && !data.biomes.contains(base.biomeName)) { biomes.add(base.biomeName); } @@ -82,7 +93,15 @@ public class SubGuiNpcBiomes extends SubGuiInterface { } if (button.id == 3) { data.biomes.clear(); + Set allBiomes = new HashSet(); + for (BiomeDictionary.Type type : BiomeDictionary.Type.values()) { + allBiomes.addAll(BiomeDictionary.getBiomesForType(type)); + } for (BiomeGenBase base : BiomeGenBase.getBiomeGenArray()) { + if (base != null) + allBiomes.add(base); + } + for (BiomeGenBase base : allBiomes) { if (base != null) { data.biomes.add(base.biomeName); } diff --git a/src/main/java/noppes/npcs/scripted/NpcAPI.java b/src/main/java/noppes/npcs/scripted/NpcAPI.java index 76a9936c2..d19c809bf 100644 --- a/src/main/java/noppes/npcs/scripted/NpcAPI.java +++ b/src/main/java/noppes/npcs/scripted/NpcAPI.java @@ -32,6 +32,8 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraft.world.biome.BiomeGenBase; +import net.minecraftforge.common.BiomeDictionary; +import net.minecraftforge.common.BiomeDictionary.Type; import noppes.npcs.CustomNpcs; import noppes.npcs.NoppesUtilServer; import noppes.npcs.api.*; @@ -277,7 +279,15 @@ public class NpcAPI extends AbstractNpcAPI { @Override public String[] getAllBiomeNames() { List biomes = new ArrayList<>(); + Set allBiomes = new HashSet(); + for (Type type : BiomeDictionary.Type.values()) { + allBiomes.addAll(BiomeDictionary.getBiomesForType(type)); + } for (BiomeGenBase base : BiomeGenBase.getBiomeGenArray()) { + if (base != null) + allBiomes.add(base); + } + for (BiomeGenBase base : allBiomes) { if (base != null && base.biomeName != null) { biomes.add(base.biomeName); } From 6bad9163a0d48db95434f062bf2f332d66392598 Mon Sep 17 00:00:00 2001 From: Kam Date: Mon, 7 Jul 2025 05:50:29 -0400 Subject: [PATCH 3/8] Avoid saving profile on every login --- .../java/kamkeel/npcs/controllers/ProfileController.java | 8 +++++++- .../kamkeel/npcs/controllers/data/profile/Profile.java | 3 ++- src/main/java/noppes/npcs/util/CustomNPCsThreader.java | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/kamkeel/npcs/controllers/ProfileController.java b/src/main/java/kamkeel/npcs/controllers/ProfileController.java index a8f2bf91c..77ee89578 100644 --- a/src/main/java/kamkeel/npcs/controllers/ProfileController.java +++ b/src/main/java/kamkeel/npcs/controllers/ProfileController.java @@ -97,6 +97,7 @@ public class ProfileController implements IProfileHandler { if (player == null) return; Profile profile; + boolean profileModified = false; if (activeProfiles.containsKey(player.getUniqueID())) { profile = activeProfiles.get(player.getUniqueID()); profile.player = player; @@ -109,6 +110,7 @@ public class ProfileController implements IProfileHandler { profile.getSlots().put(0, defaultSlot); profile.currentSlotId = 0; saveSlotData(player); + profileModified = true; } if (!profile.getSlots().containsKey(profile.currentSlotId)) { profile.currentSlotId = 0; @@ -117,7 +119,10 @@ public class ProfileController implements IProfileHandler { activeProfiles.put(player.getUniqueID(), profile); loadSlotData(player); verifySlotQuests(profile.player); - save(player, profile); + // Avoid saving on every login; only persist if the profile was + // modified (e.g. default slot creation). + if (profileModified) + save(player, profile); } } @@ -341,6 +346,7 @@ public class ProfileController implements IProfileHandler { return ProfileOperation.error(MSG_CANNOT_CLONE_CURRENT); } if (temporary) { + // Use a negative ID for temporary slots so they are never saved to disk. destinationSlotId = getNextAvailableTempSlot(profile); } else { if (destinationSlotId <= 0) { diff --git a/src/main/java/kamkeel/npcs/controllers/data/profile/Profile.java b/src/main/java/kamkeel/npcs/controllers/data/profile/Profile.java index 857d169f6..04ce9b66c 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/profile/Profile.java +++ b/src/main/java/kamkeel/npcs/controllers/data/profile/Profile.java @@ -81,7 +81,8 @@ public class Profile implements IProfile { compound.setInteger("CurrentSlotId", currentSlotId); NBTTagCompound slotsCompound = new NBTTagCompound(); for (Map.Entry entry : slots.entrySet()) { - // Save only non-temporary slots. + // Temporary slots (typically using negative IDs) are kept in memory + // only and skipped here so they never persist to disk. if (entry.getValue().isTemporary()) continue; slotsCompound.setTag(String.valueOf(entry.getKey()), entry.getValue().toNBT()); diff --git a/src/main/java/noppes/npcs/util/CustomNPCsThreader.java b/src/main/java/noppes/npcs/util/CustomNPCsThreader.java index 3019fb5b1..6ed04819d 100644 --- a/src/main/java/noppes/npcs/util/CustomNPCsThreader.java +++ b/src/main/java/noppes/npcs/util/CustomNPCsThreader.java @@ -4,5 +4,10 @@ import java.util.concurrent.Executor; import java.util.concurrent.Executors; public class CustomNPCsThreader { + /** + * Executor used for all asynchronous profile and player data saves. + * It is single-threaded so submitted tasks run sequentially and the + * save order for a given player is preserved. + */ public static final Executor customNPCThread = Executors.newSingleThreadExecutor(); } From 23b55c343fc19b8b32d59be01340802091fd4d36 Mon Sep 17 00:00:00 2001 From: Kam Date: Mon, 7 Jul 2025 05:56:26 -0400 Subject: [PATCH 4/8] To Dev --- src/api | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api b/src/api index 14f7bd3dd..9f85df41e 160000 --- a/src/api +++ b/src/api @@ -1 +1 @@ -Subproject commit 14f7bd3dd402498e3217aca8d3de26f53340169b +Subproject commit 9f85df41e02418c825a24ff82b764b10598088d2 From db55dee0480ed732012e46b4a11cfe1bf1bf3d10 Mon Sep 17 00:00:00 2001 From: Kam Date: Mon, 7 Jul 2025 05:58:38 -0400 Subject: [PATCH 5/8] Fix Respawn Event Issue --- src/main/java/noppes/npcs/ServerEventsHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/noppes/npcs/ServerEventsHandler.java b/src/main/java/noppes/npcs/ServerEventsHandler.java index 5b98bdca4..c5b92db0a 100644 --- a/src/main/java/noppes/npcs/ServerEventsHandler.java +++ b/src/main/java/noppes/npcs/ServerEventsHandler.java @@ -286,7 +286,7 @@ public class ServerEventsHandler { } @SubscribeEvent - public void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) { + public void onPlayerRespawn(cpw.mods.fml.common.gameevent.PlayerEvent.PlayerRespawnEvent event) { if (event.player == null || event.player.worldObj == null || event.player.worldObj.isRemote) return; From db899fe479af11da49ee9dbd186a66ce01fbb67b Mon Sep 17 00:00:00 2001 From: Kam Date: Mon, 7 Jul 2025 06:06:05 -0400 Subject: [PATCH 6/8] Better Collection Handling --- .../java/noppes/npcs/client/gui/SubGuiNpcBiomes.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcBiomes.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcBiomes.java index 8c262cb79..95c11fd27 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiNpcBiomes.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiNpcBiomes.java @@ -9,10 +9,7 @@ import noppes.npcs.client.gui.util.GuiNpcLabel; import noppes.npcs.client.gui.util.SubGuiInterface; import noppes.npcs.controllers.data.SpawnData; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; public class SubGuiNpcBiomes extends SubGuiInterface { private SpawnData data; @@ -50,7 +47,7 @@ public class SubGuiNpcBiomes extends SubGuiInterface { List biomes = new ArrayList(); Set allBiomes = new HashSet(); for (BiomeDictionary.Type type : BiomeDictionary.Type.values()) { - allBiomes.addAll(BiomeDictionary.getBiomesForType(type)); + Collections.addAll(allBiomes, BiomeDictionary.getBiomesForType(type)); } for (BiomeGenBase base : BiomeGenBase.getBiomeGenArray()) { if (base != null) @@ -95,7 +92,7 @@ public class SubGuiNpcBiomes extends SubGuiInterface { data.biomes.clear(); Set allBiomes = new HashSet(); for (BiomeDictionary.Type type : BiomeDictionary.Type.values()) { - allBiomes.addAll(BiomeDictionary.getBiomesForType(type)); + Collections.addAll(allBiomes, BiomeDictionary.getBiomesForType(type)); } for (BiomeGenBase base : BiomeGenBase.getBiomeGenArray()) { if (base != null) From 9850e4b751125d341946f760c246a323840eb5f4 Mon Sep 17 00:00:00 2001 From: Kam Date: Mon, 7 Jul 2025 06:12:33 -0400 Subject: [PATCH 7/8] Update build.gradle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 755eef405..d7092be2b 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { id 'idea' } -version = "1.10.2.3" +version = "1.10.2" group= "kamkeel.customnpc-plus" archivesBaseName = "CustomNPC-Plus" From 9e6f341d77873e62eb90dc3e6e8383fd9ea50019 Mon Sep 17 00:00:00 2001 From: Kam Date: Mon, 7 Jul 2025 06:30:37 -0400 Subject: [PATCH 8/8] Fix biome collection bug and add spawn GUI tooltip --- .../java/noppes/npcs/client/gui/global/GuiNpcNaturalSpawns.java | 1 + src/main/java/noppes/npcs/scripted/NpcAPI.java | 2 +- src/main/resources/assets/customnpcs/lang/en_US.lang | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNpcNaturalSpawns.java b/src/main/java/noppes/npcs/client/gui/global/GuiNpcNaturalSpawns.java index ca5b7fe9e..aba615c0e 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNpcNaturalSpawns.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNpcNaturalSpawns.java @@ -66,6 +66,7 @@ public class GuiNpcNaturalSpawns extends GuiNPCInterface2 implements IGuiData, I addButton(new GuiNpcButton(4, guiLeft + 90, y - 5, 50, 20, "selectServer.edit")); addSlider(new GuiNpcSlider(this, 5, guiLeft + 4, y += 17, 180, 20, (float) this.spawn.itemWeight / 100)); + addExtra(new GuiHoverText(1, "spawning.naturalInfo", guiLeft + 188, y + 5)); this.spawnEntryScroll.guiLeft = guiLeft + 4; this.spawnEntryScroll.guiTop = y + 40; diff --git a/src/main/java/noppes/npcs/scripted/NpcAPI.java b/src/main/java/noppes/npcs/scripted/NpcAPI.java index d19c809bf..deadb8b6d 100644 --- a/src/main/java/noppes/npcs/scripted/NpcAPI.java +++ b/src/main/java/noppes/npcs/scripted/NpcAPI.java @@ -281,7 +281,7 @@ public class NpcAPI extends AbstractNpcAPI { List biomes = new ArrayList<>(); Set allBiomes = new HashSet(); for (Type type : BiomeDictionary.Type.values()) { - allBiomes.addAll(BiomeDictionary.getBiomesForType(type)); + Collections.addAll(allBiomes, BiomeDictionary.getBiomesForType(type)); } for (BiomeGenBase base : BiomeGenBase.getBiomeGenArray()) { if (base != null) diff --git a/src/main/resources/assets/customnpcs/lang/en_US.lang b/src/main/resources/assets/customnpcs/lang/en_US.lang index 92f6c1c8e..ad733fa6b 100644 --- a/src/main/resources/assets/customnpcs/lang/en_US.lang +++ b/src/main/resources/assets/customnpcs/lang/en_US.lang @@ -405,6 +405,7 @@ spawning.liquidSpawning=Spawns in Liquid spawning.airSpawning=Spawns in Air spawning.minHeight=Minimum Height spawning.maxHeight=Maximum Height +spawning.naturalInfo=Add at least one spawn entry and configure spawn options for the NPC to spawn naturally role.name=Role role.none=No Role