From b8ed85e519c81b47822855cd4d0e62f9b1ba3571 Mon Sep 17 00:00:00 2001 From: Arubik <102335860+ArubikU@users.noreply.github.com> Date: Thu, 3 Jul 2025 11:27:06 -0500 Subject: [PATCH 1/6] Add furniture spawn, remove, and replace functions Introduces SpawnFurnitureFunction, RemoveFurnitureFunction, and ReplaceFurnitureFunction for event contexts, enabling dynamic furniture manipulation via context functions. Adds BlockStateHitBox type and registration, with cleanup logic in BukkitFurniture. Updates parameter providers and function registries to support new features. --- .../entity/furniture/BukkitFurniture.java | 56 +++-- .../furniture/hitbox/BlockStateHitBox.java | 201 ++++++++++++++++++ .../furniture/hitbox/BukkitHitBoxTypes.java | 1 + .../core/entity/furniture/HitBoxTypes.java | 7 +- .../plugin/context/event/EventFunctions.java | 40 +++- .../context/function/CommonFunctions.java | 3 + .../function/RemoveFurnitureFunction.java | 60 ++++++ .../function/ReplaceFurnitureFunction.java | 109 ++++++++++ .../function/SpawnFurnitureFunction.java | 93 ++++++++ .../parameter/FurnitureParameterProvider.java | 13 +- 10 files changed, 560 insertions(+), 23 deletions(-) create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BlockStateHitBox.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/RemoveFurnitureFunction.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ReplaceFurnitureFunction.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SpawnFurnitureFunction.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java index ccc9c42cc..d62099b7b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java @@ -1,5 +1,32 @@ package net.momirealms.craftengine.bukkit.entity.furniture; +import java.io.IOException; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.Vector; + +import org.bukkit.Location; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.ItemDisplay; +import org.bukkit.entity.Player; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.joml.Quaternionf; +import org.joml.Vector3f; + import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import it.unimi.dsi.fastutil.ints.IntArrayList; import net.momirealms.craftengine.bukkit.entity.BukkitEntity; @@ -8,7 +35,16 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflect import net.momirealms.craftengine.bukkit.util.EntityUtils; import net.momirealms.craftengine.bukkit.util.LegacyAttributeUtils; import net.momirealms.craftengine.bukkit.util.LocationUtils; -import net.momirealms.craftengine.core.entity.furniture.*; +import net.momirealms.craftengine.core.entity.furniture.AnchorType; +import net.momirealms.craftengine.core.entity.furniture.Collider; +import net.momirealms.craftengine.core.entity.furniture.CustomFurniture; +import net.momirealms.craftengine.core.entity.furniture.ExternalModel; +import net.momirealms.craftengine.core.entity.furniture.Furniture; +import net.momirealms.craftengine.core.entity.furniture.FurnitureElement; +import net.momirealms.craftengine.core.entity.furniture.FurnitureExtraData; +import net.momirealms.craftengine.core.entity.furniture.FurnitureManager; +import net.momirealms.craftengine.core.entity.furniture.HitBox; +import net.momirealms.craftengine.core.entity.furniture.Seat; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.ArrayUtils; import net.momirealms.craftengine.core.util.Key; @@ -16,18 +52,6 @@ import net.momirealms.craftengine.core.util.QuaternionUtils; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.WorldPosition; import net.momirealms.craftengine.core.world.collision.AABB; -import org.bukkit.Location; -import org.bukkit.attribute.Attribute; -import org.bukkit.entity.*; -import org.bukkit.persistence.PersistentDataType; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.joml.Quaternionf; -import org.joml.Vector3f; - -import java.io.IOException; -import java.lang.ref.WeakReference; -import java.util.*; public class BukkitFurniture implements Furniture { private final Key id; @@ -184,6 +208,12 @@ public class BukkitFurniture implements Furniture { if (!isValid()) { return; } + // Clean up BlockStateHitBoxes before destroying the furniture + for (HitBox hitBox : this.hitBoxes.values()) { + if (hitBox instanceof net.momirealms.craftengine.bukkit.entity.furniture.hitbox.BlockStateHitBox) { + ((net.momirealms.craftengine.bukkit.entity.furniture.hitbox.BlockStateHitBox) hitBox).removePlacedBlock(); + } + } this.baseEntity().remove(); for (Collider entity : this.colliderEntities) { if (entity != null) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BlockStateHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BlockStateHitBox.java new file mode 100644 index 000000000..96ec5c235 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BlockStateHitBox.java @@ -0,0 +1,201 @@ +package net.momirealms.craftengine.bukkit.entity.furniture.hitbox; + +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import org.bukkit.Material; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +import net.momirealms.craftengine.bukkit.util.BlockStateUtils; +import net.momirealms.craftengine.core.block.BlockStateWrapper; +import net.momirealms.craftengine.core.entity.furniture.AbstractHitBox; +import net.momirealms.craftengine.core.entity.furniture.Collider; +import net.momirealms.craftengine.core.entity.furniture.HitBox; +import net.momirealms.craftengine.core.entity.furniture.HitBoxFactory; +import net.momirealms.craftengine.core.entity.furniture.HitBoxTypes; +import net.momirealms.craftengine.core.entity.furniture.Seat; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.LazyReference; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import net.momirealms.craftengine.core.world.World; +import net.momirealms.craftengine.core.world.WorldPosition; +import net.momirealms.craftengine.core.world.collision.AABB; + +public class BlockStateHitBox extends AbstractHitBox { + public static final Factory FACTORY = new Factory(); + + private final LazyReference lazyBlockState; + private final boolean dropContainer; + private WorldPosition placedPosition; + private BlockStateWrapper originalBlockState; + + public BlockStateHitBox(Seat[] seats, Vector3f position, LazyReference lazyBlockState, + boolean canUseOn, boolean blocksBuilding, boolean canBeHitByProjectile, boolean dropContainer) { + super(seats, position, canUseOn, blocksBuilding, canBeHitByProjectile); + this.lazyBlockState = lazyBlockState; + this.dropContainer = dropContainer; + } + + public LazyReference blockState() { + return lazyBlockState; + } + + public boolean dropContainer() { + return dropContainer; + } + + @Override + public Key type() { + return HitBoxTypes.BLOCKSTATE; + } + + @Override + public void initPacketsAndColliders(int[] entityId, WorldPosition position, Quaternionf conjugated, + BiConsumer packets, Consumer collider, + BiConsumer aabb) { + Vector3f offset = conjugated.transform(new Vector3f(position())); + World world = position.world(); + int blockX = (int) Math.floor(position.x() + offset.x); + int blockY = (int) Math.floor(position.y() + offset.y); + int blockZ = (int) Math.floor(position.z() - offset.z); + + // Store the placed position for later removal + this.placedPosition = new WorldPosition(world, blockX, blockY, blockZ); + + // Store the original block state before placing our block + try { + // Get the bukkit block data from the world + org.bukkit.World bukkitWorld = (org.bukkit.World) world.platformWorld(); + org.bukkit.block.data.BlockData blockData = bukkitWorld.getBlockAt(blockX, blockY, blockZ).getBlockData(); + this.originalBlockState = BlockStateUtils.toPackedBlockState(blockData); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to get original block state", e); + // Fallback to air + this.originalBlockState = CraftEngine.instance().blockManager().createPackedBlockState("minecraft:air"); + } + + // Place the block + BlockStateWrapper blockStateWrapper = lazyBlockState.get(); + if (blockStateWrapper != null) { + world.setBlockAt(blockX, blockY, blockZ, blockStateWrapper, 3); // UPDATE_ALL flags + } + + // If the block can be used on, add AABB for interaction + if (canUseItemOn()) { + aabb.accept(entityId[0], new AABB(blockX, blockY, blockZ, blockX + 1, blockY + 1, blockZ + 1)); + } + } + + @Override + public void initShapeForPlacement(double x, double y, double z, float yaw, Quaternionf conjugated, Consumer aabbs) { + if (blocksBuilding()) { + Vector3f offset = conjugated.transform(new Vector3f(position())); + int blockX = (int) Math.floor(x + offset.x); + int blockY = (int) Math.floor(y + offset.y); + int blockZ = (int) Math.floor(z - offset.z); + aabbs.accept(new AABB(blockX, blockY, blockZ, blockX + 1, blockY + 1, blockZ + 1)); + } + } + + @Override + public int[] acquireEntityIds(Supplier entityIdSupplier) { + return new int[] {entityIdSupplier.get()}; + } + + /** + * Removes the placed block and handles container drops if needed + */ + public void removePlacedBlock() { + if (placedPosition == null) return; + + World world = placedPosition.world(); + int x = (int) placedPosition.x(); + int y = (int) placedPosition.y(); + int z = (int) placedPosition.z(); + + // Drop container contents if the flag is enabled + if (dropContainer) { + dropContainerContents(world, x, y, z); + } + + // Restore the original block state + if (originalBlockState != null) { + world.setBlockAt(x, y, z, originalBlockState, 3); + } else { + // Fallback to air if no original state was stored + BlockStateWrapper airState = CraftEngine.instance().blockManager().createPackedBlockState("minecraft:air"); + if (airState != null) { + world.setBlockAt(x, y, z, airState, 3); + } + } + } + + /** + * Drops the contents of a container block + */ + private void dropContainerContents(World world, int x, int y, int z) { + try { + // Get the bukkit world and block + org.bukkit.World bukkitWorld = (org.bukkit.World) world.platformWorld(); + if (bukkitWorld == null) return; + + org.bukkit.block.Block block = bukkitWorld.getBlockAt(x, y, z); + if (block.getState() instanceof InventoryHolder inventoryHolder) { + org.bukkit.inventory.Inventory inventory = inventoryHolder.getInventory(); + org.bukkit.Location dropLocation = block.getLocation().add(0.5, 0.5, 0.5); + + // Drop all items in the inventory + for (ItemStack itemStack : inventory.getContents()) { + if (itemStack != null && itemStack.getType() != Material.AIR) { + bukkitWorld.dropItemNaturally(dropLocation, itemStack); + } + } + + // Clear the inventory + inventory.clear(); + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to drop container contents for BlockStateHitBox", e); + } + } + + public static class Factory implements HitBoxFactory { + + @Override + public HitBox create(Map arguments) { + Vector3f position = net.momirealms.craftengine.core.util.MiscUtils.getAsVector3f( + arguments.getOrDefault("position", "0"), "position"); + + String blockStateString = ResourceConfigUtils.requireNonEmptyStringOrThrow( + arguments.get("block-state"), "warning.config.furniture.hitbox.blockstate.missing_block_state"); + + boolean canUseOn = ResourceConfigUtils.getAsBoolean( + arguments.getOrDefault("can-use-item-on", false), "can-use-item-on"); + boolean blocksBuilding = ResourceConfigUtils.getAsBoolean( + arguments.getOrDefault("blocks-building", true), "blocks-building"); + boolean canBeHitByProjectile = ResourceConfigUtils.getAsBoolean( + arguments.getOrDefault("can-be-hit-by-projectile", false), "can-be-hit-by-projectile"); + boolean dropContainer = ResourceConfigUtils.getAsBoolean( + arguments.getOrDefault("drop-container", true), "drop-container"); + + LazyReference lazyBlockState = LazyReference.lazyReference( + () -> CraftEngine.instance().blockManager().createPackedBlockState(blockStateString)); + + return new BlockStateHitBox( + HitBoxFactory.getSeats(arguments), + position, + lazyBlockState, + canUseOn, + blocksBuilding, + canBeHitByProjectile, + dropContainer + ); + } + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BukkitHitBoxTypes.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BukkitHitBoxTypes.java index dda752638..0a152f5ca 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BukkitHitBoxTypes.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BukkitHitBoxTypes.java @@ -11,5 +11,6 @@ public class BukkitHitBoxTypes extends HitBoxTypes { register(SHULKER, ShulkerHitBox.FACTORY); register(HAPPY_GHAST, HappyGhastHitBox.FACTORY); register(CUSTOM, CustomHitBox.FACTORY); + register(BLOCKSTATE, BlockStateHitBox.FACTORY); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxTypes.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxTypes.java index f77435813..ba595b4f7 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxTypes.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxTypes.java @@ -1,5 +1,8 @@ package net.momirealms.craftengine.core.entity.furniture; +import java.util.Map; +import java.util.Optional; + import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; @@ -8,14 +11,12 @@ import net.momirealms.craftengine.core.registry.WritableRegistry; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.ResourceKey; -import java.util.Map; -import java.util.Optional; - public class HitBoxTypes { public static final Key INTERACTION = Key.of("minecraft:interaction"); public static final Key SHULKER = Key.of("minecraft:shulker"); public static final Key HAPPY_GHAST = Key.of("minecraft:happy_ghast"); public static final Key CUSTOM = Key.of("minecraft:custom"); + public static final Key BLOCKSTATE = Key.of("minecraft:blockstate"); public static void register(Key key, HitBoxFactory factory) { Holder.Reference holder = ((WritableRegistry) BuiltInRegistries.HITBOX_FACTORY) diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java index 8613eb5c4..a59629618 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java @@ -1,7 +1,40 @@ package net.momirealms.craftengine.core.plugin.context.event; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext; -import net.momirealms.craftengine.core.plugin.context.function.*; +import net.momirealms.craftengine.core.plugin.context.function.ActionBarFunction; +import net.momirealms.craftengine.core.plugin.context.function.BreakBlockFunction; +import net.momirealms.craftengine.core.plugin.context.function.CancelEventFunction; +import net.momirealms.craftengine.core.plugin.context.function.CommandFunction; +import net.momirealms.craftengine.core.plugin.context.function.CommonFunctions; +import net.momirealms.craftengine.core.plugin.context.function.DropLootFunction; +import net.momirealms.craftengine.core.plugin.context.function.Function; +import net.momirealms.craftengine.core.plugin.context.function.FunctionFactory; +import net.momirealms.craftengine.core.plugin.context.function.LevelerExpFunction; +import net.momirealms.craftengine.core.plugin.context.function.MessageFunction; +import net.momirealms.craftengine.core.plugin.context.function.OpenWindowFunction; +import net.momirealms.craftengine.core.plugin.context.function.ParticleFunction; +import net.momirealms.craftengine.core.plugin.context.function.PlaceBlockFunction; +import net.momirealms.craftengine.core.plugin.context.function.PlaySoundFunction; +import net.momirealms.craftengine.core.plugin.context.function.PotionEffectFunction; +import net.momirealms.craftengine.core.plugin.context.function.RemoveCooldownFunction; +import net.momirealms.craftengine.core.plugin.context.function.RemoveFurnitureFunction; +import net.momirealms.craftengine.core.plugin.context.function.RemovePotionEffectFunction; +import net.momirealms.craftengine.core.plugin.context.function.ReplaceFurnitureFunction; +import net.momirealms.craftengine.core.plugin.context.function.RunFunction; +import net.momirealms.craftengine.core.plugin.context.function.SetCooldownFunction; +import net.momirealms.craftengine.core.plugin.context.function.SetCountFunction; +import net.momirealms.craftengine.core.plugin.context.function.SetFoodFunction; +import net.momirealms.craftengine.core.plugin.context.function.SetSaturationFunction; +import net.momirealms.craftengine.core.plugin.context.function.SpawnFurnitureFunction; +import net.momirealms.craftengine.core.plugin.context.function.SwingHandFunction; +import net.momirealms.craftengine.core.plugin.context.function.TitleFunction; +import net.momirealms.craftengine.core.plugin.context.function.UpdateInteractionFunction; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; @@ -12,8 +45,6 @@ import net.momirealms.craftengine.core.util.MiscUtils; import net.momirealms.craftengine.core.util.ResourceConfigUtils; import net.momirealms.craftengine.core.util.ResourceKey; -import java.util.*; - public class EventFunctions { static { @@ -39,6 +70,9 @@ public class EventFunctions { register(CommonFunctions.LEVELER_EXP, new LevelerExpFunction.FactoryImpl<>(EventConditions::fromMap)); register(CommonFunctions.SET_COOLDOWN, new SetCooldownFunction.FactoryImpl<>(EventConditions::fromMap)); register(CommonFunctions.REMOVE_COOLDOWN, new RemoveCooldownFunction.FactoryImpl<>(EventConditions::fromMap)); + register(CommonFunctions.SPAWN_FURNITURE, new SpawnFurnitureFunction.FactoryImpl<>(EventConditions::fromMap)); + register(CommonFunctions.REMOVE_FURNITURE, new RemoveFurnitureFunction.FactoryImpl<>(EventConditions::fromMap)); + register(CommonFunctions.REPLACE_FURNITURE, new ReplaceFurnitureFunction.FactoryImpl<>(EventConditions::fromMap)); } public static void register(Key key, FunctionFactory factory) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommonFunctions.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommonFunctions.java index 8c0bc6435..f81794979 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommonFunctions.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommonFunctions.java @@ -27,4 +27,7 @@ public final class CommonFunctions { public static final Key DROP_LOOT = Key.of("craftengine:drop_loot"); public static final Key SWING_HAND = Key.of("craftengine:swing_hand"); public static final Key LEVELER_EXP = Key.of("craftengine:leveler_exp"); + public static final Key SPAWN_FURNITURE = Key.of("craftengine:spawn_furniture"); + public static final Key REMOVE_FURNITURE = Key.of("craftengine:remove_furniture"); + public static final Key REPLACE_FURNITURE = Key.of("craftengine:replace_furniture"); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/RemoveFurnitureFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/RemoveFurnitureFunction.java new file mode 100644 index 000000000..7acd7f40d --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/RemoveFurnitureFunction.java @@ -0,0 +1,60 @@ +package net.momirealms.craftengine.core.plugin.context.function; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import net.momirealms.craftengine.core.entity.furniture.Furniture; +import net.momirealms.craftengine.core.plugin.context.Condition; +import net.momirealms.craftengine.core.plugin.context.Context; +import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import net.momirealms.craftengine.core.world.WorldPosition; + +public class RemoveFurnitureFunction extends AbstractConditionalFunction { + private final boolean dropLoot; + private final boolean playSound; + + public RemoveFurnitureFunction(boolean dropLoot, boolean playSound, List> predicates) { + super(predicates); + this.dropLoot = dropLoot; + this.playSound = playSound; + } + + @Override + public void runInternal(CTX ctx) { + Optional optionalWorldPosition = ctx.getOptionalParameter(DirectContextParameters.POSITION); + if (optionalWorldPosition.isPresent()) { + // Buscar muebles en el contexto + Optional optionalFurniture = ctx.getOptionalParameter(DirectContextParameters.FURNITURE); + if (optionalFurniture.isPresent()) { + Furniture furniture = optionalFurniture.get(); + if (furniture.isValid()) { + furniture.destroy(); + // TODO: Implementar lógica para dropear loot y reproducir sonidos + // usando this.dropLoot y this.playSound cuando sea necesario + } + } + } + } + + @Override + public Key type() { + return CommonFunctions.REMOVE_FURNITURE; + } + + public static class FactoryImpl extends AbstractFactory { + + public FactoryImpl(java.util.function.Function, Condition> factory) { + super(factory); + } + + @Override + public Function create(Map arguments) { + boolean dropLoot = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("drop-loot", true), "drop-loot"); + boolean playSound = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("play-sound", true), "play-sound"); + return new RemoveFurnitureFunction<>(dropLoot, playSound, getPredicates(arguments)); + } + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ReplaceFurnitureFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ReplaceFurnitureFunction.java new file mode 100644 index 000000000..15a903a51 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ReplaceFurnitureFunction.java @@ -0,0 +1,109 @@ +package net.momirealms.craftengine.core.plugin.context.function; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import net.momirealms.craftengine.core.entity.furniture.AnchorType; +import net.momirealms.craftengine.core.entity.furniture.CustomFurniture; +import net.momirealms.craftengine.core.entity.furniture.Furniture; +import net.momirealms.craftengine.core.entity.furniture.FurnitureExtraData; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.context.Condition; +import net.momirealms.craftengine.core.plugin.context.Context; +import net.momirealms.craftengine.core.plugin.context.number.NumberProvider; +import net.momirealms.craftengine.core.plugin.context.number.NumberProviders; +import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import net.momirealms.craftengine.core.world.WorldPosition; + +public class ReplaceFurnitureFunction extends AbstractConditionalFunction { + private final Key newFurnitureId; + private final NumberProvider x; + private final NumberProvider y; + private final NumberProvider z; + private final NumberProvider pitch; + private final NumberProvider yaw; + private final AnchorType anchorType; + private final boolean dropLoot; + private final boolean playSound; + + public ReplaceFurnitureFunction(Key newFurnitureId, NumberProvider x, NumberProvider y, NumberProvider z, + NumberProvider pitch, NumberProvider yaw, AnchorType anchorType, + boolean dropLoot, boolean playSound, List> predicates) { + super(predicates); + this.newFurnitureId = newFurnitureId; + this.x = x; + this.y = y; + this.z = z; + this.pitch = pitch; + this.yaw = yaw; + this.anchorType = anchorType; + this.dropLoot = dropLoot; + this.playSound = playSound; + } + + @Override + public void runInternal(CTX ctx) { + Optional optionalWorldPosition = ctx.getOptionalParameter(DirectContextParameters.POSITION); + Optional optionalOldFurniture = ctx.getOptionalParameter(DirectContextParameters.FURNITURE); + + if (optionalWorldPosition.isPresent() && optionalOldFurniture.isPresent()) { + Furniture oldFurniture = optionalOldFurniture.get(); + + // Obtener la nueva posición o usar la actual del mueble + double xPos = this.x.getDouble(ctx); + double yPos = this.y.getDouble(ctx); + double zPos = this.z.getDouble(ctx); + float pitchValue = this.pitch.getFloat(ctx); + float yawValue = this.yaw.getFloat(ctx); + + WorldPosition newPosition = new WorldPosition(optionalWorldPosition.get().world(), xPos, yPos, zPos, pitchValue, yawValue); + + // Obtener el nuevo mueble + Optional optionalNewFurniture = CraftEngine.instance().furnitureManager().furnitureById(this.newFurnitureId); + if (optionalNewFurniture.isPresent()) { + CustomFurniture newFurniture = optionalNewFurniture.get(); + AnchorType anchor = this.anchorType != null ? this.anchorType : newFurniture.getAnyAnchorType(); + + // Remover el mueble antiguo + if (oldFurniture.isValid()) { + oldFurniture.destroy(); + // TODO: Implementar lógica para dropear loot usando this.dropLoot + } + + // Colocar el nuevo mueble + FurnitureExtraData extraData = FurnitureExtraData.builder().anchorType(anchor).build(); + CraftEngine.instance().furnitureManager().place(newPosition, newFurniture, extraData, this.playSound); + } + } + } + + @Override + public Key type() { + return CommonFunctions.REPLACE_FURNITURE; + } + + public static class FactoryImpl extends AbstractFactory { + + public FactoryImpl(java.util.function.Function, Condition> factory) { + super(factory); + } + + @Override + public Function create(Map arguments) { + String furnitureIdStr = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("furniture-id"), "warning.config.function.replace_furniture.missing_furniture_id"); + Key furnitureId = Key.of(furnitureIdStr); + NumberProvider x = NumberProviders.fromObject(arguments.getOrDefault("x", "")); + NumberProvider y = NumberProviders.fromObject(arguments.getOrDefault("y", "")); + NumberProvider z = NumberProviders.fromObject(arguments.getOrDefault("z", "")); + NumberProvider pitch = NumberProviders.fromObject(arguments.getOrDefault("pitch", "")); + NumberProvider yaw = NumberProviders.fromObject(arguments.getOrDefault("yaw", "")); + AnchorType anchorType = Optional.ofNullable(arguments.get("anchor-type")).map(o -> AnchorType.valueOf(o.toString().toUpperCase())).orElse(null); + boolean dropLoot = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("drop-loot", true), "drop-loot"); + boolean playSound = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("play-sound", true), "play-sound"); + return new ReplaceFurnitureFunction<>(furnitureId, x, y, z, pitch, yaw, anchorType, dropLoot, playSound, getPredicates(arguments)); + } + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SpawnFurnitureFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SpawnFurnitureFunction.java new file mode 100644 index 000000000..e18a1e8f4 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/SpawnFurnitureFunction.java @@ -0,0 +1,93 @@ +package net.momirealms.craftengine.core.plugin.context.function; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import net.momirealms.craftengine.core.entity.furniture.AnchorType; +import net.momirealms.craftengine.core.entity.furniture.CustomFurniture; +import net.momirealms.craftengine.core.entity.furniture.FurnitureExtraData; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.context.Condition; +import net.momirealms.craftengine.core.plugin.context.Context; +import net.momirealms.craftengine.core.plugin.context.number.NumberProvider; +import net.momirealms.craftengine.core.plugin.context.number.NumberProviders; +import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import net.momirealms.craftengine.core.world.World; +import net.momirealms.craftengine.core.world.WorldPosition; + +public class SpawnFurnitureFunction extends AbstractConditionalFunction { + private final Key furnitureId; + private final NumberProvider x; + private final NumberProvider y; + private final NumberProvider z; + private final NumberProvider pitch; + private final NumberProvider yaw; + private final AnchorType anchorType; + private final boolean playSound; + + public SpawnFurnitureFunction(Key furnitureId, NumberProvider x, NumberProvider y, NumberProvider z, + NumberProvider pitch, NumberProvider yaw, AnchorType anchorType, + boolean playSound, List> predicates) { + super(predicates); + this.furnitureId = furnitureId; + this.x = x; + this.y = y; + this.z = z; + this.pitch = pitch; + this.yaw = yaw; + this.anchorType = anchorType; + this.playSound = playSound; + } + + @Override + public void runInternal(CTX ctx) { + Optional optionalWorldPosition = ctx.getOptionalParameter(DirectContextParameters.POSITION); + if (optionalWorldPosition.isPresent()) { + World world = optionalWorldPosition.get().world(); + double xPos = this.x.getDouble(ctx); + double yPos = this.y.getDouble(ctx); + double zPos = this.z.getDouble(ctx); + float pitchValue = this.pitch.getFloat(ctx); + float yawValue = this.yaw.getFloat(ctx); + + WorldPosition position = new WorldPosition(world, xPos, yPos, zPos, pitchValue, yawValue); + + Optional optionalFurniture = CraftEngine.instance().furnitureManager().furnitureById(this.furnitureId); + if (optionalFurniture.isPresent()) { + CustomFurniture furniture = optionalFurniture.get(); + AnchorType anchor = this.anchorType != null ? this.anchorType : furniture.getAnyAnchorType(); + FurnitureExtraData extraData = FurnitureExtraData.builder().anchorType(anchor).build(); + CraftEngine.instance().furnitureManager().place(position, furniture, extraData, this.playSound); + } + } + } + + @Override + public Key type() { + return CommonFunctions.SPAWN_FURNITURE; + } + + public static class FactoryImpl extends AbstractFactory { + + public FactoryImpl(java.util.function.Function, Condition> factory) { + super(factory); + } + + @Override + public Function create(Map arguments) { + String furnitureIdStr = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("furniture-id"), "warning.config.function.spawn_furniture.missing_furniture_id"); + Key furnitureId = Key.of(furnitureIdStr); + NumberProvider x = NumberProviders.fromObject(arguments.getOrDefault("x", "")); + NumberProvider y = NumberProviders.fromObject(arguments.getOrDefault("y", "")); + NumberProvider z = NumberProviders.fromObject(arguments.getOrDefault("z", "")); + NumberProvider pitch = NumberProviders.fromObject(arguments.getOrDefault("pitch", "")); + NumberProvider yaw = NumberProviders.fromObject(arguments.getOrDefault("yaw", "")); + AnchorType anchorType = Optional.ofNullable(arguments.get("anchor-type")).map(o -> AnchorType.valueOf(o.toString().toUpperCase())).orElse(null); + boolean playSound = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("play-sound", true), "play-sound"); + return new SpawnFurnitureFunction<>(furnitureId, x, y, z, pitch, yaw, anchorType, playSound, getPredicates(arguments)); + } + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/parameter/FurnitureParameterProvider.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/parameter/FurnitureParameterProvider.java index 2f49aca37..3b06b968f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/parameter/FurnitureParameterProvider.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/parameter/FurnitureParameterProvider.java @@ -1,20 +1,25 @@ package net.momirealms.craftengine.core.plugin.context.parameter; -import net.momirealms.craftengine.core.entity.furniture.Furniture; -import net.momirealms.craftengine.core.plugin.context.ChainParameterProvider; -import net.momirealms.craftengine.core.plugin.context.ContextKey; - import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.function.Function; +import net.momirealms.craftengine.core.entity.furniture.Furniture; +import net.momirealms.craftengine.core.plugin.context.ChainParameterProvider; +import net.momirealms.craftengine.core.plugin.context.ContextKey; + public class FurnitureParameterProvider implements ChainParameterProvider { private static final Map, Function> CONTEXT_FUNCTIONS = new HashMap<>(); static { CONTEXT_FUNCTIONS.put(DirectContextParameters.ID, Furniture::id); CONTEXT_FUNCTIONS.put(DirectContextParameters.UUID, Furniture::uuid); CONTEXT_FUNCTIONS.put(DirectContextParameters.ANCHOR_TYPE, Furniture::anchorType); + CONTEXT_FUNCTIONS.put(DirectContextParameters.X, furniture -> furniture.position().x()); + CONTEXT_FUNCTIONS.put(DirectContextParameters.Y, furniture -> furniture.position().y()); + CONTEXT_FUNCTIONS.put(DirectContextParameters.Z, furniture -> furniture.position().z()); + CONTEXT_FUNCTIONS.put(DirectContextParameters.PITCH, furniture -> furniture.position().yRot()); + CONTEXT_FUNCTIONS.put(DirectContextParameters.YAW, furniture -> furniture.position().xRot()); } @SuppressWarnings("unchecked") From 5820df920896cefdd0b4745698be4e6db3f97179 Mon Sep 17 00:00:00 2001 From: Arubik <102335860+ArubikU@users.noreply.github.com> Date: Thu, 3 Jul 2025 11:27:56 -0500 Subject: [PATCH 2/6] Update .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4a412a23f..b914f987b 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,5 @@ build/ .idea/ !/libs/*.jar -!/gradle/wrapper/*.jar \ No newline at end of file +!/gradle/wrapper/*.jar +.vscode/settings.json From c3b49c95abf3bf2455692527643669ff31e6f6c2 Mon Sep 17 00:00:00 2001 From: Arubik <102335860+ArubikU@users.noreply.github.com> Date: Thu, 3 Jul 2025 12:15:02 -0500 Subject: [PATCH 3/6] Removed BlockstateHitbox --- .../entity/furniture/BukkitFurniture.java | 6 - .../furniture/hitbox/BlockStateHitBox.java | 201 ------------------ .../furniture/hitbox/BukkitHitBoxTypes.java | 1 - .../core/entity/furniture/HitBoxTypes.java | 1 - 4 files changed, 209 deletions(-) delete mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BlockStateHitBox.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java index d62099b7b..b3aa0479c 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java @@ -208,12 +208,6 @@ public class BukkitFurniture implements Furniture { if (!isValid()) { return; } - // Clean up BlockStateHitBoxes before destroying the furniture - for (HitBox hitBox : this.hitBoxes.values()) { - if (hitBox instanceof net.momirealms.craftengine.bukkit.entity.furniture.hitbox.BlockStateHitBox) { - ((net.momirealms.craftengine.bukkit.entity.furniture.hitbox.BlockStateHitBox) hitBox).removePlacedBlock(); - } - } this.baseEntity().remove(); for (Collider entity : this.colliderEntities) { if (entity != null) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BlockStateHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BlockStateHitBox.java deleted file mode 100644 index 96ec5c235..000000000 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BlockStateHitBox.java +++ /dev/null @@ -1,201 +0,0 @@ -package net.momirealms.craftengine.bukkit.entity.furniture.hitbox; - -import java.util.Map; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Supplier; - -import org.bukkit.Material; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.joml.Quaternionf; -import org.joml.Vector3f; - -import net.momirealms.craftengine.bukkit.util.BlockStateUtils; -import net.momirealms.craftengine.core.block.BlockStateWrapper; -import net.momirealms.craftengine.core.entity.furniture.AbstractHitBox; -import net.momirealms.craftengine.core.entity.furniture.Collider; -import net.momirealms.craftengine.core.entity.furniture.HitBox; -import net.momirealms.craftengine.core.entity.furniture.HitBoxFactory; -import net.momirealms.craftengine.core.entity.furniture.HitBoxTypes; -import net.momirealms.craftengine.core.entity.furniture.Seat; -import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.util.Key; -import net.momirealms.craftengine.core.util.LazyReference; -import net.momirealms.craftengine.core.util.ResourceConfigUtils; -import net.momirealms.craftengine.core.world.World; -import net.momirealms.craftengine.core.world.WorldPosition; -import net.momirealms.craftengine.core.world.collision.AABB; - -public class BlockStateHitBox extends AbstractHitBox { - public static final Factory FACTORY = new Factory(); - - private final LazyReference lazyBlockState; - private final boolean dropContainer; - private WorldPosition placedPosition; - private BlockStateWrapper originalBlockState; - - public BlockStateHitBox(Seat[] seats, Vector3f position, LazyReference lazyBlockState, - boolean canUseOn, boolean blocksBuilding, boolean canBeHitByProjectile, boolean dropContainer) { - super(seats, position, canUseOn, blocksBuilding, canBeHitByProjectile); - this.lazyBlockState = lazyBlockState; - this.dropContainer = dropContainer; - } - - public LazyReference blockState() { - return lazyBlockState; - } - - public boolean dropContainer() { - return dropContainer; - } - - @Override - public Key type() { - return HitBoxTypes.BLOCKSTATE; - } - - @Override - public void initPacketsAndColliders(int[] entityId, WorldPosition position, Quaternionf conjugated, - BiConsumer packets, Consumer collider, - BiConsumer aabb) { - Vector3f offset = conjugated.transform(new Vector3f(position())); - World world = position.world(); - int blockX = (int) Math.floor(position.x() + offset.x); - int blockY = (int) Math.floor(position.y() + offset.y); - int blockZ = (int) Math.floor(position.z() - offset.z); - - // Store the placed position for later removal - this.placedPosition = new WorldPosition(world, blockX, blockY, blockZ); - - // Store the original block state before placing our block - try { - // Get the bukkit block data from the world - org.bukkit.World bukkitWorld = (org.bukkit.World) world.platformWorld(); - org.bukkit.block.data.BlockData blockData = bukkitWorld.getBlockAt(blockX, blockY, blockZ).getBlockData(); - this.originalBlockState = BlockStateUtils.toPackedBlockState(blockData); - } catch (Exception e) { - CraftEngine.instance().logger().warn("Failed to get original block state", e); - // Fallback to air - this.originalBlockState = CraftEngine.instance().blockManager().createPackedBlockState("minecraft:air"); - } - - // Place the block - BlockStateWrapper blockStateWrapper = lazyBlockState.get(); - if (blockStateWrapper != null) { - world.setBlockAt(blockX, blockY, blockZ, blockStateWrapper, 3); // UPDATE_ALL flags - } - - // If the block can be used on, add AABB for interaction - if (canUseItemOn()) { - aabb.accept(entityId[0], new AABB(blockX, blockY, blockZ, blockX + 1, blockY + 1, blockZ + 1)); - } - } - - @Override - public void initShapeForPlacement(double x, double y, double z, float yaw, Quaternionf conjugated, Consumer aabbs) { - if (blocksBuilding()) { - Vector3f offset = conjugated.transform(new Vector3f(position())); - int blockX = (int) Math.floor(x + offset.x); - int blockY = (int) Math.floor(y + offset.y); - int blockZ = (int) Math.floor(z - offset.z); - aabbs.accept(new AABB(blockX, blockY, blockZ, blockX + 1, blockY + 1, blockZ + 1)); - } - } - - @Override - public int[] acquireEntityIds(Supplier entityIdSupplier) { - return new int[] {entityIdSupplier.get()}; - } - - /** - * Removes the placed block and handles container drops if needed - */ - public void removePlacedBlock() { - if (placedPosition == null) return; - - World world = placedPosition.world(); - int x = (int) placedPosition.x(); - int y = (int) placedPosition.y(); - int z = (int) placedPosition.z(); - - // Drop container contents if the flag is enabled - if (dropContainer) { - dropContainerContents(world, x, y, z); - } - - // Restore the original block state - if (originalBlockState != null) { - world.setBlockAt(x, y, z, originalBlockState, 3); - } else { - // Fallback to air if no original state was stored - BlockStateWrapper airState = CraftEngine.instance().blockManager().createPackedBlockState("minecraft:air"); - if (airState != null) { - world.setBlockAt(x, y, z, airState, 3); - } - } - } - - /** - * Drops the contents of a container block - */ - private void dropContainerContents(World world, int x, int y, int z) { - try { - // Get the bukkit world and block - org.bukkit.World bukkitWorld = (org.bukkit.World) world.platformWorld(); - if (bukkitWorld == null) return; - - org.bukkit.block.Block block = bukkitWorld.getBlockAt(x, y, z); - if (block.getState() instanceof InventoryHolder inventoryHolder) { - org.bukkit.inventory.Inventory inventory = inventoryHolder.getInventory(); - org.bukkit.Location dropLocation = block.getLocation().add(0.5, 0.5, 0.5); - - // Drop all items in the inventory - for (ItemStack itemStack : inventory.getContents()) { - if (itemStack != null && itemStack.getType() != Material.AIR) { - bukkitWorld.dropItemNaturally(dropLocation, itemStack); - } - } - - // Clear the inventory - inventory.clear(); - } - } catch (Exception e) { - CraftEngine.instance().logger().warn("Failed to drop container contents for BlockStateHitBox", e); - } - } - - public static class Factory implements HitBoxFactory { - - @Override - public HitBox create(Map arguments) { - Vector3f position = net.momirealms.craftengine.core.util.MiscUtils.getAsVector3f( - arguments.getOrDefault("position", "0"), "position"); - - String blockStateString = ResourceConfigUtils.requireNonEmptyStringOrThrow( - arguments.get("block-state"), "warning.config.furniture.hitbox.blockstate.missing_block_state"); - - boolean canUseOn = ResourceConfigUtils.getAsBoolean( - arguments.getOrDefault("can-use-item-on", false), "can-use-item-on"); - boolean blocksBuilding = ResourceConfigUtils.getAsBoolean( - arguments.getOrDefault("blocks-building", true), "blocks-building"); - boolean canBeHitByProjectile = ResourceConfigUtils.getAsBoolean( - arguments.getOrDefault("can-be-hit-by-projectile", false), "can-be-hit-by-projectile"); - boolean dropContainer = ResourceConfigUtils.getAsBoolean( - arguments.getOrDefault("drop-container", true), "drop-container"); - - LazyReference lazyBlockState = LazyReference.lazyReference( - () -> CraftEngine.instance().blockManager().createPackedBlockState(blockStateString)); - - return new BlockStateHitBox( - HitBoxFactory.getSeats(arguments), - position, - lazyBlockState, - canUseOn, - blocksBuilding, - canBeHitByProjectile, - dropContainer - ); - } - } -} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BukkitHitBoxTypes.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BukkitHitBoxTypes.java index 0a152f5ca..dda752638 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BukkitHitBoxTypes.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/BukkitHitBoxTypes.java @@ -11,6 +11,5 @@ public class BukkitHitBoxTypes extends HitBoxTypes { register(SHULKER, ShulkerHitBox.FACTORY); register(HAPPY_GHAST, HappyGhastHitBox.FACTORY); register(CUSTOM, CustomHitBox.FACTORY); - register(BLOCKSTATE, BlockStateHitBox.FACTORY); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxTypes.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxTypes.java index ba595b4f7..20c2115f3 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxTypes.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxTypes.java @@ -16,7 +16,6 @@ public class HitBoxTypes { public static final Key SHULKER = Key.of("minecraft:shulker"); public static final Key HAPPY_GHAST = Key.of("minecraft:happy_ghast"); public static final Key CUSTOM = Key.of("minecraft:custom"); - public static final Key BLOCKSTATE = Key.of("minecraft:blockstate"); public static void register(Key key, HitBoxFactory factory) { Holder.Reference holder = ((WritableRegistry) BuiltInRegistries.HITBOX_FACTORY) From f8d501e6e7aef50671410e24025bfe6b8a1c0e8e Mon Sep 17 00:00:00 2001 From: Arubik <102335860+ArubikU@users.noreply.github.com> Date: Thu, 3 Jul 2025 15:19:26 -0500 Subject: [PATCH 4/6] yaw and pitch --- .../context/function/ReplaceFurnitureFunction.java | 10 +++++----- .../context/parameter/FurnitureParameterProvider.java | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ReplaceFurnitureFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ReplaceFurnitureFunction.java index 15a903a51..2a2ac74db 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ReplaceFurnitureFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ReplaceFurnitureFunction.java @@ -95,11 +95,11 @@ public class ReplaceFurnitureFunction extends AbstractCondi public Function create(Map arguments) { String furnitureIdStr = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("furniture-id"), "warning.config.function.replace_furniture.missing_furniture_id"); Key furnitureId = Key.of(furnitureIdStr); - NumberProvider x = NumberProviders.fromObject(arguments.getOrDefault("x", "")); - NumberProvider y = NumberProviders.fromObject(arguments.getOrDefault("y", "")); - NumberProvider z = NumberProviders.fromObject(arguments.getOrDefault("z", "")); - NumberProvider pitch = NumberProviders.fromObject(arguments.getOrDefault("pitch", "")); - NumberProvider yaw = NumberProviders.fromObject(arguments.getOrDefault("yaw", "")); + NumberProvider x = NumberProviders.fromObject(arguments.getOrDefault("x", "")); + NumberProvider y = NumberProviders.fromObject(arguments.getOrDefault("y", "")); + NumberProvider z = NumberProviders.fromObject(arguments.getOrDefault("z", "")); + NumberProvider pitch = NumberProviders.fromObject(arguments.getOrDefault("pitch", "")); + NumberProvider yaw = NumberProviders.fromObject(arguments.getOrDefault("yaw", "")); AnchorType anchorType = Optional.ofNullable(arguments.get("anchor-type")).map(o -> AnchorType.valueOf(o.toString().toUpperCase())).orElse(null); boolean dropLoot = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("drop-loot", true), "drop-loot"); boolean playSound = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("play-sound", true), "play-sound"); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/parameter/FurnitureParameterProvider.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/parameter/FurnitureParameterProvider.java index 3b06b968f..8ca0d81ee 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/parameter/FurnitureParameterProvider.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/parameter/FurnitureParameterProvider.java @@ -18,8 +18,8 @@ public class FurnitureParameterProvider implements ChainParameterProvider furniture.position().x()); CONTEXT_FUNCTIONS.put(DirectContextParameters.Y, furniture -> furniture.position().y()); CONTEXT_FUNCTIONS.put(DirectContextParameters.Z, furniture -> furniture.position().z()); - CONTEXT_FUNCTIONS.put(DirectContextParameters.PITCH, furniture -> furniture.position().yRot()); - CONTEXT_FUNCTIONS.put(DirectContextParameters.YAW, furniture -> furniture.position().xRot()); + CONTEXT_FUNCTIONS.put(DirectContextParameters.PITCH, furniture -> furniture.pitch()); + CONTEXT_FUNCTIONS.put(DirectContextParameters.YAW, furniture -> furniture.yaw()); } @SuppressWarnings("unchecked") From e7d2741de5a5429d485415575aae48dd7155c0bc Mon Sep 17 00:00:00 2001 From: Arubik <102335860+ArubikU@users.noreply.github.com> Date: Sat, 5 Jul 2025 09:44:54 -0500 Subject: [PATCH 5/6] fixed requests of jhqwqmc --- .../entity/furniture/BukkitFurniture.java | 53 ++++++------------- .../core/entity/furniture/HitBoxTypes.java | 8 +-- .../function/RemoveFurnitureFunction.java | 6 +-- .../function/ReplaceFurnitureFunction.java | 9 ++-- .../parameter/FurnitureParameterProvider.java | 4 +- 5 files changed, 28 insertions(+), 52 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java index b3aa0479c..c31816e18 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java @@ -1,32 +1,5 @@ package net.momirealms.craftengine.bukkit.entity.furniture; -import java.io.IOException; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.Vector; - -import org.bukkit.Location; -import org.bukkit.attribute.Attribute; -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.ItemDisplay; -import org.bukkit.entity.Player; -import org.bukkit.persistence.PersistentDataType; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.joml.Quaternionf; -import org.joml.Vector3f; - import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import it.unimi.dsi.fastutil.ints.IntArrayList; import net.momirealms.craftengine.bukkit.entity.BukkitEntity; @@ -35,16 +8,7 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflect import net.momirealms.craftengine.bukkit.util.EntityUtils; import net.momirealms.craftengine.bukkit.util.LegacyAttributeUtils; import net.momirealms.craftengine.bukkit.util.LocationUtils; -import net.momirealms.craftengine.core.entity.furniture.AnchorType; -import net.momirealms.craftengine.core.entity.furniture.Collider; -import net.momirealms.craftengine.core.entity.furniture.CustomFurniture; -import net.momirealms.craftengine.core.entity.furniture.ExternalModel; -import net.momirealms.craftengine.core.entity.furniture.Furniture; -import net.momirealms.craftengine.core.entity.furniture.FurnitureElement; -import net.momirealms.craftengine.core.entity.furniture.FurnitureExtraData; -import net.momirealms.craftengine.core.entity.furniture.FurnitureManager; -import net.momirealms.craftengine.core.entity.furniture.HitBox; -import net.momirealms.craftengine.core.entity.furniture.Seat; +import net.momirealms.craftengine.core.entity.furniture.*; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.ArrayUtils; import net.momirealms.craftengine.core.util.Key; @@ -52,6 +16,18 @@ import net.momirealms.craftengine.core.util.QuaternionUtils; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.WorldPosition; import net.momirealms.craftengine.core.world.collision.AABB; +import org.bukkit.Location; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.*; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +import java.io.IOException; +import java.lang.ref.WeakReference; +import java.util.*; public class BukkitFurniture implements Furniture { private final Key id; @@ -161,6 +137,7 @@ public class BukkitFurniture implements Furniture { @NotNull public Object spawnPacket(Player player) { // TODO hasPermission might be slow, can we use a faster way in the future? + // TODO Make it based on conditions. So we can dynamically control which furniture should be sent to the player if (!this.minimized || player.hasPermission(FurnitureManager.FURNITURE_ADMIN_NODE)) { return this.cachedSpawnPacket; } else { @@ -385,4 +362,4 @@ public class BukkitFurniture implements Furniture { newLocation.add(offset.x, offset.y + 0.6, -offset.z); return newLocation; } -} +} \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxTypes.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxTypes.java index 20c2115f3..881f8c609 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxTypes.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxTypes.java @@ -1,8 +1,5 @@ package net.momirealms.craftengine.core.entity.furniture; -import java.util.Map; -import java.util.Optional; - import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; @@ -11,6 +8,9 @@ import net.momirealms.craftengine.core.registry.WritableRegistry; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.ResourceKey; +import java.util.Map; +import java.util.Optional; + public class HitBoxTypes { public static final Key INTERACTION = Key.of("minecraft:interaction"); public static final Key SHULKER = Key.of("minecraft:shulker"); @@ -31,4 +31,4 @@ public class HitBoxTypes { } return factory.create(arguments); } -} +} \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/RemoveFurnitureFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/RemoveFurnitureFunction.java index 7acd7f40d..e2caefed5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/RemoveFurnitureFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/RemoveFurnitureFunction.java @@ -26,14 +26,14 @@ public class RemoveFurnitureFunction extends AbstractCondit public void runInternal(CTX ctx) { Optional optionalWorldPosition = ctx.getOptionalParameter(DirectContextParameters.POSITION); if (optionalWorldPosition.isPresent()) { - // Buscar muebles en el contexto + // Search for furniture in the context Optional optionalFurniture = ctx.getOptionalParameter(DirectContextParameters.FURNITURE); if (optionalFurniture.isPresent()) { Furniture furniture = optionalFurniture.get(); if (furniture.isValid()) { furniture.destroy(); - // TODO: Implementar lógica para dropear loot y reproducir sonidos - // usando this.dropLoot y this.playSound cuando sea necesario + // TODO: Implement logic to drop loot and play sounds + // using this.dropLoot and this.playSound when necessary } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ReplaceFurnitureFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ReplaceFurnitureFunction.java index 2a2ac74db..fd671a065 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ReplaceFurnitureFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/ReplaceFurnitureFunction.java @@ -52,7 +52,7 @@ public class ReplaceFurnitureFunction extends AbstractCondi if (optionalWorldPosition.isPresent() && optionalOldFurniture.isPresent()) { Furniture oldFurniture = optionalOldFurniture.get(); - // Obtener la nueva posición o usar la actual del mueble + // Get the new position or use the current furniture position double xPos = this.x.getDouble(ctx); double yPos = this.y.getDouble(ctx); double zPos = this.z.getDouble(ctx); @@ -61,19 +61,18 @@ public class ReplaceFurnitureFunction extends AbstractCondi WorldPosition newPosition = new WorldPosition(optionalWorldPosition.get().world(), xPos, yPos, zPos, pitchValue, yawValue); - // Obtener el nuevo mueble + // Get the new furniture Optional optionalNewFurniture = CraftEngine.instance().furnitureManager().furnitureById(this.newFurnitureId); if (optionalNewFurniture.isPresent()) { CustomFurniture newFurniture = optionalNewFurniture.get(); AnchorType anchor = this.anchorType != null ? this.anchorType : newFurniture.getAnyAnchorType(); - // Remover el mueble antiguo + // Remove the old furniture if (oldFurniture.isValid()) { oldFurniture.destroy(); - // TODO: Implementar lógica para dropear loot usando this.dropLoot } - // Colocar el nuevo mueble + // Place the new furniture FurnitureExtraData extraData = FurnitureExtraData.builder().anchorType(anchor).build(); CraftEngine.instance().furnitureManager().place(newPosition, newFurniture, extraData, this.playSound); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/parameter/FurnitureParameterProvider.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/parameter/FurnitureParameterProvider.java index 8ca0d81ee..8b3974115 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/parameter/FurnitureParameterProvider.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/parameter/FurnitureParameterProvider.java @@ -18,8 +18,8 @@ public class FurnitureParameterProvider implements ChainParameterProvider furniture.position().x()); CONTEXT_FUNCTIONS.put(DirectContextParameters.Y, furniture -> furniture.position().y()); CONTEXT_FUNCTIONS.put(DirectContextParameters.Z, furniture -> furniture.position().z()); - CONTEXT_FUNCTIONS.put(DirectContextParameters.PITCH, furniture -> furniture.pitch()); - CONTEXT_FUNCTIONS.put(DirectContextParameters.YAW, furniture -> furniture.yaw()); + CONTEXT_FUNCTIONS.put(DirectContextParameters.PITCH, furniture -> furniture.position().xRot()); + CONTEXT_FUNCTIONS.put(DirectContextParameters.YAW, furniture -> furniture.position().yRot()); } @SuppressWarnings("unchecked") From d5d011ca526e126918652975da108ba6b0298cda Mon Sep 17 00:00:00 2001 From: Arubik <102335860+ArubikU@users.noreply.github.com> Date: Mon, 4 Aug 2025 17:55:28 -0500 Subject: [PATCH 6/6] Update EventFunctions.java --- .../craftengine/core/plugin/context/event/EventFunctions.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java index ae534b927..b646c323e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java @@ -17,6 +17,7 @@ import net.momirealms.craftengine.core.plugin.context.function.Function; import net.momirealms.craftengine.core.plugin.context.function.FunctionFactory; import net.momirealms.craftengine.core.plugin.context.function.LevelerExpFunction; import net.momirealms.craftengine.core.plugin.context.function.MessageFunction; +import net.momirealms.craftengine.core.plugin.context.function.MythicMobsSkillFunction; import net.momirealms.craftengine.core.plugin.context.function.OpenWindowFunction; import net.momirealms.craftengine.core.plugin.context.function.ParticleFunction; import net.momirealms.craftengine.core.plugin.context.function.PlaceBlockFunction;