Skip to content
Open

Tags #29

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public void render(MatrixStack matrixStack, VertexConsumerProvider vertexConsume
matrixStack.push();
this.getContextModel().body.rotate(matrixStack);
boolean isHelicopterMode = ConfigHandler.isHelicopterModeOn() && (playerRenderState.isSwimming || playerRenderState.isGliding);
this.renderItem(!playerRenderState.equippedChestStack.isEmpty() ? 1.0F : playerRenderState.jacketVisible ? 0.5F : 0F, matrixStack, vertexConsumerProvider, light, isHelicopterMode ? playerRenderState.age : 0);
this.renderItem(!playerRenderState.equippedChestStack.isEmpty() ? 1.0F : playerRenderState.jacketVisible ? 0.5F : 0F,
matrixStack, vertexConsumerProvider, light, isHelicopterMode ? playerRenderState.age : 0);
matrixStack.pop();
}
}
Expand All @@ -55,8 +56,8 @@ private void renderItem(float offset, MatrixStack matrices, VertexConsumerProvid
if (this.mainArm == Arm.RIGHT) {
matrices.scale(-1F, 1F, -1F);
}
boolean bl = this.mainStack.getItem() instanceof ShieldItem;
if (bl) {

if (this.mainStack.getItem() instanceof ShieldItem) {
float scale = 1.5F;
matrices.scale(scale, scale, scale);
if (this.mainArm == Arm.LEFT) {
Expand All @@ -67,11 +68,11 @@ private void renderItem(float offset, MatrixStack matrices, VertexConsumerProvid
matrices.translate(-1F / 16F, 0.25F / 16F, 1.0F / 16F);
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(25F));
}
}
if (!bl) {
} else {
final float i = ConfigHandler.getToolOrientation(this.mainStack.getItem());
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(i));
}

if (ConfigHandler.isBeltTool(this.mainStack.getItem())) {
float swordScale = 0.8F;
matrices.scale(swordScale, swordScale, swordScale);
Expand All @@ -84,6 +85,7 @@ private void renderItem(float offset, MatrixStack matrices, VertexConsumerProvid
matrices.translate(0.19F, 0.6F, 0.33F);
}
}

if (age > 0) {
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(age * 40F));
}
Expand Down
25 changes: 17 additions & 8 deletions src/main/java/com/daniking/backtools/BackToolsConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,29 @@
public class BackToolsConfig implements ConfigData {
@Comment(value = "\nThese options affect only the client that loads the mod.\nIt is not possible to override the environment of the mod.")
public final String environment = EnvType.CLIENT.name();
@Comment(value = "What items should render on your belt.")
@Comment(value = "What items should render on your belt by their resource name. Eg: minecraft:diamond_hoe")
public List<String> beltTools = new ArrayList<>();
@Comment(value = "Enabled tools, by their resource name. Eg: minecraft:diamond_hoe. Putting any entry in here converts BackTools to a whitelist-only mod. Disabled Tools will be ignored.")
public List<String> enabledTools = new ArrayList<>();
@Comment(value = "Disabled tools, by their resource name. Eg: minecraft:diamond_hoe")
public List<String> disabledTools = new ArrayList<>();
@Comment(value = "Tool orientation, by class file and degrees. Separate with \":\" . See defaults for examples.")
@Comment(value =
"""
Tool orientation, by class file and degrees.
Entries starting with "#" are tags (https://minecraft.wiki/w/Tag)
Leading namespace (e.g. minecraft:) is optional.
Separate with ":" for rotation.
Later occurrences of the same item override the previous once (Like in hoes override their config values set in mining).
Item types not listed here will default to 0.
"See defaults for examples.""")
public List<String> toolOrientation = Arrays.asList(
"net.minecraft.item.MiningToolItem" + ":0",
"net.minecraft.item.HoeItem" + ":0",
"net.minecraft.item.FishingRodItem" + ":0",
"net.minecraft.item.TridentItem" + ":0",
"net.minecraft.item.MaceItem" + ":-22.5",
"net.minecraft.item.RangedWeaponItem" + ":90");
"#minecraft:enchantable/mining" + ":0",
"#minecraft:hoes" + ":0",
"#minecraft:enchantable/fishing" + ":0",
"#minecraft:enchantable/trident" + ":0",
"mace" + ":-22.5",
"bow" + ":90",
"crossbow" + ":90");
@Comment(value = "Get in swimming position and your tools go \"Weeee\"")
public boolean helicopterMode = false;
@Comment(value = "If true, tools render with capes")
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/com/daniking/backtools/ClientSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.event.lifecycle.v1.CommonLifecycleEvents;

