mirror of
				https://github.com/coop-deluxe/sm64coopdx.git
				synced 2025-10-30 08:01:01 +00:00 
			
		
		
		
	New default mod: Visible Lakitu (#332)
* patch for beta 32 * bump version * add Visible Lakitu to default mods
This commit is contained in:
		
							parent
							
								
									b7879c1d5a
								
							
						
					
					
						commit
						79c4e6610b
					
				
					 1 changed files with 129 additions and 0 deletions
				
			
		
							
								
								
									
										129
									
								
								mods/lakituCam.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								mods/lakituCam.lua
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,129 @@
 | 
			
		|||
-- name: Visible Lakitu
 | 
			
		||||
-- description: You can now see everyone's Lakitu camera like in the Mirror room.\n\nYou may use this code for your own mods.\n\nBy Isaac
 | 
			
		||||
 | 
			
		||||
-- define our variables to hold the global id of each Lakitu's owner, and its blink timer
 | 
			
		||||
define_custom_obj_fields({ oLakituOwner = 'u32', oLakituBlinkTimer = 's32' })
 | 
			
		||||
 | 
			
		||||
-- for some reason Lua doesn't treat booleans as 1/0 numbers
 | 
			
		||||
local boolToNumber = { [true] = 1, [false] = 0 }
 | 
			
		||||
 | 
			
		||||
local function obj_update_blinking(o, timer, base, range, length)
 | 
			
		||||
    -- update our timer
 | 
			
		||||
    if timer > 0 then timer = timer - 1
 | 
			
		||||
    else timer = base + (range * math.random()) end
 | 
			
		||||
 | 
			
		||||
    -- set Lakitu's blink state depending on what our timer is at
 | 
			
		||||
    o.oAnimState = boolToNumber[(timer <= length)]
 | 
			
		||||
    return timer
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function is_current_area_sync_valid()
 | 
			
		||||
    -- check all connected players to see if their area sync is valid
 | 
			
		||||
    for i = 0, (MAX_PLAYERS - 1) do
 | 
			
		||||
        local np = gNetworkPlayers[i]
 | 
			
		||||
        if np ~= nil and np.connected and (not np.currLevelSyncValid or not np.currAreaSyncValid) then
 | 
			
		||||
            return false
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    return true
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function active_player(m, np)
 | 
			
		||||
    -- check if this player is connected and in the same level
 | 
			
		||||
    if not np.connected or np.currCourseNum ~= gNetworkPlayers[0].currCourseNum or np.currActNum ~= gNetworkPlayers[0].currActNum or np.currLevelNum ~= gNetworkPlayers[0].currLevelNum or
 | 
			
		||||
        np.currAreaIndex ~= gNetworkPlayers[0].currAreaIndex then
 | 
			
		||||
        return false
 | 
			
		||||
    end
 | 
			
		||||
    return is_player_active(m)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function obj_mark_for_deletion_on_sync(o)
 | 
			
		||||
    -- delete this Lakitu if the area's sync status is valid
 | 
			
		||||
    if gNetworkPlayers[0].currAreaSyncValid then obj_mark_for_deletion(o) end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function bhv_custom_lakitu_init(o)
 | 
			
		||||
    -- set up Lakitu's flags
 | 
			
		||||
    o.oFlags = (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)
 | 
			
		||||
    -- use the default Lakitu animations
 | 
			
		||||
    o.oAnimations = gObjectAnimations.lakitu_seg6_anims_060058F8
 | 
			
		||||
    cur_obj_init_animation(0)
 | 
			
		||||
 | 
			
		||||
    -- spawn Lakitu's cloud if this isn't the local player's Lakitu
 | 
			
		||||
    if network_local_index_from_global(o.oLakituOwner) ~= 0 then
 | 
			
		||||
        spawn_non_sync_object(id_bhvCloud, E_MODEL_MIST, o.oPosX, o.oPosY, o.oPosZ,
 | 
			
		||||
            function(obj)
 | 
			
		||||
                -- make the cloud a child of Lakitu
 | 
			
		||||
                obj.parentObj = o
 | 
			
		||||
                -- sm64 knows this is a Lakitu cloud if oBehParams2ndByte is set to 1
 | 
			
		||||
                -- if oBehParams2ndByte is 0, the cloud will behave as a Fwoosh
 | 
			
		||||
                obj.oBehParams2ndByte = 1
 | 
			
		||||
                -- make the cloud twice the size size of a normal cloud (all Lakitu clouds do this)
 | 
			
		||||
                obj_scale(obj, 2)
 | 
			
		||||
            end)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    -- init the networked Lakitu
 | 
			
		||||
    network_init_object(o, true, { "oLakituOwner", "oFaceAngleYaw", "oFaceAnglePitch" })
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function bhv_custom_lakitu(o)
 | 
			
		||||
    -- get the gNetworkPlayers table for the player that owns this Lakitu
 | 
			
		||||
    local np = network_player_from_global_index(o.oLakituOwner)
 | 
			
		||||
    -- this isn't a valid network player, delete this Lakitu
 | 
			
		||||
    if np == nil then
 | 
			
		||||
        obj_mark_for_deletion_on_sync(o)
 | 
			
		||||
        return
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    -- get the mario state of the player that owns this Lakitu
 | 
			
		||||
    local m = gMarioStates[np.localIndex]
 | 
			
		||||
 | 
			
		||||
    -- don't update this Lakitu if it isn't our Lakitu
 | 
			
		||||
    if m.playerIndex ~= 0 then
 | 
			
		||||
        -- delete this Lakitu if it's owner isn't active
 | 
			
		||||
        if not active_player(m, np) then
 | 
			
		||||
            obj_mark_for_deletion_on_sync(o)
 | 
			
		||||
            return
 | 
			
		||||
        end
 | 
			
		||||
        -- show the Lakitu for other players
 | 
			
		||||
        cur_obj_unhide()
 | 
			
		||||
 | 
			
		||||
        -- determine whether Lakitu should blink
 | 
			
		||||
        o.oLakituBlinkTimer = obj_update_blinking(o, o.oLakituBlinkTimer, 20, 40, 4)
 | 
			
		||||
        return
 | 
			
		||||
    else
 | 
			
		||||
        -- the local player cannot see it's own Lakitu
 | 
			
		||||
        cur_obj_hide()
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    -- set the Lakitu position to the camera position of that player
 | 
			
		||||
    o.oPosX = gLakituState.curPos.x
 | 
			
		||||
    o.oPosY = gLakituState.curPos.y
 | 
			
		||||
    o.oPosZ = gLakituState.curPos.z
 | 
			
		||||
 | 
			
		||||
    -- look at Mario
 | 
			
		||||
    o.oHomeX = gLakituState.curFocus.x
 | 
			
		||||
    o.oHomeZ = gLakituState.curFocus.z
 | 
			
		||||
 | 
			
		||||
    o.oFaceAngleYaw = cur_obj_angle_to_home()
 | 
			
		||||
    o.oFaceAnglePitch = atan2s(cur_obj_lateral_dist_to_home(), o.oPosY - gLakituState.curFocus.y)
 | 
			
		||||
 | 
			
		||||
    -- send the current state of our Lakitu to other players if the area sync is valild
 | 
			
		||||
    if is_current_area_sync_valid() then
 | 
			
		||||
        network_send_object(o, false)
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local bhvPlayerLakitu = hook_behavior(nil, OBJ_LIST_DEFAULT, true, bhv_custom_lakitu_init, bhv_custom_lakitu)
 | 
			
		||||
 | 
			
		||||
-- spawn the local player's Lakitu when the area's sync state is valid (every time the player warps areas)
 | 
			
		||||
local function update_lakitu()
 | 
			
		||||
    -- spawn Lakitu with our custom Lakitu behavior and the default Lakitu model; and mark it as a sync object
 | 
			
		||||
    spawn_sync_object(bhvPlayerLakitu, E_MODEL_LAKITU, 0, 0, 0, function(o)
 | 
			
		||||
        -- save the global id of the player that owns this Lakitu
 | 
			
		||||
        o.oLakituOwner = gNetworkPlayers[0].globalIndex
 | 
			
		||||
    end)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
hook_event(HOOK_ON_SYNC_VALID, update_lakitu)
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue