-- name: Snowy's cool Things! -- category: utility, qol -- description: Adds Free commands! ---------------- -- Chat Logic -- ---------------- gGlobalSyncTable.chat_toggle = false local function on_chat_toggle() if network_is_server() then gGlobalSyncTable.chat_toggle = not gGlobalSyncTable.chat_toggle if gGlobalSyncTable.chat_toggle == false then djui_chat_message_create("Chat toggled \\#f55\\off.") elseif gGlobalSyncTable.chat_toggle == true then djui_chat_message_create("Chat toggled \\#5f5\\on.") end else djui_chat_message_create("\\#f55\\Server host only!") end return true end local function on_chat_message() if gGlobalSyncTable.chat_toggle == false then djui_chat_message_create("Chat is currently \\#f55\\off.") return false elseif gGlobalSyncTable.chat_toggle == true then return true end end hook_event(HOOK_ON_CHAT_MESSAGE, on_chat_message) hook_chat_command("chat", "- Toggles chat", on_chat_toggle) --------------- -- Tag Logic -- --------------- local function on_tag(msg) if not network_is_server() then djui_chat_message_create("\\#f55\\Server host only!") return true end local args = {} for word in string.gmatch(msg, "[^%s]+") do table.insert(args, word) end if #args < 6 then djui_chat_message_create("\\#ff0\\Usage: /tag [id] [tag] [red] [green] [blue] [alpha]") return true end local player_id = tonumber(args[1]) local description = args[2] local r = tonumber(args[3]) or 255 local g = tonumber(args[4]) or 255 local b = tonumber(args[5]) or 255 local a = tonumber(args[6]) or 255 if not player_id or player_id < 0 or player_id >= MAX_PLAYERS then djui_chat_message_create("\\#f55\\Invalid ID.") return true end local np = gNetworkPlayers[player_id] if not np or not np.connected then djui_chat_message_create("\\#f55\\Player not found.") return true end network_player_set_description(np, description, r, g, b, a) djui_chat_message_create("\\#5f5\\Set tag for \\#dcdcdc\\" .. gNetworkPlayers[player_id].name) return true end hook_chat_command("tag", "[id] [tag] [red] [green] [blue] [alpha] - Puts a tag on a player in the player list", on_tag) -------------------- -- Announce Logic -- -------------------- local PADDING_X = 40 local PADDING_Y = 20 local TEXT_Y_OFFSET = 0 local display_timer = 0 local fade_duration = 15 gGlobalSyncTable.announcementText = "" gGlobalSyncTable.announcementMaxTime = 150 gGlobalSyncTable.announcementTrigger = 0 function cmd_announce(msg) if not network_is_server() then djui_chat_message_create("Error: Only the host can use /announce!") return true end local text, secStr = msg:match("^(.*)%s+(%d+)$") if not text or not secStr then djui_chat_message_create("Use: /announce [message] [seconds]") return true end gGlobalSyncTable.announcementText = text gGlobalSyncTable.announcementMaxTime = tonumber(secStr) * 30 gGlobalSyncTable.announcementTrigger = gGlobalSyncTable.announcementTrigger + 1 return true end hook_chat_command("announce", "[MSG] [SECONDS] - Announces a message to the server", cmd_announce) local last_trigger = 0 function watch_network_announcements() if gGlobalSyncTable.announcementTrigger ~= last_trigger then last_trigger = gGlobalSyncTable.announcementTrigger display_timer = gGlobalSyncTable.announcementMaxTime end end hook_event(HOOK_UPDATE, watch_network_announcements) function custom_announcer_render() local text_to_show = gGlobalSyncTable.announcementText if display_timer > 0 and text_to_show ~= "" then display_timer = display_timer - 1 local alpha = 160 local text_alpha = 255 if display_timer < fade_duration then local fade_scale = display_timer / fade_duration alpha = 160 * fade_scale text_alpha = 255 * fade_scale end djui_hud_set_font(FONT_NORMAL) local text_width = djui_hud_measure_text(text_to_show) local text_height = 16 local box_width = text_width + (PADDING_X * 2) local box_height = text_height + (PADDING_Y * 2) local screen_width = djui_hud_get_screen_width() local box_x = (screen_width - box_width) / 2 local box_y = 20 djui_hud_set_color(0, 0, 0, alpha) djui_hud_render_rect(box_x, box_y, box_width, box_height) local text_x = box_x + PADDING_X local text_y = box_y + PADDING_Y + TEXT_Y_OFFSET djui_hud_set_color(255, 255, 255, text_alpha) djui_hud_print_text(text_to_show, text_x, text_y, 1) end end hook_event(HOOK_ON_HUD_RENDER, custom_announcer_render) ----------------- -- Color Logic -- ----------------- local function split_arguments(input_string) local args = {} for word in input_string:gmatch("%S+") do table.insert(args, word) end return args end local function hex_to_rgb(hex) hex = hex:gsub("#", "") if #hex ~= 6 then return nil end return { r = tonumber(hex:sub(1, 2), 16), g = tonumber(hex:sub(3, 4), 16), b = tonumber(hex:sub(5, 6), 16) } end function on_color_command(msg) if network_is_server() or network_is_moderator() then local args = split_arguments(msg) local target_id = tonumber(args[1]) local part_id = tonumber(args[2]) local hex_string = args[3] if not target_id or not part_id or not hex_string then djui_chat_message_create("Usage: /color [id] [part] [hex]") return true end local np = network_player_from_global_index(target_id) if not np or not np.connected then djui_chat_message_create("Who?this player is not found.") return true end local rgb_color = hex_to_rgb(hex_string) if not rgb_color then djui_chat_message_create("Hex only!") return true end network_player_set_override_palette_color(np, part_id, rgb_color) djui_chat_message_create("Success!") else djui_chat_message_create("No permission.") end return true end function on_resetcolor_command(msg) if network_is_server() or network_is_moderator() then local args = split_arguments(msg) local target_id = tonumber(args[1]) if not target_id then djui_chat_message_create("Usage: /resetcolor [id]") return true end local np = network_player_from_global_index(target_id) if not np or not np.connected then djui_chat_message_create("Who?this player is not found.") return true end network_player_reset_override_palette(np) djui_chat_message_create("Player color reset successfully.") else djui_chat_message_create("No permission.") end return true end function on_color_help() djui_chat_message_create("Parts: 0 - Overalls, 1 - Shirt, 2 - Gloves, 3 - Shoes, 4 - Hair, 5 - Skin, 6 - Cap, 7 - Emblem, 8 - PLAYER_PART_MAX") djui_chat_message_create("You have to use the numeric ID when typing the part argument.") return true end hook_chat_command("color", "[id] [part - 0|1|2|3|4|5|6|7|8] [hex] - Override a player's color.", on_color_command) hook_chat_command("colorhelp", "- Lists parts for color command.", on_color_help) hook_chat_command("resetcolor", "[id] - Reset a player's color", on_resetcolor_command) ---------------- -- Join logic -- ---------------- local server_started_announced = false local join_timers = {} local function on_packet_receive(packet) if packet.purpose == "chat_msg" then djui_chat_message_create(packet.message) end end local function broadcast_network_message(text) djui_chat_message_create(text) local packet = { purpose = "chat_msg", message = text } network_send(true, packet) end local function on_player_connected(m) if not m or m.playerIndex == 0 then return end join_timers[m.playerIndex] = 6 end local function update_join_timers() if not server_started_announced then local hostPlayer = gNetworkPlayers[0] if hostPlayer and hostPlayer.name and hostPlayer.name ~= "" then if network_is_server() then return true end server_started_announced = true end end for i = 1, MAX_PLAYERS - 1 do if join_timers[i] and join_timers[i] > 0 then join_timers[i] = join_timers[i] - 1 if join_timers[i] == 0 then local np = gNetworkPlayers[i] if np and np.connected then local joined_name = (np.name and np.name ~= "") and np.name or "A player" if network_is_server() then broadcast_network_message("\\#ffff55\\" .. joined_name .. " \\#ffff55\\connected.") end end join_timers[i] = nil end end end end local function on_player_disconnected(m) if not m then return end join_timers[m.playerIndex] = nil local np = gNetworkPlayers[m.playerIndex] if np then local player_name = (np.name and np.name ~= "") and np.name or "A player" if network_is_server() then broadcast_network_message("\\#55ffff\\" .. player_name .. " \\#55ffff\\disconnected.") end end end hook_event(HOOK_ON_PLAYER_CONNECTED, on_player_connected) hook_event(HOOK_ON_PLAYER_DISCONNECTED, on_player_disconnected) hook_event(HOOK_UPDATE, update_join_timers) hook_event(HOOK_ON_PACKET_RECEIVE, on_packet_receive) ---------------- -- Warp LOGIC -- ---------------- function do_nothing() return true end local level_map = { ["bob"] = LEVEL_BOB, ["wf"] = LEVEL_WF, ["jrb"] = LEVEL_JRB, ["ccm"] = LEVEL_CCM, ["bbh"] = LEVEL_BBH, ["hmc"] = LEVEL_HMC, ["lll"] = LEVEL_LLL, ["ssl"] = LEVEL_SSL, ["ddd"] = LEVEL_DDD, ["sl"] = LEVEL_SL, ["wdw"] = LEVEL_WDW, ["ttm"] = LEVEL_TTM, ["thi"] = LEVEL_THI, ["ttc"] = LEVEL_TTC, ["rr"] = LEVEL_RR, ["bitdw"] = LEVEL_BITDW, ["bitfs"] = LEVEL_BITFS, ["bits"] = LEVEL_BITS, ["main"] = LEVEL_CASTLE, ["cg"] = LEVEL_CASTLE_GROUNDS, ["cy"] = LEVEL_CASTLE_COURTYARD, } local function on_warp_chat_command(msg) if not gNetworkPlayers[0] or not gNetworkPlayers[0].connected then return false end local args = {} for arg in string.gmatch(msg, "%S+") do table.insert(args, arg) end if #args == 0 then do_nothing() return true end local target_level = string.lower(args[1]) local target_act = 0 -- Default strictly to Act 0 if unspecified if args[2] then local parsed_act = tonumber(args[2]) if parsed_act then target_act = parsed_act else do_nothing() end end local level_id = level_map[target_level] if level_id then warp_to_level(level_id, 1, target_act) do_nothing() return true else djui_chat_message_create("\\#f55\\Invalid level!") return true end end hook_chat_command("warp", "[level_name] [act] - Warps you to a specific stage and act", on_warp_chat_command)