diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/entity/AgeableEntityBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/entity/AgeableEntityBridge.java new file mode 100644 index 00000000..325e17e8 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/entity/AgeableEntityBridge.java @@ -0,0 +1,6 @@ +package io.izzel.arclight.common.bridge.entity; + +public interface AgeableEntityBridge extends LivingEntityBridge { + + boolean bridge$isAgeLocked(); +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/entity/EntityBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/entity/EntityBridge.java index ed39ea23..a48dfc42 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/entity/EntityBridge.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/entity/EntityBridge.java @@ -54,6 +54,4 @@ public interface EntityBridge extends ICommandSourceBridge { int bridge$getRideCooldown(); boolean bridge$canCollideWith(Entity entity); - - void bridge$inactiveTick(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/AgeableEntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/AgeableEntityMixin.java index ec5a2323..f24d32ed 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/AgeableEntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/AgeableEntityMixin.java @@ -1,5 +1,6 @@ package io.izzel.arclight.common.mixin.core.entity; +import io.izzel.arclight.common.bridge.entity.AgeableEntityBridge; import net.minecraft.entity.AgeableEntity; import net.minecraft.nbt.CompoundNBT; import net.minecraft.world.World; @@ -14,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import javax.annotation.Nullable; @Mixin(AgeableEntity.class) -public abstract class AgeableEntityMixin extends CreatureEntityMixin { +public abstract class AgeableEntityMixin extends CreatureEntityMixin implements AgeableEntityBridge { // @formatter:off @Shadow public abstract boolean isChild(); @@ -38,4 +39,9 @@ public abstract class AgeableEntityMixin extends CreatureEntityMixin { private boolean arclight$tickIfNotLocked(World world) { return world.isRemote || ageLocked; } + + @Override + public boolean bridge$isAgeLocked() { + return this.ageLocked; + } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/EntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/EntityMixin.java index c2983121..fee7c3f3 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/EntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/EntityMixin.java @@ -73,7 +73,6 @@ import org.bukkit.event.vehicle.VehicleEnterEvent; import org.bukkit.event.vehicle.VehicleExitEvent; import org.bukkit.plugin.PluginManager; import org.bukkit.projectiles.ProjectileSource; -import org.spigotmc.ActivationRange; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; @@ -201,41 +200,18 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge, // @formatter:on private static final int CURRENT_LEVEL = 2; - public boolean persist; + public boolean persist = true; public boolean valid; public org.bukkit.projectiles.ProjectileSource projectileSource; // For projectiles only public boolean forceExplosionKnockback; // SPIGOT-949 - public org.spigotmc.ActivationRange.ActivationType activationType; - public boolean defaultActivationState; - public long activatedTick = Integer.MIN_VALUE; public boolean persistentInvisibility = false; - @Inject(method = "", at = @At("RETURN")) - private void arclight$init(EntityType entityTypeIn, World worldIn, CallbackInfo ci) { - this.persist = true; - activationType = ActivationRange.initializeEntityActivationType((Entity) (Object) this); - if (worldIn != null) { - this.defaultActivationState = ActivationRange.initializeEntityActivationState((Entity) (Object) this, ((WorldBridge) worldIn).bridge$spigotConfig()); - } else { - this.defaultActivationState = false; - } - } - private CraftEntity bukkitEntity; public CraftEntity getBukkitEntity() { return internal$getBukkitEntity(); } - public void inactiveTick() { - this.tick(); - } - - @Override - public void bridge$inactiveTick() { - this.inactiveTick(); - } - @Override public CommandSender bridge$getBukkitSender(CommandSource wrapper) { return internal$getBukkitEntity(); diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/bridge/EntityBridge_ActivationRange.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/bridge/EntityBridge_ActivationRange.java new file mode 100644 index 00000000..3d049627 --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/bridge/EntityBridge_ActivationRange.java @@ -0,0 +1,6 @@ +package io.izzel.arclight.impl.bridge; + +public interface EntityBridge_ActivationRange { + + void bridge$inactiveTick(); +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/EntityMixin_ActivationRange.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/EntityMixin_ActivationRange.java new file mode 100644 index 00000000..b1dee40d --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/EntityMixin_ActivationRange.java @@ -0,0 +1,46 @@ +package io.izzel.arclight.impl.mixin.optimization.general.activationrange; + +import io.izzel.arclight.common.bridge.world.WorldBridge; +import io.izzel.arclight.impl.bridge.EntityBridge_ActivationRange; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.world.World; +import org.spigotmc.ActivationRange; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Entity.class) +public abstract class EntityMixin_ActivationRange implements EntityBridge_ActivationRange { + + // @formatter:off + @Shadow public abstract void recalculateSize(); + @Shadow public int ticksExisted; + @Shadow public abstract void remove(); + @Shadow public World world; + // @formatter:on + + public ActivationRange.ActivationType activationType; + public boolean defaultActivationState; + public long activatedTick = Integer.MIN_VALUE; + + @Inject(method = "", at = @At("RETURN")) + private void arclight$init(EntityType entityTypeIn, World worldIn, CallbackInfo ci) { + activationType = ActivationRange.initializeEntityActivationType((Entity) (Object) this); + if (worldIn != null) { + this.defaultActivationState = ActivationRange.initializeEntityActivationState((Entity) (Object) this, ((WorldBridge) worldIn).bridge$spigotConfig()); + } else { + this.defaultActivationState = false; + } + } + + public void inactiveTick() { + } + + @Override + public void bridge$inactiveTick() { + this.inactiveTick(); + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/ServerWorldMixin_ActivationRange.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/ServerWorldMixin_ActivationRange.java new file mode 100644 index 00000000..a679ec6a --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/ServerWorldMixin_ActivationRange.java @@ -0,0 +1,34 @@ +package io.izzel.arclight.impl.mixin.optimization.general.activationrange; + +import io.izzel.arclight.impl.bridge.EntityBridge_ActivationRange; +import net.minecraft.entity.Entity; +import net.minecraft.world.server.ServerWorld; +import org.spigotmc.ActivationRange; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.function.BooleanSupplier; + +@Mixin(ServerWorld.class) +public class ServerWorldMixin_ActivationRange { + + @Inject(method = "tick", at = @At(value = "INVOKE", remap = false, target = "Lit/unimi/dsi/fastutil/ints/Int2ObjectMap;int2ObjectEntrySet()Lit/unimi/dsi/fastutil/objects/ObjectSet;")) + private void activationRange$activateEntity(BooleanSupplier hasTimeLeft, CallbackInfo ci) { + ActivationRange.activateEntities((ServerWorld) (Object) this); + } + + @Inject(method = "updateEntity", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;forceSetPosition(DDD)V")) + private void activationRange$inactiveTick(Entity entityIn, CallbackInfo ci) { + if (!ActivationRange.checkIfActive(entityIn)) { + if (entityIn.addedToChunk) { + ++entityIn.ticksExisted; + if (entityIn.canUpdate()) { + ((EntityBridge_ActivationRange) entityIn).bridge$inactiveTick(); + } + } + ci.cancel(); + } + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/AbstractArrowEntityMixin_ActivationRange.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/AbstractArrowEntityMixin_ActivationRange.java new file mode 100644 index 00000000..38b2c54a --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/AbstractArrowEntityMixin_ActivationRange.java @@ -0,0 +1,23 @@ +package io.izzel.arclight.impl.mixin.optimization.general.activationrange.entity; + +import io.izzel.arclight.impl.mixin.optimization.general.activationrange.EntityMixin_ActivationRange; +import net.minecraft.entity.projectile.AbstractArrowEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(AbstractArrowEntity.class) +public abstract class AbstractArrowEntityMixin_ActivationRange extends EntityMixin_ActivationRange { + + // @formatter:off + @Shadow public boolean inGround; + @Shadow protected int timeInGround; + // @formatter:on + + @Override + public void inactiveTick() { + super.inactiveTick(); + if (this.inGround) { + this.timeInGround++; + } + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/AgeableEntityMixin_ActivationRange.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/AgeableEntityMixin_ActivationRange.java new file mode 100644 index 00000000..7b3d9ece --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/AgeableEntityMixin_ActivationRange.java @@ -0,0 +1,33 @@ +package io.izzel.arclight.impl.mixin.optimization.general.activationrange.entity; + +import io.izzel.arclight.common.bridge.entity.AgeableEntityBridge; +import io.izzel.arclight.impl.mixin.optimization.general.activationrange.EntityMixin_ActivationRange; +import net.minecraft.entity.AgeableEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(AgeableEntity.class) +public abstract class AgeableEntityMixin_ActivationRange extends EntityMixin_ActivationRange { + + // @formatter:off + @Shadow public abstract int getGrowingAge(); + @Shadow public abstract void setGrowingAge(int age); + // @formatter:on + + @Override + public void inactiveTick() { + super.inactiveTick(); + if (((AgeableEntityBridge) this).bridge$isAgeLocked()) { + this.recalculateSize(); + } else { + int i = this.getGrowingAge(); + if (i < 0) { + ++i; + this.setGrowingAge(i); + } else if (i > 0) { + --i; + this.setGrowingAge(i); + } + } + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/AreaEffectCloudEntityMixin_ActivationRange.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/AreaEffectCloudEntityMixin_ActivationRange.java new file mode 100644 index 00000000..b9dee5b1 --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/AreaEffectCloudEntityMixin_ActivationRange.java @@ -0,0 +1,23 @@ +package io.izzel.arclight.impl.mixin.optimization.general.activationrange.entity; + +import io.izzel.arclight.impl.mixin.optimization.general.activationrange.EntityMixin_ActivationRange; +import net.minecraft.entity.AreaEffectCloudEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(AreaEffectCloudEntity.class) +public abstract class AreaEffectCloudEntityMixin_ActivationRange extends EntityMixin_ActivationRange { + + // @formatter:off + @Shadow public int waitTime; + @Shadow private int duration; + // @formatter:on + + @Override + public void inactiveTick() { + super.inactiveTick(); + if (this.ticksExisted >= this.waitTime + this.duration) { + this.remove(); + } + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/FireworkRocketEntityMixin_ActivationRange.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/FireworkRocketEntityMixin_ActivationRange.java new file mode 100644 index 00000000..4c3b2f03 --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/FireworkRocketEntityMixin_ActivationRange.java @@ -0,0 +1,25 @@ +package io.izzel.arclight.impl.mixin.optimization.general.activationrange.entity; + +import io.izzel.arclight.impl.mixin.optimization.general.activationrange.EntityMixin_ActivationRange; +import net.minecraft.entity.projectile.FireworkRocketEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(FireworkRocketEntity.class) +public abstract class FireworkRocketEntityMixin_ActivationRange extends EntityMixin_ActivationRange { + + // @formatter:off + @Shadow private int fireworkAge; + @Shadow public int lifetime; + @Shadow protected abstract void func_213893_k(); + // @formatter:on + + @Override + public void inactiveTick() { + super.inactiveTick(); + ++this.fireworkAge; + if (!this.world.isRemote && this.fireworkAge > this.lifetime) { + this.func_213893_k(); + } + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/ItemEntityMixin_ActivationRange.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/ItemEntityMixin_ActivationRange.java new file mode 100644 index 00000000..5ec286bd --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/ItemEntityMixin_ActivationRange.java @@ -0,0 +1,55 @@ +package io.izzel.arclight.impl.mixin.optimization.general.activationrange.entity; + +import io.izzel.arclight.common.bridge.world.WorldBridge; +import io.izzel.arclight.common.mod.ArclightConstants; +import io.izzel.arclight.impl.mixin.optimization.general.activationrange.EntityMixin_ActivationRange; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import net.minecraftforge.event.ForgeEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ItemEntity.class) +public abstract class ItemEntityMixin_ActivationRange extends EntityMixin_ActivationRange { + + // @formatter:off + @Shadow public int pickupDelay; + @Shadow public int age; + @Shadow(remap = false) public int lifespan; + @Shadow public abstract ItemStack getItem(); + // @formatter:on + + @Inject(method = "(Lnet/minecraft/entity/EntityType;Lnet/minecraft/world/World;)V", at = @At("RETURN")) + private void activationRange$init(EntityType entityType, World world, CallbackInfo ci) { + this.lifespan = ((WorldBridge) this.world).bridge$spigotConfig().itemDespawnRate; + } + + @Inject(method = "(Lnet/minecraft/world/World;DDDLnet/minecraft/item/ItemStack;)V", at = @At("RETURN")) + private void activationRange$init(World worldIn, double x, double y, double z, ItemStack stack, CallbackInfo ci) { + if (this.lifespan == 6000) { + this.lifespan = ((WorldBridge) this.world).bridge$spigotConfig().itemDespawnRate; + } + } + + private int lastTick = ArclightConstants.currentTick - 1; + + @Override + public void inactiveTick() { + super.inactiveTick(); + int elapsedTicks = ArclightConstants.currentTick - this.lastTick; + if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks; + if (this.age != -32768) this.age += elapsedTicks; + this.lastTick = ArclightConstants.currentTick; + + if (!this.world.isRemote && this.age >= this.lifespan) { + int hook = ForgeEventFactory.onItemExpire((ItemEntity) (Object) this, this.getItem()); + if (hook < 0) this.remove(); + else this.lifespan += hook; + } + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/LivingEntityMixin_ActivationRange.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/LivingEntityMixin_ActivationRange.java new file mode 100644 index 00000000..4c13b3db --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/LivingEntityMixin_ActivationRange.java @@ -0,0 +1,20 @@ +package io.izzel.arclight.impl.mixin.optimization.general.activationrange.entity; + +import io.izzel.arclight.impl.mixin.optimization.general.activationrange.EntityMixin_ActivationRange; +import net.minecraft.entity.LivingEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(LivingEntity.class) +public abstract class LivingEntityMixin_ActivationRange extends EntityMixin_ActivationRange { + + // @formatter:off + @Shadow protected int idleTime; + // @formatter:on + + @Override + public void inactiveTick() { + super.inactiveTick(); + this.idleTime++; + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/VillagerEntityMixin_ActivationRange.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/VillagerEntityMixin_ActivationRange.java new file mode 100644 index 00000000..4f6b8aa1 --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/general/activationrange/entity/VillagerEntityMixin_ActivationRange.java @@ -0,0 +1,24 @@ +package io.izzel.arclight.impl.mixin.optimization.general.activationrange.entity; + +import io.izzel.arclight.common.bridge.world.WorldBridge; +import io.izzel.arclight.impl.mixin.optimization.general.activationrange.EntityMixin_ActivationRange; +import net.minecraft.entity.merchant.villager.VillagerEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(VillagerEntity.class) +public abstract class VillagerEntityMixin_ActivationRange extends EntityMixin_ActivationRange { + + // @formatter:off + @Shadow protected abstract void updateAITasks(); + // @formatter:on + + @Override + public void inactiveTick() { + super.inactiveTick(); + if (((WorldBridge) this.world).bridge$spigotConfig().tickInactiveVillagers + && ((VillagerEntity) (Object) this).isServerWorld()) { + this.updateAITasks(); + } + } +} diff --git a/arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.1_16.json b/arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.1_16.json index ec081ebc..33a2e412 100644 --- a/arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.1_16.json +++ b/arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.1_16.json @@ -5,6 +5,15 @@ "refmap": "mixins.arclight.impl.refmap.1_16.json", "mixins": [ "ClassInheritanceMultiMapMixin", - "VoxelShapesMixin" + "VoxelShapesMixin", + "activationrange.EntityMixin_ActivationRange", + "activationrange.ServerWorldMixin_ActivationRange", + "activationrange.entity.AbstractArrowEntityMixin_ActivationRange", + "activationrange.entity.AgeableEntityMixin_ActivationRange", + "activationrange.entity.AreaEffectCloudEntityMixin_ActivationRange", + "activationrange.entity.FireworkRocketEntityMixin_ActivationRange", + "activationrange.entity.ItemEntityMixin_ActivationRange", + "activationrange.entity.LivingEntityMixin_ActivationRange", + "activationrange.entity.VillagerEntityMixin_ActivationRange" ] } \ No newline at end of file