Cast, Convert & more
This commit is contained in:
@@ -4,8 +4,13 @@ import net.minecraft.entity.Entity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Mixin(Entity.class)
|
||||
public interface EntityAccessor {
|
||||
@Invoker("canAddPassenger")
|
||||
boolean invokeCanAddPassenger(Entity other);
|
||||
boolean minions$canAddPassenger(Entity other);
|
||||
|
||||
@Invoker("streamIntoPassengers")
|
||||
Stream<Entity> minions$streamIntoPassengers();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package io.github.skippyall.minions.mixins;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.entity.PistonBlockEntity;
|
||||
import net.minecraft.block.piston.PistonBehavior;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
@Mixin(PistonBlockEntity.class)
|
||||
public abstract class PistonMovingBlockEntityMixin {
|
||||
@WrapOperation(method = "pushEntities", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/entity/Entity;getPistonBehavior()Lnet/minecraft/block/piston/PistonBehavior;"
|
||||
))
|
||||
private static PistonBehavior moveFakePlayers(Entity entity, Operation<PistonBehavior> original, World world, BlockPos pos, float f, PistonBlockEntity pistonBlockEntity)
|
||||
{
|
||||
if (entity instanceof MinionFakePlayer && pistonBlockEntity.getPushedBlock().isOf(Blocks.SLIME_BLOCK))
|
||||
{
|
||||
Vec3d vec3d = entity.getVelocity();
|
||||
double x = vec3d.x;
|
||||
double y = vec3d.y;
|
||||
double z = vec3d.z;
|
||||
Direction direction = pistonBlockEntity.getMovementDirection();
|
||||
switch (direction.getAxis()) {
|
||||
case X -> x = direction.getOffsetX();
|
||||
case Y -> y = direction.getOffsetY();
|
||||
case Z -> z = direction.getOffsetZ();
|
||||
}
|
||||
|
||||
entity.setVelocity(x, y, z);
|
||||
}
|
||||
return original.call(entity);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,21 @@
|
||||
package io.github.skippyall.minions.mixins;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import io.github.skippyall.minions.mixinhelper.EntityViewMixinHelper;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.predicate.entity.EntityPredicates;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.world.SpawnHelper;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(SpawnHelper.class)
|
||||
public class SpawnHelperMixin {
|
||||
@Redirect(method = "spawnEntitiesInChunk(Lnet/minecraft/entity/SpawnGroup;Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/world/chunk/Chunk;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/SpawnHelper$Checker;Lnet/minecraft/world/SpawnHelper$Runner;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerWorld;getClosestPlayer(DDDDZ)Lnet/minecraft/entity/player/PlayerEntity;"))
|
||||
private static PlayerEntity checkMobSpawningMinion(ServerWorld instance, double x, double y, double z, double maxDistance, boolean b) {
|
||||
return instance.getClosestPlayer(x, y, z, maxDistance, EntityPredicates.EXCEPT_SPECTATOR.and(entity -> {
|
||||
@WrapOperation(method = "spawnEntitiesInChunk(Lnet/minecraft/entity/SpawnGroup;Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/world/chunk/Chunk;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/SpawnHelper$Checker;Lnet/minecraft/world/SpawnHelper$Runner;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerWorld;getClosestPlayer(DDDDZ)Lnet/minecraft/entity/player/PlayerEntity;"))
|
||||
private static PlayerEntity checkMobSpawningMinion(ServerWorld world, double x, double y, double z, double maxDistance, boolean ignoreCreative, Operation<PlayerEntity> original) {
|
||||
EntityViewMixinHelper.ADDITIONAL_PREDICATE.set(entity -> {
|
||||
if(entity instanceof ServerPlayerEntity player) {
|
||||
if(player instanceof MinionFakePlayer minion) {
|
||||
return minion.canSpawnMobs();
|
||||
@@ -22,6 +23,9 @@ public class SpawnHelperMixin {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
});
|
||||
PlayerEntity player = original.call(world, x, y, z, maxDistance, ignoreCreative);
|
||||
EntityViewMixinHelper.ADDITIONAL_PREDICATE.remove();
|
||||
return player;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package io.github.skippyall.minions.mixins;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
||||
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.world.tick.TickManager;
|
||||
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;
|
||||
|
||||
@Mixin(TickManager.class)
|
||||
public abstract class TickRateManagerMixin {
|
||||
@Shadow
|
||||
public abstract boolean shouldTick();
|
||||
|
||||
@ModifyReturnValue(method = "shouldSkipTick", at = @At("TAIL"))
|
||||
private boolean handler(boolean alreadyFrozen, Entity entity) {
|
||||
if (alreadyFrozen) return true;
|
||||
if (shouldTick()) return false;
|
||||
|
||||
return !isActualPlayer(entity) && // not carrying players
|
||||
((EntityAccessor) entity)
|
||||
.minions$streamIntoPassengers()
|
||||
.noneMatch(TickRateManagerMixin::isActualPlayer);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static boolean isActualPlayer(Entity e) {
|
||||
return e instanceof PlayerEntity && !(e instanceof MinionFakePlayer);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user