import java.util.Map;
import java.util.WeakHashMap;
Expand All @@ -18,6 +19,8 @@ public class ClientSetup implements ClientModInitializer {
public void onInitializeClient() {
AutoConfig.register(BackToolsConfig.class, JanksonConfigSerializer::new);
config = AutoConfig.getConfigHolder(BackToolsConfig.class).getConfig();
ConfigHandler.init();

// since we depend on item tags, our config can't load until the tags are loaded first. (creating / joining worlds)
CommonLifecycleEvents.TAGS_LOADED.register((registries, client) -> ConfigHandler.init());
}
}
94 changes: 51 additions & 43 deletions src/main/java/com/daniking/backtools/ConfigHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,35 @@

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.MappingResolver;
import net.minecraft.item.*;
import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.entry.RegistryEntryList;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Environment(EnvType.CLIENT)
public class ConfigHandler {
private static final HashMap<Class<?>, Float> TOOL_ORIENTATIONS = new HashMap<>();
private static final HashSet<Identifier> ENABLED_TOOLS = new HashSet<>();
private static final @NotNull Pattern TOOL_ORIENTATION_PATTERN = Pattern.compile("^(?<isTag>#)?(?:(?<namespace>minecraft):)?(?<itemOrTag>.+?):(?<orientation>.+?)$");
private static final Map<Item, Float> TOOL_ORIENTATIONS = new LinkedHashMap<>();
private static final Set<Identifier> ENABLED_TOOLS = new HashSet<>();
private static final Set<Identifier> DISABLED_TOOLS = new HashSet<>();
private static final HashSet<Identifier> BELT_TOOLS = new HashSet<>();
private static boolean HELICOPTER_MODE = false;
private static boolean RENDER_WITH_CAPES = true;
public static final HashSet<Identifier> BELT_TOOLS = new HashSet<>();

public static float getToolOrientation(@NotNull Item item) {
return getToolOrientation(item.getClass());
}
Float orientation = TOOL_ORIENTATIONS.get(item);

public static float getToolOrientation(@NotNull Class<?> object) {
if (object.equals(Item.class)) {
return 0;
}
if (!TOOL_ORIENTATIONS.containsKey(object)) {
TOOL_ORIENTATIONS.put(object, getToolOrientation(object.getSuperclass()));
}
return TOOL_ORIENTATIONS.get(object);
return Objects.requireNonNullElse(orientation, 0.0F);
}

public static boolean isItemEnabled(final Item item) {
Expand Down Expand Up @@ -84,47 +81,58 @@ public static void init() {

private static void parseOrientation() {
TOOL_ORIENTATIONS.clear();
MappingResolver resolver = FabricLoader.getInstance().getMappingResolver();

for (String configText : ClientSetup.config.toolOrientation) {
final String[] split = new String[2];
final int i = configText.indexOf(':');
if (i == -1) {
BackTools.LOGGER.error("[CONFIG_FILE]: Tool orientation class file and degrees must be separated with \":\"!");
} else {
split[0] = configText.substring(0, i);//chunk of the text, contains the file class.
split[1] = configText.substring(i + 1);//orientation
}
Matcher matcher = TOOL_ORIENTATION_PATTERN.matcher(configText);

Class<?> path = null;
for (String namespace : resolver.getNamespaces()) {
if (matcher.matches()) {
float orientation;
try {
path = Class.forName(resolver.unmapClassName(namespace, split[0]));

// if no error was thrown, we were successful!
break;
} catch (ClassNotFoundException ignored) {
orientation = Float.parseFloat(matcher.group("orientation"));
} catch (NumberFormatException exception) {
BackTools.LOGGER.error("[CONFIG_FILE]: Could not load config option, because string \"{}\" was not an integer!", matcher.group("orientation"));
continue;
}
}

if (path != null) {
try {
if (Item.class.isAssignableFrom(path)) {
TOOL_ORIENTATIONS.put(path, Float.parseFloat(split[1]));
final @Nullable String nameSpace = matcher.group("namespace");
if (matcher.group("isTag") == null) { // not a tag
final @NotNull String itemID = matcher.group("itemOrTag"); // item id can't be null or the pattern didn't match

final @Nullable Identifier identifier = Identifier.of(Objects.requireNonNullElse(nameSpace, Identifier.DEFAULT_NAMESPACE), itemID);
final @NotNull Optional<RegistryEntry.Reference<Item>> optionalRegistryEntry = Registries.ITEM.getOptional(RegistryKey.of(
Registries.ITEM.getKey(), identifier
));

if (optionalRegistryEntry.isPresent()) {
TOOL_ORIENTATIONS.put(optionalRegistryEntry.get().value(), orientation);
} else {
BackTools.LOGGER.error("[CONFIG_FILE]: Could not find any item with identifier of {}", identifier);
}
} else { // is a tag
final @NotNull String tagID = matcher.group("itemOrTag"); // tag id can't be null or the pattern didn't match

final @Nullable Identifier identifier = Identifier.of(Objects.requireNonNullElse(nameSpace, Identifier.DEFAULT_NAMESPACE), tagID);
TagKey<Item> tag = TagKey.of(RegistryKeys.ITEM, identifier);

Optional<RegistryEntryList.Named<Item>> optionalRegistryEntries = Registries.ITEM.getOptional(tag);

if (optionalRegistryEntries.isPresent()) {
for (RegistryEntry<Item> registryEntry : optionalRegistryEntries.get()){
TOOL_ORIENTATIONS.put(registryEntry.value(), orientation);
}
} else {
BackTools.LOGGER.error("[CONFIG_FILE]: Invalid Tool class file: {}", split[0]);
BackTools.LOGGER.error("[CONFIG_FILE]: Could not find any item tag with identifier of {}", identifier);
}
} catch (NumberFormatException e) {
BackTools.LOGGER.error("[CONFIG_FILE]: Could not parse text: {}", configText);
}
} else {
BackTools.LOGGER.error("[CONFIG_FILE]: Could not find class to add orientation: {}", split[0]);
BackTools.LOGGER.error("[CONFIG_FILE]: Could not read tool configuration \"{}\"!", configText);
}
}
}

public static boolean isHelicopterModeOn() {
return HELICOPTER_MODE;
}

public static boolean isRenderWithCapesTrue() { return RENDER_WITH_CAPES; }
}
29 changes: 10 additions & 19 deletions src/main/java/com/daniking/backtools/HeldItemContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,71 +11,62 @@ public class HeldItemContext {
public ItemStack activeMain = ItemStack.EMPTY;
public ItemStack activeOff = ItemStack.EMPTY;


public void tick(ItemStack main, ItemStack off) {

if (droppedEntity != null && !droppedEntity.getStack().isEmpty()) {
this.reset(droppedEntity.getStack());
droppedEntity = null;
return;
}

//check to see if we should remove the main hand back tool
if(areStacksEqual(main, previousMain) || areStacksEqual(off, previousMain)) {
if(ItemStack.areItemsAndComponentsEqual(main, previousMain) || ItemStack.areItemsAndComponentsEqual(off, previousMain)) {
previousMain = ItemStack.EMPTY;
}

if(areStacksEqual(main, previousOff) || areStacksEqual(off, previousOff)) {
if(ItemStack.areItemsAndComponentsEqual(main, previousOff) || ItemStack.areItemsAndComponentsEqual(off, previousOff)) {
previousOff = ItemStack.EMPTY;
}
//set back tool if main tool was an item, and we don't see that item anymore.
if(!activeMain.isEmpty() && !areStacksEqual(main, activeMain) && !areStacksEqual(off, activeMain)) {
if(!activeMain.isEmpty() && !ItemStack.areItemsAndComponentsEqual(main, activeMain) && !ItemStack.areItemsAndComponentsEqual(off, activeMain)) {
previousMain = activeMain;
activeMain = ItemStack.EMPTY;
}
// this.updateActiveStacks(main, off);
// //set back tool if offhand tool was an item, and we don't see that item anymore.
// this.updatePreviousStacks(main, off);

if(!activeOff.isEmpty() && !areStacksEqual(main, activeOff) && !areStacksEqual(off, activeOff)) {
if(!activeOff.isEmpty() && !ItemStack.areItemsAndComponentsEqual(main, activeOff) && !ItemStack.areItemsAndComponentsEqual(off, activeOff)) {
previousOff = activeOff;
activeOff = ItemStack.EMPTY;
}
if(ConfigHandler.isItemEnabled(main.getItem())) {
activeMain = main;
if(areStacksEqual(activeMain, activeOff)) {
if(ItemStack.areItemsAndComponentsEqual(activeMain, activeOff)) {
activeOff = ItemStack.EMPTY;
}
}

if(ConfigHandler.isItemEnabled(off.getItem())) {
activeOff = off;
if(areStacksEqual(activeOff, activeMain)) {
if(ItemStack.areItemsAndComponentsEqual(activeOff, activeMain)) {
activeMain = ItemStack.EMPTY;
}
}
}

private void reset(ItemStack entityStack) {
if (areStacksEqual(entityStack, previousMain)) {
if (ItemStack.areItemsAndComponentsEqual(entityStack, previousMain)) {
previousMain = ItemStack.EMPTY;
}
if (areStacksEqual(entityStack, activeMain)) {
if (ItemStack.areItemsAndComponentsEqual(entityStack, activeMain)) {
activeMain = ItemStack.EMPTY;
}
//Check to see if we should remove the offhand BackTool
if (areStacksEqual(entityStack, previousOff)) {
if (ItemStack.areItemsAndComponentsEqual(entityStack, previousOff)) {
previousOff = ItemStack.EMPTY;
}
if (areStacksEqual(entityStack, activeOff)) {
if (ItemStack.areItemsAndComponentsEqual(entityStack, activeOff)) {
activeOff = ItemStack.EMPTY;
}
}

public static boolean areStacksEqual(final ItemStack a, final ItemStack b) {
return !a.isEmpty() && !b.isEmpty() &&
(a.getComponents().isEmpty() || !b.getComponents().isEmpty()) &&
(!a.getComponents().isEmpty() || b.getComponents().isEmpty()) &&
a.getItem() == b.getItem();
}
}