mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-29 03:49:15 +00:00
优化粒子行为实现
This commit is contained in:
@@ -7,6 +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 PARTICLE = Key.of("craftengine:particle");
|
||||
public static final Key WALL_PARTICLE = Key.of("craftengine:wall_particle");
|
||||
public static final Key SIMPLE_PARTICLE = Key.of("craftengine:simple_particle");
|
||||
public static final Key WALL_TORCH_PARTICLE = Key.of("craftengine:wall_torch_particle");
|
||||
}
|
||||
|
||||
@@ -1,115 +1,25 @@
|
||||
package net.momirealms.craftengine.core.plugin.context.function;
|
||||
|
||||
import net.momirealms.craftengine.core.block.BlockStateWrapper;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
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.Color;
|
||||
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.Position;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.World;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import net.momirealms.craftengine.core.world.particle.*;
|
||||
import net.momirealms.craftengine.core.world.particle.ParticleConfig;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ParticleFunction<CTX extends Context> extends AbstractConditionalFunction<CTX> {
|
||||
public static final Map<Key, java.util.function.Function<Map<String, Object>, ParticleData>> DATA_TYPES = new HashMap<>();
|
||||
private final ParticleConfig config;
|
||||
|
||||
static {
|
||||
registerParticleData(map -> new BlockStateData(
|
||||
LazyReference.lazyReference(new Supplier<>() {
|
||||
final String blockState = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("block-state"), "warning.config.function.particle.missing_block_state");
|
||||
@Override
|
||||
public BlockStateWrapper get() {
|
||||
return CraftEngine.instance().blockManager().createBlockState(this.blockState);
|
||||
}
|
||||
})),
|
||||
ParticleTypes.BLOCK, ParticleTypes.FALLING_DUST, ParticleTypes.DUST_PILLAR, ParticleTypes.BLOCK_CRUMBLE, ParticleTypes.BLOCK_MARKER);
|
||||
registerParticleData(map -> new ColorData(
|
||||
Color.fromStrings(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("color"), "warning.config.function.particle.missing_color").split(","))),
|
||||
ParticleTypes.ENTITY_EFFECT, ParticleTypes.TINTED_LEAVES);
|
||||
registerParticleData(map -> new JavaTypeData(
|
||||
ResourceConfigUtils.getAsFloat(map.get("charge"), "charge")),
|
||||
ParticleTypes.SCULK_CHARGE);
|
||||
registerParticleData(map -> new JavaTypeData(
|
||||
ResourceConfigUtils.getAsInt(map.get("shriek"), "shriek")),
|
||||
ParticleTypes.SHRIEK);
|
||||
registerParticleData(map -> new DustData(
|
||||
Color.fromStrings(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("color"), "warning.config.function.particle.missing_color").split(",")),
|
||||
ResourceConfigUtils.getAsFloat(map.getOrDefault("scale", 1), "scale")),
|
||||
ParticleTypes.DUST);
|
||||
registerParticleData(map -> new DustTransitionData(
|
||||
Color.fromStrings(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("from"), "warning.config.function.particle.missing_from").split(",")),
|
||||
Color.fromStrings(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("to"), "warning.config.function.particle.missing_to").split(",")),
|
||||
ResourceConfigUtils.getAsFloat(map.getOrDefault("scale", 1), "scale")),
|
||||
ParticleTypes.DUST_COLOR_TRANSITION);
|
||||
registerParticleData(map -> new ItemStackData(
|
||||
LazyReference.lazyReference(new Supplier<>() {
|
||||
final Key itemId = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("item"), "warning.config.function.particle.missing_item"));
|
||||
@Override
|
||||
public Item<?> get() {
|
||||
return CraftEngine.instance().itemManager().createWrappedItem(this.itemId, null);
|
||||
}
|
||||
})
|
||||
),
|
||||
ParticleTypes.ITEM);
|
||||
registerParticleData(map -> new VibrationData(
|
||||
NumberProviders.fromObject(map.getOrDefault("target-x", 0)),
|
||||
NumberProviders.fromObject(map.getOrDefault("target-y", 0)),
|
||||
NumberProviders.fromObject(map.getOrDefault("target-z", 0)),
|
||||
NumberProviders.fromObject(map.getOrDefault("arrival-time", 10))),
|
||||
ParticleTypes.VIBRATION);
|
||||
registerParticleData(map -> new TrailData(
|
||||
NumberProviders.fromObject(map.getOrDefault("target-x", 0)),
|
||||
NumberProviders.fromObject(map.getOrDefault("target-y", 0)),
|
||||
NumberProviders.fromObject(map.getOrDefault("target-z", 0)),
|
||||
Color.fromStrings(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("color"), "warning.config.function.particle.missing_color").split(",")),
|
||||
NumberProviders.fromObject(map.getOrDefault("duration", 10))),
|
||||
ParticleTypes.TRAIL);
|
||||
}
|
||||
|
||||
public static void registerParticleData(java.util.function.Function<Map<String, Object>, ParticleData> function, Key... types) {
|
||||
for (Key type : types) {
|
||||
DATA_TYPES.put(type, function);
|
||||
}
|
||||
}
|
||||
|
||||
private final Key particleType;
|
||||
private final NumberProvider x;
|
||||
private final NumberProvider y;
|
||||
private final NumberProvider z;
|
||||
private final NumberProvider count;
|
||||
private final NumberProvider xOffset;
|
||||
private final NumberProvider yOffset;
|
||||
private final NumberProvider zOffset;
|
||||
private final NumberProvider speed;
|
||||
private final ParticleData particleData;
|
||||
|
||||
public ParticleFunction(Key particleType, NumberProvider x, NumberProvider y, NumberProvider z, NumberProvider count,
|
||||
NumberProvider xOffset, NumberProvider yOffset, NumberProvider zOffset, NumberProvider speed, ParticleData particleData, List<Condition<CTX>> predicates) {
|
||||
public ParticleFunction(ParticleConfig config, List<Condition<CTX>> predicates) {
|
||||
super(predicates);
|
||||
this.particleType = particleType;
|
||||
this.count = count;
|
||||
this.xOffset = xOffset;
|
||||
this.yOffset = yOffset;
|
||||
this.zOffset = zOffset;
|
||||
this.speed = speed;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.particleData = particleData;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,8 +27,8 @@ public class ParticleFunction<CTX extends Context> extends AbstractConditionalFu
|
||||
Optional<WorldPosition> optionalWorldPosition = ctx.getOptionalParameter(DirectContextParameters.POSITION);
|
||||
if (optionalWorldPosition.isPresent()) {
|
||||
World world = optionalWorldPosition.get().world();
|
||||
Position position = new Vec3d(this.x.getDouble(ctx), this.y.getDouble(ctx), this.z.getDouble(ctx));
|
||||
world.spawnParticle(position, this.particleType, this.count.getInt(ctx), this.xOffset.getDouble(ctx), this.yOffset.getDouble(ctx), this.zOffset.getDouble(ctx), this.speed.getDouble(ctx), this.particleData, ctx);
|
||||
Position position = new Vec3d(config.x.getDouble(ctx), config.y.getDouble(ctx), config.z.getDouble(ctx));
|
||||
world.spawnParticle(position, config.particleType, config.count.getInt(ctx), config.xOffset.getDouble(ctx), config.yOffset.getDouble(ctx), config.zOffset.getDouble(ctx), config.speed.getDouble(ctx), config.particleData, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,17 +45,7 @@ public class ParticleFunction<CTX extends Context> extends AbstractConditionalFu
|
||||
|
||||
@Override
|
||||
public Function<CTX> create(Map<String, Object> arguments) {
|
||||
Key particleType = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("particle"), "warning.config.function.particle.missing_particle"));
|
||||
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 count = NumberProviders.fromObject(arguments.getOrDefault("count", 1));
|
||||
NumberProvider xOffset = NumberProviders.fromObject(arguments.getOrDefault("offset-x", 0));
|
||||
NumberProvider yOffset = NumberProviders.fromObject(arguments.getOrDefault("offset-y", 0));
|
||||
NumberProvider zOffset = NumberProviders.fromObject(arguments.getOrDefault("offset-z", 0));
|
||||
NumberProvider speed = NumberProviders.fromObject(arguments.getOrDefault("speed", 0));
|
||||
return new ParticleFunction<>(particleType, x, y, z, count, xOffset, yOffset, zOffset, speed,
|
||||
Optional.ofNullable(ParticleFunction.DATA_TYPES.get(particleType)).map(it -> it.apply(arguments)).orElse(null), getPredicates(arguments));
|
||||
return new ParticleFunction<>(ParticleConfig.fromMap$function(arguments), getPredicates(arguments));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,26 @@ package net.momirealms.craftengine.core.util;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public enum HorizontalDirection {
|
||||
NORTH,
|
||||
SOUTH,
|
||||
WEST,
|
||||
EAST;
|
||||
NORTH(0, -1),
|
||||
SOUTH(0, 1),
|
||||
WEST(-1, 0),
|
||||
EAST(1, 0);
|
||||
|
||||
private final int adjX;
|
||||
private final int adjZ;
|
||||
|
||||
HorizontalDirection(int adjX, int adjZ) {
|
||||
this.adjX = adjX;
|
||||
this.adjZ = adjZ;
|
||||
}
|
||||
|
||||
public int stepX() {
|
||||
return this.adjX;
|
||||
}
|
||||
|
||||
public int stepZ() {
|
||||
return this.adjZ;
|
||||
}
|
||||
|
||||
public Direction toDirection() {
|
||||
return switch (this) {
|
||||
|
||||
@@ -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, @Nullable Context context);
|
||||
void spawnParticle(Position location, Key particle, int count, double xOffset, double yOffset, double zOffset, double speed, @Nullable ParticleData extraData, @NotNull Context context);
|
||||
|
||||
long time();
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package net.momirealms.craftengine.core.world.particle;
|
||||
|
||||
import net.momirealms.craftengine.core.plugin.context.number.NumberProvider;
|
||||
import net.momirealms.craftengine.core.plugin.context.number.NumberProviders;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ParticleConfig {
|
||||
public final Key particleType;
|
||||
public final NumberProvider x;
|
||||
public final NumberProvider y;
|
||||
public final NumberProvider z;
|
||||
public final NumberProvider count;
|
||||
public final NumberProvider xOffset;
|
||||
public final NumberProvider yOffset;
|
||||
public final NumberProvider zOffset;
|
||||
public final NumberProvider speed;
|
||||
public final ParticleData particleData;
|
||||
|
||||
public ParticleConfig(Key particleType, NumberProvider x, NumberProvider y, NumberProvider z, NumberProvider count, NumberProvider xOffset, NumberProvider yOffset, NumberProvider zOffset, NumberProvider speed, ParticleData particleData) {
|
||||
this.particleType = particleType;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.count = count;
|
||||
this.xOffset = xOffset;
|
||||
this.yOffset = yOffset;
|
||||
this.zOffset = zOffset;
|
||||
this.speed = speed;
|
||||
this.particleData = particleData;
|
||||
}
|
||||
|
||||
public static ParticleConfig fromMap$function(Map<String, Object> arguments) {
|
||||
Key particleType = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("particle"), "warning.config.function.particle.missing_particle"));
|
||||
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 count = NumberProviders.fromObject(arguments.getOrDefault("count", 1));
|
||||
NumberProvider xOffset = NumberProviders.fromObject(arguments.getOrDefault("offset-x", 0));
|
||||
NumberProvider yOffset = NumberProviders.fromObject(arguments.getOrDefault("offset-y", 0));
|
||||
NumberProvider zOffset = NumberProviders.fromObject(arguments.getOrDefault("offset-z", 0));
|
||||
NumberProvider speed = NumberProviders.fromObject(arguments.getOrDefault("speed", 0));
|
||||
return new ParticleConfig(particleType, x, y, z, count, xOffset, yOffset, zOffset, speed, Optional.ofNullable(ParticleDataTypes.TYPES.get(particleType)).map(it -> it.apply(arguments)).orElse(null));
|
||||
}
|
||||
|
||||
public static ParticleConfig fromMap$blockEntity(Map<String, Object> arguments) {
|
||||
Key particleType = Key.of(arguments.getOrDefault("particle", "flame").toString());
|
||||
NumberProvider x = NumberProviders.fromObject(arguments.getOrDefault("x", 0));
|
||||
NumberProvider y = NumberProviders.fromObject(arguments.getOrDefault("y", 0));
|
||||
NumberProvider z = NumberProviders.fromObject(arguments.getOrDefault("z", 0));
|
||||
NumberProvider count = NumberProviders.fromObject(arguments.getOrDefault("count", 1));
|
||||
NumberProvider xOffset = NumberProviders.fromObject(arguments.getOrDefault("offset-x", 0));
|
||||
NumberProvider yOffset = NumberProviders.fromObject(arguments.getOrDefault("offset-y", 0));
|
||||
NumberProvider zOffset = NumberProviders.fromObject(arguments.getOrDefault("offset-z", 0));
|
||||
NumberProvider speed = NumberProviders.fromObject(arguments.getOrDefault("speed", 0));
|
||||
return new ParticleConfig(particleType, x, y, z, count, xOffset, yOffset, zOffset, speed, Optional.ofNullable(ParticleDataTypes.TYPES.get(particleType)).map(it -> it.apply(arguments)).orElse(null));
|
||||
}
|
||||
|
||||
public Key particleType() {
|
||||
return particleType;
|
||||
}
|
||||
|
||||
public NumberProvider x() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public NumberProvider y() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public NumberProvider z() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public NumberProvider count() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public NumberProvider xOffset() {
|
||||
return xOffset;
|
||||
}
|
||||
|
||||
public NumberProvider yOffset() {
|
||||
return yOffset;
|
||||
}
|
||||
|
||||
public NumberProvider zOffset() {
|
||||
return zOffset;
|
||||
}
|
||||
|
||||
public NumberProvider speed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
public ParticleData particleData() {
|
||||
return particleData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package net.momirealms.craftengine.core.world.particle;
|
||||
|
||||
import net.momirealms.craftengine.core.block.BlockStateWrapper;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.context.number.NumberProviders;
|
||||
import net.momirealms.craftengine.core.util.Color;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.LazyReference;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class ParticleDataTypes {
|
||||
public static final Map<Key, java.util.function.Function<Map<String, Object>, ParticleData>> TYPES = new HashMap<>();
|
||||
|
||||
static {
|
||||
registerParticleData(map -> new BlockStateData(
|
||||
LazyReference.lazyReference(new Supplier<>() {
|
||||
final String blockState = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("block-state"), "warning.config.function.particle.missing_block_state");
|
||||
@Override
|
||||
public BlockStateWrapper get() {
|
||||
return CraftEngine.instance().blockManager().createBlockState(this.blockState);
|
||||
}
|
||||
})),
|
||||
ParticleTypes.BLOCK, ParticleTypes.FALLING_DUST, ParticleTypes.DUST_PILLAR, ParticleTypes.BLOCK_CRUMBLE, ParticleTypes.BLOCK_MARKER);
|
||||
registerParticleData(map -> new ColorData(
|
||||
Color.fromStrings(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("color"), "warning.config.function.particle.missing_color").split(","))),
|
||||
ParticleTypes.ENTITY_EFFECT, ParticleTypes.TINTED_LEAVES);
|
||||
registerParticleData(map -> new JavaTypeData(
|
||||
ResourceConfigUtils.getAsFloat(map.get("charge"), "charge")),
|
||||
ParticleTypes.SCULK_CHARGE);
|
||||
registerParticleData(map -> new JavaTypeData(
|
||||
ResourceConfigUtils.getAsInt(map.get("shriek"), "shriek")),
|
||||
ParticleTypes.SHRIEK);
|
||||
registerParticleData(map -> new DustData(
|
||||
Color.fromStrings(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("color"), "warning.config.function.particle.missing_color").split(",")),
|
||||
ResourceConfigUtils.getAsFloat(map.getOrDefault("scale", 1), "scale")),
|
||||
ParticleTypes.DUST);
|
||||
registerParticleData(map -> new DustTransitionData(
|
||||
Color.fromStrings(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("from"), "warning.config.function.particle.missing_from").split(",")),
|
||||
Color.fromStrings(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("to"), "warning.config.function.particle.missing_to").split(",")),
|
||||
ResourceConfigUtils.getAsFloat(map.getOrDefault("scale", 1), "scale")),
|
||||
ParticleTypes.DUST_COLOR_TRANSITION);
|
||||
registerParticleData(map -> new ItemStackData(
|
||||
LazyReference.lazyReference(new Supplier<>() {
|
||||
final Key itemId = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("item"), "warning.config.function.particle.missing_item"));
|
||||
@Override
|
||||
public Item<?> get() {
|
||||
return CraftEngine.instance().itemManager().createWrappedItem(this.itemId, null);
|
||||
}
|
||||
})
|
||||
),
|
||||
ParticleTypes.ITEM);
|
||||
registerParticleData(map -> new VibrationData(
|
||||
NumberProviders.fromObject(map.getOrDefault("target-x", 0)),
|
||||
NumberProviders.fromObject(map.getOrDefault("target-y", 0)),
|
||||
NumberProviders.fromObject(map.getOrDefault("target-z", 0)),
|
||||
NumberProviders.fromObject(map.getOrDefault("arrival-time", 10))),
|
||||
ParticleTypes.VIBRATION);
|
||||
registerParticleData(map -> new TrailData(
|
||||
NumberProviders.fromObject(map.getOrDefault("target-x", 0)),
|
||||
NumberProviders.fromObject(map.getOrDefault("target-y", 0)),
|
||||
NumberProviders.fromObject(map.getOrDefault("target-z", 0)),
|
||||
Color.fromStrings(ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("color"), "warning.config.function.particle.missing_color").split(",")),
|
||||
NumberProviders.fromObject(map.getOrDefault("duration", 10))),
|
||||
ParticleTypes.TRAIL);
|
||||
}
|
||||
|
||||
public static void registerParticleData(java.util.function.Function<Map<String, Object>, ParticleData> function, Key... types) {
|
||||
for (Key type : types) {
|
||||
TYPES.put(type, function);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user