Skip to content

Commit b500fd3

Browse files
committed
- removed white and black list from config and instead allowing items to get removed from the very same liste by prepending it with a minus. This should make the config more intuitive, since the orientation is set in the same list where it gets used.
- added some default belt items - added special case for fishing rod and OnAStickItems - made shield offset configurable - deduplicated code - allow belt items to work wit offhand - fixed bug if both offhand and mainhand items get rendered, affecting each other (bow + shield) - update cloth config version - removed Herobrine from the minecraft movie - fixed bug of some items not getting rotated correctly (bow)
1 parent e3b1d2d commit b500fd3

5 files changed

Lines changed: 226 additions & 165 deletions

File tree

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ maven_group = com.daniking.backtools
1111
archives_base_name = backtools
1212
# Dependencies
1313
fabric_version=0.107.0+1.21.3
14-
cloth_config_version=15.0.127
14+
cloth_config_version=16.0.143

src/main/java/com/daniking/backtools/BackToolFeatureRenderer.java

Lines changed: 75 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@
1111
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
1212
import net.minecraft.client.render.item.ItemRenderer;
1313
import net.minecraft.client.util.math.MatrixStack;
14-
import net.minecraft.item.ItemStack;
15-
import net.minecraft.item.ModelTransformationMode;
16-
import net.minecraft.item.ShieldItem;
14+
import net.minecraft.item.*;
1715
import net.minecraft.util.Arm;
1816
import net.minecraft.util.math.RotationAxis;
17+
import org.jetbrains.annotations.NotNull;
1918

