sm64coopdx/mods/mquake/_mquake_d_actions.lua
2024-03-22 14:45:48 -04:00

517 lines
17 KiB
Lua

if SM64COOPDX_VERSION == nil then return end
local play_step_sound,set_mario_action,play_character_sound,vec3f_length,perform_ground_step,vec3f_copy,perform_air_step,clampf,vec3f_add,set_mario_particle_flags,play_mario_heavy_landing_sound = play_step_sound,set_mario_action,play_character_sound,vec3f_length,perform_ground_step,vec3f_copy,perform_air_step,clampf,vec3f_add,set_mario_particle_flags,play_mario_heavy_landing_sound
local function play_local_footstep_sounds(m,rate,max)
cl_footstepTimer = cl_footstepTimer + rate
if (cl_footstepTimer >= max) then
m.marioObj.header.gfx.animInfo.animFrame = 0
play_step_sound(m, 0, 1)
cl_footstepTimer = 0
end
end
-------------------------------
-- Code for our local player --
-------------------------------
--- @param m MarioState
local function local_act_dm_grounded_movement(m)
local valid_update = local_update(m)
local metal_underwater = (m.flags & MARIO_METAL_CAP) ~= 0 and m.pos.y <= m.waterLevel-sv_playersubmergelevel
local crouch = gPlayerSyncTable[m.playerIndex].playerCrouching
if (metal_underwater and m.action ~= ACT_DM_GROUNDED_MOVEMENT_METAL) then
SV_PlayerMovement_Store(m,true)
set_mario_action(m, ACT_DM_GROUNDED_MOVEMENT_METAL, 0)
m.action = ACT_DM_GROUNDED_MOVEMENT_METAL
SV_PlayerMovement_Store(m,false)
-- return
elseif (m.action == ACT_DM_GROUNDED_MOVEMENT_METAL and not metal_underwater) then
set_mario_action(m, ACT_DM_GROUNDED_MOVEMENT, 0)
m.action = ACT_DM_GROUNDED_MOVEMENT
-- return
end
if (m.floor ~= nil) then
if (m.floor.normal.y <= SV_GetSurfaceStandableMinimum(m.floor.type,m.area.terrainType)) then
SV_PlayerMovement_Relative(m)
set_mario_action(m, ACT_DM_AIR_MOVEMENT, 0)
act_dm_air_movement(m)
return
end
end
if (m.controller.buttonDown & A_BUTTON) ~= 0 and no_dialog_open() and m.floor ~= nil then
set_character_animation(m, CHAR_ANIM_IDLE_HEAD_CENTER)
-- m.controller.buttonPressed = m.controller.buttonPressed & ~A_BUTTON
if (m.vel.y < 0) then m.vel.y = m.vel.y * 0.33 end
m.vel.y = m.vel.y + ifelse(metal_underwater,135*sv_jumpheight,140*sv_jumpheight)
if (m.vel.y > 320*sv_jumpheight) then m.vel.y = 320*sv_jumpheight end
play_mario_jump_sound(m)
SV_PlayerMovement_Relative(m)
-- SV_PlayerMovement_Store(m,true)
set_mario_action(m, ACT_DM_AIR_MOVEMENT, 0)
act_dm_air_movement(m)
return
end
SV_PlayerMovement(m)
set_character_animation(m, CHAR_ANIM_A_POSE)
if (not cl_bowserthrow) then
local len = vec3f_length(vec3_qscale(m.vel,1,0,1))
if (len < 1) then
m.faceAngle.y = m.area.camera.yaw + 0x8000
if (m.action == ACT_DM_GROUNDED_MOVEMENT) then m.action = ACT_DM_GROUNDED_IDLE end
else
play_local_footstep_sounds(m,len * 0.08,60)
m.faceAngle.y = atan2s(m.vel.z, m.vel.x)
if (m.action == ACT_DM_GROUNDED_IDLE) then m.action = ACT_DM_GROUNDED_MOVEMENT end
end
end
if (valid_update) then
m.forwardVel = vec3f_length(vec3_qscale(m.vel,sv_scalerate,0,sv_scalerate))
else m.forwardVel = 0 end
SV_PlayerMovement_Scale(m,false)
local stepResult = perform_ground_step(m)
SV_PlayerMovement_Scale(m,true)
if (stepResult == GROUND_STEP_LEFT_GROUND) then
SV_PlayerMovement_Relative(m)
if (m.action == ACT_DM_GROUNDED_MOVEMENT_METAL) then
set_mario_action(m, ACT_DM_AIR_MOVEMENT_METAL, 0)
else
set_mario_action(m, ACT_DM_AIR_MOVEMENT, 0)
end
end
if m.wall ~= nil and (stepResult == GROUND_STEP_HIT_WALL) then --or (stepResult == GROUND_STEP_HIT_WALL_CONTINUE_QSTEPS) or (stepResult == GROUND_STEP_HIT_WALL_STOP_QSTEPS)) then
vec3f_copy(m.vel, PHYS_CollideWithNormal(m.vel,m.wall.normal,0.0))
end
if (m.pos.y <= m.waterLevel-sv_playersubmergelevel and m.waterLevel > m.floorHeight + sv_playersubmergelevel) and (m.flags & MARIO_METAL_CAP) == 0 then
if (m.action == ACT_DM_GROUNDED_MOVEMENT_METAL) then
set_mario_action(m, ACT_DM_AIR_MOVEMENT_METAL, 0)
else
set_mario_action(m, ACT_DM_WATER_MOVEMENT, 0)
end
end
end
--- @param m MarioState
local function local_act_dm_air_movement(m)
local valid_update = local_update(m)
-- AngleVectors(m)
local metal_underwater = (m.flags & MARIO_METAL_CAP) ~= 0 and m.pos.y <= m.waterLevel-sv_playersubmergelevel
local act = m.action
local crouch = gPlayerSyncTable[m.playerIndex].playerCrouching
if (metal_underwater and act ~= ACT_DM_AIR_MOVEMENT_METAL) then
SV_PlayerMovement_Store(m,true)
set_mario_action(m, ACT_DM_AIR_MOVEMENT_METAL, 0)
m.action = ACT_DM_AIR_MOVEMENT_METAL
SV_PlayerMovement_Store(m,false)
-- return
elseif (act == ACT_DM_AIR_MOVEMENT_METAL and not metal_underwater) then
set_mario_action(m, ACT_DM_AIR_MOVEMENT, 0)
m.action = ACT_DM_AIR_MOVEMENT
-- return
end
if (m.controller.buttonPressed & Z_TRIG) ~= 0 and (m.controller.buttonDown & A_BUTTON) == 0 and sv_groundpound and m.heldObj == nil and no_dialog_open() then --and m.prevAction ~= ACT_DM_WATER_MOVEMENT then
m.vel.y = 0
m.controller.buttonPressed = m.controller.buttonPressed & ~Z_TRIG
set_mario_action(m, ifelse(metal_underwater,ACT_DM_GROUND_POUND_METAL,ACT_GROUND_POUND), 1)
play_sound(SOUND_ACTION_TWIRL,m.marioObj.header.gfx.cameraToObject)
return
end
SV_PlayerMovement(m)
local len_spd = vec3f_length(vec3_qscale(m.vel,1,0,1))
if (len_spd < 1) then
m.faceAngle.y = m.area.camera.yaw + 0x8000
else
m.faceAngle.y = atan2s(m.vel.z, m.vel.x)
end
set_character_animation(m, CHAR_ANIM_A_POSE)
if (metal_underwater) then
SV_UserGravity(m,0.66)
else
SV_UserGravity(m,1.0)
end
if ((m.flags & MARIO_WING_CAP) ~= 0 and (m.controller.buttonPressed & A_BUTTON) ~= 0) and no_dialog_open() then
if (m.vel.y < 0) then m.vel.y = 0 end
m.vel.y = m.vel.y + ifelse(metal_underwater,100,200)
if (m.vel.y > 320) then m.vel.y = 320 end
set_mario_particle_flags(m, (PARTICLE_DUST | PARTICLE_MIST_CIRCLE), false)
end
local preStepYVel = m.vel.y
if (valid_update) then
m.forwardVel = len_spd*sv_scalerate
else m.forwardVel = 0 end
SV_PlayerMovement_Scale(m,false)
local stepResult = perform_air_step(m,0)
SV_PlayerMovement_Scale(m,true)
if (stepResult == AIR_STEP_LANDED) then
if (m.floor ~= nil) then
if (m.floor.normal.y > SV_GetSurfaceStandableMinimum(m.floor.type,m.area.terrainType) and ifelse(sv_sticky,m.vel.y < (sv_gravity*sv_tickrate)*2,true)) then
vec3f_copy(m.vel, PHYS_CollideWithNormal(m.vel,m.floor.normal,0.0))
-- SV_PlayerMovement_Store(m,true)
cl_airstrafelimiter = 0
m.marioObj.header.gfx.animInfo.animFrame = 0
play_step_sound(m, 0, 1)
gLakituState.roll = gLakituState.roll + clampf(-1.75*(preStepYVel+200),0,1000)
if (m.action == ACT_DM_AIR_MOVEMENT_METAL) then
set_mario_action(m, ACT_DM_GROUNDED_MOVEMENT_METAL, 0)
else
set_mario_action(m, ACT_DM_GROUNDED_MOVEMENT, 0)
end
return
else
vec3f_copy(m.vel, PHYS_CollideWithNormal(m.vel,m.floor.normal,0))
vec3f_add(m.pos,vec3_scale(m.floor.normal,6))
-- vec3f_add(m.vel,vec3_scale(m.floor.normal,clampf(preStepYVel*0.75,-1,1)))
return
end
end
end
if (stepResult == AIR_STEP_HIT_WALL) and m.wall ~= nil then
if (m.controller.buttonDown & ifelse(cl_altWalljumpKey,B_BUTTON,A_BUTTON)) ~= 0 and sv_walljump and no_dialog_open() and m.heldObj == nil and len_spd > 100 then
cl_airstrafelimiter = 0.66
vec3f_copy(m.vel, PHYS_CollideWithNormal(m.vel,m.wall.normal,0.965))
set_mario_particle_flags(m, (PARTICLE_VERTICAL_STAR | PARTICLE_DUST), false)
m.vel.y = 250*sv_jumpheight
play_sound(SOUND_ACTION_BONK,m.marioObj.header.gfx.cameraToObject)
play_character_sound(m,CHAR_SOUND_YAH_WAH_HOO)
else
vec3f_copy(m.vel, PHYS_CollideWithNormal(m.vel,m.wall.normal,0.05))
end
end
if (m.pos.y <= m.waterLevel-sv_playersubmergelevel and m.waterLevel > m.floorHeight + sv_playersubmergelevel) and (m.flags & MARIO_METAL_CAP) == 0 then
if (m.action ~= ACT_DM_AIR_MOVEMENT_METAL) then
set_mario_action(m, ACT_DM_WATER_MOVEMENT, 0)
end
end
end
--- @param m MarioState
local function local_act_dm_water_movement(m)
local valid_update = local_update(m)
-- AngleVectors(m)
SV_WaterMovement(m)
SV_PlayerMovement_Store(m,true)
if (m.playerIndex == 0) then
if (vec3f_length(vec3_qscale(m.vel,1,0,1)) < 1) then
m.faceAngle.y = m.area.camera.yaw + 0x8000
else
m.faceAngle.y = atan2s(m.vel.z, m.vel.x)
end
set_character_animation(m, CHAR_ANIM_A_POSE)
else
local scale = m.forwardVel
if (scale < 10) then
set_character_animation(m, CHAR_ANIM_WATER_IDLE)
else
set_character_anim_with_accel(m, CHAR_ANIM_FLUTTERKICK, scale*0x800)
end
end
if (valid_update) then
m.forwardVel = vec3f_length(vec3_qscale(m.vel,sv_scalerate,0,sv_scalerate))
else m.forwardVel = 0 end
if (m.pos.y+(m.vel.y*sv_scalerate) < m.floorHeight + 2) then
m.pos.y = m.floorHeight + 2
m.vel.y = 0
end
SV_PlayerMovement_Scale(m,false)
local stepResult = perform_air_step(m,0)
SV_PlayerMovement_Scale(m,true)
if (stepResult == AIR_STEP_HIT_WALL) and m.wall ~= nil then
vec3f_copy(m.vel, PHYS_CollideWithNormal(m.vel,m.wall.normal,0.05))
end
local isSnowy = ((m.area.terrainType & TERRAIN_MASK) == TERRAIN_SNOW)
if (m.area.camera.pos.y >= m.waterLevel - 15 and not isSnowy) or mario_holding_underwater_shell(m) then
m.healCounter = 1
if (m.controller.buttonDown & A_BUTTON) ~= 0 and m.vel.y > 0 then
m.vel.y = 180
end
elseif (not mario_holding_underwater_shell(m)) then
m.health = m.health - ifelse(isSnowy,3,1)
end
if (m.pos.y > m.waterLevel-sv_playersubmergelevel) then
set_mario_action(m, ACT_DM_AIR_MOVEMENT, 0)
return
end
end
--- @param m MarioState
local function local_act_dm_ground_pound(m)
local valid_update = local_update(m)
local metal_underwater = (m.flags & MARIO_METAL_CAP) ~= 0 and m.pos.y <= m.waterLevel-sv_playersubmergelevel
if (metal_underwater and act ~= ACT_DM_GROUND_POUND_METAL) then
SV_PlayerMovement_Store(m,true)
set_mario_action(m, ACT_DM_GROUND_POUND_METAL, 0)
SV_PlayerMovement_Store(m,false)
elseif (act == ACT_DM_AIR_MOVEMENT_METAL and not metal_underwater) then
set_mario_action(m, ACT_DM_GROUND_POUND, 0)
end
if (m.controller.buttonPressed & Z_TRIG) ~= 0 then
m.vel.x = 0
m.vel.z = 0
end
m.faceAngle.y = m.area.camera.yaw + 0x8000
set_character_animation(m, CHAR_ANIM_A_POSE)
SV_UserGravityEx(m,1.0,0.75)
SV_PlayerMovement_Scale(m,false)
local stepResult = perform_air_step(m,0)
SV_PlayerMovement_Scale(m,true)
if (stepResult == AIR_STEP_LANDED) then
if (m.floor ~= nil) then
play_mario_heavy_landing_sound(m, SOUND_ACTION_TERRAIN_HEAVY_LANDING)
set_mario_particle_flags(m, (PARTICLE_MIST_CIRCLE | PARTICLE_HORIZONTAL_STAR), false)
gLakituState.roll = gLakituState.roll + 500
if (m.controller.buttonDown & A_BUTTON) ~= 0 and m.health > 0xFF then
SV_HandleSpecialFloors(m,true)
local direction = GetAngleVectors(m).forward
local yV = m.vel.y * 0.32 * sv_scalerate
local len = vec3f_length(vec3_qscale(m.vel,1,0,1))
vec3f_copy(m.vel,vec3_scale(direction,len*0.895))
vec3f_add(m.vel,vec3_qscale(m.floor.normal,-0.3,85 * clampf((len+math.abs(yV)) / 320, 0.5, 1.0),-0.3))
m.vel.y = (m.vel.y + (250 * clampf((len+math.abs(yV)) / 320, 0.65, 1.0)))*sv_jumpheight
-- PHYS_CollideWithNormal(m.vel,m.floor.normal,0.0,1.0)
set_mario_action(m, ifelse(metal_underwater,ACT_DM_AIR_MOVEMENT_METAL,ACT_DM_AIR_MOVEMENT), 0)
play_character_sound(m,CHAR_SOUND_YAHOO)
else
m.forwardVel = 0
m.vel.x = 0
m.vel.y = 0
m.vel.z = 0
set_mario_action(m, ifelse(metal_underwater,ACT_DM_GROUNDED_MOVEMENT_METAL,ACT_GROUND_POUND_LAND), 0)
end
return;
end
end
end
--- @param m MarioState
local function local_act_dm_pole_movement(m)
local_update(m)
m.vel.x = 0
m.vel.z = 0
if (m.health <= 0xFF or m.usedObj == nil or (m.controller.buttonPressed & Z_TRIG) ~= 0) then
m.vel.y = 0
m.forwardVel = 3
m.controller.buttonPressed = m.controller.buttonPressed & ~(Z_TRIG|A_BUTTON)
return set_mario_action(m, ACT_DM_AIR_MOVEMENT, 0)
end
m.faceAngle.y = m.area.camera.yaw + 0x8000
if (m.controller.buttonPressed & A_BUTTON) ~= 0 then
m.vel.y = 12
m.forwardVel = 36
return set_mario_action(m, ACT_WALL_KICK_AIR, 0)
end
set_character_animation(m, CHAR_ANIM_A_POSE)
local o = m.usedObj
local i = ifelse(gFirstPersonCamera.pitch < 0,1.0,-1.0)
m.pos.y = m.pos.y + (m.usedObj.oPosY-cl_poleY)
cl_poleY = m.usedObj.oPosY
m.pos.x = o.oPosX + sins(m.faceAngle.y)
m.pos.z = o.oPosZ + coss(m.faceAngle.y)
m.vel.y = m.controller.rawStickY*0.66*i
local intendedPos = m.pos.y + (m.vel.y*sv_scalerate)
if (intendedPos < o.oPosY) then
m.vel.y = 0
m.pos.y = o.oPosY
end
if (intendedPos > o.oPosY+o.hitboxHeight) then
m.vel.y = 0
m.pos.y = o.oPosY+o.hitboxHeight
end
SV_PlayerMovement_Scale(m,false)
local stepResult = perform_air_step(m,0)
SV_PlayerMovement_Scale(m,true)
end
----------------------------------
-- Prediction for other players --
----------------------------------
--- @param m MarioState
local function prediction_act_dm_grounded_movement(m)
local crouch = gPlayerSyncTable[m.playerIndex].playerCrouching
if ((m.controller.buttonDown & A_BUTTON) ~= 0 or (m.controller.buttonPressed & A_BUTTON) ~= 0) and m.floor ~= nil then
play_character_sound(m,CHAR_SOUND_YAH_WAH_HOO)
-- return
end
if (not cl_disableAccelPred) then SV_PlayerMovement(m) end
local scale = m.forwardVel
if (scale < 5) then
set_character_animation(m, ifelse(crouch,CHAR_ANIM_CROUCHING,CHAR_ANIM_FIRST_PERSON))
else
play_step_sound(m, ifelse(crouch,26,9), ifelse(crouch,79,45))
set_character_anim_with_accel(m, ifelse(crouch,CHAR_ANIM_CRAWLING,CHAR_ANIM_RUNNING), scale*ifelse(crouch,0x4000,0x2600))
end
m.forwardVel = vec3f_length(vec3_qscale(m.vel,sv_scalerate,0,sv_scalerate))
SV_PlayerMovement_Scale(m,false)
local stepResult = perform_ground_step(m)
SV_PlayerMovement_Scale(m,true)
end
--- @param m MarioState
local function prediction_act_dm_air_movement(m)
local crouch = gPlayerSyncTable[m.playerIndex].playerCrouching
if (not cl_disableAccelPred) then SV_PlayerMovement(m) end
set_character_animation(m, ifelse(crouch,CHAR_ANIM_FAST_LONGJUMP,ifelse(m.vel.y < 0,CHAR_ANIM_DOUBLE_JUMP_FALL,CHAR_ANIM_DOUBLE_JUMP_RISE)))
if (metal_underwater) then
SV_UserGravity(m,0.66)
else
SV_UserGravity(m,1.0)
end
if ((m.flags & MARIO_WING_CAP) ~= 0 and (m.controller.buttonDown & A_BUTTON) ~= 0 and m.vel.y < 0) then m.vel.y = 0 end
m.forwardVel = vec3f_length(vec3_qscale(m.vel,sv_scalerate,0,sv_scalerate))
SV_PlayerMovement_Scale(m,false)
local stepResult = perform_air_step(m,0)
SV_PlayerMovement_Scale(m,true)
end
--- @param m MarioState
local function prediction_act_dm_water_movement(m)
if (not cl_disableAccelPred) then SV_WaterMovement(m) end
local scale = m.forwardVel
if (scale < 10) then
set_character_animation(m, CHAR_ANIM_WATER_IDLE)
else
set_character_anim_with_accel(m, CHAR_ANIM_FLUTTERKICK, scale*0x800)
end
if (vec3f_length(m.vel) <= 10) then
m.forwardVel = 0
return
end
m.forwardVel = vec3f_length(vec3_qscale(m.vel,sv_scalerate,0,sv_scalerate))
SV_PlayerMovement_Scale(m,false)
local stepResult = perform_air_step(m,0)
SV_PlayerMovement_Scale(m,true)
end
--- @param m MarioState
local function prediction_act_dm_ground_pound(m)
set_character_animation(m, CHAR_ANIM_TRIPLE_JUMP_GROUND_POUND)
SV_UserGravityEx(m,1.0,0.75)
SV_PlayerMovement_Scale(m,false)
local stepResult = perform_air_step(m,0)
SV_PlayerMovement_Scale(m,true)
if (stepResult == AIR_STEP_LANDED) then
if (m.floor ~= nil) then
play_mario_heavy_landing_sound(m, SOUND_ACTION_TERRAIN_HEAVY_LANDING)
set_mario_particle_flags(m, (PARTICLE_MIST_CIRCLE | PARTICLE_HORIZONTAL_STAR), false)
if (m.controller.buttonDown & A_BUTTON) ~= 0 then
play_character_sound(m,CHAR_SOUND_YAHOO)
end
end
end
end
--- @param m MarioState
local function prediction_act_dm_pole_movement(m)
set_character_animation(m, CHAR_ANIM_IDLE_ON_POLE)
SV_PlayerMovement_Scale(m,false)
local stepResult = perform_air_step(m,0)
SV_PlayerMovement_Scale(m,true)
end
--- @param m MarioState
function act_dm_grounded_movement(m)
if (m.playerIndex == 0) then return local_act_dm_grounded_movement(m) else return prediction_act_dm_grounded_movement(m) end
end
--- @param m MarioState
function act_dm_air_movement(m)
if (m.playerIndex == 0) then return local_act_dm_air_movement(m) else return prediction_act_dm_air_movement(m) end
end
--- @param m MarioState
function act_dm_water_movement(m)
if (m.playerIndex == 0) then return local_act_dm_water_movement(m) else return prediction_act_dm_water_movement(m) end
end
--- @param m MarioState
function act_dm_ground_pound(m)
if (m.playerIndex == 0) then return local_act_dm_ground_pound(m) else return prediction_act_dm_ground_pound(m) end
end
--- @param m MarioState
function act_dm_pole_movement(m)
if (m.playerIndex == 0) then return local_act_dm_pole_movement(m) else return prediction_act_dm_pole_movement(m) end
end