-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.lua
407 lines (351 loc) · 15.1 KB
/
main.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
-- name: Gun Mod DX
-- incompatible: weapon
-- description: Gun Mod DX v3.0.2\nBy \\#ec7731\\Agent X\\#dcdcdc\\\nSpecial thanks to \\#f296af\\PeachyPeach\\#dcdcdc\\\n\nThis is a rewritten & overhauled version of my original Gun Mod for sm64ex-coop. I thought this would make a good mod to bundle with sm64coopdx. If you have two pistols, you are able to dual wield them as well!\n\nPress [\\#3040ff\\Y\\#dcdcdc\\] to shoot\nPress [\\#3040ff\\X\\#dcdcdc\\] to reload\nRun \\#00ffff\\/gm help\\#dcdcdc\\ for help
-- deluxe: true
if SM64COOPDX_VERSION == nil then return end
gGlobalSyncTable.gunModEnabled = true
local renderHud = true
gShootableHitboxes = {
[id_bhvMario] = hurt_player,
[id_bhvStar] = hurt_star,
[id_bhvMessagePanel] = hurt_sign,
[id_bhvToadMessage] = hurt_toad,
[id_bhvExclamationBox] = hurt_exclamation_box,
[id_bhvBreakableBox] = hurt_breakable_box,
[id_bhvBreakableBoxSmall] = hurt_breakable_box_small,
[id_bhvBowlingBall] = hurt_bowling_ball,
[id_bhvWaterBomb] = hurt_water_bomb,
[id_bhvTree] = hurt_tree,
[id_bhvChainChomp] = hurt_chain_chomp,
[id_bhvGoomba] = hurt_goomba,
[id_bhvBobomb] = hurt_bobomb,
[id_bhvHomingAmp] = hurt_amp,
[id_bhvCirclingAmp] = hurt_amp,
[id_bhvKoopa] = hurt_koopa,
[id_bhvFlyGuy] = hurt_snufit,
[id_bhvChuckya] = hurt_chuckya,
[id_bhvPiranhaPlant] = hurt_piranha_plant,
[id_bhvSnufit] = hurt_snufit,
[id_bhvSwoop] = hurt_snufit,
[id_bhvSpindrift] = hurt_spindrift,
[id_bhvMrBlizzard] = hurt_mr_blizzard,
[id_bhvMrI] = hurt_mr_i,
[id_bhvScuttlebug] = hurt_scuttlebug,
[id_bhvPokeyBodyPart] = hurt_pokey,
[id_bhvSkeeter] = hurt_scuttlebug,
[id_bhvSmallBully] = hurt_bully,
[id_bhvBigBully] = hurt_bully,
[id_bhvSmallChillBully] = hurt_bully,
[id_bhvBigChillBully] = hurt_bully,
[id_bhvMoneybag] = hurt_moneybag,
[id_bhvKingBobomb] = hurt_king_bobomb,
[id_bhvBowser] = hurt_bowser,
[id_bhvYoshi] = hurt_yoshi
}
--- @param enable boolean
--- @return nil
--- Globally enables or disables Gun Mod
local function enable_gun_mod(enable)
if not network_is_server() and not network_is_moderator() then return end
if type(enable) ~= "boolean" then return end
gGlobalSyncTable.gunModEnabled = enable
djui_popup_create("Gun Mod has been " .. if_then_else(gGlobalSyncTable.gunModEnabled, "enabled.", "disabled."), 2)
end
--- @param weapon WeaponId
--- Returns a weapon by its ID
local function get_weapon(weapon)
return gWeaponTable[weapon]
end
--- @return nil
--- Returns whether or not the Gun Mod HUD will render
local function get_render_hud()
return renderHud
end
--- @param enable boolean
--- @return nil
--- Sets whether or not the Gun Mod HUD will render
local function set_render_hud(enable)
if type(enable) ~= "boolean" then return end
renderHud = enable
end
--- @param behavior BehaviorId
--- @param hurtFunc fun(obj:Object, bulletObj:Object)
--- @return nil
local function shootable_register(behavior, hurtFunc)
if type(behavior) ~= "number" or type(hurtFunc) ~= "function" then return end
gShootableHitboxes[behavior] = hurtFunc
end
--- @param m MarioState
local function mario_update(m)
if active_player(m) == 0 then return end
if gGlobalSyncTable.gunModEnabled and gPlayerSyncTable[m.playerIndex].curWeapon ~= nil then
local spawned = false
local held = obj_get_first_with_behavior_id(id_bhvHeldWeapon)
while held ~= nil do
if obj_get_weapon_owner(held) == gNetworkPlayers[m.playerIndex].globalIndex then
spawned = true
break
end
held = obj_get_next_with_same_behavior_id(held)
end
if not spawned then
spawn_non_sync_object(
id_bhvHeldWeapon,
gWeaponTable[gPlayerSyncTable[m.playerIndex].curWeapon].model,
0, 0, 0,
--- @param o Object
function(o)
obj_set_weapon_params(o, gNetworkPlayers[m.playerIndex].globalIndex, gPlayerSyncTable[m.playerIndex].curWeapon, 0, 0)
end
)
if gPlayerSyncTable[m.playerIndex].curWeapon2 ~= nil then
spawn_non_sync_object(
id_bhvHeldWeapon,
gWeaponTable[gPlayerSyncTable[m.playerIndex].curWeapon2].model,
0, 0, 0,
--- @param o Object
function(o)
obj_set_weapon_params(o, gNetworkPlayers[m.playerIndex].globalIndex, gPlayerSyncTable[m.playerIndex].curWeapon2, 1, 0)
end
)
end
end
end
if m.playerIndex ~= 0 then return end
if vec3f_dist(m.pos, m.area.camera.pos) < 500 and (m.action & ACT_GROUP_MASK) ~= ACT_GROUP_CUTSCENE then
-- m.marioBodyState.modelState = m.marioBodyState.modelState | MODEL_STATE_NOISE_ALPHA
end
if get_first_person_enabled() then
if gGlobalSyncTable.gunModEnabled and obj_get_first_with_behavior_id(id_bhvViewmodel) == nil and cur_weapon() ~= nil then
spawn_viewmodels()
end
if (m.action & ACT_FLAG_IDLE) ~= 0 then
m.faceAngle.y = gLakituState.yaw + 0x8000
end
-- movement
-- if m.action ~= ACT_CUSTOM_MOVEMENT then
-- set_mario_action(m, ACT_CUSTOM_MOVEMENT, 0)
-- vec3f_copy(gPlayerFirstPerson.movement.pos, m.pos)
-- end
elseif not camera_config_is_mouse_look_enabled() then
djui_hud_set_mouse_locked(false)
end
-- disable negative vertical speed conservation so guns don't appear lower than normal
local group = (m.action & ACT_GROUP_MASK)
if (group == ACT_GROUP_MOVING or group == ACT_GROUP_STATIONARY or group == ACT_GROUP_OBJECT) and (m.action & ACT_FLAG_AIR) == 0 and m.vel.y < 0 then
m.vel.y = 0
end
if gGlobalSyncTable.gunModEnabled then
weapon_update()
end
end
local function on_level_init()
local obj = obj_get_first(OBJ_LIST_SURFACE)
while obj ~= nil do
obj.header.gfx.skipInViewCheck = true
obj = obj_get_next(obj)
end
spawn_dialog_arrow()
if not mod_storage_load_bool("init") then
mod_storage_save_bool("init", true)
audio_sample_play(SOUND_CUSTOM_BAD_TO_THE_BONE, gMarioStates[0].pos, 1)
end
end
local function on_hud_render_behind()
local weapon = cur_weapon()
if weapon == nil or not renderHud or not gGlobalSyncTable.gunModEnabled or gNetworkPlayers[0].currActNum == 99 or obj_get_first_with_behavior_id(id_bhvActSelector) ~= nil then return end
djui_hud_set_resolution(RESOLUTION_N64)
djui_hud_set_font(FONT_HUD)
local width = djui_hud_get_screen_width()
local height = djui_hud_get_screen_height()
if get_first_person_enabled() and weapon ~= nil and not is_game_paused() then
djui_hud_set_color(255, 255, 0, 127)
djui_hud_render_texture(TEX_CROSSHAIR, width * 0.5 - 4, height * 0.5 - 4, 0.5, 0.5)
end
local y = height - 35
djui_hud_set_color(255, 255, 255, 255)
if weapon.maxAmmo ~= 0 then
djui_hud_print_text(weapon.ammo .. "/" .. weapon.maxAmmo, width - 128, y, 1)
end
local weapon2 = cur_dual_wield_weapon()
if weapon2 ~= nil and weapon2.maxAmmo ~= 0 then
djui_hud_print_text(weapon2.ammo .. "/" .. weapon2.maxAmmo, 16, y, 1)
end
end
function on_packet_receive(dataTable)
if dataTable.packet == PACKET_ATTACK then
if gNetworkPlayers[0].currLevelNum == dataTable.level and gNetworkPlayers[0].currAreaIndex == dataTable.area and gNetworkPlayers[0].currActNum == dataTable.act then
audio_sample_play(SOUND_CUSTOM_IMPACT, gMarioStates[0].pos, 1)
end
if dataTable.yoshi then
local pos = gMarioStates[network_local_index_from_global(dataTable.globalIndex)].pos
spawn_non_sync_object(
id_bhvExplosion,
E_MODEL_TROLL_EXPLOSION,
pos.x, pos.y + 80, pos.z,
nil
)
end
if gNetworkPlayers[0].globalIndex ~= dataTable.globalIndex then return end
if dataTable.yoshi then
set_health(0)
else
set_health(get_health() - gWeaponTable[dataTable.weaponId].damage)
end
elseif dataTable.packet == PACKET_SOUND then
if gNetworkPlayers[0].currLevelNum == dataTable.level and gNetworkPlayers[0].currAreaIndex == dataTable.area and gNetworkPlayers[0].currActNum == dataTable.act then
-- audio_sample_stop(gSoundTable[dataTable.sound])
audio_sample_play(gSoundTable[dataTable.sound], { x = dataTable.x, y = dataTable.y, z = dataTable.z }, dataTable.volume)
end
end
end
--------------
-- commands --
--------------
local function on_fp_command()
set_first_person_enabled(not gFirstPersonCamera.enabled)
djui_chat_message_create("[Gun Mod] First person mode status: " .. on_or_off(gFirstPersonCamera.enabled))
return true
end
local function on_fov_command(msg)
local fov = tonumber(msg)
if fov ~= nil then
if fov <= 0 then
fov = FIRST_PERSON_DEFAULT_FOV
end
mod_storage_save_number("fov", fov)
gFirstPersonCamera.fov = fov
djui_chat_message_create("[Gun Mod] Set FOV to " .. fov)
return true
end
djui_chat_message_create("/gm \\#00ffff\\fov\\#ffff00\\ [number]\\#ffffff\\\nSets the first person camera FOV, default is \\#ffff00\\70\\#ffffff\\")
return true
end
local function on_give_command(msg)
-- if not network_is_server() and not network_is_moderator() then
-- djui_chat_message_create("\\#ffa0a0\\You do not have permission to run this command.")
-- return true
-- end
if not gGlobalSyncTable.gunModEnabled then
djui_chat_message_create("\\#ffa0a0\\[Gun Mod] You need to enable Gun Mod to give yourself a weapon.")
return true
end
for id, weapon in pairs(gWeaponTable) do
if weapon.name:lower() == msg:lower() then
pickup_weapon(id)
local text = string.format("[Gun Mod] Gave %s %s", name_without_hex(gNetworkPlayers[0].name), weapon.name)
djui_chat_message_create(text)
return true
end
end
djui_chat_message_create("/gm \\#00ffff\\give\\#ffff00\\ " .. get_weapon_list_string() .. "\\#ffffff\\\nGives yourself a gun")
return true
end
local function on_gm_command(msg)
local args = split(msg)
if args[1] == "fp" then
return on_fp_command()
elseif args[1] == "fov" then
return on_fov_command(args[2] or "")
elseif args[1] == "give" then
return on_give_command(args[2] or "")
end
if msg:gsub("%s+", "") == "" and (network_is_server() or network_is_moderator()) then
gGlobalSyncTable.gunModEnabled = not gGlobalSyncTable.gunModEnabled
djui_chat_message_create("[Gun Mod] Status: " .. on_or_off(gGlobalSyncTable.gunModEnabled))
else
djui_chat_message_create("/gm \\#00ffff\\[fp|fov|give]\\#7f7f7f\\ (leave blank to toggle Gun Mod on or off)")
end
return true
end
smlua_text_utils_dialog_replace(DIALOG_167, 1, 4, 30, 200, "Welcome to Gun Mod. After\
4 months in development,\
hopefully it will have\
been worth the wait.\
This mod has actually been\
in development for 16\
months, but progress was\
pretty slow until recently.\
I decided to rewrite the\
rewrite to make this\
mod's code less of a\
total mess.\
-- TUTORIAL --\
Press X to shoot\
Press Y to reload\
Run slash gm help\
Princess Toadstool's\
castle is just ahead.\
\
\
Press [A] to jump, [Z] to\
crouch, and [B] to punch,\
read a sign, or grab\
something.\
Press [B] again to throw\
something you're holding.")
gServerSettings.playerInteractions = PLAYER_INTERACTIONS_PVP
_G.gunModApi = {
enable_gun_mod = enable_gun_mod,
get_render_hud = get_render_hud,
set_render_hud = set_render_hud,
get_weapon = get_weapon,
weapon_register = weapon_register,
weapon_unregister = weapon_unregister,
weapon_unregister_all = weapon_unregister_all,
get_weapon_list_string = get_weapon_list_string,
obj_set_weapon_params = obj_set_weapon_params,
obj_get_weapon_owner = obj_get_weapon_owner,
obj_get_weapon_id = obj_get_weapon_id,
obj_get_weapon_dual_wield = obj_get_weapon_dual_wield,
obj_get_weapon_extra = obj_get_weapon_extra,
cur_weapon = cur_weapon,
cur_dual_wield_weapon = cur_dual_wield_weapon,
get_inventory_slot = get_inventory_slot,
set_inventory_slot = set_inventory_slot,
pickup_weapon = pickup_weapon,
get_health = get_health,
set_health = set_health,
common_shoot = common_shoot,
common_reload = common_reload,
bullet_ricochet = bullet_ricochet,
obj_generate_hitbox_multiply_func = obj_generate_hitbox_multiply_func,
obj_generate_health_func = obj_generate_health_func,
shootable_register = shootable_register
}
local fov = mod_storage_load_number("fov")
if fov == 0 then
fov = FIRST_PERSON_DEFAULT_FOV
mod_storage_save_number("fov", fov)
end
gFirstPersonCamera.fov = fov
if START_IN_FIRST_PERSON then
set_first_person_enabled(true)
end
hook_event(HOOK_MARIO_UPDATE, mario_update)
hook_event(HOOK_ON_LEVEL_INIT, on_level_init)
hook_event(HOOK_ON_PACKET_RECEIVE, on_packet_receive)
hook_event(HOOK_ON_HUD_RENDER_BEHIND, on_hud_render_behind)
gm_hook_behavior(id_bhvMessagePanel, false, obj_sign_hitbox)
gm_hook_behavior(id_bhvExclamationBox, false, nil, obj_generate_hitbox_multiply_func(1, 1.8))
gm_hook_behavior(id_bhvBreakableBox, false, obj_generate_health_func(HEALTH_BREAKABLE_BOX))
gm_hook_behavior(id_bhvBowlingBall, false, obj_generate_health_func(HEALTH_BOWLING_BALL))
gm_hook_behavior(id_bhvWaterBomb, false, nil, obj_generate_hitbox_multiply_func(1, 2))
gm_hook_behavior(id_bhvChainChomp, false, nil, obj_generate_hitbox_multiply_func(1.5, 1.5))
gm_hook_behavior(id_bhvHomingAmp, false, nil, obj_amp_hitbox)
gm_hook_behavior(id_bhvCirclingAmp, false, nil, obj_amp_hitbox)
gm_hook_behavior(id_bhvFlyGuy, false, nil, obj_generate_hitbox_multiply_func(0.75, 1.75))
gm_hook_behavior(id_bhvChuckya, false, obj_chuckya_hitbox)
gm_hook_behavior(id_bhvSnufit, false, nil, obj_snufit_hitbox)
gm_hook_behavior(id_bhvSpindrift, false, nil, obj_generate_hitbox_multiply_func(0.75, 2))
gm_hook_behavior(id_bhvKingBobomb, false, obj_king_bobomb_hitbox)
gm_hook_behavior(id_bhvBowser, false, obj_generate_health_func(HEALTH_BOWSER))
gm_hook_behavior(id_bhvStaticObject, false, obj_skip_in_view_check)
hook_chat_command("gm", "\\#00ffff\\[fp|fov|give]\\#7f7f7f\\ (leave blank to toggle Gun Mod on or off)", on_gm_command)
-- matches the function(s) below
for i = 0, MAX_PLAYERS - 1 do
gPlayerSyncTable[i].curWeapon = WEAPON_MAGNUM
gPlayerSyncTable[i].curWeapon2 = WEAPON_PISTOL
end
pickup_weapon(WEAPON_MAGNUM)
pickup_weapon(WEAPON_PISTOL)