mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-15 09:03:53 +01:00
Character Setup Rework (#17576)
* Character Setup Rework Little tweaks Species selection done~ Merk randomize body button Body color and eye color Merk more replaced code Convert robolimbs to tgui Add a warning if flavor text/ooc notes are too short Custom preview icons for species selector! A sidequest that only took 8 hours. Also add digitigrade and blood type. Remove unused body_descriptor system completely Finish the general tab~ Reorganization to prepare for loadout page creation * Start of work on the loadout screen * Only send the data that's actually selected * Get rid of these ugly ../../../.. * Retype this to avoid conflicts * Holy shit why did this work this way * Finish loadout screen * Add copy loadout function * Finish occupation page * Move Special Roles into general tab * Fix path conflict * Move size prefs to general tab * Convert jukebox and volume settings to datum/preference * Fix a little mergery fuckery in loadout * Migrate jukebox to new range * Fix TabbedMenu tabs * Fix wordwrap for loadout screen * Kill the vore tab, just traits left to convert * Convert custom messages * Convert custom species name * Convert blood color and reagents * Move icobase to tgui * Finished * This can fuck off too * Fix a few bugs * Update index.tsx * initial for emote sound mode switch * Make show_roles actually work, hide fluff items * Fix not being able to select species * Add emote_sound_mode to body tab * Fix runtime when no active gear list is present * Add a save notification to character setup * Switch to floating * Add more search bars * Whoops forgot to add this --------- Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,255 @@
|
||||
/datum/preferences
|
||||
var/list/all_underwear
|
||||
var/list/all_underwear_metadata
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment
|
||||
name = "Equipment"
|
||||
sort_order = 1
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment/load_character(list/save_data)
|
||||
pref.all_underwear = check_list_copy(save_data["all_underwear"])
|
||||
pref.all_underwear_metadata = check_list_copy(save_data["all_underwear_metadata"])
|
||||
for(var/i in pref.all_underwear_metadata)
|
||||
pref.all_underwear_metadata[i] = path2text_list(pref.all_underwear_metadata[i])
|
||||
pref.headset = save_data["headset"]
|
||||
pref.backbag = save_data["backbag"]
|
||||
pref.pdachoice = save_data["pdachoice"]
|
||||
pref.communicator_visibility = save_data["communicator_visibility"]
|
||||
pref.ringtone = save_data["ringtone"]
|
||||
pref.shoe_hater = save_data["shoe_hater"]
|
||||
pref.no_jacket = save_data["no_jacket"]
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment/save_character(list/save_data)
|
||||
save_data["all_underwear"] = pref.all_underwear
|
||||
var/list/underwear = list()
|
||||
for(var/i in pref.all_underwear_metadata)
|
||||
underwear[i] = check_list_copy(pref.all_underwear_metadata[i])
|
||||
save_data["all_underwear_metadata"] = underwear
|
||||
save_data["headset"] = pref.headset
|
||||
save_data["backbag"] = pref.backbag
|
||||
save_data["pdachoice"] = pref.pdachoice
|
||||
save_data["communicator_visibility"] = pref.communicator_visibility
|
||||
save_data["ringtone"] = pref.ringtone
|
||||
save_data["shoe_hater"] = pref.shoe_hater
|
||||
save_data["no_jacket"] = pref.no_jacket
|
||||
|
||||
var/global/list/valid_ringtones = list(
|
||||
"beep",
|
||||
"boom",
|
||||
"slip",
|
||||
"honk",
|
||||
"SKREE",
|
||||
"xeno",
|
||||
"spark",
|
||||
"rad",
|
||||
"servo",
|
||||
"buh-boop",
|
||||
"trombone",
|
||||
"whistle",
|
||||
"chirp",
|
||||
"slurp",
|
||||
"pwing",
|
||||
"clack",
|
||||
"bzzt",
|
||||
"chimes",
|
||||
"prbt",
|
||||
"bark",
|
||||
"bork",
|
||||
"roark",
|
||||
"chitter",
|
||||
"squish"
|
||||
)
|
||||
|
||||
// Moved from /datum/preferences/proc/copy_to()
|
||||
/datum/category_item/player_setup_item/loadout/equipment/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
character.all_underwear.Cut()
|
||||
character.all_underwear_metadata.Cut()
|
||||
|
||||
for(var/underwear_category_name in pref.all_underwear)
|
||||
var/datum/category_group/underwear/underwear_category = global_underwear.categories_by_name[underwear_category_name]
|
||||
if(underwear_category)
|
||||
var/underwear_item_name = pref.all_underwear[underwear_category_name]
|
||||
character.all_underwear[underwear_category_name] = underwear_category.items_by_name[underwear_item_name]
|
||||
if(pref.all_underwear_metadata[underwear_category_name])
|
||||
character.all_underwear_metadata[underwear_category_name] = pref.all_underwear_metadata[underwear_category_name]
|
||||
else
|
||||
pref.all_underwear -= underwear_category_name
|
||||
|
||||
// TODO - Looks like this is duplicating the work of sanitize_character() if so, remove
|
||||
if(pref.headset > GLOB.headsetlist.len || pref.headset < 1)
|
||||
pref.headset = 1 //Same as above
|
||||
character.headset = pref.headset
|
||||
|
||||
if(pref.backbag > backbaglist.len || pref.backbag < 1)
|
||||
pref.backbag = 2 //Same as above
|
||||
character.backbag = pref.backbag
|
||||
|
||||
if(pref.pdachoice > 8 || pref.pdachoice < 1)
|
||||
pref.pdachoice = 1
|
||||
character.pdachoice = pref.pdachoice
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment/sanitize_character()
|
||||
if(!istype(pref.all_underwear))
|
||||
pref.all_underwear = list()
|
||||
|
||||
for(var/datum/category_group/underwear/WRC in global_underwear.categories)
|
||||
for(var/datum/category_item/underwear/WRI in WRC.items)
|
||||
if(WRI.is_default(pref.identifying_gender ? pref.identifying_gender : MALE))
|
||||
pref.all_underwear[WRC.name] = WRI.name
|
||||
break
|
||||
|
||||
if(!istype(pref.all_underwear_metadata))
|
||||
pref.all_underwear_metadata = list()
|
||||
|
||||
for(var/underwear_category in pref.all_underwear)
|
||||
var/datum/category_group/underwear/UWC = global_underwear.categories_by_name[underwear_category]
|
||||
if(!UWC)
|
||||
pref.all_underwear -= underwear_category
|
||||
else
|
||||
var/datum/category_item/underwear/UWI = UWC.items_by_name[pref.all_underwear[underwear_category]]
|
||||
if(!UWI)
|
||||
pref.all_underwear -= underwear_category
|
||||
|
||||
for(var/underwear_metadata in pref.all_underwear_metadata)
|
||||
if(!(underwear_metadata in pref.all_underwear))
|
||||
pref.all_underwear_metadata -= underwear_metadata
|
||||
pref.headset = sanitize_integer(pref.headset, 1, GLOB.headsetlist.len, initial(pref.headset))
|
||||
pref.backbag = sanitize_integer(pref.backbag, 1, backbaglist.len, initial(pref.backbag))
|
||||
pref.pdachoice = sanitize_integer(pref.pdachoice, 1, pdachoicelist.len, initial(pref.pdachoice))
|
||||
pref.ringtone = sanitize(pref.ringtone, 20)
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
var/list/underwear_data = list()
|
||||
for(var/datum/category_group/underwear/UWC in global_underwear.categories)
|
||||
var/item_name = LAZYACCESS(pref.all_underwear, UWC.name) || "None"
|
||||
|
||||
var/list/tweaks = list()
|
||||
var/datum/category_item/underwear/UWI = UWC.items_by_name[item_name]
|
||||
if(UWI)
|
||||
for(var/datum/gear_tweak/gt in UWI.tweaks)
|
||||
UNTYPED_LIST_ADD(tweaks, list(
|
||||
"ref" = REF(gt),
|
||||
"contents" = gt.get_contents(get_metadata(UWC.name, gt))
|
||||
))
|
||||
|
||||
UNTYPED_LIST_ADD(underwear_data, list(
|
||||
"category" = UWC.name,
|
||||
"name" = item_name,
|
||||
"tweaks" = tweaks
|
||||
))
|
||||
data["underwear"] = underwear_data
|
||||
|
||||
data["headset_type"] = GLOB.headsetlist[pref.headset]
|
||||
data["backpack_type"] = backbaglist[pref.backbag]
|
||||
data["pda_type"] = pdachoicelist[pref.pdachoice]
|
||||
data["communicator_visibility"] = pref.communicator_visibility // boolean
|
||||
data["ringtone"] = pref.ringtone
|
||||
data["shoes"] = pref.shoe_hater
|
||||
data["jacket"] = pref.no_jacket
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment/tgui_static_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment/tgui_constant_data()
|
||||
var/list/data = ..()
|
||||
|
||||
data["headsetlist"] = GLOB.headsetlist
|
||||
data["backbaglist"] = backbaglist
|
||||
data["pdachoicelist"] = pdachoicelist
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment/proc/get_metadata(var/underwear_category, var/datum/gear_tweak/gt)
|
||||
var/metadata = pref.all_underwear_metadata[underwear_category]
|
||||
if(!metadata)
|
||||
metadata = list()
|
||||
pref.all_underwear_metadata[underwear_category] = metadata
|
||||
|
||||
var/tweak_data = metadata["[gt]"]
|
||||
if(!tweak_data)
|
||||
tweak_data = gt.get_default()
|
||||
metadata["[gt]"] = tweak_data
|
||||
return tweak_data
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment/proc/set_metadata(var/underwear_category, var/datum/gear_tweak/gt, var/new_metadata)
|
||||
var/list/metadata = pref.all_underwear_metadata[underwear_category]
|
||||
metadata["[gt]"] = new_metadata
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/equipment/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/mob/user = ui.user
|
||||
|
||||
switch(action)
|
||||
if("change_headset")
|
||||
// Takes the JS index
|
||||
var/new_headset = text2num(params["headset"]) + 1
|
||||
if(LAZYACCESS(GLOB.headsetlist, new_headset))
|
||||
pref.headset = new_headset
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("change_backpack")
|
||||
// Takes the JS index
|
||||
var/new_backbag = text2num(params["backbag"]) + 1
|
||||
if(LAZYACCESS(backbaglist, new_backbag))
|
||||
pref.backbag = new_backbag
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("change_pda")
|
||||
// Takes the JS index
|
||||
var/new_pdachoice = text2num(params["pda"]) + 1
|
||||
if(LAZYACCESS(backbaglist, new_pdachoice))
|
||||
pref.pdachoice = new_pdachoice
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("change_underwear")
|
||||
var/datum/category_group/underwear/UWC = LAZYACCESS(global_underwear.categories_by_name, params["underwear"])
|
||||
if(!UWC)
|
||||
return
|
||||
var/datum/category_item/underwear/selected_underwear = tgui_input_list(user, "Choose underwear:", "Character Preference", UWC.items, pref.all_underwear[UWC.name])
|
||||
if(selected_underwear)
|
||||
pref.all_underwear[UWC.name] = selected_underwear.name
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("underwear_tweak")
|
||||
var/underwear = params["underwear"]
|
||||
if(!(underwear in pref.all_underwear))
|
||||
return TOPIC_NOACTION
|
||||
var/datum/gear_tweak/gt = locate(params["tweak"])
|
||||
if(!gt)
|
||||
return TOPIC_NOACTION
|
||||
var/new_metadata = gt.get_metadata(user, get_metadata(underwear, gt))
|
||||
if(new_metadata)
|
||||
set_metadata(underwear, gt, new_metadata)
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("toggle_comm_visibility")
|
||||
pref.communicator_visibility = !pref.communicator_visibility
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("set_ringtone")
|
||||
var/choice = tgui_input_list(user, "Please select a ringtone. All of these choices come with an associated preset sound. Alternately, select \"Other\" to specify manually.", "Character Preference", valid_ringtones + "Other", pref.ringtone)
|
||||
if(!choice)
|
||||
return TOPIC_NOACTION
|
||||
if(choice == "Other")
|
||||
var/raw_choice = sanitize(tgui_input_text(user, "Please enter a custom ringtone. If this doesn't match any of the other listed choices, your PDA will use the default (\"beep\") sound.", "Character Preference", null, 20), 20)
|
||||
if(raw_choice)
|
||||
pref.ringtone = raw_choice
|
||||
else
|
||||
pref.ringtone = choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("toggle_shoes")
|
||||
pref.shoe_hater = !pref.shoe_hater
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("toggle_jacket")
|
||||
pref.no_jacket = !pref.no_jacket
|
||||
return TOPIC_REFRESH
|
||||
@@ -0,0 +1,295 @@
|
||||
var/list/loadout_categories = list()
|
||||
var/list/gear_datums = list()
|
||||
|
||||
/datum/loadout_category
|
||||
var/category = ""
|
||||
var/list/gear = list()
|
||||
|
||||
/datum/loadout_category/New(var/cat)
|
||||
category = cat
|
||||
..()
|
||||
|
||||
/hook/startup/proc/populate_gear_list()
|
||||
|
||||
//create a list of gear datums to sort
|
||||
for(var/datum/gear/G as anything in subtypesof(/datum/gear))
|
||||
if(initial(G.type_category) == G)
|
||||
continue
|
||||
var/use_name = initial(G.display_name)
|
||||
var/use_category = initial(G.sort_category)
|
||||
|
||||
if(!use_name)
|
||||
error("Loadout - Missing display name: [G]")
|
||||
continue
|
||||
if(isnull(initial(G.cost)))
|
||||
error("Loadout - Missing cost: [G]")
|
||||
continue
|
||||
if(!initial(G.path))
|
||||
error("Loadout - Missing path definition: [G]")
|
||||
continue
|
||||
|
||||
if(!loadout_categories[use_category])
|
||||
loadout_categories[use_category] = new /datum/loadout_category(use_category)
|
||||
var/datum/loadout_category/LC = loadout_categories[use_category]
|
||||
gear_datums[use_name] = new G
|
||||
LC.gear[use_name] = gear_datums[use_name]
|
||||
|
||||
loadout_categories = sortAssoc(loadout_categories)
|
||||
for(var/loadout_category in loadout_categories)
|
||||
var/datum/loadout_category/LC = loadout_categories[loadout_category]
|
||||
LC.gear = sortAssoc(LC.gear)
|
||||
return 1
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout
|
||||
name = "Loadout"
|
||||
sort_order = 2
|
||||
var/current_tab = "General"
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/load_character(list/save_data)
|
||||
pref.gear_list = list()
|
||||
var/all_gear = check_list_copy(save_data["gear_list"])
|
||||
for(var/i in all_gear)
|
||||
var/list/entries = check_list_copy(all_gear["[i]"])
|
||||
for(var/j in entries)
|
||||
entries["[j]"] = path2text_list(entries["[j]"])
|
||||
pref.gear_list["[i]"] = entries
|
||||
pref.gear_slot = save_data["gear_slot"]
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/save_character(list/save_data)
|
||||
var/list/all_gear = list()
|
||||
var/worn_gear = check_list_copy(pref.gear_list)
|
||||
for(var/i in worn_gear)
|
||||
var/list/entries = check_list_copy(worn_gear["[i]"])
|
||||
if(!length(entries))
|
||||
entries = check_list_copy(worn_gear[i])
|
||||
for(var/j in entries)
|
||||
entries["[j]"] = check_list_copy(entries["[j]"])
|
||||
all_gear["[i]"] = entries
|
||||
save_data["gear_list"] = all_gear
|
||||
save_data["gear_slot"] = pref.gear_slot
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/proc/is_valid_gear(datum/gear/G, max_cost)
|
||||
if(G.whitelisted && CONFIG_GET(flag/loadout_whitelist) != LOADOUT_WHITELIST_OFF && pref.client) //VOREStation Edit.
|
||||
if(CONFIG_GET(flag/loadout_whitelist) == LOADOUT_WHITELIST_STRICT && G.whitelisted != pref.species)
|
||||
return FALSE
|
||||
if(CONFIG_GET(flag/loadout_whitelist) == LOADOUT_WHITELIST_LAX && !is_alien_whitelisted(pref.client, GLOB.all_species[G.whitelisted]))
|
||||
return FALSE
|
||||
|
||||
if(max_cost && G.cost > max_cost)
|
||||
return FALSE
|
||||
if(pref.client)
|
||||
if(G.ckeywhitelist && !(pref.client_ckey in G.ckeywhitelist))
|
||||
return FALSE
|
||||
if(G.character_name && !(pref.real_name in G.character_name))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/sanitize_character()
|
||||
var/mob/preference_mob = preference_mob()
|
||||
if(LAZYLEN(pref.gear_list) < 0)
|
||||
return
|
||||
|
||||
if(pref.gear_slot > LAZYLEN(pref.gear_list))
|
||||
pref.gear_slot = 1
|
||||
|
||||
var/list/active_gear_list = LAZYACCESS(pref.gear_list, "[pref.gear_slot]")
|
||||
var/total_cost = 0
|
||||
for(var/gear_name in active_gear_list)
|
||||
if(!gear_datums[gear_name])
|
||||
to_chat(preference_mob, span_warning("You cannot have the \the [gear_name]."))
|
||||
active_gear_list -= gear_name
|
||||
continue
|
||||
|
||||
var/datum/gear/G = gear_datums[gear_name]
|
||||
if(!is_valid_gear(G))
|
||||
to_chat(preference_mob, span_warning("You cannot take \the [gear_name] as you are not whitelisted for the species or item."))
|
||||
active_gear_list -= gear_name
|
||||
continue
|
||||
|
||||
if(total_cost + G.cost > MAX_GEAR_COST)
|
||||
active_gear_list -= gear_name
|
||||
to_chat(preference_mob, span_warning("You cannot afford to take \the [gear_name]"))
|
||||
continue
|
||||
total_cost += G.cost
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["total_cost"] = get_total()
|
||||
data["gear_slot"] = pref.gear_slot
|
||||
var/list/active_gear_list = LAZYACCESS(pref.gear_list, "[pref.gear_slot]")
|
||||
data["active_gear_list"] = active_gear_list
|
||||
|
||||
var/list/gear_tweaks = list()
|
||||
for(var/item in active_gear_list)
|
||||
var/datum/gear/G = gear_datums[item]
|
||||
var/list/tweaks = list()
|
||||
for(var/datum/gear_tweak/tweak in G.gear_tweaks)
|
||||
UNTYPED_LIST_ADD(tweaks, list(
|
||||
"ref" = REF(tweak),
|
||||
"contents" = tweak.get_contents(get_tweak_metadata(G, tweak))
|
||||
))
|
||||
gear_tweaks[G.display_name] = tweaks
|
||||
data["gear_tweaks"] = gear_tweaks
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/tgui_static_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
var/list/categories = list()
|
||||
for(var/category in loadout_categories)
|
||||
var/datum/loadout_category/LC = loadout_categories[category]
|
||||
var/list/items = list()
|
||||
for(var/gear in LC.gear)
|
||||
var/datum/gear/G = LC.gear[gear]
|
||||
if(!is_valid_gear(G))
|
||||
continue
|
||||
|
||||
UNTYPED_LIST_ADD(items, list(
|
||||
"name" = G.display_name,
|
||||
"desc" = G.description,
|
||||
"cost" = G.cost,
|
||||
"show_roles" = G.show_roles,
|
||||
"allowed_roles" = G.allowed_roles
|
||||
))
|
||||
categories[category] = items
|
||||
data["categories"] = categories
|
||||
|
||||
data["max_gear_cost"] = MAX_GEAR_COST
|
||||
|
||||
return data
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/proc/get_gear_metadata(var/datum/gear/G)
|
||||
var/list/active_gear_list = LAZYACCESS(pref.gear_list, "[pref.gear_slot]")
|
||||
|
||||
// {"/datum/gear_tweak/custom_name": "" }
|
||||
. = LAZYACCESS(active_gear_list, G.display_name)
|
||||
if(!.)
|
||||
. = list()
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/proc/get_tweak_metadata(var/datum/gear/G, var/datum/gear_tweak/tweak)
|
||||
var/list/metadata = get_gear_metadata(G)
|
||||
. = metadata["[tweak]"]
|
||||
if(!.)
|
||||
. = tweak.get_default()
|
||||
metadata["[tweak]"] = .
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/proc/set_tweak_metadata(var/datum/gear/G, var/datum/gear_tweak/tweak, var/new_metadata)
|
||||
var/list/metadata = get_gear_metadata(G)
|
||||
metadata["[tweak]"] = new_metadata
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/proc/get_total()
|
||||
var/list/active_gear_list = LAZYACCESS(pref.gear_list, "[pref.gear_slot]")
|
||||
. = 0
|
||||
for(var/gear_name in active_gear_list)
|
||||
var/datum/gear/G = gear_datums[gear_name]
|
||||
if(G)
|
||||
. += G.cost
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/loadout/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/list/active_gear_list = LAZYACCESS(pref.gear_list, "[pref.gear_slot]")
|
||||
var/mob/user = ui.user
|
||||
|
||||
switch(action)
|
||||
if("next_slot")
|
||||
pref.gear_slot = pref.gear_slot + 1
|
||||
if(pref.gear_slot > CONFIG_GET(number/loadout_slots))
|
||||
pref.gear_slot = 1
|
||||
if(!("[pref.gear_slot]" in pref.gear_list))
|
||||
pref.gear_list["[pref.gear_slot]"] = list()
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("prev_slot")
|
||||
pref.gear_slot = pref.gear_slot - 1
|
||||
if(pref.gear_slot <= 0)
|
||||
pref.gear_slot = CONFIG_GET(number/loadout_slots)
|
||||
if(!("[pref.gear_slot]" in pref.gear_list))
|
||||
pref.gear_list["[pref.gear_slot]"] = list()
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("clear_loadout")
|
||||
active_gear_list.Cut()
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("copy_loadout")
|
||||
var/copy_to = tgui_input_number(user, "What slot would you like to copy slot [pref.gear_slot] to?", "Copy Slot", 1, CONFIG_GET(number/loadout_slots), 1)
|
||||
if(!copy_to)
|
||||
return TOPIC_HANDLED
|
||||
|
||||
if("[copy_to]" in pref.gear_list)
|
||||
var/confirm = tgui_alert(user, "This will overwrite slot [copy_to], are you sure?", "Are you sure?", list("No", "Yes"))
|
||||
if(confirm != "Yes")
|
||||
return TOPIC_HANDLED
|
||||
|
||||
pref.gear_list["[copy_to]"] = check_list_copy(active_gear_list)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("toggle_gear")
|
||||
var/datum/gear/TG = gear_datums[params["gear"]]
|
||||
if(TG)
|
||||
if(TG.display_name in active_gear_list)
|
||||
active_gear_list -= TG.display_name
|
||||
else if(get_total() + TG.cost <= MAX_GEAR_COST)
|
||||
active_gear_list[TG.display_name] = list()
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
if("gear_tweak")
|
||||
var/datum/gear/gear = gear_datums[params["gear"]]
|
||||
var/datum/gear_tweak/tweak = locate(params["tweak"])
|
||||
if(!tweak || !gear || !(tweak in gear.gear_tweaks))
|
||||
return TOPIC_HANDLED
|
||||
var/metadata = tweak.get_metadata(user, get_tweak_metadata(gear, tweak))
|
||||
if(!metadata)
|
||||
return TOPIC_HANDLED
|
||||
set_tweak_metadata(gear, tweak, metadata)
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
/datum/gear
|
||||
var/display_name //Name/index. Must be unique.
|
||||
var/description //Description of this gear. If left blank will default to the description of the pathed item.
|
||||
var/path //Path to item.
|
||||
var/cost = 1 //Number of points used. Items in general cost 1 point, storage/armor/gloves/special use costs 2 points.
|
||||
var/slot //Slot to equip to.
|
||||
var/list/allowed_roles //Roles that can spawn with this item.
|
||||
var/show_roles = TRUE //Show the role restrictions on this item?
|
||||
var/whitelisted //Term to check the whitelist for..
|
||||
var/sort_category = "General"
|
||||
var/list/gear_tweaks = list() //List of datums which will alter the item after it has been spawned.
|
||||
var/exploitable = 0 //Does it go on the exploitable information list?
|
||||
var/type_category = null
|
||||
var/list/ckeywhitelist //restricted based on these ckeys?
|
||||
var/list/character_name //restricted to these character names?
|
||||
|
||||
/datum/gear/New()
|
||||
..()
|
||||
if(!description)
|
||||
var/obj/O = path
|
||||
description = initial(O.desc)
|
||||
gear_tweaks = list(gear_tweak_free_name, gear_tweak_free_desc, GLOB.gear_tweak_item_tf_spawn, GLOB.gear_tweak_free_matrix_recolor)
|
||||
|
||||
/datum/gear_data
|
||||
var/path
|
||||
var/location
|
||||
|
||||
/datum/gear_data/New(var/path, var/location)
|
||||
src.path = path
|
||||
src.location = location
|
||||
|
||||
/datum/gear/proc/spawn_item(var/location, var/metadata)
|
||||
var/datum/gear_data/gd = new(path, location)
|
||||
if(length(gear_tweaks) && metadata)
|
||||
for(var/datum/gear_tweak/gt in gear_tweaks)
|
||||
gt.tweak_gear_data(metadata["[gt]"], gd)
|
||||
var/item = new gd.path(gd.location)
|
||||
if(length(gear_tweaks) && metadata)
|
||||
for(var/datum/gear_tweak/gt in gear_tweaks)
|
||||
gt.tweak_item(item, metadata["[gt]"])
|
||||
var/mob/M = location
|
||||
if(istype(M) && exploitable) //Update exploitable info records for the mob without creating a duplicate object at their feet.
|
||||
M.amend_exploitable(item)
|
||||
return item
|
||||
@@ -1,304 +0,0 @@
|
||||
var/list/loadout_categories = list()
|
||||
var/list/gear_datums = list()
|
||||
|
||||
/datum/loadout_category
|
||||
var/category = ""
|
||||
var/list/gear = list()
|
||||
|
||||
/datum/loadout_category/New(var/cat)
|
||||
category = cat
|
||||
..()
|
||||
|
||||
/hook/startup/proc/populate_gear_list()
|
||||
|
||||
//create a list of gear datums to sort
|
||||
for(var/datum/gear/G as anything in subtypesof(/datum/gear))
|
||||
if(initial(G.type_category) == G)
|
||||
continue
|
||||
var/use_name = initial(G.display_name)
|
||||
var/use_category = initial(G.sort_category)
|
||||
|
||||
if(!use_name)
|
||||
error("Loadout - Missing display name: [G]")
|
||||
continue
|
||||
if(isnull(initial(G.cost)))
|
||||
error("Loadout - Missing cost: [G]")
|
||||
continue
|
||||
if(!initial(G.path))
|
||||
error("Loadout - Missing path definition: [G]")
|
||||
continue
|
||||
|
||||
if(!loadout_categories[use_category])
|
||||
loadout_categories[use_category] = new /datum/loadout_category(use_category)
|
||||
var/datum/loadout_category/LC = loadout_categories[use_category]
|
||||
gear_datums[use_name] = new G
|
||||
LC.gear[use_name] = gear_datums[use_name]
|
||||
|
||||
loadout_categories = sortAssoc(loadout_categories)
|
||||
for(var/loadout_category in loadout_categories)
|
||||
var/datum/loadout_category/LC = loadout_categories[loadout_category]
|
||||
LC.gear = sortAssoc(LC.gear)
|
||||
return 1
|
||||
|
||||
/datum/category_item/player_setup_item/loadout
|
||||
name = "Loadout"
|
||||
sort_order = 1
|
||||
var/current_tab = "General"
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/load_character(list/save_data)
|
||||
pref.gear_list = list()
|
||||
var/all_gear = check_list_copy(save_data["gear_list"])
|
||||
for(var/i in all_gear)
|
||||
var/list/entries = check_list_copy(all_gear["[i]"])
|
||||
for(var/j in entries)
|
||||
entries["[j]"] = path2text_list(entries["[j]"])
|
||||
pref.gear_list["[i]"] = entries
|
||||
pref.gear_slot = save_data["gear_slot"]
|
||||
if(pref.gear_list!=null && pref.gear_slot!=null)
|
||||
pref.gear = pref.gear_list["[pref.gear_slot]"]
|
||||
else
|
||||
pref.gear = check_list_copy(save_data["gear"])
|
||||
pref.gear_slot = 1
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/save_character(list/save_data)
|
||||
pref.gear_list["[pref.gear_slot]"] = pref.gear
|
||||
var/list/all_gear = list()
|
||||
var/worn_gear = check_list_copy(pref.gear_list)
|
||||
for(var/i in worn_gear)
|
||||
var/list/entries = check_list_copy(worn_gear["[i]"])
|
||||
if(!length(entries))
|
||||
entries = check_list_copy(worn_gear[i])
|
||||
for(var/j in entries)
|
||||
entries["[j]"] = check_list_copy(entries["[j]"])
|
||||
all_gear["[i]"] = entries
|
||||
save_data["gear_list"] = all_gear
|
||||
save_data["gear_slot"] = pref.gear_slot
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/proc/valid_gear_choices(var/max_cost)
|
||||
. = list()
|
||||
for(var/gear_name in gear_datums)
|
||||
var/datum/gear/G = gear_datums[gear_name]
|
||||
|
||||
if(G.whitelisted && CONFIG_GET(flag/loadout_whitelist) != LOADOUT_WHITELIST_OFF && pref.client) //VOREStation Edit.
|
||||
if(CONFIG_GET(flag/loadout_whitelist) == LOADOUT_WHITELIST_STRICT && G.whitelisted != pref.species)
|
||||
continue
|
||||
if(CONFIG_GET(flag/loadout_whitelist) == LOADOUT_WHITELIST_LAX && !is_alien_whitelisted(pref.client, GLOB.all_species[G.whitelisted]))
|
||||
continue
|
||||
|
||||
if(max_cost && G.cost > max_cost)
|
||||
continue
|
||||
if(pref.client)
|
||||
if(G.ckeywhitelist && !(pref.client_ckey in G.ckeywhitelist))
|
||||
continue
|
||||
if(G.character_name && pref.client.prefs && !(pref.client.prefs.real_name in G.character_name))
|
||||
continue
|
||||
. += gear_name
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/sanitize_character()
|
||||
var/mob/preference_mob = preference_mob()
|
||||
if(!islist(pref.gear))
|
||||
pref.gear = list()
|
||||
if(!islist(pref.gear_list))
|
||||
pref.gear_list = list()
|
||||
|
||||
for(var/gear_name in pref.gear)
|
||||
if(!(gear_name in gear_datums))
|
||||
pref.gear -= gear_name
|
||||
var/total_cost = 0
|
||||
for(var/gear_name in pref.gear)
|
||||
if(!gear_datums[gear_name])
|
||||
to_chat(preference_mob, span_warning("You cannot have more than one of the \the [gear_name]"))
|
||||
pref.gear -= gear_name
|
||||
else if(!(gear_name in valid_gear_choices()))
|
||||
to_chat(preference_mob, span_warning("You cannot take \the [gear_name] as you are not whitelisted for the species or item.")) //Vorestation Edit
|
||||
pref.gear -= gear_name
|
||||
else
|
||||
var/datum/gear/G = gear_datums[gear_name]
|
||||
if(total_cost + G.cost > MAX_GEAR_COST)
|
||||
pref.gear -= gear_name
|
||||
to_chat(preference_mob, span_warning("You cannot afford to take \the [gear_name]"))
|
||||
else
|
||||
total_cost += G.cost
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/content()
|
||||
. = list()
|
||||
var/mob/preference_mob = preference_mob() //Vorestation Edit
|
||||
var/total_cost = 0
|
||||
if(pref.gear && pref.gear.len)
|
||||
for(var/i = 1; i <= pref.gear.len; i++)
|
||||
var/datum/gear/G = gear_datums[pref.gear[i]]
|
||||
if(G)
|
||||
total_cost += G.cost
|
||||
|
||||
var/fcolor = "#3366CC"
|
||||
if(total_cost < MAX_GEAR_COST)
|
||||
fcolor = "#E67300"
|
||||
|
||||
. += "<table align = 'center' width = 100%>"
|
||||
. += "<tr><td colspan=3><center><a href='byond://?src=\ref[src];prev_slot=1'>\<\<</a>" + span_bold("<font color = '[fcolor]'>\[[pref.gear_slot]\]</font> ") + "<a href='byond://?src=\ref[src];next_slot=1'>\>\></a>" + span_bold("<font color = '[fcolor]'>[total_cost]/[MAX_GEAR_COST]</font> loadout points spent.") + " \[<a href='byond://?src=\ref[src];clear_loadout=1'>Clear Loadout</a>\]</center></td></tr>"
|
||||
|
||||
. += "<tr><td colspan=3><center><b>"
|
||||
var/firstcat = 1
|
||||
for(var/category in loadout_categories)
|
||||
|
||||
if(firstcat)
|
||||
firstcat = 0
|
||||
else
|
||||
. += " |"
|
||||
|
||||
var/datum/loadout_category/LC = loadout_categories[category]
|
||||
var/category_cost = 0
|
||||
for(var/gear in LC.gear)
|
||||
if(gear in pref.gear)
|
||||
var/datum/gear/G = LC.gear[gear]
|
||||
category_cost += G.cost
|
||||
|
||||
if(category == current_tab)
|
||||
. += " " + span_linkOn("[category] - [category_cost]") + " "
|
||||
else
|
||||
if(category_cost)
|
||||
. += " <a href='byond://?src=\ref[src];select_category=[category]'><font color = '#E67300'>[category] - [category_cost]</font></a> "
|
||||
else
|
||||
. += " <a href='byond://?src=\ref[src];select_category=[category]'>[category] - 0</a> "
|
||||
. += "</b></center></td></tr>"
|
||||
|
||||
var/datum/loadout_category/LC = loadout_categories[current_tab]
|
||||
. += "<tr><td colspan=3><hr></td></tr>"
|
||||
. += "<tr><td colspan=3>" + span_bold("<center>[LC.category]</center>") + "</td></tr>"
|
||||
. += "<tr><td colspan=3><hr></td></tr>"
|
||||
for(var/gear_name in LC.gear)
|
||||
var/datum/gear/G = LC.gear[gear_name]
|
||||
if(preference_mob && preference_mob.client)
|
||||
if(G.ckeywhitelist && !(preference_mob.ckey in G.ckeywhitelist))
|
||||
continue
|
||||
if(G.character_name && preference_mob.client.prefs && !(preference_mob.client.prefs.real_name in G.character_name))
|
||||
continue
|
||||
var/ticked = (G.display_name in pref.gear)
|
||||
. += "<tr style='vertical-align:top;'><td width=25%><a style='white-space:normal;' [ticked ? "class='linkOn' " : ""]href='byond://?src=\ref[src];toggle_gear=[html_encode(G.display_name)]'>[G.display_name]</a></td>"
|
||||
. += "<td width = 10% style='vertical-align:top'>[G.cost]</td>"
|
||||
. += "<td>" + span_normal(span_italics("[G.description]")) + "</td></tr>"
|
||||
if(G.show_roles && G.allowed_roles)
|
||||
. += "<td colspan=3> Restricted to: [list2text(G.allowed_roles,", ")]</td>"
|
||||
if(ticked)
|
||||
. += "<tr><td colspan=3>"
|
||||
for(var/datum/gear_tweak/tweak in G.gear_tweaks)
|
||||
. += " <a href='byond://?src=\ref[src];gear=[url_encode(G.display_name)];tweak=\ref[tweak]'>[tweak.get_contents(get_tweak_metadata(G, tweak))]</a>"
|
||||
. += "</td></tr>"
|
||||
. += "</table>"
|
||||
. = jointext(., null)
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/proc/get_gear_metadata(var/datum/gear/G)
|
||||
. = pref.gear[G.display_name]
|
||||
if(!.)
|
||||
. = list()
|
||||
pref.gear[G.display_name] = .
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/proc/get_tweak_metadata(var/datum/gear/G, var/datum/gear_tweak/tweak)
|
||||
var/list/metadata = get_gear_metadata(G)
|
||||
. = metadata["[tweak]"]
|
||||
if(!.)
|
||||
. = tweak.get_default()
|
||||
metadata["[tweak]"] = .
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/proc/set_tweak_metadata(var/datum/gear/G, var/datum/gear_tweak/tweak, var/new_metadata)
|
||||
var/list/metadata = get_gear_metadata(G)
|
||||
metadata["[tweak]"] = new_metadata
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/OnTopic(href, href_list, user)
|
||||
if(href_list["toggle_gear"])
|
||||
var/datum/gear/TG = gear_datums[href_list["toggle_gear"]]
|
||||
if(TG.display_name in pref.gear)
|
||||
pref.gear -= TG.display_name
|
||||
else
|
||||
var/total_cost = 0
|
||||
for(var/gear_name in pref.gear)
|
||||
var/datum/gear/G = gear_datums[gear_name]
|
||||
if(istype(G)) total_cost += G.cost
|
||||
if((total_cost+TG.cost) <= MAX_GEAR_COST)
|
||||
pref.gear += TG.display_name
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
if(href_list["gear"] && href_list["tweak"])
|
||||
var/datum/gear/gear = gear_datums[url_decode(href_list["gear"])]
|
||||
var/datum/gear_tweak/tweak = locate(href_list["tweak"])
|
||||
if(!tweak || !istype(gear) || !(tweak in gear.gear_tweaks))
|
||||
return TOPIC_NOACTION
|
||||
var/metadata = tweak.get_metadata(user, get_tweak_metadata(gear, tweak))
|
||||
if(!metadata || !CanUseTopic(user))
|
||||
return TOPIC_NOACTION
|
||||
set_tweak_metadata(gear, tweak, metadata)
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
if(href_list["next_slot"] || href_list["prev_slot"])
|
||||
//Set the current slot in the gear list to the currently selected gear
|
||||
pref.gear_list["[pref.gear_slot]"] = pref.gear
|
||||
//If we're moving up a slot..
|
||||
if(href_list["next_slot"])
|
||||
//change the current slot number
|
||||
pref.gear_slot = pref.gear_slot+1
|
||||
if(pref.gear_slot > CONFIG_GET(number/loadout_slots))
|
||||
pref.gear_slot = 1
|
||||
//If we're moving down a slot..
|
||||
else if(href_list["prev_slot"])
|
||||
//change current slot one down
|
||||
pref.gear_slot = pref.gear_slot-1
|
||||
if(pref.gear_slot<1)
|
||||
pref.gear_slot = CONFIG_GET(number/loadout_slots)
|
||||
// Set the currently selected gear to whatever's in the new slot
|
||||
if(pref.gear_list["[pref.gear_slot]"])
|
||||
pref.gear = pref.gear_list["[pref.gear_slot]"]
|
||||
else
|
||||
pref.gear = list()
|
||||
pref.gear_list["[pref.gear_slot]"] = list()
|
||||
// Refresh?
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
else if(href_list["select_category"])
|
||||
current_tab = href_list["select_category"]
|
||||
return TOPIC_REFRESH
|
||||
else if(href_list["clear_loadout"])
|
||||
pref.gear.Cut()
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
return ..()
|
||||
|
||||
/datum/gear
|
||||
var/display_name //Name/index. Must be unique.
|
||||
var/description //Description of this gear. If left blank will default to the description of the pathed item.
|
||||
var/path //Path to item.
|
||||
var/cost = 1 //Number of points used. Items in general cost 1 point, storage/armor/gloves/special use costs 2 points.
|
||||
var/slot //Slot to equip to.
|
||||
var/list/allowed_roles //Roles that can spawn with this item.
|
||||
var/show_roles = TRUE //Show the role restrictions on this item?
|
||||
var/whitelisted //Term to check the whitelist for..
|
||||
var/sort_category = "General"
|
||||
var/list/gear_tweaks = list() //List of datums which will alter the item after it has been spawned.
|
||||
var/exploitable = 0 //Does it go on the exploitable information list?
|
||||
var/type_category = null
|
||||
var/list/ckeywhitelist //restricted based on these ckeys?
|
||||
var/list/character_name //restricted to these character names?
|
||||
|
||||
/datum/gear/New()
|
||||
..()
|
||||
if(!description)
|
||||
var/obj/O = path
|
||||
description = initial(O.desc)
|
||||
gear_tweaks = list(gear_tweak_free_name, gear_tweak_free_desc, GLOB.gear_tweak_item_tf_spawn, GLOB.gear_tweak_free_matrix_recolor)
|
||||
|
||||
/datum/gear_data
|
||||
var/path
|
||||
var/location
|
||||
|
||||
/datum/gear_data/New(var/path, var/location)
|
||||
src.path = path
|
||||
src.location = location
|
||||
|
||||
/datum/gear/proc/spawn_item(var/location, var/metadata)
|
||||
var/datum/gear_data/gd = new(path, location)
|
||||
if(length(gear_tweaks) && metadata)
|
||||
for(var/datum/gear_tweak/gt in gear_tweaks)
|
||||
gt.tweak_gear_data(metadata["[gt]"], gd)
|
||||
var/item = new gd.path(gd.location)
|
||||
if(length(gear_tweaks) && metadata)
|
||||
for(var/datum/gear_tweak/gt in gear_tweaks)
|
||||
gt.tweak_item(item, metadata["[gt]"])
|
||||
var/mob/M = location
|
||||
if(istype(M) && exploitable) //Update exploitable info records for the mob without creating a duplicate object at their feet.
|
||||
M.amend_exploitable(item)
|
||||
return item
|
||||
Reference in New Issue
Block a user