diff --git a/common-files/src/main/resources/translations/en.yml b/common-files/src/main/resources/translations/en.yml index 8a428d817..fedd0c09a 100644 --- a/common-files/src/main/resources/translations/en.yml +++ b/common-files/src/main/resources/translations/en.yml @@ -401,6 +401,8 @@ warning.config.function.set_cooldown.missing_time: "Issue found in file warning.config.function.set_cooldown.missing_id: "Issue found in file - The config '' is missing the required 'id' argument for 'set_cooldown' function." warning.config.function.remove_cooldown.missing_id: "Issue found in file - The config '' is missing the required 'id' argument for 'remove_cooldown' function." warning.config.function.mythic_mobs_skill.missing_skill: "Issue found in file - The config '' is missing the required 'skill' argument for 'mythic_mobs_skill' function." +warning.config.function.spawn_furniture.missing_furniture_id: "Issue found in file - The config '' is missing the required 'furniture-id' argument for 'spawn_furniture' function." +warning.config.function.replace_furniture.missing_furniture_id: "Issue found in file - The config '' is missing the required 'furniture-id' argument for 'replace_furniture' function." warning.config.selector.missing_type: "Issue found in file - The config '' is missing the required 'type' argument for selector." warning.config.selector.invalid_type: "Issue found in file - The config '' is using an invalid selector type ''." warning.config.selector.invalid_target: "Issue found in file - The config '' is using an invalid selector target ''." diff --git a/common-files/src/main/resources/translations/zh_cn.yml b/common-files/src/main/resources/translations/zh_cn.yml index 3512ddf1b..7a22c1732 100644 --- a/common-files/src/main/resources/translations/zh_cn.yml +++ b/common-files/src/main/resources/translations/zh_cn.yml @@ -401,6 +401,8 @@ warning.config.function.set_cooldown.missing_time: "在文件 warning.config.function.set_cooldown.missing_id: "在文件 中发现问题 - 配置项 '' 缺少 'set_cooldown' 函数必需的 'id' 参数" warning.config.function.remove_cooldown.missing_id: "在文件 中发现问题 - 配置项 '' 缺少 'remove_cooldown' 函数必需的 'id' 参数" warning.config.function.mythic_mobs_skill.missing_skill: "在文件 中发现问题 - 配置项 '' 缺少 'mythic_mobs_skill' 函数必需的 'skill' 参数" +warning.config.function.spawn_furniture.missing_furniture_id: "在文件 中发现问题 - 配置项 '' 缺少 'spawn_furniture' 函数必需的 'furniture-id' 参数" +warning.config.function.replace_furniture.missing_furniture_id: "在文件 中发现问题 - 配置项 '' 缺少 'replace_furniture' 函数必需的 'furniture-id' 参数" warning.config.selector.missing_type: "在文件 中发现问题 - 配置项 '' 缺少选择器必需的 'type' 参数" warning.config.selector.invalid_type: "在文件 中发现问题 - 配置项 '' 使用了无效的选择器类型 ''" warning.config.selector.invalid_target: "在文件 中发现问题 - 配置项 '' 使用了无效的选择器目标 ''" 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 0fa908dec..88a2eb2ff 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 @@ -1,11 +1,19 @@ package net.momirealms.craftengine.core.plugin.context.function; import net.momirealms.craftengine.core.entity.furniture.Furniture; +import net.momirealms.craftengine.core.entity.player.InteractionHand; +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.loot.LootTable; import net.momirealms.craftengine.core.plugin.context.Condition; import net.momirealms.craftengine.core.plugin.context.Context; +import net.momirealms.craftengine.core.plugin.context.ContextHolder; import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters; +import net.momirealms.craftengine.core.sound.SoundData; +import net.momirealms.craftengine.core.sound.SoundSource; 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; import java.util.List; @@ -24,18 +32,36 @@ public class RemoveFurnitureFunction extends AbstractCondit @Override public void runInternal(CTX ctx) { - Optional optionalWorldPosition = ctx.getOptionalParameter(DirectContextParameters.POSITION); - if (optionalWorldPosition.isPresent()) { - // 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: Implement logic to drop loot and play sounds - // using this.dropLoot and this.playSound when necessary - } + ctx.getOptionalParameter(DirectContextParameters.FURNITURE).ifPresent(furniture -> removeFurniture(ctx, furniture, dropLoot, playSound)); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + public static void removeFurniture(Context ctx, Furniture furniture, boolean dropLoot, boolean playSound) { + if (!furniture.isValid()) return; + WorldPosition position = furniture.position(); + World world = position.world(); + furniture.destroy(); + LootTable lootTable = furniture.config().lootTable(); + if (dropLoot && lootTable != null) { + ContextHolder.Builder builder = ContextHolder.builder() + .withParameter(DirectContextParameters.POSITION, position) + .withParameter(DirectContextParameters.FURNITURE, furniture) + .withOptionalParameter(DirectContextParameters.FURNITURE_ITEM, furniture.extraData().item().orElse(null)); + Optional optionalPlayer = ctx.getOptionalParameter(DirectContextParameters.PLAYER); + Player player = optionalPlayer.orElse(null); + if (player != null) { + Item itemInHand = player.getItemInHand(InteractionHand.MAIN_HAND); + builder.withParameter(DirectContextParameters.PLAYER, player) + .withOptionalParameter(DirectContextParameters.ITEM_IN_HAND, itemInHand.isEmpty() ? null : itemInHand); } + List> items = lootTable.getRandomItems(builder.build(), world, player); + for (Item item : items) { + world.dropItemNaturally(position, item); + } + } + if (playSound) { + SoundData breakSound = furniture.config().settings().sounds().breakSound(); + world.playSound(position, breakSound.id(), breakSound.volume().get(), breakSound.pitch().get(), SoundSource.BLOCK); } } 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 171674596..ab7e278ec 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 @@ -4,14 +4,22 @@ 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.entity.player.InteractionHand; +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.loot.LootTable; 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.ContextHolder; 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.sound.SoundData; +import net.momirealms.craftengine.core.sound.SoundSource; 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; import java.util.List; @@ -29,9 +37,18 @@ public class ReplaceFurnitureFunction extends AbstractCondi 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) { + 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; @@ -48,34 +65,24 @@ public class ReplaceFurnitureFunction extends AbstractCondi 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(); - + WorldPosition worldPosition = optionalWorldPosition.get(); + // 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); float pitchValue = this.pitch.getFloat(ctx); float yawValue = this.yaw.getFloat(ctx); - - WorldPosition newPosition = new WorldPosition(optionalWorldPosition.get().world(), xPos, yPos, zPos, pitchValue, yawValue); - - // 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(); - - // Remove the old furniture - if (oldFurniture.isValid()) { - oldFurniture.destroy(); - } - - // Place the new furniture - FurnitureExtraData extraData = FurnitureExtraData.builder().anchorType(anchor).build(); - CraftEngine.instance().furnitureManager().place(newPosition, newFurniture, extraData, this.playSound); - } + WorldPosition newPosition = new WorldPosition(worldPosition.world(), xPos, yPos, zPos, pitchValue, yawValue); + + // Remove the old furniture + RemoveFurnitureFunction.removeFurniture(ctx, oldFurniture, dropLoot, playSound); + + // Place the new furniture + SpawnFurnitureFunction.spawnFurniture(this.newFurnitureId, newPosition, this.anchorType, this.playSound); } } @@ -92,14 +99,13 @@ public class ReplaceFurnitureFunction extends AbstractCondi @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); + Key furnitureId = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("furniture-id"), "warning.config.function.replace_furniture.missing_furniture_id")); 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); + AnchorType anchorType = ResourceConfigUtils.getAsEnum(arguments.get("anchor-type"), AnchorType.class, 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 index f3234e792..66b527272 100644 --- 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 @@ -1,7 +1,6 @@ package net.momirealms.craftengine.core.plugin.context.function; 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; @@ -28,9 +27,17 @@ public class SpawnFurnitureFunction extends AbstractConditi 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) { + 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; @@ -44,25 +51,24 @@ public class SpawnFurnitureFunction extends AbstractConditi @Override public void runInternal(CTX ctx) { - Optional optionalWorldPosition = ctx.getOptionalParameter(DirectContextParameters.POSITION); - if (optionalWorldPosition.isPresent()) { - World world = optionalWorldPosition.get().world(); + ctx.getOptionalParameter(DirectContextParameters.POSITION).ifPresent(worldPosition -> { + World world = worldPosition.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); - } - } + spawnFurniture(this.furnitureId, position, this.anchorType, this.playSound); + }); + } + + public static void spawnFurniture(Key furnitureId, WorldPosition position, AnchorType anchorType, boolean playSound) { + CraftEngine.instance().furnitureManager().furnitureById(furnitureId).ifPresent(furniture -> { + AnchorType anchor = Optional.ofNullable(anchorType).orElse(furniture.getAnyAnchorType()); + FurnitureExtraData extraData = FurnitureExtraData.builder().anchorType(anchor).build(); + CraftEngine.instance().furnitureManager().place(position, furniture, extraData, playSound); + }); } @Override @@ -78,14 +84,13 @@ public class SpawnFurnitureFunction extends AbstractConditi @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); + Key furnitureId = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("furniture-id"), "warning.config.function.spawn_furniture.missing_furniture_id")); 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); + AnchorType anchorType = ResourceConfigUtils.getAsEnum(arguments.get("anchor-type"), AnchorType.class, 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)); }