-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathc-viewmodel.lua
144 lines (119 loc) · 5.17 KB
/
c-viewmodel.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
if SM64COOPDX_VERSION == nil then return end
local CAP_FLICKER_FRAMES = 0x4444449249255555 -- this is beyond my comprehension
gFirstPersonViewmodels = {
armObjs = { nil, nil },
gunObjs = { nil, nil }
}
--- @param o Object
local function bhv_viewmodel_init(o)
o.oFlags = OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE
o.oGraphYOffset = 0
end
--- @param o Object
local function bhv_viewmodel_loop(o)
if not gGlobalSyncTable.gunModEnabled or not get_first_person_enabled() then
obj_mark_for_deletion(o)
return
end
local dualWield = obj_get_weapon_dual_wield(o) ~= 0
--- @type Weapon
local weapon = if_then_else(dualWield, cur_dual_wield_weapon(), cur_weapon())
if not weapon.reqCheck(gMarioStates[0]) then
cur_obj_hide()
else
cur_obj_unhide()
end
local horizontalOffset = 30
if cur_dual_wield_weapon() ~= nil then
horizontalOffset = if_then_else(obj_get_weapon_dual_wield(o) ~= 0, -50, 50)
end
-- math to calculate staying in the same screen position no matter what
o.oPosX = gLakituState.pos.x - 35 * coss(gFirstPersonCamera.pitch) * sins(gFirstPersonCamera.yaw)
o.oPosY = gLakituState.pos.y - 35 * sins(gFirstPersonCamera.pitch)
o.oPosZ = gLakituState.pos.z - 35 * coss(gFirstPersonCamera.pitch) * coss(gFirstPersonCamera.yaw)
-- math to offset it to the left or right
o.oPosX = o.oPosX + sins(gFirstPersonCamera.yaw + 0x4000) * horizontalOffset
o.oPosZ = o.oPosZ + coss(gFirstPersonCamera.yaw + 0x4000) * horizontalOffset
o.oFaceAnglePitch = 0
o.oFaceAngleYaw = gFirstPersonCamera.yaw + 0x4000
o.oFaceAngleRoll = -gFirstPersonCamera.pitch
if weapon ~= nil then
if weapon.deployTimer > 0 then
obj_set_animation(o, "arm_reload_end")
-- freeze animation if the time hasn't come to show the arm rising up
if o.header.gfx.animInfo.animFrame > 0 and weapon.deployTimer - o.header.gfx.animInfo.curAnim.loopEnd > 0 then
o.header.gfx.animInfo.animFrame = 0
end
else
local half = math.floor(weapon.reloadTime * 0.5)
if weapon.reloadTimer <= 0 then
if weapon.cooldownTimer > 0 then
obj_set_animation(o, "arm_shoot")
else
obj_set_animation(o, "arm_idle")
-- *try* keep both arms in sync
if dualWield then
o.header.gfx.animInfo.animFrame = gFirstPersonViewmodels.armObjs[1].header.gfx.animInfo.animFrame
end
end
elseif weapon.reloadTimer < half then
obj_set_animation(o, "arm_reload_end")
else
obj_set_animation(o, "arm_reload_start")
end
end
end
o.globalPlayerIndex = gNetworkPlayers[0].globalIndex
--- @type MarioState
local m = gMarioStates[0]
if m.capTimer < 64 and ((1 << m.capTimer) & CAP_FLICKER_FRAMES) ~= 0 then
o.oAnimState = 0
else
local vanishCap = if_then_else((gMarioStates[0].flags & MARIO_VANISH_CAP) ~= 0, 2, 0)
local metalCap = if_then_else((gMarioStates[0].flags & MARIO_METAL_CAP) ~= 0, 1, 0)
o.oAnimState = metalCap + vanishCap
end
local cameraDistance = 200
local cameraHeight = 100
gLakituState.pos.x = gLakituState.pos.x + cameraDistance * sins(gLakituState.yaw)
gLakituState.pos.y = gLakituState.pos.y + cameraHeight + (cameraDistance * sins(gFirstPersonCamera.pitch))
gLakituState.pos.z = gLakituState.pos.z + cameraDistance * coss(gLakituState.yaw)
cur_obj_hide()
end
id_bhvViewmodel = hook_behavior(nil, OBJ_LIST_GENACTOR, true, bhv_viewmodel_init, bhv_viewmodel_loop, "bhvGmViewmodel")
--- @param weapon Weapon
local function spawn_viewmodel(weapon, dualWield)
local index = if_then_else(dualWield, 1, 2)
dualWield = if_then_else(dualWield, 1, 0)
gFirstPersonViewmodels.armObjs[index] = spawn_non_sync_object(
id_bhvViewmodel,
weapon.armModel,
0, -10000, 0,
--- @param o Object
function(o)
obj_set_weapon_params(o, 0, 0, dualWield, 0)
end
)
gFirstPersonViewmodels.gunObjs[index] = spawn_non_sync_object(
id_bhvViewmodel,
weapon.model,
0, -10000, 0,
--- @param o Object
function(o)
obj_set_weapon_params(o, 0, 0, dualWield, 0)
end
)
end
function spawn_viewmodels()
local weapon1 = cur_weapon()
local weapon2 = cur_dual_wield_weapon()
if weapon1 == nil then return end
spawn_viewmodel(weapon1, false)
if weapon2 ~= nil then spawn_viewmodel(weapon2, true) end
end
function delete_viewmodels()
gFirstPersonViewmodels.armObjs[1] = obj_mark_for_deletion(gFirstPersonViewmodels.armObjs[1])
gFirstPersonViewmodels.armObjs[2] = obj_mark_for_deletion(gFirstPersonViewmodels.armObjs[2])
gFirstPersonViewmodels.gunObjs[1] = obj_mark_for_deletion(gFirstPersonViewmodels.gunObjs[1])
gFirstPersonViewmodels.gunObjs[2] = obj_mark_for_deletion(gFirstPersonViewmodels.gunObjs[2])
end