2019
@Environment(EnvType.CLIENT)
2120
public class BackToolFeatureRenderer<M extends PlayerEntityModel> extends PlayerHeldItemFeatureRenderer<PlayerEntityRenderState, M> {
@@ -29,8 +28,14 @@ public BackToolFeatureRenderer(FeatureRendererContext<PlayerEntityRenderState, M
2928

3029
@Override
3130
public void render(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, PlayerEntityRenderState playerRenderState, float limbAngle, float limbDistance) {
32-
if (!(playerRenderState.capeVisible && playerRenderState.skinTextures.capeTexture() != null && !ConfigHandler.isRenderWithCapesTrue()) &&
33-
!playerRenderState.invisible && playerRenderState.sleepingDirection == null &&
31+
// if (!playerRenderState.capeVisible || playerRenderState.skinTextures.capeTexture() == null || ConfigHandler.shouldRenderWithCapes()) {
32+
// // stuff 2
33+
// } else {
34+
// // stuff 1
35+
// }
36+
37+
if (!(playerRenderState.capeVisible && playerRenderState.skinTextures.capeTexture() != null && !ConfigHandler.shouldRenderWithCapes()) &&
38+
!playerRenderState.invisible && playerRenderState.sleepingDirection == null && // todo render belt tools when sleeping
3439
ClientSetup.HELD_TOOLS.containsKey(playerRenderState.name)) {
3540

3641
final HeldItemContext ctx = ClientSetup.HELD_TOOLS.get(playerRenderState.name);
@@ -39,81 +44,87 @@ public void render(MatrixStack matrixStack, VertexConsumerProvider vertexConsume
3944
return;
4045
}
4146
this.setRenders(ctx.previousMain, ctx.previousOff, playerRenderState.mainArm);
42-
matrixStack.push();
4347
this.getContextModel().body.rotate(matrixStack);
44-
boolean isHelicopterMode = ConfigHandler.isHelicopterModeOn() && (playerRenderState.isSwimming || playerRenderState.isGliding);
45-
this.renderItem(!playerRenderState.equippedChestStack.isEmpty() ? 1.0F : playerRenderState.jacketVisible ? 0.5F : 0F,
46-
matrixStack, vertexConsumerProvider, light, isHelicopterMode ? playerRenderState.age : 0);
47-
matrixStack.pop();
48+
final float age = ConfigHandler.isHelicopterModeOn() && (playerRenderState.isSwimming || playerRenderState.isGliding) ? playerRenderState.age : 0;
49+
final float offset = !playerRenderState.equippedChestStack.isEmpty() ? 1.0F : playerRenderState.jacketVisible ? 0.5F : 0F;
50+
51+
renderItem(this.mainStack, matrixStack, vertexConsumerProvider, offset, this.mainArm == Arm.RIGHT, age, light); // Main stack
52+
renderItem(this.offStack, matrixStack, vertexConsumerProvider, offset, this.mainArm == Arm.LEFT, age, light); // Off stack
4853
}
4954
}
5055

51-
private void renderItem(float offset, MatrixStack matrices, VertexConsumerProvider provider, int light, final float age) {
52-
matrices.translate(0F, 4F / 16F, 1.91F / 16F + (offset / 16F));
53-
matrices.translate(0F, 0F, 0.025F);
56+
private void renderItem(final @NotNull ItemStack stack, final @NotNull MatrixStack matrices, final @NotNull VertexConsumerProvider provider, float offset, final boolean isInverted, final float age, int light) {
57+
if (!stack.isEmpty()) {
58+
final Item item = stack.getItem();
59+
matrices.push();
5460

55-
if (!this.mainStack.isEmpty()) {
56-
if (this.mainArm == Arm.RIGHT) {
57-
matrices.scale(-1F, 1F, -1F);
58-
}
59-
if (this.mainStack.getItem() instanceof ShieldItem) {
60-
float scale = 1.5F;
61+
float orientationZ = ConfigHandler.getBeltOrientation(item);
62+
if (orientationZ != Float.MIN_VALUE) {
63+
// always do scaling and translations first before rotating, since the coordinate system rotates with the item
64+
// and makes translations afterwards so much harder!
65+
final float scale = 0.6F;
6166
matrices.scale(scale, scale, scale);
62-
if (this.mainArm == Arm.LEFT) {
63-
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180F));
64-
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-25F));
65-
matrices.translate(-2.5F / 16F, 2F / 16F, 1.25F / 16F);
67+
68+
if (isInverted) {
69+
matrices.translate(-6 / 16F - 0.025F - offset / 16F, 1F, -0.5 / 16F);
6670
} else {
67-
matrices.translate(-1F / 16F, 0.25F / 16F, 1.0F / 16F);
68-
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(25F));
71+
matrices.translate(6 / 16F + 0.025F + offset / 16F, 1F, -0.5 / 16F);
6972
}
73+
74+
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(90F));
75+
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(orientationZ));
7076
} else {
71-
final int z = ConfigHandler.getToolOrientation(this.mainStack.getItem());
72-
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(z));
73-
}
77+
orientationZ = ConfigHandler.getBackOrientation(item);
7478

75-
if (ConfigHandler.isBeltTool(this.mainStack.getItem())) {
76-
float swordScale = 0.8F;
77-
matrices.scale(swordScale, swordScale, swordScale);
79+
if (orientationZ != Float.MIN_VALUE) {
80+
// default shield doesn't look good. So we scale it up and
81+
if (item instanceof ShieldItem) {
82+
float scale = 1.5F;
83+
matrices.scale(scale, scale, scale);
7884

79-
if (this.mainArm == Arm.LEFT) {
80-
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(90F));
81-
matrices.translate(0.19F, 0.6F, -0.33F);
82-
} else {
83-
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(270F));
84-
matrices.translate(0.19F, 0.6F, 0.33F);
85-
}
86-
}
85+
if (isInverted) {
86+
// tiny difference to avoid z-fighting if main and offhand item get rendered at the same time
87+
matrices.translate(0F, 0, 0.001);
8788

88-
if (age > 0) {
89-
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(age * 40F));
90-
}
91-
MinecraftClient.getInstance().getItemRenderer().renderItem(this.mainStack, ModelTransformationMode.FIXED, light, OverlayTexture.DEFAULT_UV, matrices, provider, null, 0);
92-
}
93-
if (!this.offStack.isEmpty()) {
94-
if (this.mainArm == Arm.LEFT) {
95-
matrices.scale(-1F, 1F, -1F);
96-
}
97-
if (this.offStack.getItem() instanceof ShieldItem) {
98-
float scale = 1.5F;
99-
matrices.scale(scale, scale, scale);
100-
if (this.mainArm == Arm.RIGHT) {
101-
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180F));
102-
matrices.translate(-2.5F / 16F, 2F / 16F, 1.25F / 16F);
103-
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-25F));
89+
matrices.translate(1 / 16F, 3 / 16F, 0.025F + offset / 16F);
90+
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(orientationZ));
91+
} else {
92+
matrices.translate(-1 / 16F, 3 / 16F, 0.025F + offset / 16F);
93+
matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(90 + orientationZ));
94+
}
95+
96+
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180F));
97+
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(90));
98+
} else {
99+
matrices.translate(0F, 4F / 16F, 1.91F / 16F + 0.025F + offset / 16F);
100+
101+
if (isInverted) {
102+
// tiny difference to avoid z-fighting if main and offhand item get rendered at the same time
103+
matrices.translate(0F, 0, 0.001);
104+
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180F));
105+
}
106+
107+
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(orientationZ));
108+
109+
// again special case for fishing rod and alike since they look wierd with the fishing line defying gravity
110+
if (item instanceof FishingRodItem || item instanceof OnAStickItem) {
111+
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(180F));
112+
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(90F));
113+
}
114+
115+
if (age > 0) {
116+
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(age * 40F));
117+
}
118+
}
104119
} else {
105-
matrices.translate(-1F / 16F, 0.25F / 16F, 1.0F / 16F);
106-
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(25F));
120+
BackTools.LOGGER.info("Item {} was marked as enabled, but was neither a back nor a belt tool!", stack.getItem());
121+
matrices.pop();
122+
return; // Early return, without render, if neither back nor belt tool
107123
}
108-
} else {
109-
final int z = ConfigHandler.getToolOrientation(this.mainStack.getItem());
110-
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(z));
111124
}
112125

