use of org.lanternpowered.server.effect.particle.LanternParticleType in project LanternServer by LanternPowered.
the class CommandParticle method completeSpec.
@Override
public void completeSpec(PluginContainer pluginContainer, CommandSpec.Builder specBuilder) {
specBuilder.arguments(new PatternMatchingCommandElement(Text.of("type")) {
@Override
protected Iterable<String> getChoices(CommandSource source) {
return Sponge.getGame().getRegistry().getAllOf(ParticleType.class).stream().filter(type -> ((LanternParticleType) type).getInternalType().isPresent()).map(CatalogType::getId).collect(Collectors.toList());
}
@Override
protected Object getValue(String choice) throws IllegalArgumentException {
final Optional<ParticleType> ret = Sponge.getGame().getRegistry().getType(ParticleType.class, choice);
if (!ret.isPresent() || !((LanternParticleType) ret.get()).getInternalType().isPresent()) {
throw new IllegalArgumentException("Invalid input " + choice + " was found");
}
return ret.get();
}
}, GenericArguments2.targetedVector3d(Text.of("position")), // The default value should be 0 for x, y and z
GenericArguments2.vector3d(Text.of("offset"), Vector3d.ZERO), GenericArguments2.doubleNum(Text.of("speed"), 1.0), GenericArguments.optional(GenericArguments2.integer(Text.of("count"), 1)), GenericArguments.optional(new CommandElement(Text.of("mode")) {
@Nullable
@Override
protected Object parseValue(CommandSource source, CommandArgs args) throws ArgumentParseException {
return args.next();
}
@Override
public List<String> complete(CommandSource src, CommandArgs args, CommandContext context) {
Optional<String> arg = args.nextIfPresent();
if (arg.isPresent()) {
return Stream.of("normal", "force").filter(new StartsWithPredicate(arg.get())).collect(Collectors.toList());
}
return Collections.emptyList();
}
}), GenericArguments.optional(GenericArguments.player(Text.of("player"))), GenericArguments.optional(new CommandElement(Text.of("params")) {
@Nullable
@Override
protected Object parseValue(CommandSource source, CommandArgs args) throws ArgumentParseException {
List<Integer> params = new ArrayList<>();
while (args.hasNext()) {
String arg = args.next();
try {
params.add(Integer.parseInt(arg));
} catch (NumberFormatException e) {
throw args.createError(t("Expected an integer, but input '%s' was not", arg));
}
}
return params.stream().mapToInt(i -> i).toArray();
}
@Override
public List<String> complete(CommandSource src, CommandArgs args, CommandContext context) {
return Collections.emptyList();
}
})).executor((src, args) -> {
final LanternParticleType particleType = args.<LanternParticleType>getOne("type").get();
final int particleId = particleType.getInternalType().getAsInt();
final Vector3f position = args.<Vector3d>getOne("position").get().toFloat();
final Vector3f offset = args.<Vector3d>getOne("offset").get().toFloat();
final float speed = args.<Double>getOne("speed").get().floatValue();
final int count = args.<Integer>getOne("count").orElse(1);
final boolean longDistance = args.<String>getOne("mode").map(mode -> mode.equalsIgnoreCase("force")).orElse(false);
final int[] params = args.<int[]>getOne("params").orElse(new int[0]);
final LanternWorld world = CommandHelper.getWorld(src, args);
final int dataLength;
if (particleType == ParticleTypes.BLOCK_CRACK || particleType == ParticleTypes.BLOCK_DUST || particleType == ParticleTypes.FALLING_DUST) {
dataLength = 1;
} else if (particleType == ParticleTypes.ITEM_CRACK) {
dataLength = 2;
} else {
dataLength = 0;
}
if (params.length != dataLength) {
throw new CommandException(t("Invalid parameters (%s), length mismatch (got %s, expected %s) for the particle type %s", Arrays.toString(params), params.length, dataLength, particleType.getId()));
}
final MessagePlayOutSpawnParticle message = new MessagePlayOutSpawnParticle(particleId, position, offset, speed, count, params, longDistance);
if (args.hasAny("player")) {
args.<LanternPlayer>getOne("player").get().getConnection().send(message);
} else {
for (LanternPlayer player : world.getRawPlayers()) {
player.getConnection().send(message);
}
}
src.sendMessage(t("commands.particle.success", particleType.getName(), count));
return CommandResult.success();
});
}
use of org.lanternpowered.server.effect.particle.LanternParticleType in project LanternServer by LanternPowered.
the class ProcessorPlayOutParticleEffect method preProcess.
private ICachedMessage preProcess(ParticleEffect effect0) {
final LanternParticleEffect effect = (LanternParticleEffect) effect0;
final LanternParticleType type = effect.getType();
final OptionalInt internalType = type.getInternalType();
// Special cases
if (!internalType.isPresent()) {
if (type == ParticleTypes.FIREWORKS) {
// Create the fireworks data item
final LanternItemStack itemStack = new LanternItemStack(ItemTypes.FIREWORKS);
itemStack.tryOffer(Keys.FIREWORK_EFFECTS, effect.getOptionOrDefault(ParticleOptions.FIREWORK_EFFECTS).get());
// Write the item to a parameter list
final ByteBufParameterList parameterList = new ByteBufParameterList(ByteBufferAllocator.unpooled());
parameterList.add(EntityParameters.Fireworks.ITEM, itemStack);
return new CachedFireworksMessage(new MessagePlayOutEntityMetadata(CachedFireworksMessage.ENTITY_ID, parameterList));
} else if (type == ParticleTypes.FERTILIZER) {
final int quantity = effect.getOptionOrDefault(ParticleOptions.QUANTITY).get();
return new CachedEffectMessage(2005, quantity, false);
} else if (type == ParticleTypes.SPLASH_POTION) {
final int potionId = this.potionEffectTypeToId.getInt(effect.getOptionOrDefault(ParticleOptions.POTION_EFFECT_TYPE).get());
return new CachedEffectMessage(2002, potionId, false);
} else if (type == ParticleTypes.BREAK_BLOCK) {
final int state = getBlockState(effect, type.getDefaultOption(ParticleOptions.BLOCK_STATE));
if (state == 0) {
return EmptyCachedMessage.INSTANCE;
}
return new CachedEffectMessage(2001, state, false);
} else if (type == ParticleTypes.MOBSPAWNER_FLAMES) {
return new CachedEffectMessage(2004, 0, false);
} else if (type == ParticleTypes.ENDER_TELEPORT) {
return new CachedEffectMessage(2003, 0, false);
} else if (type == ParticleTypes.DRAGON_BREATH_ATTACK) {
return new CachedEffectMessage(2006, 0, false);
} else if (type == ParticleTypes.FIRE_SMOKE) {
final Direction direction = effect.getOptionOrDefault(ParticleOptions.DIRECTION).get();
return new CachedEffectMessage(2000, getDirectionData(direction), false);
}
return EmptyCachedMessage.INSTANCE;
}
final int internalId = internalType.getAsInt();
final Vector3f offset = effect.getOption(ParticleOptions.OFFSET).map(Vector3d::toFloat).orElse(Vector3f.ZERO);
final int quantity = effect.getOption(ParticleOptions.QUANTITY).orElse(1);
int[] extra = null;
// The extra values, normal behavior offsetX, offsetY, offsetZ
double f0 = 0f;
double f1 = 0f;
double f2 = 0f;
// Depends on behavior
// Note: If the count > 0 -> speed = 0f else if count = 0 -> speed = 1f
final Optional<BlockState> defaultBlockState;
if (type != ParticleTypes.ITEM_CRACK && (defaultBlockState = type.getDefaultOption(ParticleOptions.BLOCK_STATE)).isPresent()) {
final int state = getBlockState(effect, defaultBlockState);
if (state == 0) {
return EmptyCachedMessage.INSTANCE;
}
extra = new int[] { state };
}
final Optional<ItemStackSnapshot> defaultItemStackSnapshot;
if (extra == null && (defaultItemStackSnapshot = type.getDefaultOption(ParticleOptions.ITEM_STACK_SNAPSHOT)).isPresent()) {
final Optional<ItemStackSnapshot> optItemStackSnapshot = effect.getOption(ParticleOptions.ITEM_STACK_SNAPSHOT);
if (optItemStackSnapshot.isPresent()) {
extra = toExtraItemData(optItemStackSnapshot.get().createStack());
} else {
final Optional<BlockState> optBlockState = effect.getOption(ParticleOptions.BLOCK_STATE);
if (optBlockState.isPresent()) {
final BlockState blockState = optBlockState.get();
final Optional<ItemType> optItemType = blockState.getType().getItem();
if (optItemType.isPresent()) {
// TODO: Item damage value
extra = new int[] { ItemRegistryModule.get().getInternalId(optItemType.get()), 0 };
} else {
return EmptyCachedMessage.INSTANCE;
}
} else {
extra = toExtraItemData(defaultItemStackSnapshot.get().createStack());
}
}
}
if (extra == null) {
extra = new int[0];
}
final Optional<Double> defaultScale = type.getDefaultOption(ParticleOptions.SCALE);
final Optional<Color> defaultColor;
final Optional<NotePitch> defaultNote;
final Optional<Vector3d> defaultVelocity;
if (defaultScale.isPresent()) {
double scale = effect.getOption(ParticleOptions.SCALE).orElse(defaultScale.get());
// Server formula: sizeServer = (-sizeClient * 2) + 2
if (type == ParticleTypes.LARGE_EXPLOSION || type == ParticleTypes.SWEEP_ATTACK) {
scale = (-scale * 2f) + 2f;
}
if (scale == 0f) {
return new CachedParticleMessage(internalId, offset, quantity, extra);
}
f0 = scale;
} else if ((defaultColor = type.getDefaultOption(ParticleOptions.COLOR)).isPresent()) {
final boolean isSpell = type == ParticleTypes.MOB_SPELL || type == ParticleTypes.AMBIENT_MOB_SPELL;
Color color = effect.getOption(ParticleOptions.COLOR).orElse(null);
if (!isSpell && (color == null || color.equals(defaultColor.get()))) {
return new CachedParticleMessage(internalId, offset, quantity, extra);
} else if (isSpell && color == null) {
color = defaultColor.get();
}
f0 = color.getRed() / 255f;
f1 = color.getGreen() / 255f;
f2 = color.getBlue() / 255f;
// but we already chose for the color, can't have both
if (isSpell) {
f0 = Math.max(f0, 0.001f);
f2 = Math.max(f0, 0.001f);
}
// If the f0 value 0 is, the redstone will set it automatically to red 255
if (f0 == 0f && type == ParticleTypes.REDSTONE_DUST) {
f0 = 0.00001f;
}
} else if ((defaultNote = type.getDefaultOption(ParticleOptions.NOTE)).isPresent()) {
final NotePitch notePitch = effect.getOption(ParticleOptions.NOTE).orElse(defaultNote.get());
final float note = ((LanternNotePitch) notePitch).getInternalId();
if (note == 0f) {
return new CachedParticleMessage(internalId, offset, quantity, extra);
}
f0 = note / 24f;
} else if ((defaultVelocity = type.getDefaultOption(ParticleOptions.VELOCITY)).isPresent()) {
final Vector3d velocity = effect.getOption(ParticleOptions.VELOCITY).orElse(defaultVelocity.get());
f0 = velocity.getX();
f1 = velocity.getY();
f2 = velocity.getZ();
final Optional<Boolean> slowHorizontalVelocity = type.getDefaultOption(ParticleOptions.SLOW_HORIZONTAL_VELOCITY);
if (slowHorizontalVelocity.isPresent() && effect.getOption(ParticleOptions.SLOW_HORIZONTAL_VELOCITY).orElse(slowHorizontalVelocity.get())) {
f0 = 0f;
f2 = 0f;
}
// The y value won't work for this effect, if the value isn't 0 the velocity won't work
if (type == ParticleTypes.WATER_SPLASH) {
f1 = 0f;
}
if (f0 == 0f && f1 == 0f && f2 == 0f) {
return new CachedParticleMessage(internalId, offset, quantity, extra);
}
}
// Is this check necessary?
if (f0 == 0f && f1 == 0f && f2 == 0f) {
return new CachedParticleMessage(internalId, offset, quantity, extra);
}
return new CachedOffsetParticleMessage(internalId, new Vector3f(f0, f1, f2), offset, quantity, extra);
}
Aggregations