Skip to content

Commit

Permalink
Prevent special mob spawning and other miscellaneous features
Browse files Browse the repository at this point in the history
resolves #30
  • Loading branch information
DrexHD committed Nov 18, 2023
1 parent f6d9f2e commit b08fadc
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 113 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Config option to toggle fake join/disconnect messages
- Allow offline players in /vanish command
- Prevent even more sounds
- Prevent special mob spawning (spawners, skeleton traps, zombie reinforcements)
- Prevent sweeping edge attacking players
- Prevent dispensers equipping armor

### Fixed
- Projectiles colliding/hitting players
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/me/drex/vanish/VanishMod.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.drex.vanish;

import me.drex.vanish.api.VanishAPI;
import me.drex.vanish.command.VanishCommand;
import me.drex.vanish.compat.ModCompat;
import me.drex.vanish.config.ConfigManager;
Expand All @@ -8,15 +9,20 @@
import net.fabricmc.api.DedicatedServerModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySelector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.function.Predicate;

public class VanishMod implements DedicatedServerModInitializer {

public static final String MOD_ID = "vanish";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);

public static final ThreadLocal<Entity> ACTIVE_ENTITY = ThreadLocal.withInitial(() -> null);
public static final Predicate<Entity> NO_SPECTATORS_AND_NO_VANISH = EntitySelector.NO_SPECTATORS.and(entity -> !VanishAPI.isVanished(entity));
public static final Predicate<Entity> CAN_BE_COLLIDED_WITH_AND_NO_VANISH = NO_SPECTATORS_AND_NO_VANISH.and(Entity::canBeCollidedWith);

