#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/New(mob/dead/new_player/owner) . = ..() if(!owner.age_verify()) return populate_buttons(owner) /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(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) show_hud(hud_version) /atom/movable/screen/lobby plane = SPLASHSCREEN_PLANE 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 icon = 'icons/hud/lobby/background.dmi' icon_state = "background" screen_loc = "TOP,CENTER:-61" /atom/movable/screen/lobby/button ///Is the button currently enabled? var/enabled = TRUE ///Is the button currently being hovered over with the mouse? var/highlighted = FALSE /// The ref of the mob that owns this button. Only the owner can click on it. var/owner /atom/movable/screen/lobby/button/Click(location, control, params) if(owner != REF(usr)) return . = ..() if(!enabled) return flick("[base_icon_state]_pressed", src) update_appearance(UPDATE_ICON) return TRUE /atom/movable/screen/lobby/button/MouseEntered(location,control,params) if(owner != REF(usr)) return . = ..() highlighted = TRUE update_appearance(UPDATE_ICON) /atom/movable/screen/lobby/button/MouseExited() if(owner != REF(usr)) return . = ..() highlighted = FALSE update_appearance(UPDATE_ICON) /atom/movable/screen/lobby/button/update_icon(updates) . = ..() if(!enabled) icon_state = "[base_icon_state]_disabled" return else if(highlighted) icon_state = "[base_icon_state]_highlighted" 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 enabled = status update_appearance(UPDATE_ICON) return TRUE ///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" base_icon_state = "character_setup" /atom/movable/screen/lobby/button/character_setup/Click(location, control, params) . = ..() if(!.) return hud.mymob.client.prefs.current_tab = SETTINGS_TAB hud.mymob.client.prefs.ShowChoices(hud.mymob) ///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) . = ..() switch(SSticker.current_state) if(GAME_STATE_PREGAME, GAME_STATE_STARTUP) RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(hide_ready_button)) if(GAME_STATE_SETTING_UP) set_button_status(FALSE) RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(show_ready_button)) else set_button_status(FALSE) /atom/movable/screen/lobby/button/ready/proc/hide_ready_button() SIGNAL_HANDLER set_button_status(FALSE) UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP) RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(show_ready_button)) /atom/movable/screen/lobby/button/ready/proc/show_ready_button() SIGNAL_HANDLER set_button_status(TRUE) UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP) RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(hide_ready_button)) /atom/movable/screen/lobby/button/ready/Click(location, control, params) . = ..() if(!.) return var/mob/dead/new_player/new_player = hud.mymob ready = !ready if(ready) new_player.ready = PLAYER_READY_TO_PLAY base_icon_state = "ready" else new_player.ready = PLAYER_NOT_READY base_icon_state = "not_ready" update_appearance(UPDATE_ICON) ///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 base_icon_state = "join_game" enabled = FALSE /atom/movable/screen/lobby/button/join/Initialize(mapload) . = ..() switch(SSticker.current_state) if(GAME_STATE_PREGAME, GAME_STATE_STARTUP) RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(show_join_button)) if(GAME_STATE_SETTING_UP) set_button_status(TRUE) RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(hide_join_button)) else set_button_status(TRUE) /atom/movable/screen/lobby/button/join/Click(location, control, params) . = ..() if(!.) return if(!SSticker?.IsRoundInProgress()) to_chat(hud.mymob, span_boldwarning("The round is either not ready, or has already finished...")) return //Determines Relevent Population Cap var/relevant_cap var/hpc = CONFIG_GET(number/hard_popcap) var/epc = CONFIG_GET(number/extreme_popcap) if(hpc && epc) relevant_cap = min(hpc, epc) else relevant_cap = max(hpc, epc) var/mob/dead/new_player/new_player = hud.mymob if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(new_player.key) in GLOB.admin_datums))) to_chat(new_player, span_danger("[CONFIG_GET(string/hard_popcap_message)]")) var/queue_position = SSticker.queued_players.Find(new_player) if(queue_position == 1) to_chat(new_player, span_notice("You are next in line to join the game. You will be notified when a slot opens up.")) else if(queue_position) to_chat(new_player, span_notice("There are [queue_position-1] players in front of you in the queue to join the game.")) else SSticker.queued_players += new_player to_chat(new_player, span_notice("You have been added to the queue to join the game. Your position in queue is [SSticker.queued_players.len].")) return new_player.LateChoices() /atom/movable/screen/lobby/button/join/proc/show_join_button() SIGNAL_HANDLER set_button_status(TRUE) UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP) RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(hide_join_button)) /atom/movable/screen/lobby/button/join/proc/hide_join_button() SIGNAL_HANDLER set_button_status(FALSE) UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP) RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(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" base_icon_state = "observe" enabled = FALSE /atom/movable/screen/lobby/button/observe/Initialize(mapload) . = ..() if(SSticker.current_state > GAME_STATE_STARTUP) set_button_status(TRUE) else RegisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME, PROC_REF(enable_observing)) /atom/movable/screen/lobby/button/observe/Click(location, control, params) . = ..() if(!.) return var/mob/dead/new_player/new_player = hud.mymob new_player.make_me_an_observer() /atom/movable/screen/lobby/button/observe/proc/enable_observing() SIGNAL_HANDLER flick("[base_icon_state]_enabled", src) set_button_status(TRUE) UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME, PROC_REF(enable_observing)) //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:+29" /atom/movable/screen/lobby/button/bottom/settings/Click(location, control, params) . = ..() if(!.) return hud.mymob.client.prefs.current_tab = PREFERENCES_TAB hud.mymob.client.prefs.ShowChoices(hud.mymob) /atom/movable/screen/lobby/button/bottom/changelog_button name = "View Changelog" icon_state = "changelog" base_icon_state = "changelog" 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/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/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/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/bottom/poll/SlowInit(mapload) . = ..() if(!usr) return var/mob/dead/new_player/new_player = usr if(is_guest_key(new_player.key)) set_button_status(FALSE) return if(!SSdbcore.Connect()) set_button_status(FALSE) return var/isadmin = FALSE if(new_player.client?.holder) isadmin = TRUE var/datum/db_query/query_get_new_polls = SSdbcore.NewQuery({" SELECT id FROM [format_table_name("poll_question")] WHERE (adminonly = 0 OR :isadmin = 1) AND Now() BETWEEN starttime AND endtime AND deleted = 0 AND id NOT IN ( SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = :ckey AND deleted = 0 ) AND id NOT IN ( SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = :ckey AND deleted = 0 ) "}, list("isadmin" = isadmin, "ckey" = new_player.ckey)) if(!query_get_new_polls.Execute()) qdel(query_get_new_polls) set_button_status(FALSE) return if(query_get_new_polls.NextRow()) new_poll = TRUE else new_poll = FALSE update_appearance(UPDATE_OVERLAYS) qdel(query_get_new_polls) if(QDELETED(new_player)) set_button_status(FALSE) return /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/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