diff --git a/code/datums/outfits/outfit.dm b/code/datums/outfits/outfit.dm index 184f1155da2..0134a62d7fb 100644 --- a/code/datums/outfits/outfit.dm +++ b/code/datums/outfits/outfit.dm @@ -27,6 +27,8 @@ var/list/chameleon_extras //extra types for chameleon outfit changes, mostly guns + var/can_be_admin_equipped = TRUE // Set to FALSE if your outfit requires runtime parameters + /datum/outfit/proc/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) //to be overriden for customization depending on client prefs,species etc return @@ -159,3 +161,72 @@ types += chameleon_extras listclearnulls(types) return types + +/datum/outfit/proc/save_to_file(mob/admin) + var/stored_data = get_json_data() + var/json = json_encode(stored_data) + //Kinda annoying but as far as i can tell you need to make actual file. + var/f = file("data/TempOutfitUpload") + fdel(f) + WRITE_FILE(f,json) + admin << ftp(f, "[name].json") + +/datum/outfit/proc/load_from(list/outfit_data) + //This could probably use more strict validation + name = outfit_data["name"] + uniform = text2path(outfit_data["uniform"]) + suit = text2path(outfit_data["suit"]) + back = text2path(outfit_data["back"]) + belt = text2path(outfit_data["belt"]) + gloves = text2path(outfit_data["gloves"]) + shoes = text2path(outfit_data["shoes"]) + head = text2path(outfit_data["head"]) + mask = text2path(outfit_data["mask"]) + l_ear = text2path(outfit_data["l_ear"]) + r_ear = text2path(outfit_data["r_ear"]) + glasses = text2path(outfit_data["glasses"]) + id = text2path(outfit_data["id"]) + l_pocket = text2path(outfit_data["l_pocket"]) + r_pocket = text2path(outfit_data["r_pocket"]) + suit_store = text2path(outfit_data["suit_store"]) + r_hand = text2path(outfit_data["r_hand"]) + l_hand = text2path(outfit_data["l_hand"]) + internals_slot = outfit_data["internals_slot"] + var/list/backpack = outfit_data["backpack_contents"] + backpack_contents = list() + for(var/item in backpack) + var/itype = text2path(item) + if(itype) + backpack_contents[itype] = backpack[item] + var/list/impl = outfit_data["implants"] + implants = list() + for(var/I in impl) + var/imptype = text2path(I) + if(imptype) + implants += imptype + return TRUE + +/datum/outfit/proc/get_json_data() + . = list() + .["outfit_type"] = type + .["name"] = name + .["uniform"] = uniform + .["suit"] = suit + .["back"] = back + .["belt"] = belt + .["gloves"] = gloves + .["shoes"] = shoes + .["head"] = head + .["mask"] = mask + .["l_ear"] = l_ear + .["r_ear"] = r_ear + .["glasses"] = glasses + .["id"] = id + .["l_pocket"] = l_pocket + .["r_pocket"] = r_pocket + .["suit_store"] = suit_store + .["r_hand"] = r_hand + .["l_hand"] = l_hand + .["internals_slot"] = internals_slot + .["backpack_contents"] = backpack_contents + .["implants"] = implants \ No newline at end of file diff --git a/code/datums/outfits/vv_outfit.dm b/code/datums/outfits/vv_outfit.dm new file mode 100644 index 00000000000..5a4791eea89 --- /dev/null +++ b/code/datums/outfits/vv_outfit.dm @@ -0,0 +1,172 @@ +// This outfit preserves varedits made on the items +// Created from admin helpers. +/datum/outfit/varedit + var/list/vv_values + var/list/stored_access + var/update_id_name = FALSE //If the name of the human is same as the name on the id they're wearing we'll update provided id when equipping + +/datum/outfit/varedit/pre_equip(mob/living/carbon/human/H, visualsOnly) + H.delete_equipment() //Applying VV to wrong objects is not reccomended. + . = ..() + +/datum/outfit/varedit/proc/set_equipment_by_slot(slot, item_path) + switch(slot) + if(slot_w_uniform) + uniform = item_path + if(slot_back) + back = item_path + if(slot_wear_suit) + suit = item_path + if(slot_belt) + belt = item_path + if(slot_gloves) + gloves = item_path + if(slot_shoes) + shoes = item_path + if(slot_head) + head = item_path + if(slot_wear_mask) + mask = item_path + if(slot_l_ear) + l_ear = item_path + if(slot_r_ear) + r_ear = item_path + if(slot_glasses) + glasses = item_path + if(slot_wear_id) + id = item_path + if(slot_s_store) + suit_store = item_path + if(slot_l_store) + l_pocket = item_path + if(slot_r_store) + r_pocket = item_path + + +/proc/collect_vv(obj/item/I) + //Temporary/Internal stuff, do not copy these. + var/static/list/ignored_vars = list("vars","x","y","z","plane","layer","override","animate_movement","pixel_step_size","screen_loc","fingerprintslast","tip_timer") + + if(istype(I)) + var/list/vedits = list() + for(var/varname in I.vars) + if(!I.can_vv_get(varname)) + continue + if(varname in ignored_vars) + continue + var/vval = I.vars[varname] + //Does it even work ? + if(vval == initial(I.vars[varname])) + continue + //Only text/numbers and icons variables to make it less weirdness prone. + if(!istext(vval) && !isnum(vval) && !isicon(vval)) + continue + vedits[varname] = I.vars[varname] + return vedits + +/mob/living/carbon/human/proc/copy_outfit() + var/datum/outfit/varedit/O = new + + //Copy equipment + var/list/result = list() + var/list/slots_to_check = list(slot_w_uniform, slot_back, slot_wear_suit, slot_belt, slot_gloves, slot_shoes, slot_head, slot_wear_mask, slot_l_ear, slot_r_ear, slot_glasses, slot_wear_id, slot_s_store, slot_l_store, slot_r_store) + for(var/s in slots_to_check) + var/obj/item/I = get_item_by_slot(s) + var/vedits = collect_vv(I) + if(vedits) + result["[s]"] = vedits + if(istype(I)) + O.set_equipment_by_slot(s, I.type) + + //Copy access + O.stored_access = list() + var/obj/item/id_slot = get_item_by_slot(slot_wear_id) + if(id_slot) + O.stored_access |= id_slot.GetAccess() + var/obj/item/card/id/ID = id_slot.GetID() + if(ID && ID.registered_name == real_name) + O.update_id_name = TRUE + //Copy hands + if(l_hand && r_hand) //Not in the mood to let outfits transfer amputees + var/obj/item/left_hand = l_hand + var/obj/item/right_hand = r_hand + if(istype(left_hand)) + O.l_hand = left_hand.type + var/vedits = collect_vv(left_hand) + if(vedits) + result["LHAND"] = vedits + if(istype(right_hand)) + O.r_hand = right_hand.type + var/vedits = collect_vv(left_hand) + if(vedits) + result["RHAND"] = vedits + O.vv_values = result + //Copy backpack contents if exist. + var/obj/item/backpack = get_item_by_slot(slot_back) + if(istype(backpack) && SEND_SIGNAL(backpack, COMSIG_CONTAINS_STORAGE)) + var/list/bp_stuff = list() + var/list/typecounts = list() + SEND_SIGNAL(backpack, COMSIG_TRY_STORAGE_RETURN_INVENTORY, bp_stuff, FALSE) + for(var/obj/item/I in bp_stuff) + if(typecounts[I.type]) + typecounts[I.type] += 1 + else + typecounts[I.type] = 1 + O.backpack_contents = typecounts + //TODO : Copy varedits from backpack stuff too. + //Copy implants + O.implants = list() + for(var/obj/item/implant/I in contents) + if(istype(I)) + O.implants |= I.type + //Copy to outfit cache + var/outfit_name = stripped_input(usr, "Enter the outfit name") + O.name = outfit_name + GLOB.custom_outfits += O + to_chat(usr, "Outfit registered, use select equipment to equip it.") + +/datum/outfit/varedit/post_equip(mob/living/carbon/human/H, visualsOnly) + . = ..() + //Apply VV + for(var/slot in vv_values) + var/list/edits = vv_values[slot] + var/obj/item/I + switch(slot) + if("LHAND") + I = H.l_hand + if("RHAND") + I = H.r_hand + else + I = H.get_item_by_slot(text2num(slot)) + for(var/vname in edits) + I.vv_edit_var(vname,edits[vname]) + //Apply access + var/obj/item/id_slot = H.get_item_by_slot(slot_wear_id) + if(id_slot) + var/obj/item/card/id/card = id_slot.GetID() + if(istype(card)) + card.access |= stored_access + if(update_id_name) + card.registered_name = H.real_name + card.update_label() + +/datum/outfit/varedit/get_json_data() + . = .. () + .["stored_access"] = stored_access + .["update_id_name"] = update_id_name + var/list/stripped_vv = list() + for(var/slot in vv_values) + var/list/vedits = vv_values[slot] + var/list/stripped_edits = list() + for(var/edit in vedits) + if(istext(vedits[edit]) || isnum(vedits[edit]) || isnull(vedits[edit])) + stripped_edits[edit] = vedits[edit] + if(stripped_edits.len) + stripped_vv[slot] = stripped_edits + .["vv_values"] = stripped_vv + +/datum/outfit/varedit/load_from(list/outfit_data) + . = ..() + stored_access = outfit_data["stored_access"] + vv_values = outfit_data["vv_values"] + update_id_name = outfit_data["update_id_name"] \ No newline at end of file diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 06c2361b90a..26a38e7bad5 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -118,7 +118,8 @@ var/list/admin_verbs_event = list( /client/proc/cmd_admin_create_centcom_report, /client/proc/fax_panel, /client/proc/event_manager_panel, - /client/proc/modify_goals + /client/proc/modify_goals, + /client/proc/outfit_manager ) var/list/admin_verbs_spawn = list( diff --git a/code/modules/admin/outfits.dm b/code/modules/admin/outfits.dm new file mode 100644 index 00000000000..8804c66c1c1 --- /dev/null +++ b/code/modules/admin/outfits.dm @@ -0,0 +1,249 @@ +GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits + +/client/proc/outfit_manager() + set category = "Debug" + set name = "Outfit Manager" + + if(!check_rights(R_DEBUG)) + return + holder.outfit_manager(usr) + +/datum/admins/proc/outfit_manager(mob/admin) + var/list/dat = list("" + dat += "Create
" + dat += "Load from file" + admin << browse(dat.Join(),"window=outfitmanager") + +/datum/admins/proc/save_outfit(mob/admin,datum/outfit/O) + O.save_to_file(admin) + outfit_manager(admin) + +/datum/admins/proc/delete_outfit(mob/admin,datum/outfit/O) + GLOB.custom_outfits -= O + qdel(O) + to_chat(admin,"Outfit deleted.") + outfit_manager(admin) + +/datum/admins/proc/load_outfit(mob/admin) + var/outfit_file = input("Pick outfit json file:", "File") as null|file + if(!outfit_file) + return + var/filedata = file2text(outfit_file) + var/json = json_decode(filedata) + if(!json) + to_chat(admin,"JSON decode error.") + return + var/otype = text2path(json["outfit_type"]) + if(!ispath(otype,/datum/outfit)) + to_chat(admin,"Malformed/Outdated file.") + return + var/datum/outfit/O = new otype + if(!O.load_from(json)) + to_chat(admin,"Malformed/Outdated file.") + return + GLOB.custom_outfits += O + outfit_manager(admin) + +/datum/admins/proc/create_outfit(mob/admin) + var/list/uniforms = typesof(/obj/item/clothing/under) + var/list/suits = typesof(/obj/item/clothing/suit) + var/list/gloves = typesof(/obj/item/clothing/gloves) + var/list/shoes = typesof(/obj/item/clothing/shoes) + var/list/headwear = typesof(/obj/item/clothing/head) + var/list/glasses = typesof(/obj/item/clothing/glasses) + var/list/masks = typesof(/obj/item/clothing/mask) + var/list/ids = typesof(/obj/item/card/id) + + var/uniform_select = "" + + var/suit_select = "" + + var/gloves_select = "" + + var/shoes_select = "" + + var/head_select = "" + + var/glasses_select = "" + + var/mask_select = "" + + var/id_select = "" + + var/dat = {" + Create Outfit +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name: + +
Uniform: + [uniform_select] +
Suit: + [suit_select] +
Back: + +
Belt: + +
Gloves: + [gloves_select] +
Shoes: + [shoes_select] +
Head: + [head_select] +
Mask: + [mask_select] +
Left Ear: + +
Right Ear: + +
Glasses: + [glasses_select] +
ID: + [id_select] +
Left Pocket: + +
Right Pocket: + +
Suit Store: + +
Right Hand: + +
Left Hand: + +
+
+ +
+ "} + admin << browse(dat, "window=dressup;size=550x600") + + +/datum/admins/proc/create_outfit_finalize(mob/admin, list/href_list) + var/datum/outfit/O = new + + O.name = href_list["outfit_name"] + O.uniform = text2path(href_list["outfit_uniform"]) + O.shoes = text2path(href_list["outfit_shoes"]) + O.gloves = text2path(href_list["outfit_gloves"]) + O.suit = text2path(href_list["outfit_suit"]) + O.head = text2path(href_list["outfit_head"]) + O.back = text2path(href_list["outfit_back"]) + O.mask = text2path(href_list["outfit_mask"]) + O.glasses = text2path(href_list["outfit_glasses"]) + O.r_hand = text2path(href_list["outfit_r_hand"]) + O.l_hand = text2path(href_list["outfit_l_hand"]) + O.suit_store = text2path(href_list["outfit_s_store"]) + O.l_pocket = text2path(href_list["outfit_l_pocket"]) + O.r_pocket = text2path(href_list["outfit_r_pocket"]) + O.id = text2path(href_list["outfit_id"]) + O.belt = text2path(href_list["outfit_belt"]) + O.l_ear = text2path(href_list["outfit_l_ear"]) + O.r_ear = text2path(href_list["outfit_r_ear"]) + + GLOB.custom_outfits.Add(O) + message_admins("[key_name(usr)] created \"[O.name]\" outfit!") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 224f07d4277..7f0660332fb 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -333,9 +333,6 @@ if("Cancel") return if("Yes") delmob = 1 - log_admin("[key_name(usr)] has used rudimentary transformation on [key_name(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]") - message_admins("[key_name_admin(usr)] has used rudimentary transformation on [key_name_admin(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]", 1) - switch(href_list["simplemake"]) if("observer") M.change_mob_type( /mob/dead/observer , null, null, delmob, 1 ) if("drone") M.change_mob_type( /mob/living/carbon/alien/humanoid/drone , null, null, delmob, 1 ) @@ -343,7 +340,11 @@ if("queen") M.change_mob_type( /mob/living/carbon/alien/humanoid/queen/large , null, null, delmob, 1 ) if("sentinel") M.change_mob_type( /mob/living/carbon/alien/humanoid/sentinel , null, null, delmob, 1 ) if("larva") M.change_mob_type( /mob/living/carbon/alien/larva , null, null, delmob, 1 ) - if("human") M.change_mob_type( /mob/living/carbon/human, null, null, delmob, 1 ) + if("human") + var/posttransformoutfit = usr.client.robust_dress_shop() + var/mob/living/carbon/human/newmob = M.change_mob_type(/mob/living/carbon/human, null, null, delmob, 1) + if(posttransformoutfit && istype(newmob)) + newmob.equipOutfit(posttransformoutfit) if("slime") M.change_mob_type( /mob/living/carbon/slime , null, null, delmob, 1 ) if("monkey") M.change_mob_type( /mob/living/carbon/human/monkey , null, null, delmob, 1 ) if("robot") M.change_mob_type( /mob/living/silicon/robot , null, null, delmob, 1 ) @@ -360,6 +361,9 @@ if("constructwraith") M.change_mob_type( /mob/living/simple_animal/hostile/construct/wraith , null, null, delmob, 1 ) if("shade") M.change_mob_type( /mob/living/simple_animal/shade , null, null, delmob, 1 ) + log_admin("[key_name(usr)] has used rudimentary transformation on [key_name(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]") + message_admins("[key_name_admin(usr)] has used rudimentary transformation on [key_name_admin(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]", 1) + /////////////////////////////////////new ban stuff else if(href_list["unbanf"]) @@ -1502,14 +1506,22 @@ usr.client.cmd_admin_animalize(M) else if(href_list["incarn_ghost"]) - if(!check_rights(R_SPAWN)) return + if(!check_rights(R_SPAWN)) + return var/mob/dead/observer/G = locateUID(href_list["incarn_ghost"]) if(!istype(G)) to_chat(usr, "This will only work on /mob/dead/observer") - log_admin("[key_name(G)] was incarnated by [key_name(src.owner)]") - message_admins("[key_name_admin(G)] was incarnated by [key_name_admin(src.owner)]") - G.incarnate_ghost() + + var/posttransformoutfit = usr.client.robust_dress_shop() + + var/mob/living/carbon/human/H = G.incarnate_ghost() + + if(posttransformoutfit && istype(H)) + H.equipOutfit(posttransformoutfit) + + log_admin("[key_name(G)] was incarnated by [key_name(owner)]") + message_admins("[key_name_admin(G)] was incarnated by [key_name_admin(owner)]") else if(href_list["togmutate"]) if(!check_rights(R_SPAWN)) return @@ -3360,6 +3372,29 @@ message_admins("[key_name_admin(usr)] forcefully unlinked the discord account belonging to [target_ckey]") log_admin("[key_name_admin(usr)] forcefully unlinked the discord account belonging to [target_ckey]") + else if(href_list["create_outfit_finalize"]) + if(!check_rights(R_ADMIN)) + return + create_outfit_finalize(usr,href_list) + else if(href_list["load_outfit"]) + if(!check_rights(R_ADMIN)) + return + load_outfit(usr) + else if(href_list["create_outfit_menu"]) + if(!check_rights(R_ADMIN)) + return + create_outfit(usr) + else if(href_list["delete_outfit"]) + if(!check_rights(R_ADMIN)) + return + var/datum/outfit/O = locate(href_list["chosen_outfit"]) in GLOB.custom_outfits + delete_outfit(usr,O) + else if(href_list["save_outfit"]) + if(!check_rights(R_ADMIN)) + return + var/datum/outfit/O = locate(href_list["chosen_outfit"]) in GLOB.custom_outfits + save_outfit(usr,O) + /client/proc/create_eventmob_for(var/mob/living/carbon/human/H, var/killthem = 0) if(!check_rights(R_EVENT)) return diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 6a419ebb29a..00f106e7870 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -576,109 +576,79 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that if(!check_rights(R_EVENT)) return - if(!ishuman(M)) + if(!ishuman(M) || !isobserver(M)) alert("Invalid mob") return - var/list/choices = list( - "strip", - "as job...", - "emergency response team member", - "emergency response team leader" + var/dresscode = robust_dress_shop() + + if(!dresscode) + return + + var/delete_pocket + var/mob/living/carbon/human/H + if(isobserver(M)) + H = M.change_mob_type(/mob/living/carbon/human, null, null, TRUE) + else + H = M + if(H.l_store || H.r_store || H.s_store) //saves a lot of time for admins and coders alike + if(alert("Should the items in their pockets be dropped? Selecting \"No\" will delete them.", "Robust quick dress shop", "Yes", "No") == "No") + delete_pocket = TRUE + + for (var/obj/item/I in H.get_equipped_items(delete_pocket)) + qdel(I) + if(dresscode != "Naked") + H.equipOutfit(dresscode) + + H.regenerate_icons() + + feedback_add_details("admin_verb", "SE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + log_admin("[key_name(usr)] changed the equipment of [key_name(M)] to [dresscode].") + message_admins("[key_name_admin(usr)] changed the equipment of [key_name_admin(M)] to [dresscode].", 1) + +/client/proc/robust_dress_shop() + var/list/outfits = list( + "Naked", + "As Job...", + "Custom..." ) - var/admin_outfits = subtypesof(/datum/outfit/admin) - for(var/type in admin_outfits) - var/datum/outfit/O = type - var/name = initial(O.name) - if(name != "Naked") - choices[initial(O.name)] = type + var/list/paths = subtypesof(/datum/outfit) - typesof(/datum/outfit/job) + for(var/path in paths) + var/datum/outfit/O = path //not much to initalize here but whatever + if(initial(O.can_be_admin_equipped)) + outfits[initial(O.name)] = path - var/dostrip = 0 - switch(alert("Strip [M] before dressing?", "Strip?", "Yes", "No", "Cancel")) - if("Yes") - dostrip = 1 - if("Cancel") - return - - var/dresscode = input("Select dress for [M]", "Robust quick dress shop") as null|anything in choices + var/dresscode = input("Select outfit", "Robust quick dress shop") as null|anything in outfits if(isnull(dresscode)) return - var/datum/outfit/O - if(!(dresscode in list("strip", "as job...", "emergency response team member", "emergency response team leader"))) - O = choices[dresscode] + if(outfits[dresscode]) + dresscode = outfits[dresscode] - var/datum/job/jobdatum - if(dresscode == "as job...") - var/jobname = input("Select job", "Robust quick dress shop") as null|anything in get_all_jobs() - jobdatum = SSjobs.GetJob(jobname) + if(dresscode == "As Job...") + var/list/job_paths = subtypesof(/datum/outfit/job) + var/list/job_outfits = list() + for(var/path in job_paths) + var/datum/outfit/O = path + if(initial(O.can_be_admin_equipped)) + job_outfits[initial(O.name)] = path - feedback_add_details("admin_verb", "SEQ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - if(dostrip) - for(var/obj/item/I in M) - if(istype(I, /obj/item/implant)) - continue - if(istype(I, /obj/item/organ)) - continue - qdel(I) + dresscode = input("Select job equipment", "Robust quick dress shop") as null|anything in job_outfits + dresscode = job_outfits[dresscode] + if(isnull(dresscode)) + return + if(dresscode == "Custom...") + var/list/custom_names = list() + for(var/datum/outfit/D in GLOB.custom_outfits) + custom_names[D.name] = D + var/selected_name = input("Select outfit", "Robust quick dress shop") as null|anything in custom_names + dresscode = custom_names[selected_name] + if(isnull(dresscode)) + return - switch(dresscode) - if("strip") - //do nothing - - // god is dead - if("as job...") - if(jobdatum) - dresscode = "[jobdatum.title]" - jobdatum.equip(M) - - if("emergency response team member", "emergency response team leader") - var/datum/response_team/equip_team = null - switch(alert("Level", "Emergency Response Team", "Amber", "Red", "Gamma")) - if("Amber") - equip_team = new /datum/response_team/amber - if("Red") - equip_team = new /datum/response_team/red - if("Gamma") - equip_team = new /datum/response_team/gamma - if(!equip_team) - return - if(dresscode == "emergency response team leader") - equip_team.equip_officer("Commander", M) - else - var/list/ert_outfits = list("Security", "Engineer", "Medic", "Janitor", "Paranormal") - var/echoice = input("Loadout Type", "Emergency Response Team") as null|anything in ert_outfits - if(!echoice) - return - switch(echoice) - if("Commander") - equip_team.equip_officer("Commander", M) - if("Security") - equip_team.equip_officer("Security", M) - if("Engineer") - equip_team.equip_officer("Engineer", M) - if("Medic") - equip_team.equip_officer("Medic", M) - if("Janitor") - equip_team.equip_officer("Janitor", M) - if("Paranormal") - equip_team.equip_officer("Paranormal", M) - else - to_chat(src, "Invalid ERT Loadout selected") - - - else // outfit datum - if(O) - M.equipOutfit(O, FALSE) - - M.regenerate_icons() - - log_admin("[key_name(usr)] changed the equipment of [key_name(M)] to [dresscode].") - message_admins("[key_name_admin(usr)] changed the equipment of [key_name_admin(M)] to [dresscode].", 1) - return - + return dresscode /client/proc/startSinglo() set category = "Debug" diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index 0a0a2e45abd..d337ddee67d 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -15,7 +15,8 @@ standard_outfit_options = list() for(var/path in subtypesof(/datum/outfit/job)) var/datum/outfit/O = path - standard_outfit_options[initial(O.name)] = path + if(initial(O.can_be_admin_equipped)) + standard_outfit_options[initial(O.name)] = path sortTim(standard_outfit_options, /proc/cmp_text_asc) outfit_options = standard_outfit_options diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index c8c7d5c32e3..b1ae3acc7ce 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -766,14 +766,17 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/proc/incarnate_ghost() if(!client) return + var/mob/living/carbon/human/new_char = new(get_turf(src)) client.prefs.copy_to(new_char) if(mind) - mind.active = 1 + mind.active = TRUE mind.transfer_to(new_char) else new_char.key = key + return new_char + /mob/dead/observer/is_literate() return TRUE diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 47dd5622379..64ea9c9eb11 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -575,3 +575,10 @@ return 0 return O.equip(src, visualsOnly) + +//delete all equipment without dropping anything +/mob/living/carbon/human/proc/delete_equipment() + for(var/slot in get_all_slots())//order matters, dependant slots go first + qdel(slot) + for(var/obj/item/I in l_hand, r_hand) + qdel(I) diff --git a/code/modules/response_team/ert.dm b/code/modules/response_team/ert.dm index cdc81a9e759..222d92583b1 100644 --- a/code/modules/response_team/ert.dm +++ b/code/modules/response_team/ert.dm @@ -240,32 +240,21 @@ var/ert_request_answered = FALSE switch(officer_type) if("Engineer") M.equipOutfit(engineering_outfit) - M.job = "ERT Engineering" if("Security") M.equipOutfit(security_outfit) - M.job = "ERT Security" if("Medic") M.equipOutfit(medical_outfit) - M.job = "ERT Medical" if("Janitor") M.equipOutfit(janitor_outfit) - M.job = "ERT Janitor" if("Paranormal") M.equipOutfit(paranormal_outfit) - M.job = "ERT Paranormal" - M.mind.isholy = TRUE if("Commander") - // Override name and age for the commander - M.rename_character(null, "[pick("Lieutenant", "Captain", "Major")] [pick(GLOB.last_names)]") - M.age = rand(35,45) - M.equipOutfit(command_outfit) - M.job = "ERT Commander" /datum/response_team/proc/cannot_send_team() event_announcement.Announce("[station_name()], we are unfortunately unable to send you an Emergency Response Team at this time.", "ERT Unavailable") @@ -317,6 +306,7 @@ var/ert_request_answered = FALSE name = "Response team" var/rt_assignment = "Emergency Response Team Member" var/rt_job = "This is a bug" + var/rt_mob_job = "This is a bug" // The job set on the actual mob. allow_backbag_choice = FALSE allow_loadout = FALSE pda = /obj/item/pda/heads/ert diff --git a/code/modules/response_team/ert_outfits.dm b/code/modules/response_team/ert_outfits.dm index b287643901d..93b87e7d1ec 100644 --- a/code/modules/response_team/ert_outfits.dm +++ b/code/modules/response_team/ert_outfits.dm @@ -23,6 +23,10 @@ PDA.ownrank = rt_assignment PDA.name = "PDA-[H.real_name] ([PDA.ownjob])" +/datum/outfit/job/centcom/response_team/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + . = ..() + + H.job = rt_mob_job //////////////////// COMMANDER /////////////////// @@ -30,6 +34,7 @@ name = "RT Commander" rt_assignment = "Emergency Response Team Leader" rt_job = "Emergency Response Team Leader" + rt_mob_job = "ERT Commander" uniform = /obj/item/clothing/under/rank/centcom_officer back = /obj/item/storage/backpack/ert/commander @@ -39,6 +44,12 @@ l_pocket = /obj/item/pinpointer r_pocket = /obj/item/melee/classic_baton/telescopic +/datum/outfit/job/centcom/response_team/commander/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + . = ..() + + H.rename_character(null, "[pick("Lieutenant", "Captain", "Major")] [pick(GLOB.last_names)]") + H.age = rand(35,45) + /datum/outfit/job/centcom/response_team/commander/amber name = "RT Commander (Amber)" shoes = /obj/item/clothing/shoes/combat @@ -107,6 +118,7 @@ /datum/outfit/job/centcom/response_team/security name = "RT Security" rt_job = "Emergency Response Team Officer" + rt_mob_job = "ERT Security" uniform = /obj/item/clothing/under/rank/security back = /obj/item/storage/backpack/ert/security belt = /obj/item/storage/belt/security/response_team @@ -194,6 +206,7 @@ /datum/outfit/job/centcom/response_team/engineer name = "RT Engineer" rt_job = "Emergency Response Team Engineer" + rt_mob_job = "ERT Engineering" back = /obj/item/storage/backpack/ert/engineer uniform = /obj/item/clothing/under/rank/engineer @@ -276,6 +289,7 @@ /datum/outfit/job/centcom/response_team/medic name = "RT Medic" rt_job = "Emergency Response Team Medic" + rt_mob_job = "ERT Medical" uniform = /obj/item/clothing/under/rank/medical back = /obj/item/storage/backpack/ert/medical pda = /obj/item/pda/heads/ert/medical @@ -312,6 +326,7 @@ /datum/outfit/job/centcom/response_team/medic/red name = "RT Medic (Red)" + rt_mob_job = "ERT Medical" shoes = /obj/item/clothing/shoes/white gloves = /obj/item/clothing/gloves/color/latex/nitrile suit = /obj/item/clothing/suit/space/hardsuit/ert/medical @@ -377,6 +392,7 @@ /datum/outfit/job/centcom/response_team/paranormal name = "RT Paranormal" rt_job = "Emergency Response Team Inquisitor" + rt_mob_job = "ERT Paranormal" uniform = /obj/item/clothing/under/rank/chaplain back = /obj/item/storage/backpack/ert/security gloves = /obj/item/clothing/gloves/color/black @@ -392,6 +408,11 @@ /obj/item/flashlight/seclite = 1 ) +/datum/outfit/job/centcom/response_team/paranormal/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + . = ..() + if(H.mind) + H.mind.isholy = TRUE + /datum/outfit/job/centcom/response_team/paranormal/amber name = "RT Paranormal (Amber)" suit = /obj/item/clothing/suit/armor/vest/ert/security/paranormal @@ -433,6 +454,7 @@ /datum/outfit/job/centcom/response_team/janitorial name = "RT Janitor" rt_job = "Emergency Response Team Janitor" + rt_mob_job = "ERT Janitor" uniform = /obj/item/clothing/under/color/purple back = /obj/item/storage/backpack/ert/janitor belt = /obj/item/storage/belt/janitor/full diff --git a/code/modules/vr/vr_outfits.dm b/code/modules/vr/vr_outfits.dm index ce8d52b4880..e61ea829b27 100644 --- a/code/modules/vr/vr_outfits.dm +++ b/code/modules/vr/vr_outfits.dm @@ -1,12 +1,12 @@ //place all the outfits for your levels in here. /datum/outfit/vr/vr_basic - name = "basic vr" + name = "Basic Virtual Reality" uniform = /obj/item/clothing/under/psysuit shoes = /obj/item/clothing/shoes/black /datum/outfit/vr/roman - name = "roman" + name = "Roman" uniform = /obj/item/clothing/under/roman shoes = /obj/item/clothing/shoes/roman l_hand = /obj/item/shield/riot/roman diff --git a/paradise.dme b/paradise.dme index c49361b8e20..cad5f6ab907 100644 --- a/paradise.dme +++ b/paradise.dme @@ -346,6 +346,7 @@ #include "code\datums\looping_sounds\weather.dm" #include "code\datums\outfits\outfit.dm" #include "code\datums\outfits\outfit_admin.dm" +#include "code\datums\outfits\vv_outfit.dm" #include "code\datums\ruins\lavaland.dm" #include "code\datums\ruins\space.dm" #include "code\datums\spells\area_teleport.dm" @@ -1151,6 +1152,7 @@ #include "code\modules\admin\IsBanned.dm" #include "code\modules\admin\machine_upgrade.dm" #include "code\modules\admin\NewBan.dm" +#include "code\modules\admin\outfits.dm" #include "code\modules\admin\player_panel.dm" #include "code\modules\admin\secrets.dm" #include "code\modules\admin\sql_notes.dm"