Merge pull request #15990 from SandPoot/lobby-collapse

Collapsible lobby buttons
This commit is contained in:
Lin
2023-07-20 11:55:29 -05:00
committed by GitHub
10 changed files with 220 additions and 31 deletions

View File

@@ -0,0 +1,4 @@
/// Sent from /atom/movable/screen/lobby/button/collapse/proc/collapse_buttons() : ()
#define COMSIG_HUD_LOBBY_COLLAPSED "hud_lobby_collapsed"
/// Sent from /atom/movable/screen/lobby/button/collapse/proc/expand_buttons() : ()
#define COMSIG_HUD_LOBBY_EXPANDED "hud_lobby_expanded"

View File

@@ -187,8 +187,14 @@
#define ABOVE_HUD_LAYER 30
#define ABOVE_HUD_RENDER_TARGET "ABOVE_HUD_PLANE"
#define LOBBY_BACKGROUND_LAYER 3
#define LOBBY_BUTTON_LAYER 4
///Layer for lobby menu collapse button
#define LOBBY_BELOW_MENU_LAYER 2
///Layer for lobby menu background image and main buttons (Join/Ready, Observe, Charater Prefs)
#define LOBBY_MENU_LAYER 3
///Layer for lobby menu shutter, which covers up the menu to collapse/expand it
#define LOBBY_SHUTTER_LAYER 4
///Layer for lobby menu buttons that are hanging away from and lower than the main panel
#define LOBBY_BOTTOM_BUTTON_LAYER 5
#define SPLASHSCREEN_LAYER 90
#define SPLASHSCREEN_PLANE 90

View File

@@ -0,0 +1,34 @@
// So we want to have compile time guarantees these methods exist on local type, unfortunately 515 killed the .proc/procname and .verb/verbname syntax so we have to use nameof()
// For the record: GLOBAL_VERB_REF would be useless as verbs can't be global.
#if DM_VERSION < 515
/// Call by name proc references, checks if the proc exists on either this type or as a global proc.
#define PROC_REF(X) (.proc/##X)
/// Call by name verb references, checks if the verb exists on either this type or as a global verb.
#define VERB_REF(X) (.verb/##X)
/// Call by name proc reference, checks if the proc exists on either the given type or as a global proc
#define TYPE_PROC_REF(TYPE, X) (##TYPE.proc/##X)
/// Call by name verb reference, checks if the verb exists on either the given type or as a global verb
#define TYPE_VERB_REF(TYPE, X) (##TYPE.verb/##X)
/// Call by name proc reference, checks if the proc is an existing global proc
#define GLOBAL_PROC_REF(X) (/proc/##X)
#else
/// Call by name proc references, checks if the proc exists on either this type or as a global proc.
#define PROC_REF(X) (nameof(.proc/##X))
/// Call by name verb references, checks if the verb exists on either this type or as a global verb.
#define VERB_REF(X) (nameof(.verb/##X))
/// Call by name proc reference, checks if the proc exists on either the given type or as a global proc
#define TYPE_PROC_REF(TYPE, X) (nameof(##TYPE.proc/##X))
/// Call by name verb reference, checks if the verb exists on either the given type or as a global verb
#define TYPE_VERB_REF(TYPE, X) (nameof(##TYPE.verb/##X))
/// Call by name proc reference, checks if the proc is an existing global proc
#define GLOBAL_PROC_REF(X) (/proc/##X)
#endif

View File

