9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-25 09:59:20 +00:00

refactor(furniture): 完善家具函数生成移除替换逻辑

This commit is contained in:
jhqwqmc
2025-08-06 12:04:28 +08:00
parent beaa0680b9
commit aa2988b8c8
5 changed files with 98 additions and 57 deletions

View File

@@ -401,6 +401,8 @@ warning.config.function.set_cooldown.missing_time: "<yellow>Issue found in file
warning.config.function.set_cooldown.missing_id: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'id' argument for 'set_cooldown' function.</yellow>"
warning.config.function.remove_cooldown.missing_id: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'id' argument for 'remove_cooldown' function.</yellow>"
warning.config.function.mythic_mobs_skill.missing_skill: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'skill' argument for 'mythic_mobs_skill' function.</yellow>"
warning.config.function.spawn_furniture.missing_furniture_id: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'furniture-id' argument for 'spawn_furniture' function.</yellow>"
warning.config.function.replace_furniture.missing_furniture_id: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'furniture-id' argument for 'replace_furniture' function.</yellow>"
warning.config.selector.missing_type: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'type' argument for selector.</yellow>"
warning.config.selector.invalid_type: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is using an invalid selector type '<arg:2>'.</yellow>"
warning.config.selector.invalid_target: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is using an invalid selector target '<arg:2>'.</yellow>"

View File

@@ -401,6 +401,8 @@ warning.config.function.set_cooldown.missing_time: "<yellow>在文件 <arg:0>
warning.config.function.set_cooldown.missing_id: "<yellow>在文件 <arg:0> 中发现问题 - 配置项 '<arg:1>' 缺少 'set_cooldown' 函数必需的 'id' 参数</yellow>"
warning.config.function.remove_cooldown.missing_id: "<yellow>在文件 <arg:0> 中发现问题 - 配置项 '<arg:1>' 缺少 'remove_cooldown' 函数必需的 'id' 参数</yellow>"
warning.config.function.mythic_mobs_skill.missing_skill: "<yellow>在文件 <arg:0> 中发现问题 - 配置项 '<arg:1>' 缺少 'mythic_mobs_skill' 函数必需的 'skill' 参数</yellow>"
warning.config.function.spawn_furniture.missing_furniture_id: "<yellow>在文件 <arg:0> 中发现问题 - 配置项 '<arg:1>' 缺少 'spawn_furniture' 函数必需的 'furniture-id' 参数</yellow>"
warning.config.function.replace_furniture.missing_furniture_id: "<yellow>在文件 <arg:0> 中发现问题 - 配置项 '<arg:1>' 缺少 'replace_furniture' 函数必需的 'furniture-id' 参数</yellow>"
warning.config.selector.missing_type: "<yellow>在文件 <arg:0> 中发现问题 - 配置项 '<arg:1>' 缺少选择器必需的 'type' 参数</yellow>"
warning.config.selector.invalid_type: "<yellow>在文件 <arg:0> 中发现问题 - 配置项 '<arg:1>' 使用了无效的选择器类型 '<arg:2>'</yellow>"
warning.config.selector.invalid_target: "<yellow>在文件 <arg:0> 中发现问题 - 配置项 '<arg:1>' 使用了无效的选择器目标 '<arg:2>'</yellow>"

View File

@@ -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<CTX extends Context> extends AbstractCondit
@Override
public void runInternal(CTX ctx) {
Optional<WorldPosition> optionalWorldPosition = ctx.getOptionalParameter(DirectContextParameters.POSITION);
if (optionalWorldPosition.isPresent()) {
// Search for furniture in the context
Optional<Furniture> 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<Player> 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<Item<?>> 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);
}
}

View File

@@ -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<CTX extends Context> 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<Condition<CTX>> predicates) {
public ReplaceFurnitureFunction(
Key newFurnitureId,
NumberProvider x,
NumberProvider y,
NumberProvider z,
NumberProvider pitch,
NumberProvider yaw,
AnchorType anchorType,
boolean dropLoot,
boolean playSound,
List<Condition<CTX>> predicates
) {
super(predicates);
this.newFurnitureId = newFurnitureId;
this.x = x;
@@ -48,34 +65,24 @@ public class ReplaceFurnitureFunction<CTX extends Context> extends AbstractCondi
public void runInternal(CTX ctx) {
Optional<WorldPosition> optionalWorldPosition = ctx.getOptionalParameter(DirectContextParameters.POSITION);
Optional<Furniture> 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<CustomFurniture> 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<CTX extends Context> extends AbstractCondi
@Override
public Function<CTX> create(Map<String, Object> 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", "<arg:furniture.x>"));
NumberProvider y = NumberProviders.fromObject(arguments.getOrDefault("y", "<arg:furniture.y>"));
NumberProvider z = NumberProviders.fromObject(arguments.getOrDefault("z", "<arg:furniture.z>"));
NumberProvider pitch = NumberProviders.fromObject(arguments.getOrDefault("pitch", "<arg:furniture.pitch>"));
NumberProvider yaw = NumberProviders.fromObject(arguments.getOrDefault("yaw", "<arg:furniture.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));

View File

@@ -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<CTX extends Context> 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<Condition<CTX>> predicates) {
public SpawnFurnitureFunction(
Key furnitureId,
NumberProvider x,
NumberProvider y,
NumberProvider z,
NumberProvider pitch,
NumberProvider yaw,
AnchorType anchorType,
boolean playSound,
List<Condition<CTX>> predicates
) {
super(predicates);
this.furnitureId = furnitureId;
this.x = x;
@@ -44,25 +51,24 @@ public class SpawnFurnitureFunction<CTX extends Context> extends AbstractConditi
@Override
public void runInternal(CTX ctx) {
Optional<WorldPosition> 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<CustomFurniture> 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<CTX extends Context> extends AbstractConditi
@Override
public Function<CTX> create(Map<String, Object> 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", "<arg:position.x>"));
NumberProvider y = NumberProviders.fromObject(arguments.getOrDefault("y", "<arg:position.y>"));
NumberProvider z = NumberProviders.fromObject(arguments.getOrDefault("z", "<arg:position.z>"));
NumberProvider pitch = NumberProviders.fromObject(arguments.getOrDefault("pitch", "<arg:pitch>"));
NumberProvider yaw = NumberProviders.fromObject(arguments.getOrDefault("yaw", "<arg: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));
}