diff --git a/CHANGELOG.md b/CHANGELOG.md index 805f20d2b..96d53fef7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ - Fixed strong potion of reaching duration - Fixed iceologer model - Fixed carpet profiler incompatibility +- Fixed aether dungeons incompatibility +- Fixed buttercup not being compostable - Added more config options - Added zh_tw translations (Thanks to Lobster0228) - Added fr_fr translations (Thanks to Franco227) diff --git a/common/src/main/java/com/faboslav/friendsandfoes/common/FriendsAndFoes.java b/common/src/main/java/com/faboslav/friendsandfoes/common/FriendsAndFoes.java index 50b9b2379..d41fdd739 100644 --- a/common/src/main/java/com/faboslav/friendsandfoes/common/FriendsAndFoes.java +++ b/common/src/main/java/com/faboslav/friendsandfoes/common/FriendsAndFoes.java @@ -78,6 +78,7 @@ public static void init() { public static void lateInit() { FriendsAndFoesBlockEntityTypes.lateInit(); + FriendsAndFoesItems.registerCompostableItems(); BiomeModifications.addButtercupFeature(); } diff --git a/common/src/main/java/com/faboslav/friendsandfoes/common/init/FriendsAndFoesItems.java b/common/src/main/java/com/faboslav/friendsandfoes/common/init/FriendsAndFoesItems.java index 1e0b6d057..e9f31414e 100644 --- a/common/src/main/java/com/faboslav/friendsandfoes/common/init/FriendsAndFoesItems.java +++ b/common/src/main/java/com/faboslav/friendsandfoes/common/init/FriendsAndFoesItems.java @@ -6,6 +6,7 @@ import com.faboslav.friendsandfoes.common.init.registry.ResourcefulRegistry; import com.faboslav.friendsandfoes.common.item.DispenserAddedSpawnEgg; import com.faboslav.friendsandfoes.common.item.FriendsAndFoesArmorMaterials; +import net.minecraft.block.ComposterBlock; import net.minecraft.entity.EntityType; import net.minecraft.item.ArmorItem; import net.minecraft.item.BlockItem; @@ -66,4 +67,8 @@ public final class FriendsAndFoesItems private FriendsAndFoesItems() { } + + public static void registerCompostableItems() { + ComposterBlock.registerCompostableItem(0.65F, FriendsAndFoesItems.BUTTERCUP.get()); + } } diff --git a/fabric/src/main/java/com/yungnickyoung/minecraft/yungsapi/world/processor/StructureEntityProcessor.java b/common/src/main/java/com/faboslav/friendsandfoes/common/world/processor/StructureEntityProcessor.java similarity index 85% rename from fabric/src/main/java/com/yungnickyoung/minecraft/yungsapi/world/processor/StructureEntityProcessor.java rename to common/src/main/java/com/faboslav/friendsandfoes/common/world/processor/StructureEntityProcessor.java index eef006ea6..9d6e213e1 100644 --- a/fabric/src/main/java/com/yungnickyoung/minecraft/yungsapi/world/processor/StructureEntityProcessor.java +++ b/common/src/main/java/com/faboslav/friendsandfoes/common/world/processor/StructureEntityProcessor.java @@ -1,4 +1,4 @@ -package com.yungnickyoung.minecraft.yungsapi.world.processor; +package com.faboslav.friendsandfoes.common.world.processor; import net.minecraft.structure.StructurePlacementData; import net.minecraft.structure.StructureTemplate.StructureEntityInfo; @@ -7,7 +7,6 @@ import net.minecraft.world.ServerWorldAccess; /** - * This is very important placeholder for compatibilitty ( * Originally from YUNG's API by. * YUNGNICKYOUNG (https://github.com/YUNG-GANG/YUNGs-API) */ diff --git a/common/src/main/java/com/faboslav/friendsandfoes/common/world/processor/StructureProcessingContext.java b/common/src/main/java/com/faboslav/friendsandfoes/common/world/processor/StructureProcessingContext.java new file mode 100644 index 000000000..155101a17 --- /dev/null +++ b/common/src/main/java/com/faboslav/friendsandfoes/common/world/processor/StructureProcessingContext.java @@ -0,0 +1,41 @@ +package com.faboslav.friendsandfoes.common.world.processor; + +import net.minecraft.structure.StructurePlacementData; +import net.minecraft.structure.StructureTemplate; +import net.minecraft.util.Util; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.ServerWorldAccess; + +import java.util.ArrayList; +import java.util.List; + +/** + * Originally from YUNG's API by. + * YUNGNICKYOUNG (https://github.com/YUNG-GANG/YUNGs-API) + */ +public record StructureProcessingContext( + ServerWorldAccess serverWorldAccess, + StructurePlacementData structurePlacementData, + BlockPos structurePiecePos, + BlockPos structurePiecePivotPos, + List rawEntityInfos) +{ + public StructureProcessingContext( + ServerWorldAccess serverWorldAccess, + StructurePlacementData structurePlacementData, + BlockPos structurePiecePos, + BlockPos structurePiecePivotPos, + List rawEntityInfos + ) { + this.serverWorldAccess = serverWorldAccess; + this.structurePlacementData = structurePlacementData; + this.structurePiecePos = structurePiecePos; + this.structurePiecePivotPos = structurePiecePivotPos; + this.rawEntityInfos = Util.make(() -> { + List list = new ArrayList<>(rawEntityInfos.size()); + rawEntityInfos.forEach((entityInfo) -> + list.add(new StructureTemplate.StructureEntityInfo(entityInfo.pos, entityInfo.blockPos, entityInfo.nbt))); + return list; + }); + } +} \ No newline at end of file diff --git a/common/src/main/resources/friendsandfoes.accesswidener b/common/src/main/resources/friendsandfoes.accesswidener index 30cbc17f1..aa523efb4 100644 --- a/common/src/main/resources/friendsandfoes.accesswidener +++ b/common/src/main/resources/friendsandfoes.accesswidener @@ -34,6 +34,7 @@ accessible method net/minecraft/particle/DefaultParticleType (Z)V accessible method net/minecraft/block/ButtonBlock getClickSound (Z)Lnet/minecraft/sound/SoundEvent; accessible method net/minecraft/entity/ai/brain/sensor/SensorType (Ljava/util/function/Supplier;)V accessible method net/minecraft/advancement/criterion/Criteria register (Ljava/lang/String;Lnet/minecraft/advancement/criterion/Criterion;)Lnet/minecraft/advancement/criterion/Criterion; -accessible method net/minecraft/entity/effect/StatusEffect (Lnet/minecraft/entity/effect/StatusEffectCategory;I)V accessible field net/minecraft/block/Oxidizable OXIDATION_LEVEL_INCREASES Ljava/util/function/Supplier; accessible field net/minecraft/block/Oxidizable OXIDATION_LEVEL_DECREASES Ljava/util/function/Supplier; +accessible method net/minecraft/entity/effect/StatusEffect (Lnet/minecraft/entity/effect/StatusEffectCategory;I)V +accessible method net/minecraft/block/ComposterBlock registerCompostableItem (FLnet/minecraft/item/ItemConvertible;)V diff --git a/fabric/src/main/java/com/faboslav/friendsandfoes/fabric/mixin/StructureEntityProcessorMixin.java b/fabric/src/main/java/com/faboslav/friendsandfoes/fabric/mixin/StructureEntityProcessorMixin.java index 0e3113e5f..60fcd09e3 100644 --- a/fabric/src/main/java/com/faboslav/friendsandfoes/fabric/mixin/StructureEntityProcessorMixin.java +++ b/fabric/src/main/java/com/faboslav/friendsandfoes/fabric/mixin/StructureEntityProcessorMixin.java @@ -1,7 +1,7 @@ package com.faboslav.friendsandfoes.fabric.mixin; -import com.yungnickyoung.minecraft.yungsapi.world.processor.StructureEntityProcessor; -import net.fabricmc.loader.api.FabricLoader; +import com.faboslav.friendsandfoes.common.world.processor.StructureEntityProcessor; +import com.faboslav.friendsandfoes.common.world.processor.StructureProcessingContext; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.SpawnReason; @@ -13,20 +13,16 @@ import net.minecraft.structure.StructureTemplate; import net.minecraft.structure.StructureTemplate.StructureEntityInfo; import net.minecraft.structure.processor.StructureProcessor; -import net.minecraft.util.BlockMirror; -import net.minecraft.util.BlockRotation; -import net.minecraft.util.math.BlockBox; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.random.Random; import net.minecraft.world.ServerWorldAccess; -import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Final; 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; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.ArrayList; @@ -36,7 +32,7 @@ /** * Allows for processing entities in Jigsaw structures. * Originally from YUNG's API by. - * YUNGNICKYOUNG(https://github.com/YUNG-GANG/YUNGs-API) + * YUNGNICKYOUNG (YUNGs-API) */ @Mixin(StructureTemplate.class) public final class StructureEntityProcessorMixin @@ -45,17 +41,56 @@ public final class StructureEntityProcessorMixin @Final private List entities; - /** - * Reimplements vanilla behavior for spawning entities, - * but with additional behavior allowing for the use of entity processing ({@link StructureEntityProcessor}) - */ + @Unique + private static final ThreadLocal friendsandfoes_context = new ThreadLocal<>(); + @Inject( method = "place", at = @At( value = "INVOKE", - target = "net/minecraft/structure/StructureTemplate.spawnEntities (Lnet/minecraft/world/ServerWorldAccess;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/BlockMirror;Lnet/minecraft/util/BlockRotation;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/BlockBox;Z)V" + target = "Lnet/minecraft/structure/StructureTemplate;spawnEntities(Lnet/minecraft/world/ServerWorldAccess;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/BlockMirror;Lnet/minecraft/util/BlockRotation;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/BlockBox;Z)V" ) ) + private void friendsandfoes_captureContext( + ServerWorldAccess world, + BlockPos pos, + BlockPos pivot, + StructurePlacementData placementData, + Random random, + int flags, + CallbackInfoReturnable cir + ) { + friendsandfoes_context.set(new StructureProcessingContext( + world, + placementData, + pos, + pivot, + entities + )); + } + + + @Inject( + method = "place", + at = @At( + value = "INVOKE", + shift = At.Shift.AFTER, + target = "Lnet/minecraft/structure/StructureTemplate;spawnEntities(Lnet/minecraft/world/ServerWorldAccess;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/BlockMirror;Lnet/minecraft/util/BlockRotation;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/BlockBox;Z)V")) + private void friendsandfoes_clearContext( + ServerWorldAccess serverLevelAccessor, BlockPos structurePiecePos, BlockPos structurePiecePivotPos, + StructurePlacementData structurePlaceSettings, Random randomSource, int i, CallbackInfoReturnable cir + ) { + friendsandfoes_context.remove(); + } + + @Inject( + method = "place", + at = @At( + value = "INVOKE", + target = "net/minecraft/structure/StructureTemplate.spawnEntities (Lnet/minecraft/world/ServerWorldAccess;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/BlockMirror;Lnet/minecraft/util/BlockRotation;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/BlockBox;Z)V" + ), + cancellable = true + ) private void friendsandfoes_processEntities( ServerWorldAccess serverWorldAccess, BlockPos structurePiecePos, @@ -65,56 +100,36 @@ private void friendsandfoes_processEntities( int flags, CallbackInfoReturnable cir ) { - if (!FabricLoader.getInstance().isModLoaded("yungsapi")) { - for (StructureEntityInfo entityInfo : friendsandfoes_processEntityInfos( - serverWorldAccess, - structurePiecePos, - structurePieceBottomCenterPos, - structurePlacementData, - this.entities - )) { - BlockPos blockPos = entityInfo.blockPos; - - if ( - structurePlacementData.getBoundingBox() != null - && !structurePlacementData.getBoundingBox().contains(blockPos) - ) { - continue; - } + StructureProcessingContext ctx = friendsandfoes_context.get(); + + if (ctx.structurePlacementData().getProcessors().stream().noneMatch(p -> p instanceof StructureEntityProcessor)) { + return; + } - NbtCompound compoundTag = entityInfo.nbt.copy(); - Vec3d vec3d = entityInfo.pos; - - NbtList nbtList = new NbtList(); - nbtList.add(NbtDouble.of(vec3d.getX())); - nbtList.add(NbtDouble.of(vec3d.getY())); - nbtList.add(NbtDouble.of(vec3d.getZ())); - compoundTag.put("Pos", nbtList); - compoundTag.remove("UUID"); - - friendsandfoes_getEntity(serverWorldAccess, compoundTag).ifPresent((entity) -> { - float f = entity.applyMirror(structurePlacementData.getMirror()); - f += entity.getYaw() - entity.applyRotation(structurePlacementData.getRotation()); - entity.refreshPositionAndAngles( - vec3d.getX(), - vec3d.getY(), - vec3d.getZ(), - f, - entity.getPitch() - ); - if (structurePlacementData.shouldInitializeMobs() && entity instanceof MobEntity) { + List processedEntities = friendsandfoes_processEntityInfoList(ctx); + + for (StructureTemplate.StructureEntityInfo entityInfo : processedEntities) { + BlockPos entityBlockPos = entityInfo.blockPos; + if (ctx.structurePlacementData().getBoundingBox() == null || ctx.structurePlacementData().getBoundingBox().contains(entityBlockPos)) { + NbtCompound entityNbt = entityInfo.nbt.copy(); + Vec3d entityPos = entityInfo.pos; + NbtList listTag = new NbtList(); + listTag.add(NbtDouble.of(entityPos.x)); + listTag.add(NbtDouble.of(entityPos.y)); + listTag.add(NbtDouble.of(entityPos.z)); + entityNbt.put("Pos", listTag); + entityNbt.remove("UUID"); + friendsandfoes_tryCreateEntity(serverWorldAccess, entityNbt).ifPresent((entity) -> { + float f = entity.applyMirror(ctx.structurePlacementData().getMirror()); + f += entity.getYaw() - entity.applyRotation(ctx.structurePlacementData().getRotation()); + entity.refreshPositionAndAngles(entityPos.x, entityPos.y, entityPos.z, f, entity.getPitch()); + if (ctx.structurePlacementData().shouldInitializeMobs() && entity instanceof MobEntity) { ((MobEntity) entity).initialize( serverWorldAccess, - serverWorldAccess.getLocalDifficulty( - new BlockPos( - (int) vec3d.getX(), - (int) vec3d.getY(), - (int) vec3d.getZ() - ) - ), + serverWorldAccess.getLocalDifficulty(BlockPos.ofFloored(entityPos)), SpawnReason.STRUCTURE, null, - compoundTag + entityNbt ); } @@ -122,88 +137,42 @@ private void friendsandfoes_processEntities( }); } } - } - /** - * Cancel spawning entities. - * This behavior is recreated in {@link #friendsandfoes_processEntities} - */ - @Inject( - method = "spawnEntities", - at = @At(value = "HEAD"), - cancellable = true - ) - private void friendsandfoes_cancelPlaceEntities( - ServerWorldAccess serverWorldAccess, - BlockPos structurePiecePos, - BlockMirror mirror, - BlockRotation rotation, - BlockPos pivot, - @Nullable BlockBox area, - boolean initializeMobs, - CallbackInfo ci - ) { - if (!FabricLoader.getInstance().isModLoaded("yungsapi")) { - ci.cancel(); - } + cir.cancel(); } - /** - * Applies placement data and {@link StructureEntityProcessor}s to entities in a structure. - */ - private List friendsandfoes_processEntityInfos( - ServerWorldAccess serverWorldAccess, - BlockPos structurePiecePos, - BlockPos structurePieceBottomCenterPos, - StructurePlacementData structurePlacementData, - List rawEntityList - ) { - List processedEntities = new ArrayList<>(); + @Unique + private List friendsandfoes_processEntityInfoList(StructureProcessingContext ctx) { + List processedEntities = new ArrayList<>(); + + ServerWorldAccess serverLevelAccessor = ctx.serverWorldAccess(); + BlockPos structurePiecePos = ctx.structurePiecePos(); + BlockPos structurePiecePivotPos = ctx.structurePiecePivotPos(); + StructurePlacementData structurePlaceSettings = ctx.structurePlacementData(); + List rawEntityInfos = ctx.rawEntityInfos(); - for (StructureEntityInfo rawEntityItem : rawEntityList) { - // Calculate transformed position so processors have access to the actual global world coordinates of the entity + for (StructureTemplate.StructureEntityInfo rawEntityInfo : rawEntityInfos) { Vec3d globalPos = StructureTemplate - .transformAround( - rawEntityItem.pos, - structurePlacementData.getMirror(), - structurePlacementData.getRotation(), - structurePlacementData.getPosition() - ).add(Vec3d.of(structurePiecePos)); + .transformAround(rawEntityInfo.pos, + structurePlaceSettings.getMirror(), + structurePlaceSettings.getRotation(), + structurePlaceSettings.getPosition()) + .add(Vec3d.of(structurePiecePos)); BlockPos globalBlockPos = StructureTemplate - .transformAround( - rawEntityItem.blockPos, - structurePlacementData.getMirror(), - structurePlacementData.getRotation(), - structurePlacementData.getPosition() - ).add(structurePiecePos); - - StructureEntityInfo globalEntityInfo = new StructureEntityInfo( - globalPos, - globalBlockPos, - rawEntityItem.nbt - ); - - // Apply processors - for (StructureProcessor processor : structurePlacementData.getProcessors()) { - if (!(processor instanceof StructureEntityProcessor)) { - continue; - } - - globalEntityInfo = ((StructureEntityProcessor) processor).processEntity( - serverWorldAccess, - structurePiecePos, - structurePieceBottomCenterPos, - rawEntityItem, - globalEntityInfo, - structurePlacementData - ); - - if (globalEntityInfo == null) { - break; + .transformAround(rawEntityInfo.blockPos, + structurePlaceSettings.getMirror(), + structurePlaceSettings.getRotation(), + structurePlaceSettings.getPosition()) + .add(structurePiecePos); + StructureTemplate.StructureEntityInfo globalEntityInfo = new StructureTemplate.StructureEntityInfo(globalPos, globalBlockPos, rawEntityInfo.nbt); + + for (StructureProcessor processor : structurePlaceSettings.getProcessors()) { + if (processor instanceof StructureEntityProcessor) { + globalEntityInfo = ((StructureEntityProcessor) processor).processEntity(serverLevelAccessor, structurePiecePos, structurePiecePivotPos, rawEntityInfo, globalEntityInfo, structurePlaceSettings); + if (globalEntityInfo == null) break; } } - // null value from processor indicates the entity should not be spawned if (globalEntityInfo != null) { processedEntities.add(globalEntityInfo); } @@ -212,12 +181,13 @@ private List friendsandfoes_processEntityInfos( return processedEntities; } - private static Optional friendsandfoes_getEntity( - ServerWorldAccess serverWorldAccess, + @Unique + private static Optional friendsandfoes_tryCreateEntity( + ServerWorldAccess serverLevelAccessor, NbtCompound compoundTag ) { try { - return EntityType.getEntityFromNbt(compoundTag, serverWorldAccess.toServerWorld()); + return EntityType.getEntityFromNbt(compoundTag, serverLevelAccessor.toServerWorld()); } catch (Exception exception) { return Optional.empty(); } diff --git a/fabric/src/main/java/com/faboslav/friendsandfoes/fabric/world/processor/IceologerCabinArmorStandProcessor.java b/fabric/src/main/java/com/faboslav/friendsandfoes/fabric/world/processor/IceologerCabinArmorStandProcessor.java index 2539e4479..f2d5ea00c 100644 --- a/fabric/src/main/java/com/faboslav/friendsandfoes/fabric/world/processor/IceologerCabinArmorStandProcessor.java +++ b/fabric/src/main/java/com/faboslav/friendsandfoes/fabric/world/processor/IceologerCabinArmorStandProcessor.java @@ -3,7 +3,7 @@ import com.faboslav.friendsandfoes.common.init.fabric.FriendsAndFoesStructureProcessorTypesImpl; import com.faboslav.friendsandfoes.common.util.world.processor.IceologerCabinArmorStandProcessorHelper; import com.mojang.serialization.Codec; -import com.yungnickyoung.minecraft.yungsapi.world.processor.StructureEntityProcessor; +import com.faboslav.friendsandfoes.common.world.processor.StructureEntityProcessor; import net.minecraft.structure.StructurePlacementData; import net.minecraft.structure.StructureTemplate; import net.minecraft.structure.processor.StructureProcessorType; diff --git a/fabric/src/main/java/com/faboslav/friendsandfoes/fabric/world/processor/IllusionerShackItemFrameProcessor.java b/fabric/src/main/java/com/faboslav/friendsandfoes/fabric/world/processor/IllusionerShackItemFrameProcessor.java index f7aedadac..4c9f916b7 100644 --- a/fabric/src/main/java/com/faboslav/friendsandfoes/fabric/world/processor/IllusionerShackItemFrameProcessor.java +++ b/fabric/src/main/java/com/faboslav/friendsandfoes/fabric/world/processor/IllusionerShackItemFrameProcessor.java @@ -3,7 +3,7 @@ import com.faboslav.friendsandfoes.common.init.fabric.FriendsAndFoesStructureProcessorTypesImpl; import com.faboslav.friendsandfoes.common.util.world.processor.IllusionerShackItemFrameProcessorHelper; import com.mojang.serialization.Codec; -import com.yungnickyoung.minecraft.yungsapi.world.processor.StructureEntityProcessor; +import com.faboslav.friendsandfoes.common.world.processor.StructureEntityProcessor; import net.minecraft.structure.StructurePlacementData; import net.minecraft.structure.StructureTemplate; import net.minecraft.structure.StructureTemplate.StructureEntityInfo;