@@ -1,12 +1,20 @@
#define SHUTTER_MOVEMENT_DURATION 0.4 SECONDS
#define SHUTTER_WAIT_DURATION 0.2 SECONDS
/datum/hud/new_player
///Whether the menu is currently on the client's screen or not
var/menu_hud_status = TRUE
/datum/hud/new_player/proc/populate_buttons(mob/dead/new_player/owner)
var/list/buttons = subtypesof(/atom/movable/screen/lobby)
for(var/button_type in buttons)
var/atom/movable/screen/lobby/lobbyscreen = new button_type()
var/atom/movable/screen/lobby/lobbyscreen = new button_type(our_hud = src)
lobbyscreen.SlowInit()
lobbyscreen.hud = src
static_inventory += lobbyscreen
if(!lobbyscreen.always_shown)
lobbyscreen.RegisterSignal(src, COMSIG_HUD_LOBBY_COLLAPSED, TYPE_PROC_REF(/atom/movable/screen/lobby, collapse_button))
lobbyscreen.RegisterSignal(src, COMSIG_HUD_LOBBY_EXPANDED, TYPE_PROC_REF(/atom/movable/screen/lobby, expand_button))
if(istype(lobbyscreen, /atom/movable/screen/lobby/button))
var/atom/movable/screen/lobby/button/lobby_button = lobbyscreen
lobby_button.owner = REF(owner)
@@ -14,15 +22,35 @@
/atom/movable/screen/lobby
plane = SPLASHSCREEN_PLANE
layer = LOBBY_BUTTON_LAYER
layer = LOBBY_MENU_LAYER
screen_loc = "TOP,CENTER"
///Whether this HUD element can be hidden from the client's "screen" (moved off-screen) or not
var/always_shown = FALSE
/atom/movable/screen/lobby/New(loc, datum/hud/our_hud, ...)
if(our_hud)
hud = our_hud
return ..()
/// Run sleeping actions after initialize
/atom/movable/screen/lobby/proc/SlowInit()
return
///Animates moving the button off-screen
/atom/movable/screen/lobby/proc/collapse_button()
SIGNAL_HANDLER
//wait for the shutter to come down
animate(src, transform = transform, time = SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION)
//then pull the buttons up with the shutter
animate(transform = transform.Translate(x = 0, y = 146), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN)
///Animates moving the button back into place
/atom/movable/screen/lobby/proc/expand_button()
SIGNAL_HANDLER
//the buttons are off-screen, so we sync them up to come down with the shutter
animate(src, transform = matrix(), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_OUT)
/atom/movable/screen/lobby/background
layer = LOBBY_BACKGROUND_LAYER
icon = 'icons/hud/lobby/background.dmi'
icon_state = "background"
screen_loc = "TOP,CENTER:-61"
@@ -73,6 +101,7 @@
return
icon_state = base_icon_state
///Updates the button's status: TRUE to enable interaction with the button, FALSE to disable
/atom/movable/screen/lobby/button/proc/set_button_status(status)
if(status == enabled)
return FALSE
@@ -82,6 +111,7 @@
///Prefs menu
/atom/movable/screen/lobby/button/character_setup
name = "View Character Setup"
screen_loc = "TOP:-70,CENTER:-54"
icon = 'icons/hud/lobby/character_setup.dmi'
icon_state = "character_setup"
@@ -96,10 +126,12 @@
///Button that appears before the game has started
/atom/movable/screen/lobby/button/ready
name = "Toggle Readiness"
screen_loc = "TOP:-8,CENTER:-65"
icon = 'icons/hud/lobby/ready.dmi'
icon_state = "not_ready"
base_icon_state = "not_ready"
///Whether we are readied up for the round or not
var/ready = FALSE
/atom/movable/screen/lobby/button/ready/Initialize(mapload)
@@ -141,6 +173,7 @@
///Shown when the game has started
/atom/movable/screen/lobby/button/join
name = "Join Game"
screen_loc = "TOP:-13,CENTER:-58"
icon = 'icons/hud/lobby/join.dmi'
icon_state = "" //Default to not visible
@@ -204,6 +237,7 @@
RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, .proc/show_join_button)
/atom/movable/screen/lobby/button/observe
name = "Observe"
screen_loc = "TOP:-40,CENTER:-54"
icon = 'icons/hud/lobby/observe.dmi'
icon_state = "observe_disabled"
@@ -230,13 +264,18 @@
set_button_status(TRUE)
UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME, .proc/enable_observing)
/atom/movable/screen/lobby/button/settings
//Subtype the bottom buttons away so the collapse/expand shutter goes behind them
/atom/movable/screen/lobby/button/bottom
layer = LOBBY_BOTTOM_BUTTON_LAYER
icon = 'icons/hud/lobby/bottom_buttons.dmi'
/atom/movable/screen/lobby/button/bottom/settings
name = "View Game Preferences"
icon_state = "settings"
base_icon_state = "settings"
screen_loc = "TOP:-122,CENTER:+30"
screen_loc = "TOP:-122,CENTER:+29"
/atom/movable/screen/lobby/button/settings/Click(location, control, params)
/atom/movable/screen/lobby/button/bottom/settings/Click(location, control, params)
. = ..()
if(!.)
return
@@ -244,39 +283,38 @@
hud.mymob.client.prefs.current_tab = GAME_PREFERENCES_TAB
hud.mymob.client.prefs.ShowChoices(hud.mymob)
/atom/movable/screen/lobby/button/changelog_button
icon = 'icons/hud/lobby/bottom_buttons.dmi'
/atom/movable/screen/lobby/button/bottom/changelog_button
name = "View Changelog"
icon_state = "changelog"
base_icon_state = "changelog"
screen_loc ="TOP:-122,CENTER:+58"
screen_loc ="TOP:-122,CENTER:+57"
/atom/movable/screen/lobby/button/bottom/changelog_button/Click(location, control, params)
. = ..()
usr.client?.changelog()
/atom/movable/screen/lobby/button/crew_manifest
icon = 'icons/hud/lobby/bottom_buttons.dmi'
/atom/movable/screen/lobby/button/bottom/crew_manifest
name = "View Crew Manifest"
icon_state = "crew_manifest"
base_icon_state = "crew_manifest"
screen_loc = "TOP:-122,CENTER:+2"
/atom/movable/screen/lobby/button/crew_manifest/Click(location, control, params)
/atom/movable/screen/lobby/button/bottom/crew_manifest/Click(location, control, params)
. = ..()
if(!.)
return
var/mob/dead/new_player/new_player = hud.mymob
new_player.ViewManifest()
/atom/movable/screen/lobby/button/changelog_button/Click(location, control, params)
. = ..()
usr.client?.changelog()
/atom/movable/screen/lobby/button/poll
icon = 'icons/hud/lobby/bottom_buttons.dmi'
/atom/movable/screen/lobby/button/bottom/poll
name = "View Available Polls"
icon_state = "poll"
base_icon_state = "poll"
screen_loc = "TOP:-122,CENTER:-26"
///Whether the button should have a New Poll notification overlay
var/new_poll = FALSE
/atom/movable/screen/lobby/button/poll/SlowInit(mapload)
/atom/movable/screen/lobby/button/bottom/poll/SlowInit(mapload)
. = ..()
if(!usr)
return
@@ -320,14 +358,89 @@
set_button_status(FALSE)
return
/atom/movable/screen/lobby/button/poll/update_overlays()
/atom/movable/screen/lobby/button/bottom/poll/update_overlays()
. = ..()
if(new_poll)
. += mutable_appearance('icons/hud/lobby/poll_overlay.dmi', "new_poll")
/atom/movable/screen/lobby/button/poll/Click(location, control, params)
/atom/movable/screen/lobby/button/bottom/poll/Click(location, control, params)
. = ..()
if(!.)
return
var/mob/dead/new_player/new_player = hud.mymob
new_player.handle_player_polling()
/atom/movable/screen/lobby/button/collapse
name = "Collapse Lobby Menu"
icon = 'icons/hud/lobby/collapse_expand.dmi'
icon_state = "collapse"
base_icon_state = "collapse"
layer = LOBBY_BELOW_MENU_LAYER
screen_loc = "TOP:-82,CENTER:-54"
always_shown = TRUE
/atom/movable/screen/lobby/button/collapse/Click(location, control, params)
. = ..()
if(!.)
return
if(!istype(hud, /datum/hud/new_player))
return
var/datum/hud/new_player/our_hud = hud
base_icon_state = our_hud.menu_hud_status ? "expand" : "collapse"
name = "[our_hud.menu_hud_status ? "Expand" : "Collapse"] Lobby Menu"
set_button_status(FALSE)
//get the shutter object used by our hud
var/atom/movable/screen/lobby/shutter/menu_shutter = locate(/atom/movable/screen/lobby/shutter) in hud.static_inventory
//animate the shutter
menu_shutter.setup_shutter_animation()
//animate bottom buttons' movement
if(our_hud.menu_hud_status)
collapse_menu()
else
expand_menu()
our_hud.menu_hud_status = !our_hud.menu_hud_status
//re-enable clicking the button when the shutter animation finishes
//we use sleep here so it can work during game setup, as addtimer would not work until the game would finish setting up
sleep(2 * SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION)
set_button_status(TRUE)
///Moves the button to the top of the screen, leaving only the screen part in view
///Sends a signal on the hud for the menu hud elements to listen to
/atom/movable/screen/lobby/button/collapse/proc/collapse_menu()
SEND_SIGNAL(hud, COMSIG_HUD_LOBBY_COLLAPSED)
//wait for the shutter to come down
animate(src, transform = transform, time = SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION)
//then pull the button up with the shutter and leave it on the edge of the screen
animate(transform = transform.Translate(x = 0, y = 134), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN)
///Extends the button back to its usual spot
///Sends a signal on the hud for the menu hud elements to listen to
/atom/movable/screen/lobby/button/collapse/proc/expand_menu()
SEND_SIGNAL(hud, COMSIG_HUD_LOBBY_EXPANDED)
animate(src, transform = matrix(), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_OUT)
/atom/movable/screen/lobby/shutter
icon = 'icons/hud/lobby/shutter.dmi'
icon_state = "shutter"
base_icon_state = "shutter"
screen_loc = "TOP:+143,CENTER:-73" //"home" position is off-screen
layer = LOBBY_SHUTTER_LAYER
always_shown = TRUE
///Sets up the shutter pulling down and up. It's the same animation for both collapsing and expanding the menu.
/atom/movable/screen/lobby/shutter/proc/setup_shutter_animation()
//bring down the shutter
animate(src, transform = transform.Translate(x = 0, y = -143), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_OUT)
//wait a little bit before bringing the shutter up
animate(transform = transform, time = SHUTTER_WAIT_DURATION)
//pull the shutter back off-screen
animate(transform = matrix(), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN)
#undef SHUTTER_MOVEMENT_DURATION
#undef SHUTTER_WAIT_DURATION

