mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 13:37:58 +01:00
Added Trinkets support
This commit is contained in:
parent
0e74cc6bbe
commit
32a23a6ca5
24 changed files with 445 additions and 136 deletions
10
build.gradle
10
build.gradle
|
@ -39,6 +39,14 @@ repositories {
|
|||
name = 'minelp-release'
|
||||
url = 'https://repo.minelittlepony-mod.com/maven/release'
|
||||
}
|
||||
maven {
|
||||
name = "TerraformersMC"
|
||||
url = "https://maven.terraformersmc.com/"
|
||||
}
|
||||
maven {
|
||||
name = "Ladysnake Libs"
|
||||
url = "https://ladysnake.jfrog.io/artifactory/mods"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
@ -55,6 +63,8 @@ dependencies {
|
|||
modCompileOnly("com.terraformersmc:modmenu:${project.modmenu_version}")
|
||||
// implementation 'org.jetbrains:intellij-fernflower:1.2.1.16'
|
||||
modCompileOnly("net.caffienemc.sodium:sodium-fabric-mc1.19.2:0.4.4+build.18")
|
||||
|
||||
modCompileOnly "dev.emi:trinkets:3.4.0"
|
||||
}
|
||||
|
||||
processResources {
|
||||
|
|
|
@ -10,7 +10,7 @@ import com.minelittlepony.unicopia.ability.data.Hit;
|
|||
import com.minelittlepony.unicopia.ability.data.Pos;
|
||||
import com.minelittlepony.unicopia.ability.data.tree.TreeType;
|
||||
import com.minelittlepony.unicopia.block.data.BlockDestructionManager;
|
||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPConnector;
|
||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPDelegate;
|
||||
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
|
@ -54,7 +54,7 @@ public class EarthPonyKickAbility implements Ability<Pos> {
|
|||
|
||||
@Override
|
||||
public double getCostEstimate(Pony player) {
|
||||
double distance = MineLPConnector.getPlayerPonyRace(player.getMaster()).isDefault() ? 6 : -6;
|
||||
double distance = MineLPDelegate.getInstance().getPlayerPonyRace(player.getMaster()).isDefault() ? 6 : -6;
|
||||
|
||||
return RayTraceHelper.doTrace(player.getMaster(), distance, 1)
|
||||
.getBlockPos()
|
||||
|
@ -65,7 +65,7 @@ public class EarthPonyKickAbility implements Ability<Pos> {
|
|||
@Nullable
|
||||
@Override
|
||||
public Pos tryActivate(Pony player) {
|
||||
double distance = MineLPConnector.getPlayerPonyRace(player.getMaster()).isDefault() ? 6 : -6;
|
||||
double distance = MineLPDelegate.getInstance().getPlayerPonyRace(player.getMaster()).isDefault() ? 6 : -6;
|
||||
|
||||
return RayTraceHelper.doTrace(player.getMaster(), distance, 1)
|
||||
.getBlockPos()
|
||||
|
@ -76,7 +76,7 @@ public class EarthPonyKickAbility implements Ability<Pos> {
|
|||
|
||||
private Pos getDefaultKickLocation(Pony player) {
|
||||
Vec3d kickVector = player.getMaster().getRotationVector().multiply(1, 0, 1);
|
||||
if (!MineLPConnector.getPlayerPonyRace(player.getMaster()).isDefault()) {
|
||||
if (!MineLPDelegate.getInstance().getPlayerPonyRace(player.getMaster()).isDefault()) {
|
||||
kickVector = kickVector.rotateY((float)Math.PI);
|
||||
}
|
||||
return new Pos(new BlockPos(player.getOriginVector().add(kickVector)));
|
||||
|
|
|
@ -11,7 +11,7 @@ import com.minelittlepony.unicopia.Unicopia;
|
|||
import com.minelittlepony.unicopia.client.gui.LanSettingsScreen;
|
||||
import com.minelittlepony.unicopia.client.gui.UHud;
|
||||
import com.minelittlepony.unicopia.client.gui.spellbook.SpellbookScreen;
|
||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPConnector;
|
||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPDelegate;
|
||||
import com.minelittlepony.unicopia.container.*;
|
||||
import com.minelittlepony.unicopia.entity.player.PlayerCamera;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
@ -41,7 +41,7 @@ public class UnicopiaClient implements ClientModInitializer {
|
|||
public static Race getPreferredRace() {
|
||||
if (!Unicopia.getConfig().ignoreMineLP.get()
|
||||
&& MinecraftClient.getInstance().player != null) {
|
||||
Race race = MineLPConnector.getPlayerPonyRace();
|
||||
Race race = MineLPDelegate.getInstance().getPlayerPonyRace();
|
||||
|
||||
if (!race.isDefault()) {
|
||||
return race;
|
||||
|
|
|
@ -7,7 +7,7 @@ import com.minelittlepony.common.client.gui.ScrollContainer;
|
|||
import com.minelittlepony.common.client.gui.element.*;
|
||||
import com.minelittlepony.common.client.gui.style.Style;
|
||||
import com.minelittlepony.unicopia.*;
|
||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPConnector;
|
||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPDelegate;
|
||||
import com.minelittlepony.unicopia.util.RegistryIndexer;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
@ -97,7 +97,7 @@ public class SettingsScreen extends GameGui {
|
|||
return Text.translatable("unicopia.options.ignore_mine_lp.undetected").formatted(Formatting.DARK_GREEN);
|
||||
}
|
||||
|
||||
return Text.translatable("unicopia.options.ignore_mine_lp.detected", MineLPConnector.getPlayerPonyRace().getDisplayName()).formatted(Formatting.GREEN);
|
||||
return Text.translatable("unicopia.options.ignore_mine_lp.detected", MineLPDelegate.getInstance().getPlayerPonyRace().getDisplayName()).formatted(Formatting.GREEN);
|
||||
}
|
||||
|
||||
return Text.translatable("unicopia.options.ignore_mine_lp.missing").formatted(Formatting.RED);
|
||||
|
|
|
@ -1,26 +1,33 @@
|
|||
package com.minelittlepony.unicopia.client.minelittlepony;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.minelittlepony.api.model.IModel;
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.api.model.fabric.PonyModelPrepareCallback;
|
||||
import com.minelittlepony.api.model.gear.IGear;
|
||||
import com.minelittlepony.unicopia.Owned;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.client.render.LevitatingItemRenderer;
|
||||
import com.minelittlepony.unicopia.*;
|
||||
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.util.AnimationUtil;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class Main implements ClientModInitializer {
|
||||
public class Main extends MineLPDelegate implements ClientModInitializer {
|
||||
|
||||
private boolean hookErroring;
|
||||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
INSTANCE = this;
|
||||
PonyModelPrepareCallback.EVENT.register(this::onPonyModelPrepared);
|
||||
IGear.register(BangleGear::new);
|
||||
IGear.register(AmuletGear::new);
|
||||
|
@ -52,4 +59,39 @@ public class Main implements ClientModInitializer {
|
|||
hookErroring = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Race getPlayerPonyRace(PlayerEntity player) {
|
||||
switch (MineLittlePony.getInstance().getManager().getPony(player).getRace(false)) {
|
||||
case ALICORN:
|
||||
return Race.ALICORN;
|
||||
case CHANGELING:
|
||||
case CHANGEDLING:
|
||||
return Race.CHANGELING;
|
||||
case ZEBRA:
|
||||
case EARTH:
|
||||
return Race.EARTH;
|
||||
case GRYPHON:
|
||||
case HIPPOGRIFF:
|
||||
case PEGASUS:
|
||||
return Race.PEGASUS;
|
||||
case BATPONY:
|
||||
return Race.BAT;
|
||||
case SEAPONY:
|
||||
case UNICORN:
|
||||
return Race.UNICORN;
|
||||
default:
|
||||
return Race.HUMAN;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<VertexConsumer> getItemBuffer(VertexConsumerProvider vertexConsumers, Identifier texture) {
|
||||
if (LevitatingItemRenderer.isEnabled()) {
|
||||
return Optional.of(vertexConsumers.getBuffer(LevitatingItemRenderer.getRenderLayer(texture)));
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
package com.minelittlepony.unicopia.client.minelittlepony;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.client.render.LevitatingItemRenderer;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public final class MineLPConnector {
|
||||
public static Race getPlayerPonyRace() {
|
||||
return getPlayerPonyRace(MinecraftClient.getInstance().player);
|
||||
}
|
||||
|
||||
public static Race getPlayerPonyRace(PlayerEntity player) {
|
||||
if (!FabricLoader.getInstance().isModLoaded("minelp") || player == null) {
|
||||
return Race.HUMAN;
|
||||
}
|
||||
|
||||
switch (MineLittlePony.getInstance().getManager().getPony(player).getRace(false)) {
|
||||
case ALICORN:
|
||||
return Race.ALICORN;
|
||||
case CHANGELING:
|
||||
case CHANGEDLING:
|
||||
return Race.CHANGELING;
|
||||
case ZEBRA:
|
||||
case EARTH:
|
||||
return Race.EARTH;
|
||||
case GRYPHON:
|
||||
case HIPPOGRIFF:
|
||||
case PEGASUS:
|
||||
return Race.PEGASUS;
|
||||
case BATPONY:
|
||||
return Race.BAT;
|
||||
case SEAPONY:
|
||||
case UNICORN:
|
||||
return Race.UNICORN;
|
||||
default:
|
||||
return Race.HUMAN;
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<VertexConsumer> getItemBuffer(VertexConsumerProvider vertexConsumers, Identifier texture) {
|
||||
if (!FabricLoader.getInstance().isModLoaded("minelp")) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (LevitatingItemRenderer.isEnabled()) {
|
||||
return Optional.of(vertexConsumers.getBuffer(LevitatingItemRenderer.getRenderLayer(texture)));
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.minelittlepony.unicopia.client.minelittlepony;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class MineLPDelegate {
|
||||
static MineLPDelegate INSTANCE = new MineLPDelegate();
|
||||
|
||||
public static MineLPDelegate getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public final Race getPlayerPonyRace() {
|
||||
return getPlayerPonyRace(MinecraftClient.getInstance().player);
|
||||
}
|
||||
|
||||
public Race getPlayerPonyRace(PlayerEntity player) {
|
||||
return Race.HUMAN;
|
||||
}
|
||||
|
||||
public Optional<VertexConsumer> getItemBuffer(VertexConsumerProvider vertexConsumers, Identifier texture) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
|
@ -21,7 +21,6 @@ import net.minecraft.client.render.entity.feature.FeatureRendererContext;
|
|||
import net.minecraft.client.render.entity.model.BipedEntityModel;
|
||||
import net.minecraft.client.render.item.ItemRenderer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
@ -43,9 +42,9 @@ public class AmuletFeatureRenderer<E extends LivingEntity> implements AccessoryF
|
|||
@Override
|
||||
public void render(MatrixStack matrices, VertexConsumerProvider renderContext, int lightUv, E entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) {
|
||||
|
||||
ItemStack stack = entity.getEquippedStack(EquipmentSlot.CHEST);
|
||||
ItemStack stack = AmuletItem.getForEntity(entity);
|
||||
|
||||
if (stack.getItem() instanceof AmuletItem) {
|
||||
if (!stack.isEmpty()) {
|
||||
Identifier texture = textures.computeIfAbsent(Registry.ITEM.getId(stack.getItem()), id -> new Identifier(id.getNamespace(), "textures/models/armor/" + id.getPath() + ".png"));
|
||||
|
||||
VertexConsumer consumer = ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayer.getArmorCutoutNoCull(texture), false, false);
|
||||
|
|
|
@ -2,9 +2,9 @@ package com.minelittlepony.unicopia.client.render;
|
|||
|
||||
import com.minelittlepony.common.util.Color;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPConnector;
|
||||
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||
import com.minelittlepony.unicopia.item.GlowableItem;
|
||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPDelegate;
|
||||
import com.minelittlepony.unicopia.item.*;
|
||||
import com.minelittlepony.unicopia.trinkets.TrinketsDelegate;
|
||||
|
||||
import net.minecraft.client.model.Dilation;
|
||||
import net.minecraft.client.model.Model;
|
||||
|
@ -24,13 +24,11 @@ import net.minecraft.client.render.entity.model.BipedEntityModel;
|
|||
import net.minecraft.client.render.entity.model.EntityModelPartNames;
|
||||
import net.minecraft.client.render.item.ItemRenderer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.decoration.ArmorStandEntity;
|
||||
import net.minecraft.item.DyeableItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Arm;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.*;
|
||||
|
||||
public class BraceletFeatureRenderer<E extends LivingEntity> implements AccessoryFeatureRenderer.Feature<E> {
|
||||
|
||||
|
@ -50,16 +48,21 @@ public class BraceletFeatureRenderer<E extends LivingEntity> implements Accessor
|
|||
|
||||
@Override
|
||||
public void render(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, E entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) {
|
||||
ItemStack item = entity.getEquippedStack(EquipmentSlot.CHEST);
|
||||
FriendshipBraceletItem.getWornBangles(entity, TrinketsDelegate.MAINHAND).findFirst().ifPresent(bangle -> {
|
||||
renderBangleThirdPerson(bangle, stack, renderContext, lightUv, entity, limbDistance, limbAngle, tickDelta, age, headYaw, headPitch, entity.getMainArm());
|
||||
});
|
||||
FriendshipBraceletItem.getWornBangles(entity, TrinketsDelegate.OFFHAND).findFirst().ifPresent(bangle -> {
|
||||
renderBangleThirdPerson(bangle, stack, renderContext, lightUv, entity, limbDistance, limbAngle, tickDelta, age, headYaw, headPitch, entity.getMainArm().getOpposite());
|
||||
});
|
||||
}
|
||||
|
||||
if (item.getItem() instanceof FriendshipBraceletItem) {
|
||||
private void renderBangleThirdPerson(ItemStack item, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, E entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch, Arm mainArm) {
|
||||
int j = ((DyeableItem)item.getItem()).getColor(item);
|
||||
|
||||
boolean alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).getModel().startsWith("slim");
|
||||
|
||||
BraceletModel model = alex ? alexModel : steveModel;
|
||||
|
||||
boolean isLeft = entity.getMainArm() == Arm.LEFT;
|
||||
boolean isLeft = mainArm == Arm.LEFT;
|
||||
|
||||
if (entity instanceof ArmorStandEntity) {
|
||||
ModelPart arm = isLeft ? context.getModel().leftArm : context.getModel().rightArm;
|
||||
|
@ -73,16 +76,13 @@ public class BraceletFeatureRenderer<E extends LivingEntity> implements Accessor
|
|||
VertexConsumer consumer = ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayer.getArmorCutoutNoCull(TEXTURE), false, false);
|
||||
|
||||
model.setAngles(context.getModel());
|
||||
model.setVisible(entity.getMainArm());
|
||||
model.setVisible(mainArm);
|
||||
model.render(stack, consumer, glowing ? 0x0F00F0 : lightUv, OverlayTexture.DEFAULT_UV, Color.r(j), Color.g(j), Color.b(j), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, E entity, ModelPart armModel, Arm side) {
|
||||
ItemStack item = entity.getEquippedStack(EquipmentSlot.CHEST);
|
||||
|
||||
if (item.getItem() instanceof FriendshipBraceletItem) {
|
||||
FriendshipBraceletItem.getWornBangles(entity, side == entity.getMainArm() ? TrinketsDelegate.MAINHAND : TrinketsDelegate.OFFHAND).findFirst().ifPresent(item -> {
|
||||
int j = ((DyeableItem)item.getItem()).getColor(item);
|
||||
|
||||
boolean alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).getModel().startsWith("slim");
|
||||
|
@ -91,8 +91,7 @@ public class BraceletFeatureRenderer<E extends LivingEntity> implements Accessor
|
|||
|
||||
boolean glowing = ((GlowableItem)item.getItem()).isGlowing(item);
|
||||
|
||||
|
||||
if (!MineLPConnector.getPlayerPonyRace((ClientPlayerEntity)entity).isDefault()) {
|
||||
if (!MineLPDelegate.getInstance().getPlayerPonyRace((ClientPlayerEntity)entity).isDefault()) {
|
||||
stack.translate(side == Arm.LEFT ? 0.06 : -0.06, 0.3, 0);
|
||||
} else {
|
||||
stack.translate(0, -0.1, 0);
|
||||
|
@ -103,7 +102,7 @@ public class BraceletFeatureRenderer<E extends LivingEntity> implements Accessor
|
|||
model.setAngles(context.getModel());
|
||||
model.setVisible(side);
|
||||
model.render(stack, consumer, glowing ? 0x0F00F0 : lightUv, OverlayTexture.DEFAULT_UV, Color.r(j), Color.g(j), Color.b(j), 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static class BraceletModel extends Model {
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.client.render;
|
|||
import java.util.Optional;
|
||||
|
||||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPConnector;
|
||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPDelegate;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.util.AnimationUtil;
|
||||
|
||||
|
@ -24,7 +24,7 @@ public class PlayerPoser {
|
|||
Pony pony = Pony.of(player);
|
||||
float progress = pony.getAnimationProgress(MinecraftClient.getInstance().getTickDelta());
|
||||
Animation animation = pony.getAnimation();
|
||||
boolean isPony = !MineLPConnector.getPlayerPonyRace(player).isDefault();
|
||||
boolean isPony = !MineLPDelegate.getInstance().getPlayerPonyRace(player).isDefault();
|
||||
|
||||
switch (animation) {
|
||||
case WOLOLO: {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.minelittlepony.unicopia.client.render;
|
||||
|
||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPConnector;
|
||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPDelegate;
|
||||
|
||||
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry;
|
||||
|
@ -70,7 +70,7 @@ public class PolearmRenderer implements DynamicItemRenderer, UnclampedModelPredi
|
|||
matrices.scale(1, -1, -1);
|
||||
Identifier id = Registry.ITEM.getId(stack.getItem());
|
||||
Identifier texture = new Identifier(id.getNamespace(), "textures/entity/polearm/" + id.getPath() + ".png");
|
||||
model.render(matrices, MineLPConnector.getItemBuffer(vertexConsumers, texture).orElseGet(() -> {
|
||||
model.render(matrices, MineLPDelegate.getInstance().getItemBuffer(vertexConsumers, texture).orElseGet(() -> {
|
||||
return ItemRenderer.getDirectItemGlintConsumer(vertexConsumers, model.getLayer(texture), false, stack.hasGlint());
|
||||
}), light, overlay, 1, 1, 1, 1);
|
||||
matrices.pop();
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.minelittlepony.unicopia.ability.magic.Affine;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
||||
import com.minelittlepony.unicopia.trinkets.TrinketsDelegate;
|
||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||
import com.minelittlepony.unicopia.util.Tickable;
|
||||
|
||||
|
@ -43,7 +44,17 @@ public class PlayerCharmTracker implements Tickable, NbtSerialisable {
|
|||
|
||||
@Override
|
||||
public void tick() {
|
||||
armour.update(pony.getMaster().getInventory().armor.stream());
|
||||
armour.update(getAll());
|
||||
}
|
||||
|
||||
private Stream<ItemStack> getAll() {
|
||||
if (!TrinketsDelegate.hasTrinkets()) {
|
||||
return pony.getMaster().getInventory().armor.stream();
|
||||
}
|
||||
return Stream.concat(
|
||||
TrinketsDelegate.getInstance().getEquipped(pony.getMaster(), TrinketsDelegate.NECKLACE),
|
||||
pony.getMaster().getInventory().armor.stream()
|
||||
);
|
||||
}
|
||||
|
||||
public ItemTracker getArmour() {
|
||||
|
|
|
@ -201,7 +201,7 @@ public class AlicornAmuletItem extends AmuletItem implements PlayerCharmTracker.
|
|||
}, 50);
|
||||
}
|
||||
|
||||
pony.findAllEntitiesInRange(10, e -> e instanceof MobEntity && !((MobEntity)e).hasStatusEffect(UEffects.CORRUPT_INFLUENCE)).forEach(e -> {
|
||||
pony.findAllEntitiesInRange(10, e -> e instanceof MobEntity mob && !mob.hasStatusEffect(UEffects.CORRUPT_INFLUENCE)).forEach(e -> {
|
||||
((MobEntity)e).addStatusEffect(new StatusEffectInstance(UEffects.CORRUPT_INFLUENCE, 1300, 1));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
import com.minelittlepony.unicopia.trinkets.TrinketsDelegate;
|
||||
|
||||
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
@ -99,7 +100,14 @@ public class AmuletItem extends WearableItem {
|
|||
}
|
||||
|
||||
public boolean isApplicable(LivingEntity entity) {
|
||||
return isApplicable(entity.getEquippedStack(EquipmentSlot.CHEST));
|
||||
return isApplicable(getForEntity(entity));
|
||||
}
|
||||
|
||||
public static ItemStack getForEntity(LivingEntity entity) {
|
||||
return TrinketsDelegate.getInstance().getEquipped(entity, TrinketsDelegate.NECKLACE)
|
||||
.filter(stack -> stack.getItem() instanceof AmuletItem)
|
||||
.findFirst()
|
||||
.orElse(ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
public boolean isChargable() {
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.minelittlepony.unicopia.EquinePredicates;
|
|||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.trinkets.TrinketsDelegate;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
@ -23,9 +24,7 @@ import net.minecraft.item.DyeableItem;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.stat.Stats;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class FriendshipBraceletItem extends WearableItem implements DyeableItem, GlowableItem {
|
||||
|
@ -115,10 +114,11 @@ public class FriendshipBraceletItem extends WearableItem implements DyeableItem,
|
|||
|
||||
public static boolean isComrade(Caster<?> caster, Entity entity) {
|
||||
if (entity instanceof LivingEntity) {
|
||||
return caster.getMasterId().filter(id -> {
|
||||
return isSignedBy(((LivingEntity)entity).getOffHandStack(), id)
|
||||
|| isSignedBy(((LivingEntity)entity).getEquippedStack(EquipmentSlot.CHEST), id);
|
||||
}).isPresent();
|
||||
return caster.getMasterId()
|
||||
.filter(id -> getWornBangles((LivingEntity)entity)
|
||||
.anyMatch(stack -> isSignedBy(stack, id))
|
||||
)
|
||||
.isPresent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -126,4 +126,16 @@ public class FriendshipBraceletItem extends WearableItem implements DyeableItem,
|
|||
public static Stream<Pony> getPartyMembers(Caster<?> caster, double radius) {
|
||||
return Pony.stream(caster.findAllEntitiesInRange(radius, entity -> isComrade(caster, entity)));
|
||||
}
|
||||
|
||||
public static Stream<ItemStack> getWornBangles(LivingEntity entity) {
|
||||
return Stream.concat(
|
||||
TrinketsDelegate.getInstance().getEquipped(entity, TrinketsDelegate.MAINHAND),
|
||||
TrinketsDelegate.getInstance().getEquipped(entity, TrinketsDelegate.OFFHAND)
|
||||
).filter(stack -> stack.getItem() == UItems.FRIENDSHIP_BRACELET);
|
||||
}
|
||||
|
||||
public static Stream<ItemStack> getWornBangles(LivingEntity entity, Identifier slot) {
|
||||
return TrinketsDelegate.getInstance().getEquipped(entity, slot)
|
||||
.filter(stack -> stack.getItem() == UItems.FRIENDSHIP_BRACELET);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package com.minelittlepony.unicopia.item;
|
||||
|
||||
import com.minelittlepony.unicopia.trinkets.TrinketsDelegate;
|
||||
|
||||
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
||||
import net.minecraft.block.DispenserBlock;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ArmorItem;
|
||||
import net.minecraft.item.ArmorMaterials;
|
||||
|
@ -18,26 +19,26 @@ import net.minecraft.world.World;
|
|||
public abstract class WearableItem extends Item implements Wearable {
|
||||
|
||||
public WearableItem(FabricItemSettings settings) {
|
||||
super(settings.equipmentSlot(s -> ((WearableItem)s.getItem()).getPreferredSlot(s)));
|
||||
super(configureEquipmentSlotSupplier(settings));
|
||||
DispenserBlock.registerBehavior(this, ArmorItem.DISPENSER_BEHAVIOR);
|
||||
TrinketsDelegate.getInstance().registerTrinket(this);
|
||||
}
|
||||
|
||||
private static FabricItemSettings configureEquipmentSlotSupplier(FabricItemSettings settings) {
|
||||
if (TrinketsDelegate.hasTrinkets()) {
|
||||
return settings;
|
||||
}
|
||||
return settings.equipmentSlot(s -> ((WearableItem)s.getItem()).getPreferredSlot(s));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) {
|
||||
ItemStack stack = player.getStackInHand(hand);
|
||||
|
||||
EquipmentSlot slot = MobEntity.getPreferredEquipmentSlot(stack);
|
||||
ItemStack currentArmor = player.getEquippedStack(slot);
|
||||
|
||||
if (currentArmor.isEmpty()) {
|
||||
ItemStack result = stack.copy();
|
||||
result.setCount(1);
|
||||
player.equipStack(slot, result);
|
||||
stack.decrement(1);
|
||||
return TypedActionResult.success(stack, world.isClient());
|
||||
}
|
||||
|
||||
return TypedActionResult.fail(stack);
|
||||
return TrinketsDelegate.getInstance().getAvailableTrinketSlots(player, TrinketsDelegate.ALL).stream()
|
||||
.findAny()
|
||||
.filter(slotId -> TrinketsDelegate.getInstance().equipStack(player, slotId, stack))
|
||||
.map(slotId -> TypedActionResult.success(stack, world.isClient()))
|
||||
.orElseGet(() -> TypedActionResult.fail(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package com.minelittlepony.unicopia.trinkets;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public interface TrinketsDelegate {
|
||||
Identifier MAINHAND = new Identifier("hand:glove");
|
||||
Identifier OFFHAND = new Identifier("offhand:glove");
|
||||
Identifier NECKLACE = new Identifier("chest:necklace");
|
||||
|
||||
Set<Identifier> ALL = new TreeSet<>(List.of(MAINHAND, OFFHAND, NECKLACE));
|
||||
|
||||
TrinketsDelegate EMPTY = new TrinketsDelegate() {};
|
||||
|
||||
static TrinketsDelegate getInstance() {
|
||||
if (!hasTrinkets()) {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
return TrinketsDelegateImpl.INSTANCE;
|
||||
}
|
||||
|
||||
static boolean hasTrinkets() {
|
||||
return FabricLoader.getInstance().isModLoaded("trinkets");
|
||||
}
|
||||
|
||||
default boolean equipStack(LivingEntity entity, Identifier slot, ItemStack stack) {
|
||||
EquipmentSlot eq = MobEntity.getPreferredEquipmentSlot(stack);
|
||||
if (!entity.getEquippedStack(eq).isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
entity.equipStack(eq, stack.split(1));
|
||||
return true;
|
||||
}
|
||||
|
||||
default Set<Identifier> getAvailableTrinketSlots(LivingEntity entity, Set<Identifier> probedSlots) {
|
||||
return Set.of();
|
||||
}
|
||||
|
||||
default Stream<ItemStack> getEquipped(LivingEntity entity) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
default Stream<ItemStack> getEquipped(LivingEntity entity, Identifier slot) {
|
||||
|
||||
if (slot == NECKLACE || slot == MAINHAND) {
|
||||
return Stream.of(entity.getEquippedStack(EquipmentSlot.CHEST));
|
||||
}
|
||||
if (slot == OFFHAND) {
|
||||
return Stream.of(entity.getOffHandStack());
|
||||
}
|
||||
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
default void registerTrinket(Item item) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.minelittlepony.unicopia.trinkets;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.minelittlepony.unicopia.util.InventoryUtil;
|
||||
|
||||
import dev.emi.trinkets.TrinketSlot;
|
||||
import dev.emi.trinkets.api.*;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.world.event.GameEvent;
|
||||
|
||||
class TrinketsDelegateImpl implements TrinketsDelegate {
|
||||
static final TrinketsDelegateImpl INSTANCE = new TrinketsDelegateImpl();
|
||||
// who tf designed this api?
|
||||
|
||||
@Override
|
||||
public boolean equipStack(LivingEntity entity, Identifier slot, ItemStack stack) {
|
||||
return getInventory(entity, slot).map(inventory -> {
|
||||
for (int position = 0; position < inventory.size(); position++) {
|
||||
if (inventory.getStack(position).isEmpty() && TrinketSlot.canInsert(stack, new SlotReference(inventory, position), entity)) {
|
||||
SoundEvent soundEvent = stack.getEquipSound();
|
||||
inventory.setStack(position, stack.split(1));
|
||||
if (soundEvent != null) {
|
||||
entity.emitGameEvent(GameEvent.EQUIP);
|
||||
entity.playSound(soundEvent, 1, 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}).orElse(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Identifier> getAvailableTrinketSlots(LivingEntity entity, Set<Identifier> probedSlots) {
|
||||
probedSlots = new HashSet<>(probedSlots);
|
||||
probedSlots.removeAll(getInventories(entity)
|
||||
.filter(inventory -> InventoryUtil.getOpenSlot(inventory) == -1)
|
||||
.map(slot -> slot.getSlotType())
|
||||
.map(TrinketsDelegateImpl::getSlotId)
|
||||
.collect(Collectors.toSet()));
|
||||
return probedSlots;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<ItemStack> getEquipped(LivingEntity entity) {
|
||||
return getInventories(entity).flatMap(InventoryUtil::stream).filter(s -> !s.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<ItemStack> getEquipped(LivingEntity entity, Identifier slot) {
|
||||
return getInventory(entity, slot).stream().flatMap(InventoryUtil::stream).filter(s -> !s.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerTrinket(Item item) {
|
||||
TrinketsApi.registerTrinket(item, new UnicopiaTrinket(item));
|
||||
}
|
||||
|
||||
public Optional<TrinketInventory> getInventory(LivingEntity entity, Identifier slot) {
|
||||
return TrinketsApi.getTrinketComponent(entity)
|
||||
.map(component -> component.getInventory()
|
||||
.getOrDefault(slot.getNamespace(), Map.of())
|
||||
.getOrDefault(slot.getPath(), null)
|
||||
);
|
||||
}
|
||||
|
||||
private Stream<TrinketInventory> getInventories(LivingEntity entity) {
|
||||
return TrinketsApi.getTrinketComponent(entity)
|
||||
.stream()
|
||||
.map(component -> component.getInventory())
|
||||
.flatMap(groups -> groups.values().stream())
|
||||
.flatMap(group -> group.values().stream());
|
||||
}
|
||||
|
||||
private static Identifier getSlotId(SlotType slotType) {
|
||||
return new Identifier(slotType.getGroup(), slotType.getName());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package com.minelittlepony.unicopia.trinkets;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||
import com.minelittlepony.unicopia.item.WearableItem;
|
||||
|
||||
import dev.emi.trinkets.api.*;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.attribute.EntityAttribute;
|
||||
import net.minecraft.entity.attribute.EntityAttributeModifier;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
|
||||
public class UnicopiaTrinket implements Trinket {
|
||||
|
||||
private final Item item;
|
||||
|
||||
public UnicopiaTrinket(Item item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEquip(ItemStack stack, SlotReference slot, LivingEntity entity) {
|
||||
if (entity.isSpectator() || stack.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SoundEvent soundEvent = stack.getEquipSound();
|
||||
if (soundEvent != null) {
|
||||
entity.playSound(soundEvent, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
public int getMaxCount(ItemStack stack, SlotReference slot, LivingEntity entity) {
|
||||
// https://github.com/emilyploszaj/trinkets/issues/215
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEquip(ItemStack stack, SlotReference slot, LivingEntity entity) {
|
||||
if (item instanceof FriendshipBraceletItem && !FriendshipBraceletItem.isSigned(stack)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return slot.inventory().getStack(slot.index()).isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(ItemStack stack, SlotReference slot, LivingEntity entity) {
|
||||
item.inventoryTick(stack, entity.world, entity, slot.index(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Multimap<EntityAttribute, EntityAttributeModifier> getModifiers(ItemStack stack, SlotReference slot, LivingEntity entity, UUID uuid) {
|
||||
Multimap<EntityAttribute, EntityAttributeModifier> modifiers = Trinket.super.getModifiers(stack, slot, entity, uuid);
|
||||
if (item instanceof WearableItem wearable) {
|
||||
item.getAttributeModifiers(wearable.getPreferredSlot(stack));
|
||||
}
|
||||
return modifiers;
|
||||
}
|
||||
}
|
|
@ -13,4 +13,13 @@ public interface InventoryUtil {
|
|||
static Stream<Integer> slots(Inventory inventory) {
|
||||
return Stream.iterate(0, i -> i < inventory.size(), i -> i + 1);
|
||||
}
|
||||
|
||||
static int getOpenSlot(Inventory inventory) {
|
||||
for (int i = 0; i < inventory.size(); i++) {
|
||||
if (inventory.getStack(i).isEmpty()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
10
src/main/resources/data/trinkets/entities/unicopia.json
Normal file
10
src/main/resources/data/trinkets/entities/unicopia.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"entities": [
|
||||
"player"
|
||||
],
|
||||
"slots": [
|
||||
"hand/glove",
|
||||
"offhand/glove",
|
||||
"chest/necklace"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"unicopia:alicorn_amulet",
|
||||
"unicopia:pegasus_amulet"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"unicopia:friendship_bracelet"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"unicopia:friendship_bracelet"
|
||||
]
|
||||
}
|
Loading…
Reference in a new issue