ready for 1.0! Idc that it may be buggy, I want 1.0 now!
This commit is contained in:
@@ -52,6 +52,10 @@ import kotlin.reflect.full.declaredMemberProperties
|
||||
// Copying particle params in-game.
|
||||
// Custom curve equation command args (parse from strings).
|
||||
// Force field "config" option.
|
||||
// add rotation offset to transformWithVel
|
||||
|
||||
// TODO: (now)
|
||||
// nothing lmao
|
||||
|
||||
|
||||
var ALL_PARTICLE_EMITTERS: Array<ParticleEmitter> = emptyArray()
|
||||
|
||||
@@ -77,7 +77,7 @@ class DisplayEntity(var properties: DisplayEntityProperties?) {
|
||||
putString("billboard", properties.billboard)
|
||||
|
||||
if (properties.customName != null) {
|
||||
putString("CustomName", properties.customName)
|
||||
putString("CustomName", "{\"text\":\"${properties.customName}\"}")
|
||||
putByte("CustomNameVisible", 1)
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,10 @@ class LerpCurves(val function: (Float) -> Float) {
|
||||
|
||||
fun custom(equation: (Float) -> Float) = LerpCurves(equation)
|
||||
}
|
||||
|
||||
fun deepCopy() : LerpCurves {
|
||||
return LerpCurves(this.function)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,12 +76,16 @@ fun raycastFromPlayer(player: ServerPlayerEntity, maxDistance: Double): HitResul
|
||||
|
||||
|
||||
fun randomFloatBetween(min: Float, max: Float) : Float {
|
||||
return Random.nextFloat() * (max - min) + min
|
||||
return if (min == max) { max }
|
||||
else if (min > max) { Random.nextFloat() * (min - max) + max }
|
||||
else { Random.nextFloat() * (max - min) + min }
|
||||
}
|
||||
|
||||
|
||||
fun randomIntBetween(min: Int, max: Int) : Int {
|
||||
return Random.nextInt(max - min) + min
|
||||
return if (min == max) { max }
|
||||
else if (min > max) { Random.nextInt(min - max) + max }
|
||||
else { Random.nextInt(max - min) + min }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -377,6 +377,25 @@ fun pairVec3fArg(access: KProperty1<EmitterParams,ParamClasses.PairVec3f>,
|
||||
)
|
||||
)
|
||||
)
|
||||
.then(CommandManager.literal("Constant")
|
||||
.then(CommandManager.argument("X", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Y", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Z", FloatArgumentType.floatArg())
|
||||
.executes { context ->
|
||||
val id = StringArgumentType.getString(context, "Emitter ID")
|
||||
val x = FloatArgumentType.getFloat(context, "X")
|
||||
val y = FloatArgumentType.getFloat(context, "Y")
|
||||
val z = FloatArgumentType.getFloat(context, "Z")
|
||||
|
||||
updateParam(id, access, ParamClasses.PairVec3f.Constant(Vector3f(x, y, z)))
|
||||
|
||||
successText(access, "Constant", id, context)
|
||||
Command.SINGLE_SUCCESS
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
.then(CommandManager.literal("Null")
|
||||
.executes { context ->
|
||||
val id = StringArgumentType.getString(context, "Emitter ID")
|
||||
@@ -430,12 +449,12 @@ fun transformWithVelArg(access: KProperty1<EmitterParams, ParamClasses.Transform
|
||||
}
|
||||
)
|
||||
)
|
||||
.then(CommandManager.literal("None")
|
||||
.then(CommandManager.literal("Null")
|
||||
.executes { context ->
|
||||
val id = StringArgumentType.getString(context, "Emitter ID")
|
||||
|
||||
updateParam(id, access, ParamClasses.TransformWithVel.None)
|
||||
successText(access, "None", id, context)
|
||||
updateParam(id, access, ParamClasses.TransformWithVel.Null)
|
||||
successText(access, "Null", id, context)
|
||||
Command.SINGLE_SUCCESS
|
||||
}
|
||||
)
|
||||
@@ -458,7 +477,7 @@ fun stringCurveArg(access: KProperty1<EmitterParams, ParamClasses.StringCurve>,
|
||||
}
|
||||
)
|
||||
.executes { context ->
|
||||
stringCurveAddArg(context, access, -1)
|
||||
stringCurveAddArg(context, access, null)
|
||||
Command.SINGLE_SUCCESS
|
||||
}
|
||||
)
|
||||
@@ -472,7 +491,7 @@ fun stringCurveArg(access: KProperty1<EmitterParams, ParamClasses.StringCurve>,
|
||||
}
|
||||
)
|
||||
.executes { context ->
|
||||
stringCurveRemoveArg(context, access, -1)
|
||||
stringCurveRemoveArg(context, access, null)
|
||||
Command.SINGLE_SUCCESS
|
||||
}
|
||||
)
|
||||
@@ -492,7 +511,6 @@ fun stringCurveArg(access: KProperty1<EmitterParams, ParamClasses.StringCurve>,
|
||||
Command.SINGLE_SUCCESS
|
||||
}
|
||||
else {
|
||||
println("$modelCurve, $curve, $curveName")
|
||||
negativeFeedback("Failed to update param \"modelCurve.curve\"! The curve is invalid!", context)
|
||||
Command.SINGLE_SUCCESS
|
||||
}
|
||||
@@ -505,7 +523,7 @@ fun stringCurveArg(access: KProperty1<EmitterParams, ParamClasses.StringCurve>,
|
||||
|
||||
fun stringCurveAddArg(context: CommandContext<ServerCommandSource>,
|
||||
access: KProperty1<EmitterParams, ParamClasses.StringCurve>,
|
||||
index: Int
|
||||
index: Int?
|
||||
) {
|
||||
val id = StringArgumentType.getString(context, "Emitter ID")
|
||||
val item = ItemStackArgumentType.getItemStackArgument(context, "Item").item
|
||||
@@ -513,12 +531,12 @@ fun stringCurveAddArg(context: CommandContext<ServerCommandSource>,
|
||||
|
||||
val modelCurve = getEmitterDataById(id)?.modelCurve
|
||||
|
||||
if (index == -1 && modelCurve != null) {
|
||||
if (index == null && modelCurve != null) {
|
||||
modelCurve.array = modelCurve.array.toMutableList().apply { add(itemId) }.toTypedArray()
|
||||
updateParam(id, access, modelCurve)
|
||||
}
|
||||
else if (modelCurve != null) {
|
||||
modelCurve.array = modelCurve.array.toMutableList().apply { add(index.coerceIn(0, modelCurve.array.lastIndex), itemId) }.toTypedArray()
|
||||
modelCurve.array = modelCurve.array.toMutableList().apply { add(index!!.coerceIn(0, modelCurve.array.lastIndex), itemId) }.toTypedArray()
|
||||
updateParam(id, access, modelCurve)
|
||||
}
|
||||
|
||||
@@ -527,7 +545,7 @@ fun stringCurveAddArg(context: CommandContext<ServerCommandSource>,
|
||||
|
||||
fun stringCurveRemoveArg(context: CommandContext<ServerCommandSource>,
|
||||
access: KProperty1<EmitterParams, ParamClasses.StringCurve>,
|
||||
index: Int
|
||||
index: Int?
|
||||
) {
|
||||
val id = StringArgumentType.getString(context, "Emitter ID")
|
||||
|
||||
@@ -535,13 +553,13 @@ fun stringCurveRemoveArg(context: CommandContext<ServerCommandSource>,
|
||||
|
||||
val item: String
|
||||
|
||||
if (index == -1 && modelCurve != null && modelCurve.array.isNotEmpty()) {
|
||||
if (index == null && modelCurve != null && modelCurve.array.isNotEmpty()) {
|
||||
item = modelCurve.array.last()
|
||||
modelCurve.array = modelCurve.array.toMutableList().apply { removeLast() }.toTypedArray()
|
||||
updateParam(id, access, modelCurve)
|
||||
}
|
||||
else if (modelCurve != null && modelCurve.array.isNotEmpty()) {
|
||||
item = modelCurve.array[index.coerceIn(0, modelCurve.array.lastIndex)]
|
||||
item = modelCurve.array[index!!.coerceIn(0, modelCurve.array.lastIndex)]
|
||||
modelCurve.array = modelCurve.array.toMutableList().apply { removeAt(index.coerceIn(0, modelCurve.array.lastIndex)) }.toTypedArray()
|
||||
updateParam(id, access, modelCurve)
|
||||
}
|
||||
@@ -698,8 +716,15 @@ fun forceFieldArg(access: KProperty1<EmitterParams,ParamClasses.ForceFieldArray>
|
||||
.then(CommandManager.argument("Radius", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Min Force", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Max Force", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Index", IntegerArgumentType.integer())
|
||||
.executes { context ->
|
||||
forceFieldAddArg(context, access, "Sphere")
|
||||
val index = IntegerArgumentType.getInteger(context, "Index")
|
||||
forceFieldAddArg(context, access, "Sphere", index)
|
||||
Command.SINGLE_SUCCESS
|
||||
}
|
||||
)
|
||||
.executes { context ->
|
||||
forceFieldAddArg(context, access, "Sphere", null)
|
||||
Command.SINGLE_SUCCESS
|
||||
}
|
||||
)
|
||||
@@ -710,15 +735,20 @@ fun forceFieldArg(access: KProperty1<EmitterParams,ParamClasses.ForceFieldArray>
|
||||
.then(CommandManager.argument("Size X", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Size Y", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Size Z", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Dir X", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Dir Y", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Dir Z", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Force", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Force X", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Force Y", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Force Z", FloatArgumentType.floatArg())
|
||||
.then(CommandManager.argument("Index", IntegerArgumentType.integer())
|
||||
.executes { context ->
|
||||
forceFieldAddArg(context, access, "Cube")
|
||||
val index = IntegerArgumentType.getInteger(context, "Index")
|
||||
forceFieldAddArg(context, access, "Cube", index)
|
||||
Command.SINGLE_SUCCESS
|
||||
}
|
||||
)
|
||||
.executes { context ->
|
||||
forceFieldAddArg(context, access, "Cube", null)
|
||||
Command.SINGLE_SUCCESS
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -742,7 +772,7 @@ fun forceFieldArg(access: KProperty1<EmitterParams,ParamClasses.ForceFieldArray>
|
||||
}
|
||||
)
|
||||
.executes { context ->
|
||||
forceFieldRemoveArg(context, access, -1)
|
||||
forceFieldRemoveArg(context, access, null)
|
||||
Command.SINGLE_SUCCESS
|
||||
}
|
||||
)
|
||||
@@ -750,7 +780,8 @@ fun forceFieldArg(access: KProperty1<EmitterParams,ParamClasses.ForceFieldArray>
|
||||
|
||||
fun forceFieldAddArg(context: CommandContext<ServerCommandSource>,
|
||||
access: KProperty1<EmitterParams, ParamClasses.ForceFieldArray>,
|
||||
shape: String
|
||||
shape: String,
|
||||
index: Int?
|
||||
) {
|
||||
val id = StringArgumentType.getString(context, "Emitter ID")
|
||||
val x = FloatArgumentType.getFloat(context, "X")
|
||||
@@ -775,21 +806,29 @@ fun forceFieldAddArg(context: CommandContext<ServerCommandSource>,
|
||||
val sizeX = FloatArgumentType.getFloat(context, "Size X")
|
||||
val sizeY = FloatArgumentType.getFloat(context, "Size Y")
|
||||
val sizeZ = FloatArgumentType.getFloat(context, "Size Z")
|
||||
val dirX = FloatArgumentType.getFloat(context, "Dir X")
|
||||
val dirY = FloatArgumentType.getFloat(context, "Dir Y")
|
||||
val dirZ = FloatArgumentType.getFloat(context, "Dir Z")
|
||||
val force = FloatArgumentType.getFloat(context, "Force")
|
||||
val forceX = FloatArgumentType.getFloat(context, "Force X")
|
||||
val forceY = FloatArgumentType.getFloat(context, "Force Y")
|
||||
val forceZ = FloatArgumentType.getFloat(context, "Force Z")
|
||||
|
||||
forceField = ForceField(
|
||||
Vector3f(x, y, z),
|
||||
ForceFieldShape.Cube(Vector3f(sizeX, sizeY, sizeZ), Vector3f(dirX, dirY, dirZ), force)
|
||||
ForceFieldShape.Cube(Vector3f(sizeX, sizeY, sizeZ), Vector3f(forceX, forceY, forceZ))
|
||||
)
|
||||
}
|
||||
|
||||
if (forceFields != null && forceField != null) {
|
||||
if (index == null) {
|
||||
forceFields.array = forceFields.array.toMutableList().apply { add(forceField) }.toTypedArray()
|
||||
}
|
||||
else {
|
||||
val newIndex = index.coerceIn(0, forceFields.array.size)
|
||||
forceFields.array = forceFields.array.toMutableList().apply { add(newIndex, forceField) }.toTypedArray()
|
||||
}
|
||||
|
||||
val calcIndex = index?.coerceIn(0, forceFields.array.size)
|
||||
|
||||
updateParam(id, access, forceFields)
|
||||
successText(access, "++ForceField", id, context)
|
||||
successText(access, "++ForceField at $calcIndex", id, context)
|
||||
}
|
||||
else {
|
||||
negativeFeedback("Failed to update param \"forceFields\"! The Emitter ID is most likely invalid!", context)
|
||||
@@ -798,18 +837,19 @@ fun forceFieldAddArg(context: CommandContext<ServerCommandSource>,
|
||||
|
||||
fun forceFieldRemoveArg(context: CommandContext<ServerCommandSource>,
|
||||
access: KProperty1<EmitterParams, ParamClasses.ForceFieldArray>,
|
||||
index: Int
|
||||
index: Int?
|
||||
) {
|
||||
val id = StringArgumentType.getString(context, "Emitter ID")
|
||||
|
||||
val forceFields = getEmitterDataById(id)?.forceFields
|
||||
|
||||
if (index == -1 && forceFields != null && forceFields.array.isNotEmpty()) {
|
||||
if (index == null && forceFields != null && forceFields.array.isNotEmpty()) {
|
||||
forceFields.array = forceFields.array.toMutableList().apply { removeLast() }.toTypedArray()
|
||||
updateParam(id, access, forceFields)
|
||||
}
|
||||
else if (forceFields != null && forceFields.array.isNotEmpty()) {
|
||||
forceFields.array = forceFields.array.toMutableList().apply { removeAt(index.coerceIn(0, forceFields.array.lastIndex)) }.toTypedArray()
|
||||
val newIndex = index?.coerceIn(0, forceFields.array.lastIndex) ?: forceFields.array.lastIndex
|
||||
forceFields.array = forceFields.array.toMutableList().apply { removeAt(newIndex) }.toTypedArray()
|
||||
updateParam(id, access, forceFields)
|
||||
}
|
||||
else {
|
||||
@@ -817,7 +857,7 @@ fun forceFieldRemoveArg(context: CommandContext<ServerCommandSource>,
|
||||
return
|
||||
}
|
||||
|
||||
val calcIndex = if (index == -1) { forceFields.array.size } else { index.coerceIn(0, forceFields.array.size) }
|
||||
val calcIndex = index?.coerceIn(0, forceFields.array.size) ?: forceFields.array.size
|
||||
|
||||
successText(access, "--ForceField at $calcIndex", id, context)
|
||||
}
|
||||
@@ -828,18 +868,18 @@ fun lerpValIntArg(access: KProperty1<EmitterParams, ParamClasses.LerpValInt>,
|
||||
{
|
||||
return configArg
|
||||
.then(CommandManager.literal("LerpInt")
|
||||
.then(CommandManager.argument("Min", IntegerArgumentType.integer())
|
||||
.then(CommandManager.argument("Max", IntegerArgumentType.integer())
|
||||
.then(CommandManager.argument("From", IntegerArgumentType.integer())
|
||||
.then(CommandManager.argument("To", IntegerArgumentType.integer())
|
||||
.then(curveListArg("Curve")
|
||||
.executes { context ->
|
||||
val id = StringArgumentType.getString(context, "Emitter ID")
|
||||
val min = IntegerArgumentType.getInteger(context, "Min")
|
||||
val max = IntegerArgumentType.getInteger(context, "Max")
|
||||
val from = IntegerArgumentType.getInteger(context, "From")
|
||||
val to = IntegerArgumentType.getInteger(context, "To")
|
||||
val curveName = StringArgumentType.getString(context, "Curve")
|
||||
|
||||
val curve = stringToCurve(curveName)
|
||||
|
||||
updateParam(id, access, ParamClasses.LerpValInt.LerpInt(min, max, curve!!))
|
||||
updateParam(id, access, ParamClasses.LerpValInt.LerpInt(from, to, curve!!))
|
||||
|
||||
successText(access, "LerpInt", id, context)
|
||||
Command.SINGLE_SUCCESS
|
||||
|
||||
@@ -5,8 +5,12 @@ import com.bytedice.bde_particles.particles.idRegister
|
||||
import com.mojang.brigadier.Command
|
||||
import com.mojang.brigadier.CommandDispatcher
|
||||
import com.mojang.brigadier.arguments.StringArgumentType
|
||||
import com.mojang.brigadier.context.CommandContext
|
||||
import net.minecraft.command.CommandRegistryAccess
|
||||
import net.minecraft.command.argument.ItemStackArgumentType
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.Items
|
||||
import net.minecraft.server.command.CommandManager
|
||||
import net.minecraft.server.command.ServerCommandSource
|
||||
import net.minecraft.text.Style
|
||||
@@ -33,26 +37,42 @@ object GiveEmitterTool {
|
||||
CompletableFuture.completedFuture(builder.build())
|
||||
}
|
||||
|
||||
dispatcher.register(
|
||||
command
|
||||
.then(itemNameArg
|
||||
.then(itemTypeArg
|
||||
dispatcher.register(command
|
||||
.then(emitterIdSuggestion
|
||||
.then(itemTypeArg
|
||||
.then(itemNameArg
|
||||
.executes { context ->
|
||||
val name = StringArgumentType.getString(context, "Item Name")
|
||||
val item = ItemStackArgumentType.getItemStackArgument(context, "Item Type")
|
||||
val emitterId = StringArgumentType.getString(context, "Emitter ID")
|
||||
|
||||
val feedback = Text.literal("BPS - You like fancy particles. Don't you?\nBPS - gave particle emitter, bound to ID: \"${emitterId}\".")
|
||||
.setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(0, 200, 0).rgb)))
|
||||
exec(context, emitterId, item.item, name)
|
||||
Command.SINGLE_SUCCESS
|
||||
}
|
||||
)
|
||||
.executes { context ->
|
||||
val item = ItemStackArgumentType.getItemStackArgument(context, "Item Type")
|
||||
val emitterId = StringArgumentType.getString(context, "Emitter ID")
|
||||
|
||||
context.source.player?.inventory?.insertStack(ParticleEmitterTool.makeData(item.item, name, emitterId))
|
||||
context.source.sendFeedback({ feedback }, false)
|
||||
exec(context, emitterId, item.item, emitterId)
|
||||
Command.SINGLE_SUCCESS
|
||||
}
|
||||
)
|
||||
.executes { context ->
|
||||
val emitterId = StringArgumentType.getString(context, "Emitter ID")
|
||||
|
||||
exec(context, emitterId, Items.AMETHYST_SHARD, emitterId)
|
||||
Command.SINGLE_SUCCESS
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun exec(context: CommandContext<ServerCommandSource>, emitterId: String, itemType: Item, itemName: String) {
|
||||
val feedback = Text.literal("BPS - You like fancy particles. Don't you?\nBPS - gave particle emitter, bound to ID: \"${emitterId}\".")
|
||||
.setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(0, 200, 0).rgb)))
|
||||
|
||||
context.source.player?.inventory?.insertStack(ParticleEmitterTool.makeData(itemType, itemName, emitterId))
|
||||
context.source.sendFeedback({ feedback }, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,19 +122,18 @@ object ManageEmitters {
|
||||
}
|
||||
|
||||
private fun createExec(context: CommandContext<ServerCommandSource>, newEmitterId: String, presetEmitterId: String) {
|
||||
val params = getEmitterDataById(presetEmitterId)?.copy()
|
||||
val params = getEmitterDataById(presetEmitterId)
|
||||
val usedDefault = params == null
|
||||
|
||||
println(params?.modelCurve?.array?.size)
|
||||
|
||||
val result = addToRegister(
|
||||
newEmitterId,
|
||||
params ?: EmitterParams.DEFAULT,
|
||||
(params ?: EmitterParams.DEFAULT).deepCopy(),
|
||||
)
|
||||
|
||||
if (usedDefault && result.second) {
|
||||
positiveFeedback(
|
||||
"Successfully added new Emitter with ID \"${result.first}\" to register.\n(DEFAULT params were used as a preset because the specified Preset Emitter ID wasn't valid.)",
|
||||
"Successfully added new Emitter with ID \"${result.first}\" to register.\n" +
|
||||
"(DEFAULT preset was used because the specified Preset Emitter ID wasn't valid.)",
|
||||
context
|
||||
)
|
||||
}
|
||||
@@ -146,7 +145,8 @@ object ManageEmitters {
|
||||
}
|
||||
else {
|
||||
negativeFeedback(
|
||||
"Failed to add new Emitter with ID \"${result.first}\" to register.\nThe provided Emitter ID is either reserved for system use or already in use.",
|
||||
"Failed to add new Emitter with ID \"${result.first}\" to register.\n" +
|
||||
"The provided Emitter ID is either reserved for system use or already in use.",
|
||||
context
|
||||
)
|
||||
}
|
||||
|
||||
@@ -74,8 +74,8 @@ class EOrigin(rot: Vector2f, eOrigin: Vec3d) {
|
||||
|
||||
class ShapeDebug(eOrigin: Vec3d, spawnPosOffset: Vector3f, shape: SpawningShape) {
|
||||
val shapeScale: Vector3f? = when (shape) {
|
||||
is SpawningShape.Circle -> Vector3f(shape.radius * 1.75f * 2, shape.radius * 1.75f * 2, 0.0001f)
|
||||
is SpawningShape.Sphere -> Vector3f(shape.radius * 1.75f * 2, shape.radius * 1.75f * 2, 0.0001f)
|
||||
is SpawningShape.Circle -> Vector3f(shape.radius * 2 * 2, shape.radius * 2 * 2, 0.0001f)
|
||||
is SpawningShape.Sphere -> Vector3f(shape.radius * 2 * 2, shape.radius * 2 * 2, 0.0001f)
|
||||
is SpawningShape.Rect -> Vector3f(shape.size.x, 0.0001f, shape.size.y)
|
||||
is SpawningShape.Cube -> Vector3f(shape.size.x, shape.size.y, shape.size.z)
|
||||
else -> null
|
||||
@@ -135,7 +135,7 @@ class ForceFieldDebug {
|
||||
var FFDEArray: Array<DisplayEntity> = emptyArray()
|
||||
|
||||
fun makeArray(eOrigin: Vec3d, forceFieldArray: ParamClasses.ForceFieldArray, spawnPosOffset: Vector3f) {
|
||||
forceFieldArray.array.forEach {
|
||||
forceFieldArray.array.forEachIndexed { index, it ->
|
||||
val shapeScale = when (it.shape) {
|
||||
is ForceFieldShape.Sphere -> Vector3f(1.333f * it.shape.radius * 2, 1.333f * it.shape.radius * 2, 0.0001f)
|
||||
is ForceFieldShape.Cube -> it.shape.size
|
||||
@@ -143,11 +143,11 @@ class ForceFieldDebug {
|
||||
|
||||
val newOffset = Vector3f(spawnPosOffset).add(it.pos)
|
||||
|
||||
val displayEntity = DisplayEntity(
|
||||
DisplayEntityProperties(
|
||||
val displayEntity = DisplayEntity(DisplayEntityProperties(
|
||||
pos = eOrigin.add(newOffset.x.toDouble(), newOffset.y.toDouble(), newOffset.z.toDouble()),
|
||||
model = if (it.shape is ForceFieldShape.Sphere) { "minecraft:snowball" } else { "minecraft:white_stained_glass" },
|
||||
tags = arrayOf("DEBUG", "E_DEBUG", "eOrigin_DEBUG", "BPS_UUID", SESSION_UUID.toString()),
|
||||
customName = "forceField index: $index",
|
||||
brightnessOverride = 15,
|
||||
billboard = if (it.shape is ForceFieldShape.Sphere) { Billboard.CENTER } else { Billboard.FIXED },
|
||||
scale = shapeScale
|
||||
|
||||
@@ -34,6 +34,16 @@ data class EmitterParams (
|
||||
var brightnessCurve: ParamClasses.LerpValInt,
|
||||
)
|
||||
{
|
||||
fun deepCopy() : EmitterParams {
|
||||
val cModelCurveArray = this.modelCurve.deepCopy()
|
||||
val cForceFieldArray = this.forceFields.deepCopy()
|
||||
val cParams = this.copy()
|
||||
|
||||
cParams.modelCurve = cModelCurveArray
|
||||
cParams.forceFields = cForceFieldArray
|
||||
return cParams
|
||||
}
|
||||
|
||||
companion object Presets {
|
||||
val DEFAULT = EmitterParams(
|
||||
maxCount = 200,
|
||||
@@ -49,7 +59,7 @@ data class EmitterParams (
|
||||
initVel = ParamClasses.PairVec3f.Null,
|
||||
initCenterVel = ParamClasses.PairFloat(0.4f, 0.5f),
|
||||
initScale = ParamClasses.PairVec3f.Uniform(0.5f, 1.5f),
|
||||
transformWithVel = ParamClasses.TransformWithVel.None,
|
||||
transformWithVel = ParamClasses.TransformWithVel.Null,
|
||||
forceFields = ParamClasses.ForceFieldArray(emptyArray()),
|
||||
constVel = Vector3f(0.0f, 0.0f, 0.0f),
|
||||
drag = 0.075f,
|
||||
@@ -68,7 +78,7 @@ data class EmitterParams (
|
||||
),
|
||||
LerpCurves.Sqrt
|
||||
),
|
||||
brightnessCurve = ParamClasses.LerpValInt.LerpInt(15, 0, LerpCurves.Sqrt)
|
||||
brightnessCurve = ParamClasses.LerpValInt.LerpInt(15, 5, LerpCurves.Sqrt)
|
||||
)
|
||||
val DEBUG = EmitterParams(
|
||||
maxCount = 50,
|
||||
@@ -103,7 +113,7 @@ data class EmitterParams (
|
||||
),
|
||||
LerpCurves.Linear
|
||||
),
|
||||
brightnessCurve = ParamClasses.LerpValInt.Null
|
||||
brightnessCurve = ParamClasses.LerpValInt.LerpInt(15, 5, LerpCurves.Sqrt)
|
||||
)
|
||||
val STRESS_TEST = EmitterParams(
|
||||
maxCount = 10000,
|
||||
@@ -119,7 +129,7 @@ data class EmitterParams (
|
||||
initVel = ParamClasses.PairVec3f.NonUniform(0.0f, 4.0f, 0.0f, 0.0f, 8.0f, 0.0f),
|
||||
initCenterVel = ParamClasses.PairFloat(-1.5f, -1.5f),
|
||||
initScale = ParamClasses.PairVec3f.Uniform(10.0f, 15.0f),
|
||||
transformWithVel = ParamClasses.TransformWithVel.None,
|
||||
transformWithVel = ParamClasses.TransformWithVel.Null,
|
||||
forceFields = ParamClasses.ForceFieldArray(
|
||||
arrayOf(ForceField(
|
||||
Vector3f(0.0f, 75.0f, 0.0f),
|
||||
|
||||
@@ -5,4 +5,11 @@ import org.joml.Vector3f
|
||||
data class ForceField (
|
||||
val pos: Vector3f,
|
||||
val shape: ForceFieldShape
|
||||
)
|
||||
) {
|
||||
fun deepCopy(): ForceField {
|
||||
return ForceField(
|
||||
Vector3f(pos),
|
||||
shape.deepCopy()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -36,29 +36,22 @@ class ParamClasses {
|
||||
)
|
||||
}
|
||||
}
|
||||
data class Constant(val value: Vector3f) : PairVec3f()
|
||||
data object Null : PairVec3f()
|
||||
}
|
||||
|
||||
class PairInt (
|
||||
private val min: Int,
|
||||
private val max: Int,
|
||||
val min: Int,
|
||||
val max: Int,
|
||||
) {
|
||||
fun randomize() : Int {
|
||||
return if (min == max) { max }
|
||||
else if (min > max) { max }
|
||||
else { randomIntBetween(min, max) }
|
||||
}
|
||||
fun randomize() : Int { return randomIntBetween(min, max) }
|
||||
}
|
||||
|
||||
class PairFloat(
|
||||
private val min: Float,
|
||||
private val max: Float,
|
||||
val min: Float,
|
||||
val max: Float,
|
||||
) {
|
||||
fun randomize() : Float {
|
||||
return if (min == max) { max }
|
||||
else if (min > max) { max }
|
||||
else { randomFloatBetween(min, max) }
|
||||
}
|
||||
fun randomize() : Float { return randomFloatBetween(min, max) }
|
||||
}
|
||||
|
||||
sealed class LerpValVec3f {
|
||||
@@ -191,7 +184,7 @@ class ParamClasses {
|
||||
return Vector3f(contractFactor, contractFactor, stretchFactor)
|
||||
}
|
||||
}
|
||||
data object None : TransformWithVel()
|
||||
data object Null : TransformWithVel()
|
||||
}
|
||||
|
||||
class StringCurve (
|
||||
@@ -199,9 +192,17 @@ class ParamClasses {
|
||||
var curve: LerpCurves
|
||||
) {
|
||||
fun lerp(t: Float) : String { return lerpArray(array as Array<Any>, t, curve) as String }
|
||||
|
||||
fun deepCopy(): StringCurve {
|
||||
return StringCurve(array.copyOf(), curve.deepCopy())
|
||||
}
|
||||
}
|
||||
|
||||
data class ForceFieldArray (
|
||||
var array: Array<ForceField>
|
||||
)
|
||||
) {
|
||||
fun deepCopy(): ForceFieldArray {
|
||||
return ForceFieldArray(array.map { it.deepCopy() }.toTypedArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,31 +25,36 @@ class Particle(
|
||||
private val originOffset = when (val offset = emitterParams.offset) {
|
||||
is ParamClasses.PairVec3f.Uniform -> offset.randomize()
|
||||
is ParamClasses.PairVec3f.NonUniform -> offset.randomize()
|
||||
ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
|
||||
is ParamClasses.PairVec3f.Constant -> offset.value
|
||||
is ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
|
||||
}
|
||||
|
||||
private var rot = when (val initRot = emitterParams.initRot) {
|
||||
is ParamClasses.PairVec3f.Uniform -> initRot.randomize()
|
||||
is ParamClasses.PairVec3f.NonUniform -> initRot.randomize()
|
||||
ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
|
||||
is ParamClasses.PairVec3f.Constant -> initRot.value
|
||||
is ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
|
||||
}
|
||||
|
||||
private var rotVel = when (val initRotVel = emitterParams.rotVel) {
|
||||
is ParamClasses.PairVec3f.Uniform -> initRotVel.randomize()
|
||||
is ParamClasses.PairVec3f.NonUniform -> initRotVel.randomize()
|
||||
ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
|
||||
is ParamClasses.PairVec3f.Constant -> initRotVel.value
|
||||
is ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
|
||||
}
|
||||
|
||||
private var vel = when (val initVel = emitterParams.initVel) {
|
||||
is ParamClasses.PairVec3f.Uniform -> initVel.randomize()
|
||||
is ParamClasses.PairVec3f.NonUniform -> initVel.randomize()
|
||||
ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
|
||||
is ParamClasses.PairVec3f.Constant -> initVel.value
|
||||
is ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
|
||||
}
|
||||
|
||||
private var scale = when (val initScale = emitterParams.initScale) {
|
||||
is ParamClasses.PairVec3f.Uniform -> initScale.randomize()
|
||||
is ParamClasses.PairVec3f.NonUniform -> initScale.randomize()
|
||||
ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
|
||||
is ParamClasses.PairVec3f.Constant -> initScale.value
|
||||
is ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
|
||||
}
|
||||
|
||||
private var lifeTime = emitterParams.lifeTime.randomize()
|
||||
@@ -138,29 +143,32 @@ class Particle(
|
||||
val newOriginOffset = Vector3f(originOffset.mul(emitterParams.offsetCurve.lerpToVector3f(timeAliveClamped)))
|
||||
val newBrightness = emitterParams.brightnessCurve.lerpToInt(timeAliveClamped)
|
||||
|
||||
val newScale: Vector3f
|
||||
val TWVScale: Vector3f
|
||||
//val TWVRot: Vector3f
|
||||
val newRot: Vector3f
|
||||
|
||||
when (emitterParams.transformWithVel) {
|
||||
is ParamClasses.TransformWithVel.RotOnly -> {
|
||||
newScale = calcScale(timeAliveClamped)
|
||||
TWVScale = Vector3f(1.0f, 1.0f, 1.0f)
|
||||
newRot = (emitterParams.transformWithVel as ParamClasses.TransformWithVel.RotOnly).velToRot(vel)
|
||||
}
|
||||
is ParamClasses.TransformWithVel.ScaleAndRot -> {
|
||||
newScale = Vector3f(scale).mul((emitterParams.transformWithVel as ParamClasses.TransformWithVel.ScaleAndRot).velToScale(vel))
|
||||
TWVScale = (emitterParams.transformWithVel as ParamClasses.TransformWithVel.ScaleAndRot).velToScale(vel)
|
||||
newRot = (emitterParams.transformWithVel as ParamClasses.TransformWithVel.ScaleAndRot).velToRot(vel)
|
||||
}
|
||||
else -> {
|
||||
newScale = calcScale(timeAliveClamped)
|
||||
TWVScale = Vector3f(1.0f, 1.0f, 1.0f)
|
||||
newRot = calcRot(timeAliveClamped)
|
||||
}
|
||||
}
|
||||
|
||||
val newScale = TWVScale.mul(calcScale(timeAliveClamped))
|
||||
//val newRot = TWVRot.add(calcRot(timeAliveClamped))
|
||||
rot = newRot
|
||||
}
|
||||
}
|
||||
|
||||
vel = newVel
|
||||
pos = newPos
|
||||
|
||||
|
||||
for (forceField in emitterParams.forceFields.array) {
|
||||
if (forceField.shape is ForceFieldShape.Sphere) { vel.add(sphereSdfVel(forceField)) }
|
||||
else if (forceField.shape is ForceFieldShape.Cube) { vel.add(cubeSdfVel(forceField)) }
|
||||
@@ -206,7 +214,7 @@ class Particle(
|
||||
val shape = forceField.shape
|
||||
|
||||
val sdfVal = sdfCube(forceField.pos, shape.size, pos)
|
||||
val velDir = if (sdfVal < 0) { shape.dir.mul(shape.force) }
|
||||
val velDir = if (sdfVal < 0) { shape.force }
|
||||
else { Vector3f(0.0f, 0.0f, 0.0f) }
|
||||
|
||||
return velDir
|
||||
|
||||
@@ -11,10 +11,10 @@ import net.minecraft.util.math.Vec3d
|
||||
import org.joml.Vector2f
|
||||
|
||||
class ParticleEmitter(
|
||||
private var pos: Vec3d,
|
||||
private var rot: Vector2f,
|
||||
private val world: ServerWorld,
|
||||
private val params: EmitterParams,
|
||||
var pos: Vec3d,
|
||||
var rot: Vector2f,
|
||||
val world: ServerWorld,
|
||||
val params: EmitterParams,
|
||||
private val debug: Boolean = false
|
||||
) {
|
||||
private var allParticles: Array<Particle> = emptyArray()
|
||||
|
||||
@@ -33,7 +33,7 @@ fun addToRegister(id: String, params: EmitterParams) : Pair<String, Boolean> {
|
||||
|
||||
params.modelCurve.array = newModels.toTypedArray()
|
||||
|
||||
idRegister[id] = params
|
||||
idRegister[newId] = params
|
||||
println("BPS - Registered Emitter ID \"$newId\".")
|
||||
return Pair(newId, true)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.joml.Vector3f
|
||||
import kotlin.math.*
|
||||
import kotlin.random.Random
|
||||
|
||||
sealed class SpawningShape() {
|
||||
sealed class SpawningShape {
|
||||
class Circle(val radius: Float, val spawnOnEdge: Boolean) : SpawningShape() {
|
||||
fun randomWithin(): Vector3f {
|
||||
val randRadius = radius * sqrt(randomFloatBetween(0.0f, 1.0f))
|
||||
@@ -121,9 +121,16 @@ sealed class ForceFieldShape {
|
||||
val radius: Float,
|
||||
val force: Pair<Float, Float>,
|
||||
) : ForceFieldShape()
|
||||
|
||||
data class Cube(
|
||||
val size: Vector3f,
|
||||
val dir: Vector3f,
|
||||
val force: Float
|
||||
val force: Vector3f
|
||||
) : ForceFieldShape()
|
||||
|
||||
fun deepCopy() : ForceFieldShape {
|
||||
return when (this) {
|
||||
is Sphere -> Sphere(this.radius, this.force)
|
||||
is Cube -> Cube(Vector3f(this.size), Vector3f(this.force))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user