Remove build artifacts, dev tool configs, unused dependencies, and third-party source dumps. Add proper README, update .gitignore, clean up Makefile.
225 lines
7.6 KiB
Java
225 lines
7.6 KiB
Java
package com.tiedup.remake.client.renderer;
|
|
|
|
import com.mojang.blaze3d.vertex.PoseStack;
|
|
import com.mojang.math.Axis;
|
|
import com.tiedup.remake.client.animation.render.RenderConstants;
|
|
import com.tiedup.remake.client.model.DamselModel;
|
|
import com.tiedup.remake.compat.wildfire.WildfireCompat;
|
|
import com.tiedup.remake.compat.wildfire.render.WildfireDamselLayer;
|
|
import com.tiedup.remake.entities.AbstractTiedUpNpc;
|
|
import net.minecraft.client.model.HumanoidArmorModel;
|
|
import net.minecraft.client.model.geom.ModelLayers;
|
|
import net.minecraft.client.renderer.MultiBufferSource;
|
|
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
|
import net.minecraft.client.renderer.entity.HumanoidMobRenderer;
|
|
import net.minecraft.client.renderer.entity.layers.HumanoidArmorLayer;
|
|
import net.minecraft.client.renderer.entity.layers.ItemInHandLayer;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraftforge.api.distmarker.Dist;
|
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
|
|
/**
|
|
* Renderer for AbstractTiedUpNpc and all subtypes (Kidnapper, Elite, Archer, Merchant, Shiny).
|
|
*
|
|
* <p>Uses ISkinnedEntity interface for polymorphic texture lookup.
|
|
* Each entity subclass overrides getSkinTexture() to return the appropriate texture.
|
|
*
|
|
* <p><b>Issue #19 fix:</b> Replaced 6+ instanceof checks with single interface call.
|
|
*/
|
|
@OnlyIn(Dist.CLIENT)
|
|
public class DamselRenderer
|
|
extends HumanoidMobRenderer<AbstractTiedUpNpc, DamselModel>
|
|
{
|
|
|
|
/**
|
|
* Normal arms model (4px wide - Steve model).
|
|
*/
|
|
private final DamselModel normalModel;
|
|
|
|
/**
|
|
* Slim arms model (3px wide - Alex model).
|
|
*/
|
|
private final DamselModel slimModel;
|
|
|
|
/**
|
|
* Create renderer.
|
|
*
|
|
* Phase 19: Uses vanilla ModelLayers.PLAYER for full layer support (jacket, sleeves, pants).
|
|
*/
|
|
public DamselRenderer(EntityRendererProvider.Context context) {
|
|
super(
|
|
context,
|
|
new DamselModel(context.bakeLayer(ModelLayers.PLAYER), false),
|
|
0.5f // Shadow radius
|
|
);
|
|
// Store both models for runtime swapping
|
|
this.normalModel = this.getModel();
|
|
this.slimModel = new DamselModel(
|
|
context.bakeLayer(ModelLayers.PLAYER_SLIM),
|
|
true
|
|
);
|
|
|
|
// Add armor render layer (renders equipped armor)
|
|
this.addLayer(
|
|
new HumanoidArmorLayer<>(
|
|
this,
|
|
new HumanoidArmorModel<>(
|
|
context.bakeLayer(ModelLayers.PLAYER_INNER_ARMOR)
|
|
),
|
|
new HumanoidArmorModel<>(
|
|
context.bakeLayer(ModelLayers.PLAYER_OUTER_ARMOR)
|
|
),
|
|
context.getModelManager()
|
|
)
|
|
);
|
|
|
|
// Add item in hand layer (renders held items)
|
|
this.addLayer(
|
|
new ItemInHandLayer<>(this, context.getItemInHandRenderer())
|
|
);
|
|
|
|
// Add Wildfire breast layer BEFORE bondage (so bondage renders on top of breasts)
|
|
if (WildfireCompat.isLoaded()) {
|
|
this.addLayer(
|
|
new WildfireDamselLayer<>(this, context.getModelSet())
|
|
);
|
|
}
|
|
|
|
// Add V2 bondage render layer (GLB-based V2 equipment rendering)
|
|
this.addLayer(new com.tiedup.remake.v2.bondage.client.V2BondageRenderLayer<>(this));
|
|
}
|
|
|
|
/**
|
|
* Render the entity.
|
|
* Uses entity's hasSlimArms() for model selection.
|
|
*
|
|
* Phase 19: Wearer layer hiding is now handled in DamselModel.setupAnim()
|
|
* to ensure it happens after visibility resets.
|
|
*
|
|
* DOG pose: X rotation is applied in setupRotations() AFTER Y rotation,
|
|
* so the "belly down" direction follows entity facing.
|
|
* Head compensation is applied in DamselModel.setupAnim().
|
|
* Body rotation smoothing is handled in AbstractTiedUpNpc.tick().
|
|
*/
|
|
@Override
|
|
public void render(
|
|
AbstractTiedUpNpc entity,
|
|
float entityYaw,
|
|
float partialTicks,
|
|
PoseStack poseStack,
|
|
MultiBufferSource buffer,
|
|
int packedLight
|
|
) {
|
|
// Use entity's hasSlimArms() - each entity type overrides this appropriately
|
|
boolean useSlim = entity.hasSlimArms();
|
|
|
|
// Swap to appropriate model
|
|
this.model = useSlim ? this.slimModel : this.normalModel;
|
|
|
|
// Apply vertical offset for sitting/kneeling/dog poses
|
|
// This ensures the model AND all layers (gag, blindfold, etc.) move together
|
|
float verticalOffset = getVerticalOffset(entity);
|
|
boolean pushedPose = false;
|
|
if (verticalOffset != 0) {
|
|
poseStack.pushPose();
|
|
pushedPose = true;
|
|
// Convert from model units (16 = 1 block) to render units
|
|
poseStack.translate(0, verticalOffset / 16.0, 0);
|
|
}
|
|
|
|
// Call parent render
|
|
// Note: Wearer layer hiding happens in DamselModel.setupAnim()
|
|
super.render(
|
|
entity,
|
|
entityYaw,
|
|
partialTicks,
|
|
poseStack,
|
|
buffer,
|
|
packedLight
|
|
);
|
|
|
|
if (pushedPose) {
|
|
poseStack.popPose();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get vertical offset for sitting/kneeling/dog poses.
|
|
* Returns offset in model units (16 units = 1 block).
|
|
*
|
|
* @param entity The entity to check
|
|
* @return Vertical offset (negative = down)
|
|
*/
|
|
private float getVerticalOffset(AbstractTiedUpNpc entity) {
|
|
if (entity.isSitting()) {
|
|
return RenderConstants.DAMSEL_SIT_OFFSET;
|
|
} else if (entity.isKneeling()) {
|
|
return RenderConstants.DAMSEL_KNEEL_OFFSET;
|
|
} else if (entity.isDogPose()) {
|
|
return RenderConstants.DAMSEL_DOG_OFFSET;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Get the texture location based on entity type.
|
|
*
|
|
* <p>Issue #19 fix: Uses ISkinnedEntity interface instead of instanceof cascade.
|
|
* Each entity subclass implements getSkinTexture() to return appropriate texture.
|
|
*/
|
|
@Override
|
|
public ResourceLocation getTextureLocation(AbstractTiedUpNpc entity) {
|
|
// ISkinnedEntity provides polymorphic skin texture lookup
|
|
// Each entity type (Damsel, Kidnapper, Elite, Archer, Merchant, Shiny)
|
|
// overrides getSkinTexture() to return the correct texture
|
|
return entity.getSkinTexture();
|
|
}
|
|
|
|
/**
|
|
* Apply scale transformation.
|
|
*/
|
|
@Override
|
|
protected void scale(
|
|
AbstractTiedUpNpc entity,
|
|
PoseStack poseStack,
|
|
float partialTick
|
|
) {
|
|
poseStack.scale(0.9375f, 0.9375f, 0.9375f);
|
|
}
|
|
|
|
/**
|
|
* Setup rotations for the entity.
|
|
*
|
|
* DOG pose: After Y rotation is applied by parent, add X rotation
|
|
* to make the body horizontal. This is applied in entity-local space,
|
|
* so the "belly down" direction follows the entity's facing.
|
|
*/
|
|
@Override
|
|
protected void setupRotations(
|
|
AbstractTiedUpNpc entity,
|
|
PoseStack poseStack,
|
|
float ageInTicks,
|
|
float rotationYaw,
|
|
float partialTicks
|
|
) {
|
|
// Call parent to apply Y rotation (body facing)
|
|
super.setupRotations(
|
|
entity,
|
|
poseStack,
|
|
ageInTicks,
|
|
rotationYaw,
|
|
partialTicks
|
|
);
|
|
|
|
// DOG pose: Apply X rotation to make body horizontal
|
|
// This happens AFTER Y rotation, so it's in entity-local space
|
|
if (entity.isDogPose()) {
|
|
// Rotate -90° on X axis around the model's pivot point
|
|
// Pivot at waist height (12 model units = 0.75 blocks up from feet)
|
|
poseStack.translate(0, 0.75, 0);
|
|
poseStack.mulPose(Axis.XP.rotationDegrees(-90));
|
|
poseStack.translate(0, -0.75, 0);
|
|
}
|
|
}
|
|
}
|