Impl. CustomNPC support with "custom names"

Version 1.17.2.6 .

Now, if a CustomNPC has a specific name, and an entry exist in the config with
the same custom name (as when one is set up with a name-tag and added with
"/tbm-edit custom"), then the custom config will be applied to that CustomNPC
entity.
This commit is contained in:
Stephen Seo 2022-09-02 19:20:06 +09:00
parent f58a1942ca
commit 8242e2ae01
9 changed files with 192 additions and 22 deletions

View file

@ -1,5 +1,10 @@
# Upcoming changes
# Version 1.17.2.6
Implemented getting EntityInfo for CustomNPCs that have the same name as a
"custom entry" in the "server\_config.entity" array in the config.
# Version 1.17.2.5
Refactored OtherModHandling.java to be more efficient when handling CustomNPCs

View file

@ -14,7 +14,7 @@ apply plugin: 'eclipse'
//apply plugin: 'maven-publish'
apply plugin: 'com.github.johnrengelman.shadow'
version = "1.17.2.5"
version = "1.17.2.6"
group = "com.burnedkirby.TurnBasedMinecraft"
archivesBaseName = "TurnBasedMinecraft"

View file

@ -151,7 +151,11 @@ public class BattleGui extends Screen {
for (Map.Entry<Integer, Combatant> e : TurnBasedMinecraftMod.proxy.getLocalBattle()
.getSideAEntrySet()) {
if (e.getValue().entity != null) {
addButton(new EntitySelectionButton(width / 4 - 60, y, 120, 20, e.getValue().entity.getName().getString(), e.getKey(), true, (button) -> {
String name = e.getValue().entity.getName().getString();
if (name.isEmpty()) {
name = "Unknown";
}
addButton(new EntitySelectionButton(width / 4 - 60, y, 120, 20, name, e.getKey(), true, (button) -> {
buttonActionEvent(button, ButtonAction.ATTACK_TARGET);
}));
} else {
@ -169,7 +173,11 @@ public class BattleGui extends Screen {
for (Map.Entry<Integer, Combatant> e : TurnBasedMinecraftMod.proxy.getLocalBattle()
.getSideBEntrySet()) {
if (e.getValue().entity != null) {
addButton(new EntitySelectionButton(width * 3 / 4 - 60, y, 120, 20, e.getValue().entity.getName().getString(), e.getKey(), false, (button) -> {
String name = e.getValue().entity.getName().getString();
if (name.isEmpty()) {
name = "Unknown";
}
addButton(new EntitySelectionButton(width * 3 / 4 - 60, y, 120, 20, name, e.getKey(), false, (button) -> {
buttonActionEvent(button, ButtonAction.ATTACK_TARGET);
}));
} else {

View file

@ -142,6 +142,14 @@ public class Battle
} catch(NullPointerException exception) {
entityInfo = null;
}
if (entityInfo == null) {
// Check if is CustomNPC with matching name entry.
try {
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getCustomEntityInfoReference(OtherModHandler.getCustomNPCName(e));
} catch(NullPointerException exception) {
entityInfo = null;
}
}
if(entityInfo == null)
{
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e);
@ -180,6 +188,14 @@ public class Battle
} catch(NullPointerException exception) {
entityInfo = null;
}
if (entityInfo == null) {
// Check if is CustomNPC with matching name entry.
try {
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getCustomEntityInfoReference(OtherModHandler.getCustomNPCName(e));
} catch(NullPointerException exception) {
entityInfo = null;
}
}
if(entityInfo == null)
{
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e);
@ -311,12 +327,20 @@ public class Battle
} catch(NullPointerException exception) {
entityInfo = null;
}
if (entityInfo == null) {
// Check if entity is CustomNPC entity.
try {
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getCustomEntityInfoReference(OtherModHandler.getCustomNPCName(e));
} catch(NullPointerException exception) {
entityInfo = null;
}
}
if(entityInfo == null)
{
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e);
}
if(entityInfo == null && !(e instanceof PlayerEntity) && TurnBasedMinecraftMod.proxy.isServerRunning())
if(isServer && entityInfo == null && !(e instanceof PlayerEntity) && TurnBasedMinecraftMod.proxy.isServerRunning())
{
return;
}
@ -374,12 +398,20 @@ public class Battle
} catch(NullPointerException exception) {
entityInfo = null;
}
if (entityInfo == null) {
// Check if entity is CustomNPC entity.
try {
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getCustomEntityInfoReference(OtherModHandler.getCustomNPCName(e));
} catch(NullPointerException exception) {
entityInfo = null;
}
}
if(entityInfo == null)
{
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e);
}
if(entityInfo == null && !(e instanceof PlayerEntity) && TurnBasedMinecraftMod.proxy.isServerRunning())
if(isServer && entityInfo == null && !(e instanceof PlayerEntity) && TurnBasedMinecraftMod.proxy.isServerRunning())
{
return;
}

View file

@ -61,6 +61,11 @@ public class BattleManager
} catch (NullPointerException e) {
receiverCustomName = null;
}
if (receiverCustomName == null) {
// If entity does not have a "custom name", see if it is a CustomNPC and get its name.
receiverCustomName = OtherModHandler.getCustomNPCName(event.getEntity());
}
String attackerClassName;
try {
attackerClassName = event.getSource().getEntity().getClass().getName();
@ -73,6 +78,10 @@ public class BattleManager
} catch (NullPointerException e) {
attackerCustomName = null;
}
if (attackerCustomName == null) {
// If entity does not have a "custom name", see if it is a CustomNPC and get its name.
attackerCustomName = OtherModHandler.getCustomNPCName(event.getSource().getEntity());
}
// verify that both entities are EntityPlayer and not in creative or has a corresponding EntityInfo
if(!((event.getEntity() instanceof PlayerEntity && !((PlayerEntity)event.getEntity()).isCreative())
@ -190,12 +199,20 @@ public class BattleManager
} catch (NullPointerException e) {
targetedCustomName = null;
}
if (targetedCustomName == null) {
// If entity does not have a "custom name", see if it is a CustomNPC and get its name.
targetedCustomName = OtherModHandler.getCustomNPCName(event.getEntity());
}
String attackerCustomName;
try {
attackerCustomName = event.getEntity().getCustomName().getString();
} catch (NullPointerException e) {
attackerCustomName = null;
}
if (attackerCustomName == null) {
// If entity does not have a "custom name", see if it is a CustomNPC and get its name.
attackerCustomName = OtherModHandler.getCustomNPCName(event.getEntity());
}
EntityInfo attackerInfo = TurnBasedMinecraftMod.proxy.getConfig().getCustomEntityInfoReference(attackerCustomName);
if(attackerInfo == null)
@ -366,4 +383,4 @@ public class BattleManager
public static Collection<ItemGroup> getOtherFoodItemGroups() {
return otherFoodItemGroups;
}
}
}

View file

@ -4,10 +4,21 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import net.minecraft.entity.Entity;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.IEventBus;
public class OtherModHandler {
private static boolean customNPCsExists = false;
private static Object NpcAPIObject = null;
private static Class<?> NpcAPIClass = null;
private static Method NpcAPI_getEntity = null;
private static Class<?> ICustomNPCClass = null;
private static Method ICustomNPC_getDisplayMethod = null;
private static Class<?> INPCDisplayClass = null;
private static Method INPCDisplay_getNameMethod = null;
public OtherModHandler() {
}
@ -15,13 +26,12 @@ public class OtherModHandler {
// Check if CustomNPCs is available, and handle player damage events if it is.
for (int i = 0; i < 1; ++i) {
// Check if required classes exist
Class<?> customNPCsAPI = null;
try {
customNPCsAPI = Class.forName("noppes.npcs.api.NpcAPI");
NpcAPIClass = Class.forName("noppes.npcs.api.NpcAPI");
} catch (ClassNotFoundException e) {
TurnBasedMinecraftMod.logger.info("NpcAPI not found, not handling it.");
}
if (customNPCsAPI == null) {
if (NpcAPIClass == null) {
break;
}
@ -96,12 +106,11 @@ public class OtherModHandler {
}
// Check if available
Object instance = null;
try {
Method instanceMethod = customNPCsAPI.getMethod("Instance");
instance = instanceMethod.invoke(null);
if (!customNPCsAPI.isInstance(instance)) {
instance = null;
Method instanceMethod = NpcAPIClass.getMethod("Instance");
NpcAPIObject = instanceMethod.invoke(null);
if (!NpcAPIClass.isInstance(NpcAPIObject)) {
NpcAPIObject = null;
TurnBasedMinecraftMod.logger.error("NpcAPI.Instance() is not NpcAPI!");
}
} catch (NoSuchMethodException e) {
@ -111,14 +120,14 @@ public class OtherModHandler {
} catch (IllegalAccessException e) {
TurnBasedMinecraftMod.logger.error("Failed to call NpcAPI.Instance(), IllegalAccessException!");
}
if (instance == null) {
if (NpcAPIObject == null) {
break;
}
Boolean isAvailable = false;
try {
Method isAvailableMethod = customNPCsAPI.getMethod("IsAvailable");
isAvailable = (Boolean)isAvailableMethod.invoke(instance);
Method isAvailableMethod = NpcAPIClass.getMethod("IsAvailable");
isAvailable = (Boolean)isAvailableMethod.invoke(NpcAPIObject);
} catch (NoSuchMethodException e) {
TurnBasedMinecraftMod.logger.warn("NpcAPI.IsAvailable() does not exist!");
} catch (InvocationTargetException e) {
@ -137,7 +146,7 @@ public class OtherModHandler {
Method getNPCsEventBusMethod = null;
try {
getNPCsEventBusMethod = customNPCsAPI.getMethod("events");
getNPCsEventBusMethod = NpcAPIClass.getMethod("events");
} catch (NoSuchMethodException e) {
TurnBasedMinecraftMod.logger.warn("NpcAPI.events() could not be found!");
}
@ -147,7 +156,7 @@ public class OtherModHandler {
IEventBus customNPCsEventBus = null;
try {
customNPCsEventBus = (IEventBus) getNPCsEventBusMethod.invoke(instance);
customNPCsEventBus = (IEventBus) getNPCsEventBusMethod.invoke(NpcAPIObject);
} catch (InvocationTargetException e) {
TurnBasedMinecraftMod.logger.warn("Failed to invoke NpcAPI.events(), InvocationTargetException!");
} catch (IllegalAccessException e) {
@ -227,6 +236,105 @@ public class OtherModHandler {
}
});
TurnBasedMinecraftMod.logger.info("Enabled NpcAPI handling of Player damaged event");
try {
NpcAPI_getEntity = NpcAPIClass.getMethod("getIEntity", Entity.class);
} catch (NoSuchMethodException e) {
TurnBasedMinecraftMod.logger.warn("Failed to reflect NpcAPI.getIEntity() method");
}
if (NpcAPI_getEntity == null) {
break;
}
try {
ICustomNPCClass = Class.forName("noppes.npcs.api.entity.ICustomNpc");
} catch (ClassNotFoundException e) {
TurnBasedMinecraftMod.logger.warn("Failed to reflect ICustomNPC class");
}
if (ICustomNPCClass == null) {
break;
}
try {
ICustomNPC_getDisplayMethod = ICustomNPCClass.getMethod("getDisplay");
} catch (NoSuchMethodException e) {
TurnBasedMinecraftMod.logger.warn("Failed to reflect ICustomNPC.getDisplay() method");
}
if (ICustomNPC_getDisplayMethod == null) {
break;
}
try {
INPCDisplayClass = Class.forName("noppes.npcs.api.entity.data.INPCDisplay");
} catch (ClassNotFoundException e) {
TurnBasedMinecraftMod.logger.warn("Failed to reflect INPCDisplay class");
}
if (INPCDisplayClass == null) {
break;
}
try {
INPCDisplay_getNameMethod = INPCDisplayClass.getMethod("getName");
} catch (NoSuchMethodException e) {
TurnBasedMinecraftMod.logger.warn("Failed to reflect INPCDisplay.getName() method");
}
if (INPCDisplay_getNameMethod == null) {
break;
}
customNPCsExists = true;
}
}
public static String getCustomNPCName(Entity entity) {
if (customNPCsExists) {
Object ientity = null;
try {
ientity = NpcAPI_getEntity.invoke(NpcAPIObject, entity);
} catch (InvocationTargetException e) {
TurnBasedMinecraftMod.logger.debug("Cannot getCustomNPCName, NpcAPI.getEntity(...) InvocationTargetException");
} catch (IllegalAccessException e) {
TurnBasedMinecraftMod.logger.debug("Cannot getCustomNPCName, NpcAPI.getEntity(...) IllegalAccessException");
}
if (ientity == null) {
return null;
}
if (!ICustomNPCClass.isInstance(ientity)) {
TurnBasedMinecraftMod.logger.debug("Cannot getCustomNPCName, entity is not ICustomNPC!");
return null;
}
Object objINPCDisplay = null;
try {
objINPCDisplay = ICustomNPC_getDisplayMethod.invoke(ientity);
} catch (InvocationTargetException e) {
TurnBasedMinecraftMod.logger.error("Failed to get INPCDisplay object, InvocationTargetException!");
} catch (IllegalAccessException e) {
TurnBasedMinecraftMod.logger.error("Failed to get INPCDisplay object, IllegalAccessException!");
}
if (!INPCDisplayClass.isInstance(objINPCDisplay)) {
TurnBasedMinecraftMod.logger.debug("Cannot getCustomNPCName, ientity object is not ICustomNPC!");
return null;
}
String name = null;
try {
name = (String)INPCDisplay_getNameMethod.invoke(objINPCDisplay);
} catch (InvocationTargetException e) {
TurnBasedMinecraftMod.logger.error("Failed to get INPCDisplay name, InvocationTargetException!");
} catch (IllegalAccessException e) {
TurnBasedMinecraftMod.logger.error("Failed to get INPCDisplay name, IllegalAccessException!");
} catch (ClassCastException e) {
TurnBasedMinecraftMod.logger.error("Failed to get INPCDisplay name, ClassCastException!");
}
if (name == null) {
TurnBasedMinecraftMod.logger.debug("Cannot getCustomNPCName, got null name!");
}
return name;
} else {
TurnBasedMinecraftMod.logger.debug("Cannot getCustomNPCName, reflected classes/methods not loaded!");
return null;
}
}
}

View file

@ -35,7 +35,7 @@ public class TurnBasedMinecraftMod
{
public static final String MODID = "com_burnedkirby_turnbasedminecraft";
public static final String NAME = "Turn Based Minecraft Mod";
public static final String VERSION = "1.17.2.5";
public static final String VERSION = "1.17.2.6";
public static final String CONFIG_FILENAME = "TBM_Config.toml";
public static final String DEFAULT_CONFIG_FILENAME = "TBM_Config_DEFAULT.toml";
public static final String CONFIG_DIRECTORY = "config/TurnBasedMinecraft/";

View file

@ -15,7 +15,7 @@ license="MIT"
# The modid of the mod
modId="com_burnedkirby_turnbasedminecraft" #mandatory
# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it
version="1.17.2.5" #mandatory
version="1.17.2.6" #mandatory
# A display name for the mod
displayName="TurnBasedMinecraftMod" #mandatory
# A URL to query for updates for this mod. See the JSON update specification <here>

View file

@ -3,7 +3,7 @@
"modid": "com_burnedkirby_turnbasedminecraft",
"name": "Turn Based Minecraft",
"description": "Changes battles to be turn-based.",
"version": "1.17.2.5",
"version": "1.17.2.6",
"mcversion": "1.16.3",
"url": "",
"updateUrl": "",