ready for 1.0! Idc that it may be buggy, I want 1.0 now!

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