Skip to content

Commit

Permalink
Merge pull request #20 from ModFest/feature/entity_modif
Browse files Browse the repository at this point in the history
Allow entities to be "immutable" by default
  • Loading branch information
sisby-folk authored Feb 3, 2025
2 parents 846f0f7 + 6398edf commit ad4085f
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 11 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ authors=jaskarth, unascribed
contributors=Patbox, IThundxr
license=AGPL-3.0-or-later
# Mod Version
baseVersion=0.6.1
baseVersion=0.6.2
# Branch Metadata
branch=1.21
tagBranch=1.21
Expand Down
14 changes: 10 additions & 4 deletions src/main/java/net/modfest/fireblanket/Fireblanket.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
import net.fabricmc.fabric.api.entity.event.v1.ServerEntityWorldChangeEvents;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
import net.fabricmc.fabric.api.gamerule.v1.GameRuleFactory;
import net.fabricmc.fabric.api.gamerule.v1.GameRuleRegistry;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.ServerLoginConnectionEvents;
Expand All @@ -28,6 +29,7 @@
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.GameRules;
import net.modfest.fireblanket.command.CmdFindReplaceCommand;
import net.modfest.fireblanket.command.DumpCommand;
import net.modfest.fireblanket.command.RegionCommand;
Expand All @@ -49,9 +51,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
Expand All @@ -61,6 +60,13 @@ public class Fireblanket implements ModInitializer {
public static final Identifier FULL_STREAM_COMPRESSION = Identifier.of("fireblanket", "full_stream_compression");
public static final Identifier REGIONS_UPDATE = Identifier.of("fireblanket", "regions_update");

/**
* Whether new entities will be fixed.
* @see net.modfest.fireblanket.mixin.entity_immutability
*/
public static final GameRules.Key<GameRules.BooleanRule> NEW_ENTITIES_IMMUTABLE =
GameRuleRegistry.register("newEntitiesImmutable", GameRules.Category.MOBS, GameRuleFactory.createBooleanRule(true));

public static final Logger LOGGER = LoggerFactory.getLogger("Fireblanket");

public record QueuedPacket(ClientConnection conn, Packet<?> packet, PacketCallbacks listener) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package net.modfest.fireblanket.mixin.accessor;

import net.minecraft.entity.decoration.ArmorStandEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(ArmorStandEntity.class)
public interface ArmorStandEntityAccessor {
@Accessor
void setDisabledSlots(int d);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package net.modfest.fireblanket.mixin.accessor;

import net.minecraft.entity.decoration.ItemFrameEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(ItemFrameEntity.class)
public interface ItemFrameAccessor {
@Accessor
void setFixed(boolean v);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package net.modfest.fireblanket.mixin.adventure_fix;

import net.minecraft.block.BlockState;
import net.minecraft.block.FarmlandBlock;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
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;

@Mixin(FarmlandBlock.class)
public class MixinFarmlandBlock {
@Inject(
method = "setToDirt",
at = @At("HEAD"),
cancellable = true
)
private static void doNotSetToDirt(@Nullable Entity entity, BlockState state, World world, BlockPos pos, CallbackInfo ci) {
if (entity instanceof PlayerEntity player && !player.canModifyBlocks()) {
ci.cancel();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package net.modfest.fireblanket.mixin.entity_immutability;

import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.entity.decoration.AbstractDecorationEntity;
import net.minecraft.item.DecorationItem;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.ActionResult;
import net.modfest.fireblanket.Fireblanket;
import net.modfest.fireblanket.util.ImmutableEntities;
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.CallbackInfoReturnable;

@Mixin(DecorationItem.class)
public class MixinDecorationItem {
@Inject(method = "useOnBlock(Lnet/minecraft/item/ItemUsageContext;)Lnet/minecraft/util/ActionResult;", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getOrDefault(Lnet/minecraft/component/ComponentType;Ljava/lang/Object;)Ljava/lang/Object;"))
private void onInitSpawnedEntity(ItemUsageContext context, CallbackInfoReturnable<ActionResult> cir, @Local AbstractDecorationEntity entity) {
if (context.getWorld().getGameRules().getBoolean(Fireblanket.NEW_ENTITIES_IMMUTABLE)) {
ImmutableEntities.makeImmutable(entity);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package net.modfest.fireblanket.mixin.entity_immutability;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnReason;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.modfest.fireblanket.Fireblanket;
import net.modfest.fireblanket.util.ImmutableEntities;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;

import java.util.function.Consumer;

@Mixin(EntityType.class)
public class MixinEntityType {
@WrapOperation(method = "create(Lnet/minecraft/server/world/ServerWorld;Ljava/util/function/Consumer;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/SpawnReason;ZZ)Lnet/minecraft/entity/Entity;", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/EntityType;create(Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;"))
private Entity afterCreated(EntityType<?> instance, World world, Operation<Entity> original, ServerWorld world2, @Nullable Consumer<Entity> afterConsumer, BlockPos pos, SpawnReason reason, boolean alignPosition, boolean invertY) {
var entity = original.call(instance, world);
if (world.getGameRules().getBoolean(Fireblanket.NEW_ENTITIES_IMMUTABLE) && reason == SpawnReason.SPAWN_EGG) {
if (entity != null) {
ImmutableEntities.makeImmutable(entity);
}
}
return entity;
}
}
27 changes: 27 additions & 0 deletions src/main/java/net/modfest/fireblanket/util/ImmutableEntities.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package net.modfest.fireblanket.util;

import net.minecraft.entity.Entity;
import net.modfest.fireblanket.mixin.accessor.ArmorStandEntityAccessor;
import net.modfest.fireblanket.mixin.accessor.ItemFrameAccessor;
import net.modfest.fireblanket.mixinsupport.ImmmovableLivingEntity;

public class ImmutableEntities {
public static void makeImmutable(Entity entity) {
// Set invulnerability
entity.setInvulnerable(true);

if (entity instanceof ArmorStandEntityAccessor ae) {
// Disable all slots
ae.setDisabledSlots(4144959);
// Disable movement (prevents abuse of fishing rods)
if (entity instanceof ImmmovableLivingEntity im) {
im.setNoMovement(true);
}
}

if (entity instanceof ItemFrameAccessor ie) {
// Make item frames fixed
ie.setFixed(true);
}
}
}
5 changes: 3 additions & 2 deletions src/main/resources/assets/fireblanket/lang/en_us.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"argument.entity.selector.limit.unforced": "Targeting too many entities with no distance filter; add `force=true` to the selector to bypass",
"argument.entity.options.force.description": "Force-allow more than 50 entities targeted with no distance filter"
}
"argument.entity.options.force.description": "Force-allow more than 50 entities targeted with no distance filter",
"gamerule.newEntitiesImmutable": "Whether newly spawned entities should be immutable. (Item frames will be fixed for example"
}
13 changes: 9 additions & 4 deletions src/main/resources/fireblanket.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,30 @@
"compatibilityLevel": "JAVA_17",
"plugin": "net.modfest.fireblanket.FireblanketMixin",
"mixins": [
"accessor.ArmorStandEntityAccessor",
"accessor.BlockEntityTypeAccessor",
"accessor.ClientConnectionAccessor",
"accessor.EntityTypeAccessor",
"accessor.ItemFrameAccessor",
"accessor.ServerChunkManagerAccessor",
"accessor.ServerLoginNetworkHandlerAccessor",
"adventure_fix.MixinItemStack",
"adventure_fix.MixinItemStack",
"adventure_fix.MixinPlayerInteractEntityC2SPacketHandler",
"adventure_fix.MixinServerPlayerInteractionManager",
"adventure_fix.MixinFarmlandBlock",
"ai.MixinTemptGoal",
"be_sync.MixinBlockEntity",
"be_sync.MixinChunkHolder",
"block.MixinCommandBlock",
"block_format.MixinChunkSection",
"entity_immutability.MixinDecorationItem",
"entity_immutability.MixinEntityType",
"entity_ticking.MixinDebugStickItem",
"entity_ticking.MixinEntity",
"entity_ticking.MixinItemGroups",
"entity_ticking.MixinLivingEntity",
"entity_ticking.MixinMinecraftServer",
"entity_ticking.MixinServerChunkLoadingManager",
"mods.create.MixinSuperGlueEntity",
"footgun.MixinEntitySelectorOptions",
"footgun.MixinEntitySelectorReader",
"fsc.MixinClientConnection",
Expand All @@ -32,6 +36,7 @@
"io_uring.MixinServerNetworkIo",
"mods.create.AccessorSmartBlockEntity",
"mods.create.MixinMechanicalBearingBlockEntity",
"mods.create.MixinSuperGlueEntity",
"mods.mythicmetals.MixinCarmotShield",
"mods.pehkui.MixinScaleUtils",
"mods.pswg.MixinComplexCollisionManager",
Expand Down Expand Up @@ -61,7 +66,6 @@
"client.adventure_fix.MixinClientPlayerInteractionManager",
"client.be_masking.MixinBlockEntityRenderDispatcher",
"client.be_masking.MixinRebuildTask",
"mods.masking.sodium.MixinChunkRenderRebuildTask",
"client.bufferbuilder_opto.MixinBufferBuilder",
"client.bufferbuilder_opto.MixinVertexFormat",
"client.entity_masking.MixinEntityRenderer",
Expand All @@ -79,6 +83,7 @@
"client.vbo_opto.MixinShaderProgram",
"client.vbo_opto.MixinVertexBuffer",
"gamemode_selection.MixinKeyboard",
"gamemode_selection.MixinSelectionScreen"
"gamemode_selection.MixinSelectionScreen",
"mods.masking.sodium.MixinChunkRenderRebuildTask"
]
}

0 comments on commit ad4085f

Please sign in to comment.