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

273 lines
No EOL
7.7 KiB
Lua

POWERUP_NONE = 0
POWERUP_MUSHROOM = 1
POWERUP_GREEN_SHELL = 2
POWERUP_RED_SHELL = 3
POWERUP_BANANA = 4
POWERUP_MAX = 5
define_custom_obj_fields({
oPowerupType = 'u32',
oPowerupIndex = 'u32',
})
function bhv_powerup_init(obj)
obj.oFlags = OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE
obj.oOpacity = 255
local m = gMarioStates[obj.heldByPlayerIndex]
local mTheta = m.faceAngle.y
local mMag = 0
if obj.oPowerupType == POWERUP_BANANA then
mMag = 100 * (obj.oPowerupIndex + 1)
end
obj.oPosX = m.pos.x - sins(mTheta) * mMag
obj.oPosY = m.pos.y
obj.oPosZ = m.pos.z - coss(mTheta) * mMag
end
function bhv_powerup_stale(obj)
if obj.oPowerupType == POWERUP_MUSHROOM then
obj.oAction = 1
obj.oTimer = 0
else
obj.activeFlags = ACTIVE_FLAG_DEACTIVATED
end
end
function bhv_powerup_spin(obj)
local m = gMarioStates[obj.heldByPlayerIndex]
local theta = get_network_area_timer() / 8.0
theta = theta + (math.pi * 2) * obj.oPowerupIndex / 3.0
local mag = 120
if obj.oAction == 1 then
local scalar = (1 - (obj.oTimer / 5))
scalar = scalar * scalar
mag = mag * scalar
end
local vec = {
x = m.pos.x + math.sin(theta) * mag,
y = m.pos.y + mag,
z = m.pos.z + math.cos(theta) * mag
}
vec.y = find_floor_height(vec.x, vec.y, vec.z) + 50
if vec.y < m.pos.y + 50 then vec.y = m.pos.y + 50 end
return vec
end
function bhv_powerup_trail(obj)
local prevObj = gMarioStates[obj.heldByPlayerIndex].marioObj
local s = gPlayerSyncTable[obj.heldByPlayerIndex]
for i = 0, 2 do
if i >= obj.oPowerupIndex then
break
end
if s.powerup[i] == POWERUP_BANANA then
prevObj = gPowerups[obj.heldByPlayerIndex][i]
end
end
local theta = math.atan2(prevObj.oPosX - obj.oPosX, prevObj.oPosZ - obj.oPosZ)
if theta ~= theta then theta = 0 end
local mag = 150
local newPos = {
x = prevObj.oPosX - math.sin(theta) * mag,
y = prevObj.oPosY,
z = prevObj.oPosZ - math.cos(theta) * mag
}
local vec = {
x = (newPos.x + obj.oPosX) / 2,
y = (newPos.y + obj.oPosY * 7) / 8,
z = (newPos.z + obj.oPosZ) / 2
}
local floor = find_floor_height(vec.x, vec.y, vec.z) + 25
if vec.y < floor then vec.y = floor end
return vec
end
function bhv_powerup_loop(obj)
local m = gMarioStates[obj.heldByPlayerIndex]
local s = gPlayerSyncTable[obj.heldByPlayerIndex]
local p = gPowerups[obj.heldByPlayerIndex][obj.oPowerupIndex]
if obj.oAction == 0 then
if s.powerup[obj.oPowerupIndex] ~= obj.oPowerupType or p ~= obj then
bhv_powerup_stale(obj)
end
end
local vec = nil
if obj.oPowerupType == POWERUP_BANANA then
vec = bhv_powerup_trail(obj)
else
vec = bhv_powerup_spin(obj)
end
local theta = get_network_area_timer() / 8.0
theta = theta + (math.pi * 2) * obj.oPowerupIndex / 3.0
obj_set_vec3f(obj, vec)
obj.oFaceAngleYaw = theta * 0x6000
obj.oFaceAngleRoll = 0
obj.oFaceAnglePitch = 0
if obj.oAction == 1 and obj.oTimer > 5 then
obj.activeFlags = ACTIVE_FLAG_DEACTIVATED
end
end
id_bhvPowerup = hook_behavior(nil, OBJ_LIST_LEVEL, true, bhv_powerup_init, bhv_powerup_loop)
-----------------
function use_powerup(m, powerup)
local s = gPlayerSyncTable[m.playerIndex]
local theta = m.faceAngle.y
if powerup == POWERUP_BANANA then
theta = theta + 0x8000
end
local spawnPosition = {
x = m.pos.x + sins(theta) * 120,
y = m.pos.y,
z = m.pos.z + coss(theta) * 120,
}
if powerup == POWERUP_MUSHROOM then
m.forwardVel = 300
play_character_sound(m, CHAR_SOUND_YAHOO)
elseif powerup == POWERUP_GREEN_SHELL then
spawn_sync_object(
id_bhvWeaponShell,
E_MODEL_KOOPA_SHELL,
spawnPosition.x, spawnPosition.y, spawnPosition.z,
function (obj)
if UNST22 then
obj.oFlyGuyIdleTimer = 0
obj.oFlyGuyOscTimer = gNetworkPlayers[0].globalIndex
obj.oFlyGuyUnusedJitter = 0
else
obj.oWeaponShellType = 0
obj.oWeaponShellGlobalOwner = gNetworkPlayers[0].globalIndex
obj.oWeaponShellDeactivate = 0
end
obj.oMoveAngleYaw = m.faceAngle.y
obj.oForwardVel = 85
obj.oInteractStatus = 0
end
)
elseif powerup == POWERUP_RED_SHELL then
spawn_sync_object(
id_bhvWeaponShell,
E_MODEL_RED_SHELL,
spawnPosition.x, spawnPosition.y, spawnPosition.z,
function (obj)
if UNST22 then
obj.oFlyGuyIdleTimer = 1
obj.oFlyGuyOscTimer = gNetworkPlayers[0].globalIndex
obj.oFlyGuyUnusedJitter = 0
else
obj.oWeaponShellType = 1
obj.oWeaponShellGlobalOwner = gNetworkPlayers[0].globalIndex
obj.oWeaponShellDeactivate = 0
end
obj.oMoveAngleYaw = m.faceAngle.y
obj.oForwardVel = 85
obj.oInteractStatus = 0
end
)
elseif powerup == POWERUP_BANANA then
spawn_sync_object(
id_bhvWeaponBanana,
E_MODEL_BANANA,
spawnPosition.x, spawnPosition.y, spawnPosition.z,
function (obj)
obj.oMoveAngleYaw = m.faceAngle.y
obj.oWeaponBananaGlobalOwner = gNetworkPlayers[0].globalIndex
end
)
end
end
function spawn_powerup(m, powerup, index)
if not is_in_local_area(m) then
return nil
end
if powerup == POWERUP_MUSHROOM then
return spawn_non_sync_object(
id_bhvPowerup,
E_MODEL_1UP,
0, 0, 0,
function(obj)
obj.heldByPlayerIndex = m.playerIndex
obj.oPowerupType = powerup
obj.oPowerupIndex = index
obj_set_billboard(obj)
obj_scale(obj, 1)
end
)
elseif powerup == POWERUP_GREEN_SHELL then
return spawn_non_sync_object(
id_bhvPowerup,
E_MODEL_KOOPA_SHELL,
0, 0, 0,
function(obj)
obj.heldByPlayerIndex = m.playerIndex
obj.oPowerupType = powerup
obj.oPowerupIndex = index
obj_scale(obj, 0.75)
end
)
elseif powerup == POWERUP_RED_SHELL then
return spawn_non_sync_object(
id_bhvPowerup,
E_MODEL_RED_SHELL,
0, 0, 0,
function(obj)
obj.heldByPlayerIndex = m.playerIndex
obj.oPowerupType = powerup
obj.oPowerupIndex = index
obj_scale(obj, 0.75)
end
)
elseif powerup == POWERUP_BANANA then
return spawn_non_sync_object(
id_bhvPowerup,
E_MODEL_BANANA,
0, 0, 0,
function(obj)
obj.heldByPlayerIndex = m.playerIndex
obj.oPowerupType = powerup
obj.oPowerupIndex = index
obj_scale(obj, 0.75)
end
)
end
return nil
end
function select_powerup()
local m = gMarioStates[0]
local s = gPlayerSyncTable[0]
local pick = math.random(1, POWERUP_MAX-1)
local luck = math.random() < 0.33
if luck then
s.powerup[0] = pick
s.powerup[1] = pick
s.powerup[2] = pick
else
s.powerup[0] = pick
s.powerup[1] = POWERUP_NONE
s.powerup[2] = POWERUP_NONE
end
end