diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehaviors.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehaviors.java index 948c8a44e..0ccb79370 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehaviors.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehaviors.java @@ -34,6 +34,7 @@ public class BukkitBlockBehaviors extends BlockBehaviors { public static final Key BOUNCING_BLOCK = Key.from("craftengine:bouncing_block"); public static final Key DIRECTIONAL_ATTACHED_BLOCK = Key.from("craftengine:directional_attached_block"); public static final Key LIQUID_FLOWABLE_BLOCK = Key.from("craftengine:liquid_flowable_block"); + public static final Key PARTICLE_BLOCK = Key.from("craftengine:particle_block"); public static void init() { register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE); @@ -66,5 +67,6 @@ public class BukkitBlockBehaviors extends BlockBehaviors { register(BOUNCING_BLOCK, BouncingBlockBehavior.FACTORY); register(DIRECTIONAL_ATTACHED_BLOCK, DirectionalAttachedBlockBehavior.FACTORY); register(LIQUID_FLOWABLE_BLOCK, LiquidFlowableBlockBehavior.FACTORY); + register(PARTICLE_BLOCK, ParticleBlockBehavior.FACTORY); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ParticleBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ParticleBlockBehavior.java new file mode 100644 index 000000000..548b159c9 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ParticleBlockBehavior.java @@ -0,0 +1,75 @@ +package net.momirealms.craftengine.bukkit.block.behavior; + +import net.momirealms.craftengine.bukkit.block.entity.BukkitBlockEntityTypes; +import net.momirealms.craftengine.bukkit.block.entity.BaseParticleBlockEntity; +import net.momirealms.craftengine.bukkit.block.entity.ParticleBlockEntity; +import net.momirealms.craftengine.bukkit.block.entity.WallParticleBlockEntity; +import net.momirealms.craftengine.core.block.BlockBehavior; +import net.momirealms.craftengine.core.block.CustomBlock; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; +import net.momirealms.craftengine.core.block.behavior.EntityBlockBehavior; +import net.momirealms.craftengine.core.block.entity.BlockEntity; +import net.momirealms.craftengine.core.block.entity.BlockEntityType; +import net.momirealms.craftengine.core.block.entity.tick.BlockEntityTicker; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import net.momirealms.craftengine.core.world.BlockPos; +import net.momirealms.craftengine.core.world.CEWorld; +import net.momirealms.craftengine.core.world.Vec3d; + +import java.util.List; +import java.util.Map; + +public class ParticleBlockBehavior extends BukkitBlockBehavior implements EntityBlockBehavior { + public static final Factory FACTORY = new Factory(); + private final List particles; + private final boolean inWall; + + public ParticleBlockBehavior(CustomBlock customBlock, List particles, boolean inWall) { + super(customBlock); + this.particles = particles; + this.inWall = inWall; + } + + public List particles() { + return particles; + } + + @Override + public BlockEntityType blockEntityType() { + return EntityBlockBehavior.blockEntityTypeHelper(this.inWall ? BukkitBlockEntityTypes.WALL_PARTICLE : BukkitBlockEntityTypes.PARTICLE); + } + + @Override + public BlockEntity createBlockEntity(BlockPos pos, ImmutableBlockState state) { + return this.inWall ? new WallParticleBlockEntity(pos, state) : new ParticleBlockEntity(pos, state); + } + + @Override + public BlockEntityTicker createBlockEntityTicker(CEWorld level, ImmutableBlockState state, BlockEntityType blockEntityType) { + if (this.particles().isEmpty()) return null; + return EntityBlockBehavior.createTickerHelper(BaseParticleBlockEntity::tick); + } + + public static class Factory implements BlockBehaviorFactory { + @Override + public BlockBehavior create(CustomBlock block, Map arguments) { + List particles = ResourceConfigUtils.parseConfigAsList(arguments.getOrDefault("particles", List.of()), ParticleData::fromMap); + boolean inWall = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("in-wall", false), "in-wall"); + return new ParticleBlockBehavior(block, particles, inWall); + } + } + + public record ParticleData(Key particle, Vec3d locationOffset, Vec3d offset, int count, double speed) { + + public static ParticleData fromMap(Map arguments) { + Key particle = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("type"), "warning.config.block.behavior.particle.missing_type")); + Vec3d locationOffset = ResourceConfigUtils.getAsVec3d(arguments.get("location-offset"), "location-offset"); + Vec3d offset = ResourceConfigUtils.getAsVec3d(arguments.get("offset"), "offset"); + int count = ResourceConfigUtils.getAsInt(arguments.getOrDefault("count", 1), "count"); + double speed = ResourceConfigUtils.getAsDouble(arguments.get("speed"), "speed"); + return new ParticleData(particle, locationOffset, offset, count, speed); + } + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SimpleStorageBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SimpleStorageBlockBehavior.java index 9ec94e21b..0a7933cad 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SimpleStorageBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SimpleStorageBlockBehavior.java @@ -105,10 +105,9 @@ public class SimpleStorageBlockBehavior extends BukkitBlockBehavior implements E } } - @SuppressWarnings("unchecked") @Override public BlockEntityType blockEntityType() { - return (BlockEntityType) BukkitBlockEntityTypes.SIMPLE_STORAGE; + return EntityBlockBehavior.blockEntityTypeHelper(BukkitBlockEntityTypes.SIMPLE_STORAGE); } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/BaseParticleBlockEntity.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/BaseParticleBlockEntity.java new file mode 100644 index 000000000..fb8d63c83 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/BaseParticleBlockEntity.java @@ -0,0 +1,27 @@ +package net.momirealms.craftengine.bukkit.block.entity; + +import net.momirealms.craftengine.bukkit.block.behavior.ParticleBlockBehavior; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.block.entity.BlockEntity; +import net.momirealms.craftengine.core.block.entity.BlockEntityType; +import net.momirealms.craftengine.core.world.BlockPos; +import net.momirealms.craftengine.core.world.CEWorld; +import net.momirealms.craftengine.core.world.World; + +public abstract class BaseParticleBlockEntity extends BlockEntity { + protected final ParticleBlockBehavior behavior; + protected int tickCount; + + public BaseParticleBlockEntity(BlockEntityType type, BlockPos pos, ImmutableBlockState blockState) { + super(type, pos, blockState); + this.behavior = super.blockState.behavior().getAs(ParticleBlockBehavior.class).orElseThrow(); + } + + public static void tick(CEWorld ceWorld, BlockPos blockPos, ImmutableBlockState state, BaseParticleBlockEntity particle) { + particle.tickCount++; + if (particle.tickCount % 10 != 0) return; + particle.animateTick(state, ceWorld.world(), blockPos); + } + + public abstract void animateTick(ImmutableBlockState state, World level, BlockPos pos); +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/BukkitBlockEntityTypes.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/BukkitBlockEntityTypes.java index 3e778bd32..75c449fa9 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/BukkitBlockEntityTypes.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/BukkitBlockEntityTypes.java @@ -6,4 +6,6 @@ import net.momirealms.craftengine.core.block.entity.BlockEntityTypes; public class BukkitBlockEntityTypes extends BlockEntityTypes { public static final BlockEntityType SIMPLE_STORAGE = register(BlockEntityTypeKeys.SIMPLE_STORAGE, SimpleStorageBlockEntity::new); + public static final BlockEntityType PARTICLE = register(BlockEntityTypeKeys.PARTICLE, ParticleBlockEntity::new); + public static final BlockEntityType WALL_PARTICLE = register(BlockEntityTypeKeys.WALL_PARTICLE, WallParticleBlockEntity::new); } \ No newline at end of file diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/ParticleBlockEntity.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/ParticleBlockEntity.java new file mode 100644 index 000000000..485eb0c85 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/ParticleBlockEntity.java @@ -0,0 +1,31 @@ +package net.momirealms.craftengine.bukkit.block.entity; + +import net.momirealms.craftengine.bukkit.block.behavior.ParticleBlockBehavior; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.world.BlockPos; +import net.momirealms.craftengine.core.world.Vec3d; +import net.momirealms.craftengine.core.world.World; + +public class ParticleBlockEntity extends BaseParticleBlockEntity { + + public ParticleBlockEntity(BlockPos pos, ImmutableBlockState blockState) { + super(BukkitBlockEntityTypes.PARTICLE, pos, blockState); + } + + @Override + public void animateTick(ImmutableBlockState state, World level, BlockPos pos) { + for (ParticleBlockBehavior.ParticleData particle : behavior.particles()) { + Vec3d location = particle.locationOffset().add(pos.x(), pos.y(), pos.z()); + level.spawnParticle( + location, + particle.particle(), + particle.count(), + particle.offset().x(), + particle.offset().y(), + particle.offset().z(), + particle.speed(), + null, null + ); + } + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/WallParticleBlockEntity.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/WallParticleBlockEntity.java new file mode 100644 index 000000000..7de011fb9 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/WallParticleBlockEntity.java @@ -0,0 +1,51 @@ +package net.momirealms.craftengine.bukkit.block.entity; + +import net.momirealms.craftengine.bukkit.block.behavior.ParticleBlockBehavior; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.block.properties.Property; +import net.momirealms.craftengine.core.util.Direction; +import net.momirealms.craftengine.core.util.HorizontalDirection; +import net.momirealms.craftengine.core.world.BlockPos; +import net.momirealms.craftengine.core.world.Vec3d; +import net.momirealms.craftengine.core.world.World; + +public class WallParticleBlockEntity extends BaseParticleBlockEntity { + + public WallParticleBlockEntity(BlockPos pos, ImmutableBlockState blockState) { + super(BukkitBlockEntityTypes.WALL_PARTICLE, pos, blockState); + } + + @Override + public void animateTick(ImmutableBlockState state, World level, BlockPos pos) { + Direction direction = null; + for (Property property : state.getProperties()) { + if (!property.name().equals("facing")) continue; + if (property.valueClass() == Direction.class) { + direction = (Direction) state.get(property); + break; + } else if (property.valueClass() == HorizontalDirection.class) { + direction = ((HorizontalDirection) state.get(property)).toDirection(); + break; + } + } + if (direction != null) { + direction = direction.opposite(); + } + for (ParticleBlockBehavior.ParticleData particle : behavior.particles()) { + Vec3d location = particle.locationOffset().add(pos.x(), pos.y(), pos.z()); + if (direction != null) { + location = location.add(0.27 * direction.stepX(), 0.22, 0.27 * direction.stepZ()); + } + level.spawnParticle( + location, + particle.particle(), + particle.count(), + particle.offset().x(), + particle.offset().y(), + particle.offset().z(), + particle.speed(), + null, null + ); + } + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorld.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorld.java index 2624bc78d..28b39712d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorld.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorld.java @@ -106,11 +106,11 @@ public class BukkitWorld implements World { } @Override - public void spawnParticle(Position location, Key particle, int count, double xOffset, double yOffset, double zOffset, double speed, @Nullable ParticleData extraData, @NotNull Context context) { + public void spawnParticle(Position location, Key particle, int count, double xOffset, double yOffset, double zOffset, double speed, @Nullable ParticleData extraData, @Nullable Context context) { Particle particleType = ParticleUtils.getParticle(particle); if (particleType == null) return; org.bukkit.World platformWorld = platformWorld(); - platformWorld.spawnParticle(particleType, location.x(), location.y(), location.z(), count, xOffset, yOffset, zOffset, speed, extraData == null ? null : ParticleUtils.toBukkitParticleData(extraData, context, platformWorld, location.x(), location.y(), location.z())); + platformWorld.spawnParticle(particleType, location.x(), location.y(), location.z(), count, xOffset, yOffset, zOffset, speed, extraData == null || context == null ? null : ParticleUtils.toBukkitParticleData(extraData, context, platformWorld, location.x(), location.y(), location.z())); } @Override diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/amethyst_torch.yml b/common-files/src/main/resources/resources/default/configuration/blocks/amethyst_torch.yml index 2963b0af2..1ee3349c5 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/amethyst_torch.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/amethyst_torch.yml @@ -70,6 +70,12 @@ blocks: support-types: - center - type: liquid_flowable_block + - type: particle_block + particles: + - type: smoke + location-offset: 0.5,0.7,0.5 + - type: flame + location-offset: 0.5,0.7,0.5 default:amethyst_wall_torch: loot: template: default:loot_table/basic @@ -88,6 +94,13 @@ blocks: behavior: - type: directional_attached_block - type: liquid_flowable_block + - type: particle_block + in-wall: true + particles: + - type: smoke + location-offset: 0.5,0.7,0.5 + - type: flame + location-offset: 0.5,0.7,0.5 states: properties: facing: diff --git a/common-files/src/main/resources/translations/en.yml b/common-files/src/main/resources/translations/en.yml index 824db15c7..d57a7cc15 100644 --- a/common-files/src/main/resources/translations/en.yml +++ b/common-files/src/main/resources/translations/en.yml @@ -73,6 +73,7 @@ warning.config.type.float: "Issue found in file - Failed to load warning.config.type.double: "Issue found in file - Failed to load '': Cannot cast '' to double type for option ''." warning.config.type.quaternionf: "Issue found in file - Failed to load '': Cannot cast '' to Quaternionf type for option ''." warning.config.type.vector3f: "Issue found in file - Failed to load '': Cannot cast '' to Vector3f type for option ''." +warning.config.type.vec3d: "Issue found in file - Failed to load '': Cannot cast '' to Vec3d type for option ''." warning.config.type.map: "Issue found in file - Failed to load '': Cannot cast '' to Map type for option ''." warning.config.type.snbt.invalid_syntax: "Issue found in file - Failed to load '': Invalid snbt syntax ''." warning.config.number.missing_type: "Issue found in file - The config '' is missing the required 'type' argument for number argument." @@ -304,10 +305,10 @@ warning.config.block.behavior.trapdoor.missing_open: "Issue found in fil warning.config.block.behavior.trapdoor.missing_powered: "Issue found in file - The block '' is missing the required 'powered' property for 'trapdoor_block' behavior." warning.config.block.behavior.stackable.missing_property: "Issue found in file - The block '' is missing the required '' property for 'stackable_block' behavior." warning.config.block.behavior.stackable.missing_items: "Issue found in file - The block '' is missing the required 'items' argument for 'stackable_block' behavior." -warning.config.block.behavior.fence_gate.missing_facing: "Issue found in file - The block '' is missing the required 'facing' argument for 'fence_gate_block' behavior." -warning.config.block.behavior.fence_gate.missing_in_wall: "Issue found in file - The block '' is missing the required 'in_wall' argument for 'fence_gate_block' behavior." -warning.config.block.behavior.fence_gate.missing_open: "Issue found in file - The block '' is missing the required 'powered' argument for 'fence_gate_block' behavior." -warning.config.block.behavior.fence_gate.missing_powered: "Issue found in file - The block '' is missing the required 'open' argument for 'fence_gate_block' behavior." +warning.config.block.behavior.fence_gate.missing_facing: "Issue found in file - The block '' is missing the required 'facing' property for 'fence_gate_block' behavior." +warning.config.block.behavior.fence_gate.missing_in_wall: "Issue found in file - The block '' is missing the required 'in_wall' property for 'fence_gate_block' behavior." +warning.config.block.behavior.fence_gate.missing_open: "Issue found in file - The block '' is missing the required 'powered' property for 'fence_gate_block' behavior." +warning.config.block.behavior.fence_gate.missing_powered: "Issue found in file - The block '' is missing the required 'open' property for 'fence_gate_block' behavior." warning.config.block.behavior.slab.missing_type: "Issue found in file - The block '' is missing the required 'type' property for 'slab_block' behavior." warning.config.block.behavior.stairs.missing_facing: "Issue found in file - The block '' is missing the required 'facing' property for 'stairs_block' behavior." warning.config.block.behavior.stairs.missing_half: "Issue found in file - The block '' is missing the required 'half' property for 'stairs_block' behavior." @@ -317,8 +318,9 @@ warning.config.block.behavior.sofa.missing_shape: "Issue found in file < warning.config.block.behavior.pressure_plate.missing_powered: "Issue found in file - The block '' is missing the required 'powered' property for 'pressure_plate_block' behavior." warning.config.block.behavior.grass.missing_feature: "Issue found in file - The block '' is missing the required 'feature' argument for 'grass_block' behavior." warning.config.block.behavior.double_high.missing_half: "Issue found in file - The block '' is missing the required 'half' property for 'double_block' behavior." -warning.config.block.behavior.change_over_time.missing_next_block: "Issue found in file - The block '' is missing the required 'next_block' property for 'change_over_time_block' behavior." +warning.config.block.behavior.change_over_time.missing_next_block: "Issue found in file - The block '' is missing the required 'next_block' argument for 'change_over_time_block' behavior." warning.config.block.behavior.surface_attached.missing_facing: "Issue found in file - The block '' is missing the required 'facing' property for 'surface_attached_block' behavior." +warning.config.block.behavior.particle.missing_type: "Issue found in file - The block '' is missing the required 'type' argument for 'particle_block' behavior." warning.config.model.generation.missing_parent: "Issue found in file - The config '' is missing the required 'parent' argument in 'generation' section." warning.config.model.generation.conflict: "Issue found in file - Failed to generate model for '' as two or more configurations attempt to generate different json models with the same path: ''." warning.config.model.generation.invalid_display_position: "Issue found in file - The config '' is using an invalid display position '' in 'generation.display' section. Allowed display positions: []" diff --git a/common-files/src/main/resources/translations/zh_cn.yml b/common-files/src/main/resources/translations/zh_cn.yml index f66a18c69..902056cd9 100644 --- a/common-files/src/main/resources/translations/zh_cn.yml +++ b/common-files/src/main/resources/translations/zh_cn.yml @@ -73,6 +73,7 @@ warning.config.type.float: "在文件 发现问题 - 无法加 warning.config.type.double: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为双精度类型 (选项 '')" warning.config.type.quaternionf: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为四元数类型 (选项 '')" warning.config.type.vector3f: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为三维向量类型 (选项 '')" +warning.config.type.vec3d: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为双精度浮点数三维向量类型 (选项 '')" warning.config.type.map: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为映射类型 (选项 '')" warning.config.type.snbt.invalid_syntax: "在文件 发现问题 - 无法加载 '': 无效的 SNBT 语法 ''" warning.config.number.missing_type: "在文件 发现问题 - 配置项 '' 缺少数字类型所需的 'type' 参数" @@ -311,8 +312,9 @@ warning.config.block.behavior.sofa.missing_shape: "在文件 发 warning.config.block.behavior.pressure_plate.missing_powered: "在文件 发现问题 - 方块 '' 的 'pressure_plate_block' 行为缺少必需的 'powered' 属性" warning.config.block.behavior.grass.missing_feature: "在文件 发现问题 - 方块 '' 的 'grass_block' 行为缺少必需的 'feature' 参数" warning.config.block.behavior.double_high.missing_half: "在文件 发现问题 - 方块 '' 的 'double_block' 行为缺少必需的 'half' 属性" -warning.config.block.behavior.change_over_time.missing_next_block: "在文件 发现问题 - 方块 '' 的 'change_over_time_block' 行为缺少必需的 'next-block' 配置项" +warning.config.block.behavior.change_over_time.missing_next_block: "在文件 发现问题 - 方块 '' 的 'change_over_time_block' 行为缺少必需的 'next-block' 参数" warning.config.block.behavior.surface_attached.missing_facing: "在文件 发现问题 - 方块 '' 的 'surface_attached_block' 行为缺少必需的 'facing' 属性" +warning.config.block.behavior.particle.missing_type: "在文件 发现问题 - 配置项 '' 的 'particle' 段落缺少必需的 'type' 参数" warning.config.model.generation.missing_parent: "在文件 发现问题 - 配置项 '' 的 'generation' 段落缺少必需的 'parent' 参数" warning.config.model.generation.conflict: "在文件 发现问题 - 无法为 '' 生成模型 存在多个配置尝试使用相同路径 '' 生成不同的 JSON 模型" warning.config.model.generation.invalid_display_position: "在文件 发现问题 - 配置项 '' 在 'generation.display' 区域使用了无效的 display 位置类型 ''. 可用展示类型: []" diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/behavior/EntityBlockBehavior.java b/core/src/main/java/net/momirealms/craftengine/core/block/behavior/EntityBlockBehavior.java index b5df01017..f92b0e59a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/behavior/EntityBlockBehavior.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/behavior/EntityBlockBehavior.java @@ -20,7 +20,12 @@ public interface EntityBlockBehavior { } @SuppressWarnings("unchecked") - static BlockEntityTicker createTickerHelper(BlockEntityTicker ticker) { + static BlockEntityTicker createTickerHelper(BlockEntityTicker ticker) { return (BlockEntityTicker) ticker; } + + @SuppressWarnings("unchecked") + static BlockEntityType blockEntityTypeHelper(BlockEntityType type) { + return (BlockEntityType) type; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/entity/BlockEntityTypeKeys.java b/core/src/main/java/net/momirealms/craftengine/core/block/entity/BlockEntityTypeKeys.java index b801d9156..6bc44620d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/entity/BlockEntityTypeKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/entity/BlockEntityTypeKeys.java @@ -7,5 +7,6 @@ public final class BlockEntityTypeKeys { public static final Key UNSAFE_COMPOSITE = Key.of("craftengine:unsafe_composite"); public static final Key SIMPLE_STORAGE = Key.of("craftengine:simple_storage"); - public static final Key SEAT = Key.of("craftengine:seat"); + public static final Key PARTICLE = Key.of("craftengine:particle"); + public static final Key WALL_PARTICLE = Key.of("craftengine:wall_particle"); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/ResourceConfigUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/ResourceConfigUtils.java index b62402aa4..58c09669e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/ResourceConfigUtils.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/ResourceConfigUtils.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.util; import com.mojang.datafixers.util.Either; import net.momirealms.craftengine.core.plugin.locale.LocalizedException; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; +import net.momirealms.craftengine.core.world.Vec3d; import org.jetbrains.annotations.Nullable; import org.joml.Quaternionf; import org.joml.Vector3f; @@ -261,4 +262,22 @@ public final class ResourceConfigUtils { } } } + + public static Vec3d getAsVec3d(Object o, String option) { + if (o == null) return new Vec3d(0, 0, 0); + if (o instanceof List list && list.size() == 3) { + return new Vec3d(Double.parseDouble(list.get(0).toString()), Double.parseDouble(list.get(1).toString()), Double.parseDouble(list.get(2).toString())); + } else { + String stringFormat = o.toString(); + String[] split = stringFormat.split(","); + if (split.length == 3) { + return new Vec3d(Double.parseDouble(split[0]), Double.parseDouble(split[1]), Double.parseDouble(split[2])); + } else if (split.length == 1) { + double d = Double.parseDouble(split[0]); + return new Vec3d(d, d, d); + } else { + throw new LocalizedResourceConfigException("warning.config.type.vec3d", stringFormat, option); + } + } + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/World.java b/core/src/main/java/net/momirealms/craftengine/core/world/World.java index bc6181c8b..40dd01f58 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/World.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/World.java @@ -58,7 +58,7 @@ public interface World { void levelEvent(int id, BlockPos pos, int data); - void spawnParticle(Position location, Key particle, int count, double xOffset, double yOffset, double zOffset, double speed, @Nullable ParticleData extraData, @NotNull Context context); + void spawnParticle(Position location, Key particle, int count, double xOffset, double yOffset, double zOffset, double speed, @Nullable ParticleData extraData, @Nullable Context context); long time();