Skip to content

Commit

Permalink
F1 menu: Added Option to Change Maps via the F1 Menu (#1512)
Browse files Browse the repository at this point in the history
This adds the option for admins to change the currently played map while
also starting an admin commands menu. This makes use of the combo cards
added in #1511.


![image](https://github.com/TTT-2/TTT2/assets/13639408/15eb3fdf-e471-4610-a9b3-b56e97bc424b)


![image](https://github.com/TTT-2/TTT2/assets/13639408/ce814f76-aa30-4424-80d7-d4a40870ecd0)


![image](https://github.com/TTT-2/TTT2/assets/13639408/cb6ce1ad-d113-406c-b91a-1578c827cf9f)

One thing that was added, is a hook that is called, once a client
finished the hot reload. This is needed so that the server knows when
the client is ready to resend the data:
```lua
---
-- Called when a player is ready again after they reloaded their game. Can be used to send
-- data that is needed after a reload.
-- @param Player ply The player that finished the reloading
-- @hook
-- @realm server
function GM:TTT2PlayerFinishedReloading(ply)
```

This PR also greatly extended the `map` module which can also then be
used by other addons. Details can be checked in the changed files, but
most notably are these additions:

This function returns a cached material for a given map. This also
includes maps that don't have a material. Since this works by
downloading these materials from steam, this system works as long as the
map is installed via the workshop and the workshop page has a preview
image.
```lua
---
-- Returns the cached icon of a map if there is an icon available.
-- @note This not only uses the icons available on the client through addons, it also
-- searches the workshop and tries to assign the corrent workshop icon if there
-- is no locally available map icon.
-- @param string name The map name
-- @return nil|IMaterial Returns the cached material if available
-- @realm client
function map.GetIcon(name)
```

This function returns a list of all available maps. It already excludes
those maps, where the prefix was disabled in the admin settings. This
can be used in map mote addons as a map base.
```lua
---
-- Returns a sanitized list of maps installed on the server. Sanitized means that only
-- valid maps with a prefix that is enabled are listed here. This list is automatically
-- synced between the server and all clients.
-- @return table Returns a table with the map names
-- @realm shared
function map.GetList()
```
  • Loading branch information
TimGoll committed May 20, 2024
1 parent af4aef4 commit 79b20d4
Show file tree
Hide file tree
Showing 18 changed files with 404 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ All notable changes to TTT2 will be documented here. Inspired by [keep a changel
- Added a new generic button to F1 menu elements to be used in custom menus (by @TimGoll)
- Added toggle and run buttons to many F1 menu elements (by @TimGoll)
- Added combo cards to the UI, clickable cards that act like combo boxes (by @TimGoll)
- Added a new admin commands menu (by @TimGoll)
- Added a submenu to change maps

### Changed

Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"UnlitGeneric"
{
"$basetexture" "vgui/ttt/vskin/helpscreen/commands"
"$nocull" 1
"$nodecal" 1
"$nolod" 1
"$translucent" 1
"$vertexalpha" 1
"$vertexcolor" 1
}
Binary file not shown.
4 changes: 4 additions & 0 deletions gamemodes/terrortown/gamemode/client/cl_main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,10 @@ function GM:OnReloaded()
GetConVar("ttt2_enable_dynamic_fov"):GetBool()
)

-- notify the server that the client finished reloading
net.Start("TTT2FinishedReloading")
net.SendToServer()

---
-- @realm shared
-- stylua: ignore
Expand Down
21 changes: 20 additions & 1 deletion gamemodes/terrortown/gamemode/server/sv_main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ ttt_include("sv_addonchecker")
ttt_include("sv_roleselection")
ttt_include("sh_rolelayering")

include("ttt2/libraries/map.lua")
include("ttt2/libraries/entspawn.lua")
include("ttt2/libraries/plyspawn.lua")
include("ttt2/libraries/entity_outputs.lua")
Expand Down Expand Up @@ -286,6 +285,7 @@ util.AddNetworkString("TTT2OrderEquipment")
util.AddNetworkString("TTT2RoleGlobalVoice")
util.AddNetworkString("TTT2MuteTeam")
util.AddNetworkString("TTT2UpdateHoldAimConvar")
util.AddNetworkString("TTT2FinishedReloading")

-- provide menu files by loading them from here:
fileloader.LoadFolder("terrortown/menus/score/", false, CLIENT_FILE)
Expand Down Expand Up @@ -1436,6 +1436,8 @@ function GM:OnReloaded()
-- reload everything from the playermodels
playermodels.Initialize()

map.InitializeList()

-- set the default random playermodel
self.playermodel = playermodels.GetRandomPlayerModel()
self.playercolor = COLOR_WHITE
Expand Down Expand Up @@ -1531,6 +1533,13 @@ local function ttt_toggle_newroles(ply)
end
concommand.Add("ttt_toggle_newroles", ttt_toggle_newroles)

net.Receive("TTT2FinishedReloading", function(_, ply)
---
-- @realm server
-- stylua: ignore
hook.Run("TTT2PlayerFinishedReloading", ply)
end)

---
-- This hook is used to sync the global networked vars. It is run in @{GM:SyncGlobals} after the
-- TTT2 globals are synced.
Expand Down Expand Up @@ -1680,3 +1689,13 @@ function GM:TTTCheckForWin()
return TEAM_NONE -- none_win
end
end

---
-- Called when a player is ready again after they reloaded their game. Can be used to send
-- data that is needed after a reload.
-- @param Player ply The player that finished the reloading
-- @hook
-- @realm server
function GM:TTT2PlayerFinishedReloading(ply)
map.SyncToClient(ply)
end
2 changes: 2 additions & 0 deletions gamemodes/terrortown/gamemode/server/sv_player_ext.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1679,6 +1679,8 @@ local function SetPlayerReady(_, ply)

entspawnscript.TransmitToPlayer(ply)

map.SyncToClient(ply)

---
-- @realm server
-- stylua: ignore
Expand Down
1 change: 1 addition & 0 deletions gamemodes/terrortown/gamemode/shared/sh_init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ include("ttt2/extensions/chat.lua")
include("ttt2/extensions/sound.lua")

-- include libraries
include("ttt2/libraries/map.lua")
include("ttt2/libraries/none.lua")
include("ttt2/libraries/fastutf8.lua")
include("ttt2/libraries/huds.lua")
Expand Down
11 changes: 11 additions & 0 deletions lua/terrortown/lang/en.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2252,3 +2252,14 @@ When shopping roles die, their credits can be picked up by other players with sh
When this option is disabled, only players that can pick up credits can see them on a body.
When enabled, all players can see credits on a body.]]

-- 2024-05-13
L.menu_commands_title = "Admin Commands"
L.menu_commands_description = "Change maps, spawn bots and edit player roles."

L.submenu_commands_maps_title = "Maps"

L.header_maps_prefixes = "Enable/Disable Maps by their Prefix"
L.header_maps_select = "Select and Change Maps"

L.button_change_map = "Change Map"
12 changes: 12 additions & 0 deletions lua/terrortown/menus/gamemode/commands.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--- @ignore

CLGAMEMODEMENU.base = "base_gamemodemenu"

CLGAMEMODEMENU.icon = Material("vgui/ttt/vskin/helpscreen/commands")
CLGAMEMODEMENU.title = "menu_commands_title"
CLGAMEMODEMENU.description = "menu_commands_description"
CLGAMEMODEMENU.priority = 49

function CLGAMEMODEMENU:IsAdminMenu()
return true
end
67 changes: 67 additions & 0 deletions lua/terrortown/menus/gamemode/commands/maps.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
--- @ignore

CLGAMEMODESUBMENU.base = "base_gamemodesubmenu"

CLGAMEMODESUBMENU.priority = 100
CLGAMEMODESUBMENU.title = "submenu_commands_maps_title"

local comboBase

function CLGAMEMODESUBMENU:Populate(parent)
local prefixes = map.GetPrefixes()
local maps = map.GetList()

local form = vgui.CreateTTT2Form(parent, "header_maps_prefixes")

for i = 1, #prefixes do
form:MakeCheckBox({
label = prefixes[i],
serverConvar = "ttt2_enable_map_prefix_" .. prefixes[i],
OnChange = function(_, value)
-- set global bool on the client to bridge network delay
SetGlobalBool("ttt2_enable_map_prefix_" .. prefixes[i], value)

vguihandler.Rebuild()
end,
})
end

local form2 = vgui.CreateTTT2Form(parent, "header_maps_select")

-- Create combo boxes to select element from
comboBase = form2:MakeIconLayout()

for i = 1, #maps do
local mapName = maps[i]
local prefix = map.GetPrefix(mapName)

form2:MakeComboCard({
icon = map.GetIcon(mapName),
label = mapName,
tag = prefix,
colorTag = util.StringToColor(prefix or ""),
}, comboBase)
end
end

function CLGAMEMODESUBMENU:PopulateButtonPanel(parent)
local buttonChange = vgui.Create("DButtonTTT2", parent)

buttonChange:SetText("button_change_map")
buttonChange:SetSize(175, 45)
buttonChange:SetPos(parent:GetWide() - 195, 20)
buttonChange.DoClick = function(btn)
if not comboBase.checked then
return
end

local mapName = comboBase.checked:GetText()

map.ChangeLevel(mapName)
end
buttonChange:SetEnabled(true)
end

function CLGAMEMODESUBMENU:HasButtonPanel()
return true
end
2 changes: 1 addition & 1 deletion lua/terrortown/menus/gamemode/equipment.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ CLGAMEMODEMENU.base = "base_gamemodemenu"
CLGAMEMODEMENU.icon = Material("vgui/ttt/vskin/helpscreen/equipment")
CLGAMEMODEMENU.title = "menu_equipment_title"
CLGAMEMODEMENU.description = "menu_equipment_description"
CLGAMEMODEMENU.priority = 49
CLGAMEMODEMENU.priority = 48

CLGAMEMODEMENU.isInitialized = false
CLGAMEMODEMENU.langConVar = nil
Expand Down
2 changes: 1 addition & 1 deletion lua/terrortown/menus/gamemode/roles.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ CLGAMEMODEMENU.base = "base_gamemodemenu"
CLGAMEMODEMENU.icon = Material("vgui/ttt/vskin/helpscreen/roles")
CLGAMEMODEMENU.title = "menu_roles_title"
CLGAMEMODEMENU.description = "menu_roles_description"
CLGAMEMODEMENU.priority = 47
CLGAMEMODEMENU.priority = 46

CLGAMEMODEMENU.isInitialized = false
CLGAMEMODEMENU.roles = nil
Expand Down
2 changes: 1 addition & 1 deletion lua/terrortown/menus/gamemode/server_addons.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CLGAMEMODEMENU.base = "base_gamemodemenu"
CLGAMEMODEMENU.icon = Material("vgui/ttt/vskin/helpscreen/addons")
CLGAMEMODEMENU.title = "menu_server_addons_title"
CLGAMEMODEMENU.description = "menu_server_addons_description"
CLGAMEMODEMENU.priority = 46
CLGAMEMODEMENU.priority = 45

-- overwrite and return true to enable a searchbar
function CLGAMEMODEMENU:HasSearchbar()
Expand Down
2 changes: 1 addition & 1 deletion lua/terrortown/menus/gamemode/shops.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ CLGAMEMODEMENU.base = "base_gamemodemenu"
CLGAMEMODEMENU.icon = Material("vgui/ttt/vskin/helpscreen/shops")
CLGAMEMODEMENU.title = "menu_shops_title"
CLGAMEMODEMENU.description = "menu_shops_description"
CLGAMEMODEMENU.priority = 48
CLGAMEMODEMENU.priority = 47

CLGAMEMODEMENU.isInitialized = false
CLGAMEMODEMENU.roles = nil
Expand Down
19 changes: 19 additions & 0 deletions lua/ttt2/extensions/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,25 @@ local function DoBleed(ent)
util.PaintDown(ent:GetPos() + jitter, "Blood", ent)
end

---
-- Creates a color based on a given input string.
-- @param string str The input string, can be any text
-- @return Color The created color
-- @realm shared
function util.StringToColor(str)
local hash = 0

for i = 1, #str do
hash = string.byte(str, i) + bit.lshift(hash, 8 - i) - hash
end

local r = bit.band(bit.rshift(hash, 16), 0xFF)
local g = bit.band(bit.rshift(hash, 8), 0xFF)
local b = bit.band(hash, 0xFF)

return Color(r, g, b)
end

---
-- Something hurt us, start bleeding for a bit depending on the amount
-- @param Entity ent
Expand Down

0 comments on commit 79b20d4

Please sign in to comment.