55import net .minecraft .server .world .ServerWorld ;
66import org .spongepowered .asm .mixin .Final ;
77import org .spongepowered .asm .mixin .Mixin ;
8+ import org .spongepowered .asm .mixin .Overwrite ;
89import org .spongepowered .asm .mixin .Shadow ;
910import org .spongepowered .asm .mixin .injection .At ;
1011import org .spongepowered .asm .mixin .injection .Inject ;
1112import org .spongepowered .asm .mixin .injection .Redirect ;
13+ import org .spongepowered .asm .mixin .injection .callback .CallbackInfo ;
1214import org .spongepowered .asm .mixin .injection .callback .CallbackInfoReturnable ;
1315import wearblackallday .dimthread .DimThread ;
1416
1719@ Mixin (Entity .class )
1820public abstract class EntityMixin implements Cloneable {
1921
22+ public boolean isCloned = false ;
23+
24+ @ Shadow @ Final
25+ abstract void setRemoved (Entity .RemovalReason reason );
26+
2027 /**
2128 * Schedules moving entities between dimensions to the server thread. Once all
2229 * the world finish ticking, {@code moveToWorld()} is processed in a safe manner
@@ -42,11 +49,26 @@ public void moveToWorld(ServerWorld destination, CallbackInfoReturnable<Entity>
4249 destination .getServer ().execute (
4350 () -> finalSnapshot .moveToWorld (destination )
4451 );
52+ this .removeFromDimension ();
4553 ci .setReturnValue (null );
4654 }
4755 }
4856
57+ /**
58+ * @author xiaoyu2006
59+ * @reason If this is a cloned entity, it should not execute removeFromDimension.
60+ */
61+ @ Overwrite
62+ public void removeFromDimension () {
63+ if (this .isCloned ) {
64+ return ;
65+ }
66+ this .setRemoved (Entity .RemovalReason .CHANGED_DIMENSION );
67+ }
68+
4969 protected Object clone () throws CloneNotSupportedException {
50- return super .clone ();
70+ EntityMixin cloned = (EntityMixin ) super .clone ();
71+ cloned .isCloned = true ;
72+ return cloned ;
5173 }
5274}
0 commit comments