Skip to content

Commit

Permalink
Reimplement Entity Size event
Browse files Browse the repository at this point in the history
  • Loading branch information
AlphaMode committed Nov 23, 2023
1 parent 4e7c7fc commit 35da861
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import java.util.List;

import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.Pose;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package io.github.fabricators_of_create.porting_lib.entity.events;

import io.github.fabricators_of_create.porting_lib.core.event.BaseEvent;
import io.github.fabricators_of_create.porting_lib.entity.mixin.common.EntityAccessor;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Entity.RemovalReason;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.LightningBolt;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;

Expand All @@ -21,6 +24,7 @@ public Entity getEntity() {
return entity;
}

@Deprecated(forRemoval = true)
public static final Event<EyeHeight> EYE_HEIGHT = EventFactory.createArrayBacked(EyeHeight.class, callbacks -> (entity, height) -> {
for (EyeHeight callback : callbacks) {
float newHeight = callback.onEntitySize(entity, height);
Expand All @@ -31,6 +35,11 @@ public Entity getEntity() {
return height;
});

public static final Event<EntitySize> SIZE = EventFactory.createArrayBacked(EntitySize.class, callbacks -> event -> {
for (EntitySize callback : callbacks)
callback.onEntitySizeChange(event);
});

public static final Event<JoinWorld> ON_JOIN_WORLD = EventFactory.createArrayBacked(JoinWorld.class, callbacks -> (entity, world, loadedFromDisk) -> {
for (JoinWorld callback : callbacks)
if (!callback.onJoinWorld(entity, world, loadedFromDisk))
Expand Down Expand Up @@ -69,6 +78,11 @@ public Entity getEntity() {
return false;
});

@Override
public void sendEvent() {

}

@FunctionalInterface
public interface EnteringSection {
void onEntityEnterSection(Entity entity, long packedOldPos, long packedNewPos);
Expand Down Expand Up @@ -131,4 +145,78 @@ public void sendEvent() {
public interface Tracking {
void onTrackingStart(Entity tracking, ServerPlayer player);
}

@FunctionalInterface
public interface EntitySize {
void onEntitySizeChange(Size event);
}

/**
* This event is fired whenever the {@link Pose} changes, and in a few other hardcoded scenarios.<br>
* CAREFUL: This is also fired in the Entity constructor. Therefore the entity(subclass) might not be fully initialized. Check Entity#isAddedToWorld() or !Entity#firstUpdate.<br>
* If you change the player's size, you probably want to set the eye height accordingly as well<br>
**/
public static class Size extends EntityEvents {
private final Pose pose;
private final EntityDimensions oldSize;
private EntityDimensions newSize;
private final float oldEyeHeight;
private float newEyeHeight;

public Size(Entity entity, Pose pose, EntityDimensions size, float defaultEyeHeight) {
this(entity, pose, size, size, defaultEyeHeight, defaultEyeHeight);
}

public Size(Entity entity, Pose pose, EntityDimensions oldSize, EntityDimensions newSize, float oldEyeHeight, float newEyeHeight) {
super(entity);
this.pose = pose;
this.oldSize = oldSize;
this.newSize = newSize;
this.oldEyeHeight = oldEyeHeight;
this.newEyeHeight = newEyeHeight;
}

public Pose getPose() {
return pose;
}

public EntityDimensions getOldSize() {
return oldSize;
}

public EntityDimensions getNewSize() {
return newSize;
}

public void setNewSize(EntityDimensions size) {
setNewSize(size, false);
}

/**
* Set the new size of the entity. Set updateEyeHeight to true to also update the eye height according to the new size.
*/
public void setNewSize(EntityDimensions size, boolean updateEyeHeight) {
this.newSize = size;
if (updateEyeHeight) {
this.newEyeHeight = ((EntityAccessor)this.getEntity()).callGetEyeHeight(this.getPose(), this.newSize);
}
}

public float getOldEyeHeight() {
return oldEyeHeight;
}

public float getNewEyeHeight() {
return newEyeHeight;
}

public void setNewEyeHeight(float newHeight) {
this.newEyeHeight = newHeight;
}

@Override
public void sendEvent() {
SIZE.invoker().onEntitySizeChange(this);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.github.fabricators_of_create.porting_lib.entity.mixin.common;

import net.minecraft.world.entity.Entity;

import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.Pose;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;

@Mixin(Entity.class)
public interface EntityAccessor {
@Invoker
float callGetEyeHeight(Pose pose, EntityDimensions dimensions);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@

import com.llamalad7.mixinextras.injector.ModifyReturnValue;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;

import com.llamalad7.mixinextras.sugar.Local;

import com.llamalad7.mixinextras.sugar.Share;

import com.llamalad7.mixinextras.sugar.ref.LocalRef;

import io.github.fabricators_of_create.porting_lib.entity.IEntityAdditionalSpawnData;
import io.github.fabricators_of_create.porting_lib.entity.events.EntityDataEvents;

Expand All @@ -16,12 +25,17 @@

import net.minecraft.network.protocol.game.ClientboundBundlePacket;

import net.minecraft.world.entity.EntityDimensions;

import net.minecraft.world.entity.Pose;

import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

Expand Down Expand Up @@ -51,6 +65,27 @@ public abstract class EntityMixin implements EntityExtensions {
eyeHeight = EntityEvents.EYE_HEIGHT.invoker().onEntitySize((Entity) (Object) this, eyeHeight);
}

@WrapOperation(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;getEyeHeight(Lnet/minecraft/world/entity/Pose;Lnet/minecraft/world/entity/EntityDimensions;)F"))
private float entitySizeConstructEvent(Entity instance, Pose pose, EntityDimensions dimensions, Operation<Float> original) {
EntityEvents.Size sizeEvent = new EntityEvents.Size((Entity) (Object) this, Pose.STANDING, this.dimensions, original.call(instance, pose, dimensions));
this.dimensions = sizeEvent.getNewSize();
return sizeEvent.getNewEyeHeight();
}

@WrapOperation(method = "refreshDimensions", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;getEyeHeight(Lnet/minecraft/world/entity/Pose;Lnet/minecraft/world/entity/EntityDimensions;)F"))
private float entitySizeEvent(Entity instance, Pose pose, EntityDimensions dimensions, Operation<Float> original, @Local(index = 3) EntityDimensions old, @Share("size") LocalRef<EntityEvents.Size> event) {
EntityEvents.Size sizeEvent = new EntityEvents.Size((Entity) (Object) this, pose, this.dimensions, old, getEyeHeight(), original.call(instance, pose, dimensions));
event.set(sizeEvent);
sizeEvent.sendEvent();
this.dimensions = sizeEvent.getNewSize();
return sizeEvent.getNewEyeHeight();
}

@ModifyVariable(method = "refreshDimensions", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;reapplyPosition()V"), index = 3)
private EntityDimensions modifyDimensions(EntityDimensions value, @Share("size") LocalRef<EntityEvents.Size> event) {
return event.get().getNewSize();
}

// custom spawn packets

@ModifyReturnValue(method = "getAddEntityPacket", at = @At("RETURN"))
Expand Down Expand Up @@ -127,6 +162,18 @@ public Collection<ItemEntity> captureDrops(Collection<ItemEntity> value) {
@Shadow
public abstract int getId();

@Shadow
public abstract Pose getPose();

@Shadow
private EntityDimensions dimensions;

@Shadow
protected abstract float getEyeHeight(Pose pose, EntityDimensions dimensions);

@Shadow
public abstract float getEyeHeight();

@Inject(
method = "startRiding(Lnet/minecraft/world/entity/Entity;Z)Z",
at = @At(
Expand Down Expand Up @@ -185,7 +232,7 @@ public Entity changeDimension(ServerLevel p_20118_, ITeleporter teleporter) {

this.removeAfterChangingDimensions();
this.level.getProfiler().pop();
((ServerLevel)this.level).resetEmptyTime();
((ServerLevel) this.level).resetEmptyTime();
p_20118_.resetEmptyTime();
this.level.getProfiler().pop();
return transportedEntity;
Expand Down
1 change: 1 addition & 0 deletions entity/src/main/resources/porting_lib_entity.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"common.CatSpawnerMixin",
"common.ChorusFruitItemMixin",
"common.EnderManMixin",
"common.EntityAccessor",
"common.EntityMixin",
"common.ExperienceOrbMixin",
"common.ItemMixin",
Expand Down

0 comments on commit 35da861

Please sign in to comment.