diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index df94b4ef..e42ab363 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -748,7 +748,6 @@ --- @field public unkC4 number --- @field public usedObj Object --- @field public vel Vec3f ---- @field public visibleToEnemies integer --- @field public wall Surface --- @field public wallKickTimer integer --- @field public wallNormal Vec3f diff --git a/docs/lua/structs.md b/docs/lua/structs.md index 5ccc57d9..1a4456ad 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -1071,7 +1071,6 @@ | unkC4 | `number` | | | usedObj | [Object](structs.md#Object) | | | vel | [Vec3f](structs.md#Vec3f) | read-only | -| visibleToEnemies | `integer` | | | wall | [Surface](structs.md#Surface) | | | wallKickTimer | `integer` | | | wallNormal | [Vec3f](structs.md#Vec3f) | read-only | diff --git a/mods/counter-op.lua b/mods/counter-op.lua deleted file mode 100644 index 75d2c106..00000000 --- a/mods/counter-op.lua +++ /dev/null @@ -1,88 +0,0 @@ --- name: Counter-Op --- description: All players except the host will try to kill the host - -gServerSettings.playerInteractions = PLAYER_INTERACTIONS_PVP - -function get_main_character() - local np = network_player_from_global_index(0) - if np == nil then - np = gNetworkPlayers[0] - end - return gMarioStates[np.localIndex] -end - -function is_main_character(m) - local main = get_main_character() - return m.playerIndex == main.playerIndex -end - -function does_level_match(m1, m2) - local np1 = gNetworkPlayers[m1.playerIndex] - local np2 = gNetworkPlayers[m2.playerIndex] - if np1.currActNum ~= np2.currActNum then - return false - end - if np1.currAreaIndex ~= np2.currAreaIndex then - return false - end - if np1.currCourseNum ~= np2.currCourseNum then - return false - end - if np1.currLevelNum ~= np2.currLevelNum then - return false - end - return true -end - -function mario_update_local(m) - if not is_main_character(m) then - local main = get_main_character() - local mainNp = gNetworkPlayers[main.playerIndex] - --print('>>>', mainNp.globalIndex, mainNp.currAreaSyncValid, mainNp.currLevelSyncValid) - --if mainNp.currAreaSyncValid and mainNp.currLevelSyncValid then - if not does_level_match(m, main) then - warp_to_level(mainNp.currLevelNum, mainNp.currAreaIndex, mainNp.currActNum) - end - --end - end -end - -function mario_update(m) - if m.playerIndex == 0 then - mario_update_local(m) - end - - local np = gNetworkPlayers[m.playerIndex] - if is_main_character(m) then - m.visibleToEnemies = 1 - if np.modelIndex == CT_TOAD then - np.overrideModelIndex = CT_MARIO - end - else - m.visibleToEnemies = 0 - if np.modelIndex ~= CT_TOAD then - np.overrideModelIndex = CT_TOAD - end - end -end - -function allow_pvp_attack(m1, m2) - return m1.visibleToEnemies ~= m2.visibleToEnemies -end - -function allow_interact(m, obj, interactType) - if not is_main_character(m) then - if (interactType & INTERACT_WARP) ~= 0 then return true end - if (interactType & INTERACT_WARP_DOOR) ~= 0 then return true end - if (interactType & INTERACT_STRONG_WIND) ~= 0 then return true end - if (interactType & INTERACT_BBH_ENTRANCE) ~= 0 then return true end - if (interactType & INTERACT_PLAYER) ~= 0 then return true end - return false - end - - return true -end - -hook_event(HOOK_ALLOW_INTERACT, allow_interact) -hook_event(HOOK_ALLOW_PVP_ATTACK, allow_pvp_attack) -hook_event(HOOK_MARIO_UPDATE, mario_update) \ No newline at end of file diff --git a/mods/nametags.lua b/mods/nametags.lua new file mode 100644 index 00000000..3e56bd77 --- /dev/null +++ b/mods/nametags.lua @@ -0,0 +1,172 @@ +-- name: Nametags +-- incompatible: nametags +-- description: Nametags\nBy \\#ec7731\\Agent X\\#ffffff\\\n\nThis mod adds nametags to sm64ex-coop, this helps to easily identify other players without the player list, nametags can toggled with \\#ffff00\\/nametags [on|off]\\#ffffff\\ + +MAX_SCALE = 0.32 + +gGlobalSyncTable.nametags = true +gGlobalSyncTable.dist = 7000 + +for k, v in pairs(gActiveMods) do + local name = v.name:lower() + if v.enabled and (name:find("hide") or name:find("hns") or name:find("hunt")) then + gGlobalSyncTable.nametags = false + end +end + +function clamp(x, a, b) + if x < a then return a end + if x > b then return b end + return x +end + +--- @param m MarioState +function active_player(m) + local np = gNetworkPlayers[m.playerIndex] + if m.playerIndex == 0 then + return 1 + end + if not np.connected then + return 0 + end + if np.currCourseNum ~= gNetworkPlayers[0].currCourseNum then + return 0 + end + if np.currActNum ~= gNetworkPlayers[0].currActNum then + return 0 + end + if np.currLevelNum ~= gNetworkPlayers[0].currLevelNum then + return 0 + end + if np.currAreaIndex ~= gNetworkPlayers[0].currAreaIndex then + return 0 + end + return is_player_active(m) +end + +function if_then_else(cond, if_true, if_false) + if cond then return if_true end + return if_false +end + +function djui_hud_set_adjusted_color(r, g, b, a) + local multiplier = 1 + if is_game_paused() then multiplier = 0.5 end + djui_hud_set_color(r * multiplier, g * multiplier, b * multiplier, a) +end + +function djui_hud_print_outlined_text(text, x, y, scale, r, g, b, outlineDarkness) + -- render outline + djui_hud_set_adjusted_color(r * outlineDarkness, g * outlineDarkness, b * outlineDarkness, 255) + djui_hud_print_text(text, x - (1*(scale*2)), y, scale) + djui_hud_print_text(text, x + (1*(scale*2)), y, scale) + djui_hud_print_text(text, x, y - (1*(scale*2)), scale) + djui_hud_print_text(text, x, y + (1*(scale*2)), scale) + -- render text + djui_hud_set_adjusted_color(r, g, b, 255) + djui_hud_print_text(text, x, y, scale) + djui_hud_set_color(255, 255, 255, 255) +end + +function name_and_hex(name) + local nameTable = {} + name:gsub(".", function(c) table.insert(nameTable, c) end) + + local removed = false + local color = "000000" + for k, v in pairs(nameTable) do + if v == "\\" and not removed then + removed = true + nameTable[k] = "" -- \ + nameTable[k + 1] = "" -- # + if nameTable[k + 2] ~= nil and nameTable[k + 3] ~= nil and nameTable[k + 4] ~= nil and nameTable[k + 5] ~= nil and nameTable[k + 6] ~= nil and nameTable[k + 7] ~= nil then + color = nameTable[k + 2] .. nameTable[k + 3] .. nameTable[k + 4] .. nameTable[k + 5] .. nameTable[k + 6] .. nameTable[k + 7] + end + nameTable[k + 2] = "" -- f + nameTable[k + 3] = "" -- f + nameTable[k + 4] = "" -- f + nameTable[k + 5] = "" -- f + nameTable[k + 6] = "" -- f + nameTable[k + 7] = "" -- f + nameTable[k + 8] = "" -- \ + end + end + return { name = table.concat(nameTable, ""), color = color } +end + +function hex_to_rgb(hex) + local hexTable = {} + hex:gsub("..", function(c) table.insert(hexTable, c) end) + return { r = tonumber(hexTable[1], 16), g = tonumber(hexTable[2], 16), b = tonumber(hexTable[3], 16) } +end + +showSelfTag = false +function on_hud_render() + if not gGlobalSyncTable.nametags or not gNetworkPlayers[0].currAreaSyncValid or obj_get_first_with_behavior_id(id_bhvActSelector) ~= nil then return end + + djui_hud_set_resolution(RESOLUTION_N64) + djui_hud_set_font(FONT_NORMAL) + + for i = if_then_else(showSelfTag, 0, 1), network_player_connected_count() - 1 do + local m = gMarioStates[i] + if active_player(m) ~= 0 then + if m.playerIndex == 0 and (m.input & INPUT_FIRST_PERSON) ~= 0 then return end + local out = { x = 0, y = 0, z = 0 } + local pos = { x = m.marioObj.header.gfx.pos.x, y = m.marioBodyState.headPos.y + 120, z = m.marioObj.header.gfx.pos.z } + djui_hud_world_pos_to_screen_pos(pos, out) + + local scale = MAX_SCALE + if m.playerIndex ~= 0 and vec3f_dist(gMarioStates[0].pos, m.pos) > 1000 then + scale = 0.5 + scale = scale + vec3f_dist(gMarioStates[0].pos, m.pos) / gGlobalSyncTable.dist + scale = clamp(1 - scale, 0, MAX_SCALE) + end + local info = name_and_hex(gNetworkPlayers[i].name) + local color = { r = 162, g = 202, b = 234 } + network_player_palette_to_color(gNetworkPlayers[i], SHIRT, color) + local measure = djui_hud_measure_text(info.name) * scale * 0.5 + djui_hud_print_outlined_text(info.name, out.x - measure, out.y, scale, color.r, color.g, color.b, 0.25) + end + end +end + +function on_nametags_command(msg) + if msg == "on" then + gGlobalSyncTable.nametags = true + djui_chat_message_create("Nametag status: \\#00ff00\\ON") + else + gGlobalSyncTable.nametags = false + djui_chat_message_create("Nametag status: \\#ff0000\\OFF") + end + return true +end + +function on_nametag_distance_command(msg) + if tonumber(msg) ~= nil then + djui_chat_message_create("Set distance to " .. msg) + gGlobalSyncTable.dist = tonumber(msg) + else + djui_chat_message_create("\\#ff0000\\Failed to set distance to " .. msg) + end + return true +end + +function on_show_my_tag_command(msg) + if msg == "on" then + showSelfTag = true + djui_chat_message_create("Show my tag status: \\#00ff00\\ON") + else + showSelfTag = false + djui_chat_message_create("Show my tag status: \\#ff0000\\OFF") + end + return true +end + +hook_event(HOOK_ON_HUD_RENDER, on_hud_render) + +if network_is_server() then + hook_chat_command("nametags", "[on|off] to turn nametags on or off, default is \\#00ff00\\ON", on_nametags_command) + hook_chat_command("nametag-distance", "[number] set the distance at which nametags disappear, default is 7000", on_nametag_distance_command) +end + +hook_chat_command("show-my-tag", "[on|off] to turn your own nametag on or off, default is \\#ff0000\\OFF", on_show_my_tag_command) diff --git a/mods/personal-starcount-ex.lua b/mods/personal-starcount-ex.lua new file mode 100644 index 00000000..0a720804 --- /dev/null +++ b/mods/personal-starcount-ex.lua @@ -0,0 +1,155 @@ +-- name: Personal Star Counter EX+ +-- description: See how many stars you collect!\nIdea by Mr.Needlemouse, created by Sunk\n\nModified by Demnyx. +if mod_storage_load("StarCounter") == nil then + mod_storage_save("StarCounter", "0") +end + +local TotalStarCounter = tonumber(mod_storage_load("StarCounter")) +local StarCounter = 0 +local prevNumStars = 0 + +local screenHeight = 0 +local screenWidth = 0 + +local psToggle = 1 + +---@param m MarioState +--Increments an independent counter if a star is collected. +function localStarCounter(m, o, type) + if (m.playerIndex == 0) and (type == INTERACT_STAR_OR_KEY) then + --This ensures that it increments ONLY if a star is collected. + if get_id_from_behavior(o.behavior) ~= id_bhvBowserKey then + --The hook happens after the star count increments, so this allows the independent counter to increment ONLY when YELLOW star is collected. + if m.numStars ~= prevNumStars then + StarCounter = StarCounter + 1 + TotalStarCounter = TotalStarCounter + 1 + mod_storage_save("StarCounter", tostring(TotalStarCounter)) + end + end + end +end + +-- Hud alpha stuff from Agent X +function djui_hud_set_adjusted_color(r, g, b, a) + local multiplier = 1 + if is_game_paused() then multiplier = 0.5 end + djui_hud_set_color(r * multiplier, g * multiplier, b * multiplier, a) +end + +function displayStarCounter() + local m = gMarioStates[0] + if psToggle ~= 1 then return end + if obj_get_first_with_behavior_id(id_bhvActSelector) ~= nil + or (m.action == ACT_END_PEACH_CUTSCENE + or m.action == ACT_CREDITS_CUTSCENE + or m.action == ACT_END_WAVING_CUTSCENE) then return end + + djui_hud_set_resolution(RESOLUTION_N64) + djui_hud_set_font(FONT_HUD) + + --I don't want to put this in a seperate function, there's not enough code for it to be worth it. + if m.playerIndex == 0 then + prevNumStars = m.numStars + else + return + end + + screenHeight = djui_hud_get_screen_height() + screenWidth = djui_hud_get_screen_width() + + if a == nil then + a = 255 + end + + if obj_get_first_with_behavior_id(id_bhvActSelector) ~= nil then + if a <= 255 and a > 32 then + a = a - 40 + else + a = 0 + end + else + if a >= 0 and a < 215 then + a = a + 16 + else + a = 255 + end + end + + local timerValFrames = hud_get_value(HUD_DISPLAY_TIMER) + local timerX = 0 + local timerY = 0 + + -- Move HUD graphics away from the TIMER HUD + if timerValFrames ~= 0 then + timerX = 60 + timerY = 17 + end + + --Normal personal star counter + if StarCounter >= 100 then + djui_hud_set_adjusted_color(255, 246, 0, a) + djui_hud_print_text(tostring(StarCounter), screenWidth - 61 - timerX, screenHeight - 208 - timerY, 1) + djui_hud_set_adjusted_color(232, 17, 35, a) + djui_hud_render_texture(gTextures.star, screenWidth - 77 - timerX, screenHeight - 208 - timerY, 1, 1) + else + djui_hud_set_adjusted_color(246, 246, 246, a) + djui_hud_print_text(tostring("X"), screenWidth - 61 - timerX, screenHeight - 208 - timerY, 1) + djui_hud_set_adjusted_color(255, 246, 0, a) + djui_hud_print_text(tostring(StarCounter), screenWidth - 46.8 - timerX, screenHeight - 208 - timerY, 1) + djui_hud_set_adjusted_color(232, 17, 35, a) + djui_hud_render_texture(gTextures.star, screenWidth - 77 - timerX, screenHeight - 208 - timerY, 1, 1) + end + + --Total star counter + if timerValFrames ~= 0 then + timerX = 0 + timerY = -10 + end + + local perceived_total_counter = TotalStarCounter + local milestone_counter = 0 + while perceived_total_counter >= 10000 do + perceived_total_counter = perceived_total_counter - 10000 + milestone_counter = milestone_counter + 1 + end + + if perceived_total_counter >= 100 then + djui_hud_set_adjusted_color(255, 246, 0, a) + djui_hud_print_text(tostring(perceived_total_counter), screenWidth - 61 - timerX, screenHeight - 190 - timerY, 1) + djui_hud_set_adjusted_color(50, 176, 40, a) + djui_hud_render_texture(gTextures.star, screenWidth - 77 - timerX, screenHeight - 190 - timerY, 1, 1) + if milestone_counter > 0 then + djui_hud_set_adjusted_color(246, 246, 246, a) + djui_hud_print_text(string.format("x%d", milestone_counter), screenWidth - 77 - timerX, screenHeight - 174 - timerY, 0.5) + end + else + djui_hud_set_adjusted_color(246, 246, 246, a) + djui_hud_print_text(tostring("X"), screenWidth - 61 - timerX, screenHeight - 190 - timerY, 1) + djui_hud_set_adjusted_color(255, 246, 0, a) + djui_hud_print_text(tostring(perceived_total_counter), screenWidth - 46.8 - timerX, screenHeight - 190 - timerY, 1) + djui_hud_set_adjusted_color(50, 176, 40, a) + djui_hud_render_texture(gTextures.star, screenWidth - 77 - timerX, screenHeight - 190 - timerY, 1, 1) + if milestone_counter > 0 then + djui_hud_set_adjusted_color(246, 246, 246, a) + djui_hud_print_text(string.format("x%d", milestone_counter), screenWidth - 77 - timerX, screenHeight - 174 - timerY, 0.5) + end + end + --StarCounter = 120 +end + +function PSToggle(msg) + if msg == string.lower("On") or msg == "1" then + psToggle = 1 + return true + elseif msg == string.lower("Off") or msg == "0" then + psToggle = 0 + return true + end +end + +--------- +--Hooks-- +--------- +hook_event(HOOK_ON_INTERACT, localStarCounter) +hook_event(HOOK_ON_HUD_RENDER, displayStarCounter) +hook_chat_command('pstoggle', 'On|Off - Displays stars you"ve collected. Default is On.', PSToggle) \ No newline at end of file diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index 25c5ad4b..9b0e0716 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -787,7 +787,7 @@ static struct LuaObjectField sMarioBodyStateFields[LUA_MARIO_BODY_STATE_FIELD_CO { "wingFlutter", LVT_S8, offsetof(struct MarioBodyState, wingFlutter), false, LOT_NONE }, }; -#define LUA_MARIO_STATE_FIELD_COUNT 77 +#define LUA_MARIO_STATE_FIELD_COUNT 76 static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = { { "action", LVT_U32, offsetof(struct MarioState, action), false, LOT_NONE }, { "actionArg", LVT_U32, offsetof(struct MarioState, actionArg), false, LOT_NONE }, @@ -860,7 +860,6 @@ static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = { { "unkC4", LVT_F32, offsetof(struct MarioState, unkC4), false, LOT_NONE }, { "usedObj", LVT_COBJECT_P, offsetof(struct MarioState, usedObj), false, LOT_OBJECT }, { "vel", LVT_COBJECT, offsetof(struct MarioState, vel), true, LOT_VEC3F }, - { "visibleToEnemies", LVT_U8, offsetof(struct MarioState, visibleToEnemies), false, LOT_NONE }, { "wall", LVT_COBJECT_P, offsetof(struct MarioState, wall), false, LOT_SURFACE }, { "wallKickTimer", LVT_U8, offsetof(struct MarioState, wallKickTimer), false, LOT_NONE }, { "wallNormal", LVT_COBJECT, offsetof(struct MarioState, wallNormal), true, LOT_VEC3F },