113-
if (age > 0) {
114-
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(age * 40F));
115-
}
116-
MinecraftClient.getInstance().getItemRenderer().renderItem(this.offStack, ModelTransformationMode.FIXED, light, OverlayTexture.DEFAULT_UV, matrices, provider, null, 0);
126+
MinecraftClient.getInstance().getItemRenderer().renderItem(stack, ModelTransformationMode.FIXED, light, OverlayTexture.DEFAULT_UV, matrices, provider, null, 0);
127+
matrices.pop();
117128
}
118129
}
119130

src/main/java/com/daniking/backtools/BackToolsConfig.java

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,64 @@
66
import net.fabricmc.api.EnvType;
77
import net.fabricmc.api.Environment;
88

9-
import java.util.ArrayList;
109
import java.util.Arrays;
1110
import java.util.List;
1211

1312
@Environment(EnvType.CLIENT)
1413
@Config(name = "BackTools")
1514
public class BackToolsConfig implements ConfigData {
16-
@Comment(value = "\nThese options affect only the client that loads the mod.\nIt is not possible to override the environment of the mod.")
15+
@Comment(value = """
16+
These options affect only the client that loads the mod.
17+
It is not possible to override the environment of the mod.""")
1718
public final String environment = EnvType.CLIENT.name();
18-
@Comment(value = "What items should render on your belt by their resource name. Eg: minecraft:diamond_hoe")
19-
public List<String> beltTools = new ArrayList<>();
20-
@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.")
21-
public List<String> enabledTools = new ArrayList<>();
22-
@Comment(value = "Disabled tools, by their resource name. Eg: minecraft:diamond_hoe")
23-
public List<String> disabledTools = new ArrayList<>();
2419
@Comment(value =
2520
"""
26-
Tool orientation, by class file and degrees.
27-
Entries starting with "#" are tags (https://minecraft.wiki/w/Tag)
28-
Leading namespace (e.g. minecraft:) is optional.
29-
Separate with ":" for rotation.
30-
Later occurrences of the same item override the previous once (Like in hoes override their config values set in mining).
31-
Item types not listed here will default to 0.
32-
"See defaults for examples.""")
33-
public List<String> toolOrientation = Arrays.asList("#minecraft:enchantable/mining" + ":0", "#minecraft:hoes" + ":0", "#minecraft:enchantable/fishing" + ":0", "#minecraft:enchantable/trident" + ":0", "bow" + ":90", "crossbow" + ":90");
21+
Back tool orientation, by item id, or tag and degrees for rotation, separated by a colon ":".
22+
What items should render on your back
23+
24+
- Entries starting with a hash "#" are tags (https://minecraft.wiki/w/Tag)
25+
- Entries without a leading hash "#" are item identifiers
26+
- Entries starting with a minus "-" will remove them from the list.
27+
E.g.
28+
> "#minecraft:hoes", -iron_hoe" will do all hoes but the iron one.
29+
> "minecraft:iron_hoe, -#hoes" will do no hoes at all.
30+
> "-iron_hoe #minecraft:hoes" will do all hoes,
31+
since the iron one is removed without being in the list in the list in the first place,
32+
and then added with all the other hoes in the tag.
33+
- Later occurrences of the same item will override all the previous ones
34+
- Leading namespace (e.g. minecraft:) is optional.
35+
- See defaults for examples""")
36+
public List<String> backTools = Arrays.asList(
37+
"#minecraft:pickaxes:0",
38+
"#minecraft:axes:0",
39+
"#minecraft:shovels:0",
40+
"#minecraft:hoes:0",
41+
"minecraft:fishing_rod:0",
42+
"minecraft:carrot_on_a_stick:0",
43+
"minecraft:warped_fungus_on_a_stick:0",
44+
"minecraft:shears:0",
45+
"#minecraft:swords:0",
46+
"minecraft:mace:-22.5",
47+
"minecraft:trident:0",
48+
"minecraft:bow:90",
49+
"minecraft:crossbow:90",
50+
"minecraft:shield:65");
51+
@Comment(value = """
52+
Belt tool orientation, by item id, or tag and degrees for rotation, separated by a colon ":".
53+
What items should render on your belt, overwriting a possible occurrence in the backTools list,
54+
with one exception: a negation here will not remove it from the backtools.
55+
So, if for example "iron_hoe" is added to backTools, and "-iron_hoe" is added to beltTools,
56+
it will stay in the backTools list.
57+
However, if both have a "iron_hoe" entry, the hoe will render on the belt.
58+
59+
Else wise same rules as above.""")
60+
public List<String> beltTools = Arrays.asList(
61+
"#minecraft:bundles:180",
62+
"minecraft:potion:180",
63+
"minecraft:splash_potion:180",
64+
"minecraft:lingering_potion:180",
65+
"minecraft:lead:180"
66+
);
3467
@Comment(value = "Get in swimming position and your tools go \"Weeee\"")
3568
public boolean helicopterMode = false;
3669
@Comment(value = "If true, tools render with capes")

src/main/java/com/daniking/backtools/ClientSetup.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ public void onInitializeClient() {
2121
config = AutoConfig.getConfigHolder(BackToolsConfig.class).getConfig();
2222

2323
// since we depend on item tags, our config can't load until the tags are loaded first. (creating / joining worlds)
24-
CommonLifecycleEvents.TAGS_LOADED.register((registries, client) -> ConfigHandler.init());
24+
CommonLifecycleEvents.TAGS_LOADED.register((registries, client) -> ConfigHandler.reload());
2525
}
2626
}

0 commit comments

Comments
 (0)