[TGUI] Loadout (#27026)

* [TGUI] Loadout

* Loadout Tweaks

* Cleanup

* Almost there

* Allow to sort alphabetical

* UX tweaks

* Note and remove tweaks from scarf

* Oh fuck

* Ooops

* Sorting features

* Global search

* Rebuild

* Sure

* Rebuildo and some review changes

* TGUI REBUILDO!

---------

Co-authored-by: ROdenFL <ROdenFL@yandex.ru>
Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
This commit is contained in:
Aylong
2024-11-09 08:04:53 +00:00
committed by GitHub
co-authored by ROdenFL Burzah
parent 9329140099
commit ca50656a51
22 changed files with 611 additions and 235 deletions
+2 -2
View File
@@ -1565,10 +1565,10 @@
#undef ICON_SHIFT_XY
/datum/character_save/proc/get_gear_metadata(datum/gear/G) // NYI
. = loadout_gear[G.type]
. = loadout_gear["[G]"]
if(!.)
. = list()
loadout_gear[G.type] = .
loadout_gear["[G]"] = .
/datum/character_save/proc/get_tweak_metadata(datum/gear/G, datum/gear_tweak/tweak)
var/list/metadata = get_gear_metadata(G)
@@ -85,34 +85,6 @@
active_character.gen_record = genmsg
active_character.SetRecords(user)
if(href_list["preference"] == "gear")
if(href_list["toggle_gear"])
var/datum/gear/TG = GLOB.gear_datums[text2path(href_list["toggle_gear"])]
if(TG && (TG.type in active_character.loadout_gear))
active_character.loadout_gear -= TG.type
else
if(TG.donator_tier && user.client.donator_level < TG.donator_tier)
to_chat(user, "<span class='warning'>That gear is only available at a higher donation tier than you are on.</span>")
return
build_loadout(TG)
else if(href_list["gear"] && href_list["tweak"]) // NYI
var/datum/gear/gear = GLOB.gear_datums[text2path(href_list["gear"])]
var/datum/gear_tweak/tweak = locate(href_list["tweak"])
if(!tweak || !istype(gear) || !(tweak in gear.gear_tweaks))
return
var/metadata = tweak.get_metadata(user, active_character.get_tweak_metadata(gear, tweak))
if(!metadata)
return
active_character.set_tweak_metadata(gear, tweak, metadata)
else if(href_list["select_category"])
gear_tab = href_list["select_category"]
else if(href_list["clear_loadout"])
active_character.loadout_gear.Cut()
ShowChoices(user)
return
switch(href_list["task"])
if("random")
var/datum/robolimb/robohead
@@ -698,6 +670,11 @@
if(new_backbag)
active_character.backbag = new_backbag
if("loadout")
var/datum/ui_module/loadout/loadout = new()
loadout.ui_interact(user)
return FALSE
if("nt_relation")
var/new_relation = tgui_input_list(user, "Choose your relation to NT. Note that this represents what others can find out about your character by researching your background, not what your character actually thinks.", "Character Preference", list("Loyal", "Supportive", "Neutral", "Skeptical", "Opposed"))
if(new_relation)
@@ -1,5 +1,10 @@
/datum/gear_tweak/proc/get_contents(metadata)
return
/datum/gear_tweak
/// Displayed in TGUI name
var/display_type
/// Font Awesome icon
var/fa_icon
/// Explains what is this do in TGUI tooltip
var/info
/datum/gear_tweak/proc/get_metadata(user, metadata)
return
@@ -10,102 +15,51 @@
/datum/gear_tweak/proc/tweak_gear_data(metadata, datum/gear_data)
return
/datum/gear_tweak/proc/tweak_item(obj/item/I, metadata)
/datum/gear_tweak/proc/tweak_item(obj/item/gear, metadata)
return
/*
* Color adjustment
*/
// MARK: Color
/datum/gear_tweak/color
display_type = "Color"
fa_icon = "palette"
info = "Recolorable"
var/list/valid_colors
/datum/gear_tweak/color/New(list/colors)
valid_colors = colors
..()
/datum/gear_tweak/color/get_contents(metadata)
return "Color: <font color='[metadata]'>&#9899;</font>"
/datum/gear_tweak/color/get_default()
return valid_colors ? valid_colors[1] : COLOR_GRAY
/datum/gear_tweak/color/get_metadata(user, metadata)
if(valid_colors)
return input(user, "Choose an item color.", "Character Preference", metadata) as null|anything in valid_colors
return tgui_input_list(user, "Choose an item color.", "Recolor Gear", valid_colors, metadata)
return tgui_input_color(user, "Choose an item color.", "Global Preference", metadata)
/datum/gear_tweak/color/tweak_item(obj/item/I, metadata)
if(valid_colors && !(metadata in valid_colors))
/datum/gear_tweak/color/tweak_item(obj/item/gear, metadata)
if((valid_colors && !(metadata in valid_colors)) || !metadata)
return
I.color = metadata
/*
* Path adjustment
*/
gear.color = metadata
/datum/gear_tweak/path
var/list/valid_paths
// MARK: Rename
/datum/gear_tweak/rename
display_type = "Name"
fa_icon = "edit"
info = "Renameable"
/datum/gear_tweak/path/New(list/paths)
valid_paths = paths
..()
/datum/gear_tweak/rename/get_default()
return ""
/datum/gear_tweak/path/get_contents(metadata)
return "Type: [metadata]"
/datum/gear_tweak/rename/get_metadata(user, metadata)
var/new_name = tgui_input_text(user, "Rename an object. Enter empty line for stock name", "Rename Gear", metadata, MAX_NAME_LEN)
if(isnull(new_name))
return metadata
return new_name
/datum/gear_tweak/path/get_default()
return valid_paths[1]
/datum/gear_tweak/path/get_metadata(user, metadata)
return input(user, "Choose a type.", "Character Preference", metadata) as null|anything in valid_paths
/datum/gear_tweak/path/tweak_gear_data(metadata, datum/gear_data/gear_data)
if(!(metadata in valid_paths))
/datum/gear_tweak/rename/tweak_item(obj/item/gear, metadata)
if(!metadata)
return
gear_data.path = valid_paths[metadata]
/*
* Content adjustment
*/
/datum/gear_tweak/contents
var/list/valid_contents
/datum/gear_tweak/contents/New()
valid_contents = args.Copy()
..()
/datum/gear_tweak/contents/get_contents(metadata)
return "Contents: [english_list(metadata, and_text = ", ")]"
/datum/gear_tweak/contents/get_default()
. = list()
for(var/i = 1 to length(valid_contents))
. += "Random"
/datum/gear_tweak/contents/get_metadata(user, list/metadata)
. = list()
for(var/i = length(metadata) to length(valid_contents))
metadata += "Random"
for(var/i = 1 to length(valid_contents))
var/entry = input(user, "Choose an entry.", "Character Preference", metadata[i]) as null|anything in (valid_contents[i] + list("Random", "None"))
if(entry)
. += entry
else
return metadata
/datum/gear_tweak/contents/tweak_item(obj/item/I, list/metadata)
if(length(metadata) != length(valid_contents))
return
for(var/i = 1 to length(valid_contents))
var/path
var/list/contents = valid_contents[i]
if(metadata[i] == "Random")
path = pick(contents)
path = contents[path]
else if(metadata[i] == "None")
continue
else
path = contents[metadata[i]]
new path(I)
gear.name = metadata
@@ -1,14 +1,5 @@
GLOBAL_LIST_EMPTY(loadout_categories)
GLOBAL_LIST_EMPTY(gear_datums)
/datum/loadout_category
var/category = ""
var/list/gear = list()
/datum/loadout_category/New(cat)
category = cat
..()
/datum/gear
/// Displayed name of the item listing.
var/display_name
@@ -48,10 +39,10 @@ GLOBAL_LIST_EMPTY(gear_datums)
location = nlocation
/datum/gear/proc/spawn_item(location, metadata)
var/datum/gear_data/gd = new(path, location)
for(var/datum/gear_tweak/gt in gear_tweaks)
gt.tweak_gear_data(metadata["[gt]"], gd)
var/item = new gd.path(gd.location)
for(var/datum/gear_tweak/gt in gear_tweaks)
gt.tweak_item(item, metadata["[gt]"])
var/datum/gear_data/gear_data = new(path, location)
for(var/datum/gear_tweak/tweak in gear_tweaks)
tweak.tweak_gear_data(metadata["[tweak]"], gear_data)
var/item = new gear_data.path(gear_data.location)
for(var/datum/gear_tweak/tweak in gear_tweaks)
tweak.tweak_item(item, metadata["[tweak]"])
return item
@@ -0,0 +1,61 @@
GLOBAL_LIST_EMPTY(gear_tgui_info)
/datum/ui_module/loadout
name = "Loadout"
/datum/ui_module/loadout/ui_state(mob/user)
return GLOB.always_state
/datum/ui_module/loadout/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Loadout", name)
ui.set_autoupdate(FALSE)
ui.open()
/datum/ui_module/loadout/ui_data(mob/user)
var/list/data = list()
data["gear_slots"] = user?.client?.prefs.build_loadout()
data["selected_gears"] = user?.client?.prefs?.active_character?.loadout_gear
return data
/datum/ui_module/loadout/ui_static_data(mob/user)
var/list/data = list()
data["gears"] = GLOB.gear_tgui_info
data["max_gear_slots"] = user?.client?.prefs?.max_gear_slots
data["user_tier"] = user?.client?.donator_level
return data
/datum/ui_module/loadout/ui_act(action, list/params)
if(..())
return
. = TRUE
var/mob/user = usr
var/datum/character_save/active_character = user.client.prefs.active_character
switch(action)
if("toggle_gear")
var/datum/gear/gear = GLOB.gear_datums[text2path(params["gear"])]
if(gear && ("[gear]" in active_character.loadout_gear))
active_character.loadout_gear -= "[gear]"
return TRUE
if(gear.donator_tier && user.client.donator_level < gear.donator_tier)
to_chat(user, "<span class='warning'>That gear is only available at a higher donation tier than you are on.</span>")
return FALSE
user.client.prefs.build_loadout(gear)
return TRUE
if("set_tweak")
if(!(params["gear"] in active_character.loadout_gear))
return FALSE
var/datum/gear/gear = GLOB.gear_datums[text2path(params["gear"])]
var/datum/gear_tweak/tweak = locate(text2path(params["tweak"])) in gear.gear_tweaks
active_character.set_tweak_metadata(gear, tweak, tweak.get_metadata(user, active_character.get_tweak_metadata(gear, tweak)))
return TRUE
if("clear_loadout")
active_character.loadout_gear.Cut()
return TRUE
+11 -59
View File
@@ -171,7 +171,6 @@ GLOBAL_LIST_INIT(special_role_times, list(
dat += "<a href='byond://?_src_=prefs;preference=tab;tab=[TAB_CHAR]' [current_tab == TAB_CHAR ? "class='linkOn'" : ""]>Character Settings</a>"
dat += "<a href='byond://?_src_=prefs;preference=tab;tab=[TAB_GAME]' [current_tab == TAB_GAME ? "class='linkOn'" : ""]>Game Preferences</a>"
dat += "<a href='byond://?_src_=prefs;preference=tab;tab=[TAB_ANTAG]' [current_tab == TAB_ANTAG ? "class='linkOn'" : ""]>Antagonists</a>"
dat += "<a href='byond://?_src_=prefs;preference=tab;tab=[TAB_GEAR]' [current_tab == TAB_GEAR ? "class='linkOn'" : ""]>Loadout</a>"
dat += "<a href='byond://?_src_=prefs;preference=tab;tab=[TAB_KEYS]' [current_tab == TAB_KEYS ? "class='linkOn'" : ""]>Key Bindings</a>"
dat += "<a href='byond://?_src_=prefs;preference=tab;tab=[TAB_TOGGLES]' [current_tab == TAB_TOGGLES ? "class='linkOn'" : ""]>General Preferences</a>"
dat += "</center>"
@@ -391,7 +390,8 @@ GLOBAL_LIST_INIT(special_role_times, list(
dat += "<b>Undershirt:</b> <a href='byond://?_src_=prefs;preference=undershirt;task=input'>[active_character.undershirt]</a><BR>"
if(S.clothing_flags & HAS_SOCKS)
dat += "<b>Socks:</b> <a href='byond://?_src_=prefs;preference=socks;task=input'>[active_character.socks]</a><BR>"
dat += "<b>Backpack Type:</b> <a href='byond://?_src_=prefs;preference=bag;task=input'>[active_character.backbag]</a><br>"
dat += "<b>Backpack Type:</b> <a href='byond://?_src_=prefs;preference=bag;task=input'>[active_character.backbag]</a><br><br>"
dat += "<a style='font-size: 1.5em;' href='byond://?_src_=prefs;preference=loadout;task=input'>Open Loadout</a><br>"
var/datum/species/myspecies = GLOB.all_species[active_character.species]
if(!isnull(myspecies))
@@ -512,53 +512,6 @@ GLOBAL_LIST_INIT(special_role_times, list(
dat += "<b>Your [EXP_TYPE_CREW] playtime is [user.client.get_exp_type(EXP_TYPE_CREW)]</b><br>"
dat += "</td></tr></table>"
if(TAB_GEAR)
var/total_cost = build_loadout()
var/fcolor = "#3366CC"
if(total_cost < max_gear_slots)
fcolor = "#E67300"
dat += "<table align='center' width='100%'>"
dat += "<tr><td colspan=4><center><b><font color='[fcolor]'>[total_cost]/[max_gear_slots]</font> loadout points spent.</b> \[<a href='byond://?_src_=prefs;preference=gear;clear_loadout=1'>Clear Loadout</a>\]</center></td></tr>"
dat += "<tr><td colspan=4><center><b>"
var/firstcat = 1
for(var/category in GLOB.loadout_categories)
if(firstcat)
firstcat = 0
else
dat += " |"
if(category == gear_tab)
dat += " <span class='linkOff'>[category]</span> "
else
dat += " <a href='byond://?_src_=prefs;preference=gear;select_category=[category]'>[category]</a> "
dat += "</b></center></td></tr>"
var/datum/loadout_category/LC = GLOB.loadout_categories[gear_tab]
dat += "<tr><td colspan=4><hr></td></tr>"
dat += "<tr><td colspan=4><b><center>[LC.category]</center></b></td></tr>"
dat += "<tr><td colspan=4><hr></td></tr>"
for(var/gear_name in LC.gear)
var/datum/gear/G = LC.gear[gear_name]
var/ticked = (G.type in active_character.loadout_gear)
if(G.donator_tier > user.client.donator_level)
dat += "<tr style='vertical-align:top;'><td width=15%><B>[G.display_name]</B></td>"
else
dat += "<tr style='vertical-align:top;'><td width=15%><a style='white-space:normal;' [ticked ? "class='linkOn' " : ""]href='byond://?_src_=prefs;preference=gear;toggle_gear=[G.type]'>[G.display_name]</a></td>"
dat += "<td width = 5% style='vertical-align:top'>[G.cost]</td><td>"
if(G.allowed_roles)
dat += "<font size=2>Restrictions: "
for(var/role in G.allowed_roles)
dat += role + " "
dat += "</font>"
dat += "</td><td><font size=2><i>[G.description]</i></font></td></tr>"
if(ticked)
. += "<tr><td colspan=4>"
for(var/datum/gear_tweak/tweak in G.gear_tweaks)
. += " <a href='byond://?_src_=prefs;preference=gear;gear=[G.type];tweak=\ref[tweak]'>[tweak.get_contents(active_character.get_tweak_metadata(G, tweak))]</a>"
. += "</td></tr>"
dat += "</table>"
if(TAB_KEYS)
dat += "<div align='center'><b>All Key Bindings:&nbsp;</b>"
dat += "<a href='byond://?_src_=prefs;preference=keybindings;all=reset'>Reset to Default</a>&nbsp;"
@@ -772,25 +725,24 @@ GLOBAL_LIST_INIT(special_role_times, list(
var/list/loadout_cache = active_character.loadout_gear.Copy()
active_character.loadout_gear.Cut()
if(new_item)
loadout_cache += new_item.type
loadout_cache += "[new_item]"
for(var/I in loadout_cache)
var/datum/gear/G = GLOB.gear_datums[text2path(I) || I]
if(!G)
for(var/item in loadout_cache)
var/datum/gear/gear = text2path(item) || item
if(!gear || !(gear.type in GLOB.gear_datums))
continue
var/added_cost = G.cost
if(!G.subtype_selection_cost) // If listings of the same subtype shouldn't have their cost added.
if(G.main_typepath in type_blacklist)
var/added_cost = gear.cost
if(!gear.subtype_selection_cost) // If listings of the same subtype shouldn't have their cost added.
if(gear.main_typepath in type_blacklist)
added_cost = 0
else
type_blacklist += G.main_typepath
type_blacklist += gear.main_typepath
if((total_cost + added_cost) > max_gear_slots)
continue // If the final cost is too high, don't add the item.
active_character.loadout_gear += G.type
active_character.loadout_gear[item] = loadout_cache[item] ? loadout_cache[item] : list()
total_cost += added_cost
return total_cost
/datum/preferences/proc/init_keybindings(overrides, raw)
if(raw)
try