sm64coopdx/mods/arena/arena-proj-flame.lua

170 lines
4.6 KiB
Lua

define_custom_obj_fields({
oArenaFlameGlobalOwner = 'u32',
})
local sArenaChildFlameLife = 30 * 1.8
function bhv_arena_child_flame_init(obj)
obj.oFlags = OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE
if global_index_hurts_mario_state(obj.oArenaFlameGlobalOwner, gMarioStates[0]) then
obj.oInteractType = INTERACT_FLAME
else
obj.oInteractType = 0
end
obj.oGraphYOffset = 30
obj.hitboxRadius = 30
obj.hitboxHeight = 30
obj.hitboxDownOffset = 0
obj.hurtboxRadius = 30
obj.hurtboxHeight = 30
obj.oWallHitboxRadius = 50
obj.oGravity = -400 / 100
obj.oBounciness = -80 / 100
obj.oDragStrength = 300 / 100
obj.oFriction = 300 / 100
obj.oBuoyancy = 200 / 100
obj_scale(obj, 3)
obj_set_billboard(obj)
-- override blue flame
local np = network_player_from_global_index(obj.oArenaFlameGlobalOwner)
if np ~= nil then
local s = gPlayerSyncTable[np.localIndex]
if s.team == 2 then
obj_set_model_extended(obj, E_MODEL_BLUE_FLAME)
end
end
end
function bhv_arena_child_flame_loop(obj)
obj.activeFlags = obj.activeFlags | ACTIVE_FLAG_UNK10
local lifeRemain = (sArenaChildFlameLife - obj.oTimer) / sArenaChildFlameLife
local size = 3 * (1 - (1 - lifeRemain) ^ 3)
obj_scale(obj, size)
if size < 0.5 then
obj.oInteractType = 0
end
if lifeRemain <= 0 then
obj_mark_for_deletion(obj)
end
obj.oInteractStatus = 0
obj.oIntangibleTimer = 0
obj.oAnimState = obj.oAnimState + 1
end
id_bhvArenaChildFlame = hook_behavior(nil, OBJ_LIST_GENACTOR, true, bhv_arena_child_flame_init, bhv_arena_child_flame_loop)
----------------------
local sArenaFlameLife = 30 * 5
function bhv_arena_flame_init(obj)
obj.oFlags = OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE
if global_index_hurts_mario_state(obj.oArenaFlameGlobalOwner, gMarioStates[0]) then
obj.oInteractType = INTERACT_FLAME
else
obj.oInteractType = 0
end
obj.oGraphYOffset = 30
obj.hitboxRadius = 100
obj.hitboxHeight = 50
obj.hitboxDownOffset = 25
obj.hurtboxRadius = 100
obj.hurtboxHeight = 50
obj.oWallHitboxRadius = 100
obj.oGravity = -400 / 100
obj.oBounciness = -80 / 100
obj.oDragStrength = 120 / 100
obj.oFriction = 120 / 100
obj.oBuoyancy = 200 / 100
obj_scale(obj, 3)
obj_set_billboard(obj)
cur_obj_play_sound_2(SOUND_OBJ_FLAME_BLOWN)
-- override blue flame
local np = network_player_from_global_index(obj.oArenaFlameGlobalOwner)
if np ~= nil then
local s = gPlayerSyncTable[np.localIndex]
if s.team == 2 then
obj_set_model_extended(obj, E_MODEL_BLUE_FLAME)
end
end
network_init_object(obj, false, nil)
end
function bhv_arena_flame_loop(obj)
obj.activeFlags = obj.activeFlags | ACTIVE_FLAG_UNK10
cur_obj_update_floor_and_walls();
local lifeRemain = (sArenaFlameLife - obj.oTimer) / sArenaFlameLife
local size = 5 * (1 - (1 - lifeRemain) ^ 3)
obj_scale(obj, size)
if size < 1.5 then
obj.oInteractType = 0
end
if lifeRemain <= 0 then
obj_mark_for_deletion(obj)
end
-- spawn child flame
if (obj.oTimer % 2) == 0 then
spawn_non_sync_object(id_bhvArenaChildFlame, E_MODEL_RED_FLAME, obj.oPosX, obj.oPosY, obj.oPosZ,
function(obj2)
obj2.oArenaFlameGlobalOwner = obj.oArenaFlameGlobalOwner
end)
end
-- find nearest target
local pos = { x = obj.oPosX, y = obj.oPosY, z = obj.oPosZ }
local target = nil
local targetDist = 2500
for i = 0, (MAX_PLAYERS - 1) do
local m = gMarioStates[i]
if global_index_hurts_mario_state(obj.oArenaFlameGlobalOwner, m) and active_player(m) then
local dist = vec3f_dist(pos, m.pos)
if dist < targetDist then
target = m
targetDist = dist
end
end
end
if target ~= nil then
-- aim toward target
local targetYaw = atan2s(target.pos.z - pos.z, target.pos.x - pos.x)
obj.oMoveAngleYaw = approach_s16_symmetric(obj.oMoveAngleYaw, targetYaw, 0x110)
-- jump
local floorDiff = obj.oFloorHeight - obj.oPosY
if math.abs(floorDiff) < 5 and math.abs(obj.oVelY) < 5 and obj.oPosY < target.pos.y then
obj.oVelY = 50
end
end
cur_obj_move_standard(200)
obj.oInteractStatus = 0
obj.oIntangibleTimer = 0
obj.oAnimState = obj.oAnimState + 1
end
id_bhvArenaFlame = hook_behavior(nil, OBJ_LIST_GENACTOR, true, bhv_arena_flame_init, bhv_arena_flame_loop)
------------------