View File

@@ -1,6 +1,9 @@
///Cooldown for the Reset Lobby Menu HUD verb
#define RESET_HUD_INTERVAL 15 SECONDS
/mob/dead/new_player
var/ready = 0
var/spawning = 0//Referenced when you want to delete the new_player later on in the code.
///Referenced when you want to delete the new_player later on in the code.
var/spawning = 0
flags_1 = NONE
@@ -11,13 +14,16 @@
hud_type = /datum/hud/new_player
hud_possible = list()
var/mob/living/new_character //for instant transfer once the round is set up
///For instant transfer once the round is set up
var/mob/living/new_character
//Used to make sure someone doesn't get spammed with messages if they're ineligible for roles
///Used to make sure someone doesn't get spammed with messages if they're ineligible for roles
var/ineligible_for_roles = FALSE
//is there a result we want to read from the age gate
///Is there a result we want to read from the age gate
var/age_gate_result
///Cooldown for the Reset Lobby Menu HUD verb
COOLDOWN_DECLARE(reset_hud_cooldown)
/mob/dead/new_player/Initialize(mapload)
if(client && SSticker.state == GAME_STATE_STARTUP)
@@ -34,6 +40,7 @@
. = ..()
GLOB.new_player_list += src
add_verb(src, /mob/dead/new_player/proc/reset_menu_hud)
/mob/dead/new_player/Destroy()
GLOB.new_player_list -= src
@@ -351,6 +358,11 @@
return
to_chat(src, "<span class='notice'>Vote successful.</span>")
/mob/dead/new_player/get_status_tab_items()
. = ..()
if(!SSticker.HasRoundStarted()) //only show this when the round hasn't started yet
. += "Readiness status: [ready ? "" : "Not "]Readied Up!"
//When you cop out of the round (NB: this HAS A SLEEP FOR PLAYER INPUT IN IT)
/mob/dead/new_player/proc/make_me_an_observer()
if(QDELETED(src) || !src.client)
@@ -579,14 +591,14 @@
if(job_datum && IsJobUnavailable(job_datum.title, TRUE) == JOB_AVAILABLE)
// Get currently occupied slots
var/num_positions_current = job_datum.current_positions
// Get total slots that can be occupied
var/num_positions_total = job_datum.total_positions
// Change to lemniscate for infinite-slot jobs
// This variable should only used to display text!
num_positions_total = (num_positions_total == -1 ? "∞" : num_positions_total)
var/command_bold = ""
if(job in GLOB.command_positions)
command_bold = " command"
@@ -752,3 +764,21 @@
return FALSE //This is the only case someone should actually be completely blocked from antag rolling as well
return TRUE
///Resets the Lobby Menu HUD, recreating and reassigning it to the new player
/mob/dead/new_player/proc/reset_menu_hud()
set name = "Reset Lobby Menu HUD"
set category = "OOC"
var/mob/dead/new_player/new_player = usr
if(!COOLDOWN_FINISHED(new_player, reset_hud_cooldown))
to_chat(new_player, span_warning("You must wait <b>[DisplayTimeText(COOLDOWN_TIMELEFT(new_player, reset_hud_cooldown))]</b> before resetting the Lobby Menu HUD again!"))
return
if(!new_player?.client)
return
COOLDOWN_START(new_player, reset_hud_cooldown, RESET_HUD_INTERVAL)
qdel(new_player.hud_used)
create_mob_hud()
to_chat(new_player, span_info("Lobby Menu HUD reset. You may reset the HUD again in <b>[DisplayTimeText(RESET_HUD_INTERVAL)]</b>."))
hud_used.show_hud(hud_used.hud_version)
#undef RESET_HUD_INTERVAL

Binary file not shown.

Before

Width:  |  Height:  |  Size: 527 B

After

Width:  |  Height:  |  Size: 558 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 844 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 919 B

BIN
icons/hud/lobby/shutter.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

View File

@@ -16,6 +16,7 @@
// BEGIN_INCLUDE
#include "_maps\_basemap.dm"
#include "_maps\map_files\FestiveBall\doorButtonOrganizer.dm"
#include "code\__byond_version_compat.dm"
#include "code\_compile_options.dm"
#include "code\world.dm"
#include "code\__DEFINES\_auxtools.dm"
@@ -159,6 +160,7 @@
#include "code\__DEFINES\dcs\flags.dm"
#include "code\__DEFINES\dcs\helpers.dm"
#include "code\__DEFINES\dcs\signals.dm"
#include "code\__DEFINES\dcs\signals\signals_hud.dm"
#include "code\__DEFINES\dcs\signals\signals_painting.dm"
#include "code\__DEFINES\dcs\signals\signals_screentips.dm"
#include "code\__DEFINES\dcs\signals\signals_medical.dm"