mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2025-03-14 07:30:08 +01:00
Compare commits
99 commits
4.11.0-bet
...
1.20.2
Author | SHA1 | Date | |
---|---|---|---|
|
57754d8dec | ||
|
ec8f92e151 | ||
|
e21ce62631 | ||
|
c78cf32bd4 | ||
|
4ef2d4ab54 | ||
|
82a89eb1ba | ||
|
8bf3bc38a4 | ||
|
e01580f804 | ||
|
040105c792 | ||
|
18591c0720 | ||
|
31a9a9b0e6 | ||
|
c46cbea872 | ||
|
299a81088c | ||
|
bdc807b102 | ||
|
e149e926d2 | ||
|
4d55f546bb | ||
|
c0e4620355 | ||
|
a3ea4f5982 | ||
|
39f4a7d26d | ||
|
71518d9478 | ||
|
dfa9ce8977 | ||
|
0d97f6b9d4 | ||
|
76211930d5 | ||
|
a40b55e142 | ||
|
aa08f12320 | ||
|
f3cc92dee6 | ||
|
9c8d6d0a86 | ||
|
8ce2fc4e6d | ||
|
7da44b879c | ||
|
f5bfa14bb1 | ||
|
d392b204a3 | ||
|
21a33ebc76 | ||
|
0895e94053 | ||
|
387c9307d0 | ||
|
475e96726e | ||
|
9d65185fcd | ||
|
c365c141ef | ||
|
a94137fda9 | ||
|
34087bd105 | ||
|
cb423186e7 | ||
|
af99765bf2 | ||
|
1faa192f33 | ||
|
b9baba84de | ||
|
814dac6414 | ||
|
667ce0ce4b | ||
|
8832beac32 | ||
|
4de3f3daa2 | ||
|
9064272771 | ||
|
011ceedafe | ||
|
2ed7f91786 | ||
|
d011c11689 | ||
|
060c4abfff | ||
|
9f77999baf | ||
|
fa0c903c0f | ||
|
a7acd2a1c1 | ||
|
101b2bd20c | ||
|
9334836aa7 | ||
|
a69140b761 | ||
|
50ce9f92d1 | ||
|
971f3623cf | ||
|
24e220bb29 | ||
|
f8b21e78ba | ||
|
131bc7cb3f | ||
|
31857e2de0 | ||
|
d3a5c80981 | ||
|
be5382ebad | ||
|
3ae6a48204 | ||
|
4717c9e458 | ||
|
e31ee1c53b | ||
|
509f6477f2 | ||
|
3322e7eaff | ||
|
4904c78e01 | ||
|
8dad366317 | ||
|
b1869c824e | ||
|
72ff58015d | ||
|
76a2e043b7 | ||
|
f54cd5682d | ||
|
26aa16d684 | ||
|
9f280f79eb | ||
|
b538174933 | ||
|
f70ec0996c | ||
|
c2337058f6 | ||
|
1c4fa62676 | ||
|
f5603b05b7 | ||
|
ca728ded81 | ||
|
24a8afc508 | ||
|
6013fa2ad5 | ||
|
2c6c23d05c | ||
|
0f9e865dc4 | ||
|
15274aba2b | ||
|
429cdb644e | ||
|
5cf082d28d | ||
|
dcb8631eb9 | ||
|
f99309cd55 | ||
|
5b9d85d8ea | ||
|
cd25b9e269 | ||
|
b37ffa9860 | ||
|
0e30b2c8dd | ||
|
4b842c9e9a |
141 changed files with 1592 additions and 1289 deletions
|
@ -6,6 +6,7 @@
|
|||
[](https://modrinth.com/mod/mine-little-pony)
|
||||
[](https://discord.gg/HbJSFyu)
|
||||

|
||||
[](https://crowdin.com/project/mine-little-pony)
|
||||

|
||||
|
||||
Turns players and mobs into ponies.
|
||||
|
|
12
build.gradle
12
build.gradle
|
@ -1,15 +1,15 @@
|
|||
buildscript {
|
||||
dependencies {
|
||||
classpath 'com.github.dexman545:Outlet:1.3.10'
|
||||
classpath 'com.github.dexman545:Outlet:1.6.1'
|
||||
}
|
||||
}
|
||||
plugins {
|
||||
id 'fabric-loom' version '1.3-SNAPSHOT'
|
||||
id 'fabric-loom' version '1.5-SNAPSHOT'
|
||||
id 'maven-publish'
|
||||
id 'com.modrinth.minotaur' version '2.+'
|
||||
id 'org.ajoberstar.reckon' version '0.13.0'
|
||||
id 'org.ajoberstar.reckon' version '0.13.1'
|
||||
}
|
||||
apply plugin: 'dex.plugins.outlet'
|
||||
apply plugin: 'io.github.dexman545.outlet'
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
|
@ -86,7 +86,9 @@ processResources {
|
|||
expand "version": project.version.toString(),
|
||||
"minecraftVersion": project.minecraft_version_range,
|
||||
"loaderVersion": ">=${project.loader_version}",
|
||||
"fabricVersion": ">=${project.fabric_version}"
|
||||
"fabricVersion": ">=${project.fabric_version}",
|
||||
"kirinVersion": ">=${project.kirin_version}",
|
||||
"msonVersion": ">=${project.mson_version}"
|
||||
}
|
||||
|
||||
from 'LICENSE'
|
||||
|
|
3
crowdin.yml
Normal file
3
crowdin.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
files:
|
||||
- source: src/main/resources/assets/minelittlepony/lang/en_us.json
|
||||
translation: /%original_path%/%locale_with_underscore%.%file_extension%
|
|
@ -3,10 +3,10 @@ org.gradle.daemon=false
|
|||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/develop
|
||||
minecraft_version=1.20.2-rc1
|
||||
yarn_mappings=1.20.2-rc1+build.2
|
||||
loader_version=0.14.22
|
||||
fabric_version=0.88.5+1.20.2
|
||||
minecraft_version=1.20.2
|
||||
yarn_mappings=1.20.2+build.4
|
||||
loader_version=0.15.1
|
||||
fabric_version=0.91.1+1.20.2
|
||||
|
||||
# Mod Properties
|
||||
group=com.minelittlepony
|
||||
|
@ -20,7 +20,7 @@ org.gradle.daemon=false
|
|||
modrinth_project_id=JBjInUXM
|
||||
|
||||
# Dependencies
|
||||
modmenu_version=8.0.0-beta.1
|
||||
kirin_version=1.16.0-beta.1+1.20.2
|
||||
hd_skins_version=6.11.0-beta.2+1.20.2
|
||||
mson_version=1.9.0-beta.1
|
||||
modmenu_version=8.0.0
|
||||
kirin_version=1.16.1+1.20.2
|
||||
hd_skins_version=6.12.4+1.20.2
|
||||
mson_version=1.9.3+1.20.2
|
||||
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,5 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
@ -1,14 +1,8 @@
|
|||
pluginManagement {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = 'Fabric'
|
||||
url = 'https://maven.fabricmc.net/'
|
||||
}
|
||||
maven {
|
||||
name = 'Jitpack'
|
||||
url = 'https://jitpack.io'
|
||||
}
|
||||
maven { name 'Fabric'; url 'https://maven.fabricmc.net/' }
|
||||
maven { name 'Jitpack'; url 'https://jitpack.io' }
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
|
2
skins
2
skins
|
@ -1 +1 @@
|
|||
Subproject commit 8987db558b16657245ab8d0b98be366f46dc157c
|
||||
Subproject commit 45dfe1101b4506077b3d3f2246b08c9b485735eb
|
|
@ -3,6 +3,7 @@ package com.minelittlepony.api.config;
|
|||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import com.minelittlepony.api.pony.meta.*;
|
||||
import com.minelittlepony.common.client.gui.VisibilityMode;
|
||||
import com.minelittlepony.common.util.GamePaths;
|
||||
import com.minelittlepony.common.util.settings.*;
|
||||
|
||||
|
@ -25,13 +26,13 @@ public class PonyConfig extends Config {
|
|||
* Sets the pony level. Want MOAR PONEHS? Well here you go.
|
||||
*/
|
||||
public final Setting<PonyLevel> ponyLevel = value("ponylevel", PonyLevel.PONIES)
|
||||
.addComment("How much pony do you want?")
|
||||
.addComment("PONIES - all players are turned into ponies")
|
||||
.addComment("HUMANS - all players are humans")
|
||||
.addComment("BOTH - players with compatible skins will be ponies whilst the rest are humans");
|
||||
.addComment("How much pony do you want?")
|
||||
.addComment("PONIES - all players are turned into ponies")
|
||||
.addComment("HUMANS - all players are humans")
|
||||
.addComment("BOTH - players with compatible skins will be ponies whilst the rest are humans");
|
||||
private final Setting<Float> scaleFactor = value("globalScaleFactor", 0.9F)
|
||||
.addComment("How large do you want your ponies to be?")
|
||||
.addComment("Default is show scale (0.9)");
|
||||
.addComment("How large do you want your ponies to be?")
|
||||
.addComment("Default is show scale (0.9)");
|
||||
|
||||
public final Setting<Boolean> sizes = value("settings", "sizes", true)
|
||||
.addComment("Allows ponies of different sizes/ages");
|
||||
|
@ -52,9 +53,14 @@ public class PonyConfig extends Config {
|
|||
.addComment("Adjust camera intersection checks to properly cull entities when they're not in view.")
|
||||
.addComment("Helps to prevent entities from vanishing when they're in long stacks");
|
||||
public final Setting<Boolean> horsieMode = value("settings", "horsieMode", false)
|
||||
.addComment("Enables the alternative horsey models from the April Fools 2023 update");
|
||||
.addComment("Enables the alternative horsey models from the April Fools 2023 update");
|
||||
public final Setting<Boolean> mixedHumanSkins = value("settings", "dualSkinMode", false)
|
||||
.addComment("(Experimental) Use priority to decide between displaying the HDSkins' texture, or vanilla mojang server skin")
|
||||
.addComment("(Experimental) eg. On pony level = HUMANS")
|
||||
.addComment("(Experimental) Any time both skins resolve to the same race (eg. on pony-level HUMANS, or if both are ponies)")
|
||||
.addComment("(Experimental) the skin with the highest priority will be chosen.");;
|
||||
|
||||
public final Setting<Sizes> sizeOverride = value("debug", "sizeOverride", Sizes.UNSET)
|
||||
public final Setting<SizePreset> sizeOverride = value("debug", "sizeOverride", SizePreset.UNSET)
|
||||
.addComment("Overrides pony sizes")
|
||||
.addComment("Possible values: TALL, BULKY, LANKY, NORMAL, YEARLING, FOAL, UNSET (default)");
|
||||
|
||||
|
@ -68,10 +74,17 @@ public class PonyConfig extends Config {
|
|||
|
||||
public final Setting<Boolean> flappyElytras = value("customisation", "flappyElytras", false)
|
||||
.addComment("Pegasi will use their wings to fly even when they're wearing an elytra");
|
||||
|
||||
public final Setting<Boolean> noFun = value("customisation", "noFun", false)
|
||||
.addComment("Disables certain easter eggs and secrets (party pooper)")
|
||||
.addComment("Turning this off may help with compatibility in some cases");
|
||||
|
||||
public final Setting<VisibilityMode> horseButton = value("horseButton", VisibilityMode.AUTO)
|
||||
.addComment("Whether to show the mine little pony settings button on the main menu")
|
||||
.addComment("AUTO (default) - only show when HDSkins is not installed")
|
||||
.addComment("ON - always show")
|
||||
.addComment("OFF - never show");
|
||||
|
||||
public PonyConfig(Path path) {
|
||||
super(HEIRARCHICAL_JSON_ADAPTER, path);
|
||||
instance = this;
|
||||
|
@ -132,14 +145,14 @@ public class PonyConfig extends Config {
|
|||
}
|
||||
|
||||
public static Size getEffectiveSize(Size size) {
|
||||
Sizes sz = instance.sizeOverride.get();
|
||||
SizePreset sz = instance.sizeOverride.get();
|
||||
|
||||
if (sz != Sizes.UNSET) {
|
||||
if (sz != SizePreset.UNSET) {
|
||||
return sz;
|
||||
}
|
||||
|
||||
if (size == Sizes.UNSET || !instance.sizes.get()) {
|
||||
return Sizes.NORMAL;
|
||||
if (size == SizePreset.UNSET || !instance.sizes.get()) {
|
||||
return SizePreset.NORMAL;
|
||||
}
|
||||
|
||||
return size;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.api.pony.network.fabric;
|
||||
package com.minelittlepony.api.events;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
@ -8,40 +8,34 @@ import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
|||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.pony.network.MsgPonyData;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class Channel {
|
||||
private static final Identifier CLIENT_PONY_DATA = new Identifier("minelittlepony", "pony_data");
|
||||
private static final Identifier REQUEST_PONY_DATA = new Identifier("minelittlepony", "request_pony_data");
|
||||
private static final Logger LOGGER = LogManager.getLogger("MineLittlePony:Networking");
|
||||
|
||||
private static boolean registered;
|
||||
|
||||
public static void bootstrap() {
|
||||
ClientLoginConnectionEvents.INIT.register((handler, client) -> {
|
||||
registered = false;
|
||||
MineLittlePony.logger.info("Resetting registered flag");
|
||||
});
|
||||
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
|
||||
MineLittlePony.logger.info("Sending consent packet to " + handler.getPlayer().getName().getString());
|
||||
LOGGER.info("Sending consent packet to " + handler.getPlayer().getName().getString());
|
||||
|
||||
sender.sendPacket(REQUEST_PONY_DATA, PacketByteBufs.empty());
|
||||
});
|
||||
|
||||
ClientPlayNetworking.registerGlobalReceiver(REQUEST_PONY_DATA, (client, handler, ignored, sender) -> {
|
||||
if (client.player != null) {
|
||||
Pony pony = Pony.getManager().getPony(client.player);
|
||||
registered = true;
|
||||
MineLittlePony.logger.info("Server has just consented");
|
||||
|
||||
sender.sendPacket(CLIENT_PONY_DATA, MsgPonyData.write(pony.metadata(), PacketByteBufs.create()));
|
||||
}
|
||||
registered = true;
|
||||
LOGGER.info("Server has just consented");
|
||||
});
|
||||
ServerPlayNetworking.registerGlobalReceiver(CLIENT_PONY_DATA, (server, player, ignore, buffer, ignore2) -> {
|
||||
PonyData packet = MsgPonyData.read(buffer);
|
||||
|
@ -51,20 +45,19 @@ public class Channel {
|
|||
});
|
||||
}
|
||||
|
||||
public static void broadcastPonyData(PonyData packet) {
|
||||
public static boolean isRegistered() {
|
||||
return registered;
|
||||
}
|
||||
|
||||
public static boolean broadcastPonyData(PonyData packet) {
|
||||
if (!isRegistered()) {
|
||||
return false;
|
||||
}
|
||||
if (FabricLoader.getInstance().getEnvironmentType() != EnvType.CLIENT) {
|
||||
throw new RuntimeException("Client packet send called by the server");
|
||||
}
|
||||
|
||||
if (!registered) {
|
||||
if (MinecraftClient.getInstance().isInSingleplayer() || MinecraftClient.getInstance().isIntegratedServerRunning()) {
|
||||
MineLittlePony.logger.info("Sending pony skin data over as we are either in single-player or lan");
|
||||
} else {
|
||||
MineLittlePony.logger.info("Skipping network packet as the server has not consented");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ClientPlayNetworking.send(CLIENT_PONY_DATA, MsgPonyData.write(packet, PacketByteBufs.create()));
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.api.pony.network;
|
||||
package com.minelittlepony.api.events;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
|
||||
|
@ -23,7 +23,8 @@ public class MsgPonyData {
|
|||
new MsgSize(buffer),
|
||||
buffer.readInt(),
|
||||
buffer.readBoolean(),
|
||||
Flags.read(Wearable.class, buffer)
|
||||
buffer.readVarInt(),
|
||||
Flags.read(Wearable.NONE, buffer)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -34,13 +35,24 @@ public class MsgPonyData {
|
|||
buffer.writeEnumConstant(data.tailLength());
|
||||
buffer.writeEnumConstant(data.tailShape());
|
||||
buffer.writeEnumConstant(data.gender());
|
||||
new MsgSize(data.size()).toBuffer(buffer);
|
||||
write(data.size(), buffer);
|
||||
buffer.writeInt(data.glowColor());
|
||||
buffer.writeBoolean(data.noSkin());
|
||||
buffer.writeVarInt(data.priority());
|
||||
data.gear().write(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private static void write(Size size, PacketByteBuf buffer) {
|
||||
buffer.writeInt(size.ordinal());
|
||||
buffer.writeString(size.name());
|
||||
buffer.writeFloat(size.shadowSize());
|
||||
buffer.writeFloat(size.scaleFactor());
|
||||
buffer.writeFloat(size.eyeHeightFactor());
|
||||
buffer.writeFloat(size.eyeDistanceFactor());
|
||||
buffer.writeFloat(size.colorCode());
|
||||
}
|
||||
|
||||
private record MsgSize (
|
||||
int ordinal,
|
||||
String name,
|
||||
|
@ -49,23 +61,8 @@ public class MsgPonyData {
|
|||
float eyeHeightFactor,
|
||||
float eyeDistanceFactor,
|
||||
int colorCode) implements Size {
|
||||
|
||||
MsgSize(Size size) {
|
||||
this(size.ordinal(), size.name(), size.shadowSize(), size.scaleFactor(), size.eyeHeightFactor(), size.eyeDistanceFactor(), size.colorCode());
|
||||
}
|
||||
|
||||
MsgSize(PacketByteBuf buffer) {
|
||||
this(buffer.readInt(), buffer.readString(32767), buffer.readFloat(), buffer.readFloat(), buffer.readFloat(), buffer.readFloat(), buffer.readInt());
|
||||
}
|
||||
|
||||
public void toBuffer(PacketByteBuf buffer) {
|
||||
buffer.writeInt(ordinal);
|
||||
buffer.writeString(name);
|
||||
buffer.writeFloat(shadowSize);
|
||||
buffer.writeFloat(scaleFactor);
|
||||
buffer.writeFloat(eyeHeightFactor);
|
||||
buffer.writeFloat(eyeDistanceFactor);
|
||||
buffer.writeFloat(colorCode);
|
||||
this(buffer.readInt(), buffer.readString(), buffer.readFloat(), buffer.readFloat(), buffer.readFloat(), buffer.readFloat(), buffer.readInt());
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.api.pony.network.fabric;
|
||||
package com.minelittlepony.api.events;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.fabric.api.event.Event;
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.api.model.fabric;
|
||||
package com.minelittlepony.api.events;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
|
@ -1,10 +0,0 @@
|
|||
package com.minelittlepony.api.model;
|
||||
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
|
||||
public interface IModelWrapper {
|
||||
/**
|
||||
* Updates metadata values to this wrapper's contained models.
|
||||
*/
|
||||
IModelWrapper applyMetadata(PonyData meta);
|
||||
}
|
|
@ -4,12 +4,8 @@ import net.minecraft.client.model.ModelPart;
|
|||
import net.minecraft.util.Arm;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import com.minelittlepony.client.model.ClientPonyModel;
|
||||
import com.minelittlepony.mson.util.PartUtil;
|
||||
|
||||
/**
|
||||
* Common interface for all undead enemies.
|
||||
*/
|
||||
public final class MobPosingHelper {
|
||||
/**
|
||||
* Rotates the provided arm to the correct orientation for holding an item.
|
||||
|
@ -34,15 +30,21 @@ public final class MobPosingHelper {
|
|||
arm.roll = cos;
|
||||
}
|
||||
|
||||
public static void rotateUndeadArms(ClientPonyModel<?> model, float move, float ticks) {
|
||||
ModelPart leftArm = model.getArm(Arm.LEFT);
|
||||
ModelPart rightArm = model.getArm(Arm.RIGHT);
|
||||
public static void rotateUndeadArms(PonyModel<?> model, float move, float ticks) {
|
||||
ModelPart leftArm = model.getForeLeg(Arm.LEFT);
|
||||
ModelPart rightArm = model.getForeLeg(Arm.RIGHT);
|
||||
|
||||
if (islookAngleRight(move)) {
|
||||
rotateArmHolding(rightArm, 1, model.getSwingAmount(), ticks);
|
||||
if (model.getAttributes().isSitting) {
|
||||
rightArm.pitch += 0.6F;
|
||||
}
|
||||
PartUtil.shift(rightArm, 0.5F, 1.5F, 3);
|
||||
} else {
|
||||
rotateArmHolding(leftArm, -1, model.getSwingAmount(), ticks);
|
||||
if (model.getAttributes().isSitting) {
|
||||
leftArm.pitch += 0.6F;
|
||||
}
|
||||
PartUtil.shift(leftArm, -0.5F, 1.5F, 3);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.minelittlepony.api.model;
|
||||
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.pony.*;
|
||||
import com.minelittlepony.client.*;
|
||||
import com.minelittlepony.common.util.animation.Interpolator;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
||||
|
@ -9,6 +9,7 @@ import java.util.*;
|
|||
|
||||
import net.minecraft.client.render.entity.model.BipedEntityModel.ArmPose;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
@ -19,6 +20,11 @@ public class ModelAttributes {
|
|||
* True if the model is sleeping in a bed.
|
||||
*/
|
||||
public boolean isSleeping;
|
||||
|
||||
/**
|
||||
* True if the model is lying down comfortably
|
||||
*/
|
||||
public boolean isLyingDown;
|
||||
/**
|
||||
* True if the model is flying like a pegasus.
|
||||
*/
|
||||
|
@ -144,9 +150,15 @@ public class ModelAttributes {
|
|||
public void updateLivingState(LivingEntity entity, Pony pony, Mode mode) {
|
||||
visualHeight = entity.getHeight() + 0.125F;
|
||||
isSitting = PonyPosture.isSitting(entity);
|
||||
isCrouching = !isSitting && mode == Mode.THIRD_PERSON && PonyPosture.isCrouching(pony, entity);
|
||||
isSleeping = entity.isAlive() && entity.isSleeping();
|
||||
isFlying = mode == Mode.THIRD_PERSON && PonyPosture.isFlying(entity);
|
||||
isSleeping = entity.isAlive() && entity.isSleeping();;
|
||||
isLyingDown = isSleeping;
|
||||
if (entity instanceof PlayerEntity) {
|
||||
boolean moving = entity.getVelocity().multiply(1, 0, 1).length() == 0 && entity.isSneaking();
|
||||
isLyingDown |= getMainInterpolator().interpolate("lyingDown", moving ? 10 : 0, 200) >= 9;
|
||||
}
|
||||
|
||||
isCrouching = !isLyingDown && !isSitting && mode == Mode.THIRD_PERSON && PonyPosture.isCrouching(pony, entity);
|
||||
isFlying = !isLyingDown && mode == Mode.THIRD_PERSON && PonyPosture.isFlying(entity);
|
||||
isGliding = entity.isFallFlying();
|
||||
isSwimming = mode == Mode.THIRD_PERSON && PonyPosture.isSwimming(entity);
|
||||
isSwimmingRotated = isSwimming;
|
||||
|
@ -156,7 +168,7 @@ public class ModelAttributes {
|
|||
interpolatorId = entity.getUuid();
|
||||
}
|
||||
isLeftHanded = entity.getMainArm() == Arm.LEFT;
|
||||
isHorsey = MineLittlePony.getInstance().getConfig().horsieMode.get();
|
||||
isHorsey = PonyConfig.getInstance().horsieMode.get();
|
||||
featureSkins = SkinsProxy.instance.getAvailableSkins(entity);
|
||||
mainArm = entity.getMainArm();
|
||||
activeHand = entity.getActiveHand();
|
||||
|
@ -164,7 +176,7 @@ public class ModelAttributes {
|
|||
}
|
||||
|
||||
public Interpolator getMainInterpolator() {
|
||||
return metadata.getInterpolator(interpolatorId);
|
||||
return Interpolator.linear(interpolatorId);
|
||||
}
|
||||
|
||||
public boolean shouldLiftArm(ArmPose pose, ArmPose complement, float sigma) {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package com.minelittlepony.api.model;
|
||||
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import net.minecraft.client.render.entity.model.ModelWithArms;
|
||||
import net.minecraft.client.render.entity.model.BipedEntityModel.ArmPose;
|
||||
import net.minecraft.util.Arm;
|
||||
|
||||
public interface ModelWithHooves extends ModelWithArms {
|
||||
ModelPart getForeLeg(Arm side);
|
||||
|
||||
ModelPart getHindLeg(Arm side);
|
||||
|
||||
ArmPose getArmPoseForSide(Arm side);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.client.model;
|
||||
package com.minelittlepony.api.model;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.ArmorItem;
|
||||
|
@ -6,12 +6,11 @@ import net.minecraft.item.ItemStack;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.IModelWrapper;
|
||||
import com.minelittlepony.api.model.armour.*;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.client.model.armour.PonyArmourModel;
|
||||
import com.minelittlepony.mson.api.*;
|
||||
import com.minelittlepony.client.model.PlayerModelKey;
|
||||
import com.minelittlepony.client.model.armour.*;
|
||||
import com.minelittlepony.mson.api.ModelKey;
|
||||
import com.minelittlepony.mson.api.MsonModel;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
@ -19,14 +18,14 @@ import java.util.function.Consumer;
|
|||
/**
|
||||
* Container class for the various models and their associated piece of armour.
|
||||
*/
|
||||
public class ModelWrapper<T extends LivingEntity, M extends PonyModel<?>> implements IModelWrapper {
|
||||
public class Models<T extends LivingEntity, M extends PonyModel<?>> {
|
||||
@Nullable
|
||||
private final MsonModel.Factory<PonyArmourModel<T>> armorFactory;
|
||||
private final Map<ModelKey<PonyArmourModel<?>>, PonyArmourModel<T>> armor = new HashMap<>();
|
||||
|
||||
private final M body;
|
||||
|
||||
public ModelWrapper(PlayerModelKey<T, ? super M> playerModelKey, boolean slimArms, @Nullable Consumer<M> initializer) {
|
||||
public Models(PlayerModelKey<T, ? super M> playerModelKey, boolean slimArms, @Nullable Consumer<M> initializer) {
|
||||
this.armorFactory = playerModelKey.armorFactory();
|
||||
this.body = playerModelKey.getKey(slimArms).createModel();
|
||||
if (initializer != null) {
|
||||
|
@ -34,7 +33,7 @@ public class ModelWrapper<T extends LivingEntity, M extends PonyModel<?>> implem
|
|||
}
|
||||
}
|
||||
|
||||
public ModelWrapper(ModelKey<M> key) {
|
||||
public Models(ModelKey<M> key) {
|
||||
this.armorFactory = null;
|
||||
this.body = key.createModel();
|
||||
}
|
||||
|
@ -50,8 +49,7 @@ public class ModelWrapper<T extends LivingEntity, M extends PonyModel<?>> implem
|
|||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelWrapper<T, M> applyMetadata(PonyData meta) {
|
||||
public Models<T, M> applyMetadata(PonyData meta) {
|
||||
body.setMetadata(meta);
|
||||
armor.values().forEach(a -> a.setMetadata(meta));
|
||||
return this;
|
|
@ -12,7 +12,7 @@ import com.minelittlepony.api.pony.PonyData;
|
|||
import com.minelittlepony.api.pony.meta.*;
|
||||
import com.minelittlepony.mson.api.MsonModel;
|
||||
|
||||
public interface PonyModel<T extends LivingEntity> extends MsonModel, ModelWithArms, ModelWithHat, ModelWithHead {
|
||||
public interface PonyModel<T extends LivingEntity> extends MsonModel, ModelWithHooves, ModelWithHat, ModelWithHead {
|
||||
|
||||
void copyAttributes(BipedEntityModel<T> other);
|
||||
|
||||
|
@ -79,7 +79,7 @@ public interface PonyModel<T extends LivingEntity> extends MsonModel, ModelWithA
|
|||
* i.e. Used to change wing rendering when using saddlebags.
|
||||
*/
|
||||
default boolean isEmbedded(Wearable wearable) {
|
||||
return getAttributes().metadata.isWearing(wearable);
|
||||
return getAttributes().metadata.gear().matches(wearable);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
package com.minelittlepony.client.model;
|
||||
package com.minelittlepony.api.model;
|
||||
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import net.minecraft.client.render.entity.model.BipedEntityModel;
|
||||
import net.minecraft.client.render.entity.model.ModelWithArms;
|
||||
import net.minecraft.client.render.entity.model.BipedEntityModel.ArmPose;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.util.Arm;
|
||||
|
||||
import com.minelittlepony.api.model.*;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.pony.meta.Size;
|
||||
import com.minelittlepony.mson.api.ModelView;
|
||||
import com.minelittlepony.mson.api.model.BoxBuilder.RenderLayerSetter;
|
||||
|
||||
public interface IPonyMixinModel<T extends LivingEntity, M extends PonyModel<T>> extends PonyModel<T> {
|
||||
|
||||
public interface PonyModelMixin<T extends LivingEntity, M extends PonyModel<T>> extends PonyModel<T> {
|
||||
M mixin();
|
||||
|
||||
@Override
|
||||
|
@ -71,6 +70,22 @@ public interface IPonyMixinModel<T extends LivingEntity, M extends PonyModel<T>>
|
|||
return mixin().getRiderYOffset();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
default ModelPart getForeLeg(Arm side) {
|
||||
return mixin().getForeLeg(side);
|
||||
}
|
||||
|
||||
@Override
|
||||
default ModelPart getHindLeg(Arm side) {
|
||||
return mixin().getHindLeg(side);
|
||||
}
|
||||
|
||||
@Override
|
||||
default ArmPose getArmPoseForSide(Arm side) {
|
||||
return mixin().getArmPoseForSide(side);
|
||||
}
|
||||
|
||||
@Override
|
||||
default void setArmAngle(Arm arm, MatrixStack stack) {
|
||||
if (mixin() instanceof ModelWithArms) {
|
||||
|
@ -93,7 +108,7 @@ public interface IPonyMixinModel<T extends LivingEntity, M extends PonyModel<T>>
|
|||
mixin().setHatVisible(hatVisible);
|
||||
}
|
||||
|
||||
interface Caster<T extends LivingEntity, M extends PonyModel<T> & HornedPonyModel<T>, ArmModel> extends IPonyMixinModel<T, M>, HornedPonyModel<T> {
|
||||
interface Caster<T extends LivingEntity, M extends PonyModel<T> & HornedPonyModel<T>, ArmModel> extends PonyModelMixin<T, M>, HornedPonyModel<T> {
|
||||
@Override
|
||||
default boolean isCasting() {
|
||||
return mixin().isCasting();
|
|
@ -0,0 +1,7 @@
|
|||
package com.minelittlepony.api.model;
|
||||
|
||||
public interface PreviewModel {
|
||||
boolean forceSeapony();
|
||||
|
||||
boolean forceNirik();
|
||||
}
|
|
@ -3,7 +3,7 @@ package com.minelittlepony.api.model;
|
|||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
public interface IPart {
|
||||
public interface SubModel {
|
||||
/**
|
||||
* Sets the model's various rotation angles.
|
||||
*/
|
|
@ -2,8 +2,8 @@ package com.minelittlepony.api.model;
|
|||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
||||
public interface WingedPonyModel<T extends LivingEntity> extends PonyModel<T> {
|
||||
|
@ -16,7 +16,7 @@ public interface WingedPonyModel<T extends LivingEntity> extends PonyModel<T> {
|
|||
*/
|
||||
default boolean wingsAreOpen() {
|
||||
return (getAttributes().isSwimming || getAttributes().isFlying || getAttributes().isCrouching)
|
||||
&& (MineLittlePony.getInstance().getConfig().flappyElytras.get() || !getAttributes().isGliding);
|
||||
&& (PonyConfig.getInstance().flappyElytras.get() || !getAttributes().isGliding);
|
||||
}
|
||||
|
||||
default boolean isBurdened() {
|
||||
|
@ -28,7 +28,7 @@ public interface WingedPonyModel<T extends LivingEntity> extends PonyModel<T> {
|
|||
/**
|
||||
* Gets the wings of this pegasus/flying creature
|
||||
*/
|
||||
IPart getWings();
|
||||
SubModel getWings();
|
||||
|
||||
/**
|
||||
* Determines angle used to animate wing flaps whilst flying/swimming.
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
package com.minelittlepony.api.model.armour;
|
||||
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
|
||||
public interface IArmourModel<T extends LivingEntity> {
|
||||
/**
|
||||
* Called to synchronise this armour's angles with that of another.
|
||||
*
|
||||
* @param model The other model to mimic
|
||||
*/
|
||||
boolean poseModel(T entity, float limbAngle, float limbDistance, float age, float headYaw, float headPitch,
|
||||
EquipmentSlot slot, ArmourLayer layer,
|
||||
PonyModel<T> mainModel);
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package com.minelittlepony.api.model.armour;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.client.model.armour.DefaultArmourTextureResolver;
|
||||
|
||||
/**
|
||||
* A resolver for looking up the texture for a piece of armour.
|
||||
* <p>
|
||||
* This is for modders who want to override the default implementation found in {@link DefaultArmourTextureResolver}.
|
||||
*/
|
||||
public interface IArmourTextureResolver {
|
||||
/**
|
||||
* Gets the armour texture to be used for the given entity, armour piece, slot, and render layer.
|
||||
*/
|
||||
Identifier getTexture(LivingEntity entity, ItemStack itemstack, EquipmentSlot slot, ArmourLayer layer, @Nullable String type);
|
||||
|
||||
/**
|
||||
* Gets the armour variant for the identified texture.
|
||||
* Either normal for pony-style textures, or legacy for other textures.
|
||||
*/
|
||||
default ArmourVariant getVariant(ArmourLayer layer, Identifier resolvedTexture) {
|
||||
return ArmourVariant.NORMAL;
|
||||
}
|
||||
}
|
|
@ -9,22 +9,23 @@ import net.minecraft.util.Identifier;
|
|||
|
||||
import com.minelittlepony.api.model.*;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.client.render.entity.feature.GearFeature;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Interface for an accessory on a pony's body.
|
||||
*/
|
||||
public interface Gear {
|
||||
List<Supplier<Gear>> MOD_GEARS = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Registers a custom gear to be used with the mod.
|
||||
* <p>
|
||||
* This would be awesome for creating socks.
|
||||
*/
|
||||
static Supplier<Gear> register(Supplier<Gear> gear) {
|
||||
GearFeature.addModGear(gear);
|
||||
MOD_GEARS.add(gear);
|
||||
return gear;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,9 @@ import java.util.*;
|
|||
public final class DefaultPonySkinHelper {
|
||||
public static final Identifier STEVE = new Identifier("minelittlepony", "textures/entity/player/wide/steve_pony.png");
|
||||
|
||||
public static final Identifier SEAPONY_SKIN_TYPE_ID = new Identifier("minelp", "seapony");
|
||||
public static final Identifier NIRIK_SKIN_TYPE_ID = new Identifier("minelp", "nirik");
|
||||
|
||||
private static final Map<SkinTextures, SkinTextures> SKINS = new HashMap<>();
|
||||
|
||||
public static SkinTextures getTextures(SkinTextures original) {
|
||||
|
@ -27,7 +30,7 @@ public final class DefaultPonySkinHelper {
|
|||
}
|
||||
|
||||
public static String getModelType(UUID id) {
|
||||
SkinTextures textures = DefaultSkinHelper.getTexture(id);
|
||||
SkinTextures textures = DefaultSkinHelper.getSkinTextures(id);
|
||||
return getModelType(Pony.getManager().getPony(textures.texture(), id).race(), textures.model());
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.minelittlepony.api.pony.meta.*;
|
||||
import com.minelittlepony.common.util.animation.Interpolator;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
@ -50,67 +49,57 @@ public record PonyData (
|
|||
* rather than a user-uploaded one.
|
||||
*/
|
||||
boolean noSkin,
|
||||
/**
|
||||
* (Experimental) Priority.
|
||||
* Used to decide which skin to use when dual skin mode is active.
|
||||
* Provides an optional tie-breaker when the client has to decide between displaying
|
||||
* either the HDSkins texture or vanilla texture given both are otherwise acceptable.
|
||||
*
|
||||
* Any time both skins resolve to the same race (eg. on pony-level HUMANS, or if both are ponies)
|
||||
* the skin with the highest priority will be chosen.
|
||||
*
|
||||
* If both have the same priority, HD Skins' texture will always be used (old default).
|
||||
*/
|
||||
int priority,
|
||||
/**
|
||||
* Gets the trigger pixel values as they appeared in the underlying image.
|
||||
*/
|
||||
Map<String, TriggerPixelType<?>> attributes
|
||||
Map<String, TValue<?>> attributes
|
||||
) implements Comparable<PonyData> {
|
||||
private static final Function<Race, PonyData> OF_RACE = Util.memoize(race -> {
|
||||
return new PonyData(race, TailLength.FULL, TailShape.STRAIGHT, Gender.MARE, Sizes.NORMAL, 0x4444aa, Wearable.EMPTY_FLAGS, true, Util.make(new TreeMap<>(), attributes -> {
|
||||
attributes.put("race", race);
|
||||
attributes.put("tailLength", TailLength.FULL);
|
||||
attributes.put("tailShape", TailShape.STRAIGHT);
|
||||
attributes.put("gender", Gender.MARE);
|
||||
attributes.put("size", Sizes.NORMAL);
|
||||
attributes.put("magic", TriggerPixelType.of(0x4444aa));
|
||||
attributes.put("gear", TriggerPixelType.of(0));
|
||||
}));
|
||||
});
|
||||
public static final int DEFAULT_MAGIC_COLOR = 0x4444aa;
|
||||
private static final Function<Race, PonyData> OF_RACE = Util.memoize(race -> new PonyData(race, TailLength.FULL, TailShape.STRAIGHT, Gender.MARE, SizePreset.NORMAL, DEFAULT_MAGIC_COLOR, true, 0, Wearable.EMPTY_FLAGS));
|
||||
public static final PonyData NULL = OF_RACE.apply(Race.HUMAN);
|
||||
|
||||
public static PonyData emptyOf(Race race) {
|
||||
return OF_RACE.apply(race);
|
||||
}
|
||||
|
||||
|
||||
public PonyData(Race race, TailLength tailLength, TailShape tailShape, Gender gender, Size size, int glowColor, boolean noSkin, Flags<Wearable> wearables) {
|
||||
this(race, tailLength, tailShape, gender, size, glowColor, wearables, noSkin, Util.make(new TreeMap<>(), map -> {
|
||||
map.put("race", race);
|
||||
map.put("tailLength", tailLength);
|
||||
map.put("tailShape", tailShape);
|
||||
map.put("gender", gender);
|
||||
map.put("size", size);
|
||||
map.put("magic", TriggerPixelType.of(glowColor));
|
||||
map.put("gear", TriggerPixelType.of(wearables.colorCode()));
|
||||
}));
|
||||
}
|
||||
public PonyData(Race race, TailLength tailLength, TailShape tailShape, Gender gender, Size size, int glowColor, TriggerPixelType.Multiple<Wearable> wearables, boolean noSkin) {
|
||||
this(race, tailLength, tailShape, gender, size, glowColor,
|
||||
Flags.of(Wearable.class, wearables.colorCode(), wearables.value()),
|
||||
noSkin, Util.make(new TreeMap<>(), map -> {
|
||||
map.put("race", race);
|
||||
map.put("tailLength", tailLength);
|
||||
map.put("tailShape", tailShape);
|
||||
map.put("gender", gender);
|
||||
map.put("size", size);
|
||||
map.put("magic", TriggerPixelType.of(glowColor));
|
||||
map.put("gear", wearables);
|
||||
})
|
||||
public PonyData(TriggerPixel.Mat image, boolean noSkin) {
|
||||
this(
|
||||
TriggerPixel.RACE.read(image),
|
||||
TriggerPixel.TAIL.read(image),
|
||||
TriggerPixel.TAIL_SHAPE.read(image),
|
||||
TriggerPixel.GENDER.read(image),
|
||||
TriggerPixel.SIZE.read(image),
|
||||
TriggerPixel.GLOW.read(image),
|
||||
noSkin,
|
||||
TriggerPixel.PRIORITY.read(image),
|
||||
TriggerPixel.WEARABLES.read(image)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks it this pony is wearing the given accessory.
|
||||
*/
|
||||
public boolean isWearing(Wearable wearable) {
|
||||
return gear().includes(wearable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an interpolator for interpolating values.
|
||||
*/
|
||||
public Interpolator getInterpolator(UUID interpolatorId) {
|
||||
return Interpolator.linear(interpolatorId);
|
||||
public PonyData(Race race, TailLength tailLength, TailShape tailShape, Gender gender, Size size, int glowColor, boolean noSkin, int priority, Flags<Wearable> wearables) {
|
||||
this(race, tailLength, tailShape, gender, size, glowColor, wearables, noSkin, priority, Util.make(new TreeMap<>(), map -> {
|
||||
map.put("race", race);
|
||||
map.put("tailLength", tailLength);
|
||||
map.put("tailShape", tailShape);
|
||||
map.put("gender", gender);
|
||||
map.put("size", size);
|
||||
map.put("magic", new TValue.Numeric(glowColor));
|
||||
map.put("priority", new TValue.Numeric(priority));
|
||||
map.put("gear", wearables);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.minelittlepony.api.pony;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
|
@ -10,8 +11,7 @@ import java.util.Optional;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* The PonyManager is responsible for reading and recoding all the pony data associated with an entity of skin.
|
||||
*
|
||||
* The PonyManager is responsible for reading and recoding all the pony data associated with the skin of an entity.
|
||||
*/
|
||||
public interface PonyManager {
|
||||
/**
|
||||
|
@ -19,7 +19,25 @@ public interface PonyManager {
|
|||
*
|
||||
* If the supplied entity is null or can't be determined to be a pony, returns the empty optional.
|
||||
*/
|
||||
Optional<Pony> getPony(@Nullable Entity entity);
|
||||
default Optional<Pony> getPony(@Nullable Entity entity) {
|
||||
return entity instanceof LivingEntity living ? getPony(living) : Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a pony representation of the passed in entity.
|
||||
*
|
||||
* If the supplied entity is null or can't be determined to be a pony, returns the empty optional.
|
||||
*/
|
||||
Optional<Pony> getPony(LivingEntity entity);
|
||||
|
||||
/**
|
||||
* Gets a random background pony determined by the given uuid.
|
||||
*
|
||||
* Useful for mods that offer customisation, especially ones that have a whole lot of NPCs.
|
||||
*
|
||||
* @param uuid id of a player
|
||||
*/
|
||||
Pony getBackgroundPony(UUID uuid);
|
||||
|
||||
/**
|
||||
* Gets or creates a pony for the given player.
|
||||
|
@ -29,13 +47,6 @@ public interface PonyManager {
|
|||
*/
|
||||
Pony getPony(PlayerEntity player);
|
||||
|
||||
/**
|
||||
* Gets or creates a pony for the given skin resource and vanilla model type.
|
||||
*
|
||||
* @param resource A texture resource
|
||||
*/
|
||||
Pony getPony(Identifier resource);
|
||||
|
||||
/**
|
||||
* Gets or creates a pony for the given skin resource and entity id.
|
||||
*
|
||||
|
@ -46,23 +57,16 @@ public interface PonyManager {
|
|||
* @param resource A texture resource
|
||||
* @param uuid id of a player
|
||||
*/
|
||||
Pony getPony(Identifier resource, UUID uuid);
|
||||
Pony getPony(@Nullable Identifier resource, @Nullable UUID uuid);
|
||||
|
||||
/**
|
||||
* Gets a random background pony determined by the given uuid.
|
||||
* Gets or creates a pony for the given skin resource and vanilla model type.
|
||||
*
|
||||
* Useful for mods that offer customisation, especially ones that have a whole lot of NPCs.
|
||||
*
|
||||
* @param uuid A UUID. Either a user or an entity.
|
||||
* @param resource A texture resource
|
||||
*/
|
||||
Pony getBackgroundPony(UUID uuid);
|
||||
|
||||
/**
|
||||
* De-registers a pony from the cache.
|
||||
*/
|
||||
void removePony(Identifier resource);
|
||||
|
||||
void clearCache();
|
||||
default Pony getPony(Identifier resource) {
|
||||
return getPony(resource, null);
|
||||
}
|
||||
|
||||
interface ForcedPony {}
|
||||
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package com.minelittlepony.api.pony;
|
||||
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.client.PreviewModel;
|
||||
import com.minelittlepony.client.SkinsProxy;
|
||||
import com.minelittlepony.client.render.entity.AquaticPlayerPonyRenderer;
|
||||
import com.minelittlepony.api.model.PreviewModel;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
@ -101,7 +99,26 @@ public final class PonyPosture {
|
|||
}
|
||||
return Pony.getManager().getPony(entity).filter(pony -> {
|
||||
return (pony.race() == Race.SEAPONY
|
||||
|| (entity instanceof AbstractClientPlayerEntity player && SkinsProxy.instance.getSkin(AquaticPlayerPonyRenderer.SKIN_TYPE_ID, player).isPresent())
|
||||
|| (entity instanceof AbstractClientPlayerEntity player && SkinsProxy.instance.getSkin(DefaultPonySkinHelper.SEAPONY_SKIN_TYPE_ID, player).isPresent())
|
||||
);
|
||||
}).isPresent();
|
||||
}
|
||||
|
||||
public static boolean isNirikModifier(LivingEntity entity) {
|
||||
if (entity instanceof PreviewModel preview) {
|
||||
return preview.forceNirik();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static boolean hasNirikForm(LivingEntity entity) {
|
||||
if (entity instanceof PreviewModel preview) {
|
||||
return preview.forceNirik();
|
||||
}
|
||||
return Pony.getManager().getPony(entity).filter(pony -> {
|
||||
return (pony.race() == Race.KIRIN
|
||||
&& (entity instanceof AbstractClientPlayerEntity player && SkinsProxy.instance.getSkin(DefaultPonySkinHelper.NIRIK_SKIN_TYPE_ID, player).isPresent())
|
||||
);
|
||||
}).isPresent();
|
||||
}
|
||||
|
|
|
@ -1,40 +1,27 @@
|
|||
package com.minelittlepony.client;
|
||||
package com.minelittlepony.api.pony;
|
||||
|
||||
import com.minelittlepony.common.client.gui.ScrollContainer;
|
||||
import com.minelittlepony.common.client.gui.Tooltip;
|
||||
import com.minelittlepony.common.client.gui.element.Button;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.network.AbstractClientPlayerEntity;
|
||||
import net.minecraft.client.texture.PlayerSkinProvider;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Proxy handler for getting player skin data from HDSkins
|
||||
*/
|
||||
public class SkinsProxy {
|
||||
|
||||
public static SkinsProxy instance = new SkinsProxy();
|
||||
|
||||
@Nullable
|
||||
public Identifier getSkinTexture(GameProfile profile) {
|
||||
PlayerSkinProvider skins = MinecraftClient.getInstance().getSkinProvider();
|
||||
return skins.getSkinTextures(profile).texture();
|
||||
}
|
||||
|
||||
public void renderOption(Screen screen, @Nullable Screen parent, int row, int RIGHT, ScrollContainer content) {
|
||||
content.addButton(new Button(RIGHT, row += 20, 150, 20))
|
||||
.setEnabled(false)
|
||||
.getStyle()
|
||||
.setTooltip(Tooltip.of("minelp.options.skins.hdskins.disabled", 200))
|
||||
.setText("minelp.options.skins.hdskins.open");
|
||||
}
|
||||
|
||||
public Optional<Identifier> getSkin(Identifier skinTypeId, AbstractClientPlayerEntity player) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
@ -43,17 +30,3 @@ public class SkinsProxy {
|
|||
return Set.of();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -4,50 +4,56 @@ import net.minecraft.network.PacketByteBuf;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
public record Flags<T extends Enum<T>> (
|
||||
boolean[] flags,
|
||||
List<T> values,
|
||||
public record Flags<T extends Enum<T> & TValue<T>> (
|
||||
T def,
|
||||
Set<T> values,
|
||||
int colorCode
|
||||
) implements Comparable<Flags<T>> {
|
||||
) implements Comparable<Flags<T>>, TValue<T> {
|
||||
|
||||
public static <T extends Enum<T>> Flags<T> of(Class<T> type) {
|
||||
return new Flags<>(new boolean[type.getEnumConstants().length], List.<T>of(), 0);
|
||||
public static <T extends Enum<T> & TValue<T>> Flags<T> of(T def) {
|
||||
return new Flags<>(def, Set.<T>of(), 0);
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> Flags<T> of(Class<T> type, int colorCode, boolean...flags) {
|
||||
return new Flags<>(flags, flags(type.getEnumConstants(), flags), colorCode);
|
||||
public static <T extends Enum<T> & TValue<T>> Flags<T> of(T def, int colorCode, Set<T> values) {
|
||||
return new Flags<>(def, values, colorCode);
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> Flags<T> read(Class<T> type, PacketByteBuf buffer) {
|
||||
public static <T extends Enum<T> & TValue<T>> Flags<T> read(T def, PacketByteBuf buffer) {
|
||||
int length = buffer.readVarInt();
|
||||
List<T> values = new ArrayList<>();
|
||||
T[] all = type.getEnumConstants();
|
||||
boolean[] flags = new boolean[all.length];
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<T> values = EnumSet.noneOf((Class<T>)def.getClass());
|
||||
@SuppressWarnings("unchecked")
|
||||
T[] all = (T[])def.getClass().getEnumConstants();
|
||||
for (int i = 0; i < length; i++) {
|
||||
values.add(all[buffer.readInt()]);
|
||||
flags[i] = true;
|
||||
}
|
||||
return new Flags<>(flags, values, buffer.readInt());
|
||||
}
|
||||
|
||||
public static <T> List<T> flags(T[] values, boolean[] flags) {
|
||||
List<T> wears = new ArrayList<>();
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
if (flags[i]) wears.add(values[i]);
|
||||
}
|
||||
return wears;
|
||||
}
|
||||
|
||||
public boolean includes(T t) {
|
||||
return flags[t.ordinal()];
|
||||
}
|
||||
|
||||
public int compareTo(Flags<T> other) {
|
||||
return Arrays.compare(flags, other.flags);
|
||||
return new Flags<>(def, values, buffer.readInt());
|
||||
}
|
||||
|
||||
public void write(PacketByteBuf buffer) {
|
||||
buffer.writeCollection(values, (buf, value) -> buf.writeInt(value.ordinal()));
|
||||
buffer.writeInt(colorCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "[Flags " + values + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TValue<T>> getOptions() {
|
||||
return def.getOptions();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public boolean matches(TValue<?> o) {
|
||||
return o.getClass() == def.getClass() && values.contains((T)o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Flags<T> other) {
|
||||
return Integer.compare(colorCode(), other.colorCode());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
public enum Gender implements TriggerPixelType<Gender> {
|
||||
public enum Gender implements TValue<Gender> {
|
||||
MARE(0),
|
||||
STALLION(0xffffff),
|
||||
ABOMONATION(0x888888);
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public enum Race implements TriggerPixelType<Race> {
|
||||
public enum Race implements TValue<Race> {
|
||||
HUMAN (0x000000, false, false),
|
||||
EARTH (0xf9b131, false, false),
|
||||
PEGASUS (0x88caf0, true, false),
|
||||
|
@ -17,16 +15,13 @@ public enum Race implements TriggerPixelType<Race> {
|
|||
BATPONY (0xeeeeee, true, false),
|
||||
SEAPONY (0x3655dd, false, true);
|
||||
|
||||
private boolean wings;
|
||||
private boolean horn;
|
||||
private final boolean wings;
|
||||
private final boolean horn;
|
||||
|
||||
private int triggerPixel;
|
||||
|
||||
public static final List<Race> REGISTRY = Arrays.asList(values());
|
||||
|
||||
Race(int triggerPixel, boolean wings, boolean horn) {
|
||||
this.triggerPixel = triggerPixel;
|
||||
private final int colorCode;
|
||||
|
||||
Race(int colorCode, boolean wings, boolean horn) {
|
||||
this.colorCode = colorCode;
|
||||
this.wings = wings;
|
||||
this.horn = horn;
|
||||
}
|
||||
|
@ -68,6 +63,6 @@ public enum Race implements TriggerPixelType<Race> {
|
|||
|
||||
@Override
|
||||
public int colorCode() {
|
||||
return triggerPixel;
|
||||
return colorCode;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@ package com.minelittlepony.api.pony.meta;
|
|||
/**
|
||||
* Represents the different model sizes that are possible.
|
||||
*
|
||||
* For a list of possible presets, look at {@link Sizes}.
|
||||
* For a list of possible presets, look at {@link SizePreset}.
|
||||
* This interface exists for servers so they can work with this information even though they might not have access to the client config.
|
||||
*
|
||||
*/
|
||||
public interface Size extends TriggerPixelType<Size> {
|
||||
public interface Size extends TValue<Size> {
|
||||
/**
|
||||
* The Enum index of this size. May be used on the client to convert to an instance of Sizes or use {@link Sizes#of}
|
||||
* The Enum index of this size. May be used on the client to convert to an instance of Sizes or use {@link SizePreset#of}
|
||||
*
|
||||
* Made to be compatible with the enum variant.
|
||||
*/
|
||||
|
@ -41,4 +41,9 @@ public interface Size extends TriggerPixelType<Size> {
|
|||
* A scale factor used to alter the camera's distance.
|
||||
*/
|
||||
float eyeDistanceFactor();
|
||||
|
||||
/**
|
||||
* The trigger pixel colour corresponding to this size.
|
||||
*/
|
||||
int colorCode();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import com.minelittlepony.api.config.PonyConfig;
|
|||
*
|
||||
* For spooky things at a distance, use {@link Size} instead.
|
||||
*/
|
||||
public enum Sizes implements Size {
|
||||
public enum SizePreset implements Size {
|
||||
TALL (0x534b76, 0.45f, 1.1F, 1.15F),
|
||||
BULKY (0xce3254, 0.5f, 1, 1.05F),
|
||||
LANKY (0x3254ce, 0.45F, 0.85F, 0.9F),
|
||||
|
@ -18,21 +18,23 @@ public enum Sizes implements Size {
|
|||
FOAL (0xffbe53, 0.25f, 0.6F, 0.5F),
|
||||
UNSET (0x000000, 1, 1, 1);
|
||||
|
||||
public static final Sizes[] REGISTRY = values();
|
||||
private final int triggerValue;
|
||||
private final float shadowSize;
|
||||
private final float scale;
|
||||
private final float camera;
|
||||
|
||||
private int triggerValue;
|
||||
|
||||
private float shadowSize;
|
||||
private float scale;
|
||||
private float camera;
|
||||
|
||||
Sizes(int pixel, float shadowSz, float scaleF, float cameraF) {
|
||||
SizePreset(int pixel, float shadowSz, float scaleF, float cameraF) {
|
||||
triggerValue = pixel;
|
||||
shadowSize = shadowSz;
|
||||
scale = scaleF;
|
||||
camera = cameraF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int colorCode() {
|
||||
return triggerValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float shadowSize() {
|
||||
return shadowSize * PonyConfig.getInstance().getGlobalScaleFactor();
|
||||
|
@ -53,25 +55,6 @@ public enum Sizes implements Size {
|
|||
|
||||
@Override
|
||||
public float eyeDistanceFactor() {
|
||||
if (!PonyConfig.getInstance().fillycam.get()) {
|
||||
return 1;
|
||||
}
|
||||
return camera * PonyConfig.getInstance().getGlobalScaleFactor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int colorCode() {
|
||||
return triggerValue;
|
||||
}
|
||||
|
||||
public static Sizes of(Size size) {
|
||||
if (size instanceof Sizes) {
|
||||
return (Sizes)size;
|
||||
}
|
||||
int i = size.ordinal();
|
||||
if (i < 0 || i >= REGISTRY.length) {
|
||||
return UNSET;
|
||||
}
|
||||
return REGISTRY[i];
|
||||
return eyeHeightFactor();
|
||||
}
|
||||
}
|
66
src/main/java/com/minelittlepony/api/pony/meta/TValue.java
Normal file
66
src/main/java/com/minelittlepony/api/pony/meta/TValue.java
Normal file
|
@ -0,0 +1,66 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface for enums that can be parsed from an image trigger pixel value.
|
||||
*/
|
||||
public interface TValue<T> {
|
||||
/**
|
||||
* Gets the pixel colour matching this enum value.
|
||||
*/
|
||||
int colorCode();
|
||||
|
||||
/**
|
||||
* Gets the pixel colour matching this enum value, adjusted to fill all three channels.
|
||||
*/
|
||||
default int getChannelAdjustedColorCode() {
|
||||
return colorCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string representation of this value.
|
||||
*/
|
||||
String name();
|
||||
|
||||
default String getHexValue() {
|
||||
return toHex(colorCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of possible values this trigger pixel can accept.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
default List<TValue<T>> getOptions() {
|
||||
if (this instanceof Enum) {
|
||||
// cast is required because gradle's compiler is more strict
|
||||
return Arrays.asList(getClass().getEnumConstants());
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
default boolean matches(TValue<?> o) {
|
||||
return o != null && colorCode() == o.colorCode();
|
||||
}
|
||||
|
||||
static String toHex(int color) {
|
||||
String v = Integer.toHexString(color).toUpperCase();
|
||||
while (v.length() < 6) {
|
||||
v = "0" + v;
|
||||
}
|
||||
return "#" + v;
|
||||
}
|
||||
|
||||
public record Numeric(int colorCode) implements TValue<Integer> {
|
||||
@Override
|
||||
public String name() {
|
||||
return "[Numeric " + getHexValue() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TValue<Integer>> getOptions() {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
public enum TailLength implements TriggerPixelType<TailLength> {
|
||||
public enum TailLength implements TValue<TailLength> {
|
||||
STUB (0x425844),
|
||||
QUARTER (0xd19fe4),
|
||||
HALF (0x534b76),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
public enum TailShape implements TriggerPixelType<TailShape> {
|
||||
public enum TailShape implements TValue<TailShape> {
|
||||
STRAIGHT(0),
|
||||
BUMPY (0xfc539f),
|
||||
SWIRLY (0x3eff22),
|
||||
|
|
|
@ -1,112 +1,92 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
import net.minecraft.client.texture.NativeImage;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.minecraft.util.math.ColorHelper;
|
||||
|
||||
import org.joml.Vector2i;
|
||||
|
||||
import com.minelittlepony.common.util.Color;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Individual trigger pixels for a pony skin.
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public enum TriggerPixel {
|
||||
RACE(Race.HUMAN, Channel.ALL, 0, 0),
|
||||
TAIL(TailLength.FULL, Channel.ALL, 1, 0),
|
||||
GENDER(Gender.MARE, Channel.ALL, 2, 0),
|
||||
SIZE(Sizes.NORMAL, Channel.ALL, 3, 0),
|
||||
GLOW(null, Channel.RAW, 0, 1),
|
||||
WEARABLES(Wearable.NONE, Channel.RAW, 1, 1),
|
||||
TAIL_SHAPE(TailShape.STRAIGHT, Channel.ALL, 2, 1);
|
||||
public interface TriggerPixel<T> {
|
||||
Vector2i MAX_COORDS = new Vector2i();
|
||||
|
||||
private final int x;
|
||||
private final int y;
|
||||
TriggerPixel<Race> RACE = ofOptions(0, 0, Race.HUMAN, Race.values());
|
||||
TriggerPixel<TailLength> TAIL = ofOptions(1, 0, TailLength.FULL, TailLength.values());
|
||||
TriggerPixel<Gender> GENDER = ofOptions(2, 0, Gender.MARE, Gender.values());
|
||||
TriggerPixel<TailShape> TAIL_SHAPE = ofOptions(2, 1, TailShape.STRAIGHT, TailShape.values());
|
||||
TriggerPixel<Size> SIZE = ofOptions(3, 0, SizePreset.NORMAL, SizePreset.values());
|
||||
TriggerPixel<Integer> GLOW = ofColor(0, 1);
|
||||
TriggerPixel<Flags<Wearable>> WEARABLES = ofFlags(1, 1, Wearable.EMPTY_FLAGS, Wearable.values());
|
||||
TriggerPixel<Integer> PRIORITY = ofColor(2, 2);
|
||||
|
||||
private final Channel channel;
|
||||
static <T extends TValue<T>> TriggerPixel<T> ofOptions(int x, int y, T def, T[] options) {
|
||||
MAX_COORDS.x = Math.max(MAX_COORDS.x, x);
|
||||
MAX_COORDS.y = Math.max(MAX_COORDS.y, y);
|
||||
Int2ObjectOpenHashMap<T> lookup = buildLookup(options);
|
||||
return image -> {
|
||||
int color = Color.abgrToArgb(image.getColor(x, y));
|
||||
|
||||
private final TriggerPixelType<?> def;
|
||||
|
||||
private static final TriggerPixel[] VALUES = values();
|
||||
private static final int MAX_READ_X = Arrays.stream(VALUES).mapToInt(i -> i.x).max().getAsInt();
|
||||
private static final int MAX_READ_Y = Arrays.stream(VALUES).mapToInt(i -> i.y).max().getAsInt();
|
||||
|
||||
TriggerPixel(TriggerPixelType<?> def, Channel channel, int x, int y) {
|
||||
this.def = def;
|
||||
this.channel = channel;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
if (ColorHelper.Argb.getAlpha(color) < 255) {
|
||||
return (T)def;
|
||||
}
|
||||
return lookup.getOrDefault(color & 0x00FFFFFF, def);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads this trigger pixel's value and returns the raw colour.
|
||||
*
|
||||
* @param image Image to read
|
||||
*/
|
||||
public int readColor(NativeImage image) {
|
||||
return channel.readValue(x, y, image);
|
||||
static TriggerPixel<Integer> ofColor(int x, int y) {
|
||||
MAX_COORDS.x = Math.max(MAX_COORDS.x, x);
|
||||
MAX_COORDS.y = Math.max(MAX_COORDS.y, y);
|
||||
return image -> Color.abgrToArgb(image.getColor(x, y));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads this trigger pixel's value and parses it to an Enum instance.
|
||||
*
|
||||
* @param image Image to read
|
||||
*/
|
||||
public <T extends TriggerPixelType<T>> T readValue(NativeImage image) {
|
||||
int color = readColor(image);
|
||||
static <T extends Enum<T> & TValue<T>> TriggerPixel<Flags<T>> ofFlags(int x, int y, Flags<T> def, T[] options) {
|
||||
MAX_COORDS.x = Math.max(MAX_COORDS.x, x);
|
||||
MAX_COORDS.y = Math.max(MAX_COORDS.y, y);
|
||||
Int2ObjectOpenHashMap<T> lookup = buildLookup(options);
|
||||
var flagReader = new Object() {
|
||||
boolean readFlag(int color, Set<T> values) {
|
||||
T value = lookup.get(color);
|
||||
return value != null && values.add(value);
|
||||
}
|
||||
};
|
||||
return image -> {
|
||||
int color = Color.abgrToArgb(image.getColor(x, y));
|
||||
if (ColorHelper.Argb.getAlpha(color) < 255) {
|
||||
return def;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<T> values = EnumSet.noneOf((Class<T>)def.def().getClass());
|
||||
if (flagReader.readFlag(ColorHelper.Argb.getRed(color), values)
|
||||
| flagReader.readFlag(ColorHelper.Argb.getGreen(color), values)
|
||||
| flagReader.readFlag(ColorHelper.Argb.getBlue(color), values)) {
|
||||
return new Flags<>(def.def(), values, color & 0x00FFFFFF);
|
||||
}
|
||||
return def;
|
||||
};
|
||||
}
|
||||
|
||||
if (Channel.ALPHA.readValue(x, y, image) < 255) {
|
||||
return (T)def;
|
||||
static <T extends TValue<T>> Int2ObjectOpenHashMap<T> buildLookup(T[] options) {
|
||||
Int2ObjectOpenHashMap<T> lookup = new Int2ObjectOpenHashMap<>();
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
lookup.put(options[i].colorCode(), options[i]);
|
||||
}
|
||||
|
||||
return TriggerPixelType.getByTriggerPixel((T)def, color);
|
||||
return lookup;
|
||||
}
|
||||
|
||||
public <T extends Enum<T> & TriggerPixelType<T>> TriggerPixelType.Multiple<T> readFlags(NativeImage image) {
|
||||
boolean[] out = new boolean[def.getClass().getEnumConstants().length];
|
||||
readFlags(out, image);
|
||||
return new TriggerPixelType.Multiple<>(readColor(image), (T)def, out);
|
||||
|
||||
T read(Mat image);
|
||||
|
||||
static boolean isTriggerPixelCoord(int x, int y) {
|
||||
return x <= MAX_COORDS.x && y <= MAX_COORDS.y;
|
||||
}
|
||||
|
||||
public <T extends Enum<T> & TriggerPixelType<T>> void readFlags(boolean[] out, NativeImage image) {
|
||||
readFlag(out, Channel.RED, image);
|
||||
readFlag(out, Channel.GREEN, image);
|
||||
readFlag(out, Channel.BLUE, image);
|
||||
interface Mat {
|
||||
int getColor(int x, int y);
|
||||
}
|
||||
|
||||
private <T extends Enum<T> & TriggerPixelType<T>> void readFlag(boolean[] out, Channel channel, NativeImage image) {
|
||||
|
||||
if (Channel.ALPHA.readValue(x, y, image) < 255) {
|
||||
return;
|
||||
}
|
||||
|
||||
T value = TriggerPixelType.getByTriggerPixel((T)def, channel.readValue(x, y, image));
|
||||
|
||||
out[value.ordinal()] |= value != def;
|
||||
}
|
||||
|
||||
public static boolean isTriggerPixelCoord(int x, int y) {
|
||||
return x <= MAX_READ_X && y <= MAX_READ_Y;
|
||||
}
|
||||
|
||||
enum Channel {
|
||||
RAW (0xFFFFFFFF, 0),
|
||||
ALL (0x00FFFFFF, 0),
|
||||
ALPHA(0x000000FF, 24),
|
||||
RED (0x000000FF, 0),
|
||||
GREEN(0x000000FF, 8),
|
||||
BLUE (0x000000FF, 16);
|
||||
|
||||
private int mask;
|
||||
private int offset;
|
||||
|
||||
Channel(int mask, int offset) {
|
||||
this.mask = mask;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public int readValue(int x, int y, NativeImage image) {
|
||||
return (Color.abgrToArgb(image.getColor(x, y)) >> offset) & mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface for enums that can be parsed from an image trigger pixel value.
|
||||
*/
|
||||
public interface TriggerPixelType<T> {
|
||||
/**
|
||||
* Gets the pixel colour matching this enum value.
|
||||
*/
|
||||
int colorCode();
|
||||
|
||||
/**
|
||||
* Gets the pixel colour matching this enum value, adjusted to fill all three channels.
|
||||
*/
|
||||
default int getChannelAdjustedColorCode() {
|
||||
return colorCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string representation of this value.
|
||||
*/
|
||||
default String name() {
|
||||
return "[Numeric " + getHexValue() + "]";
|
||||
}
|
||||
|
||||
default String getHexValue() {
|
||||
return toHex(colorCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of possible values this trigger pixel can accept.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
default <Option extends TriggerPixelType<T>> List<Option> getOptions() {
|
||||
if (this instanceof Enum) {
|
||||
// cast is required because gradle's compiler is more strict
|
||||
return (List<Option>)List.of(getClass().getEnumConstants());
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
default boolean matches(Object o) {
|
||||
return equals(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enum value corresponding to the given enum type and pixel value.
|
||||
* If none are found, the first parameter is returned as the default.
|
||||
*
|
||||
* @param type Return type and default value.
|
||||
* @param pixelValue The pixel colour to search for.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
static <T extends TriggerPixelType<T>> T getByTriggerPixel(T type, int pixelValue) {
|
||||
return (T)type.getOptions().stream()
|
||||
.filter(i -> i.colorCode() == pixelValue)
|
||||
.findFirst()
|
||||
.orElse(type);
|
||||
}
|
||||
|
||||
static TriggerPixelType<?> of(int color) {
|
||||
return () -> color;
|
||||
}
|
||||
|
||||
static String toHex(int color) {
|
||||
String v = Integer.toHexString(color).toUpperCase();
|
||||
while (v.length() < 6) {
|
||||
v = "0" + v;
|
||||
}
|
||||
return "#" + v;
|
||||
}
|
||||
|
||||
public record Multiple<T extends Enum<T> & TriggerPixelType<T>> (
|
||||
int colorCode,
|
||||
T def,
|
||||
boolean[] value
|
||||
) implements TriggerPixelType<boolean[]> {
|
||||
@Override
|
||||
public String name() {
|
||||
return "[Flags " + Arrays.toString(value) + "]";
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<TriggerPixelType<T>> getOptions() {
|
||||
return def.getOptions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object o) {
|
||||
return o.getClass() == def.getClass() && value()[((Enum<?>)o).ordinal()];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +1,31 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.client.model.gear.SaddleBags;
|
||||
import com.minelittlepony.common.util.Color;
|
||||
import net.minecraft.util.math.ColorHelper;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public enum Wearable implements TriggerPixelType<Wearable> {
|
||||
public enum Wearable implements TValue<Wearable> {
|
||||
NONE (0x00, null),
|
||||
CROWN (0x16, new Identifier("minelittlepony", "textures/models/crown.png")),
|
||||
MUFFIN (0x32, new Identifier("minelittlepony", "textures/models/muffin.png")),
|
||||
HAT (0x64, new Identifier("textures/entity/witch.png")),
|
||||
ANTLERS (0x96, new Identifier("minelittlepony", "textures/models/antlers.png")),
|
||||
SADDLE_BAGS_LEFT (0xC6, SaddleBags.TEXTURE),
|
||||
SADDLE_BAGS_RIGHT (0xC7, SaddleBags.TEXTURE),
|
||||
SADDLE_BAGS_BOTH (0xC8, SaddleBags.TEXTURE),
|
||||
SADDLE_BAGS_LEFT (0xC6, new Identifier("minelittlepony", "textures/models/saddlebags.png")),
|
||||
SADDLE_BAGS_RIGHT (0xC7, new Identifier("minelittlepony", "textures/models/saddlebags.png")),
|
||||
SADDLE_BAGS_BOTH (0xC8, new Identifier("minelittlepony", "textures/models/saddlebags.png")),
|
||||
STETSON (0xFA, new Identifier("minelittlepony", "textures/models/stetson.png"));
|
||||
|
||||
private int triggerValue;
|
||||
|
||||
private final Identifier id;
|
||||
|
||||
private final Identifier texture;
|
||||
|
||||
public static final List<Wearable> VALUES = Arrays.stream(values()).toList();
|
||||
public static final Map<Identifier, Wearable> REGISTRY = VALUES.stream().collect(Collectors.toMap(Wearable::getId, Function.identity()));
|
||||
public static final Map<Identifier, Wearable> REGISTRY = Arrays.stream(values()).collect(Collectors.toMap(Wearable::getId, Function.identity()));
|
||||
|
||||
public static final Flags<Wearable> EMPTY_FLAGS = Flags.of(Wearable.class);
|
||||
public static final Flags<Wearable> EMPTY_FLAGS = Flags.of(NONE);
|
||||
|
||||
Wearable(int pixel, Identifier texture) {
|
||||
triggerValue = pixel;
|
||||
|
@ -56,6 +52,6 @@ public enum Wearable implements TriggerPixelType<Wearable> {
|
|||
|
||||
@Override
|
||||
public int getChannelAdjustedColorCode() {
|
||||
return triggerValue == 0 ? 0 : Color.argbToHex(255, triggerValue, triggerValue, triggerValue);
|
||||
return triggerValue == 0 ? 0 : ColorHelper.Argb.getArgb(255, triggerValue, triggerValue, triggerValue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
package com.minelittlepony.client;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.client.model.armour.DefaultArmourTextureResolver;
|
||||
import com.minelittlepony.client.render.MobRenderers;
|
||||
import com.minelittlepony.common.client.gui.VisibilityMode;
|
||||
import com.minelittlepony.common.util.settings.Setting;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class ClientPonyConfig extends PonyConfig {
|
||||
|
||||
/**
|
||||
* Visibility mode for the horse button.
|
||||
*/
|
||||
public final Setting<VisibilityMode> horseButton = value("horseButton", VisibilityMode.AUTO)
|
||||
.addComment("Whether to show the mine little pony settings button on the main menu")
|
||||
.addComment("AUTO (default) - only show when HDSkins is not installed")
|
||||
.addComment("ON - always show")
|
||||
.addComment("OFF - never show");
|
||||
|
||||
public ClientPonyConfig(Path path) {
|
||||
super(path);
|
||||
MobRenderers.REGISTRY.values().forEach(r -> value("entities", r.name, true));
|
||||
disablePonifiedArmour.onChanged(t -> DefaultArmourTextureResolver.INSTANCE.invalidate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
super.save();
|
||||
PlayerEntity player = MinecraftClient.getInstance().player;
|
||||
if (player != null) {
|
||||
player.calculateDimensions();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import net.minecraft.entity.player.PlayerEntity;
|
|||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.*;
|
||||
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.common.util.settings.Setting;
|
||||
|
||||
|
@ -31,7 +32,7 @@ public class HorseCam {
|
|||
*/
|
||||
public static float transformCameraAngle(float pitch) {
|
||||
|
||||
if (!MineLittlePony.getInstance().getConfig().fillycam.get()) {
|
||||
if (!PonyConfig.getInstance().fillycam.get()) {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
|
@ -51,7 +52,7 @@ public class HorseCam {
|
|||
Pony pony = Pony.getManager().getPony(player);
|
||||
|
||||
if (!pony.race().isHuman()) {
|
||||
Setting<Boolean> fillyCam = MineLittlePony.getInstance().getConfig().fillycam;
|
||||
Setting<Boolean> fillyCam = PonyConfig.getInstance().fillycam;
|
||||
|
||||
fillyCam.set(false);
|
||||
final float vanillaHeight = player.getEyeHeight(player.getPose());
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package com.minelittlepony.client;
|
||||
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.pony.PonyManager;
|
||||
import com.minelittlepony.api.pony.network.fabric.Channel;
|
||||
import com.minelittlepony.api.events.Channel;
|
||||
import com.minelittlepony.client.model.ModelType;
|
||||
import com.minelittlepony.client.model.armour.ArmourTextureResolver;
|
||||
import com.minelittlepony.client.render.MobRenderers;
|
||||
import com.minelittlepony.client.render.PonyRenderDispatcher;
|
||||
import com.minelittlepony.common.client.gui.VisibilityMode;
|
||||
import com.minelittlepony.common.client.gui.element.Button;
|
||||
|
@ -13,6 +14,8 @@ import com.minelittlepony.common.event.ScreenInitCallback;
|
|||
import com.minelittlepony.common.event.SkinFilterCallback;
|
||||
import com.minelittlepony.common.util.GamePaths;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||
|
@ -23,6 +26,7 @@ import net.minecraft.client.gui.screen.Screen;
|
|||
import net.minecraft.client.gui.screen.TitleScreen;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
@ -38,7 +42,6 @@ public class MineLittlePony implements ClientModInitializer {
|
|||
|
||||
public static final Logger logger = LogManager.getLogger("MineLittlePony");
|
||||
|
||||
private ClientPonyConfig config;
|
||||
private PonyManagerImpl ponyManager;
|
||||
private VariatedTextureSupplier variatedTextures;
|
||||
|
||||
|
@ -65,7 +68,7 @@ public class MineLittlePony implements ClientModInitializer {
|
|||
hasHdSkins = FabricLoader.getInstance().isModLoaded("hdskins");
|
||||
hasModMenu = FabricLoader.getInstance().isModLoaded("modmenu");
|
||||
|
||||
config = new ClientPonyConfig(GamePaths.getConfigDirectory().resolve("minelp.json"));
|
||||
PonyConfig config = new ClientPonyConfig(GamePaths.getConfigDirectory().resolve("minelp.json"));
|
||||
ponyManager = new PonyManagerImpl(config);
|
||||
variatedTextures = new VariatedTextureSupplier();
|
||||
|
||||
|
@ -103,13 +106,13 @@ public class MineLittlePony implements ClientModInitializer {
|
|||
}
|
||||
|
||||
if ((mainMenu || inGame) && keyBinding.isPressed()) {
|
||||
client.setScreen(new PonySettingsscreen(client.currentScreen));
|
||||
client.setScreen(new PonySettingsScreen(client.currentScreen));
|
||||
}
|
||||
}
|
||||
|
||||
private void onScreenInit(Screen screen, ScreenInitCallback.ButtonList buttons) {
|
||||
if (screen instanceof TitleScreen) {
|
||||
VisibilityMode mode = config.horseButton.get();
|
||||
VisibilityMode mode = ClientPonyConfig.getInstance().horseButton.get();
|
||||
boolean show = mode == VisibilityMode.ON || (mode == VisibilityMode.AUTO
|
||||
&& !(hasHdSkins || hasModMenu
|
||||
));
|
||||
|
@ -117,7 +120,7 @@ public class MineLittlePony implements ClientModInitializer {
|
|||
if (show) {
|
||||
int y = hasHdSkins ? 75 : 50;
|
||||
Button button = buttons.addButton(new Button(screen.width - 50, screen.height - y, 20, 20))
|
||||
.onClick(sender -> MinecraftClient.getInstance().setScreen(new PonySettingsscreen(screen)));
|
||||
.onClick(sender -> MinecraftClient.getInstance().setScreen(new PonySettingsScreen(screen)));
|
||||
button.getStyle()
|
||||
.setIcon(new TextureSprite()
|
||||
.setPosition(2, 2)
|
||||
|
@ -130,14 +133,7 @@ public class MineLittlePony implements ClientModInitializer {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the global MineLP client configuration.
|
||||
*/
|
||||
public PonyConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public PonyManager getManager() {
|
||||
public PonyManagerImpl getManager() {
|
||||
return ponyManager;
|
||||
}
|
||||
|
||||
|
@ -151,5 +147,22 @@ public class MineLittlePony implements ClientModInitializer {
|
|||
public PonyRenderDispatcher getRenderDispatcher() {
|
||||
return renderDispatcher;
|
||||
}
|
||||
|
||||
private static final class ClientPonyConfig extends PonyConfig {
|
||||
public ClientPonyConfig(Path path) {
|
||||
super(path);
|
||||
MobRenderers.REGISTRY.values().forEach(r -> value("entities", r.name, true));
|
||||
disablePonifiedArmour.onChanged(t -> ArmourTextureResolver.INSTANCE.invalidate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
super.save();
|
||||
PlayerEntity player = MinecraftClient.getInstance().player;
|
||||
if (player != null) {
|
||||
player.calculateDimensions();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import net.minecraft.util.Identifier;
|
|||
|
||||
import com.google.gson.*;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.pony.meta.*;
|
||||
import com.minelittlepony.client.util.render.NativeUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -53,16 +52,7 @@ class PonyDataLoader {
|
|||
}).map(PonyDataLoader::loaded).orElseGet(() -> {
|
||||
return load(callback -> {
|
||||
NativeUtil.parseImage(identifier, image -> {
|
||||
callback.accept(new PonyData(
|
||||
TriggerPixel.RACE.readValue(image),
|
||||
TriggerPixel.TAIL.readValue(image),
|
||||
TriggerPixel.TAIL_SHAPE.readValue(image),
|
||||
TriggerPixel.GENDER.readValue(image),
|
||||
TriggerPixel.SIZE.readValue(image),
|
||||
TriggerPixel.GLOW.readColor(image),
|
||||
TriggerPixel.WEARABLES.readFlags(image),
|
||||
noSkin
|
||||
));
|
||||
callback.accept(new PonyData(image, noSkin));
|
||||
}, e -> {
|
||||
MineLittlePony.logger.fatal("Unable to read {} metadata", identifier, e);
|
||||
callback.accept(PonyData.NULL);
|
||||
|
|
|
@ -9,10 +9,10 @@ import com.minelittlepony.client.render.blockentity.skull.PonySkullRenderer;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.AbstractClientPlayerEntity;
|
||||
import net.minecraft.client.util.DefaultSkinHelper;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
@ -22,25 +22,18 @@ import java.util.UUID;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* The PonyManager is responsible for reading and recoding all the pony data associated with an entity of skin.
|
||||
*/
|
||||
class PonyManagerImpl implements PonyManager, SimpleSynchronousResourceReloadListener {
|
||||
public class PonyManagerImpl implements PonyManager, SimpleSynchronousResourceReloadListener {
|
||||
private static final Identifier ID = new Identifier("minelittlepony", "background_ponies");
|
||||
|
||||
private final PonyConfig config;
|
||||
|
||||
private final LoadingCache<Identifier, Pony> defaultedPoniesCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(30, TimeUnit.SECONDS)
|
||||
.build(CacheLoader.from(resource -> {
|
||||
return new Pony(resource, PonyDataLoader.parse(resource, true));
|
||||
}));
|
||||
.build(CacheLoader.from(resource -> new Pony(resource, PonyDataLoader.parse(resource, true))));
|
||||
|
||||
private final LoadingCache<Identifier, Pony> poniesCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(30, TimeUnit.SECONDS)
|
||||
.build(CacheLoader.from(resource -> {
|
||||
return new Pony(resource, PonyDataLoader.parse(resource, false));
|
||||
}));
|
||||
.build(CacheLoader.from(resource -> new Pony(resource, PonyDataLoader.parse(resource, false))));
|
||||
|
||||
public PonyManagerImpl(PonyConfig config) {
|
||||
this.config = config;
|
||||
|
@ -56,78 +49,61 @@ class PonyManagerImpl implements PonyManager, SimpleSynchronousResourceReloadLis
|
|||
}
|
||||
|
||||
@Override
|
||||
public Pony getPony(Identifier resource) {
|
||||
return loadPony(resource, false);
|
||||
public Pony getPony(PlayerEntity player) {
|
||||
return getPony(getSkin(player), player instanceof ForcedPony ? null : player.getGameProfile() == null ? player.getUuid() : player.getGameProfile().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Pony> getPony(@Nullable Entity entity) {
|
||||
public Optional<Pony> getPony(LivingEntity entity) {
|
||||
if (entity instanceof PlayerEntity player) {
|
||||
return Optional.of(getPony(player));
|
||||
}
|
||||
|
||||
if (entity instanceof LivingEntity living) {
|
||||
return Optional.ofNullable(MineLittlePony.getInstance().getRenderDispatcher().getPonyRenderer(living)).map(d -> d.getEntityPony(living));
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
Identifier skin = getSkin(entity);
|
||||
return skin == null ? Optional.empty() : Optional.of(getPony(skin, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pony getPony(PlayerEntity player) {
|
||||
Identifier skin = getSkin(player);
|
||||
UUID uuid = player.getGameProfile() == null ? player.getUuid() : player.getGameProfile().getId();
|
||||
|
||||
if (skin != null) {
|
||||
if (player instanceof PonyManager.ForcedPony) {
|
||||
return getPony(skin);
|
||||
}
|
||||
|
||||
return getPony(skin, uuid);
|
||||
public Pony getPony(@Nullable Identifier resource, @Nullable UUID uuid) {
|
||||
if (resource == null) {
|
||||
return uuid == null ? loadPony(DefaultSkinHelper.getTexture(), true) : getBackgroundPony(uuid);
|
||||
}
|
||||
|
||||
if (config.ponyLevel.get() == PonyLevel.PONIES) {
|
||||
Pony pony = loadPony(resource, false);
|
||||
|
||||
if (uuid != null && PonyConfig.getInstance().ponyLevel.get() == PonyLevel.PONIES && pony.metadata().race().isHuman()) {
|
||||
return getBackgroundPony(uuid);
|
||||
}
|
||||
|
||||
return loadPony(DefaultSkinHelper.getTexture(uuid).texture(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pony getPony(Identifier resource, UUID uuid) {
|
||||
Pony pony = getPony(resource);
|
||||
|
||||
if (config.ponyLevel.get() == PonyLevel.PONIES && pony.metadata().race().isHuman()) {
|
||||
return getBackgroundPony(uuid);
|
||||
}
|
||||
|
||||
return pony;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pony getBackgroundPony(UUID uuid) {
|
||||
return loadPony(MineLittlePony.getInstance().getVariatedTextures().get(VariatedTextureSupplier.BACKGROUND_PONIES_POOL, uuid).orElse(DefaultSkinHelper.getTexture(uuid).texture()), true);
|
||||
public Pony getBackgroundPony(@Nullable UUID uuid) {
|
||||
if (config.ponyLevel.get() == PonyLevel.PONIES) {
|
||||
return loadPony(MineLittlePony.getInstance().getVariatedTextures().get(VariatedTextureSupplier.BACKGROUND_PONIES_POOL, uuid).orElse(DefaultSkinHelper.getSkinTextures(uuid).texture()), true);
|
||||
}
|
||||
return loadPony(DefaultSkinHelper.getSkinTextures(uuid).texture(), true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Identifier getSkin(PlayerEntity player) {
|
||||
if (player.getGameProfile() == null) {
|
||||
return null;
|
||||
}
|
||||
if (player instanceof AbstractClientPlayerEntity) {
|
||||
return ((AbstractClientPlayerEntity)player).method_52814().texture();
|
||||
private Identifier getSkin(LivingEntity entity) {
|
||||
if (entity instanceof PlayerEntity player) {
|
||||
if (player.getGameProfile() != null && player instanceof AbstractClientPlayerEntity clientPlayer) {
|
||||
return clientPlayer.getSkinTextures().texture();
|
||||
}
|
||||
} else {
|
||||
if (MineLittlePony.getInstance().getRenderDispatcher().getPonyRenderer(entity) != null) {
|
||||
return MinecraftClient.getInstance().getEntityRenderDispatcher().getRenderer(entity).getTexture(entity);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePony(Identifier resource) {
|
||||
poniesCache.invalidate(resource);
|
||||
defaultedPoniesCache.invalidate(resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCache() {
|
||||
MineLittlePony.logger.info("Flushed {} cached ponies.", poniesCache.size());
|
||||
poniesCache.invalidateAll();
|
||||
|
|
|
@ -5,6 +5,7 @@ import net.minecraft.client.gui.DrawContext;
|
|||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.text.*;
|
||||
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.client.render.MobRenderers;
|
||||
import com.minelittlepony.common.client.gui.GameGui;
|
||||
import com.minelittlepony.common.client.gui.ScrollContainer;
|
||||
|
@ -23,7 +24,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
* In-Game options menu.
|
||||
*
|
||||
*/
|
||||
public class PonySettingsscreen extends GameGui {
|
||||
public class PonySettingsScreen extends GameGui {
|
||||
private static final String OPTIONS_PREFIX = "minelp.options.";
|
||||
private static final String PONY_LEVEL = OPTIONS_PREFIX + "ponylevel";
|
||||
private static final String MOB_PREFIX = "minelp.mobs.";
|
||||
|
@ -34,17 +35,22 @@ public class PonySettingsscreen extends GameGui {
|
|||
public static final Text SCALE_SHOW = Text.translatable("minelp.debug.scale.sa");
|
||||
public static final Text SCALE_MIN = Text.translatable("minelp.debug.scale.min");
|
||||
|
||||
private ClientPonyConfig config;
|
||||
public static HorseButtonFactory buttonFactory = (screen, parent, row, RIGHT, content) -> {
|
||||
content.addButton(new Button(RIGHT, row += 20, 150, 20))
|
||||
.setEnabled(false)
|
||||
.getStyle()
|
||||
.setTooltip(Tooltip.of("minelp.options.skins.hdskins.disabled", 200))
|
||||
.setText("minelp.options.skins.hdskins.open");
|
||||
};
|
||||
|
||||
private final PonyConfig config = PonyConfig.getInstance();
|
||||
|
||||
private final ScrollContainer content = new ScrollContainer();
|
||||
|
||||
private final boolean hiddenOptions;
|
||||
|
||||
public PonySettingsscreen(@Nullable Screen parent) {
|
||||
public PonySettingsScreen(@Nullable Screen parent) {
|
||||
super(Text.literal(OPTIONS_PREFIX + "title"), parent);
|
||||
|
||||
config = (ClientPonyConfig)MineLittlePony.getInstance().getConfig();
|
||||
|
||||
content.margin.top = 30;
|
||||
content.margin.bottom = 30;
|
||||
content.getContentPadding().top = 10;
|
||||
|
@ -158,7 +164,7 @@ public class PonySettingsscreen extends GameGui {
|
|||
row += 15;
|
||||
|
||||
content.addButton(new Label(RIGHT, row)).getStyle().setText("minelp.options.skins");
|
||||
SkinsProxy.instance.renderOption(this, parent, row, RIGHT, content);
|
||||
buttonFactory.renderOption(this, parent, row, RIGHT, content);
|
||||
}
|
||||
|
||||
public Text describeCurrentScale(AbstractSlider<Float> sender) {
|
||||
|
@ -188,7 +194,6 @@ public class PonySettingsscreen extends GameGui {
|
|||
|
||||
@Override
|
||||
public void render(DrawContext context, int mouseX, int mouseY, float tickDelta) {
|
||||
renderBackground(context, mouseX, mouseY, tickDelta);
|
||||
super.render(context, mouseX, mouseY, tickDelta);
|
||||
content.render(context, mouseX, mouseY, tickDelta);
|
||||
}
|
||||
|
@ -197,4 +202,8 @@ public class PonySettingsscreen extends GameGui {
|
|||
public void removed() {
|
||||
config.save();
|
||||
}
|
||||
|
||||
public interface HorseButtonFactory {
|
||||
void renderOption(Screen screen, @Nullable Screen parent, int row, int RIGHT, ScrollContainer content);
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package com.minelittlepony.client;
|
||||
|
||||
public interface PreviewModel {
|
||||
boolean forceSeapony();
|
||||
}
|
|
@ -2,9 +2,8 @@ package com.minelittlepony.client.compat.hdskins;
|
|||
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
|
||||
import com.minelittlepony.api.model.PreviewModel;
|
||||
import com.minelittlepony.api.pony.*;
|
||||
import com.minelittlepony.client.PreviewModel;
|
||||
import com.minelittlepony.client.render.EquineRenderManager;
|
||||
import com.minelittlepony.hdskins.client.gui.player.*;
|
||||
import com.minelittlepony.hdskins.client.gui.player.skins.PlayerSkins;
|
||||
|
||||
|
@ -13,20 +12,20 @@ import java.util.UUID;
|
|||
/**
|
||||
* Dummy model used for the skin uploading screen.
|
||||
*/
|
||||
class DummyPony extends DummyPlayer implements PreviewModel, PonyManager.ForcedPony, EquineRenderManager.RegistrationHandler {
|
||||
class DummyPony extends DummyPlayer implements PreviewModel, PonyManager.ForcedPony {
|
||||
|
||||
public DummyPony(ClientWorld world, PlayerSkins<?> textures) {
|
||||
super(world, textures);
|
||||
setUuid(UUID.randomUUID()); // uuid must be random so animations aren't linked between the two previews
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldUpdateRegistration(Pony pony) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean forceSeapony() {
|
||||
return getTextures().getPosture().getActiveSkinType() == MineLPHDSkins.seaponySkinType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean forceNirik() {
|
||||
return getTextures().getPosture().getActiveSkinType() == MineLPHDSkins.nirikSkinType;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.minelittlepony.client.compat.hdskins;
|
||||
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.client.PonySettingsscreen;
|
||||
import com.minelittlepony.client.PonySettingsScreen;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.common.client.gui.dimension.Bounds;
|
||||
import com.minelittlepony.common.client.gui.element.Button;
|
||||
|
@ -29,22 +28,22 @@ class GuiSkinsMineLP extends GuiSkins {
|
|||
chooser.addSkinChangedEventListener(type -> {
|
||||
MineLittlePony.logger.debug("Invalidating old local skin, checking updated local skin");
|
||||
if (type == SkinType.SKIN) {
|
||||
Pony.getManager().removePony(previewer.getLocal().getSkins().get(SkinType.SKIN).getId());
|
||||
MineLittlePony.getInstance().getManager().removePony(previewer.getLocal().getSkins().get(SkinType.SKIN).getId());
|
||||
}
|
||||
});
|
||||
uploader.addSkinLoadedEventListener((type, location, profileTexture) -> {
|
||||
MineLittlePony.logger.debug("Invalidating old remote skin, checking updated remote skin");
|
||||
if (type == SkinType.SKIN) {
|
||||
Pony.getManager().removePony(location);
|
||||
MineLittlePony.getInstance().getManager().removePony(location);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initServerPreviewButtons(Bounds area) {
|
||||
if (!(parent instanceof PonySettingsscreen)) {
|
||||
if (!(parent instanceof PonySettingsScreen)) {
|
||||
addButton(new Button(area.right() - 20, area.bottom() + 5, 20, 20))
|
||||
.onClick(sender -> client.setScreen(new PonySettingsscreen(this)))
|
||||
.onClick(sender -> client.setScreen(new PonySettingsScreen(this)))
|
||||
.getStyle()
|
||||
.setIcon(new TextureSprite()
|
||||
.setPosition(2, 2)
|
||||
|
|
|
@ -4,7 +4,7 @@ import net.minecraft.client.gui.DrawContext;
|
|||
import net.minecraft.text.Text;
|
||||
|
||||
import com.minelittlepony.api.pony.*;
|
||||
import com.minelittlepony.api.pony.meta.TriggerPixelType;
|
||||
import com.minelittlepony.api.pony.meta.TValue;
|
||||
import com.minelittlepony.common.client.gui.ITextContext;
|
||||
import com.minelittlepony.common.client.gui.dimension.Bounds;
|
||||
import com.minelittlepony.hdskins.client.gui.Carousel;
|
||||
|
@ -37,7 +37,7 @@ class LegendOverlayWidget implements Carousel.Element, ITextContext {
|
|||
});
|
||||
}
|
||||
|
||||
private void drawLegendBlock(DrawContext context, int index, int x, int y, int mouseX, int mouseY, String key, TriggerPixelType<?> value) {
|
||||
private void drawLegendBlock(DrawContext context, int index, int x, int y, int mouseX, int mouseY, String key, TValue<?> value) {
|
||||
context.fill(0, 0, LEGEND_BLOCK_BOUNDS.width, LEGEND_BLOCK_BOUNDS.height, 0xFF003333);
|
||||
context.fill(1, 1, LEGEND_BLOCK_BOUNDS.width - 1, LEGEND_BLOCK_BOUNDS.height - 1, value.colorCode() | 0xFF000000);
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package com.minelittlepony.client.compat.hdskins;
|
||||
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.config.PonyLevel;
|
||||
import com.minelittlepony.api.pony.*;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.common.client.gui.ScrollContainer;
|
||||
import com.minelittlepony.common.client.gui.element.Button;
|
||||
|
@ -10,6 +11,7 @@ import com.minelittlepony.hdskins.client.*;
|
|||
import com.minelittlepony.hdskins.client.gui.GuiSkins;
|
||||
import com.minelittlepony.hdskins.client.gui.player.DummyPlayer;
|
||||
import com.minelittlepony.hdskins.client.gui.player.skins.PlayerSkins.PlayerSkin;
|
||||
import com.minelittlepony.hdskins.client.profile.SkinLoader.ProvidedSkins;
|
||||
import com.minelittlepony.hdskins.profile.SkinType;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
@ -27,7 +29,6 @@ import net.minecraft.item.Items;
|
|||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.client.*;
|
||||
import com.minelittlepony.client.render.entity.AquaticPlayerPonyRenderer;
|
||||
|
||||
/**
|
||||
* All the interactions with HD Skins.
|
||||
|
@ -35,15 +36,18 @@ import com.minelittlepony.client.render.entity.AquaticPlayerPonyRenderer;
|
|||
public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer {
|
||||
|
||||
static SkinType seaponySkinType;
|
||||
static SkinType nirikSkinType;
|
||||
|
||||
static final Map<SkinType, Wearable> wearableTypes = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
SkinsProxy.instance = this;
|
||||
PonySettingsScreen.buttonFactory = this::renderOption;
|
||||
|
||||
seaponySkinType = SkinType.register(AquaticPlayerPonyRenderer.SKIN_TYPE_ID, Items.COD_BUCKET.getDefaultStack());
|
||||
Wearable.VALUES.forEach(wearable -> {
|
||||
seaponySkinType = SkinType.register(DefaultPonySkinHelper.SEAPONY_SKIN_TYPE_ID, Items.COD_BUCKET.getDefaultStack());
|
||||
nirikSkinType = SkinType.register(DefaultPonySkinHelper.NIRIK_SKIN_TYPE_ID, Items.LAVA_BUCKET.getDefaultStack());
|
||||
Wearable.REGISTRY.values().forEach(wearable -> {
|
||||
if (wearable != Wearable.NONE) {
|
||||
wearableTypes.put(SkinType.register(wearable.getId(), Items.BUNDLE.getDefaultStack()), wearable);
|
||||
}
|
||||
|
@ -56,10 +60,29 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer {
|
|||
// Ponify the skins GUI.
|
||||
GuiSkins.setSkinsGui(GuiSkinsMineLP::new);
|
||||
});
|
||||
|
||||
HDSkins.getInstance().getSkinPrioritySorter().addSelector((skinType, playerSkins) -> {
|
||||
if (skinType == SkinType.SKIN && PonyConfig.getInstance().mixedHumanSkins.get()) {
|
||||
Optional<Pony> hdPony = getPony(playerSkins.hd());
|
||||
Optional<Pony> vanillaPony = getPony(playerSkins.vanilla());
|
||||
|
||||
if (hdPony.isPresent() && vanillaPony.isPresent()
|
||||
&& vanillaPony.get().metadata().priority() > hdPony.get().metadata().priority()
|
||||
&& (PonyConfig.getInstance().ponyLevel.get() == PonyLevel.HUMANS || vanillaPony.get().metadata().race().isHuman() == hdPony.get().metadata().race().isHuman())) {
|
||||
return playerSkins.vanilla();
|
||||
}
|
||||
}
|
||||
return playerSkins.combined();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderOption(Screen screen, @Nullable Screen parent, int row, int RIGHT, ScrollContainer content) {
|
||||
static Optional<Pony> getPony(PlayerSkinLayers.Layer layer) {
|
||||
return layer
|
||||
.getSkin(SkinType.SKIN)
|
||||
.map(Pony.getManager()::getPony);
|
||||
}
|
||||
|
||||
private void renderOption(Screen screen, @Nullable Screen parent, int row, int RIGHT, ScrollContainer content) {
|
||||
content.addButton(new Button(RIGHT, row += 20, 150, 20))
|
||||
.onClick(button -> MinecraftClient.getInstance().setScreen(
|
||||
parent instanceof GuiSkins ? parent : GuiSkins.create(screen, HDSkins.getInstance().getSkinServerList())
|
||||
|
@ -80,10 +103,11 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer {
|
|||
}
|
||||
|
||||
if (entity instanceof AbstractClientPlayerEntity player) {
|
||||
PlayerSkins skins = PlayerSkins.of(player);
|
||||
if (skins != null) {
|
||||
return skins.getProvidedSkinTypes();
|
||||
}
|
||||
return PlayerSkins.of(player)
|
||||
.map(PlayerSkins::layers)
|
||||
.map(PlayerSkinLayers::combined)
|
||||
.map(PlayerSkinLayers.Layer::getProvidedSkinTypes)
|
||||
.orElseGet(Set::of);
|
||||
}
|
||||
|
||||
return Set.of();
|
||||
|
@ -100,7 +124,7 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer {
|
|||
PlayerSkin main = dummy.getTextures().get(SkinType.SKIN);
|
||||
Wearable wearable = Wearable.REGISTRY.getOrDefault(type.getId(), Wearable.NONE);
|
||||
PonyData metadata = Pony.getManager().getPony(main.getId()).metadata();
|
||||
if (wearable != Wearable.NONE && metadata.isWearing(wearable)) {
|
||||
if (wearable != Wearable.NONE && metadata.gear().matches(wearable)) {
|
||||
|
||||
if (wearable.isSaddlebags() && metadata.race().supportsLegacySaddlebags()) {
|
||||
return Optional.of(main.getId());
|
||||
|
@ -110,13 +134,16 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer {
|
|||
}
|
||||
}
|
||||
|
||||
return Optional.of(player).map(PlayerSkins::of).map(skins -> skins.getSkin(type));
|
||||
return Optional.of(player).flatMap(PlayerSkins::of)
|
||||
.map(PlayerSkins::layers)
|
||||
.map(PlayerSkinLayers::combined).flatMap(skins -> skins.getSkin(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getSkinTexture(GameProfile profile) {
|
||||
return HDSkins.getInstance().getProfileRepository()
|
||||
.getNow(profile)
|
||||
.load(profile)
|
||||
.getNow(ProvidedSkins.EMPTY)
|
||||
.getSkin(SkinType.SKIN)
|
||||
.orElseGet(() -> super.getSkinTexture(profile));
|
||||
}
|
||||
|
|
|
@ -31,6 +31,9 @@ class PonifiedDualCarouselWidget extends DualCarouselWidget {
|
|||
if (type == MineLPHDSkins.seaponySkinType) {
|
||||
return NativeImageFilters.GREYSCALE.load(SeaponyRenderer.SEAPONY, SeaponyRenderer.SEAPONY, getExclusion());
|
||||
}
|
||||
if (type == MineLPHDSkins.nirikSkinType) {
|
||||
return super.getDefaultSkin(SkinType.SKIN, modelVariant);
|
||||
}
|
||||
|
||||
Wearable wearable = MineLPHDSkins.wearableTypes.getOrDefault(type, Wearable.NONE);
|
||||
|
||||
|
|
|
@ -3,11 +3,11 @@ package com.minelittlepony.client.compat.modmenu;
|
|||
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||
|
||||
import com.minelittlepony.client.PonySettingsscreen;
|
||||
import com.minelittlepony.client.PonySettingsScreen;
|
||||
|
||||
public class MineLPModMenuFactory implements ModMenuApi {
|
||||
@Override
|
||||
public ConfigScreenFactory<?> getModConfigScreenFactory() {
|
||||
return PonySettingsscreen::new;
|
||||
return PonySettingsScreen::new;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.entity.EntityDimensions;
|
||||
import net.minecraft.entity.EntityPose;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
|
@ -20,8 +19,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity implements EquineRenderManager.RegistrationHandler {
|
||||
public MixinClientPlayerEntity() { super(null, null); }
|
||||
|
||||
@Nullable
|
||||
private Pony pony;
|
||||
private final EquineRenderManager.SyncedPony syncedPony = new EquineRenderManager.SyncedPony();
|
||||
|
||||
@Inject(method = "startRiding(Lnet/minecraft/entity/Entity;Z)Z", at = @At("RETURN"))
|
||||
private void onStartRiding(Entity entity, boolean bl, CallbackInfoReturnable<Boolean> info) {
|
||||
|
@ -34,12 +32,8 @@ abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity implem
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldUpdateRegistration(Pony pony) {
|
||||
if (this.pony != pony && (this.pony == null || this.pony.metadata().compareTo(pony.metadata()) != 0)) {
|
||||
this.pony = pony.immutableCopy();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
public EquineRenderManager.SyncedPony getSyncedPony() {
|
||||
return syncedPony;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.minelittlepony.client.mixin;
|
||||
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.config.PonyLevel;
|
||||
import com.minelittlepony.api.pony.DefaultPonySkinHelper;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
|
||||
import net.minecraft.client.util.DefaultSkinHelper;
|
||||
import net.minecraft.client.util.SkinTextures;
|
||||
|
@ -21,16 +21,16 @@ abstract class MixinDefaultSkinHelper {
|
|||
at = @At("RETURN"),
|
||||
cancellable = true)
|
||||
private static void onGetTexture(CallbackInfoReturnable<Identifier> cir) {
|
||||
if (MineLittlePony.getInstance().getConfig().ponyLevel.get() == PonyLevel.PONIES) {
|
||||
if (PonyConfig.getInstance().ponyLevel.get() == PonyLevel.PONIES) {
|
||||
cir.setReturnValue(DefaultPonySkinHelper.STEVE);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "getTexture(Ljava/util/UUID;)Lnet/minecraft/client/util/SkinTextures;",
|
||||
@Inject(method = "getSkinTextures(Ljava/util/UUID;)Lnet/minecraft/client/util/SkinTextures;",
|
||||
at = @At("RETURN"),
|
||||
cancellable = true)
|
||||
private static void onGetTexture(UUID uuid, CallbackInfoReturnable<SkinTextures> cir) {
|
||||
if (MineLittlePony.getInstance().getConfig().ponyLevel.get() == PonyLevel.PONIES) {
|
||||
if (PonyConfig.getInstance().ponyLevel.get() == PonyLevel.PONIES) {
|
||||
cir.setReturnValue(DefaultPonySkinHelper.getTextures(cir.getReturnValue()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.minelittlepony.client.model;
|
||||
|
||||
import com.minelittlepony.api.model.*;
|
||||
import com.minelittlepony.api.model.fabric.PonyModelPrepareCallback;
|
||||
import com.minelittlepony.api.pony.meta.Sizes;
|
||||
import com.minelittlepony.api.events.PonyModelPrepareCallback;
|
||||
import com.minelittlepony.api.pony.meta.SizePreset;
|
||||
import com.minelittlepony.client.transform.PonyTransformation;
|
||||
import com.minelittlepony.client.util.render.RenderList;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
@ -50,7 +50,7 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
|
||||
protected final RenderList mainRenderList;
|
||||
|
||||
private final List<IPart> parts = new ArrayList<>();
|
||||
private final List<SubModel> parts = new ArrayList<>();
|
||||
|
||||
public AbstractPonyModel(ModelPart tree) {
|
||||
super(tree);
|
||||
|
@ -66,18 +66,18 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
.add(withStage(BodyPart.HEAD, helmetRenderList = RenderList.of(hat)));
|
||||
}
|
||||
|
||||
protected <P extends IPart> P addPart(P part) {
|
||||
protected <P extends SubModel> P addPart(P part) {
|
||||
parts.add(part);
|
||||
return part;
|
||||
}
|
||||
|
||||
protected RenderList forPart(Supplier<IPart> part) {
|
||||
protected RenderList forPart(Supplier<SubModel> part) {
|
||||
return (stack, vertices, overlayUv, lightUv, red, green, blue, alpha) -> {
|
||||
part.get().renderPart(stack, vertices, overlayUv, lightUv, red, green, blue, alpha, attributes);
|
||||
};
|
||||
}
|
||||
|
||||
protected RenderList forPart(IPart part) {
|
||||
protected RenderList forPart(SubModel part) {
|
||||
return (stack, vertices, overlayUv, lightUv, red, green, blue, alpha) -> {
|
||||
part.renderPart(stack, vertices, overlayUv, lightUv, red, green, blue, alpha, attributes);
|
||||
};
|
||||
|
@ -119,11 +119,10 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
}
|
||||
|
||||
protected void setModelAngles(T entity, float limbAngle, float limbSpeed, float animationProgress, float headYaw, float headPitch) {
|
||||
|
||||
float pitch = (float)Math.toRadians(attributes.motionPitch);
|
||||
float pitch = attributes.motionPitch * MathHelper.RADIANS_PER_DEGREE;
|
||||
head.setAngles(
|
||||
MathHelper.clamp(attributes.isSleeping ? 0.1f : headPitch / 57.29578F, -1.25f - pitch, 0.5f - pitch),
|
||||
attributes.isSleeping ? (Math.abs(entity.getUuid().getMostSignificantBits()) % 2.8F) - 1.9F : headYaw / 57.29578F,
|
||||
attributes.isSleeping ? (Math.signum(MathHelper.wrapDegrees(headYaw)) * 1.3F) : headYaw * MathHelper.RADIANS_PER_DEGREE,
|
||||
0
|
||||
);
|
||||
|
||||
|
@ -149,7 +148,7 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
} else {
|
||||
adjustBody(0, ORIGIN);
|
||||
|
||||
if (!attributes.isSleeping) {
|
||||
if (!attributes.isLyingDown) {
|
||||
animateBreathing(animationProgress);
|
||||
}
|
||||
|
||||
|
@ -159,7 +158,7 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
}
|
||||
}
|
||||
|
||||
if (attributes.isSleeping) {
|
||||
if (attributes.isLyingDown) {
|
||||
ponySleep();
|
||||
}
|
||||
|
||||
|
@ -197,7 +196,6 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
leftLeg.pitch = MathUtil.Angles._90_DEG;
|
||||
|
||||
HEAD_SLEEPING.set(head);
|
||||
head.pivotZ = sneaking ? -1 : 1;
|
||||
|
||||
FONT_LEGS_SLEEPING.add(rightArm);
|
||||
FONT_LEGS_SLEEPING.add(leftArm);
|
||||
|
@ -341,7 +339,7 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
}
|
||||
|
||||
protected float getLegOutset() {
|
||||
if (attributes.isSleeping) {
|
||||
if (attributes.isLyingDown) {
|
||||
return 3.6f;
|
||||
}
|
||||
|
||||
|
@ -368,6 +366,7 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
case NECK: return neck;
|
||||
case TAIL:
|
||||
case LEGS:
|
||||
case BACK:
|
||||
case BODY: return body;
|
||||
}
|
||||
}
|
||||
|
@ -437,7 +436,8 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
break;
|
||||
case THROW_SPEAR:
|
||||
arm.pitch = MathUtil.Angles._90_DEG * 2;
|
||||
arm.roll += 0.3F * -limbSpeed * sigma;
|
||||
arm.roll += (0.3F * -limbSpeed + 0.6F) * sigma;
|
||||
arm.pivotY ++;
|
||||
break;
|
||||
case SPYGLASS:
|
||||
float addedPitch = sneaking ? -0.2617994F : 0;
|
||||
|
@ -450,10 +450,10 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
arm.pivotX -= 6 * sigma;
|
||||
arm.pivotZ -= 2;
|
||||
}
|
||||
if (getSize() == Sizes.TALL) {
|
||||
if (getSize() == SizePreset.TALL) {
|
||||
arm.pivotY += 1;
|
||||
}
|
||||
if (getSize() == Sizes.FOAL) {
|
||||
if (getSize() == SizePreset.FOAL) {
|
||||
arm.pivotY -= 2;
|
||||
}
|
||||
|
||||
|
@ -490,7 +490,7 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
* @param entity The entity we are being called for.
|
||||
*/
|
||||
protected void swingItem(T entity) {
|
||||
if (getSwingAmount() > 0 && !attributes.isSleeping) {
|
||||
if (getSwingAmount() > 0 && !attributes.isLyingDown) {
|
||||
Arm mainSide = getPreferredArm(entity);
|
||||
|
||||
swingArm(getArm(mainSide));
|
||||
|
@ -558,7 +558,7 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
|
||||
@Override
|
||||
public float getRiderYOffset() {
|
||||
switch ((Sizes)getSize()) {
|
||||
switch ((SizePreset)getSize()) {
|
||||
case NORMAL: return 0.4F;
|
||||
case FOAL:
|
||||
case TALL:
|
||||
|
@ -604,10 +604,10 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
matrices.translate(left / 10, -0.2F, -0.5F);
|
||||
}
|
||||
|
||||
matrices.translate(left * 0.1F, 0.45F, 0);
|
||||
matrices.translate(-left * 0.1F, 0.45F, 0);
|
||||
|
||||
if (getAttributes().heldStack.getUseAction() == UseAction.BLOCK && getAttributes().itemUseTime == 0) {
|
||||
matrices.translate(left * -0.1F, -0.25F, 0);
|
||||
matrices.translate(left * 0.02F, -0.25F, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -623,6 +623,13 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
stack.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180));
|
||||
}
|
||||
|
||||
boolean crouching = attributes.isCrouching;
|
||||
|
||||
if (attributes.isLyingDown && !attributes.isSleeping) {
|
||||
stack.translate(0, 1.35F, 0);
|
||||
attributes.isCrouching = sneaking;
|
||||
}
|
||||
|
||||
if (attributes.isHorsey) {
|
||||
if (part == BodyPart.BODY) {
|
||||
stack.scale(1.5F, 1, 1.5F);
|
||||
|
@ -634,5 +641,7 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
}
|
||||
|
||||
PonyTransformation.forSize(getSize()).transform(this, part, stack);
|
||||
|
||||
attributes.isCrouching = crouching;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,12 +8,12 @@ import net.minecraft.util.Hand;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.api.events.PonyModelPrepareCallback;
|
||||
import com.minelittlepony.api.model.*;
|
||||
import com.minelittlepony.api.model.fabric.PonyModelPrepareCallback;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.pony.meta.Size;
|
||||
import com.minelittlepony.api.pony.meta.Sizes;
|
||||
import com.minelittlepony.api.pony.meta.SizePreset;
|
||||
import com.minelittlepony.mson.api.model.biped.MsonPlayer;
|
||||
|
||||
/**
|
||||
|
@ -51,7 +51,7 @@ public abstract class ClientPonyModel<T extends LivingEntity> extends MsonPlayer
|
|||
child = entity.isBaby();
|
||||
attributes.updateLivingState(entity, pony, mode);
|
||||
PonyModelPrepareCallback.EVENT.invoker().onPonyModelPrepared(entity, this, mode);
|
||||
sneaking = attributes.isCrouching;
|
||||
sneaking = attributes.isCrouching && !attributes.isLyingDown;
|
||||
riding = attributes.isSitting;
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ public abstract class ClientPonyModel<T extends LivingEntity> extends MsonPlayer
|
|||
|
||||
@Override
|
||||
public Size getSize() {
|
||||
return child ? Sizes.FOAL : PonyModel.super.getSize();
|
||||
return child ? SizePreset.FOAL : PonyModel.super.getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -93,10 +93,16 @@ public abstract class ClientPonyModel<T extends LivingEntity> extends MsonPlayer
|
|||
}
|
||||
|
||||
@Override
|
||||
public ModelPart getArm(Arm side) {
|
||||
return super.getArm(side);
|
||||
public ModelPart getForeLeg(Arm side) {
|
||||
return getArm(side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelPart getHindLeg(Arm side) {
|
||||
return side == Arm.LEFT ? leftLeg : rightLeg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmPose getArmPoseForSide(Arm side) {
|
||||
return side == Arm.RIGHT ? rightArmPose : leftArmPose;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import net.minecraft.util.Identifier;
|
|||
import net.minecraft.util.Util;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.mson.api.*;
|
||||
import com.minelittlepony.mson.api.MsonModel.Factory;
|
||||
import com.minelittlepony.mson.api.model.traversal.PartSkeleton;
|
||||
|
@ -79,7 +79,7 @@ final class ModelKeyImpl<M extends Model> implements ModelKey<M>, LocalBlock {
|
|||
}
|
||||
|
||||
private ModelContext getModelContext(FileContent<?> content) {
|
||||
if (MineLittlePony.getInstance().getConfig().horsieMode.get()) {
|
||||
if (PonyConfig.getInstance().horsieMode.get()) {
|
||||
return content.createContext(null, null, content.getLocals().extendWith(getId(), Optional.of(this), Optional.empty()).bake());
|
||||
}
|
||||
return content.createContext(null, null, content.getLocals().bake());
|
||||
|
|
|
@ -7,6 +7,7 @@ import net.minecraft.util.Identifier;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.api.model.Models;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.client.model.armour.PonyArmourModel;
|
||||
import com.minelittlepony.mson.api.*;
|
||||
|
@ -30,12 +31,12 @@ public record PlayerModelKey<T extends LivingEntity, M extends Model & PonyModel
|
|||
return slimArms ? alexKey : steveKey;
|
||||
}
|
||||
|
||||
public <E extends T, N extends M> ModelWrapper<E, N> create(boolean slimArms) {
|
||||
public <E extends T, N extends M> Models<E, N> create(boolean slimArms) {
|
||||
return create(slimArms, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public <E extends T, N extends M> ModelWrapper<E, N> create(boolean slimArms, @Nullable Consumer<N> initializer) {
|
||||
return new ModelWrapper(this, slimArms, initializer);
|
||||
public <E extends T, N extends M> Models<E, N> create(boolean slimArms, @Nullable Consumer<N> initializer) {
|
||||
return new Models(this, slimArms, initializer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package com.minelittlepony.api.model.armour;
|
||||
package com.minelittlepony.client.model.armour;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.client.model.armour.PonyArmourModel;
|
||||
import com.minelittlepony.mson.api.ModelKey;
|
||||
import com.minelittlepony.mson.api.Mson;
|
||||
|
||||
|
@ -18,7 +17,7 @@ public interface ArmorModelRegistry {
|
|||
if (id.getNamespace().equals("minecraft")) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return REGISTRY.computeIfAbsent(id.withPath(p -> "models/armor/" + layer.name().toLowerCase(Locale.ROOT) + "_" + p + ".json"), i -> {
|
||||
return REGISTRY.computeIfAbsent(id.withPath(p -> "armor/" + layer.name().toLowerCase(Locale.ROOT) + "_" + p + ".json"), i -> {
|
||||
return Optional.of(Mson.getInstance().registerModel(i, PonyArmourModel::new));
|
||||
}).filter(key -> key.getModelData().isPresent());
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.api.model.armour;
|
||||
package com.minelittlepony.client.model.armour;
|
||||
|
||||
/**
|
||||
* The layer used to render a given armour piece.
|
|
@ -13,9 +13,6 @@ import com.google.common.base.Strings;
|
|||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.model.armour.ArmourLayer;
|
||||
import com.minelittlepony.api.model.armour.ArmourVariant;
|
||||
import com.minelittlepony.api.model.armour.IArmourTextureResolver;
|
||||
import com.minelittlepony.util.ResourceUtil;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -38,8 +35,8 @@ import java.util.concurrent.TimeUnit;
|
|||
* - the "minecraft" namespace is always replaced with "minelittlepony"
|
||||
* <p>
|
||||
*/
|
||||
public class DefaultArmourTextureResolver implements IArmourTextureResolver {
|
||||
public static final DefaultArmourTextureResolver INSTANCE = new DefaultArmourTextureResolver();
|
||||
public class ArmourTextureResolver {
|
||||
public static final ArmourTextureResolver INSTANCE = new ArmourTextureResolver();
|
||||
|
||||
private final Cache<String, Identifier> cache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(30, TimeUnit.SECONDS)
|
||||
|
@ -49,7 +46,6 @@ public class DefaultArmourTextureResolver implements IArmourTextureResolver {
|
|||
cache.invalidateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getTexture(LivingEntity entity, ItemStack stack, EquipmentSlot slot, ArmourLayer layer, @Nullable String type) {
|
||||
Identifier material = stack.getItem() instanceof ArmorItem armor
|
||||
? new Identifier(armor.getMaterial().getName())
|
||||
|
@ -129,7 +125,6 @@ public class DefaultArmourTextureResolver implements IArmourTextureResolver {
|
|||
return MinecraftClient.getInstance().getResourceManager().getResource(texture).isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmourVariant getVariant(ArmourLayer layer, Identifier resolvedTexture) {
|
||||
if (resolvedTexture.getPath().endsWith("_pony.png")) {
|
||||
return ArmourVariant.NORMAL;
|
|
@ -1,7 +1,6 @@
|
|||
package com.minelittlepony.api.model.armour;
|
||||
package com.minelittlepony.client.model.armour;
|
||||
|
||||
import com.minelittlepony.client.model.ModelType;
|
||||
import com.minelittlepony.client.model.armour.PonyArmourModel;
|
||||
import com.minelittlepony.mson.api.ModelKey;
|
||||
|
||||
import java.util.Optional;
|
|
@ -6,16 +6,14 @@ import net.minecraft.entity.EquipmentSlot;
|
|||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.armour.*;
|
||||
import com.minelittlepony.client.model.AbstractPonyModel;
|
||||
|
||||
public class PonyArmourModel<T extends LivingEntity> extends AbstractPonyModel<T> implements IArmourModel<T> {
|
||||
public class PonyArmourModel<T extends LivingEntity> extends AbstractPonyModel<T> {
|
||||
|
||||
public PonyArmourModel(ModelPart tree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean poseModel(T entity, float limbAngle, float limbDistance, float age, float headYaw, float headPitch,
|
||||
EquipmentSlot slot, ArmourLayer layer,
|
||||
PonyModel<T> mainModel) {
|
||||
|
|
|
@ -6,10 +6,11 @@ import net.minecraft.client.render.entity.model.EntityModel;
|
|||
import net.minecraft.client.render.entity.model.GuardianEntityModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.mob.GuardianEntity;
|
||||
import com.minelittlepony.client.model.IPonyMixinModel;
|
||||
|
||||
import com.minelittlepony.api.model.PonyModelMixin;
|
||||
import com.minelittlepony.client.model.entity.race.SeaponyModel;
|
||||
|
||||
public class GuardianPonyModel extends GuardianEntityModel implements IPonyMixinModel.Caster<GuardianEntity, SeaponyModel<GuardianEntity>, ModelPart> {
|
||||
public class GuardianPonyModel extends GuardianEntityModel implements PonyModelMixin.Caster<GuardianEntity, SeaponyModel<GuardianEntity>, ModelPart> {
|
||||
private final SeaponyModel<GuardianEntity> mixin;
|
||||
|
||||
public GuardianPonyModel(ModelPart tree) {
|
||||
|
|
|
@ -78,7 +78,7 @@ public class SkeleponyModel<T extends HostileEntity> extends AlicornModel<T> {
|
|||
|
||||
@Override
|
||||
protected float getLegOutset() {
|
||||
if (attributes.isSleeping) return 2.6f;
|
||||
if (attributes.isLyingDown) return 2.6f;
|
||||
if (attributes.isCrouching) return 0;
|
||||
return 4;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.minelittlepony.client.model.entity.race;
|
||||
|
||||
import com.minelittlepony.api.model.IPart;
|
||||
import com.minelittlepony.api.model.SubModel;
|
||||
import com.minelittlepony.api.model.WingedPonyModel;
|
||||
import com.minelittlepony.client.model.part.PonyWings;
|
||||
import com.minelittlepony.mson.api.ModelView;
|
||||
|
@ -24,7 +24,7 @@ public class AlicornModel<T extends LivingEntity> extends UnicornModel<T> implem
|
|||
}
|
||||
|
||||
@Override
|
||||
public IPart getWings() {
|
||||
public SubModel getWings() {
|
||||
return wings;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.minelittlepony.client.model.entity.race;
|
||||
|
||||
import com.minelittlepony.api.model.IPart;
|
||||
import com.minelittlepony.api.model.SubModel;
|
||||
import com.minelittlepony.client.model.AbstractPonyModel;
|
||||
import com.minelittlepony.client.model.part.*;
|
||||
import com.minelittlepony.mson.api.ModelView;
|
||||
|
@ -12,7 +12,7 @@ public class EarthPonyModel<T extends LivingEntity> extends AbstractPonyModel<T>
|
|||
|
||||
private final boolean smallArms;
|
||||
|
||||
protected IPart tail;
|
||||
protected SubModel tail;
|
||||
protected PonySnout snout;
|
||||
protected PonyEars ears;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.minelittlepony.client.model.entity.race;
|
||||
|
||||
import com.minelittlepony.api.model.IPart;
|
||||
import com.minelittlepony.api.model.SubModel;
|
||||
import com.minelittlepony.api.model.WingedPonyModel;
|
||||
import com.minelittlepony.client.model.part.PonyWings;
|
||||
import com.minelittlepony.mson.api.ModelView;
|
||||
|
@ -24,7 +24,7 @@ public class PegasusModel<T extends LivingEntity> extends EarthPonyModel<T> impl
|
|||
}
|
||||
|
||||
@Override
|
||||
public IPart getWings() {
|
||||
public SubModel getWings() {
|
||||
return wings;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.minelittlepony.client.model.entity.race;
|
||||
|
||||
import com.minelittlepony.client.model.armour.PonyArmourModel;
|
||||
import com.minelittlepony.mson.api.ModelView;
|
||||
import com.minelittlepony.api.model.*;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.client.model.armour.PonyArmourModel;
|
||||
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
@ -65,7 +65,7 @@ public class SeaponyModel<T extends LivingEntity> extends UnicornModel<T> {
|
|||
|
||||
float flapMotion = MathHelper.cos(ticks / 10) / 5;
|
||||
|
||||
if (attributes.isSleeping) {
|
||||
if (attributes.isLyingDown) {
|
||||
flapMotion /= 2;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.minelittlepony.client.model.entity.race;
|
||||
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.model.*;
|
||||
import com.minelittlepony.api.pony.meta.Size;
|
||||
import com.minelittlepony.api.pony.meta.Sizes;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.api.pony.meta.SizePreset;
|
||||
import com.minelittlepony.client.model.part.UnicornHorn;
|
||||
import com.minelittlepony.client.util.render.RenderList;
|
||||
import com.minelittlepony.mson.api.ModelView;
|
||||
|
@ -57,7 +57,7 @@ public class UnicornModel<T extends LivingEntity> extends EarthPonyModel<T> impl
|
|||
|
||||
@Override
|
||||
public boolean isCasting() {
|
||||
return MineLittlePony.getInstance().getConfig().tpsmagic.get()
|
||||
return PonyConfig.getInstance().tpsmagic.get()
|
||||
&& (rightArmPose != ArmPose.EMPTY || leftArmPose != ArmPose.EMPTY);
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ public class UnicornModel<T extends LivingEntity> extends EarthPonyModel<T> impl
|
|||
|
||||
@Override
|
||||
public ModelPart getArm(Arm side) {
|
||||
if (hasMagic() && getArmPoseForSide(side) != ArmPose.EMPTY && MineLittlePony.getInstance().getConfig().tpsmagic.get()) {
|
||||
if (hasMagic() && getArmPoseForSide(side) != ArmPose.EMPTY && PonyConfig.getInstance().tpsmagic.get()) {
|
||||
return side == Arm.LEFT ? unicornArmLeft : unicornArmRight;
|
||||
}
|
||||
return super.getArm(side);
|
||||
|
@ -80,7 +80,7 @@ public class UnicornModel<T extends LivingEntity> extends EarthPonyModel<T> impl
|
|||
protected void positionheldItem(Arm arm, MatrixStack matrices) {
|
||||
super.positionheldItem(arm, matrices);
|
||||
|
||||
if (!MineLittlePony.getInstance().getConfig().tpsmagic.get() || !hasMagic()) {
|
||||
if (!PonyConfig.getInstance().tpsmagic.get() || !hasMagic()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -101,9 +101,9 @@ public class UnicornModel<T extends LivingEntity> extends EarthPonyModel<T> impl
|
|||
float x = 0.3F;
|
||||
float z = -0.4F;
|
||||
|
||||
if (size == Sizes.TALL || size == Sizes.YEARLING) {
|
||||
if (size == SizePreset.TALL || size == SizePreset.YEARLING) {
|
||||
z += 0.05F;
|
||||
} else if (size == Sizes.FOAL) {
|
||||
} else if (size == SizePreset.FOAL) {
|
||||
x -= 0.1F;
|
||||
z -= 0.1F;
|
||||
}
|
||||
|
|
|
@ -23,10 +23,9 @@ public class DeerAntlers extends WearableGear {
|
|||
dayChecked = true;
|
||||
Calendar cal = Calendar.getInstance();
|
||||
dayResult = cal.get(Calendar.MONTH) == Calendar.DECEMBER
|
||||
&& cal.get(Calendar.DAY_OF_MONTH) == 25;
|
||||
&& Math.abs(cal.get(Calendar.DAY_OF_MONTH) - 25) < 2;
|
||||
}
|
||||
|
||||
|
||||
return dayResult;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,13 +13,9 @@ import net.minecraft.client.model.ModelPart;
|
|||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class SaddleBags extends WearableGear {
|
||||
|
||||
public static final Identifier TEXTURE = new Identifier("minelittlepony", "textures/models/saddlebags.png");
|
||||
|
||||
private final ModelPart leftBag;
|
||||
private final ModelPart rightBag;
|
||||
|
||||
|
@ -63,7 +59,7 @@ public class SaddleBags extends WearableGear {
|
|||
strap.visible = wearable == Wearable.SADDLE_BAGS_BOTH;
|
||||
|
||||
dropAmount = hangLow ? 0.15F : 0;
|
||||
dropAmount = model.getAttributes().metadata.getInterpolator(interpolatorId).interpolate("dropAmount", dropAmount, 3);
|
||||
dropAmount = model.getAttributes().getMainInterpolator().interpolate("dropAmount", dropAmount, 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -5,11 +5,11 @@ import net.minecraft.client.render.VertexConsumer;
|
|||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import com.minelittlepony.api.model.IPart;
|
||||
import com.minelittlepony.api.model.SubModel;
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.common.util.animation.Interpolator;
|
||||
|
||||
public class LionTail implements IPart {
|
||||
public class LionTail implements SubModel {
|
||||
|
||||
private ModelPart tail;
|
||||
|
||||
|
|
|
@ -5,12 +5,13 @@ import net.minecraft.client.render.VertexConsumer;
|
|||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import com.minelittlepony.api.model.IPart;
|
||||
import com.minelittlepony.api.model.SubModel;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.mson.api.*;
|
||||
import com.minelittlepony.mson.api.model.PartBuilder;
|
||||
|
||||
public class PonyEars implements IPart, MsonModel {
|
||||
public class PonyEars implements SubModel, MsonModel {
|
||||
private final ModelPart right;
|
||||
private final ModelPart left;
|
||||
|
||||
|
@ -29,6 +30,12 @@ public class PonyEars implements IPart, MsonModel {
|
|||
@Override
|
||||
public void setPartAngles(ModelAttributes attributes, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) {
|
||||
right.resetTransform();
|
||||
left.resetTransform();
|
||||
|
||||
if (attributes.metadata.race() == Race.CHANGEDLING
|
||||
|| attributes.metadata.race() == Race.CHANGELING) {
|
||||
return;
|
||||
}
|
||||
|
||||
limbSpeed = MathHelper.clamp(limbSpeed, 0, 1);
|
||||
|
||||
|
|
|
@ -4,14 +4,14 @@ import net.minecraft.client.model.ModelPart;
|
|||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import com.minelittlepony.api.model.IPart;
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.model.SubModel;
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.api.pony.meta.Gender;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.mson.api.*;
|
||||
import com.minelittlepony.mson.api.model.PartBuilder;
|
||||
|
||||
public class PonySnout implements IPart, MsonModel {
|
||||
public class PonySnout implements SubModel, MsonModel {
|
||||
|
||||
private final ModelPart mare;
|
||||
private final ModelPart stallion;
|
||||
|
@ -41,7 +41,7 @@ public class PonySnout implements IPart, MsonModel {
|
|||
public void setVisible(boolean visible, ModelAttributes attributes) {
|
||||
visible &= !attributes.isHorsey
|
||||
&& !attributes.metadata.race().isHuman()
|
||||
&& MineLittlePony.getInstance().getConfig().snuzzles.get();
|
||||
&& PonyConfig.getInstance().snuzzles.get();
|
||||
Gender gender = attributes.metadata.gender();
|
||||
|
||||
mare.visible = (visible && gender.isMare());
|
||||
|
|
|
@ -14,7 +14,7 @@ import com.minelittlepony.util.MathUtil;
|
|||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class PonyTail implements IPart, MsonModel {
|
||||
public class PonyTail implements SubModel, MsonModel {
|
||||
private static final float TAIL_Z = 14;
|
||||
private static final float TAIL_RIDING_Y = 3;
|
||||
private static final float TAIL_RIDING_Z = 13;
|
||||
|
|
|
@ -12,7 +12,7 @@ import com.minelittlepony.mson.api.ModelView;
|
|||
import com.minelittlepony.mson.api.MsonModel;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
||||
public class PonyWings<T extends Model & WingedPonyModel<?>> implements IPart, MsonModel {
|
||||
public class PonyWings<T extends Model & WingedPonyModel<?>> implements SubModel, MsonModel {
|
||||
|
||||
protected T pegasus;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.minelittlepony.client.model.part;
|
||||
|
||||
import com.minelittlepony.api.model.IPart;
|
||||
import com.minelittlepony.api.model.SubModel;
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.mson.api.MsonModel;
|
||||
|
||||
|
@ -9,7 +9,7 @@ import net.minecraft.client.render.VertexConsumer;
|
|||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class SeaponyTail implements IPart, MsonModel {
|
||||
public class SeaponyTail implements SubModel, MsonModel {
|
||||
private final ModelPart tailBase;
|
||||
|
||||
private final ModelPart tailTip;
|
||||
|
@ -23,7 +23,7 @@ public class SeaponyTail implements IPart, MsonModel {
|
|||
|
||||
@Override
|
||||
public void setPartAngles(ModelAttributes attributes, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) {
|
||||
float rotation = attributes.isSleeping ? 0 : MathHelper.sin(animationProgress * 0.536f) / 4;
|
||||
float rotation = attributes.isLyingDown ? 0 : MathHelper.sin(animationProgress * 0.536f) / 4;
|
||||
|
||||
tailBase.pitch = MathHelper.HALF_PI + rotation;
|
||||
tailTip.pitch = rotation;
|
||||
|
|
|
@ -7,12 +7,12 @@ import net.minecraft.client.render.VertexConsumer;
|
|||
import net.minecraft.client.render.VertexConsumerProvider.Immediate;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import com.minelittlepony.api.model.IPart;
|
||||
import com.minelittlepony.api.model.SubModel;
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.client.render.MagicGlow;
|
||||
import com.minelittlepony.common.util.Color;
|
||||
|
||||
public class UnicornHorn implements IPart {
|
||||
public class UnicornHorn implements SubModel {
|
||||
|
||||
private final ModelPart horn;
|
||||
private final ModelPart glow;
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package com.minelittlepony.client.render;
|
||||
|
||||
import net.minecraft.client.render.*;
|
||||
import net.minecraft.client.render.RenderLayer.MultiPhaseParameters;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class ArmorRenderLayers extends RenderPhase {
|
||||
private ArmorRenderLayers() {
|
||||
super(null, null, null);
|
||||
}
|
||||
|
||||
private static final BiFunction<Identifier, Boolean, RenderLayer> ARMOR_TRANSLUCENT_NO_CULL = Util.memoize((texture, decal) -> {
|
||||
return RenderLayer.of(decal ? "armor_decal_translucent_no_cull" : "armor_translucent_no_cull",
|
||||
VertexFormats.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL, VertexFormat.DrawMode.QUADS, 256, true, false, MultiPhaseParameters.builder()
|
||||
.program(ARMOR_CUTOUT_NO_CULL_PROGRAM)
|
||||
.texture(new RenderPhase.Texture(texture, false, false))
|
||||
.transparency(TRANSLUCENT_TRANSPARENCY)
|
||||
.cull(DISABLE_CULLING)
|
||||
.lightmap(ENABLE_LIGHTMAP)
|
||||
.overlay(ENABLE_OVERLAY_COLOR)
|
||||
.layering(VIEW_OFFSET_Z_LAYERING)
|
||||
.depthTest(decal ? EQUAL_DEPTH_TEST : LEQUAL_DEPTH_TEST)
|
||||
.build(true)
|
||||
);
|
||||
});
|
||||
|
||||
public static RenderLayer getArmorTranslucentNoCull(Identifier texture, boolean decal) {
|
||||
return ARMOR_TRANSLUCENT_NO_CULL.apply(texture, decal);
|
||||
}
|
||||
}
|
|
@ -17,7 +17,6 @@ import com.minelittlepony.api.pony.Pony;
|
|||
import com.minelittlepony.client.PonyBounds;
|
||||
|
||||
public final class DebugBoundingBoxRenderer {
|
||||
|
||||
public static <T extends LivingEntity> void render(Pony pony, EntityRenderer<T> renderer, T entity, MatrixStack stack, VertexConsumerProvider renderContext, float tickDelta) {
|
||||
|
||||
if (RenderPass.getCurrent() != RenderPass.WORLD) {
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
package com.minelittlepony.client.render;
|
||||
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.events.Channel;
|
||||
import com.minelittlepony.api.events.PonyDataCallback;
|
||||
import com.minelittlepony.api.model.*;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.network.fabric.Channel;
|
||||
import com.minelittlepony.api.pony.network.fabric.PonyDataCallback;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.client.model.ModelWrapper;
|
||||
import com.minelittlepony.client.transform.PonyPosture;
|
||||
import com.minelittlepony.mson.api.ModelKey;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
@ -22,42 +23,42 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> {
|
||||
|
||||
private ModelWrapper<T, M> playerModel;
|
||||
private Models<T, M> models;
|
||||
@Nullable
|
||||
private Function<T, Models<T, M>> modelsLookup;
|
||||
|
||||
private final IPonyRenderContext<T, M> renderer;
|
||||
private final PonyRenderContext<T, M> context;
|
||||
private final Transformer<T> transformer;
|
||||
|
||||
private final FrustrumCheck<T> frustrum = new FrustrumCheck<>(this);
|
||||
private final FrustrumCheck<T> frustrum;
|
||||
|
||||
public static void disableModelRenderProfile() {
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
public EquineRenderManager(IPonyRenderContext<T, M> renderer) {
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
public IPonyRenderContext<T, M> getContext() {
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public ModelWrapper<T, M> getModelWrapper() {
|
||||
return playerModel;
|
||||
}
|
||||
|
||||
public M getModel() {
|
||||
return playerModel.body();
|
||||
public EquineRenderManager(PonyRenderContext<T, M> context, Transformer<T> transformer, Models<T, M> models) {
|
||||
this.context = context;
|
||||
this.transformer = transformer;
|
||||
this.models = models;
|
||||
frustrum = new FrustrumCheck<>(context);
|
||||
context.setModel(models.body());
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public ModelWrapper<T, M> setModel(ModelKey<? super M> key) {
|
||||
return setModel(new ModelWrapper(key));
|
||||
public EquineRenderManager(PonyRenderContext<T, M> context, Transformer<T> transformer, ModelKey<? super M> key) {
|
||||
this(context, transformer, new Models(key));
|
||||
}
|
||||
|
||||
public ModelWrapper<T, M> setModel(ModelWrapper<T, M> wrapper) {
|
||||
playerModel = wrapper;
|
||||
return wrapper;
|
||||
public void setModelsLookup(@Nullable Function<T, Models<T, M>> modelsLookup) {
|
||||
this.modelsLookup = modelsLookup;
|
||||
}
|
||||
|
||||
public Models<T, M> getModels() {
|
||||
return models;
|
||||
}
|
||||
|
||||
public Frustum getFrustrum(T entity, Frustum vanilla) {
|
||||
|
@ -65,13 +66,67 @@ public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T
|
|||
return FrustrumCheck.ALWAYS_VISIBLE;
|
||||
}
|
||||
|
||||
if (entity.isSleeping() || !MineLittlePony.getInstance().getConfig().frustrum.get()) {
|
||||
if (entity.isSleeping() || !PonyConfig.getInstance().frustrum.get()) {
|
||||
return vanilla;
|
||||
}
|
||||
return frustrum.withCamera(entity, vanilla);
|
||||
}
|
||||
|
||||
public float getRenderYaw(T entity, float rotationYaw, float partialTicks) {
|
||||
public void preRender(T entity, ModelAttributes.Mode mode) {
|
||||
Pony pony = context.getEntityPony(entity);
|
||||
if (modelsLookup != null) {
|
||||
models = modelsLookup.apply(entity);
|
||||
context.setModel(models.body());
|
||||
}
|
||||
models.applyMetadata(pony.metadata());
|
||||
models.body().updateLivingState(entity, pony, mode);
|
||||
|
||||
if (entity instanceof PlayerEntity player && entity instanceof RegistrationHandler handler) {
|
||||
handler.getSyncedPony().synchronize(player, pony);
|
||||
}
|
||||
}
|
||||
|
||||
public void setupTransforms(T entity, MatrixStack stack, float ageInTicks, float rotationYaw, float tickDelta) {
|
||||
float s = getScaleFactor();
|
||||
stack.scale(s, s, s);
|
||||
|
||||
if (entity.hasVehicle() && entity.getVehicle() instanceof LivingEntity livingVehicles) {
|
||||
PonyRenderContext<LivingEntity, ?> renderer = MineLittlePony.getInstance().getRenderDispatcher().getPonyRenderer(livingVehicles);
|
||||
|
||||
if (renderer != null) {
|
||||
// negate vanilla translations so the rider begins at the ridees feet.
|
||||
stack.translate(0, -livingVehicles.getHeight(), 0);
|
||||
Pony pony = context.getEntityPony(entity);
|
||||
if (!pony.race().isHuman()) {
|
||||
renderer.getInternalRenderer().translateRider(livingVehicles, renderer.getEntityPony(livingVehicles), entity, pony, stack, tickDelta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity instanceof PlayerEntity) {
|
||||
if (getModels().body().getAttributes().isSitting) {
|
||||
stack.translate(0, 0.125D, 0);
|
||||
}
|
||||
}
|
||||
|
||||
rotationYaw = getMountedYaw(entity, rotationYaw, tickDelta);
|
||||
transformer.setupTransforms(entity, stack, ageInTicks, rotationYaw, tickDelta);
|
||||
|
||||
PonyPosture.of(getModels().body().getAttributes()).apply(entity, getModels().body(), stack, rotationYaw, tickDelta, 1);
|
||||
}
|
||||
|
||||
private void translateRider(T entity, Pony pony, LivingEntity passenger, Pony passengerPony, MatrixStack stack, float tickDelta) {
|
||||
if (!passengerPony.race().isHuman()) {
|
||||
float yaw = MathUtil.interpolateDegress((float)entity.prevY, (float)entity.getY(), tickDelta);
|
||||
|
||||
models.applyMetadata(pony.metadata());
|
||||
models.body().transform(BodyPart.BACK, stack);
|
||||
|
||||
PonyPosture.of(models.body().getAttributes()).apply(entity, getModels().body(), stack, yaw, tickDelta, -1);
|
||||
}
|
||||
}
|
||||
|
||||
private float getMountedYaw(T entity, float rotationYaw, float partialTicks) {
|
||||
if (entity.hasVehicle()) {
|
||||
Entity mount = entity.getVehicle();
|
||||
if (mount instanceof LivingEntity) {
|
||||
|
@ -82,72 +137,20 @@ public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T
|
|||
return rotationYaw;
|
||||
}
|
||||
|
||||
public void preRenderCallback(T entity, MatrixStack stack, float ticks) {
|
||||
updateModel(entity, ModelAttributes.Mode.THIRD_PERSON);
|
||||
|
||||
float s = getScaleFactor();
|
||||
stack.scale(s, s, s);
|
||||
|
||||
translateRider(entity, stack, ticks);
|
||||
}
|
||||
|
||||
private void translateRider(T entity, MatrixStack stack, float ticks) {
|
||||
if (entity.hasVehicle() && entity.getVehicle() instanceof LivingEntity) {
|
||||
|
||||
LivingEntity ridingEntity = (LivingEntity) entity.getVehicle();
|
||||
IPonyRenderContext<LivingEntity, ?> renderer = MineLittlePony.getInstance().getRenderDispatcher().getPonyRenderer(ridingEntity);
|
||||
|
||||
if (renderer != null) {
|
||||
// negate vanilla translations so the rider begins at the ridees feet.
|
||||
stack.translate(0, -ridingEntity.getHeight(), 0);
|
||||
|
||||
Pony riderPony = renderer.getEntityPony(ridingEntity);
|
||||
|
||||
renderer.translateRider(ridingEntity, riderPony, entity, renderer.getEntityPony(entity), stack, ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setupTransforms(T entity, MatrixStack stack, float yaw, float tickDelta) {
|
||||
PonyPosture.of(getModel().getAttributes()).apply(entity, getModel(), stack, yaw, tickDelta, 1);
|
||||
}
|
||||
|
||||
public void applyPostureRiding(T entity, MatrixStack stack, float yaw, float tickDelta) {
|
||||
PonyPosture.of(getModel().getAttributes()).apply(entity, getModel(), stack, yaw, tickDelta, -1);
|
||||
}
|
||||
|
||||
public Pony updateModel(T entity, ModelAttributes.Mode mode) {
|
||||
Pony pony = renderer.getEntityPony(entity);
|
||||
playerModel.applyMetadata(pony.metadata());
|
||||
|
||||
if (pony.hasMetadata() && entity instanceof RegistrationHandler && ((RegistrationHandler)entity).shouldUpdateRegistration(pony)) {
|
||||
entity.calculateDimensions();
|
||||
|
||||
PlayerEntity clientPlayer = MinecraftClient.getInstance().player;
|
||||
if (clientPlayer != null) {
|
||||
if (Objects.equals(entity, clientPlayer) || Objects.equals(((PlayerEntity)entity).getGameProfile(), clientPlayer.getGameProfile())) {
|
||||
Channel.broadcastPonyData(pony.metadata());
|
||||
}
|
||||
}
|
||||
PonyDataCallback.EVENT.invoker().onPonyDataAvailable((PlayerEntity)entity, pony.metadata(), EnvType.CLIENT);
|
||||
}
|
||||
|
||||
getModel().updateLivingState(entity, pony, mode);
|
||||
|
||||
return pony;
|
||||
}
|
||||
|
||||
public float getScaleFactor() {
|
||||
return getModel().getSize().scaleFactor();
|
||||
return getModels().body().getSize().scaleFactor();
|
||||
}
|
||||
|
||||
public float getShadowSize() {
|
||||
return getModels().body().getSize().shadowSize();
|
||||
}
|
||||
|
||||
public double getNamePlateYOffset(T entity) {
|
||||
|
||||
// We start by negating the height calculation done by mahjong.
|
||||
float y = -(entity.getHeight() + 0.5F);
|
||||
|
||||
// Then we add our own offsets.
|
||||
y += getModel().getAttributes().visualHeight * getScaleFactor() + 0.25F;
|
||||
y += getModels().body().getAttributes().visualHeight * getScaleFactor() + 0.25F;
|
||||
|
||||
if (entity.isSneaking()) {
|
||||
y -= 0.25F;
|
||||
|
@ -164,7 +167,48 @@ public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T
|
|||
return y;
|
||||
}
|
||||
|
||||
public interface Transformer<T extends LivingEntity> {
|
||||
void setupTransforms(T entity, MatrixStack stack, float ageInTicks, float rotationYaw, float partialTicks);
|
||||
}
|
||||
|
||||
public interface RegistrationHandler {
|
||||
boolean shouldUpdateRegistration(Pony pony);
|
||||
SyncedPony getSyncedPony();
|
||||
}
|
||||
|
||||
public interface ModelHolder<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> {
|
||||
void setModel(M model);
|
||||
}
|
||||
|
||||
public static class SyncedPony {
|
||||
@Nullable
|
||||
private Pony lastRenderedPony;
|
||||
@Nullable
|
||||
private Pony lastTransmittedPony;
|
||||
|
||||
public void synchronize(PlayerEntity player, Pony pony) {
|
||||
boolean changed = pony.compareTo(lastRenderedPony) != 0;
|
||||
|
||||
if (changed) {
|
||||
lastRenderedPony = pony;
|
||||
player.calculateDimensions();
|
||||
}
|
||||
|
||||
if (!(player instanceof PreviewModel)) {
|
||||
@Nullable
|
||||
PlayerEntity clientPlayer = MinecraftClient.getInstance().player;
|
||||
|
||||
if (Channel.isRegistered() && pony.compareTo(lastTransmittedPony) != 0) {
|
||||
if (clientPlayer != null && (Objects.equals(player, clientPlayer) || Objects.equals(player.getGameProfile(), clientPlayer.getGameProfile()))) {
|
||||
if (Channel.broadcastPonyData(pony.metadata())) {
|
||||
lastTransmittedPony = pony;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
PonyDataCallback.EVENT.invoker().onPonyDataAvailable(player, pony.metadata(), EnvType.CLIENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,11 @@ public class FrustrumCheck<T extends LivingEntity> extends Frustum {
|
|||
|
||||
private Frustum vanilla;
|
||||
|
||||
private final EquineRenderManager<T, ?> renderer;
|
||||
private final PonyRenderContext<T, ?> context;
|
||||
|
||||
public FrustrumCheck(EquineRenderManager<T, ?> render) {
|
||||
public FrustrumCheck(PonyRenderContext<T, ?> context) {
|
||||
super(new Matrix4f(), new Matrix4f());
|
||||
renderer = render;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public Frustum withCamera(T entity, Frustum vanillaFrustrum) {
|
||||
|
@ -34,7 +34,7 @@ public class FrustrumCheck<T extends LivingEntity> extends Frustum {
|
|||
|
||||
@Override
|
||||
public boolean isVisible(Box bounds) {
|
||||
return vanilla.isVisible(PonyBounds.getBoundingBox(renderer.getContext().getEntityPony(entity), entity));
|
||||
return vanilla.isVisible(PonyBounds.getBoundingBox(context.getEntityPony(entity), entity));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
package com.minelittlepony.client.render;
|
||||
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.gear.Gear;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
||||
import net.minecraft.client.render.entity.model.EntityModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
public interface IPonyRenderContext<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> extends Gear.Context<T, M> {
|
||||
|
||||
Pony getEntityPony(T entity);
|
||||
|
||||
EquineRenderManager<T, M> getInternalRenderer();
|
||||
|
||||
/**
|
||||
* Called by riders to have their transportation adjust their position.
|
||||
*/
|
||||
default void translateRider(T entity, Pony entityPony, LivingEntity passenger, Pony passengerPony, MatrixStack stack, float ticks) {
|
||||
if (!passengerPony.race().isHuman()) {
|
||||
float yaw = MathUtil.interpolateDegress((float)entity.prevY, (float)entity.getY(), ticks);
|
||||
|
||||
getInternalRenderer().getModelWrapper().applyMetadata(entityPony.metadata());
|
||||
M model = getInternalRenderer().getModelWrapper().body();
|
||||
|
||||
model.transform(BodyPart.BACK, stack);
|
||||
|
||||
getInternalRenderer().applyPostureRiding(entity, stack, yaw, ticks);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package com.minelittlepony.client.render;
|
||||
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.client.util.render.RenderLayerUtil;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -11,11 +11,9 @@ import net.minecraft.client.render.item.ItemRenderer;
|
|||
import net.minecraft.client.render.model.json.ModelTransformationMode;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.CrossbowItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.PlayerScreenHandler;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.UseAction;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
import net.minecraft.world.World;
|
||||
|
@ -24,11 +22,10 @@ public class LevitatingItemRenderer {
|
|||
private VertexConsumerProvider getProvider(Pony pony, VertexConsumerProvider renderContext) {
|
||||
final int color = pony.metadata().glowColor();
|
||||
return layer -> {
|
||||
Identifier texture = RenderLayerUtil.getTexture(layer).orElse(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE);
|
||||
if (texture == ItemRenderer.ENTITY_ENCHANTMENT_GLINT || texture == ItemRenderer.ITEM_ENCHANTMENT_GLINT) {
|
||||
if (layer.getVertexFormat() != VertexFormats.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL) {
|
||||
return renderContext.getBuffer(layer);
|
||||
}
|
||||
return renderContext.getBuffer(MagicGlow.getColoured(texture, color));
|
||||
return renderContext.getBuffer(MagicGlow.getColoured(RenderLayerUtil.getTexture(layer).orElse(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE), color));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -37,32 +34,36 @@ public class LevitatingItemRenderer {
|
|||
*/
|
||||
public void renderItem(ItemRenderer itemRenderer, @Nullable LivingEntity entity, ItemStack stack, ModelTransformationMode mode, boolean left, MatrixStack matrix, VertexConsumerProvider renderContext, @Nullable World world, int lightUv, int posLong) {
|
||||
|
||||
if (entity instanceof PlayerEntity && (mode.isFirstPerson() || mode == ModelTransformationMode.THIRD_PERSON_LEFT_HAND || mode == ModelTransformationMode.THIRD_PERSON_RIGHT_HAND)) {
|
||||
if (mode.isFirstPerson()
|
||||
|| mode == ModelTransformationMode.THIRD_PERSON_LEFT_HAND
|
||||
|| mode == ModelTransformationMode.THIRD_PERSON_RIGHT_HAND
|
||||
) {
|
||||
Pony.getManager().getPony(entity).ifPresentOrElse(pony -> {
|
||||
matrix.push();
|
||||
|
||||
Pony pony = Pony.getManager().getPony((PlayerEntity)entity);
|
||||
boolean doMagic = PonyConfig.getInstance().fpsmagic.get() && pony.hasMagic();
|
||||
|
||||
matrix.push();
|
||||
if (doMagic && mode.isFirstPerson()) {
|
||||
setupPerspective(itemRenderer, entity, stack, left, matrix);
|
||||
}
|
||||
|
||||
boolean doMagic = MineLittlePony.getInstance().getConfig().fpsmagic.get() && pony.hasMagic();
|
||||
itemRenderer.renderItem(entity, stack, mode, left, matrix, renderContext, world, lightUv, OverlayTexture.DEFAULT_UV, posLong);
|
||||
|
||||
if (doMagic && mode.isFirstPerson()) {
|
||||
setupPerspective(itemRenderer, entity, stack, left, matrix);
|
||||
}
|
||||
if (doMagic) {
|
||||
VertexConsumerProvider interceptedContext = getProvider(pony, renderContext);
|
||||
|
||||
itemRenderer.renderItem(entity, stack, mode, left, matrix, renderContext, world, lightUv, OverlayTexture.DEFAULT_UV, posLong);
|
||||
matrix.scale(1.1F, 1.1F, 1.1F);
|
||||
matrix.translate(0.015F, 0.01F, 0.01F);
|
||||
|
||||
if (doMagic) {
|
||||
VertexConsumerProvider interceptedContext = getProvider(pony, renderContext);
|
||||
itemRenderer.renderItem(entity, stack, mode, left, matrix, interceptedContext, world, lightUv, OverlayTexture.DEFAULT_UV, posLong);
|
||||
matrix.translate(-0.03F, -0.02F, -0.02F);
|
||||
itemRenderer.renderItem(entity, stack, mode, left, matrix, interceptedContext, world, lightUv, OverlayTexture.DEFAULT_UV, posLong);
|
||||
}
|
||||
|
||||
matrix.scale(1.1F, 1.1F, 1.1F);
|
||||
matrix.translate(0.015F, 0.01F, 0.01F);
|
||||
|
||||
itemRenderer.renderItem(entity, stack, mode, left, matrix, interceptedContext, world, lightUv, OverlayTexture.DEFAULT_UV, posLong);
|
||||
matrix.translate(-0.03F, -0.02F, -0.02F);
|
||||
itemRenderer.renderItem(entity, stack, mode, left, matrix, interceptedContext, world, lightUv, OverlayTexture.DEFAULT_UV, posLong);
|
||||
}
|
||||
|
||||
matrix.pop();
|
||||
matrix.pop();
|
||||
}, () -> {
|
||||
itemRenderer.renderItem(entity, stack, mode, left, matrix, renderContext, world, lightUv, OverlayTexture.DEFAULT_UV, posLong);
|
||||
});
|
||||
} else {
|
||||
itemRenderer.renderItem(entity, stack, mode, left, matrix, renderContext, world, lightUv, OverlayTexture.DEFAULT_UV, posLong);
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@ import java.util.function.BiFunction;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
public abstract class MagicGlow extends RenderPhase {
|
||||
private MagicGlow(String name, Runnable beginAction, Runnable endAction) {
|
||||
super(name, beginAction, endAction);
|
||||
private MagicGlow() {
|
||||
super(null, null, null);
|
||||
}
|
||||
|
||||
private static final Supplier<RenderLayer> MAGIC = Suppliers.memoize(() -> {
|
||||
|
@ -54,7 +54,6 @@ public abstract class MagicGlow extends RenderPhase {
|
|||
}
|
||||
|
||||
private static class Colored extends Texture {
|
||||
|
||||
private final float red;
|
||||
private final float green;
|
||||
private final float blue;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.minelittlepony.client.render;
|
||||
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.client.render.entity.*;
|
||||
import com.minelittlepony.client.render.entity.npc.*;
|
||||
|
@ -40,7 +41,7 @@ public final class MobRenderers {
|
|||
pony.switchRenderer(state, EntityType.PIGLIN, PonyPiglinRenderer::piglin);
|
||||
pony.switchRenderer(state, EntityType.PIGLIN_BRUTE, PonyPiglinRenderer::brute);
|
||||
pony.switchRenderer(state, EntityType.ZOMBIFIED_PIGLIN, PonyPiglinRenderer::zombified);
|
||||
if (!MineLittlePony.getInstance().getConfig().noFun.get()) {
|
||||
if (!PonyConfig.getInstance().noFun.get()) {
|
||||
pony.switchRenderer(state, EntityType.PIG, PonyPigRenderer::new);
|
||||
}
|
||||
});
|
||||
|
@ -78,7 +79,7 @@ public final class MobRenderers {
|
|||
}
|
||||
|
||||
public Setting<Boolean> option() {
|
||||
return MineLittlePony.getInstance().getConfig().getCategory("entities").<Boolean>get(name);
|
||||
return PonyConfig.getInstance().getCategory("entities").<Boolean>get(name);
|
||||
}
|
||||
|
||||
public boolean set(boolean value) {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package com.minelittlepony.client.render;
|
||||
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.gear.Gear;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
|
||||
import net.minecraft.client.render.entity.model.EntityModel;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
public interface PonyRenderContext<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> extends Gear.Context<T, M> {
|
||||
|
||||
Pony getEntityPony(T entity);
|
||||
|
||||
EquineRenderManager<T, M> getInternalRenderer();
|
||||
|
||||
void setModel(M model);
|
||||
}
|
|
@ -3,11 +3,9 @@ package com.minelittlepony.client.render;
|
|||
import java.util.function.Function;
|
||||
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.PonyPosture;
|
||||
import com.minelittlepony.api.pony.*;
|
||||
import com.minelittlepony.client.mixin.MixinEntityRenderers;
|
||||
import com.minelittlepony.client.render.entity.PlayerPonyRenderer;
|
||||
import com.minelittlepony.client.render.entity.AquaticPlayerPonyRenderer;
|
||||
import com.minelittlepony.client.render.entity.*;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
@ -48,16 +46,25 @@ public class PonyRenderDispatcher {
|
|||
player -> {
|
||||
return !Pony.getManager().getPony(player).race().isHuman()
|
||||
&& PonyPosture.hasSeaponyForm(player)
|
||||
&& player.method_52814().model() == armShape;
|
||||
&& player.getSkinTextures().model() == armShape;
|
||||
},
|
||||
context -> new AquaticPlayerPonyRenderer(context, armShape == SkinTextures.Model.SLIM)
|
||||
);
|
||||
Mson.getInstance().getEntityRendererRegistry().registerPlayerRenderer(
|
||||
new Identifier("minelittlepony", "nirik/" + armShape.getName()),
|
||||
player -> {
|
||||
return !Pony.getManager().getPony(player).race().isHuman()
|
||||
&& PonyPosture.hasNirikForm(player)
|
||||
&& player.getSkinTextures().model() == armShape;
|
||||
},
|
||||
context -> new FormChangingPlayerPonyRenderer(context, armShape == SkinTextures.Model.SLIM, DefaultPonySkinHelper.NIRIK_SKIN_TYPE_ID, PonyPosture::isNirikModifier)
|
||||
);
|
||||
Mson.getInstance().getEntityRendererRegistry().registerPlayerRenderer(
|
||||
new Identifier("minelittlepony", "land/" + armShape.getName()),
|
||||
player -> {
|
||||
return !Pony.getManager().getPony(player).race().isHuman()
|
||||
&& !PonyPosture.hasSeaponyForm(player)
|
||||
&& player.method_52814().model() == armShape;
|
||||
&& !PonyPosture.hasSeaponyForm(player) && !PonyPosture.hasNirikForm(player)
|
||||
&& player.getSkinTextures().model() == armShape;
|
||||
},
|
||||
context -> new PlayerPonyRenderer(context, armShape == SkinTextures.Model.SLIM)
|
||||
);
|
||||
|
@ -83,15 +90,15 @@ public class PonyRenderDispatcher {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
public <T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> IPonyRenderContext<T, M> getPonyRenderer(@Nullable T entity) {
|
||||
public <T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> PonyRenderContext<T, M> getPonyRenderer(@Nullable T entity) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
EntityRenderer<?> renderer = MinecraftClient.getInstance().getEntityRenderDispatcher().getRenderer(entity);
|
||||
|
||||
if (renderer instanceof IPonyRenderContext) {
|
||||
return (IPonyRenderContext<T, M>) renderer;
|
||||
if (renderer instanceof PonyRenderContext) {
|
||||
return (PonyRenderContext<T, M>) renderer;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -3,8 +3,8 @@ package com.minelittlepony.client.render.blockentity.skull;
|
|||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.config.PonyLevel;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.SkinsProxy;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.client.SkinsProxy;
|
||||
import com.minelittlepony.client.model.*;
|
||||
import com.minelittlepony.client.render.blockentity.skull.PonySkullRenderer.ISkull;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
@ -45,7 +45,7 @@ public class PlayerPonySkull implements ISkull {
|
|||
return skin;
|
||||
}
|
||||
|
||||
return DefaultSkinHelper.getTexture(profile).texture();
|
||||
return DefaultSkinHelper.getSkinTextures(profile).texture();
|
||||
}
|
||||
|
||||
return DefaultSkinHelper.getTexture();
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.minelittlepony.client.render.blockentity.skull;
|
|||
import com.google.common.collect.Maps;
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.client.model.ModelType;
|
||||
import com.minelittlepony.client.render.MobRenderers;
|
||||
import com.minelittlepony.client.render.entity.SkeleponyRenderer;
|
||||
|
@ -50,7 +49,7 @@ public class PonySkullRenderer {
|
|||
|
||||
ISkull skull = SKULLS.get(skullType);
|
||||
|
||||
if (skull == null || !skull.canRender(MineLittlePony.getInstance().getConfig())) {
|
||||
if (skull == null || !skull.canRender(PonyConfig.getInstance())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -64,7 +63,7 @@ public class PonySkullRenderer {
|
|||
MatrixStack stack, VertexConsumerProvider renderContext, RenderLayer layer,
|
||||
int lightUv) {
|
||||
|
||||
if (selectedSkull == null || !selectedSkull.canRender(MineLittlePony.getInstance().getConfig())) {
|
||||
if (selectedSkull == null || !selectedSkull.canRender(PonyConfig.getInstance())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package com.minelittlepony.client.render.entity;
|
||||
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.client.model.*;
|
||||
import com.minelittlepony.client.render.DebugBoundingBoxRenderer;
|
||||
import com.minelittlepony.client.render.IPonyRenderContext;
|
||||
import com.minelittlepony.client.render.PonyRenderContext;
|
||||
import com.minelittlepony.client.render.EquineRenderManager;
|
||||
import com.minelittlepony.client.render.entity.feature.*;
|
||||
import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier;
|
||||
|
@ -27,9 +28,9 @@ import net.minecraft.entity.mob.MobEntity;
|
|||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public abstract class AbstractPonyRenderer<T extends MobEntity, M extends EntityModel<T> & PonyModel<T> & ModelWithArms> extends MobEntityRenderer<T, M> implements IPonyRenderContext<T, M> {
|
||||
public abstract class AbstractPonyRenderer<T extends MobEntity, M extends EntityModel<T> & PonyModel<T> & ModelWithArms> extends MobEntityRenderer<T, M> implements PonyRenderContext<T, M> {
|
||||
|
||||
protected final EquineRenderManager<T, M> manager = new EquineRenderManager<>(this);
|
||||
protected final EquineRenderManager<T, M> manager;
|
||||
|
||||
private final Map<Wearable, Identifier> wearableTextures = new EnumMap<>(Wearable.class);
|
||||
|
||||
|
@ -39,7 +40,7 @@ public abstract class AbstractPonyRenderer<T extends MobEntity, M extends Entity
|
|||
|
||||
public AbstractPonyRenderer(EntityRendererFactory.Context context, ModelKey<? super M> key, TextureSupplier<T> texture, float scale) {
|
||||
super(context, null, 0.5F);
|
||||
this.model = manager.setModel(key).body();
|
||||
this.manager = new EquineRenderManager<>(this, super::setupTransforms, key);
|
||||
this.texture = texture;
|
||||
this.scale = scale;
|
||||
addFeatures(context);
|
||||
|
@ -64,24 +65,17 @@ public abstract class AbstractPonyRenderer<T extends MobEntity, M extends Entity
|
|||
|
||||
@Override
|
||||
public void render(T entity, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) {
|
||||
manager.preRender(entity, ModelAttributes.Mode.THIRD_PERSON);
|
||||
if (manager.getModels().body() instanceof BipedEntityModel model) {
|
||||
model.setVisible(true);
|
||||
}
|
||||
super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv);
|
||||
DebugBoundingBoxRenderer.render(getEntityPony(entity), this, entity, stack, renderContext, tickDelta);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupTransforms(T entity, MatrixStack stack, float ageInTicks, float rotationYaw, float partialTicks) {
|
||||
manager.preRenderCallback(entity, stack, partialTicks);
|
||||
if (getModel() instanceof PlayerEntityModel) {
|
||||
((PlayerEntityModel<?>)getModel()).setVisible(true);
|
||||
}
|
||||
|
||||
if (getModel().getAttributes().isSitting) {
|
||||
stack.translate(0, 0.125D, 0);
|
||||
}
|
||||
|
||||
rotationYaw = manager.getRenderYaw(entity, rotationYaw, partialTicks);
|
||||
super.setupTransforms(entity, stack, ageInTicks, rotationYaw, partialTicks);
|
||||
manager.setupTransforms(entity, stack, rotationYaw, partialTicks);
|
||||
manager.setupTransforms(entity, stack, ageInTicks, rotationYaw, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -91,7 +85,7 @@ public abstract class AbstractPonyRenderer<T extends MobEntity, M extends Entity
|
|||
|
||||
@Override
|
||||
public void scale(T entity, MatrixStack stack, float tickDelta) {
|
||||
shadowRadius = manager.getModel().getSize().shadowSize();
|
||||
shadowRadius = manager.getShadowSize();
|
||||
|
||||
if (entity.isBaby()) {
|
||||
shadowRadius *= 3; // undo vanilla shadow scaling
|
||||
|
@ -100,7 +94,7 @@ public abstract class AbstractPonyRenderer<T extends MobEntity, M extends Entity
|
|||
if (!entity.hasVehicle()) {
|
||||
stack.translate(0, 0, -entity.getWidth() / 2); // move us to the center of the shadow
|
||||
} else {
|
||||
stack.translate(0, -entity.getRidingOffset(entity.getVehicle()), 0);
|
||||
stack.translate(0, entity.getRidingOffset(entity.getVehicle()), 0);
|
||||
}
|
||||
|
||||
stack.scale(scale, scale, scale);
|
||||
|
@ -117,8 +111,7 @@ public abstract class AbstractPonyRenderer<T extends MobEntity, M extends Entity
|
|||
@Override
|
||||
public Identifier getDefaultTexture(T entity, Wearable wearable) {
|
||||
return wearableTextures.computeIfAbsent(wearable, w -> {
|
||||
Identifier texture = getTexture(entity);
|
||||
texture = new Identifier(texture.getNamespace(), texture.getPath().split("\\.")[0] + "_" + wearable.name().toLowerCase(Locale.ROOT) + ".png");
|
||||
Identifier texture = getTexture(entity).withPath(path -> path.split("\\.")[0] + "_" + wearable.name().toLowerCase(Locale.ROOT) + ".png");
|
||||
|
||||
if (MinecraftClient.getInstance().getResourceManager().getResource(texture).isPresent()) {
|
||||
return texture;
|
||||
|
@ -127,6 +120,11 @@ public abstract class AbstractPonyRenderer<T extends MobEntity, M extends Entity
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModel(M model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EquineRenderManager<T, M> getInternalRenderer() {
|
||||
return manager;
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package com.minelittlepony.client.render.entity;
|
||||
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.PonyPosture;
|
||||
import com.minelittlepony.api.model.PreviewModel;
|
||||
import com.minelittlepony.api.pony.*;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.client.PreviewModel;
|
||||
import com.minelittlepony.client.SkinsProxy;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
||||
import net.minecraft.client.network.AbstractClientPlayerEntity;
|
||||
|
@ -12,69 +10,48 @@ import net.minecraft.client.render.VertexConsumerProvider;
|
|||
import net.minecraft.client.render.entity.EntityRendererFactory;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.util.Arm;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class AquaticPlayerPonyRenderer extends PlayerPonyRenderer {
|
||||
public static final Identifier SKIN_TYPE_ID = new Identifier("minelp", "seapony");
|
||||
|
||||
private boolean wet;
|
||||
public class AquaticPlayerPonyRenderer extends FormChangingPlayerPonyRenderer {
|
||||
|
||||
public AquaticPlayerPonyRenderer(EntityRendererFactory.Context context, boolean slim) {
|
||||
super(context, slim);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getTexture(AbstractClientPlayerEntity player) {
|
||||
if (wet) {
|
||||
return SkinsProxy.instance.getSkin(SKIN_TYPE_ID, player).orElseGet(() -> super.getTexture(player));
|
||||
}
|
||||
return super.getTexture(player);
|
||||
super(context, slim, DefaultPonySkinHelper.SEAPONY_SKIN_TYPE_ID, PonyPosture::isSeaponyModifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(AbstractClientPlayerEntity player, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int light) {
|
||||
updateSeaponyState(player);
|
||||
super.render(player, entityYaw, tickDelta, stack, renderContext, light);
|
||||
|
||||
if (!(player instanceof PreviewModel) && wet && player.getVelocity().length() > 0.1F) {
|
||||
if (!(player instanceof PreviewModel) && transformed && player.getVelocity().length() > 0.1F) {
|
||||
double x = player.getEntityWorld().getRandom().nextTriangular(player.getX(), 1);
|
||||
double y = player.getEntityWorld().getRandom().nextTriangular(player.getY(), 1);
|
||||
double z = player.getEntityWorld().getRandom().nextTriangular(player.getZ(), 1);
|
||||
|
||||
player.getEntityWorld().addParticle(ParticleTypes.BUBBLE, x, y, z, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Race getPlayerRace(AbstractClientPlayerEntity entity, Pony pony) {
|
||||
Race race = super.getPlayerRace(entity, pony);
|
||||
return wet ? Race.SEAPONY : race == Race.SEAPONY ? Race.UNICORN : race;
|
||||
return PonyPosture.isSeaponyModifier(entity) ? Race.SEAPONY : race == Race.SEAPONY ? Race.UNICORN : race;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupTransforms(AbstractClientPlayerEntity entity, MatrixStack stack, float ageInTicks, float rotationYaw, float partialTicks) {
|
||||
if (wet) {
|
||||
protected void setupTransforms(AbstractClientPlayerEntity player, MatrixStack stack, float ageInTicks, float rotationYaw, float partialTicks) {
|
||||
if (PonyPosture.isSeaponyModifier(player)) {
|
||||
stack.translate(0, 0.6, 0);
|
||||
if (entity.isInSneakingPose()) {
|
||||
if (player.isInSneakingPose()) {
|
||||
stack.translate(0, 0.125, 0);
|
||||
}
|
||||
}
|
||||
super.setupTransforms(entity, stack, ageInTicks, rotationYaw, partialTicks);
|
||||
super.setupTransforms(player, stack, ageInTicks, rotationYaw, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, AbstractClientPlayerEntity player, Arm side) {
|
||||
updateSeaponyState(player);
|
||||
super.renderArm(stack, renderContext, lightUv, player, side);
|
||||
}
|
||||
|
||||
private void updateSeaponyState(AbstractClientPlayerEntity player) {
|
||||
Pony pony = getEntityPony(player);
|
||||
wet = PonyPosture.isSeaponyModifier(player);
|
||||
|
||||
protected void updateForm(AbstractClientPlayerEntity player) {
|
||||
super.updateForm(player);
|
||||
if (!(player instanceof PreviewModel)) {
|
||||
float state = wet ? 100 : 0;
|
||||
float interpolated = pony.metadata().getInterpolator(player.getUuid()).interpolate("seapony_state", state, 5);
|
||||
float state = transformed ? 100 : 0;
|
||||
float interpolated = getInternalRenderer().getModels().body().getAttributes().getMainInterpolator().interpolate("seapony_state", state, 5);
|
||||
|
||||
if (!MathUtil.compareFloats(interpolated, state)) {
|
||||
double x = player.getEntityWorld().getRandom().nextTriangular(player.getX(), 1);
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package com.minelittlepony.client.render.entity;
|
||||
|
||||
import com.minelittlepony.api.pony.*;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import net.minecraft.client.network.AbstractClientPlayerEntity;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.entity.EntityRendererFactory;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.Arm;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class FormChangingPlayerPonyRenderer extends PlayerPonyRenderer {
|
||||
protected boolean transformed;
|
||||
|
||||
private final Identifier alternateFormSkinId;
|
||||
private final Predicate<AbstractClientPlayerEntity> formModifierPredicate;
|
||||
|
||||
public FormChangingPlayerPonyRenderer(EntityRendererFactory.Context context,
|
||||
boolean slim, Identifier alternateFormSkinId, Predicate<AbstractClientPlayerEntity> formModifierPredicate) {
|
||||
super(context, slim);
|
||||
this.alternateFormSkinId = alternateFormSkinId;
|
||||
this.formModifierPredicate = formModifierPredicate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getTexture(AbstractClientPlayerEntity player) {
|
||||
if (transformed) {
|
||||
return SkinsProxy.instance.getSkin(alternateFormSkinId, player).orElseGet(() -> super.getTexture(player));
|
||||
}
|
||||
return super.getTexture(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(AbstractClientPlayerEntity player, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int light) {
|
||||
super.render(player, entityYaw, tickDelta, stack, renderContext, light);
|
||||
updateForm(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, AbstractClientPlayerEntity player, Arm side) {
|
||||
super.renderArm(stack, renderContext, lightUv, player, side);
|
||||
updateForm(player);
|
||||
}
|
||||
|
||||
protected void updateForm(AbstractClientPlayerEntity player) {
|
||||
transformed = formModifierPredicate.test(player);
|
||||
}
|
||||
}
|
|
@ -1,13 +1,14 @@
|
|||
package com.minelittlepony.client.render.entity;
|
||||
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.api.model.Models;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.SkinsProxy;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.client.SkinsProxy;
|
||||
import com.minelittlepony.client.model.*;
|
||||
import com.minelittlepony.client.render.DebugBoundingBoxRenderer;
|
||||
import com.minelittlepony.client.render.IPonyRenderContext;
|
||||
import com.minelittlepony.client.render.PonyRenderContext;
|
||||
import com.minelittlepony.client.render.entity.feature.*;
|
||||
import com.minelittlepony.client.util.render.RenderLayerUtil;
|
||||
|
||||
|
@ -26,24 +27,22 @@ import net.minecraft.client.render.entity.feature.*;
|
|||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.math.*;
|
||||
|
||||
public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRenderContext<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> {
|
||||
|
||||
protected final EquineRenderManager<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> manager = new EquineRenderManager<>(this);
|
||||
|
||||
private final Function<Race, ModelWrapper<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>>> modelsCache;
|
||||
public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRenderContext<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> {
|
||||
private final Function<Race, Models<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>>> modelsCache;
|
||||
protected final EquineRenderManager<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> manager;
|
||||
|
||||
public PlayerPonyRenderer(EntityRendererFactory.Context context, boolean slim) {
|
||||
super(context, slim);
|
||||
modelsCache = Util.memoize(race -> ModelType.getPlayerModel(race).create(slim));
|
||||
manager = new EquineRenderManager<>(this, super::setupTransforms, modelsCache.apply(Race.EARTH));
|
||||
manager.setModelsLookup(entity -> modelsCache.apply(getPlayerRace(entity, getEntityPony(entity))));
|
||||
addLayers(context);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
protected void addLayers(EntityRendererFactory.Context context) {
|
||||
// remove vanilla features (keep modded ones)
|
||||
// TODO: test with https://github.com/Globox1997/BackSlot
|
||||
features.removeIf(feature -> {
|
||||
return feature instanceof ArmorFeatureRenderer
|
||||
|| feature instanceof PlayerHeldItemFeatureRenderer
|
||||
|
@ -70,30 +69,32 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen
|
|||
|
||||
@Override
|
||||
protected void scale(AbstractClientPlayerEntity entity, MatrixStack stack, float tickDelta) {
|
||||
if (manager.getModel().getAttributes().isSitting && entity.hasVehicle()) {
|
||||
if (manager.getModels().body().getAttributes().isSitting && entity.hasVehicle()) {
|
||||
stack.translate(0, entity.getRidingOffset(entity.getVehicle()), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(AbstractClientPlayerEntity entity, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) {
|
||||
Pony pony = getEntityPony(entity);
|
||||
model = manager.setModel(modelsCache.apply(getPlayerRace(entity, pony))).body();
|
||||
// EntityModelFeatures: We have to force it to use our models otherwise EMF overrides it and breaks pony rendering
|
||||
shadowRadius = manager.getModel().getSize().shadowSize();
|
||||
manager.preRender(entity, ModelAttributes.Mode.THIRD_PERSON);
|
||||
shadowRadius = manager.getShadowSize();
|
||||
super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv);
|
||||
DebugBoundingBoxRenderer.render(pony, this, entity, stack, renderContext, tickDelta);
|
||||
DebugBoundingBoxRenderer.render(getEntityPony(entity), this, entity, stack, renderContext, tickDelta);
|
||||
|
||||
// Translate the shadow position after everything is done
|
||||
// (shadows are drawn after us)
|
||||
/*
|
||||
if (!entity.hasVehicle() && !entity.isSleeping()) {
|
||||
float yaw = MathHelper.lerpAngleDegrees(tickDelta, entity.prevBodyYaw, entity.bodyYaw);
|
||||
float l = entity.getWidth() / 2 * pony.size().scaleFactor();
|
||||
float l = entity.getWidth() / 2 * manager.getScaleFactor();
|
||||
|
||||
stack.multiply(RotationAxis.NEGATIVE_Y.rotationDegrees(yaw));
|
||||
stack.translate(0, 0, -l);
|
||||
stack.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw));
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
protected Race getPlayerRace(AbstractClientPlayerEntity entity, Pony pony) {
|
||||
|
@ -102,10 +103,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen
|
|||
|
||||
@Override
|
||||
protected void setupTransforms(AbstractClientPlayerEntity entity, MatrixStack stack, float ageInTicks, float rotationYaw, float partialTicks) {
|
||||
manager.preRenderCallback(entity, stack, partialTicks);
|
||||
rotationYaw = manager.getRenderYaw(entity, rotationYaw, partialTicks);
|
||||
super.setupTransforms(entity, stack, ageInTicks, rotationYaw, partialTicks);
|
||||
manager.setupTransforms(entity, stack, rotationYaw, partialTicks);
|
||||
manager.setupTransforms(entity, stack, ageInTicks, rotationYaw, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -144,9 +142,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen
|
|||
}
|
||||
|
||||
protected void renderArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, AbstractClientPlayerEntity player, Arm side) {
|
||||
Pony pony = getEntityPony(player);
|
||||
model = manager.setModel(modelsCache.apply(getPlayerRace(player, pony))).body();
|
||||
manager.updateModel(player, ModelAttributes.Mode.FIRST_PERSON);
|
||||
manager.preRender(player, ModelAttributes.Mode.FIRST_PERSON);
|
||||
|
||||
stack.push();
|
||||
float reflect = side == Arm.LEFT ? 1 : -1;
|
||||
|
@ -154,7 +150,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen
|
|||
stack.translate(reflect * 0.1F, -0.54F, 0);
|
||||
|
||||
Identifier texture = getTexture(player);
|
||||
Identifier playerSkin = player.method_52814().texture();
|
||||
Identifier playerSkin = player.getSkinTextures().texture();
|
||||
VertexConsumerProvider interceptedContext = layer -> {
|
||||
return renderContext.getBuffer(RenderLayerUtil
|
||||
.getTexture(layer)
|
||||
|
@ -178,6 +174,11 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen
|
|||
return getEntityPony(player).texture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModel(ClientPonyModel<AbstractClientPlayerEntity> model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EquineRenderManager<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> getInternalRenderer() {
|
||||
return manager;
|
||||
|
@ -191,7 +192,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen
|
|||
@Override
|
||||
public Identifier getDefaultTexture(AbstractClientPlayerEntity entity, Wearable wearable) {
|
||||
return SkinsProxy.instance.getSkin(wearable.getId(), entity).orElseGet(() -> {
|
||||
if (wearable.isSaddlebags() && getInternalRenderer().getModel().getRace().supportsLegacySaddlebags()) {
|
||||
if (wearable.isSaddlebags() && getInternalRenderer().getModels().body().getRace().supportsLegacySaddlebags()) {
|
||||
return getTexture(entity);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,11 +11,11 @@ import net.minecraft.entity.EquipmentSlot;
|
|||
import net.minecraft.entity.decoration.ArmorStandEntity;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import com.minelittlepony.api.model.armour.ArmourLayer;
|
||||
import com.minelittlepony.api.model.Models;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.client.model.ModelType;
|
||||
import com.minelittlepony.client.model.ModelWrapper;
|
||||
import com.minelittlepony.client.model.armour.ArmourLayer;
|
||||
import com.minelittlepony.client.model.entity.PonyArmourStandModel;
|
||||
import com.minelittlepony.client.model.entity.race.EarthPonyModel;
|
||||
import com.minelittlepony.client.render.entity.feature.ArmourFeature;
|
||||
|
@ -60,7 +60,7 @@ public class PonyStandRenderer extends ArmorStandEntityRenderer {
|
|||
}
|
||||
|
||||
class Armour extends ArmorFeatureRenderer<ArmorStandEntity, ArmorStandArmorEntityModel, ArmorStandArmorEntityModel> {
|
||||
private final ModelWrapper<ArmorStandEntity, EarthPonyModel<ArmorStandEntity>> pony = ModelType.EARTH_PONY.<ArmorStandEntity, EarthPonyModel<ArmorStandEntity>>create(false);
|
||||
private final Models<ArmorStandEntity, EarthPonyModel<ArmorStandEntity>> pony = ModelType.EARTH_PONY.<ArmorStandEntity, EarthPonyModel<ArmorStandEntity>>create(false);
|
||||
|
||||
public Armour(FeatureRendererContext<ArmorStandEntity, ArmorStandArmorEntityModel> renderer, EntityRendererFactory.Context context) {
|
||||
super(renderer,
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.client.render.entity;
|
|||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.client.mixin.IResizeable;
|
||||
import com.minelittlepony.client.model.ModelType;
|
||||
import com.minelittlepony.client.model.entity.GuardianPonyModel;
|
||||
|
@ -52,7 +53,7 @@ public class SeaponyRenderer extends GuardianEntityRenderer {
|
|||
|
||||
@Override
|
||||
public void render(GuardianEntity entity, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) {
|
||||
ponyRenderer.manager.preRenderCallback(entity, stack, tickDelta);
|
||||
ponyRenderer.manager.preRender(entity, ModelAttributes.Mode.THIRD_PERSON);
|
||||
|
||||
float height = entity.getStandingEyeHeight();
|
||||
|
||||
|
@ -61,4 +62,9 @@ public class SeaponyRenderer extends GuardianEntityRenderer {
|
|||
super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv);
|
||||
((IResizeable)entity).setStandingEyeHeight(height);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupTransforms(GuardianEntity entity, MatrixStack stack, float ageInTicks, float rotationYaw, float partialTicks) {
|
||||
ponyRenderer.manager.setupTransforms(entity, stack, ageInTicks, rotationYaw, partialTicks);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,6 @@ public class ZomponyRenderer<Zombie extends HostileEntity> extends PonyRenderer<
|
|||
}
|
||||
|
||||
public static ZomponyRenderer<GiantEntity> giant(EntityRendererFactory.Context context) {
|
||||
return new ZomponyRenderer<>(context, TextureSupplier.of(ZOMBIE), 3);
|
||||
return new ZomponyRenderer<>(context, TextureSupplier.of(ZOMBIE), 6.8F);
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue