Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ports TGUI Select Equipment menu #11337

Merged
merged 16 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions beestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -1771,6 +1771,8 @@
#include "code\modules\admin\holder2.dm"
#include "code\modules\admin\ipintel.dm"
#include "code\modules\admin\IsBanned.dm"
#include "code\modules\admin\outfit_editor.dm"
#include "code\modules\admin\outfit_manager.dm"
#include "code\modules\admin\outfits.dm"
#include "code\modules\admin\permissionedit.dm"
#include "code\modules\admin\player_panel.dm"
Expand Down Expand Up @@ -1854,6 +1856,7 @@
#include "code\modules\admin\verbs\randomverbs.dm"
#include "code\modules\admin\verbs\reestablish_db_connection.dm"
#include "code\modules\admin\verbs\requests.dm"
#include "code\modules\admin\verbs\selectequipment.dm"
#include "code\modules\admin\verbs\shuttlepanel.dm"
#include "code\modules\admin\verbs\spawnfloorcluwne.dm"
#include "code\modules\admin\verbs\spawnobjasmob.dm"
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/preferences.dm
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ GLOBAL_LIST_INIT(helmet_styles, list(
#define PREFERENCE_TAG_KEYBINDS "key_bindings"
#define PREFERENCE_TAG_PURCHASED_GEAR "purchased_gear"
#define PREFERENCE_TAG_ROLE_PREFERENCES_GLOBAL "be_special"
#define PREFERENCE_TAG_FAVORITE_OUTFITS "favorite_outfits"
#define PREFERENCE_TAG_PAI_NAME "pai_name"
#define PREFERENCE_TAG_PAI_DESCRIPTION "pai_description"
#define PREFERENCE_TAG_PAI_COMMENT "pai_comment"
Expand All @@ -151,6 +152,7 @@ GLOBAL_LIST_INIT(undatumized_preference_tags_player, list(
PREFERENCE_TAG_KEYBINDS,
PREFERENCE_TAG_PURCHASED_GEAR,
PREFERENCE_TAG_ROLE_PREFERENCES_GLOBAL,
PREFERENCE_TAG_FAVORITE_OUTFITS,
PREFERENCE_TAG_PAI_NAME,
PREFERENCE_TAG_PAI_DESCRIPTION,
PREFERENCE_TAG_PAI_COMMENT,
Expand Down
3 changes: 3 additions & 0 deletions code/__DEFINES/vv.dm
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@
// paintings
#define VV_HK_REMOVE_PAINTING "remove_painting"

//outfits
#define VV_HK_TO_OUTFIT_EDITOR "outfit_editor"

// Flags for debug_variable() that do little things to what we end up rendering

/// ALWAYS render a reduced list, useful for fuckoff big datums that need to be condensed for the sake of client load
Expand Down
46 changes: 23 additions & 23 deletions code/__HELPERS/icons.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1109,32 +1109,32 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)

/// # If you already have a human and need to get its flat icon, call `get_flat_existing_human_icon()` instead.
/// For creating consistent icons for human looking simple animals.
/proc/get_flat_human_icon(icon_id, datum/job/J, datum/preferences/prefs, dummy_key, showDirs = GLOB.cardinals, outfit_override = null)
/proc/get_flat_human_icon(icon_id, datum/job/job, datum/preferences/prefs, dummy_key, showDirs = GLOB.cardinals, outfit_override = null)
var/static/list/humanoid_icon_cache = list()
if(!icon_id || !humanoid_icon_cache[icon_id])
var/mob/living/carbon/human/dummy/body = generate_or_wait_for_human_dummy(dummy_key)

if(prefs)
prefs.apply_prefs_to(body, icon_updates = TRUE)
if(J)
J.equip(body, TRUE, FALSE, outfit_override = outfit_override)
else if (outfit_override)
body.equipOutfit(outfit_override,visualsOnly = TRUE)


var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing")
for(var/D in showDirs)
body.setDir(D)
COMPILE_OVERLAYS(body)
var/icon/partial = getFlatIcon(body)
out_icon.Insert(partial,dir=D)

humanoid_icon_cache[icon_id] = out_icon
dummy_key? unset_busy_human_dummy(dummy_key) : qdel(body)
return out_icon
else
if(icon_id && humanoid_icon_cache[icon_id])
return humanoid_icon_cache[icon_id]

var/mob/living/carbon/human/dummy/body = generate_or_wait_for_human_dummy(dummy_key)

if(prefs)
prefs.apply_prefs_to(body, icon_updates = TRUE)

var/datum/outfit/outfit = outfit_override || job?.outfit
if(job)
job.equip(body, TRUE, FALSE, outfit_override = outfit_override)
if(outfit)
body.equipOutfit(outfit_override,visualsOnly = TRUE)

var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing")
COMPILE_OVERLAYS(body)
for(var/D in showDirs)
var/icon/partial = getFlatIcon(body, defdir=D)
out_icon.Insert(partial,dir=D)

humanoid_icon_cache[icon_id] = out_icon
dummy_key? unset_busy_human_dummy(dummy_key) : qdel(body)
return out_icon

/**
* A simpler version of get_flat_human_icon() that uses an existing human as a base to create the icon.
* Does not feature caching yet, since I could not think of a good way to cache them without having a possibility
Expand Down
33 changes: 33 additions & 0 deletions code/controllers/subsystem/persistence.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ SUBSYSTEM_DEF(persistence)
if(CONFIG_GET(flag/use_antag_rep))
LoadAntagReputation()
LoadPaintings()
load_custom_outfits()
return SS_INIT_SUCCESS

/datum/controller/subsystem/persistence/proc/LoadPoly()
Expand Down Expand Up @@ -162,6 +163,7 @@ SUBSYSTEM_DEF(persistence)
if(CONFIG_GET(flag/use_antag_rep))
CollectAntagReputation()
SavePaintings()
save_custom_outfits()

/datum/controller/subsystem/persistence/proc/GetPhotoAlbums()
var/album_path = file("data/photo_albums.json")
Expand Down Expand Up @@ -331,4 +333,35 @@ SUBSYSTEM_DEF(persistence)
fdel(json_file)
WRITE_FILE(json_file, json_encode(paintings))

/datum/controller/subsystem/persistence/proc/load_custom_outfits()
var/file = file("data/custom_outfits.json")
if(!fexists(file))
return
var/outfits_json = file2text(file)
var/list/outfits = json_decode(outfits_json)
if(!islist(outfits))
return

for(var/outfit_data in outfits)
if(!islist(outfit_data))
continue

var/outfittype = text2path(outfit_data["outfit_type"])
if(!ispath(outfittype, /datum/outfit))
continue
var/datum/outfit/outfit = new outfittype
if(!outfit.load_from(outfit_data))
continue
GLOB.custom_outfits += outfit

/datum/controller/subsystem/persistence/proc/save_custom_outfits()
var/file = file("data/custom_outfits.json")
fdel(file)

var/list/data = list()
for(var/datum/outfit/outfit in GLOB.custom_outfits)
data += list(outfit.get_json_data())

WRITE_FILE(file, json_encode(data))

#undef FILE_ANTAG_REP
75 changes: 56 additions & 19 deletions code/datums/outfit.dm
Original file line number Diff line number Diff line change
Expand Up @@ -240,42 +240,42 @@
if(!istype(H) && !ismonkey(H))
return
if(H.back)
H.back.add_fingerprint(H,1) //The 1 sets a flag to ignore gloves
H.back.add_fingerprint(H, ignoregloves = TRUE)
for(var/obj/item/I in H.back.contents)
I.add_fingerprint(H,1)
I.add_fingerprint(H, ignoregloves = TRUE)
if(H.wear_id)
H.wear_id.add_fingerprint(H,1)
H.wear_id.add_fingerprint(H, ignoregloves = TRUE)
if(H.w_uniform)
H.w_uniform.add_fingerprint(H,1)
H.w_uniform.add_fingerprint(H, ignoregloves = TRUE)
if(H.wear_suit)
H.wear_suit.add_fingerprint(H,1)
H.wear_suit.add_fingerprint(H, ignoregloves = TRUE)
if(H.wear_mask)
H.wear_mask.add_fingerprint(H,1)
H.wear_mask.add_fingerprint(H, ignoregloves = TRUE)
if(H.wear_neck)
H.wear_neck.add_fingerprint(H,1)
H.wear_neck.add_fingerprint(H, ignoregloves = TRUE)
if(H.head)
H.head.add_fingerprint(H,1)
H.head.add_fingerprint(H, ignoregloves = TRUE)
if(H.shoes)
H.shoes.add_fingerprint(H,1)
H.shoes.add_fingerprint(H, ignoregloves = TRUE)
if(H.gloves)
H.gloves.add_fingerprint(H,1)
H.gloves.add_fingerprint(H, ignoregloves = TRUE)
if(H.ears)
H.ears.add_fingerprint(H,1)
H.ears.add_fingerprint(H, ignoregloves = TRUE)
if(H.glasses)
H.glasses.add_fingerprint(H,1)
H.glasses.add_fingerprint(H, ignoregloves = TRUE)
if(H.belt)
H.belt.add_fingerprint(H,1)
H.belt.add_fingerprint(H, ignoregloves = TRUE)
for(var/obj/item/I in H.belt.contents)
I.add_fingerprint(H,1)
I.add_fingerprint(H, ignoregloves = TRUE)
if(H.s_store)
H.s_store.add_fingerprint(H,1)
H.s_store.add_fingerprint(H, ignoregloves = TRUE)
if(H.l_store)
H.l_store.add_fingerprint(H,1)
H.l_store.add_fingerprint(H, ignoregloves = TRUE)
if(H.r_store)
H.r_store.add_fingerprint(H,1)
H.r_store.add_fingerprint(H, ignoregloves = TRUE)
for(var/obj/item/I in H.held_items)
I.add_fingerprint(H,1)
return 1
I.add_fingerprint(H, ignoregloves = TRUE)
return TRUE

/// Return a list of all the types that are required to disguise as this outfit type
/datum/outfit/proc/get_chameleon_disguise_info()
Expand Down Expand Up @@ -312,6 +312,33 @@
.["implants"] = implants
.["accessory"] = accessory

/// Copy most vars from another outfit to this one
/datum/outfit/proc/copy_from(datum/outfit/target)
name = target.name
uniform = target.uniform
suit = target.suit
toggle_helmet = target.toggle_helmet
back = target.back
belt = target.belt
gloves = target.gloves
shoes = target.shoes
head = target.head
mask = target.mask
neck = target.neck
ears = target.ears
glasses = target.glasses
id = target.id
l_pocket = target.l_pocket
r_pocket = target.r_pocket
suit_store = target.suit_store
r_hand = target.r_hand
l_hand = target.l_hand
internals_slot = target.internals_slot
backpack_contents = target.backpack_contents
box = target.box
implants = target.implants
accessory = target.accessory

/datum/outfit/proc/save_to_file(mob/admin)
var/stored_data = get_json_data()
var/json = json_encode(stored_data)
Expand Down Expand Up @@ -358,3 +385,13 @@
implants += imptype
accessory = text2path(outfit_data["accessory"])
return TRUE

/datum/outfit/vv_get_dropdown()
. = ..()
VV_DROPDOWN_OPTION("", "---")
VV_DROPDOWN_OPTION(VV_HK_TO_OUTFIT_EDITOR, "Outfit Editor")

/datum/outfit/vv_do_topic(list/href_list)
. = ..()
if(href_list[VV_HK_TO_OUTFIT_EDITOR])
usr.client.open_outfit_editor(src)
11 changes: 11 additions & 0 deletions code/game/objects/items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -712,13 +712,24 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item/proc/on_found(mob/finder)
return

/**
* To be overwritten to only perform visual tasks;
* this is directly called instead of `equipped` on visual-only features like human dummies equipping outfits.
*
* This separation exists to prevent things like the monkey sentience helmet from
* polling ghosts while it's just being equipped as a visual preview for a dummy.
*/
/obj/item/proc/visual_equipped(mob/user, slot, initial = FALSE)
return

// called after an item is placed in an equipment slot
// user is mob that equipped it
// slot uses the slot_X defines found in setup.dm
// for items that can be placed in multiple slots
// note this isn't called during the initial dressing of a player
/obj/item/proc/equipped(mob/user, slot, initial = FALSE)
SHOULD_CALL_PARENT(TRUE)
visual_equipped(user, slot, initial)
SEND_SIGNAL(src, COMSIG_ITEM_EQUIPPED, user, slot)
SEND_SIGNAL(user, COMSIG_MOB_EQUIPPED_ITEM, src, slot)
for(var/X in actions)
Expand Down
4 changes: 2 additions & 2 deletions code/modules/admin/admin_verbs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ GLOBAL_PROTECT(admin_verbs_ban)
GLOBAL_LIST_INIT(admin_verbs_sounds, list(/client/proc/play_local_sound, /client/proc/play_sound, /client/proc/set_round_end_sound, /client/proc/play_soundtrack))
GLOBAL_PROTECT(admin_verbs_sounds)
GLOBAL_LIST_INIT(admin_verbs_fun, list(
/client/proc/cmd_admin_dress,
/client/proc/cmd_select_equipment,
/client/proc/cmd_admin_gib_self,
/client/proc/drop_bomb,
/client/proc/set_dynex_scale,
Expand Down Expand Up @@ -237,7 +237,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
/client/proc/play_sound,
/client/proc/set_round_end_sound,
/client/proc/play_soundtrack,
/client/proc/cmd_admin_dress,
/client/proc/cmd_select_equipment,
/client/proc/cmd_admin_gib_self,
/client/proc/drop_bomb,
/client/proc/drop_dynex_bomb,
Expand Down
Loading
Loading