sm64coopdx/mods/shell-rush/level.lua
2022-03-30 20:15:17 -07:00

155 lines
4.3 KiB
Lua

gRaceShells = {}
gLevelData = gLevelDataTable[-1]
function erase_unwanted_entities(objList)
local obj = obj_get_first(objList)
while obj ~= nil do
local behaviorId = get_id_from_behavior(obj.behavior)
if gLevelData.erase[behaviorId] ~= nil then
obj.activeFlags = ACTIVE_FLAG_DEACTIVATED
end
-- iterate
obj = obj_get_next(obj)
end
end
function on_level_init()
-- set level data
local level = gNetworkPlayers[0].currLevelNum
if gLevelDataTable[level] ~= nil then
gLevelData = gLevelDataTable[level]
else
gLevelData = gLevelDataTable[-1]
end
-- spawn all of the racing shells
for i = 0, (MAX_PLAYERS - 1) do
gRaceShells[i] = spawn_non_sync_object(
id_bhvRaceShell,
E_MODEL_KOOPA_SHELL,
0, 0, 0,
function (obj) obj.heldByPlayerIndex = i end
)
end
-- spawn all of the waypoints
for i in pairs(gLevelData.waypoints) do
local waypoint = get_waypoint(i)
spawn_non_sync_object(
id_bhvRaceRing,
E_MODEL_WATER_RING,
waypoint.x, waypoint.y, waypoint.z,
function (obj) obj.oWaypointIndex = i end
)
end
-- spawn level-specific platforms
for i in pairs(gLevelData.platforms) do
local p = gLevelData.platforms[i]
spawn_non_sync_object(
id_bhvStaticCheckeredPlatform,
E_MODEL_CHECKERBOARD_PLATFORM,
p.pos.x, p.pos.y, p.pos.z,
function (obj)
obj.oOpacity = 255
obj.oFaceAnglePitch = p.rot.x
obj.oFaceAngleYaw = p.rot.y
obj.oFaceAngleRoll = p.rot.z
obj_scale_xyz(obj, p.scale.x, p.scale.y, p.scale.z)
end)
end
-- reset the local player's data
local s = gPlayerSyncTable[0]
s.waypoint = 1
s.lap = 0
s.finish = 0
for i = 0, 2 do
s.powerup[i] = POWERUP_NONE
end
-- reset the custom level objects
for i in pairs(gLevelData.powerups) do
gLevelData.powerups[i].obj = nil
end
for i = 0, (MAX_PLAYERS - 1) do
for j = 0, 2 do
gPowerups[i][j] = nil
end
end
-- erase specified level entities
erase_unwanted_entities(OBJ_LIST_GENACTOR)
erase_unwanted_entities(OBJ_LIST_LEVEL)
erase_unwanted_entities(OBJ_LIST_SURFACE)
-- reset rankings
race_clear_rankings()
end
function spawn_custom_level_objects()
-- only handle powerups if we're the server
if not network_is_server() then
return
end
-- look for existing powerups
local obj = obj_get_first(OBJ_LIST_LEVEL)
while obj ~= nil do
local behaviorId = get_id_from_behavior(obj.behavior)
if behaviorId == id_bhvItemBox then
-- find closest position to put it in
local objPos = { x = obj.oPosX, y = obj.oPosY, z = obj.oPosZ }
for i in pairs(gLevelData.powerups) do
local powPos = gLevelData.powerups[i].pos
local tempPos = { x = powPos.x, y = objPos.y, z = powPos.z }
local dist = vec3f_dist(objPos, tempPos)
if dist < 5 then
gLevelData.powerups[i].obj = obj
end
end
end
-- iterate
obj = obj_get_next(obj)
end
-- spawn missing powerups
for i in pairs(gLevelData.powerups) do
if gLevelData.powerups[i].obj == nil then
local pos = gLevelData.powerups[i].pos
gLevelData.powerups[i].obj = spawn_sync_object(
id_bhvItemBox,
E_MODEL_ITEM_BOX,
pos.x, pos.y, pos.z,
function (obj)
--obj.oMoveAngleYaw = m.faceAngle.y
end
)
end
end
end
function on_object_unload(obj)
-- react to powerups getting unloaded
for i = 0, (MAX_PLAYERS - 1) do
for j = 0, 2 do
if obj == gPowerups[i][j] then
gPowerups[i][j] = nil
end
end
end
-- react to level objects getting unloaded
for i in pairs(gLevelData.powerups) do
if gLevelData.powerups[i].obj == obj then
gLevelData.powerups[i].obj = nil
end
end
end
hook_event(HOOK_ON_LEVEL_INIT, on_level_init)
hook_event(HOOK_ON_OBJECT_UNLOAD, on_object_unload)