diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a4b76b953..1b33c55ba 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d96302af5..ff23a68d7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists \ No newline at end of file +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index f5feea6d6..23d15a936 100755 --- a/gradlew +++ b/gradlew @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -115,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -206,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. @@ -214,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 9d21a2183..db3a6ac20 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/src/main/java/com/ldtteam/structurize/api/ItemStackUtils.java b/src/main/java/com/ldtteam/structurize/api/ItemStackUtils.java index d095c9fb9..6f8fd026a 100644 --- a/src/main/java/com/ldtteam/structurize/api/ItemStackUtils.java +++ b/src/main/java/com/ldtteam/structurize/api/ItemStackUtils.java @@ -193,7 +193,7 @@ public static List getListOfStackForEntity(final Entity entity) // process entity itself final ItemStack spawnItem = getEntitySpawningItem(entity); - if (spawnItem != null && !(spawnItem.getItem() instanceof SpawnEggItem)) + if (spawnItem != null && !(spawnItem.getItem() instanceof SpawnEggItem)) // TODO: 1.22 remove this here and move it to mcol { request.add(spawnItem); } diff --git a/src/main/java/com/ldtteam/structurize/blueprints/v1/Blueprint.java b/src/main/java/com/ldtteam/structurize/blueprints/v1/Blueprint.java index 5cd3feaee..69381dc73 100644 --- a/src/main/java/com/ldtteam/structurize/blueprints/v1/Blueprint.java +++ b/src/main/java/com/ldtteam/structurize/blueprints/v1/Blueprint.java @@ -25,7 +25,8 @@ import net.minecraft.nbt.Tag; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.decoration.HangingEntity; +import net.minecraft.world.entity.decoration.BlockAttachedEntity; +import net.minecraft.world.entity.decoration.Painting; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; @@ -801,13 +802,28 @@ private static CompoundTag transformEntityInfoWithSettings(final CompoundTag ent { finalEntity.load(entityInfo); - final Vec3 entityVec = rotationMirror - .applyToPos( - finalEntity instanceof HangingEntity hang ? Vec3.atCenterOf(hang.getPos()) : finalEntity.position()) - .add(Vec3.atLowerCornerOf(pos)); + Vec3 source = finalEntity.position(); + if (finalEntity instanceof BlockAttachedEntity attachedEntity) + { + source = Vec3.atCenterOf(attachedEntity.getPos()); + } + if (finalEntity instanceof Painting painting) + { + source = paitingToMiddle(painting); + } + + Vec3 target = rotationMirror.applyToPos(source).add(Vec3.atLowerCornerOf(pos)); + finalEntity.setYRot(finalEntity.mirror(rotationMirror.mirror())); finalEntity.setYRot(finalEntity.rotate(rotationMirror.rotation())); - finalEntity.moveTo(entityVec.x, entityVec.y, entityVec.z, finalEntity.getYRot(), finalEntity.getXRot()); + finalEntity.moveTo(target.x, target.y, target.z, finalEntity.getYRot(), finalEntity.getXRot()); + + if (finalEntity instanceof Painting painting) + { + // first we need painting to be at correct state (aabb, direction etc.), then we can fix it + target = paitingFromMiddle(painting, target); + finalEntity.moveTo(target.x, target.y, target.z, finalEntity.getYRot(), finalEntity.getXRot()); + } final CompoundTag newEntityInfo = new CompoundTag(); finalEntity.save(newEntityInfo); @@ -823,6 +839,16 @@ private static CompoundTag transformEntityInfoWithSettings(final CompoundTag ent return null; } + private static Vec3 paitingToMiddle(Painting painting) + { + return painting.getBoundingBox().getCenter(); + } + + private static Vec3 paitingFromMiddle(Painting painting, Vec3 middle) + { + return middle.add(Vec3.atLowerCornerOf(painting.getPos()).subtract(painting.getBoundingBox().getCenter())); + } + private int getVolume() { return (int) sizeX * sizeY * sizeZ; diff --git a/src/main/java/com/ldtteam/structurize/client/gui/WindowScan.java b/src/main/java/com/ldtteam/structurize/client/gui/WindowScan.java index dc562ff3d..ab704cdb9 100644 --- a/src/main/java/com/ldtteam/structurize/client/gui/WindowScan.java +++ b/src/main/java/com/ldtteam/structurize/client/gui/WindowScan.java @@ -6,7 +6,6 @@ import com.ldtteam.blockui.views.ScrollingList; import com.ldtteam.blockui.views.View; import com.ldtteam.structurize.api.ItemStorage; -import com.ldtteam.structurize.api.constants.Constants; import com.ldtteam.structurize.blockentities.interfaces.IBlueprintDataProviderBE; import com.ldtteam.structurize.network.messages.*; import com.ldtteam.structurize.placement.handlers.entity.EntityHandlers; @@ -17,8 +16,6 @@ import com.ldtteam.structurize.storage.rendering.types.BoxPreviewData; import com.ldtteam.structurize.util.BlockUtils; import com.ldtteam.structurize.util.ScanToolData; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; @@ -26,7 +23,6 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; diff --git a/src/main/java/com/ldtteam/structurize/placement/StructurePlacer.java b/src/main/java/com/ldtteam/structurize/placement/StructurePlacer.java index e358f13e4..d1e294a8d 100644 --- a/src/main/java/com/ldtteam/structurize/placement/StructurePlacer.java +++ b/src/main/java/com/ldtteam/structurize/placement/StructurePlacer.java @@ -1,7 +1,6 @@ package com.ldtteam.structurize.placement; import com.ldtteam.structurize.Structurize; -import com.ldtteam.structurize.api.ItemStackUtils; import com.ldtteam.structurize.api.Log; import com.ldtteam.structurize.blockentities.BlockEntityTagSubstitution; import com.ldtteam.structurize.blocks.ModBlocks; @@ -14,11 +13,8 @@ import com.ldtteam.structurize.util.ChangeStorage; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.entity.Display; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.Mob; -import net.minecraft.world.entity.decoration.HangingEntity; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.AirBlock; @@ -31,8 +27,6 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.DoubleBlockHalf; import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; import java.util.ArrayList; import java.util.List; @@ -350,67 +344,67 @@ public BlockPlacementResult handleEntitySpawn( final BlockPos worldPos, final BlockPos localPos, final ChangeStorage storage, - final boolean simulate) + final boolean simulate) { + final BlockPos zeroPos = this.handler.getWorldPos().subtract(handler.getBluePrint().getPrimaryBlockOffset()); + + nextEntity: for (final CompoundTag compound : this.iterator.getBluePrintPositionInfo(localPos).getEntities()) { - if (compound != null) + try { - try + final Optional> type = compound == null ? Optional.empty() : EntityType.by(compound); + if (type.isEmpty()) { - final BlockPos zeroPos = this.handler.getWorldPos().subtract(handler.getBluePrint().getPrimaryBlockOffset()); + continue; + } - final Optional> type = EntityType.by(compound); - if (type.isPresent()) - { - final Entity entity = type.get().create(world); - if (entity != null) - { - entity.load(compound); - - entity.setUUID(UUID.randomUUID()); - - IEntityHandler.ActionProcessingResult finalResult = IEntityHandler.ActionProcessingResult.DENY; - List requiredItems = List.of(); - for (final IEntityHandler entityHandler : EntityHandlers.handlers) - { - final IEntityHandler.ActionProcessingResult result = entityHandler.checkPlacement(handler, entity, zeroPos); - if (result != IEntityHandler.ActionProcessingResult.PASS) - { - finalResult = result; - requiredItems = entityHandler.getRequiredItems(entity).stream() - .filter(stack -> !stack.isEmpty()).toList(); - break; - } - } - if (finalResult != IEntityHandler.ActionProcessingResult.SUCCESS) - { - continue; - } + final Entity entity = type.get().create(world); + if (entity == null) + { + continue; + } - if (!handler.isCreative() && !handler.hasRequiredItems(requiredItems)) - { - return new BlockPlacementResult(worldPos, BlockPlacementResult.Result.MISSING_ITEMS, requiredItems); - } + entity.load(compound); - if (!simulate) - { - world.addFreshEntity(entity); - this.handler.consume(requiredItems); - this.handler.triggerEntitySuccess(localPos, requiredItems, true); - } - if (storage != null) - { - storage.addToBeKilledEntity(entity); - } - } + entity.setUUID(UUID.randomUUID()); + + List requiredItems = List.of(); + nextHandler: + for (final IEntityHandler entityHandler : EntityHandlers.handlers) + { + switch (entityHandler.checkPlacement(handler, entity, zeroPos)) + { + case DENY: + continue nextEntity; + case PASS: + continue nextHandler; + case SUCCESS: + requiredItems = entityHandler.getRequiredItems(entity).stream().filter(stack -> !stack.isEmpty()).toList(); + break nextHandler; } } - catch (final RuntimeException e) + + if (!handler.isCreative() && !handler.hasRequiredItems(requiredItems)) + { + return new BlockPlacementResult(worldPos, BlockPlacementResult.Result.MISSING_ITEMS, requiredItems); + } + + if (!simulate) + { + world.addFreshEntity(entity); + this.handler.consume(requiredItems); + this.handler.triggerEntitySuccess(localPos, requiredItems, true); + } + if (storage != null) { - Log.getLogger().info("Couldn't restore entity", e); + storage.addToBeKilledEntity(entity); } } + catch (final RuntimeException e) + { + Log.getLogger().info("Couldn't restore entity", e); + } } return new BlockPlacementResult(worldPos, BlockPlacementResult.Result.SUCCESS); diff --git a/src/main/java/com/ldtteam/structurize/placement/handlers/entity/EntityHandlers.java b/src/main/java/com/ldtteam/structurize/placement/handlers/entity/EntityHandlers.java index 7eff3e055..75013d851 100644 --- a/src/main/java/com/ldtteam/structurize/placement/handlers/entity/EntityHandlers.java +++ b/src/main/java/com/ldtteam/structurize/placement/handlers/entity/EntityHandlers.java @@ -1,16 +1,14 @@ package com.ldtteam.structurize.placement.handlers.entity; -import com.ldtteam.structurize.placement.structure.IStructureHandler; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Display; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.decoration.ArmorStand; -import net.minecraft.world.entity.decoration.HangingEntity; +import net.minecraft.world.entity.decoration.BlockAttachedEntity; import net.minecraft.world.entity.decoration.ItemFrame; import net.minecraft.world.entity.vehicle.ContainerEntity; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; import net.minecraft.world.item.SpawnEggItem; import net.minecraft.world.phys.Vec3; @@ -26,9 +24,9 @@ public final class EntityHandlers static { handlers.add(new MobEntityHandler()); - handlers.add(new TextDisplayHandler()); + handlers.add(new DisplayHandler()); handlers.add(new ItemFrameHandler()); - handlers.add(new HangingEntityHandler()); + handlers.add(new BlockAttachedEntityHandler()); handlers.add(new ArmorStandHandler()); handlers.add(new ContainerEntityHandler()); @@ -93,20 +91,25 @@ public boolean canPlace(final Entity entity, final boolean isCreative, final boo @Override public List getRequiredItems(final Entity entity) { - final SpawnEggItem egg = SpawnEggItem.byId(entity.getType()); - return egg == null ? List.of() : List.of(new ItemStack(egg)); + final List content = new ArrayList<>(IEntityHandler.super.getRequiredItems(entity)); + final SpawnEggItem egg = SpawnEggItem.byId(entity.getType()); // TODO: 1.22 remove this here and move it to mcol + if (egg != null) + { + content.add(new ItemStack(egg)); + } + return content; } } /** * Handler for text displays. */ - public static class TextDisplayHandler implements IEntityHandler + public static class DisplayHandler implements IEntityHandler { @Override public boolean canHandle(final Entity entity) { - return entity instanceof Display.TextDisplay; + return entity instanceof Display; } @Override @@ -125,39 +128,30 @@ public List getRequiredItems(final Entity entity) /** * Handler for item frames. */ - public static class ItemFrameHandler extends HangingEntityHandler + public static class ItemFrameHandler extends BlockAttachedEntityHandler { @Override public boolean canHandle(final Entity entity) { return entity instanceof ItemFrame; } - - @Override - public List getRequiredItems(final Entity entity) - { - final ItemFrame frameEntity = (ItemFrame) entity; - final ItemStack frame = frameEntity.getFrameItemStack().copyWithCount(1); - final ItemStack item = frameEntity.getItem().copyWithCount(1); - return List.of(frame, item); - } } /** * Handler for hanging entities (e.g. paintings). */ - public static class HangingEntityHandler implements IEntityHandler + public static class BlockAttachedEntityHandler implements IEntityHandler { @Override public boolean canHandle(final Entity entity) { - return entity instanceof HangingEntity; + return entity instanceof BlockAttachedEntity; } @Override public Vec3 adjustPosition(final Entity entity, final BlockPos zeroPos) { - final HangingEntity hang = (HangingEntity) entity; + final BlockAttachedEntity hang = (BlockAttachedEntity) entity; return IEntityHandler.super.adjustPosition(entity, zeroPos) .subtract(Vec3.atLowerCornerOf(hang.blockPosition().subtract(hang.getPos()))); } @@ -173,16 +167,6 @@ public boolean canHandle(final Entity entity) { return entity instanceof ArmorStand; } - - @Override - public List getRequiredItems(final Entity entity) - { - final ArmorStand stand = (ArmorStand) entity; - final List request = new ArrayList<>(IEntityHandler.super.getRequiredItems(entity)); - stand.getArmorSlots().forEach(request::add); - stand.getHandSlots().forEach(request::add); - return request; - } } /** @@ -195,14 +179,6 @@ public boolean canHandle(final Entity entity) { return entity instanceof ContainerEntity; } - - @Override - public List getRequiredItems(final Entity entity) - { - final List request = new ArrayList<>(IEntityHandler.super.getRequiredItems(entity)); - request.addAll(((ContainerEntity) entity).getItemStacks()); - return request; - } } /** diff --git a/src/main/java/com/ldtteam/structurize/placement/handlers/entity/IEntityHandler.java b/src/main/java/com/ldtteam/structurize/placement/handlers/entity/IEntityHandler.java index 540c15e45..41a9b3e5d 100644 --- a/src/main/java/com/ldtteam/structurize/placement/handlers/entity/IEntityHandler.java +++ b/src/main/java/com/ldtteam/structurize/placement/handlers/entity/IEntityHandler.java @@ -1,15 +1,11 @@ package com.ldtteam.structurize.placement.handlers.entity; -import com.ldtteam.structurize.placement.handlers.placement.IPlacementHandler; +import com.ldtteam.structurize.api.ItemStackUtils; import com.ldtteam.structurize.placement.structure.IStructureHandler; -import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.EntityHitResult; -import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import java.util.List; @@ -55,7 +51,7 @@ default Vec3 adjustPosition(final Entity entity, final BlockPos zeroPos) } /** - * Check if the entity should be placed. + * Check if the entity should be placed. Can be used to modify the entity before notifying both level and {@link Entity#onAddedToLevel()} * * @param handler the actor placing the entity. * @param entity the entity being placed. @@ -90,7 +86,7 @@ default ActionProcessingResult checkPlacement(final IStructureHandler handler, f */ default List getRequiredItems(final Entity entity) { - return List.of(Objects.requireNonNullElse(entity.getPickedResult(new EntityHitResult(entity)), ItemStack.EMPTY)); + return ItemStackUtils.getItemStacksOfEntity(entity); } /** @@ -101,7 +97,7 @@ default List getRequiredItems(final Entity entity) */ default ItemStack getIcon(final Entity entity) { - return Objects.requireNonNullElse(entity.getPickResult(), ItemStack.EMPTY); + return Objects.requireNonNullElse(ItemStackUtils.getEntitySpawningItem(entity), ItemStack.EMPTY); } /**