Skip to content

Commit

Permalink
Full 1.20.4 Support (#191)
Browse files Browse the repository at this point in the history
* Update gradle.properties to iterate mod_version

Updated mod_version to ensure compatibility with FabricTailor is retained

* Update Taterzens.java to init lang as the correct datatype

Initialised an empty JsonObject to ensure the mod doesn't trip over lang being null.  Has the odd side effect of allowing the GUI to start working.

* Update LanguageUtil.java Language file path

Updated the path to the language files within the .jar.  Note that it loads from within it, NOT from the filepath in the config folder.

* Update TextUtil.java Commenting out SERVER_TRANSLATION

Commented out SEVER_TRANSLATIONS reference because it was blocking any attempt to read from the language.json files in toto.  This may be removed in future as it doesn't seem to apply anywhere else in the codebase, and was returning nothing that could be used by the functions seeking translation.

* Update EditorGUI.java Generate UUID to prevent GameProfile null crash

Generated temporary UUID to keep GameProfile from crashing the server when it tries to generate a result using a null uuid entry.

* Update Taterzens.java Syntax Error Fix

Fix syntax error for defining JsonObject

* Update TaterzensClient.java

This just seems to be dead code.  It throws an error at build when not commented out, but doesn't seem to affect mod function.  Most of the imports can be removed, too.

* Update TypeCommand.java

Introduced the concept of modEntity, which is a part of an NPC's definition, and which maps directly to the Entity Type in CAPS.

* Update NPCData.java

Added the hashmaps for the entity list and player entity so that we can track and manipulate them with ease when setting TYPE.

* Update TaterzenNPC.java

We make the necessary changes to allow player TYPE to be edited and for it to persist across world / game loads.

* Update TaterzenNPC.java

Loose bracket...
  • Loading branch information
UntalentedAmateur authored Jul 28, 2024
1 parent 47a9467 commit 9a45891
Show file tree
Hide file tree
Showing 9 changed files with 244 additions and 9 deletions.
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ loader_version=0.15.6
fabric_version=0.95.4+1.20.4

# Mod Properties
mod_version=1.0.0
# Updated mod_version to ensure FabricTailor compat retained
mod_version=1.12.5
maven_group=org.samo_lego
archives_base_name=taterzens

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ public class TaterzensClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
// We just do this to avoid client crashes
/*
EntityRendererRegistry.register(Taterzens.TATERZEN_TYPE.get(), context -> new MobRenderer<>(context, new PlayerModel<>(context.bakeLayer(ModelLayers.PLAYER), false), 1.0F) {
@Override
public ResourceLocation getTextureLocation(TaterzenNPC entity) {
return DefaultPlayerSkin.getDefaultTexture();
}
});
*/
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class Taterzens {
/**
* Language file.
*/
public static JsonObject lang;
public static JsonObject lang = new JsonObject();

/**
* List of **loaded** {@link TaterzenNPC TaterzenNPCs}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@
import static org.samo_lego.taterzens.common.util.TextUtil.successText;
import static org.samo_lego.taterzens.common.util.TextUtil.translate;

import org.samo_lego.taterzens.common.npc.NPCData;
import static org.apache.logging.log4j.LogManager.getLogger;


public class TypeCommand {

public final NPCData npcData = new NPCData();

public static void registerNode(LiteralCommandNode<CommandSourceStack> editNode, CommandBuildContext commandBuildContext) {
LiteralCommandNode<CommandSourceStack> typeNode = literal("type")
.requires(src -> Taterzens.getInstance().getPlatform().checkPermission(src, "taterzens.npc.edit.entity_type", config.perms.npcCommandPermissionLevel))
Expand Down Expand Up @@ -78,6 +85,19 @@ private static int changeType(CommandContext<CommandSourceStack> context) throws
nbt.putString("id", disguise.toString());

EntityType.loadEntityRecursive(nbt, source.getLevel(), (entityx) -> {
// We can do some manipulation based on the detail returned
// taterzen.modEntity() is a short all-caps descriptor of the current TYPE.
var removeSub = "entity.minecraft.";

var interim = entityx.getType().getDescriptionId();


String stripped = interim.replace(removeSub, "").toUpperCase();

getLogger("Taterzens").info("[Taterzens]: Setting the order to change the type - {}", stripped);

taterzen.modEntity(stripped);

Taterzens.getInstance().getPlatform().disguiseAs(taterzen, entityx);
source.sendSuccess(() ->
translate(
Expand All @@ -104,6 +124,10 @@ private static int resetType(CommandContext<CommandSourceStack> context) throws
return -1;
}
return NpcCommand.selectedTaterzenExecutor(source.getEntityOrException(), taterzen -> {

// The Reset is to PLAYER
taterzen.modEntity("PLAYER");

Taterzens.getInstance().getPlatform().clearDisguise(taterzen);
source.sendSuccess(() ->
successText("taterzens.command.entity_type.reset", taterzen.getName().getString()),
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/org/samo_lego/taterzens/common/npc/NPCData.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.mojang.datafixers.util.Pair;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -141,4 +142,11 @@ public enum FollowTypes {
PLAYERS,
MOBS
}

// We build a hashmap of entities to make our lives a little easier when changing and keeping TYPE
public HashMap<String, EntityType<?>> entityList = new HashMap<>();

// We set the player TYPE using a similar approach, since the data likes to be in a hashmap format.
public HashMap<String, String> playerEntity = new HashMap<>();

}
197 changes: 194 additions & 3 deletions src/main/java/org/samo_lego/taterzens/common/npc/TaterzenNPC.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@
import static org.samo_lego.taterzens.common.util.TextUtil.errorText;
import static org.samo_lego.taterzens.common.util.TextUtil.successText;

import static org.apache.logging.log4j.LogManager.getLogger;

/**
* The NPC itself.
*/
Expand Down Expand Up @@ -152,7 +154,8 @@ public TaterzenNPC(Level world) {
* {@link TaterzensAPI#createTaterzen(ServerPlayer, String)}
* instead, as this one doesn't set the position and custom name.
*
* @param entityType Taterzen entity type
* @param npcData.entityList.put
Taterzen entity type
* @param world Taterzen's world
*/
public TaterzenNPC(EntityType<? extends PathfinderMob> entityType, Level world) {
Expand Down Expand Up @@ -182,7 +185,160 @@ public TaterzenNPC(EntityType<? extends PathfinderMob> entityType, Level world)
this.npcData.deathSounds = new ArrayList<>(config.defaults.deathSounds);
}

// This is where the magic happens for changing entity type...
CompoundTag npcTag = new CompoundTag();
if (npcTag.contains("Entity")) {
// Update it to the current settting
getLogger("Taterzens").info("[Taterzens]: We have a valid Entity setting and are putting it in the Tag - Map - {}, - Tag -", npcData.playerEntity.get("Entity"), npcTag.getString("Entity"));
//
npcTag.putString("Entity", npcData.playerEntity.get("Entity"));
// It's actually this we need to update since we have it stored, and the playerEntity hashmap is what we're using
npcData.playerEntity.put("Entity", npcTag.getString("Entity"));
} else { // Initial NPC creation we go to PLAYER
getLogger("Taterzens").info("[Taterzens]: No valid Entity set, so it's PLAYER time.");

npcTag.putString("Entity", "PLAYER");
npcData.playerEntity.put("Entity", "PLAYER");
}

// We only want to do this ONCE, and it gets fussy if placed anywhere else.
// So, we check to see if the list is empty and then fill it if it is
if (this.npcData.entityList.isEmpty()) {

npcData.entityList.put("ALLAY", EntityType.ALLAY);
npcData.entityList.put("AREA_EFFECT_CLOUD", EntityType.AREA_EFFECT_CLOUD);
npcData.entityList.put("ARMOR_STAND", EntityType.ARMOR_STAND);
npcData.entityList.put("ARROW", EntityType.ARROW);
npcData.entityList.put("AXOLOTL", EntityType.AXOLOTL);
npcData.entityList.put("BAT", EntityType.BAT);
npcData.entityList.put("BEE", EntityType.BEE);
npcData.entityList.put("BLAZE", EntityType.BLAZE);
npcData.entityList.put("BLOCK_DISPLAY", EntityType.BLOCK_DISPLAY);
npcData.entityList.put("BOAT", EntityType.BOAT);
npcData.entityList.put("BREEZE", EntityType.BREEZE);
npcData.entityList.put("CAMEL", EntityType.CAMEL);
npcData.entityList.put("CAT", EntityType.CAT);
npcData.entityList.put("CAVE_SPIDER", EntityType.CAVE_SPIDER);
npcData.entityList.put("CHEST_BOAT", EntityType.CHEST_BOAT);
npcData.entityList.put("CHEST_MINECART", EntityType.CHEST_MINECART);
npcData.entityList.put("CHICKEN", EntityType.CHICKEN);
npcData.entityList.put("COD", EntityType.COD);
npcData.entityList.put("COMMAND_BLOCK_MINECART", EntityType.COMMAND_BLOCK_MINECART);
npcData.entityList.put("COW", EntityType.COW);
npcData.entityList.put("CREEPER", EntityType.CREEPER);
npcData.entityList.put("DOLPHIN", EntityType.DOLPHIN);
npcData.entityList.put("DONKEY", EntityType.DONKEY);
npcData.entityList.put("DRAGON_FIREBALL", EntityType.DRAGON_FIREBALL);
npcData.entityList.put("DROWNED", EntityType.DROWNED);
npcData.entityList.put("EGG", EntityType.EGG);
npcData.entityList.put("ELDER_GUARDIAN", EntityType.ELDER_GUARDIAN);
npcData.entityList.put("END_CRYSTAL", EntityType.END_CRYSTAL);
npcData.entityList.put("ENDER_DRAGON", EntityType.ENDER_DRAGON);
npcData.entityList.put("ENDER_PEARL", EntityType.ENDER_PEARL);
npcData.entityList.put("ENDERMAN", EntityType.ENDERMAN);
npcData.entityList.put("ENDERMITE", EntityType.ENDERMITE);
npcData.entityList.put("EVOKER", EntityType.EVOKER);
npcData.entityList.put("EVOKER_FANGS", EntityType.EVOKER_FANGS);
npcData.entityList.put("EXPERIENCE_BOTTLE", EntityType.EXPERIENCE_BOTTLE);
npcData.entityList.put("EXPERIENCE_ORB", EntityType.EXPERIENCE_ORB);
npcData.entityList.put("EYE_OF_ENDER", EntityType.EYE_OF_ENDER);
npcData.entityList.put("FALLING_BLOCK", EntityType.FALLING_BLOCK);
npcData.entityList.put("FIREBALL", EntityType.FIREBALL);
npcData.entityList.put("FIREWORK_ROCKET", EntityType.FIREWORK_ROCKET);
npcData.entityList.put("FISHING_BOBBER", EntityType.FISHING_BOBBER);
npcData.entityList.put("FOX", EntityType.FOX);
npcData.entityList.put("FROG", EntityType.FROG);
npcData.entityList.put("FURNACE_MINECART", EntityType.FURNACE_MINECART);
npcData.entityList.put("GHAST", EntityType.GHAST);
npcData.entityList.put("GIANT", EntityType.GIANT);
npcData.entityList.put("GLOW_ITEM_FRAME", EntityType.GLOW_ITEM_FRAME);
npcData.entityList.put("GLOW_SQUID", EntityType.GLOW_SQUID);
npcData.entityList.put("GOAT", EntityType.GOAT);
npcData.entityList.put("GUARDIAN", EntityType.GUARDIAN);
npcData.entityList.put("HOGLIN", EntityType.HOGLIN);
npcData.entityList.put("HOPPER_MINECART", EntityType.HOPPER_MINECART);
npcData.entityList.put("HORSE", EntityType.HORSE);
npcData.entityList.put("HUSK", EntityType.HUSK);
npcData.entityList.put("ILLUSIONER", EntityType.ILLUSIONER);
npcData.entityList.put("INTERACTION", EntityType.INTERACTION);
npcData.entityList.put("IRON_GOLEM", EntityType.IRON_GOLEM);
npcData.entityList.put("ITEM", EntityType.ITEM);
npcData.entityList.put("ITEM_DISPLAY", EntityType.ITEM_DISPLAY);
npcData.entityList.put("ITEM_FRAME", EntityType.ITEM_FRAME);
npcData.entityList.put("LEASH_KNOT", EntityType.LEASH_KNOT);
npcData.entityList.put("LIGHTNING_BOLT", EntityType.LIGHTNING_BOLT);
npcData.entityList.put("LLAMA", EntityType.LLAMA);
npcData.entityList.put("LLAMA_SPIT", EntityType.LLAMA_SPIT);
npcData.entityList.put("MAGMA_CUBE", EntityType.MAGMA_CUBE);
npcData.entityList.put("MARKER", EntityType.MARKER);
npcData.entityList.put("MINECART", EntityType.MINECART);
npcData.entityList.put("MOOSHROOM", EntityType.MOOSHROOM);
npcData.entityList.put("MULE", EntityType.MULE);
npcData.entityList.put("OCELOT", EntityType.OCELOT);
npcData.entityList.put("PAINTING", EntityType.PAINTING);
npcData.entityList.put("PANDA", EntityType.PANDA);
npcData.entityList.put("PARROT", EntityType.PARROT);
npcData.entityList.put("PHANTOM", EntityType.PHANTOM);
npcData.entityList.put("PIG", EntityType.PIG);
npcData.entityList.put("PIGLIN", EntityType.PIGLIN);
npcData.entityList.put("PIGLIN_BRUTE", EntityType.PIGLIN_BRUTE);
npcData.entityList.put("PILLAGER", EntityType.PILLAGER);
npcData.entityList.put("PLAYER", EntityType.PLAYER);
npcData.entityList.put("POLAR_BEAR", EntityType.POLAR_BEAR);
npcData.entityList.put("POTION", EntityType.POTION);
npcData.entityList.put("PUFFERFISH", EntityType.PUFFERFISH);
npcData.entityList.put("RABBIT", EntityType.RABBIT);
npcData.entityList.put("RAVAGER", EntityType.RAVAGER);
npcData.entityList.put("SALMON", EntityType.SALMON);
npcData.entityList.put("SHEEP", EntityType.SHEEP);
npcData.entityList.put("SHULKER", EntityType.SHULKER);
npcData.entityList.put("SHULKER_BULLET", EntityType.SHULKER_BULLET);
npcData.entityList.put("SILVERFISH", EntityType.SILVERFISH);
npcData.entityList.put("SKELETON", EntityType.SKELETON);
npcData.entityList.put("SKELETON_HORSE", EntityType.SKELETON_HORSE);
npcData.entityList.put("SLIME", EntityType.SLIME);
npcData.entityList.put("SMALL_FIREBALL", EntityType.SMALL_FIREBALL);
npcData.entityList.put("SNIFFER", EntityType.SNIFFER);
npcData.entityList.put("SNOW_GOLEM", EntityType.SNOW_GOLEM);
npcData.entityList.put("SNOWBALL", EntityType.SNOWBALL);
npcData.entityList.put("SPAWNER_MINECART", EntityType.SPAWNER_MINECART);
npcData.entityList.put("SPECTRAL_ARROW", EntityType.SPECTRAL_ARROW);
npcData.entityList.put("SPIDER", EntityType.SPIDER);
npcData.entityList.put("SQUID", EntityType.SQUID);
npcData.entityList.put("STRAY", EntityType.STRAY);
npcData.entityList.put("STRIDER", EntityType.STRIDER);
npcData.entityList.put("TADPOLE", EntityType.TADPOLE);
npcData.entityList.put("TEXT_DISPLAY", EntityType.TEXT_DISPLAY);
npcData.entityList.put("TNT", EntityType.TNT);
npcData.entityList.put("TNT_MINECART", EntityType.TNT_MINECART);
npcData.entityList.put("TRADER_LLAMA", EntityType.TRADER_LLAMA);
npcData.entityList.put("TRIDENT", EntityType.TRIDENT);
npcData.entityList.put("TROPICAL_FISH", EntityType.TROPICAL_FISH);
npcData.entityList.put("TURTLE", EntityType.TURTLE);
npcData.entityList.put("VEX", EntityType.VEX);
npcData.entityList.put("VILLAGER", EntityType.VILLAGER);
npcData.entityList.put("VINDICATOR", EntityType.VINDICATOR);
npcData.entityList.put("WANDERING_TRADER", EntityType.WANDERING_TRADER);
npcData.entityList.put("WARDEN", EntityType.WARDEN);
npcData.entityList.put("WIND_CHARGE", EntityType.WIND_CHARGE);
npcData.entityList.put("WITCH", EntityType.WITCH);
npcData.entityList.put("WITHER", EntityType.WITHER);
npcData.entityList.put("WITHER_SKELETON", EntityType.WITHER_SKELETON);
npcData.entityList.put("WITHER_SKULL", EntityType.WITHER_SKULL);
npcData.entityList.put("WOLF", EntityType.WOLF);
npcData.entityList.put("ZOGLIN", EntityType.ZOGLIN);
npcData.entityList.put("ZOMBIE", EntityType.ZOMBIE);
npcData.entityList.put("ZOMBIE_HORSE", EntityType.ZOMBIE_HORSE);
npcData.entityList.put("ZOMBIE_VILLAGER", EntityType.ZOMBIE_VILLAGER);
npcData.entityList.put("ZOMBIFIED_PIGLIN", EntityType.ZOMBIFIED_PIGLIN);
}

}

public void modEntity(String entType) {
this.npcData.playerEntity.put("Entity", entType);
}


/**
* Creates default taterzen attributes.
Expand Down Expand Up @@ -822,6 +978,30 @@ public void readAdditionalSaveData(CompoundTag tag) {
this.setAllowSwimming(npcTag.getBoolean("AllowSwimming"));
// --------------------------------------------------------------


// This magic is where we check on loading in whether the NPC has a different TYPE to what is expected
// Normally, it will default to PLAYER, but we want the TYPE changes to be persistent
// The logger is pushing details to the minecraft log so you can see it actually parsing things

getLogger("Taterzens").info("[Taterzens]: Out of interest, the Tag Entity is {}.", npcTag.get("Entity"));

if (npcTag.contains("Entity")) {
// Update it to the current settting
if (npcTag.get("Entity") == null) {
getLogger("Taterzens").error("[Taterzens]: In the SaveDataread.");

npcTag.putString("Entity", "PLAYER");
npcData.playerEntity.put("Entity", "PLAYER");
} else {
getLogger("Taterzens").info("[Taterzens]: We have a valid Entity setting and are putting it in the Tag");
//
// It's actually this we need to update since we have it stored, and the playerEntity hashmap is what we're using
npcData.playerEntity.put("Entity", npcTag.getString("Entity"));
// And we need to override the other setting
npcTag.putString("Entity", npcTag.getString("Entity"));
}
}

this.setMinCommandInteractionTime(npcTag.getLong("MinCommandInteractionTime"));
}

Expand Down Expand Up @@ -929,6 +1109,15 @@ public void addAdditionalSaveData(CompoundTag tag) {

npcTag.putLong("MinCommandInteractionTime", this.npcData.minCommandInteractionTime);


getLogger("Taterzens").info("[Taterzens]: The Game is paused or saving. We're setting NPC entity to {}", npcData.playerEntity.get("Entity"));

// We take whatever the npc has been changed to and shove it in the tag.
// Only end up in here on pausing or saving to quit
if (npcData.playerEntity.get("Entity") != null) {
npcTag.putString("Entity", npcData.playerEntity.get("Entity"));
}

tag.put("TaterzenNPCTag", npcTag);
}

Expand Down Expand Up @@ -1867,7 +2056,8 @@ public void setAllowSwimming(boolean allowSwimming) {
this.setTag("AllowSwimming", allowSwimming);
}

private void setTag(String name, boolean value) {
// Change this to public, since we want to use it elsewhere
public void setTag(String name, boolean value) {
this.npcData.booleanTags.put(name, value);
}

Expand All @@ -1883,7 +2073,8 @@ private boolean getTag(String name, boolean defaultValue) {

@Override
public EntityType<?> getPolymerEntityType(ServerPlayer player) {
return EntityType.PLAYER;
// All that other work for such a pretty little line of code
return npcData.entityList.get(npcData.playerEntity.get("Entity"));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

public class LanguageUtil {

public static final InputStream DEFAULT_LANG_STREAM = Taterzens.class.getResourceAsStream("/data/taterzens/lang/en_us.json");
public static final InputStream DEFAULT_LANG_STREAM = Taterzens.class.getResourceAsStream("/lang/en_us.json");
public static final List<String> LANG_LIST = new ArrayList<>();
private static final String API_URL = "https://api.github.com/repos/samolego/taterzens/contents/common/src/main/resources/data/taterzens/lang";
private static final String LANG_FILE_URL = "https://raw.githubusercontent.com/samolego/Taterzens/master/common/src/main/resources/data/taterzens/lang/%s.json";
Expand All @@ -31,7 +31,7 @@ public class LanguageUtil {
* Initializes the mod's language json object.
*/
public static void setupLanguage() {
String langPath = String.format("/data/taterzens/lang/%s.json", config.language);
String langPath = String.format("/lang/%s.json", config.language);
InputStream stream = Taterzens.class.getResourceAsStream(langPath);
if (stream == null) {
// Try to fetch language, as it's not present in jar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,15 @@ public static MutableComponent fromNbtElement(Tag textNbtElement) {
* @return {@link TranslatableContents} or {@link PlainTextContents.LiteralContents} depending on whether SERVER_TRANSLATIONS is loaded.
*/
public static MutableComponent translate(String key, Object... args) {
/*
// Commenting this out because SERVER_TRANSLATIONS doesn't seem to do anything, particularly when we have translation files available and loaded
// Because this always seems to be loaded, it's always going to prevent the follow on translation thanks to that return...
if (SERVER_TRANSLATIONS_LOADED) {
return Component.translatable(key, args);
}
*/

String translation;
if (lang.has(key)) {
Expand Down
Loading

0 comments on commit 9a45891

Please sign in to comment.