mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2024-11-26 14:27:59 +01:00
More changes to texture suppliers
This commit is contained in:
parent
96cfd13b96
commit
8c1a705b9e
12 changed files with 227 additions and 215 deletions
|
@ -32,6 +32,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
public class PonyManager implements IPonyManager, SimpleSynchronousResourceReloadListener {
|
public class PonyManager implements IPonyManager, SimpleSynchronousResourceReloadListener {
|
||||||
private static final Identifier ID = new Identifier("minelittlepony", "background_ponies");
|
private static final Identifier ID = new Identifier("minelittlepony", "background_ponies");
|
||||||
public static final Identifier BACKGROUND_PONIES = new Identifier("minelittlepony", "textures/entity/pony");
|
public static final Identifier BACKGROUND_PONIES = new Identifier("minelittlepony", "textures/entity/pony");
|
||||||
|
public static final Identifier BACKGROUND_ZOMPONIES = new Identifier("minelittlepony", "textures/entity/zompony");
|
||||||
|
|
||||||
private final PonyConfig config;
|
private final PonyConfig config;
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,10 @@ abstract class AbstractNpcRenderer<T extends MobEntity & VillagerDataContainer>
|
||||||
|
|
||||||
private final NpcClothingFeature<T, ClientPonyModel<T>, AbstractNpcRenderer<T>> clothing;
|
private final NpcClothingFeature<T, ClientPonyModel<T>, AbstractNpcRenderer<T>> clothing;
|
||||||
|
|
||||||
public AbstractNpcRenderer(EntityRendererFactory.Context context, String type, TextureSupplier<String> formatter) {
|
public AbstractNpcRenderer(EntityRendererFactory.Context context, String type, TextureSupplier<T> textureSupplier, TextureSupplier<String> formatter) {
|
||||||
super(context, ModelType.getPlayerModel(Race.EARTH).getKey(false));
|
super(context, ModelType.getPlayerModel(Race.EARTH).getKey(false));
|
||||||
entityType = type;
|
entityType = type;
|
||||||
baseTextures = new SillyPonyTextures<>(new CustomPonyTextures<>(new PonyTextures<>(formatter)), formatter);
|
baseTextures = new SillyPonyTextureSupplier<>(textureSupplier, formatter);
|
||||||
clothing = new NpcClothingFeature<>(this, entityType);
|
clothing = new NpcClothingFeature<>(this, entityType);
|
||||||
addFeature(clothing);
|
addFeature(clothing);
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ abstract class AbstractNpcRenderer<T extends MobEntity & VillagerDataContainer>
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldRender(ClientPonyModel<T> model, T entity, Wearable wearable, IGear gear) {
|
public boolean shouldRender(ClientPonyModel<T> model, T entity, Wearable wearable, IGear gear) {
|
||||||
|
|
||||||
boolean special = PonyTextures.isBestPony(entity);
|
boolean special = SillyPonyTextureSupplier.isBestPony(entity);
|
||||||
|
|
||||||
if (wearable == Wearable.SADDLE_BAGS_BOTH) {
|
if (wearable == Wearable.SADDLE_BAGS_BOTH) {
|
||||||
VillagerProfession profession = entity.getVillagerData().getProfession();
|
VillagerProfession profession = entity.getVillagerData().getProfession();
|
||||||
|
@ -52,7 +52,7 @@ abstract class AbstractNpcRenderer<T extends MobEntity & VillagerDataContainer>
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wearable == Wearable.MUFFIN) {
|
if (wearable == Wearable.MUFFIN) {
|
||||||
return PonyTextures.isCrownPony(entity);
|
return SillyPonyTextureSupplier.isCrownPony(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.shouldRender(model, entity, wearable, gear);
|
return super.shouldRender(model, entity, wearable, gear);
|
||||||
|
@ -85,6 +85,6 @@ abstract class AbstractNpcRenderer<T extends MobEntity & VillagerDataContainer>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Identifier getTexture(T villager) {
|
public Identifier getTexture(T villager) {
|
||||||
return baseTextures.supplyTexture(villager);
|
return baseTextures.apply(villager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ import net.minecraft.entity.passive.VillagerEntity;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
import com.minelittlepony.client.model.ClientPonyModel;
|
import com.minelittlepony.client.model.ClientPonyModel;
|
||||||
import com.minelittlepony.client.render.entity.npc.textures.PonyTextures;
|
import com.minelittlepony.client.pony.PonyManager;
|
||||||
import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier;
|
import com.minelittlepony.client.render.entity.npc.textures.*;
|
||||||
|
|
||||||
public class VillagerPonyRenderer extends AbstractNpcRenderer<VillagerEntity> {
|
public class VillagerPonyRenderer extends AbstractNpcRenderer<VillagerEntity> {
|
||||||
|
|
||||||
|
@ -15,13 +15,15 @@ public class VillagerPonyRenderer extends AbstractNpcRenderer<VillagerEntity> {
|
||||||
private static final TextureSupplier<String> FORMATTER = TextureSupplier.formatted("minelittlepony", "textures/entity/villager/%s.png");
|
private static final TextureSupplier<String> FORMATTER = TextureSupplier.formatted("minelittlepony", "textures/entity/villager/%s.png");
|
||||||
|
|
||||||
public VillagerPonyRenderer(EntityRendererFactory.Context context) {
|
public VillagerPonyRenderer(EntityRendererFactory.Context context) {
|
||||||
super(context, TYPE, FORMATTER);
|
super(context, TYPE,
|
||||||
|
TextureSupplier.ofPool(PonyManager.BACKGROUND_PONIES,
|
||||||
|
PlayerTextureSupplier.create(ProfessionTextureSupplier.create(FORMATTER))), FORMATTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initializeModel(ClientPonyModel<VillagerEntity> model) {
|
protected void initializeModel(ClientPonyModel<VillagerEntity> model) {
|
||||||
model.onSetModelAngles((m, move, swing, ticks, entity) -> {
|
model.onSetModelAngles((m, move, swing, ticks, entity) -> {
|
||||||
m.getAttributes().visualHeight += PonyTextures.isCrownPony(entity) ? 0.3F : -0.1F;
|
m.getAttributes().visualHeight += SillyPonyTextureSupplier.isCrownPony(entity) ? 0.3F : -0.1F;
|
||||||
|
|
||||||
boolean isHeadRolling = entity instanceof MerchantEntity && ((MerchantEntity)entity).getHeadRollingTimeLeft() > 0;
|
boolean isHeadRolling = entity instanceof MerchantEntity && ((MerchantEntity)entity).getHeadRollingTimeLeft() > 0;
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ import net.minecraft.entity.mob.ZombieVillagerEntity;
|
||||||
|
|
||||||
import com.minelittlepony.client.model.ClientPonyModel;
|
import com.minelittlepony.client.model.ClientPonyModel;
|
||||||
import com.minelittlepony.client.model.IMobModel;
|
import com.minelittlepony.client.model.IMobModel;
|
||||||
import com.minelittlepony.client.render.entity.npc.textures.PonyTextures;
|
import com.minelittlepony.client.pony.PonyManager;
|
||||||
import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier;
|
import com.minelittlepony.client.render.entity.npc.textures.*;
|
||||||
|
|
||||||
public class ZomponyVillagerRenderer extends AbstractNpcRenderer<ZombieVillagerEntity> {
|
public class ZomponyVillagerRenderer extends AbstractNpcRenderer<ZombieVillagerEntity> {
|
||||||
|
|
||||||
|
@ -16,13 +16,17 @@ public class ZomponyVillagerRenderer extends AbstractNpcRenderer<ZombieVillagerE
|
||||||
private static final TextureSupplier<String> FORMATTER = TextureSupplier.formatted("minelittlepony", "textures/entity/zombie_villager/zombie_%s.png");
|
private static final TextureSupplier<String> FORMATTER = TextureSupplier.formatted("minelittlepony", "textures/entity/zombie_villager/zombie_%s.png");
|
||||||
|
|
||||||
public ZomponyVillagerRenderer(EntityRendererFactory.Context context) {
|
public ZomponyVillagerRenderer(EntityRendererFactory.Context context) {
|
||||||
super(context, TYPE, FORMATTER);
|
super(context, TYPE,
|
||||||
|
TextureSupplier.ofPool(PonyManager.BACKGROUND_ZOMPONIES,
|
||||||
|
TextureSupplier.ofPool(PonyManager.BACKGROUND_PONIES,
|
||||||
|
PlayerTextureSupplier.create(ProfessionTextureSupplier.create(FORMATTER)))),
|
||||||
|
FORMATTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initializeModel(ClientPonyModel<ZombieVillagerEntity> model) {
|
protected void initializeModel(ClientPonyModel<ZombieVillagerEntity> model) {
|
||||||
model.onSetModelAngles((m, move, swing, ticks, entity) -> {
|
model.onSetModelAngles((m, move, swing, ticks, entity) -> {
|
||||||
m.getAttributes().visualHeight += PonyTextures.isCrownPony(entity) ? 0.3F : -0.1F;
|
m.getAttributes().visualHeight += SillyPonyTextureSupplier.isCrownPony(entity) ? 0.3F : -0.1F;
|
||||||
|
|
||||||
if (m.rightArmPose == ArmPose.EMPTY) {
|
if (m.rightArmPose == ArmPose.EMPTY) {
|
||||||
IMobModel.rotateUndeadArms(m, move, ticks);
|
IMobModel.rotateUndeadArms(m, move, ticks);
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
package com.minelittlepony.client.render.entity.npc.textures;
|
|
||||||
|
|
||||||
import net.minecraft.block.entity.SkullBlockEntity;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.minelittlepony.api.config.PonyConfig;
|
|
||||||
import com.minelittlepony.api.config.PonyLevel;
|
|
||||||
import com.minelittlepony.api.pony.IPony;
|
|
||||||
import com.minelittlepony.client.MineLittlePony;
|
|
||||||
import com.minelittlepony.client.SkinsProxy;
|
|
||||||
import com.minelittlepony.client.pony.PonyManager;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class CustomPonyTextures<T extends LivingEntity> implements TextureSupplier<T> {
|
|
||||||
|
|
||||||
private final TextureSupplier<T> fallback;
|
|
||||||
private final Map<String, Entry> customNameCache = new HashMap<>();
|
|
||||||
|
|
||||||
public CustomPonyTextures(TextureSupplier<T> fallback) {
|
|
||||||
this.fallback = fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Identifier supplyTexture(T entity) {
|
|
||||||
Identifier override = getCustomTexture(entity);
|
|
||||||
if (override != null) {
|
|
||||||
return override;
|
|
||||||
}
|
|
||||||
return fallback.supplyTexture(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private Identifier getCustomTexture(T entity) {
|
|
||||||
if (!entity.hasCustomName()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String key = entity.getCustomName().getString() + "_" + entity.getUuidAsString();
|
|
||||||
|
|
||||||
if (!customNameCache.containsKey(key)) {
|
|
||||||
customNameCache.put(key, new Entry(entity));
|
|
||||||
}
|
|
||||||
return customNameCache.get(key).getTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
class Entry {
|
|
||||||
private final UUID uuid;
|
|
||||||
private final Identifier texture;
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private GameProfile profile;
|
|
||||||
|
|
||||||
Entry(T entity) {
|
|
||||||
uuid = entity.getUuid();
|
|
||||||
texture = MineLittlePony.getInstance().getVariatedTextures()
|
|
||||||
.get(PonyManager.BACKGROUND_PONIES)
|
|
||||||
.getByName(entity.getCustomName().getString(), uuid)
|
|
||||||
.orElse(null);
|
|
||||||
|
|
||||||
if (texture == null) {
|
|
||||||
SkullBlockEntity.loadProperties(new GameProfile(null, entity.getCustomName().getString()), resolved -> {
|
|
||||||
profile = resolved;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier getTexture() {
|
|
||||||
if (profile != null) {
|
|
||||||
Identifier skin = SkinsProxy.instance.getSkinTexture(profile);
|
|
||||||
if (skin != null) {
|
|
||||||
if (IPony.getManager().getPony(skin).race().isHuman()) {
|
|
||||||
if (PonyConfig.getInstance().ponyLevel.get() == PonyLevel.PONIES) {
|
|
||||||
return IPony.getManager().getBackgroundPony(uuid).texture();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return skin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.minelittlepony.client.render.entity.npc.textures;
|
||||||
|
|
||||||
|
import net.minecraft.block.entity.SkullBlockEntity;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import com.minelittlepony.api.config.PonyConfig;
|
||||||
|
import com.minelittlepony.api.config.PonyLevel;
|
||||||
|
import com.minelittlepony.api.pony.IPony;
|
||||||
|
import com.minelittlepony.client.SkinsProxy;
|
||||||
|
import com.minelittlepony.util.FunctionUtil;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class PlayerTextureSupplier {
|
||||||
|
public static <T extends LivingEntity> TextureSupplier<T> create(TextureSupplier<T> fallback) {
|
||||||
|
Function<T, Entry> customNameCache = FunctionUtil.memoize(Entry::new, entity -> entity.getCustomName().getString() + "_" + entity.getUuidAsString());
|
||||||
|
return entity -> {
|
||||||
|
Identifier override = entity.hasCustomName() ? customNameCache.apply(entity).getTexture() : null;
|
||||||
|
if (override != null) {
|
||||||
|
return override;
|
||||||
|
}
|
||||||
|
return fallback.apply(entity);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class Entry {
|
||||||
|
private final UUID uuid;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private GameProfile profile;
|
||||||
|
|
||||||
|
Entry(LivingEntity entity) {
|
||||||
|
uuid = entity.getUuid();
|
||||||
|
SkullBlockEntity.loadProperties(new GameProfile(null, entity.getCustomName().getString()), resolved -> {
|
||||||
|
profile = resolved;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Identifier getTexture() {
|
||||||
|
if (profile != null) {
|
||||||
|
Identifier skin = SkinsProxy.instance.getSkinTexture(profile);
|
||||||
|
if (skin != null) {
|
||||||
|
if (IPony.getManager().getPony(skin).race().isHuman()) {
|
||||||
|
if (PonyConfig.getInstance().ponyLevel.get() == PonyLevel.PONIES) {
|
||||||
|
return IPony.getManager().getBackgroundPony(uuid).texture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,87 +0,0 @@
|
||||||
package com.minelittlepony.client.render.entity.npc.textures;
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
import net.minecraft.resource.ResourceManager;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.village.VillagerData;
|
|
||||||
import net.minecraft.village.VillagerDataContainer;
|
|
||||||
import net.minecraft.village.VillagerProfession;
|
|
||||||
import net.minecraft.village.VillagerType;
|
|
||||||
|
|
||||||
import com.minelittlepony.util.ResourceUtil;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cached pool of villager textures.
|
|
||||||
*/
|
|
||||||
public class PonyTextures<T extends LivingEntity & VillagerDataContainer> implements TextureSupplier<T> {
|
|
||||||
|
|
||||||
private final TextureSupplier<String> formatter;
|
|
||||||
|
|
||||||
private final Identifier fallback;
|
|
||||||
|
|
||||||
private final Map<String, Identifier> cache = new HashMap<>();
|
|
||||||
|
|
||||||
private final ResourceManager resourceManager = MinecraftClient.getInstance().getResourceManager();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new profession cache
|
|
||||||
*
|
|
||||||
* @param formatter Formatter used when creating new textures
|
|
||||||
* @param keyMapper Mapper to convert integer ids into a string value for format insertion
|
|
||||||
* @param fallback The default if any generated textures fail to load. This is stored in place of failing textures.
|
|
||||||
*/
|
|
||||||
public PonyTextures(TextureSupplier<String> formatter) {
|
|
||||||
this.formatter = formatter;
|
|
||||||
this.fallback = formatter.supplyTexture("villager_pony");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Identifier supplyTexture(T entity) {
|
|
||||||
VillagerData t = entity.getVillagerData();
|
|
||||||
|
|
||||||
return getTexture(t.getType(), t.getProfession());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Identifier getTexture(final VillagerType type, final VillagerProfession profession) {
|
|
||||||
|
|
||||||
|
|
||||||
String key = ResourceUtil.format("pony/%s/%s", type, profession);
|
|
||||||
|
|
||||||
if (cache.containsKey(key)) {
|
|
||||||
return cache.get(key); // People often complain that villagers cause lag,
|
|
||||||
// so let's do better than Mojang and rather NOT go
|
|
||||||
// through all the lambda generations if we can avoid it.
|
|
||||||
}
|
|
||||||
|
|
||||||
Identifier result = verifyTexture(formatter.supplyTexture(key)).orElseGet(() -> {
|
|
||||||
if (type == VillagerType.PLAINS) {
|
|
||||||
// if texture loading fails, use the fallback.
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
return getTexture(VillagerType.PLAINS, profession);
|
|
||||||
});
|
|
||||||
|
|
||||||
cache.put(key, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Optional<Identifier> verifyTexture(Identifier texture) {
|
|
||||||
return resourceManager.getResource(texture).map(i -> texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isBestPony(LivingEntity entity) {
|
|
||||||
if (!entity.hasCustomName()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String name = entity.getCustomName().getString();
|
|
||||||
return "Derpy".equals(name) || (entity.isBaby() && "Dinky".equals(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isCrownPony(LivingEntity entity) {
|
|
||||||
return isBestPony(entity) && entity.getUuid().getLeastSignificantBits() % 20 == 0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.minelittlepony.client.render.entity.npc.textures;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.village.*;
|
||||||
|
|
||||||
|
import com.minelittlepony.util.ResourceUtil;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class ProfessionTextureSupplier<T extends VillagerDataContainer> implements TextureSupplier<T> {
|
||||||
|
|
||||||
|
public static <T extends VillagerDataContainer> TextureSupplier<T> create(TextureSupplier<String> formatter) {
|
||||||
|
return TextureSupplier.memoize(new ProfessionTextureSupplier<>(formatter), ProfessionTextureSupplier::getKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final TextureSupplier<String> formatter;
|
||||||
|
|
||||||
|
private final Identifier fallback;
|
||||||
|
|
||||||
|
public ProfessionTextureSupplier(TextureSupplier<String> formatter) {
|
||||||
|
this.formatter = formatter;
|
||||||
|
this.fallback = formatter.apply("villager_pony");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier apply(T container) {
|
||||||
|
return apply(container.getVillagerData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Identifier apply(VillagerData t) {
|
||||||
|
return getTexture(t.getType(), t.getProfession());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getKey(VillagerDataContainer container) {
|
||||||
|
VillagerData t = container.getVillagerData();
|
||||||
|
return ResourceUtil.format("pony/%s/%s", t.getType(), t.getProfession());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Identifier getTexture(final VillagerType type, final VillagerProfession profession) {
|
||||||
|
String key = ResourceUtil.format("pony/%s/%s", type, profession);
|
||||||
|
return verifyTexture(formatter.apply(key)).orElseGet(() -> {
|
||||||
|
if (type == VillagerType.PLAINS) {
|
||||||
|
// if texture loading fails, use the fallback.
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getTexture(VillagerType.PLAINS, profession);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Optional<Identifier> verifyTexture(Identifier texture) {
|
||||||
|
return MinecraftClient.getInstance().getResourceManager().getResource(texture).map(i -> texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBestPony(LivingEntity entity) {
|
||||||
|
if (!entity.hasCustomName()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String name = entity.getCustomName().getString();
|
||||||
|
return "Derpy".equals(name) || (entity.isBaby() && "Dinky".equals(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isCrownPony(LivingEntity entity) {
|
||||||
|
return isBestPony(entity) && entity.getUuid().getLeastSignificantBits() % 20 == 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.minelittlepony.client.render.entity.npc.textures;
|
||||||
|
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.village.VillagerDataContainer;
|
||||||
|
|
||||||
|
public class SillyPonyTextureSupplier<T extends LivingEntity & VillagerDataContainer> implements TextureSupplier<T> {
|
||||||
|
|
||||||
|
private final TextureSupplier<T> fallback;
|
||||||
|
|
||||||
|
private final Identifier egg;
|
||||||
|
private final Identifier egg2;
|
||||||
|
|
||||||
|
public SillyPonyTextureSupplier(TextureSupplier<T> fallback, TextureSupplier<String> formatter) {
|
||||||
|
this.fallback = fallback;
|
||||||
|
this.egg = formatter.apply("silly_pony");
|
||||||
|
this.egg2 = formatter.apply("tiny_silly_pony");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier apply(T entity) {
|
||||||
|
return isBestPony(entity) ? (entity.isBaby() ? egg2 : egg) : fallback.apply(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBestPony(LivingEntity entity) {
|
||||||
|
if (!entity.hasCustomName()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String name = entity.getCustomName().getString();
|
||||||
|
return "Derpy".equals(name) || (entity.isBaby() && "Dinky".equals(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isCrownPony(LivingEntity entity) {
|
||||||
|
return isBestPony(entity) && entity.getUuid().getLeastSignificantBits() % 20 == 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,27 +0,0 @@
|
||||||
package com.minelittlepony.client.render.entity.npc.textures;
|
|
||||||
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.village.VillagerDataContainer;
|
|
||||||
|
|
||||||
public class SillyPonyTextures<T extends LivingEntity & VillagerDataContainer> implements TextureSupplier<T> {
|
|
||||||
|
|
||||||
private final TextureSupplier<T> fallback;
|
|
||||||
|
|
||||||
private final Identifier egg;
|
|
||||||
private final Identifier egg2;
|
|
||||||
|
|
||||||
public SillyPonyTextures(TextureSupplier<T> fallback, TextureSupplier<String> formatter) {
|
|
||||||
this.fallback = fallback;
|
|
||||||
this.egg = formatter.supplyTexture("silly_pony");
|
|
||||||
this.egg2 = formatter.supplyTexture("tiny_silly_pony");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Identifier supplyTexture(T entity) {
|
|
||||||
if (PonyTextures.isBestPony(entity)) {
|
|
||||||
return entity.isBaby() ? egg2 : egg;
|
|
||||||
}
|
|
||||||
return fallback.supplyTexture(entity);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +1,48 @@
|
||||||
package com.minelittlepony.client.render.entity.npc.textures;
|
package com.minelittlepony.client.render.entity.npc.textures;
|
||||||
|
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
import com.minelittlepony.client.MineLittlePony;
|
||||||
|
import com.minelittlepony.util.FunctionUtil;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A texture pool for generating multiple associated textures.
|
* A texture pool for generating multiple associated textures.
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface TextureSupplier<T> {
|
public interface TextureSupplier<T> extends Function<T, Identifier> {
|
||||||
/**
|
/**
|
||||||
* Supplies a new texture. May be generated for returned from a pool indexed by the given key.
|
* Supplies a new texture. May be generated for returned from a pool indexed by the given key.
|
||||||
*/
|
*/
|
||||||
Identifier supplyTexture(T key);
|
@Override
|
||||||
|
Identifier apply(T key);
|
||||||
|
|
||||||
static TextureSupplier<String> formatted(String domain, String path) {
|
static TextureSupplier<String> formatted(String domain, String path) {
|
||||||
return key -> new Identifier(domain, String.format(path, key));
|
return key -> new Identifier(domain, String.format(path, key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static <T extends LivingEntity> TextureSupplier<T> ofPool(Identifier poolId, TextureSupplier<T> fallback) {
|
||||||
|
final Function<T, Identifier> cache = FunctionUtil.memoize(entity -> {
|
||||||
|
return MineLittlePony.getInstance().getVariatedTextures()
|
||||||
|
.get(poolId)
|
||||||
|
.getByName(entity.getCustomName().getString(), entity.getUuid())
|
||||||
|
.orElse(null);
|
||||||
|
}, entity -> entity.getCustomName().getString() + "_" + entity.getUuidAsString());
|
||||||
|
return entity -> {
|
||||||
|
Identifier override = entity.hasCustomName() ? cache.apply(entity) : null;
|
||||||
|
if (override != null) {
|
||||||
|
return override;
|
||||||
|
}
|
||||||
|
return fallback.apply(entity);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static <A> TextureSupplier<A> memoize(Function<A, Identifier> func, Function<A, String> keyFunc) {
|
||||||
|
final Map<String, Identifier> cache = new ConcurrentHashMap<>();
|
||||||
|
return a -> cache.computeIfAbsent(keyFunc.apply(a), k -> func.apply(a));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
12
src/main/java/com/minelittlepony/util/FunctionUtil.java
Normal file
12
src/main/java/com/minelittlepony/util/FunctionUtil.java
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package com.minelittlepony.util;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public interface FunctionUtil {
|
||||||
|
static <A, B> Function<A, B> memoize(Function<A, B> func, Function<A, String> keyFunc) {
|
||||||
|
final Map<String, B> cache = new ConcurrentHashMap<>();
|
||||||
|
return a -> cache.computeIfAbsent(keyFunc.apply(a), k -> func.apply(a));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue