Skip to content

Commit

Permalink
Fixed aether incompatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Faboslav committed Nov 15, 2024
1 parent 8a09991 commit 076ec13
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 134 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- 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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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)
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -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<StructureTemplate.StructureEntityInfo> rawEntityInfos)
{
public StructureProcessingContext(
ServerWorldAccess serverWorldAccess,
StructurePlacementData structurePlacementData,
BlockPos structurePiecePos,
BlockPos structurePiecePivotPos,
List<StructureTemplate.StructureEntityInfo> rawEntityInfos
) {
this.serverWorldAccess = serverWorldAccess;
this.structurePlacementData = structurePlacementData;
this.structurePiecePos = structurePiecePos;
this.structurePiecePivotPos = structurePiecePivotPos;
this.rawEntityInfos = Util.make(() -> {
List<StructureTemplate.StructureEntityInfo> list = new ArrayList<>(rawEntityInfos.size());
rawEntityInfos.forEach((entityInfo) ->
list.add(new StructureTemplate.StructureEntityInfo(entityInfo.pos, entityInfo.blockPos, entityInfo.nbt)));
return list;
});
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand All @@ -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 (<a href="https://github.com/YUNG-GANG/">YUNGs-API</a>)
*/
@Mixin(StructureTemplate.class)
public final class StructureEntityProcessorMixin
Expand All @@ -45,17 +41,56 @@ public final class StructureEntityProcessorMixin
@Final
private List<StructureEntityInfo> 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<StructureProcessingContext> 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<Boolean> 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<Boolean> 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,
Expand All @@ -65,141 +100,79 @@ private void friendsandfoes_processEntities(
int flags,
CallbackInfoReturnable<Boolean> 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<StructureTemplate.StructureEntityInfo> 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(vec3d)
),
serverWorldAccess.getLocalDifficulty(new BlockPos(entityPos)),
SpawnReason.STRUCTURE,
null,
compoundTag
entityNbt
);
}

serverWorldAccess.spawnEntityAndPassengers(entity);
});
}
}
}

/**
* 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<StructureEntityInfo> friendsandfoes_processEntityInfos(
ServerWorldAccess serverWorldAccess,
BlockPos structurePiecePos,
BlockPos structurePieceBottomCenterPos,
StructurePlacementData structurePlacementData,
List<StructureEntityInfo> rawEntityList
) {
List<StructureEntityInfo> processedEntities = new ArrayList<>();
@Unique
private List<StructureTemplate.StructureEntityInfo> friendsandfoes_processEntityInfoList(StructureProcessingContext ctx) {
List<StructureTemplate.StructureEntityInfo> processedEntities = new ArrayList<>();

ServerWorldAccess serverLevelAccessor = ctx.serverWorldAccess();
BlockPos structurePiecePos = ctx.structurePiecePos();
BlockPos structurePiecePivotPos = ctx.structurePiecePivotPos();
StructurePlacementData structurePlaceSettings = ctx.structurePlacementData();
List<StructureTemplate.StructureEntityInfo> 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);
}
Expand All @@ -208,12 +181,13 @@ private List<StructureEntityInfo> friendsandfoes_processEntityInfos(
return processedEntities;
}

private static Optional<Entity> friendsandfoes_getEntity(
ServerWorldAccess serverWorldAccess,
@Unique
private static Optional<Entity> 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();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 076ec13

Please sign in to comment.