Skip to content

Commit

Permalink
Title Screen polish (#919)
Browse files Browse the repository at this point in the history
## Что этот PR делает
Полировка и фикс багов.
Пока план такой:

- [x] Пофиксить рандомно отсутствующее у рандомных игроков изображение в
лобби
- [x] Попробовать показывать админские кнопки раньше (Может использовать
сигналы?)
- [x] Впиндюрить куда-то логотип
- [x] Добавить преф, который позволит вернуть внешку как на паре
- [x] ???

## Summary by Sourcery

Add a preference for selecting lobby style.

New Features:
- Allow users to select a lobby style from their preferences.

Tests:
- Fix randomly missing images in the lobby.
  • Loading branch information
AyIong authored Jan 5, 2025
1 parent 12410ff commit 867aa2a
Show file tree
Hide file tree
Showing 13 changed files with 743 additions and 244 deletions.
3 changes: 2 additions & 1 deletion modular_bandastation/title_screen/_title_screen.dme
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

#include "code/_title_screen_defines.dm"
#include "code/asset_lobby.dm"
#include "code/title_screen_datum.dm"
#include "code/new_player.dm"
#include "code/station_traits.dm"
#include "code/title_screen_controls.dm"
#include "code/title_screen_datum.dm"
#include "code/title_screen_html.dm"
#include "code/title_screen_pref_middleware.dm"
#include "code/title_screen_subsystem.dm"
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
#define MAX_STATION_TRAIT_BUTTONS_VERTICAL 3
#define DEFAULT_TITLE_SCREEN_IMAGE_PATH 'modular_bandastation/title_screen/icons/default.png'
#define DEFAULT_TITLE_SCREEN_HTML_CSS 'modular_bandastation/title_screen/html/title_screen.css'
#define TITLE_SCREENS_LOCATION "config/title_screens/images/"
1 change: 1 addition & 0 deletions modular_bandastation/title_screen/code/asset_lobby.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/datum/asset/simple/html_title_screen
assets = list(
"ss220_logo.png" = 'icons/ui/common/ss220.png',
"lobby_background.png" = 'modular_bandastation/title_screen/icons/lobby_background.png',
"lobby_toggle_ready.png" = 'modular_bandastation/title_screen/icons/lobby_toggle_ready.png',
"lobby_late_join.png" = 'modular_bandastation/title_screen/icons/lobby_late_join.png',
Expand Down
4 changes: 4 additions & 0 deletions modular_bandastation/title_screen/code/new_player.dm
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@
else
SEND_SOUND(src, sound('sound/misc/menu/menu_rolldown1.ogg'))

else if(href_list["title_ready"])
if(check_rights_for(client, R_ADMIN|R_DEBUG))
SStitle.title_output(client, "true", "admin_buttons_visibility")

else if(href_list["focus"])
winset(client, "map", "focus=true")

Expand Down
10 changes: 3 additions & 7 deletions modular_bandastation/title_screen/code/title_screen_controls.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,10 @@ ADMIN_VERB(change_title_screen, R_FUN, "Title Screen: Change", ADMIN_VERB_NO_DES
if("Меняем")
var/file = input(usr) as icon|null
if(file)
SStitle.set_title_image(file)
SStitle.set_title_image(usr, file)

if("Сбрасываем")
SStitle.set_title_image()

log_admin("[key_name(usr)] is changing the title screen.")
message_admins("[key_name_admin(usr)] is changing the title screen.")
SStitle.set_title_image(usr)

/**
* Sets a titlescreen notice, a big red text on the main screen.
Expand All @@ -39,7 +36,7 @@ ADMIN_VERB(change_title_screen_notice, R_FUN, "Title Screen: Set Notice", ADMIN_
message_admins("Title Screen: [key_name_admin(usr)] setted the title screen notice, which contains: [new_notice]")

for(var/mob/dead/new_player/new_player as anything in GLOB.new_player_list)
to_chat(new_player, span_boldannounce(announce_text))
to_chat(new_player, span_boldannounce(emoji_parse(announce_text)))
SEND_SOUND(new_player, sound('sound/mobs/humanoids/moth/scream_moth.ogg'))

/**
Expand All @@ -64,7 +61,6 @@ ADMIN_VERB(change_title_screen_css, R_DEBUG, "Title Screen: Set CSS", ADMIN_VERB
set category = "Special"

if(!isnewplayer(src.mob))
to_chat(src, span_warning("Вы должны быть в лобби дабы использовать это!"))
return

SStitle.show_title_screen_to(src)
Expand Down
234 changes: 15 additions & 219 deletions modular_bandastation/title_screen/code/title_screen_datum.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
GLOBAL_LIST_INIT(available_lobby_styles, list(
"По-умолчанию" = 'modular_bandastation/title_screen/html/title_screen_default.css',
"Минималистичный" = 'modular_bandastation/title_screen/html/title_screen_minimalistic.css',
))

/datum/title_screen
/// All title screen styles.
var/title_css = DEFAULT_TITLE_SCREEN_HTML_CSS
/// Custom CSS. Can be changed by admins or coders. If empty, will be used from user preferences.
var/title_css
/// The current title screen being displayed, as `/datum/asset_cache_item`
var/datum/asset_cache_item/screen_image

Expand Down Expand Up @@ -31,7 +36,11 @@
fontawesome.send(viewer)

SSassets.transport.send_assets(viewer, screen_image.name)
viewer << browse(get_title_html(viewer, viewer.mob), "window=title_browser")
if(!title_css)
viewer << browse(get_title_html(viewer, viewer.mob, GLOB.available_lobby_styles[viewer.prefs.read_preference(/datum/preference/choiced/lobby_style)]), "window=title_browser")
else
viewer << browse(get_title_html(viewer, viewer.mob, title_css), "window=title_browser")


/datum/title_screen/proc/hide_from(client/viewer)
if(viewer?.mob)
Expand All @@ -42,234 +51,21 @@
return {"
<a class="lobby_element lobby-[href] [advanced_classes]" href='byond://?src=[REF(user)];[href]=1'>
<span class="lobby-text">[text]</span>
<img class="pixelated" src="[SSassets.transport.get_asset_url(asset_name = "lobby_[href].png")]">
<img class="pixelated default" src="[SSassets.transport.get_asset_url(asset_name = "lobby_[href].png")]">
</a>
"}

/datum/title_screen/proc/create_icon_button(user, href, tooltip, tooltip_position = "bottom", enabled = TRUE)
return {"
<a class="lobby_button lobby_element lobby-[href] [!enabled ? "disabled" : ""]" href='byond://?src=[REF(user)];[enabled ? href : ""]=1'>
<div class="toggle">
<img class="pixelated indicator [!enabled ? "disabled" : ""]" src="[SSassets.transport.get_asset_url(asset_name = "lobby_[enabled ? "highlight" : "disabled"].png")]">
<img class="pixelated default indicator [!enabled ? "disabled" : ""]" src="[SSassets.transport.get_asset_url(asset_name = "lobby_[enabled ? "highlight" : "disabled"].png")]">
</div>
<img class="pixelated" src="[SSassets.transport.get_asset_url(asset_name = "lobby_[href].png")]">
<img class="pixelated default" src="[SSassets.transport.get_asset_url(asset_name = "lobby_[href].png")]">
[tooltip ? {"
<div class="lobby-tooltip" data-position="[tooltip_position]">
<span class="lobby-tooltip-content">[tooltip]</span>
</div> "} : ""]
</a>
"}

/**
* Get the HTML of title screen.
*/
/datum/title_screen/proc/get_title_html(client/viewer, mob/user)
var/screen_image_url = SSassets.transport.get_asset_url(asset_cache_item = screen_image)
var/mob/dead/new_player/player = user
var/list/html = list()
html += {"
<!DOCTYPE html>
<html>
<head>
<title>Title Screen</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type='text/css'>
[file2text(title_css)]
</style>
</head>
<body>
"}

if(screen_image_url)
html += {"<img id="screen_image" class="bg" src="[screen_image_url]">"}

html += {"<div id="container_notice" class="[SStitle.notice ? "" : "hidden"]">[SStitle.notice]</div>"}
html += {"<input type="checkbox" id="hide_menu">"}
html += {"<div class="lobby_wrapper">"}
html += {"
<div class="lobby_container">
<img class="lobby_background pixelated" src="[SSassets.transport.get_asset_url(asset_name = "lobby_background.png")]">
<img class="lobby_shutter pixelated" src="[SSassets.transport.get_asset_url(asset_name = "lobby_shutter.png")]">
"}

html += {"<div class="lobby_buttons-center">"}
if(!SSticker || SSticker.current_state <= GAME_STATE_PREGAME)
html += create_main_button(player, "toggle_ready", "ГОТОВ", player.ready == PLAYER_READY_TO_PLAY ? "good" : "bad")
else
html += create_main_button(player, "late_join", "ИГРАТЬ")

html += create_main_button(player, "observe", "СЛЕДИТЬ")
html += create_main_button(player, "character_setup", "НАСТРОЙКА ПЕРСОНАЖА")
html += {"<div class="lobby_element lobby-name"><span id="character_name">[player.client.prefs.read_preference(/datum/preference/name/real_name)]</span></div>"}
html += {"</div>"}

html += {"<div class="lobby_buttons-bottom">"}
html += create_icon_button(player, "changelog", "Открыть чейнджлог")
html += create_icon_button(player, "settings", "Настройки игры")
html += create_icon_button(player, "manifest", "Манифест персонала")
html += create_icon_button(player, "wiki", "Перейти на вики")
html += {"</div>"}

html += {"<div id="lobby_admin" class="lobby_buttons-right hidden">"}
html += create_icon_button(player, "picture", "Сменить изображение", "right")
html += create_icon_button(player, "notice", "Оставить уведомление", "right")
html += create_icon_button(player, "css", "Заменить CSS лобби", "right")
html += {"</div>"}

if(length(GLOB.lobby_station_traits))
html += {"<div class="lobby_buttons-left">"}

var/number = 0
for(var/datum/station_trait/job/trait as anything in GLOB.lobby_station_traits)
if(!istype(trait))
continue // Skip trait if it is not a job

if(!trait.can_display_lobby_button(player.client))
continue

if(number > MAX_STATION_TRAIT_BUTTONS_VERTICAL) // 3 is a maximum
break

number++
var/traitID = replacetext(replacetext("[trait.type]", "/datum/station_trait/job/", ""), "/", "-")
var/assigned = LAZYFIND(trait.lobby_candidates, player)
html += {"
<a id="lobby-trait-[number]" class="lobby_button lobby_element" href='byond://?src=[REF(user)];trait_signup=[trait.name];id=[number]'>
<div class="toggle">
<img class="pixelated indicator trait_active [assigned ? "" : "hidden"]" src="[SSassets.transport.get_asset_url(asset_name = "lobby_active.png")]">
<img class="pixelated indicator trait_disabled [!assigned ? "" : "hidden"]" src="[SSassets.transport.get_asset_url(asset_name = "lobby_disabled.png")]">
<img class="pixelated indicator" src="[SSassets.transport.get_asset_url(asset_name = "lobby_highlight.png")]">
</div>
<img class="pixelated" src="[SSassets.transport.get_asset_url(asset_name = "lobby_[traitID].png")]">
<div class="lobby-tooltip" data-position="left">
<span class="lobby-tooltip-title">[trait.name]</span>
<span class="lobby-tooltip-content">[trait.button_desc]</span>
</div>
</a>
"}

html += {"</div>"}

html += {"
<label class="lobby_element lobby-collapse" for="hide_menu">
<span id="collapse" class="lobby-text toggle good">˄</span>
<img class="pixelated" src="[SSassets.transport.get_asset_url(asset_name = "lobby_collapse.png")]">
</label>
"}

html += {"</div></div></body>"}
html += {"
<script language="JavaScript">
let ready_int = 0;
const readyID = document.querySelector(".lobby-toggle_ready");
const ready_class = \[ "bad", "good" \];
function toggle_ready(setReady) {
if(setReady) {
ready_int = setReady;
readyID.classList.add(ready_class\[ready_int\]);
readyID.classList.remove(ready_class\[1 - ready_int\]);
} else {
ready_int++;
if(ready_int === ready_class.length)
ready_int = 0;
readyID.classList.add("good");
readyID.classList.remove("bad");
}
}

function job_sign(assign, id) {
/* I FUCKING HATE IE */
let traitID;
let trait_active;
let trait_disabled;

if(!id) {
return
}

if (id === "1") {
traitID = "lobby-trait-1";
} else if (id === "2") {
traitID = "lobby-trait-2";
} else if (id === "3"){
traitID = "lobby-trait-3";
} else {
return
}

trait_active = document.getElementById(traitID).querySelector(".trait_active");
trait_disabled = document.getElementById(traitID).querySelector(".trait_disabled");

if(assign === "true") {
trait_active.classList.remove("hidden");
trait_disabled.classList.add("hidden");
} else {
trait_active.classList.add("hidden");
trait_disabled.classList.remove("hidden");
}
}

const admin_buttons = document.getElementById("lobby_admin")
function admin_buttons_visibility(visible) {
if(visible === "true") {
admin_buttons.classList.remove("hidden")
} else {
admin_buttons.classList.add("hidden")
}
}

const notice_container = document.getElementById("container_notice");
function update_notice(notice) {
if(notice === undefined) {
notice_container.classList.add("hidden");
notice_container.textContent = "";
} else {
notice_container.classList.remove("hidden");
notice_container.textContent = notice;
}
}

const character_name_slot = document.getElementById("character_name");
function update_character_name(name) {
character_name_slot.textContent = name;
}

let collapsed = false;
const collapse = document.getElementById("collapse");
function update_collapse() {
const requestSound = new XMLHttpRequest();
requestSound.open("GET", "?src=[REF(player)];collapse=1");
requestSound.send();

collapsed = !collapsed;
if(collapsed) {
collapse.textContent = "˅";
} else {
collapse.textContent = "˄";
}
}

const image_container = document.getElementById("screen_image");
function update_image(image) {
image_container.src = image;
}

/* Return focus to Byond after click */
function reFocus() {
const focus = new XMLHttpRequest();
focus.open("GET", "?src=[REF(player)];focus=1");
focus.send();
}

document.addEventListener('keyup', reFocus);
document.addEventListener('mouseup', reFocus);
collapse.addEventListener('mouseup', update_collapse);
</script>
"}

html += "</html>"

return html.Join()

#undef MAX_STATION_TRAIT_BUTTONS_VERTICAL
Loading

0 comments on commit 867aa2a

Please sign in to comment.