@Override
public void onInitializeServer() {
Expand Down
27 changes: 0 additions & 27 deletions src/main/java/me/drex/vanish/mixin/ExperienceOrbMixin.java

This file was deleted.

2 changes: 1 addition & 1 deletion src/main/java/me/drex/vanish/mixin/MsgCommandMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ private static void vanish_stopMessage(CommandSourceStack commandSourceStack, Co
ServerPlayer player = commandSourceStack.getPlayer();
if (player == null) return;

if (VanishAPI.isVanished(player) && ConfigManager.vanish().disableMsg) {
if (ConfigManager.vanish().disableMsg && VanishAPI.isVanished(player)) {
player.sendSystemMessage(Component.translatable("text.vanish.chat.disabled").withStyle(ChatFormatting.RED));
ci.cancel();
}
Expand Down

This file was deleted.

22 changes: 0 additions & 22 deletions src/main/java/me/drex/vanish/mixin/interaction/BoatMixin.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.drex.vanish.mixin;
package me.drex.vanish.mixin.interaction;

import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
Expand All @@ -18,7 +18,7 @@ public abstract class ChunkMapMixin {
at = @At("RETURN")
)
public boolean vanish_preventChunkGeneration(boolean original, ServerPlayer player) {
return original || (VanishAPI.isVanished(player) && ConfigManager.vanish().interaction.chunkLoading);
return original || (ConfigManager.vanish().interaction.chunkLoading && VanishAPI.isVanished(player));
}

@WrapOperation(
Expand All @@ -29,7 +29,7 @@ public boolean vanish_preventChunkGeneration(boolean original, ServerPlayer play
)
)
public boolean vanish_preventMobSpawning(ServerPlayer player, Operation<Boolean> original) {
return original.call(player) || (VanishAPI.isVanished(player) && ConfigManager.vanish().interaction.mobSpawning);
return original.call(player) || (ConfigManager.vanish().interaction.mobSpawning && VanishAPI.isVanished(player));
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package me.drex.vanish.mixin.interaction;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import me.drex.vanish.api.VanishAPI;
import me.drex.vanish.config.ConfigManager;
import net.minecraft.world.entity.LivingEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;

@Mixin(LivingEntity.class)
public abstract class LivingEntityMixin {

@WrapOperation(
method = "isPushable",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/LivingEntity;isSpectator()Z"
)
)
public boolean vanish_preventPushing(LivingEntity entity, Operation<Boolean> original) {
return original.call(entity) || (ConfigManager.vanish().interaction.entityCollisions && VanishAPI.isVanished(entity));
}


}
14 changes: 10 additions & 4 deletions src/main/java/me/drex/vanish/mixin/interaction/PlayerMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@
@Mixin(Player.class)
public abstract class PlayerMixin {

@WrapWithCondition(method = "touch", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;playerTouch(Lnet/minecraft/world/entity/player/Player;)V"))
@WrapWithCondition(
method = "touch",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/Entity;playerTouch(Lnet/minecraft/world/entity/player/Player;)V"
)
)
private boolean vanish_preventPickup(Entity entity, Player player) {
return !(VanishAPI.isVanished(player) && ConfigManager.vanish().interaction.entityPickup);
}
Expand All @@ -22,10 +28,10 @@ private boolean vanish_preventPickup(Entity entity, Player player) {
at = @At("RETURN")
)
public boolean vanish_preventProjectileHits(boolean original) {
if (ConfigManager.vanish().interaction.entityCollisions && VanishAPI.isVanished((Player) (Object) this)) {
return false;
if (original) {
return !(VanishAPI.isVanished((Player) (Object) this) && ConfigManager.vanish().interaction.entityCollisions);
}
return original;
return false;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package me.drex.vanish.mixin.interaction;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import me.drex.vanish.VanishMod;
import me.drex.vanish.api.VanishAPI;
import me.drex.vanish.config.ConfigManager;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySelector;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.item.ArmorItem;
import net.minecraft.world.level.EntityGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BeehiveBlock;
import net.minecraft.world.phys.AABB;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import java.util.List;
import java.util.function.Predicate;

public class VanishEntitySelector {

/**
* This class is a collection of mixins that (conditionally) replace some {@link EntitySelector#NO_SPECTATORS} with {@link VanishMod#NO_SPECTATORS_AND_NO_VANISH}
*/

@Mixin(EntityGetter.class)
public interface EntityGetterMixin {

@WrapOperation(
method = "hasNearbyAlivePlayer",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/world/entity/EntitySelector;NO_SPECTATORS:Ljava/util/function/Predicate;"
)
)
default Predicate<Entity> vanish_preventMobSpawning(Operation<Predicate<Entity>> original) {
return ConfigManager.vanish().interaction.mobSpawning ? VanishMod.NO_SPECTATORS_AND_NO_VANISH : original.call();
}

@WrapOperation(
method = "getNearestPlayer(DDDDZ)Lnet/minecraft/world/entity/player/Player;",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/world/entity/EntitySelector;NO_SPECTATORS:Ljava/util/function/Predicate;"
)
)
default Predicate<Entity> vanish_preventMobSpawning2(Operation<Predicate<Entity>> original) {
return ConfigManager.vanish().interaction.mobSpawning ? VanishMod.NO_SPECTATORS_AND_NO_VANISH : original.call();
}

@WrapOperation(
method = "getEntityCollisions",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/world/entity/EntitySelector;NO_SPECTATORS:Ljava/util/function/Predicate;"
)
)
default Predicate<Entity> vanish_preventEntityCollisions(Operation<Predicate<Entity>> original) {
return ConfigManager.vanish().interaction.entityCollisions ? VanishMod.NO_SPECTATORS_AND_NO_VANISH : original.call();
}

@WrapOperation(
method = "getEntityCollisions",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/world/entity/EntitySelector;CAN_BE_COLLIDED_WITH:Ljava/util/function/Predicate;"
)
)
default Predicate<Entity> vanish_preventEntityCollisions2(Operation<Predicate<Entity>> original) {
return ConfigManager.vanish().interaction.entityCollisions ? VanishMod.CAN_BE_COLLIDED_WITH_AND_NO_VANISH : original.call();
}
}

@Mixin(EntitySelector.class)
public abstract static class EntitySelectorMixin {

@WrapOperation(
method = "pushableBy",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/world/entity/EntitySelector;NO_SPECTATORS:Ljava/util/function/Predicate;"
)
)
private static Predicate<Entity> vanish_preventEntityCollision(Operation<Predicate<Entity>> original, Entity entity) {
return ConfigManager.vanish().interaction.entityCollisions ? VanishMod.NO_SPECTATORS_AND_NO_VANISH.and(entity1 -> !VanishAPI.isVanished(entity)) : original.call();
}
}

@Mixin(ArmorItem.class)
public abstract static class ArmorItemMixin {

@WrapOperation(
method = "dispenseArmor",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/world/entity/EntitySelector;NO_SPECTATORS:Ljava/util/function/Predicate;"
)
)
private static Predicate<Entity> vanish_preventArmorItemEquip(Operation<Predicate<Entity>> original) {
return ConfigManager.vanish().interaction.entityPickup ? VanishMod.NO_SPECTATORS_AND_NO_VANISH : original.call();
}
}

@Mixin(AbstractMinecart.class)
public abstract static class AbstractMinecartMixin {

@WrapOperation(
method = "tick",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/Level;getEntities(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/AABB;)Ljava/util/List;"
)
)
private List<Entity> vanish_preventMinecartColision(Level instance, Entity entity, AABB aABB, Operation<List<Entity>> original) {
return true ? instance.getEntities(entity, aABB, VanishMod.NO_SPECTATORS_AND_NO_VANISH) : original.call(instance, entity, aABB);
}

}

@Mixin(Player.class)
public abstract static class PlayerMixin {

@Redirect(
method = "attack",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/Level;getEntitiesOfClass(Ljava/lang/Class;Lnet/minecraft/world/phys/AABB;)Ljava/util/List;"
)
)
private List<LivingEntity> vanish_preventSweepingEdge(Level instance, Class<LivingEntity> aClass, AABB aabb) {
return instance.getEntitiesOfClass(aClass, aabb, VanishMod.NO_SPECTATORS_AND_NO_VANISH);
}
}

@Mixin(BeehiveBlock.class)
public abstract static class BeehiveBlockMixin {

@Redirect(
method = "angerNearbyBees",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/Level;getEntitiesOfClass(Ljava/lang/Class;Lnet/minecraft/world/phys/AABB;)Ljava/util/List;"
)
)
private List<LivingEntity> vanish_preventBeeAnger(Level instance, Class<LivingEntity> aClass, AABB aabb) {
return instance.getEntitiesOfClass(aClass, aabb, VanishMod.NO_SPECTATORS_AND_NO_VANISH);
}
}

}
Loading

0 comments on commit b08fadc

Please sign in to comment.