mirror of
https://github.com/TeamMidnightDust/Decorative.git
synced 2025-12-15 12:35:10 +01:00
Enjoy a little Polymer by the Poolside
- Bath Tire and Beach Ball entities are now working with Polymer!
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
package eu.midnightdust.motschen.decorative.entity;
|
||||
|
||||
import eu.midnightdust.motschen.decorative.polymer.entity.ItemDisplayBasedEntity;
|
||||
import eu.pb4.polymer.virtualentity.api.elements.ItemDisplayElement;
|
||||
import net.minecraft.client.render.model.json.ModelTransformationMode;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
@@ -14,10 +17,12 @@ import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public class BathTireEntity extends MobEntity {
|
||||
public class BathTireEntity extends MobEntity implements ItemDisplayBasedEntity {
|
||||
public BathTireEntity(EntityType<? extends BathTireEntity> entityType, World world) {
|
||||
super(entityType, world);
|
||||
this.onCreated(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -26,7 +31,7 @@ public class BathTireEntity extends MobEntity {
|
||||
if (player.isSneaking()) {
|
||||
this.remove(RemovalReason.DISCARDED);
|
||||
System.out.println(Identifier.tryParse(this.getType().getUntranslatedName()));
|
||||
player.setStackInHand(hand, new ItemStack(Registries.ITEM.get(Identifier.tryParse("decorative:" + this.getType().getUntranslatedName()))));
|
||||
player.setStackInHand(hand, getItemStackForType());
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
else if (!player.isSneaking()) {
|
||||
@@ -57,4 +62,25 @@ public class BathTireEntity extends MobEntity {
|
||||
public boolean canWalkOnFluid(FluidState fluid) {
|
||||
return true;
|
||||
}
|
||||
private ItemStack getItemStackForType() {
|
||||
return new ItemStack(Registries.ITEM.get(Identifier.tryParse("decorative:" + this.getType().getUntranslatedName())));
|
||||
}
|
||||
|
||||
// Polymer
|
||||
@Override
|
||||
public ItemStack getVisualItemStack() {
|
||||
return getItemStackForType();
|
||||
}
|
||||
@Override
|
||||
public void setItemDisplayProperties(ItemDisplayElement display) {
|
||||
display.setInvisible(false);
|
||||
display.setModelTransformation(ModelTransformationMode.HEAD);
|
||||
display.setTeleportDuration(3);
|
||||
display.setScale(new Vector3f(1f));
|
||||
display.setTranslation(new Vector3f(0, 0.4f, 0));
|
||||
}
|
||||
@Override
|
||||
public Vec3d getClientSidePosition(Vec3d vec3d) {
|
||||
return vec3d.add(0, -1.5d, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package eu.midnightdust.motschen.decorative.entity;
|
||||
|
||||
import eu.midnightdust.motschen.decorative.init.Pool;
|
||||
import eu.midnightdust.motschen.decorative.polymer.entity.ItemDisplayBasedEntity;
|
||||
import eu.pb4.polymer.virtualentity.api.elements.ItemDisplayElement;
|
||||
import net.minecraft.client.render.model.json.ModelTransformationMode;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
@@ -12,10 +15,12 @@ import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public class BeachBallEntity extends MobEntity {
|
||||
public class BeachBallEntity extends MobEntity implements ItemDisplayBasedEntity {
|
||||
public BeachBallEntity(EntityType<? extends BeachBallEntity> entityType, World world) {
|
||||
super(entityType, world);
|
||||
this.onCreated(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -41,4 +46,25 @@ public class BeachBallEntity extends MobEntity {
|
||||
public boolean canWalkOnFluid(FluidState fluid) {
|
||||
return true;
|
||||
}
|
||||
// Polymer
|
||||
@Override
|
||||
public ItemStack getVisualItemStack() {
|
||||
return new ItemStack(Pool.BEACH_BALL_ITEM);
|
||||
}
|
||||
@Override
|
||||
public void setItemDisplayProperties(ItemDisplayElement display) {
|
||||
display.setInvisible(false);
|
||||
display.setModelTransformation(ModelTransformationMode.HEAD);
|
||||
display.setTeleportDuration(3);
|
||||
display.setScale(new Vector3f(1f));
|
||||
display.setTranslation(new Vector3f(0, -0.4f, 0));
|
||||
}
|
||||
@Override
|
||||
public Vec3d getClientSidePosition(Vec3d vec3d) {
|
||||
return vec3d.add(0, 0.25d, 0);
|
||||
}
|
||||
@Override
|
||||
public boolean isSmall() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,12 @@ package eu.midnightdust.motschen.decorative.item;
|
||||
|
||||
import eu.pb4.factorytools.api.item.AutoModeledPolymerItem;
|
||||
import net.minecraft.block.FluidBlock;
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.SpawnReason;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.stat.Stats;
|
||||
import net.minecraft.util.Hand;
|
||||
@@ -21,7 +19,7 @@ import net.minecraft.world.RaycastContext;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BathTireItem extends Item implements AutoModeledPolymerItem {
|
||||
private final EntityType<?> type;
|
||||
public final EntityType<?> type;
|
||||
|
||||
public BathTireItem(EntityType<?> type, Item.Settings settings) {
|
||||
super(settings);
|
||||
@@ -41,8 +39,7 @@ public class BathTireItem extends Item implements AutoModeledPolymerItem {
|
||||
if (!(world.getBlockState(blockPos).getBlock() instanceof FluidBlock)) {
|
||||
return TypedActionResult.pass(itemStack);
|
||||
} else if (world.canPlayerModifyAt(user, blockPos) && user.canPlaceOn(blockPos, hitResult.getSide(), itemStack)) {
|
||||
EntityType<?> entityType = this.getEntityType(itemStack.getComponents().get(DataComponentTypes.ENTITY_DATA).copyNbt());
|
||||
if (entityType.spawnFromItemStack((ServerWorld) world, itemStack, user, blockPos.up(1), SpawnReason.SPAWN_EGG, false, false) == null) {
|
||||
if (this.type.spawnFromItemStack((ServerWorld) world, itemStack, user, blockPos.up(1), SpawnReason.SPAWN_EGG, false, false) == null) {
|
||||
return TypedActionResult.pass(itemStack);
|
||||
} else {
|
||||
if (!user.getAbilities().creativeMode) {
|
||||
@@ -58,17 +55,6 @@ public class BathTireItem extends Item implements AutoModeledPolymerItem {
|
||||
}
|
||||
}
|
||||
|
||||
public EntityType<?> getEntityType(NbtCompound tag) {
|
||||
if (tag != null && tag.contains("EntityTag", 10)) {
|
||||
NbtCompound compoundTag = tag.getCompound("EntityTag");
|
||||
if (compoundTag.contains("id", 8)) {
|
||||
return EntityType.get(compoundTag.getString("id")).orElse(this.type);
|
||||
}
|
||||
}
|
||||
|
||||
return this.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getPolymerItem() {
|
||||
return Items.DRIED_KELP;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package eu.midnightdust.motschen.decorative.mixin;
|
||||
|
||||
import net.minecraft.entity.data.TrackedData;
|
||||
import net.minecraft.entity.decoration.ArmorStandEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(ArmorStandEntity.class)
|
||||
public interface ArmorStandEntityAccessor {
|
||||
@Accessor
|
||||
static TrackedData<Byte> getARMOR_STAND_FLAGS() {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package eu.midnightdust.motschen.decorative.polymer.entity;
|
||||
|
||||
import eu.midnightdust.motschen.decorative.mixin.ArmorStandEntityAccessor;
|
||||
import eu.pb4.polymer.core.api.entity.PolymerEntity;
|
||||
import eu.pb4.polymer.virtualentity.api.ElementHolder;
|
||||
import eu.pb4.polymer.virtualentity.api.VirtualEntityUtils;
|
||||
import eu.pb4.polymer.virtualentity.api.attachment.EntityAttachment;
|
||||
import eu.pb4.polymer.virtualentity.api.elements.ItemDisplayElement;
|
||||
import eu.pb4.polymer.virtualentity.api.tracker.EntityTrackedData;
|
||||
import net.minecraft.client.render.model.json.ModelTransformationMode;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.data.DataTracker;
|
||||
import net.minecraft.entity.data.TrackedData;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
public interface ItemDisplayBasedEntity extends PolymerEntity {
|
||||
WeakHashMap<LivingEntity, ItemDisplayElement> DISPLAY_ELEMENTS = new WeakHashMap<>();
|
||||
|
||||
ItemStack getVisualItemStack();
|
||||
|
||||
// This needs to be called on entity init
|
||||
default void onCreated(LivingEntity entity) {
|
||||
ElementHolder holder = new ElementHolder();
|
||||
|
||||
ItemDisplayElement display = initDisplayEntity();
|
||||
holder.addElement(display);
|
||||
DISPLAY_ELEMENTS.put(entity, display);
|
||||
|
||||
EntityAttachment.of(holder, entity);
|
||||
VirtualEntityUtils.addVirtualPassenger(entity, display.getEntityId());
|
||||
}
|
||||
default ItemDisplayElement initDisplayEntity() {
|
||||
ItemDisplayElement display = new ItemDisplayElement(getVisualItemStack());
|
||||
setItemDisplayProperties(display);
|
||||
return display;
|
||||
}
|
||||
default void setItemDisplayProperties(ItemDisplayElement display) {
|
||||
display.setInvisible(false);
|
||||
display.setModelTransformation(ModelTransformationMode.HEAD);
|
||||
display.setTeleportDuration(3);
|
||||
display.setScale(new Vector3f(1f));
|
||||
}
|
||||
default boolean isSmall() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
default float getClientSideYaw(float yaw) {
|
||||
if (DISPLAY_ELEMENTS.containsKey((LivingEntity) this)) {
|
||||
DISPLAY_ELEMENTS.get((LivingEntity) this).setYaw(yaw);
|
||||
}
|
||||
return yaw;
|
||||
}
|
||||
|
||||
@Override
|
||||
default float getClientSidePitch(float pitch) {
|
||||
if (DISPLAY_ELEMENTS.containsKey((LivingEntity) this)) {
|
||||
DISPLAY_ELEMENTS.get((LivingEntity) this).setPitch(pitch);
|
||||
}
|
||||
return pitch;
|
||||
}
|
||||
|
||||
@Override
|
||||
default EntityType<?> getPolymerEntityType(ServerPlayerEntity player) {
|
||||
return EntityType.ARMOR_STAND;
|
||||
}
|
||||
@Override
|
||||
default void modifyRawTrackedData(List<DataTracker.SerializedEntry<?>> data, ServerPlayerEntity player, boolean initial) {
|
||||
setInvisible(data, true);
|
||||
if (isSmall()) data.add(DataTracker.SerializedEntry.of(ArmorStandEntityAccessor.getARMOR_STAND_FLAGS(), (byte) (0b00000011)));
|
||||
}
|
||||
|
||||
static void setInvisible(List<DataTracker.SerializedEntry<?>> data, boolean invisible) {
|
||||
setFlag(data, EntityTrackedData.FLAGS, EntityTrackedData.INVISIBLE_FLAG_INDEX, invisible);
|
||||
}
|
||||
static void setFlag(List<DataTracker.SerializedEntry<?>> data, TrackedData<Byte> type, int index, boolean value) {
|
||||
// More elegant code that doesn't work somehow
|
||||
//var flagsData = data.stream().filter(serializedEntry -> serializedEntry.handler().equals(type.dataType())).findFirst();
|
||||
//byte b = flagsData.isEmpty() ? 0 : (byte) flagsData.get().value();
|
||||
//flagsData.ifPresent(data::remove);
|
||||
byte b = 0;
|
||||
if (value) {
|
||||
data.add(DataTracker.SerializedEntry.of(type, (byte) (b | 1 << index)));
|
||||
} else {
|
||||
data.add(DataTracker.SerializedEntry.of(type, (byte) (b & ~(1 << index))));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
src/main/resources/decorative.mixins.json
Normal file
11
src/main/resources/decorative.mixins.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"required": true,
|
||||
"package": "eu.midnightdust.motschen.decorative.mixin",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"mixins": [
|
||||
"ArmorStandEntityAccessor"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,10 @@
|
||||
]
|
||||
},
|
||||
|
||||
"mixins": [
|
||||
"decorative.mixins.json"
|
||||
],
|
||||
|
||||
"depends": {
|
||||
"fabric": "*",
|
||||
"midnightlib": "*"
|
||||
|
||||
Reference in New Issue
Block a user