Skip to content

Commit

Permalink
Add model support for bows
Browse files Browse the repository at this point in the history
Tool model now supports propigating item overrides, allowing us to add pulling properties
Added properties for pulling for bows in a convenient location
  • Loading branch information
KnightMiner committed Nov 28, 2022
1 parent 755ea9b commit 2978e7c
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package slimeknights.tconstruct.library.client.model;

import net.minecraft.client.renderer.item.ItemProperties;
import net.minecraft.client.renderer.item.ItemPropertyFunction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import slimeknights.tconstruct.library.tools.nbt.ToolStack;
import slimeknights.tconstruct.library.tools.stat.ToolStats;

/** Properties for tinker tools */
public class TinkerItemProperties {
/** ID for the pull property */
private static final ResourceLocation PULL_ID = new ResourceLocation("pull");
/** Property for bow pull amount */
private static final ItemPropertyFunction PULL = (stack, level, holder, seed) -> {
if (holder == null) {
return 0.0F;
}
return holder.getUseItem() != stack ? 0.0F : (float)(stack.getUseDuration() - holder.getUseItemRemainingTicks()) * ToolStack.from(stack).getStats().get(ToolStats.DRAW_SPEED) / 20.0F;
};

/** ID for the pulling property */
private static final ResourceLocation PULLING_ID = new ResourceLocation("pulling");
/** Boolean indicating the bow is pulling */
private static final ItemPropertyFunction PULLING = (stack, level, holder, seed) -> holder != null && holder.isUsingItem() && holder.getUseItem() == stack ? 1.0F : 0.0F;

/** Registers properties for a bow */
public static void registerBowProperties(Item item) {
ItemProperties.register(item, PULL_ID, PULL);
ItemProperties.register(item, PULLING_ID, PULLING);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ public BakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<M
// Map<Modifier,IBakedModifierModel> modifierModels = ModifierModelManager.getModelsForTool(smallModifierRoots, isLarge ? largeModifierRoots : Collections.emptyList());

Transformation largeTransforms = isLarge ? new Transformation(new Vector3f((offset.x - 8) / 32, (-offset.y - 8) / 32, 0), null, new Vector3f(2, 2, 1), null) : null;
overrides = new MaterialOverrideHandler(owner, toolParts, firstModifiers, largeTransforms, modifierModels); // TODO: nest original overrides?
overrides = new MaterialOverrideHandler(owner, toolParts, firstModifiers, largeTransforms, modifierModels, overrides); // TODO: nest original overrides?
// bake the original with no modifiers or materials
return bakeInternal(owner, spriteGetter, largeTransforms, toolParts, modifierModels, firstModifiers, Collections.emptyList(), null, overrides);
}
Expand Down Expand Up @@ -386,6 +386,9 @@ public static ToolPart read(JsonObject json) {
* Dynamic override handler to swap in the material texture
*/
public static final class MaterialOverrideHandler extends ItemOverrides {
/** If true, we are currently resolving a nested model and should ignore further nesting */
private static boolean ignoreNested = false;

// contains all the baked models since they'll never change, cleared automatically as the baked model is discarded
private final Cache<ToolCacheKey, BakedModel> cache = CacheBuilder
.newBuilder()
Expand All @@ -400,13 +403,15 @@ public static final class MaterialOverrideHandler extends ItemOverrides {
@Nullable
private final Transformation largeTransforms;
private final Map<ModifierId,IBakedModifierModel> modifierModels;
private final ItemOverrides nested;

private MaterialOverrideHandler(IModelConfiguration owner, List<ToolPart> toolParts, List<ModifierId> firstModifiers, @Nullable Transformation largeTransforms, Map<ModifierId,IBakedModifierModel> modifierModels) {
private MaterialOverrideHandler(IModelConfiguration owner, List<ToolPart> toolParts, List<ModifierId> firstModifiers, @Nullable Transformation largeTransforms, Map<ModifierId,IBakedModifierModel> modifierModels, ItemOverrides nested) {
this.owner = owner;
this.toolParts = toolParts;
this.firstModifiers = firstModifiers;
this.largeTransforms = largeTransforms;
this.modifierModels = modifierModels;
this.nested = nested;
}

/**
Expand All @@ -432,6 +437,18 @@ private BakedModel bakeDynamic(List<MaterialVariantId> materials, IToolStackView

@Override
public BakedModel resolve(BakedModel originalModel, ItemStack stack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) {
// first, resolve the overrides
// hack: we set a boolean flag to prevent that model from resolving its nested overrides, no nesting multiple deep
if (!ignoreNested) {
BakedModel overridden = nested.resolve(originalModel, stack, world, entity, seed);
if (overridden != null && overridden != originalModel) {
ignoreNested = true;
// if the override does have a new model, make sure to fetch its overrides to handle the nested texture as its most likely a tool model
BakedModel finalModel = overridden.getOverrides().resolve(overridden, stack, world, entity, seed);
ignoreNested = false;
return finalModel;
}
}
// use material IDs for the sake of internal rendering materials
List<MaterialVariantId> materialIds = MaterialIdNBT.from(stack).getMaterials();
IToolStackView tool = ToolStack.from(stack);
Expand Down

0 comments on commit 2978e7c

Please sign in to comment.