Added the ability to spawn particles from Lua

Added particles to football
Increased the object cap for particles
This commit is contained in:
MysterD 2022-03-09 18:59:55 -08:00
parent f59513f3ae
commit 1b99e22848
14 changed files with 131 additions and 13 deletions

0
autogen/autogen.sh Normal file → Executable file
View file

View file

@ -68,6 +68,7 @@ override_field_immutable = {
"TextureInfo": [ "*" ],
"Object": ["oSyncID", "createdThroughNetwork"],
"GlobalObjectAnimations": [ "*"],
"SpawnParticlesInfo": [ "model" ],
}
sLuaManuallyDefinedStructs = [

View file

@ -81,11 +81,12 @@ function vec3f_mul(dest, a)
end
function vec3f_normalize(dest)
local invsqrt = 1.0 / math.sqrt(dest.x * dest.x + dest.y * dest.y + dest.z * dest.z)
if invsqrt == 0 then
local divisor = math.sqrt(dest.x * dest.x + dest.y * dest.y + dest.z * dest.z)
if divisor == 0 then
return dest
end
local invsqrt = 1.0 / divisor
dest.x = dest.x * invsqrt
dest.y = dest.y * invsqrt
dest.z = dest.z * invsqrt

View file

@ -631,6 +631,7 @@
- [obj_get_next_with_same_behavior_id](#obj_get_next_with_same_behavior_id)
- [obj_get_next_with_same_behavior_id_and_field_f32](#obj_get_next_with_same_behavior_id_and_field_f32)
- [obj_get_next_with_same_behavior_id_and_field_s32](#obj_get_next_with_same_behavior_id_and_field_s32)
- [obj_get_temp_spawn_particles_info](#obj_get_temp_spawn_particles_info)
- [obj_has_behavior_id](#obj_has_behavior_id)
- [obj_has_model_extended](#obj_has_model_extended)
- [obj_set_model_extended](#obj_set_model_extended)
@ -11595,6 +11596,26 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
<br />
## [obj_get_temp_spawn_particles_info](#obj_get_temp_spawn_particles_info)
### Lua Example
`local SpawnParticlesInfoValue = obj_get_temp_spawn_particles_info(modelId)`
### Parameters
| Field | Type |
| ----- | ---- |
| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) |
### Returns
[SpawnParticlesInfo](structs.md#SpawnParticlesInfo)
### C Prototype
`struct SpawnParticlesInfo* obj_get_temp_spawn_particles_info(enum ModelExtendedId modelId);`
[:arrow_up_small:](#)
<br />
## [obj_has_behavior_id](#obj_has_behavior_id)
### Lua Example

View file

@ -1655,7 +1655,7 @@
| forwardVelBase | `integer` | |
| forwardVelRange | `integer` | |
| gravity | `integer` | |
| model | `integer` | |
| model | `integer` | read-only |
| offsetY | `integer` | |
| sizeBase | `number` | |
| sizeRange | `number` | |

View file

@ -163,6 +163,48 @@ define_custom_obj_fields({
oFrozen = 'u32',
})
function bhv_ball_particle_trail(obj)
local spi = obj_get_temp_spawn_particles_info(E_MODEL_SPARKLES)
if spi == nil then
return nil
end
spi.behParam = 2
spi.count = 1
spi.offsetY = -1 * ballRadius
spi.forwardVelBase = 8
spi.forwardVelRange = 0
spi.velYBase = 6
spi.velYRange = 0
spi.gravity = 0
spi.dragStrength = 5
spi.sizeBase = 10
spi.sizeRange = 30
cur_obj_spawn_particles(spi)
end
function bhv_ball_particle_bounce(obj)
local spi = obj_get_temp_spawn_particles_info(E_MODEL_MIST)
if spi == nil then
return nil
end
spi.behParam = 3
spi.count = 5
spi.offsetY = -1 * ballRadius
spi.forwardVelBase = 6
spi.forwardVelRange = -6
spi.velYBase = 6
spi.velYRange = -6
spi.gravity = 0
spi.dragStrength = 5
spi.sizeBase = 8
spi.sizeRange = 13
cur_obj_spawn_particles(spi)
end
function bhv_ball_init(obj)
-- flags and such
obj.oFlags = OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE
@ -245,7 +287,9 @@ function bhv_ball_player_collision(obj)
local vDifference = { x = objPoint.x - cylPoint.x, y = objPoint.y - cylPoint.y, z = objPoint.z - cylPoint.z }
local differenceDir = { x = vDifference.x, y = vDifference.y, z = vDifference.z }
vec3f_normalize(differenceDir)
if vec3f_length(differenceDir) ~= 0 then
vec3f_normalize(differenceDir)
end
alterPos.x = (cylPoint.x + differenceDir.x * (playerBallRadius + playerRadius + 1)) - objPoint.x
alterPos.y = (cylPoint.y + differenceDir.y * (playerBallRadius + playerRadius + 1)) - objPoint.y
@ -312,6 +356,11 @@ function bhv_ball_player_collision(obj)
end
end
-- make sure player has a velocity
if not doReflection and vPlayerMag == 0 then
doReflection = true
end
--------------------------------------
-- calculate velocity (interaction) --
--------------------------------------
@ -456,8 +505,10 @@ function bhv_ball_loop(obj)
-- detect normal along movement vector
local vMag = vec3f_length(v)
local vNorm = { x = v.x / vMag, y = v.y / vMag, z = v.z / vMag }
b = { x = v.x + vNorm.x * (vMag + ballRadius), y = v.y + vNorm.y * (vMag + ballRadius), z = v.z + vNorm.z * (vMag + ballRadius) }
if vMag > 0 then
local vNorm = { x = v.x / vMag, y = v.y / vMag, z = v.z / vMag }
b = { x = v.x + vNorm.x * (vMag + ballRadius), y = v.y + vNorm.y * (vMag + ballRadius), z = v.z + vNorm.z * (vMag + ballRadius) }
end
info = collision_find_surface_on_ray(
a.x, a.y, a.z,
@ -467,6 +518,7 @@ function bhv_ball_loop(obj)
local colNormals = {}
if info.surface ~= nil then
table.insert(colNormals, { x = info.surface.normal.x, y = info.surface.normal.y, z = info.surface.normal.z })
bhv_ball_particle_bounce(obj)
else
table.insert(colNormals, nil)
end
@ -573,6 +625,16 @@ function bhv_ball_loop(obj)
network_send_object(obj, false)
end
-- spawn a particle trail
if vMag > 50 then
bhv_ball_particle_trail(obj)
end
-- hack: make sure we never set velocity to nan
if obj.oVelX ~= obj.oVelX then obj.oVelX = 0 end
if obj.oVelY ~= obj.oVelY then obj.oVelY = 0 end
if obj.oVelZ ~= obj.oVelZ then obj.oVelZ = 0 end
-- hack: save pos/vel to detect packets
cb.oGlobalOwner = obj.oGlobalOwner
cb.oHitTime = obj.oHitTime

View file

@ -14,7 +14,7 @@ void bhv_tree_snow_or_leaf_loop(void) {
obj_mark_for_deletion(o);
if (o->oTimer > 100)
obj_mark_for_deletion(o);
if (gPrevFrameObjectCount > 212)
if (gPrevFrameObjectCount > (OBJECT_POOL_CAPACITY * 212 / 240))
obj_mark_for_deletion(o);
o->oFaceAnglePitch += o->oAngleVelPitch;
o->oFaceAngleRoll += o->oAngleVelRoll;

View file

@ -2238,13 +2238,14 @@ void cur_obj_spawn_particles(struct SpawnParticlesInfo *info) {
s32 numParticles = info->count;
// If there are a lot of objects already, limit the number of particles
if (gPrevFrameObjectCount > 150 && numParticles > 10) {
if (gPrevFrameObjectCount > (OBJECT_POOL_CAPACITY * 150 / 240) && numParticles > 10) {
numParticles = 10;
}
// We're close to running out of object slots, so don't spawn particles at
// all
if (gPrevFrameObjectCount > 210) {
if (gPrevFrameObjectCount > (OBJECT_POOL_CAPACITY * 210 / 240)) {
numParticles = 0;
}

View file

@ -1439,7 +1439,7 @@ static struct LuaObjectField sSpawnParticlesInfoFields[LUA_SPAWN_PARTICLES_INFO_
{ "forwardVelBase", LVT_S8, offsetof(struct SpawnParticlesInfo, forwardVelBase), false, LOT_NONE },
{ "forwardVelRange", LVT_S8, offsetof(struct SpawnParticlesInfo, forwardVelRange), false, LOT_NONE },
{ "gravity", LVT_S8, offsetof(struct SpawnParticlesInfo, gravity), false, LOT_NONE },
{ "model", LVT_U8, offsetof(struct SpawnParticlesInfo, model), false, LOT_NONE },
{ "model", LVT_U8, offsetof(struct SpawnParticlesInfo, model), true, LOT_NONE },
{ "offsetY", LVT_S8, offsetof(struct SpawnParticlesInfo, offsetY), false, LOT_NONE },
{ "sizeBase", LVT_F32, offsetof(struct SpawnParticlesInfo, sizeBase), false, LOT_NONE },
{ "sizeRange", LVT_F32, offsetof(struct SpawnParticlesInfo, sizeRange), false, LOT_NONE },

View file

@ -73,10 +73,11 @@ char gSmluaConstants[] = ""
" return dest\n"
"end\n"
"function vec3f_normalize(dest)\n"
" local invsqrt = 1.0 / math.sqrt(dest.x * dest.x + dest.y * dest.y + dest.z * dest.z)\n"
" if invsqrt == 0 then\n"
" local divisor = math.sqrt(dest.x * dest.x + dest.y * dest.y + dest.z * dest.z)\n"
" if divisor == 0 then\n"
" return dest\n"
" end\n"
" local invsqrt = 1.0 / divisor\n"
" dest.x = dest.x * invsqrt\n"
" dest.y = dest.y * invsqrt\n"
" dest.z = dest.z * invsqrt\n"

View file

@ -7397,6 +7397,17 @@ int smlua_func_obj_get_next_with_same_behavior_id_and_field_s32(lua_State* L) {
return 1;
}
int smlua_func_obj_get_temp_spawn_particles_info(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
int modelId = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { return 0; }
smlua_push_object(L, LOT_SPAWNPARTICLESINFO, obj_get_temp_spawn_particles_info(modelId));
return 1;
}
int smlua_func_obj_has_behavior_id(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 2)) { return 0; }
@ -8519,6 +8530,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "obj_get_next_with_same_behavior_id", smlua_func_obj_get_next_with_same_behavior_id);
smlua_bind_function(L, "obj_get_next_with_same_behavior_id_and_field_f32", smlua_func_obj_get_next_with_same_behavior_id_and_field_f32);
smlua_bind_function(L, "obj_get_next_with_same_behavior_id_and_field_s32", smlua_func_obj_get_next_with_same_behavior_id_and_field_s32);
smlua_bind_function(L, "obj_get_temp_spawn_particles_info", smlua_func_obj_get_temp_spawn_particles_info);
smlua_bind_function(L, "obj_has_behavior_id", smlua_func_obj_has_behavior_id);
smlua_bind_function(L, "obj_has_model_extended", smlua_func_obj_has_model_extended);
smlua_bind_function(L, "obj_set_model_extended", smlua_func_obj_set_model_extended);

View file

@ -190,3 +190,16 @@ struct Object *obj_get_next_with_same_behavior_id_and_field_f32(struct Object *o
}
return NULL;
}
struct SpawnParticlesInfo* obj_get_temp_spawn_particles_info(enum ModelExtendedId modelId) {
static struct SpawnParticlesInfo spi = { 0 };
u8 loadedModelId = smlua_model_util_load(modelId);
if (loadedModelId == 0xFF) {
LOG_ERROR("failed to load model %u", modelId);
return NULL;
}
spi.model = loadedModelId;
return &spi;
}

View file

@ -28,4 +28,8 @@ struct Object *obj_get_next_with_same_behavior_id(struct Object *o);
struct Object *obj_get_next_with_same_behavior_id_and_field_s32(struct Object *o, s32 fieldIndex, s32 value);
struct Object *obj_get_next_with_same_behavior_id_and_field_f32(struct Object *o, s32 fieldIndex, f32 value);
// misc obj helpers
struct SpawnParticlesInfo* obj_get_temp_spawn_particles_info(enum ModelExtendedId modelId);
#endif

View file

@ -5,8 +5,10 @@
static void on_current_user_update(UNUSED void* data) {
LOGFILE_INFO(LFT_DISCORD, "> on_current_user_update");
struct DiscordUser user;
struct DiscordUser user = { 0 };
app.users->get_current_user(app.users, &user);
// remember user id
app.userId = user.id;
gPcDebug.id = user.id;