mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2024-11-22 12:37:59 +01:00
Improve modding support for adding custom gear
This commit is contained in:
parent
eefb58e6b7
commit
abfab92d78
19 changed files with 144 additions and 69 deletions
|
@ -2,7 +2,7 @@ package com.minelittlepony.client.model;
|
|||
|
||||
import com.minelittlepony.client.model.armour.PonyArmourModel;
|
||||
import com.minelittlepony.client.render.EquineRenderManager;
|
||||
import com.minelittlepony.model.capabilities.fabric.PonyModelPrepareCallback;
|
||||
import com.minelittlepony.model.fabric.PonyModelPrepareCallback;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.api.pony.meta.Sizes;
|
||||
import com.minelittlepony.client.model.armour.ArmourWrapper;
|
||||
|
|
|
@ -6,7 +6,7 @@ import net.minecraft.entity.LivingEntity;
|
|||
import net.minecraft.util.Arm;
|
||||
import net.minecraft.util.Hand;
|
||||
|
||||
import com.minelittlepony.model.capabilities.fabric.PonyModelPrepareCallback;
|
||||
import com.minelittlepony.model.fabric.PonyModelPrepareCallback;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.IPonyData;
|
||||
import com.minelittlepony.api.pony.meta.Size;
|
||||
|
|
|
@ -4,9 +4,9 @@ import net.minecraft.entity.LivingEntity;
|
|||
|
||||
import com.minelittlepony.api.pony.IPonyData;
|
||||
import com.minelittlepony.model.IModel;
|
||||
import com.minelittlepony.model.IModelWrapper;
|
||||
import com.minelittlepony.model.armour.IArmour;
|
||||
import com.minelittlepony.model.armour.IEquestrianArmour;
|
||||
import com.minelittlepony.model.capabilities.IModelWrapper;
|
||||
import com.minelittlepony.mson.api.ModelKey;
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,7 +25,7 @@ public abstract class AbstractGear extends Model implements IGear {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId) {
|
||||
public void render(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId) {
|
||||
render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,11 +11,13 @@ import com.minelittlepony.api.pony.meta.Wearable;
|
|||
import com.minelittlepony.common.util.Color;
|
||||
import com.minelittlepony.model.BodyPart;
|
||||
import com.minelittlepony.model.IModel;
|
||||
import com.minelittlepony.model.PonyModelConstants;
|
||||
import com.minelittlepony.model.gear.IRenderContext;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ChristmasHat extends AbstractGear {
|
||||
public class ChristmasHat extends AbstractGear implements PonyModelConstants {
|
||||
|
||||
private static boolean dayChecked = false;
|
||||
private static boolean dayResult = false;
|
||||
|
@ -49,12 +51,12 @@ public class ChristmasHat extends AbstractGear {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setLivingAnimations(IModel model, Entity entity) {
|
||||
public void setModelAttributes(IModel model, Entity entity) {
|
||||
tint = model.getMetadata().getGlowColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRotationAndAngles(boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
|
||||
public void pose(boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
|
||||
float pi = PI * (float) Math.pow(swing, 16);
|
||||
|
||||
float mve = move * 0.6662f;
|
||||
|
@ -79,7 +81,7 @@ public class ChristmasHat extends AbstractGear {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId) {
|
||||
public void render(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId) {
|
||||
if (tint != 0) {
|
||||
red = Color.r(tint);
|
||||
green = Color.g(tint);
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
package com.minelittlepony.client.model.gear;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.model.IModel;
|
||||
import com.minelittlepony.model.gear.IGear;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface IRenderContext<T extends Entity, M extends IModel> {
|
||||
|
||||
IRenderContext<?, ?> NULL = (e, g) -> null;
|
||||
|
||||
default boolean shouldRender(M model, T entity, Wearable wearable, IGear gear) {
|
||||
return gear.canRender(model, entity);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
default IModel getEntityModel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
Identifier getDefaultTexture(T entity, Wearable wearable);
|
||||
}
|
|
@ -7,6 +7,7 @@ import net.minecraft.util.Identifier;
|
|||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.model.BodyPart;
|
||||
import com.minelittlepony.model.IModel;
|
||||
import com.minelittlepony.model.gear.IRenderContext;
|
||||
import com.minelittlepony.model.gear.IStackable;
|
||||
|
||||
public class Muffin extends AbstractGear implements IStackable {
|
||||
|
|
|
@ -5,6 +5,8 @@ import com.minelittlepony.api.pony.meta.Wearable;
|
|||
import com.minelittlepony.model.BodyPart;
|
||||
import com.minelittlepony.model.IModel;
|
||||
import com.minelittlepony.model.IPegasus;
|
||||
import com.minelittlepony.model.PonyModelConstants;
|
||||
import com.minelittlepony.model.gear.IRenderContext;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -15,7 +17,7 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class SaddleBags extends AbstractGear {
|
||||
public class SaddleBags extends AbstractGear implements PonyModelConstants {
|
||||
|
||||
public static final Identifier TEXTURE = new Identifier("minelittlepony", "textures/models/saddlebags.png");
|
||||
|
||||
|
@ -37,7 +39,7 @@ public class SaddleBags extends AbstractGear {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setLivingAnimations(IModel model, Entity entity) {
|
||||
public void setModelAttributes(IModel model, Entity entity) {
|
||||
this.model = model;
|
||||
|
||||
hangLow = false;
|
||||
|
@ -48,7 +50,7 @@ public class SaddleBags extends AbstractGear {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setRotationAndAngles(boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
|
||||
public void pose(boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
|
||||
float pi = PI * (float) Math.pow(swing, 16);
|
||||
|
||||
float mve = move * 0.6662f;
|
||||
|
@ -75,7 +77,7 @@ public class SaddleBags extends AbstractGear {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void renderPart(MatrixStack stack, VertexConsumer renderContext, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId) {
|
||||
public void render(MatrixStack stack, VertexConsumer renderContext, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId) {
|
||||
dropAmount = model.getMetadata().getInterpolator(interpolatorId).interpolate("dropAmount", dropAmount, 3);
|
||||
|
||||
stack.push();
|
||||
|
|
|
@ -7,6 +7,7 @@ import net.minecraft.util.Identifier;
|
|||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.model.BodyPart;
|
||||
import com.minelittlepony.model.IModel;
|
||||
import com.minelittlepony.model.gear.IRenderContext;
|
||||
import com.minelittlepony.model.gear.IStackable;
|
||||
|
||||
public class Stetson extends AbstractGear implements IStackable {
|
||||
|
|
|
@ -7,6 +7,7 @@ import net.minecraft.util.Identifier;
|
|||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.model.BodyPart;
|
||||
import com.minelittlepony.model.IModel;
|
||||
import com.minelittlepony.model.gear.IRenderContext;
|
||||
import com.minelittlepony.model.gear.IStackable;
|
||||
|
||||
public class WitchHat extends AbstractGear implements IStackable {
|
||||
|
|
|
@ -4,9 +4,9 @@ import com.minelittlepony.api.pony.IPony;
|
|||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
import com.minelittlepony.client.model.ModelWrapper;
|
||||
import com.minelittlepony.client.model.gear.IRenderContext;
|
||||
import com.minelittlepony.model.BodyPart;
|
||||
import com.minelittlepony.model.PonyModelConstants;
|
||||
import com.minelittlepony.model.gear.IRenderContext;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
||||
import net.minecraft.client.render.entity.model.EntityModel;
|
||||
|
|
|
@ -8,6 +8,7 @@ import net.minecraft.client.render.entity.model.EntityModel;
|
|||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
import com.google.common.collect.Streams;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
import com.minelittlepony.client.model.ModelType;
|
||||
|
@ -16,21 +17,27 @@ import com.minelittlepony.model.BodyPart;
|
|||
import com.minelittlepony.model.gear.IGear;
|
||||
import com.minelittlepony.model.gear.IStackable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class GearFeature<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> extends AbstractPonyFeature<T, M> {
|
||||
|
||||
private final Map<Wearable, IGear> gears;
|
||||
private static final List<Entry> MOD_GEARS = new ArrayList<>();
|
||||
|
||||
public static IGear addModGear(IGear gear) {
|
||||
MOD_GEARS.add(new Entry(gear, Wearable.NONE));
|
||||
return gear;
|
||||
}
|
||||
|
||||
private final List<Entry> gears;
|
||||
|
||||
public GearFeature(IPonyRenderContext<T, M> renderer) {
|
||||
super(renderer);
|
||||
|
||||
gears = ModelType.getWearables().collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
e -> e.getValue().createModel()
|
||||
));
|
||||
gears = Streams.concat(ModelType.getWearables().map(e -> new Entry(e.getValue().createModel(), e.getKey())), MOD_GEARS.stream()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -40,21 +47,20 @@ public class GearFeature<T extends LivingEntity, M extends EntityModel<T> & IPon
|
|||
return;
|
||||
}
|
||||
|
||||
M model = getModelWrapper().getBody();
|
||||
final M model = getModelWrapper().getBody();
|
||||
|
||||
Map<BodyPart, Float> renderStackingOffsets = new HashMap<>();
|
||||
final Map<BodyPart, Float> renderStackingOffsets = new HashMap<>();
|
||||
|
||||
for (Map.Entry<Wearable, IGear> entry : gears.entrySet()) {
|
||||
Wearable wearable = entry.getKey();
|
||||
IGear gear = entry.getValue();
|
||||
for (Entry entry : gears) {
|
||||
final IGear gear = entry.gear;
|
||||
|
||||
if (getContext().shouldRender(model, entity, wearable, gear)) {
|
||||
if (getContext().shouldRender(model, entity, entry.wearable, gear)) {
|
||||
stack.push();
|
||||
model.transform(gear.getGearLocation(), stack);
|
||||
model.getBodyPart(gear.getGearLocation()).rotate(stack);
|
||||
BodyPart part = gear.getGearLocation();
|
||||
model.transform(part, stack);
|
||||
model.getBodyPart(part).rotate(stack);
|
||||
|
||||
if (gear instanceof IStackable) {
|
||||
BodyPart part = gear.getGearLocation();
|
||||
renderStackingOffsets.compute(part, (k, v) -> {
|
||||
float offset = ((IStackable)gear).getStackingOffset();
|
||||
if (v != null) {
|
||||
|
@ -73,12 +79,22 @@ public class GearFeature<T extends LivingEntity, M extends EntityModel<T> & IPon
|
|||
|
||||
private void renderGear(M model, T entity, IGear gear, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, float limbDistance, float limbAngle, float tickDelta) {
|
||||
|
||||
gear.setLivingAnimations(model, entity);
|
||||
gear.setRotationAndAngles(model.getAttributes().isGoingFast, entity.getUuid(), limbDistance, limbAngle, model.getWobbleAmount(), tickDelta);
|
||||
gear.setModelAttributes(model, entity);
|
||||
gear.pose(model.getAttributes().isGoingFast, entity.getUuid(), limbDistance, limbAngle, model.getWobbleAmount(), tickDelta);
|
||||
|
||||
RenderLayer layer = RenderLayer.getEntityTranslucent(gear.getTexture(entity, getContext()));
|
||||
|
||||
VertexConsumer vertexConsumer = renderContext.getBuffer(layer);
|
||||
gear.renderPart(stack, vertexConsumer, lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1, entity.getUuid());
|
||||
gear.render(stack, vertexConsumer, lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1, entity.getUuid());
|
||||
}
|
||||
|
||||
static class Entry {
|
||||
IGear gear;
|
||||
Wearable wearable;
|
||||
|
||||
Entry(IGear gear, Wearable wearable) {
|
||||
this.gear = gear;
|
||||
this.wearable = wearable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.model.capabilities;
|
||||
package com.minelittlepony.model;
|
||||
|
||||
import com.minelittlepony.api.pony.IPonyData;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package com.minelittlepony.model.armour;
|
||||
|
||||
import com.minelittlepony.model.capabilities.IModelWrapper;
|
||||
import com.minelittlepony.model.IModelWrapper;
|
||||
|
||||
public interface IEquestrianArmour<V extends IArmour> extends IModelWrapper {
|
||||
/**
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
@ParametersAreNonnullByDefault
|
||||
package com.minelittlepony.model.capabilities.fabric;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.model.capabilities.fabric;
|
||||
package com.minelittlepony.model.fabric;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
|
@ -1,4 +1,4 @@
|
|||
@ParametersAreNonnullByDefault
|
||||
package com.minelittlepony.model.capabilities;
|
||||
package com.minelittlepony.model.fabric;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -1,14 +1,30 @@
|
|||
package com.minelittlepony.model.gear;
|
||||
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.client.model.gear.IRenderContext;
|
||||
import com.minelittlepony.client.render.entity.feature.GearFeature;
|
||||
import com.minelittlepony.model.BodyPart;
|
||||
import com.minelittlepony.model.IModel;
|
||||
import com.minelittlepony.model.IPart;
|
||||
|
||||
public interface IGear extends IPart {
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Interface for an accessory on a pony's body.
|
||||
*/
|
||||
public interface IGear {
|
||||
/**
|
||||
* Registers a custom gear to be used with the mod.
|
||||
* <p>
|
||||
* This would be awesome for creating socks.
|
||||
*/
|
||||
static IGear addModGear(IGear gear) {
|
||||
GearFeature.addModGear(gear);
|
||||
return gear;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this wearable can and is worn by the selected entity.
|
||||
|
@ -27,14 +43,39 @@ public interface IGear extends IPart {
|
|||
|
||||
/**
|
||||
* Gets the texture to use for this wearable.
|
||||
* Return null to use the same as the primary model.
|
||||
*
|
||||
* If you need to use the player's own skin, use {@link IRenderContext#getDefaultTexture(entity, wearable)}
|
||||
*/
|
||||
<T extends Entity> Identifier getTexture(T entity, IRenderContext<T, ?> context);
|
||||
|
||||
default <T extends Entity> RenderLayer getLayer(T entity, IRenderContext<T, ?> context) {
|
||||
return RenderLayer.getEntityTranslucent(getTexture(entity, context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Orients this wearable.
|
||||
*/
|
||||
default void setLivingAnimations(IModel model, Entity entity) {
|
||||
default void setModelAttributes(IModel model, Entity entity) {
|
||||
|
||||
}
|
||||
/**
|
||||
* Sets the model's various rotation angles.
|
||||
*
|
||||
* See {@link AbstractPonyMode.setRotationAndAngle} for an explanation of the various parameters.
|
||||
*/
|
||||
default void pose(boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders this model component.
|
||||
*/
|
||||
void render(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId);
|
||||
|
||||
/**
|
||||
* Sets whether this part should be rendered.
|
||||
*/
|
||||
default void setVisible(boolean visible) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package com.minelittlepony.model.gear;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.model.IModel;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A render context for instance of IGear.
|
||||
*
|
||||
* @param <T> The type of entity being rendered.
|
||||
* @param <M> The type of the entity's primary model.
|
||||
*/
|
||||
public interface IRenderContext<T extends Entity, M extends IModel> {
|
||||
/**
|
||||
* The empty context.
|
||||
*/
|
||||
IRenderContext<?, ?> NULL = (e, g) -> null;
|
||||
|
||||
/**
|
||||
* Checks whether the given wearable and gear are able to render for this specific entity and its renderer.
|
||||
*/
|
||||
default boolean shouldRender(M model, T entity, Wearable wearable, IGear gear) {
|
||||
return gear.canRender(model, entity);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
default M getEntityModel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default texture to use for this entity and wearable.
|
||||
*
|
||||
* May be the entity's own texture or a specific texture allocated for that wearable.
|
||||
*/
|
||||
Identifier getDefaultTexture(T entity, Wearable wearable);
|
||||
}
|
Loading…
Reference in a new issue