From 42081b38d47d7b3668451bc5afa16594e2a1c960 Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 5 Jun 2018 20:18:57 +0200 Subject: [PATCH] Implemented pony wearables as saddlebags and (soon) --- .../model/capabilities/IModel.java | 5 +++ .../model/capabilities/IModelPegasus.java | 17 ++++++++ .../model/components/PegasusWings.java | 40 ++++++++++--------- .../model/components/SaddleBags.java | 15 +++---- .../model/player/ModelAlicorn.java | 1 + .../model/player/ModelEarthPony.java | 33 ++++++++++++++- .../model/player/ModelPegasus.java | 1 + .../model/ponies/ModelVillagerPony.java | 33 +++++++++------ .../minelittlepony/pony/data/IPonyData.java | 2 + .../minelittlepony/pony/data/PonyData.java | 12 ++++++ .../pony/data/PonyWearable.java | 30 ++++++++++++++ .../pony/data/TriggerPixels.java | 22 +++++++++- 12 files changed, 170 insertions(+), 41 deletions(-) create mode 100644 src/main/java/com/minelittlepony/pony/data/PonyWearable.java diff --git a/src/main/java/com/minelittlepony/model/capabilities/IModel.java b/src/main/java/com/minelittlepony/model/capabilities/IModel.java index 3035d75b..027cbf60 100644 --- a/src/main/java/com/minelittlepony/model/capabilities/IModel.java +++ b/src/main/java/com/minelittlepony/model/capabilities/IModel.java @@ -3,6 +3,7 @@ package com.minelittlepony.model.capabilities; import com.minelittlepony.model.BodyPart; import com.minelittlepony.model.armour.PonyArmor; import com.minelittlepony.pony.data.IPonyData; +import com.minelittlepony.pony.data.PonyWearable; public interface IModel { @@ -59,4 +60,8 @@ public interface IModel { boolean isChild(); float getSwingAmount(); + + default boolean isWearing(PonyWearable wearable) { + return getMetadata().isWearing(wearable); + } } diff --git a/src/main/java/com/minelittlepony/model/capabilities/IModelPegasus.java b/src/main/java/com/minelittlepony/model/capabilities/IModelPegasus.java index 7a462af6..ea7a5ec2 100644 --- a/src/main/java/com/minelittlepony/model/capabilities/IModelPegasus.java +++ b/src/main/java/com/minelittlepony/model/capabilities/IModelPegasus.java @@ -1,5 +1,10 @@ package com.minelittlepony.model.capabilities; +import static com.minelittlepony.model.PonyModelConstants.LEFT_WING_ROTATE_ANGLE_Z_SNEAK; +import static com.minelittlepony.model.PonyModelConstants.ROTATE_270; + +import net.minecraft.util.math.MathHelper; + public interface IModelPegasus extends IModel { /** * Returns true if the wings are spread. @@ -7,4 +12,16 @@ public interface IModelPegasus extends IModel { default boolean wingsAreOpen() { return isSwimming() || isFlying() || isCrouching(); } + + + default float getWingRotationFactor(float ticks) { + if (isSwimming()) { + return (MathHelper.sin(ticks * 0.136f) / 2) + ROTATE_270; + } + if (isFlying()) { + return MathHelper.sin(ticks * 0.536f) + ROTATE_270 + 0.4f; + } + return LEFT_WING_ROTATE_ANGLE_Z_SNEAK; + } + } diff --git a/src/main/java/com/minelittlepony/model/components/PegasusWings.java b/src/main/java/com/minelittlepony/model/components/PegasusWings.java index 4f7c7690..20034aa6 100644 --- a/src/main/java/com/minelittlepony/model/components/PegasusWings.java +++ b/src/main/java/com/minelittlepony/model/components/PegasusWings.java @@ -7,6 +7,7 @@ import static com.minelittlepony.model.PonyModelConstants.*; import com.minelittlepony.model.AbstractPonyModel; import com.minelittlepony.model.capabilities.IModelPart; import com.minelittlepony.model.capabilities.IModelPegasus; +import com.minelittlepony.pony.data.PonyWearable; public class PegasusWings implements IModelPart { @@ -15,11 +16,14 @@ public class PegasusWings implements IModelPart { private final ModelWing leftWing; private final ModelWing rightWing; + private final ModelWing legacyWing; + public PegasusWings(T model, float yOffset, float stretch) { pegasus = model; - leftWing = new ModelWing(model, false, 4f, yOffset, stretch, 32); - rightWing = new ModelWing(model, true, -6f, yOffset, stretch, 16); + leftWing = new ModelWing(model, false, 4, yOffset, stretch, 32); + rightWing = new ModelWing(model, true, -6, yOffset, stretch, 16); + legacyWing = new ModelWing(model, true, -6, yOffset, stretch, 32); } @@ -28,6 +32,14 @@ public class PegasusWings implements IModelPart { } + public ModelWing getLeft() { + return leftWing; + } + + public ModelWing getRight() { + return pegasus.isWearing(PonyWearable.SADDLE_BAGS) ? legacyWing : rightWing; + } + @Override public void setRotationAndAngles(boolean rainboom, float move, float swing, float bodySwing, float ticks) { float flap = 0; @@ -44,31 +56,21 @@ public class PegasusWings implements IModelPart { flap = MathHelper.cos(mve + pi) * srt; } - leftWing.rotateWalking(flap); - rightWing.rotateWalking(-flap); + getLeft().rotateWalking(flap); + getRight().rotateWalking(-flap); if (pegasus.wingsAreOpen()) { - float flapAngle = getWingRotationFactor(ticks); - leftWing.rotateFlying(flapAngle); - rightWing.rotateFlying(-flapAngle); + float flapAngle = pegasus.getWingRotationFactor(ticks); + getLeft().rotateFlying(flapAngle); + getRight().rotateFlying(-flapAngle); } } - public float getWingRotationFactor(float ticks) { - if (pegasus.isSwimming()) { - return (MathHelper.sin(ticks * 0.136f) / 2) + ROTATE_270; - } - if (pegasus.isFlying()) { - return MathHelper.sin(ticks * 0.536f) + ROTATE_270 + 0.4f; - } - return LEFT_WING_ROTATE_ANGLE_Z_SNEAK; - } - @Override public void renderPart(float scale) { boolean standing = pegasus.wingsAreOpen(); - leftWing.render(standing, scale); - rightWing.render(standing, scale); + getLeft().render(standing, scale); + getRight().render(standing, scale); } } diff --git a/src/main/java/com/minelittlepony/model/components/SaddleBags.java b/src/main/java/com/minelittlepony/model/components/SaddleBags.java index 3809ac46..47db35ae 100644 --- a/src/main/java/com/minelittlepony/model/components/SaddleBags.java +++ b/src/main/java/com/minelittlepony/model/components/SaddleBags.java @@ -3,7 +3,6 @@ package com.minelittlepony.model.components; import static com.minelittlepony.model.PonyModelConstants.*; import com.minelittlepony.model.AbstractPonyModel; -import com.minelittlepony.model.capabilities.IModel; import com.minelittlepony.model.capabilities.IModelPart; import com.minelittlepony.render.plane.PlaneRenderer; @@ -17,11 +16,9 @@ public class SaddleBags implements IModelPart { private PlaneRenderer strap; - private IModel model; + private boolean hangLow = false; public SaddleBags(AbstractPonyModel model) { - this.model = model; - leftBag = new PlaneRenderer(model, 56, 19); rightBag = new PlaneRenderer(model, 56, 19); strap = new PlaneRenderer(model, 56, 19); @@ -69,7 +66,7 @@ public class SaddleBags implements IModelPart { float pi = PI * (float) Math.pow(swing, 16); float mve = move * 0.6662f; - float srt = swing / 4; + float srt = swing / 6; bodySwing = MathHelper.cos(mve + pi) * srt; @@ -80,9 +77,13 @@ public class SaddleBags implements IModelPart { rightBag.rotateAngleZ = -bodySwing; } + public void sethangingLow(boolean veryLow) { + hangLow = veryLow; + } + @Override public void renderPart(float scale) { - if (model.canFly()) { + if (hangLow) { GlStateManager.pushMatrix(); GlStateManager.translate(0, 0.3F, 0); } @@ -91,7 +92,7 @@ public class SaddleBags implements IModelPart { rightBag.render(scale); strap.render(scale); - if (model.canFly()) { + if (hangLow) { GlStateManager.popMatrix(); } } diff --git a/src/main/java/com/minelittlepony/model/player/ModelAlicorn.java b/src/main/java/com/minelittlepony/model/player/ModelAlicorn.java index 675cecb6..b6314073 100644 --- a/src/main/java/com/minelittlepony/model/player/ModelAlicorn.java +++ b/src/main/java/com/minelittlepony/model/player/ModelAlicorn.java @@ -25,6 +25,7 @@ public class ModelAlicorn extends ModelUnicorn implements IModelPegasus { if (canFly()) { wings.setRotationAndAngles(rainboom, move, swing, 0, ticks); + saddlebags.sethangingLow(wingsAreOpen()); } } diff --git a/src/main/java/com/minelittlepony/model/player/ModelEarthPony.java b/src/main/java/com/minelittlepony/model/player/ModelEarthPony.java index 3e682e28..b5341a9f 100644 --- a/src/main/java/com/minelittlepony/model/player/ModelEarthPony.java +++ b/src/main/java/com/minelittlepony/model/player/ModelEarthPony.java @@ -1,14 +1,17 @@ package com.minelittlepony.model.player; import com.minelittlepony.model.AbstractPonyModel; +import com.minelittlepony.model.components.SaddleBags; +import com.minelittlepony.pony.data.PonyWearable; import com.minelittlepony.render.PonyRenderer; - import net.minecraft.entity.Entity; public class ModelEarthPony extends AbstractPonyModel { private final boolean smallArms; + public SaddleBags saddlebags; + public PonyRenderer bipedCape; public ModelEarthPony(boolean smallArms) { @@ -25,6 +28,34 @@ public class ModelEarthPony extends AbstractPonyModel { } } + @Override + protected void shakeBody(float move, float swing, float bodySwing, float ticks) { + super.shakeBody(move, swing, bodySwing, ticks); + saddlebags.setRotationAndAngles(rainboom, move, swing, bodySwing, ticks); + } + + @Override + protected void renderBody(Entity entity, float move, float swing, float ticks, float headYaw, float headPitch, float scale) { + super.renderBody(entity, move, swing, ticks, headYaw, headPitch, scale); + + if (isWearing(PonyWearable.SADDLE_BAGS)) { + saddlebags.renderPart(scale); + } + } + + @Override + protected void initTextures() { + super.initTextures(); + saddlebags = new SaddleBags(this); + } + + @Override + protected void initPositions(float yOffset, float stretch) { + super.initPositions(yOffset, stretch); + + saddlebags.init(yOffset, stretch); + } + protected float getLegOutset() { if (smallArms) { if (isSleeping) return 2.6f; diff --git a/src/main/java/com/minelittlepony/model/player/ModelPegasus.java b/src/main/java/com/minelittlepony/model/player/ModelPegasus.java index dc8e8aed..95d4d055 100644 --- a/src/main/java/com/minelittlepony/model/player/ModelPegasus.java +++ b/src/main/java/com/minelittlepony/model/player/ModelPegasus.java @@ -23,6 +23,7 @@ public class ModelPegasus extends ModelEarthPony implements IModelPegasus { public void setRotationAngles(float move, float swing, float ticks, float headYaw, float headPitch, float scale, Entity entity) { super.setRotationAngles(move, swing, ticks, headYaw, headPitch, scale, entity); wings.setRotationAndAngles(rainboom, move, swing, 0, ticks); + saddlebags.sethangingLow(wingsAreOpen()); } @Override diff --git a/src/main/java/com/minelittlepony/model/ponies/ModelVillagerPony.java b/src/main/java/com/minelittlepony/model/ponies/ModelVillagerPony.java index 5cfdf302..af531fb8 100644 --- a/src/main/java/com/minelittlepony/model/ponies/ModelVillagerPony.java +++ b/src/main/java/com/minelittlepony/model/ponies/ModelVillagerPony.java @@ -1,19 +1,21 @@ package com.minelittlepony.model.ponies; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.monster.EntityZombieVillager; import net.minecraft.entity.passive.EntityVillager; import static com.minelittlepony.model.PonyModelConstants.*; import com.minelittlepony.model.components.SaddleBags; import com.minelittlepony.model.player.ModelAlicorn; +import com.minelittlepony.pony.data.PonyWearable; import com.minelittlepony.render.plane.PlaneRenderer; public class ModelVillagerPony extends ModelAlicorn { public PlaneRenderer apron, trinket; - public SaddleBags saddlebags; + private int profession; public ModelVillagerPony() { super(false); @@ -22,28 +24,35 @@ public class ModelVillagerPony extends ModelAlicorn { @Override protected void shakeBody(float move, float swing, float bodySwing, float ticks) { super.shakeBody(move, swing, bodySwing, ticks); - - saddlebags.setRotationAndAngles(rainboom, move, swing, bodySwing, ticks); apron.rotateAngleY = bodySwing; trinket.rotateAngleY = bodySwing; } + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTickTime) { + profession = getProfession(entity); + } + @Override protected void renderBody(Entity entity, float move, float swing, float ticks, float headYaw, float headPitch, float scale) { super.renderBody(entity, move, swing, ticks, headYaw, headPitch, scale); - int profession = getProfession(entity); - if (profession > -1) { - if (profession < 2) { - saddlebags.renderPart(scale); - } else if (profession == 2) { - trinket.render(scale); - } else if (profession > 2) { - apron.render(scale); - } + if (profession == 2) { + trinket.render(scale); + } else if (profession > 2) { + apron.render(scale); } } + @Override + public boolean isWearing(PonyWearable wearable) { + if (wearable == PonyWearable.SADDLE_BAGS) { + return profession > -1 && profession < 2; + } + + return super.isWearing(wearable); + } + protected int getProfession(Entity entity) { if (entity instanceof EntityVillager) { return ((EntityVillager) entity).getProfession(); diff --git a/src/main/java/com/minelittlepony/pony/data/IPonyData.java b/src/main/java/com/minelittlepony/pony/data/IPonyData.java index 74756255..671e92ee 100644 --- a/src/main/java/com/minelittlepony/pony/data/IPonyData.java +++ b/src/main/java/com/minelittlepony/pony/data/IPonyData.java @@ -35,4 +35,6 @@ public interface IPonyData extends IMetadataSection { * Returns true if and only if this metadata represents a pony that can cast magic. */ boolean hasMagic(); + + boolean isWearing(PonyWearable wearable); } diff --git a/src/main/java/com/minelittlepony/pony/data/PonyData.java b/src/main/java/com/minelittlepony/pony/data/PonyData.java index 6db2306a..74cd7eb3 100644 --- a/src/main/java/com/minelittlepony/pony/data/PonyData.java +++ b/src/main/java/com/minelittlepony/pony/data/PonyData.java @@ -19,12 +19,16 @@ public class PonyData implements IPonyData { private final PonySize size; private final int glowColor; + private final boolean[] wearables; + public PonyData() { race = PonyRace.HUMAN; tailSize = TailLengths.FULL; gender = PonyGender.MARE; size = PonySize.NORMAL; glowColor = 0x4444aa; + + wearables = new boolean[PonyWearable.values().length]; } private PonyData(BufferedImage image) { @@ -33,6 +37,8 @@ public class PonyData implements IPonyData { size = TriggerPixels.SIZE.readValue(image); gender = TriggerPixels.GENDER.readValue(image); glowColor = TriggerPixels.GLOW.readColor(image); + + wearables = TriggerPixels.WEARABLES.readFlags(image); } @Override @@ -65,6 +71,11 @@ public class PonyData implements IPonyData { return race != null && race.hasHorn() && glowColor != 0; } + @Override + public boolean isWearing(PonyWearable wearable) { + return wearables[wearable.ordinal()]; + } + @Override public String toString() { return MoreObjects.toStringHelper(this) @@ -72,6 +83,7 @@ public class PonyData implements IPonyData { .add("tailSize", tailSize) .add("gender", gender) .add("size", size) + .add("wearables", PonyWearable.flags(wearables)) .add("glowColor", "#" + Integer.toHexString(glowColor)) .toString(); } diff --git a/src/main/java/com/minelittlepony/pony/data/PonyWearable.java b/src/main/java/com/minelittlepony/pony/data/PonyWearable.java new file mode 100644 index 00000000..d78c4c15 --- /dev/null +++ b/src/main/java/com/minelittlepony/pony/data/PonyWearable.java @@ -0,0 +1,30 @@ +package com.minelittlepony.pony.data; + +import java.util.ArrayList; +import java.util.List; + +public enum PonyWearable implements ITriggerPixelMapped { + NONE(0), + SADDLE_BAGS(0xff0000), + HAT(0x00ff00); + + private int triggerValue; + + PonyWearable(int pixel) { + triggerValue = pixel; + } + + @Override + public int getTriggerPixel() { + return triggerValue; + } + + public static PonyWearable[] flags(boolean[] flags) { + List wears = new ArrayList(); + PonyWearable[] values = values(); + for (int i = 1; i < values.length; i++) { + if (flags[i]) wears.add(values[i]); + } + return wears.toArray(new PonyWearable[wears.size()]); + } +} diff --git a/src/main/java/com/minelittlepony/pony/data/TriggerPixels.java b/src/main/java/com/minelittlepony/pony/data/TriggerPixels.java index 0a0516f5..ded60e9d 100644 --- a/src/main/java/com/minelittlepony/pony/data/TriggerPixels.java +++ b/src/main/java/com/minelittlepony/pony/data/TriggerPixels.java @@ -11,8 +11,9 @@ public enum TriggerPixels { RACE(PonyRace.HUMAN, Channel.ALL, 0, 0), TAIL(TailLengths.FULL, Channel.ALL, 1, 0), GENDER(PonyGender.MARE, Channel.ALL, 2, 0), - SIZE(PonySize.NORMAL, Channel.ALL, 3, 0), - GLOW(null, Channel.RAW, 0, 1); + SIZE(PonySize.LARGE, Channel.ALL, 3, 0), + GLOW(null, Channel.RAW, 0, 1), + WEARABLES(PonyWearable.NONE, Channel.RAW, 1, 1); private int x; private int y; @@ -46,6 +47,23 @@ public enum TriggerPixels { return ITriggerPixelMapped.getByTriggerPixel((T)def, readColor(image)); } + public & ITriggerPixelMapped> boolean[] readFlags(BufferedImage image) { + boolean[] out = new boolean[def.getClass().getEnumConstants().length]; + readFlags(out, image); + return out; + } + + public & ITriggerPixelMapped> void readFlags(boolean[] out, BufferedImage image) { + readFlag(out, Channel.RED, image); + readFlag(out, Channel.GREEN, image); + readFlag(out, Channel.BLUE, image); + } + + private & ITriggerPixelMapped> void readFlag(boolean[] out, Channel channel, BufferedImage image) { + T value = ITriggerPixelMapped.getByTriggerPixel((T)def, channel.readValue(x, y, image)); + if (value != def) out[value.ordinal()] = true; + } + enum Channel { RAW(-1, 0), ALL(0xffffff, 0),