Merge remote-tracking branch 'upstream/master' into rp-markings-attempt-two
This commit is contained in:
@@ -93,7 +93,7 @@ GLOBAL_PROTECT(admin_verbs_ban)
|
||||
GLOBAL_LIST_INIT(admin_verbs_sounds, list(/client/proc/play_local_sound, /client/proc/play_sound, /client/proc/manual_play_web_sound, /client/proc/set_round_end_sound))
|
||||
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,
|
||||
@@ -232,7 +232,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
|
||||
/client/proc/play_local_sound,
|
||||
/client/proc/play_sound,
|
||||
/client/proc/set_round_end_sound,
|
||||
/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,
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
|
||||
/client/proc/open_outfit_editor(datum/outfit/target)
|
||||
var/datum/outfit_editor/ui = new(usr, target)
|
||||
ui.ui_interact(usr)
|
||||
|
||||
#define OUTFIT_EDITOR_NAME "Outfit-O-Tron 9000"
|
||||
/datum/outfit_editor
|
||||
var/client/owner
|
||||
|
||||
var/dummy_key
|
||||
|
||||
var/datum/outfit/drip
|
||||
|
||||
/datum/outfit_editor/New(user, datum/outfit/target)
|
||||
owner = CLIENT_FROM_VAR(user)
|
||||
|
||||
if(ispath(target))
|
||||
drip = new /datum/outfit
|
||||
drip.copy_from(new target)
|
||||
else if(istype(target))
|
||||
drip = target
|
||||
else
|
||||
drip = new /datum/outfit
|
||||
drip.name = "New Outfit"
|
||||
|
||||
/datum/outfit_editor/ui_state(mob/user)
|
||||
return GLOB.admin_state
|
||||
|
||||
/datum/outfit_editor/ui_status(mob/user, datum/ui_state/state)
|
||||
if(QDELETED(drip))
|
||||
return UI_CLOSE
|
||||
return ..()
|
||||
|
||||
/datum/outfit_editor/ui_close(mob/user)
|
||||
clear_human_dummy(dummy_key)
|
||||
qdel(src)
|
||||
|
||||
/datum/outfit_editor/proc/init_dummy()
|
||||
dummy_key = "outfit_editor_[owner]"
|
||||
generate_dummy_lookalike(dummy_key, owner.mob)
|
||||
unset_busy_human_dummy(dummy_key)
|
||||
|
||||
/datum/outfit_editor/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "OutfitEditor", OUTFIT_EDITOR_NAME)
|
||||
ui.open()
|
||||
ui.set_autoupdate(FALSE)
|
||||
|
||||
/datum/outfit_editor/proc/entry(data)
|
||||
if(ispath(data, /obj/item))
|
||||
var/obj/item/item = data
|
||||
return list(
|
||||
"path" = item,
|
||||
"name" = initial(item.name),
|
||||
"desc" = initial(item.desc),
|
||||
// at this point initializing the item is probably faster tbh
|
||||
"sprite" = icon2base64(icon(initial(item.icon), initial(item.icon_state))),
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
/datum/outfit_editor/proc/serialize_outfit()
|
||||
var/list/outfit_slots = drip.get_json_data()
|
||||
. = list()
|
||||
for(var/key in outfit_slots)
|
||||
var/val = outfit_slots[key]
|
||||
. += list("[key]" = entry(val))
|
||||
|
||||
/datum/outfit_editor/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["outfit"] = serialize_outfit()
|
||||
data["saveable"] = !GLOB.custom_outfits.Find(drip)
|
||||
|
||||
if(!dummy_key)
|
||||
init_dummy()
|
||||
var/icon/dummysprite = get_flat_human_icon(null,
|
||||
dummy_key = dummy_key,
|
||||
showDirs = list(SOUTH),
|
||||
outfit_override = drip)
|
||||
data["dummy64"] = icon2base64(dummysprite)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
/datum/outfit_editor/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
if(..())
|
||||
return
|
||||
. = TRUE
|
||||
|
||||
var/slot = params["slot"]
|
||||
switch(action)
|
||||
if("click")
|
||||
choose_item(slot)
|
||||
if("ctrlClick")
|
||||
choose_any_item(slot)
|
||||
if("clear")
|
||||
if(drip.vars.Find(slot))
|
||||
drip.vars[slot] = null
|
||||
|
||||
if("rename")
|
||||
var/newname = stripped_input(owner, "What do you want to name this outfit?", OUTFIT_EDITOR_NAME)
|
||||
if(newname)
|
||||
drip.name = newname
|
||||
if("save")
|
||||
GLOB.custom_outfits |= drip
|
||||
SStgui.update_user_uis(owner.mob)
|
||||
if("delete")
|
||||
GLOB.custom_outfits -= drip
|
||||
SStgui.update_user_uis(owner.mob)
|
||||
if("vv")
|
||||
owner.debug_variables(drip)
|
||||
|
||||
|
||||
/datum/outfit_editor/proc/set_item(slot, obj/item/choice)
|
||||
if(!choice)
|
||||
return
|
||||
if(!ispath(choice))
|
||||
alert(owner, "Invalid item", OUTFIT_EDITOR_NAME, "oh no")
|
||||
return
|
||||
if(initial(choice.icon_state) == null) //hacky check copied from experimentor code
|
||||
var/msg = "Warning: This item's icon_state is null, indicating it is very probably not actually a usable item."
|
||||
if(alert(owner, msg, OUTFIT_EDITOR_NAME, "Use it anyway", "Cancel") != "Use it anyway")
|
||||
return
|
||||
|
||||
if(drip.vars.Find(slot))
|
||||
drip.vars[slot] = choice
|
||||
|
||||
/datum/outfit_editor/proc/choose_any_item(slot)
|
||||
var/obj/item/choice = pick_closest_path(FALSE)
|
||||
|
||||
if(!choice)
|
||||
return
|
||||
|
||||
set_item(slot, choice)
|
||||
|
||||
//this proc will try to give a good selection of items that the user can choose from
|
||||
//it does *not* give a selection of all items that can fit in a slot because lag;
|
||||
//most notably the hand and pocket slots because they accept pretty much anything
|
||||
//also stuff that fits in the belt and back slots are scattered pretty much all over the place
|
||||
/datum/outfit_editor/proc/choose_item(slot)
|
||||
var/list/options = list()
|
||||
|
||||
switch(slot)
|
||||
if("head")
|
||||
options = typesof(/obj/item/clothing/head)
|
||||
if("glasses")
|
||||
options = typesof(/obj/item/clothing/glasses)
|
||||
if("ears")
|
||||
options = typesof(/obj/item/radio/headset)
|
||||
|
||||
if("neck")
|
||||
options = typesof(/obj/item/clothing/neck)
|
||||
if("mask")
|
||||
options = typesof(/obj/item/clothing/mask)
|
||||
|
||||
if("uniform")
|
||||
options = typesof(/obj/item/clothing/under)
|
||||
if("suit")
|
||||
options = typesof(/obj/item/clothing/suit)
|
||||
if("gloves")
|
||||
options = typesof(/obj/item/clothing/gloves)
|
||||
|
||||
if("suit_store")
|
||||
var/obj/item/clothing/suit/suit = drip.suit
|
||||
if(suit)
|
||||
suit = new suit //initial() doesn't like lists
|
||||
options = suit.allowed
|
||||
if(!options.len) //nothing will happen, but don't let the user think it's broken
|
||||
to_chat(owner, "<span class='warning'>No options available for the current suit.</span>")
|
||||
|
||||
if("belt")
|
||||
options = typesof(/obj/item/storage/belt)
|
||||
if("id")
|
||||
options = typesof(/obj/item/card/id)
|
||||
|
||||
if("l_hand")
|
||||
choose_any_item(slot)
|
||||
if("back")
|
||||
options = typesof(/obj/item/storage/backpack)
|
||||
if("r_hand")
|
||||
choose_any_item(slot)
|
||||
|
||||
if("l_pocket")
|
||||
choose_any_item(slot)
|
||||
if("shoes")
|
||||
options = typesof(/obj/item/clothing/shoes)
|
||||
if("r_pocket")
|
||||
choose_any_item(slot)
|
||||
|
||||
if(length(options))
|
||||
set_item(slot, tgui_input_list(owner, "Choose an item", OUTFIT_EDITOR_NAME, options))
|
||||
|
||||
|
||||
#undef OUTFIT_EDITOR_NAME
|
||||
@@ -0,0 +1,73 @@
|
||||
/client/proc/outfit_manager()
|
||||
set category = "Debug"
|
||||
set name = "Outfit Manager"
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
var/datum/outfit_manager/ui = new(usr)
|
||||
ui.ui_interact(usr)
|
||||
|
||||
|
||||
/datum/outfit_manager
|
||||
var/client/owner
|
||||
|
||||
/datum/outfit_manager/New(user)
|
||||
owner = CLIENT_FROM_VAR(user)
|
||||
|
||||
/datum/outfit_manager/ui_state(mob/user)
|
||||
return GLOB.admin_state
|
||||
|
||||
/datum/outfit_manager/ui_close(mob/user)
|
||||
qdel(src)
|
||||
|
||||
/datum/outfit_manager/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "OutfitManager")
|
||||
ui.open()
|
||||
|
||||
/datum/outfit_manager/proc/entry(datum/outfit/outfit)
|
||||
var/vv = FALSE
|
||||
var/datum/outfit/varedit/varoutfit = outfit
|
||||
if(istype(varoutfit))
|
||||
vv = length(varoutfit.vv_values)
|
||||
return list(
|
||||
"name" = "[outfit.name] [vv ? "(VV)" : ""]",
|
||||
"ref" = REF(outfit),
|
||||
)
|
||||
|
||||
/datum/outfit_manager/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
var/list/outfits = list()
|
||||
for(var/datum/outfit/custom_outfit in GLOB.custom_outfits)
|
||||
outfits += list(entry(custom_outfit))
|
||||
data["outfits"] = outfits
|
||||
|
||||
return data
|
||||
|
||||
/datum/outfit_manager/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
if(..())
|
||||
return
|
||||
. = TRUE
|
||||
|
||||
switch(action)
|
||||
if("new")
|
||||
owner.open_outfit_editor(new /datum/outfit)
|
||||
if("load")
|
||||
owner.holder.load_outfit(owner.mob)
|
||||
if("copy")
|
||||
var/datum/outfit/outfit = tgui_input_list(owner, "Pick an outfit to copy from", "Outfit Manager", subtypesof(/datum/outfit))
|
||||
if(ispath(outfit))
|
||||
owner.open_outfit_editor(new outfit)
|
||||
|
||||
var/datum/outfit/target_outfit = locate(params["outfit"])
|
||||
if(!istype(target_outfit))
|
||||
return
|
||||
switch(action) //wow we're switching through action again this is horrible optimization smh
|
||||
if("edit")
|
||||
owner.open_outfit_editor(target_outfit)
|
||||
if("save")
|
||||
owner.holder.save_outfit(owner.mob, target_outfit)
|
||||
if("delete")
|
||||
owner.holder.delete_outfit(owner.mob, target_outfit)
|
||||
@@ -0,0 +1,32 @@
|
||||
GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
|
||||
/datum/admins/proc/save_outfit(mob/admin, datum/outfit/O)
|
||||
O.save_to_file(admin)
|
||||
SStgui.update_user_uis(admin)
|
||||
|
||||
/datum/admins/proc/delete_outfit(mob/admin, datum/outfit/O)
|
||||
GLOB.custom_outfits -= O
|
||||
qdel(O)
|
||||
to_chat(admin,"<span class='notice'>Outfit deleted.</span>")
|
||||
SStgui.update_user_uis(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,"<span class='warning'>JSON decode error.</span>")
|
||||
return
|
||||
var/otype = text2path(json["outfit_type"])
|
||||
if(!ispath(otype,/datum/outfit))
|
||||
to_chat(admin,"<span class='warning'>Malformed/Outdated file.</span>")
|
||||
return
|
||||
var/datum/outfit/O = new otype
|
||||
if(!O.load_from(json))
|
||||
to_chat(admin,"<span class='warning'>Malformed/Outdated file.</span>")
|
||||
return
|
||||
GLOB.custom_outfits += O
|
||||
SStgui.update_user_uis(admin)
|
||||
|
||||
@@ -484,74 +484,52 @@
|
||||
set name = "Test Areas (ALL)"
|
||||
cmd_admin_areatest(FALSE)
|
||||
|
||||
/client/proc/cmd_admin_dress(mob/M in GLOB.mob_list)
|
||||
set category = "Admin.Events"
|
||||
set name = "Select equipment"
|
||||
if(!(ishuman(M) || isobserver(M)))
|
||||
alert("Invalid mob")
|
||||
return
|
||||
|
||||
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(alert("Drop Items in Pockets? No will delete them.", "Robust quick dress shop", "Yes", "No") == "No")
|
||||
delete_pocket = TRUE
|
||||
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Select Equipment") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
for (var/obj/item/I in H.get_equipped_items(delete_pocket))
|
||||
qdel(I)
|
||||
if(dresscode != "Naked")
|
||||
H.equipOutfit(dresscode)
|
||||
|
||||
H.regenerate_icons()
|
||||
|
||||
log_admin("[key_name(usr)] changed the equipment of [key_name(H)] to [dresscode].")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] changed the equipment of [ADMIN_LOOKUPFLW(H)] to [dresscode].</span>")
|
||||
|
||||
/client/proc/robust_dress_shop()
|
||||
var/list/outfits = list("Cancel","Naked","Custom","As Job...")
|
||||
var/list/paths = subtypesof(/datum/outfit) - typesof(/datum/outfit/job)
|
||||
|
||||
var/list/baseoutfits = list("Naked","Custom","As Job...", "As Plasmaman...")
|
||||
var/list/outfits = list()
|
||||
var/list/paths = subtypesof(/datum/outfit) - typesof(/datum/outfit/job) - typesof(/datum/outfit/plasmaman)
|
||||
|
||||
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
|
||||
outfits[initial(O.name)] = path
|
||||
|
||||
var/dresscode = input("Select outfit", "Robust quick dress shop") as null|anything in outfits
|
||||
var/dresscode = input("Select outfit", "Robust quick dress shop") as null|anything in baseoutfits + sortList(outfits)
|
||||
if (isnull(dresscode))
|
||||
return
|
||||
|
||||
if (outfits[dresscode])
|
||||
dresscode = outfits[dresscode]
|
||||
|
||||
if(dresscode == "Cancel")
|
||||
return
|
||||
|
||||
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
|
||||
job_outfits[initial(O.name)] = path
|
||||
|
||||
dresscode = input("Select job equipment", "Robust quick dress shop") as null|anything in job_outfits
|
||||
dresscode = input("Select job equipment", "Robust quick dress shop") as null|anything in sortList(job_outfits)
|
||||
dresscode = job_outfits[dresscode]
|
||||
if(isnull(dresscode))
|
||||
return
|
||||
|
||||
if (dresscode == "As Plasmaman...")
|
||||
var/list/plasmaman_paths = typesof(/datum/outfit/plasmaman)
|
||||
var/list/plasmaman_outfits = list()
|
||||
for(var/path in plasmaman_paths)
|
||||
var/datum/outfit/O = path
|
||||
plasmaman_outfits[initial(O.name)] = path
|
||||
|
||||
dresscode = input("Select plasmeme equipment", "Robust quick dress shop") as null|anything in sortList(plasmaman_outfits)
|
||||
dresscode = plasmaman_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
|
||||
var/selected_name = input("Select outfit", "Robust quick dress shop") as null|anything in sortList(custom_names)
|
||||
dresscode = custom_names[selected_name]
|
||||
if(isnull(dresscode))
|
||||
return
|
||||
|
||||
@@ -879,8 +879,6 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] [N.timing ? "activated" : "deactivated"] a nuke at [ADMIN_VERBOSEJMP(N)].")
|
||||
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Nuke", "[N.timing]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
|
||||
/client/proc/create_outfits()
|
||||
set category = "Debug"
|
||||
set name = "Create Custom Outfit"
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
/client/proc/cmd_select_equipment(mob/target in GLOB.mob_list)
|
||||
set category = "Admin.Events"
|
||||
set name = "Select equipment"
|
||||
|
||||
|
||||
var/datum/select_equipment/ui = new(usr, target)
|
||||
ui.ui_interact(usr)
|
||||
|
||||
/*
|
||||
* This is the datum housing the select equipment UI.
|
||||
*
|
||||
* You may notice some oddities about the way outfits are passed to the UI and vice versa here.
|
||||
* That's because it handles both outfit typepaths (for normal outfits) *and* outfit objects (for custom outfits).
|
||||
*
|
||||
* Custom outfits need to be objects as they're created in runtime.
|
||||
* "Then just handle the normal outfits as objects too and simplify the handling" - you may say.
|
||||
* There are about 300 outfit types at the time of writing this. Initializing all of these to objects would be a huge waste.
|
||||
*
|
||||
*/
|
||||
|
||||
/datum/select_equipment
|
||||
var/client/user
|
||||
var/mob/target_mob
|
||||
|
||||
var/dummy_key
|
||||
|
||||
//static list to share all the outfit typepaths between all instances of this datum.
|
||||
var/static/list/cached_outfits
|
||||
|
||||
//a typepath if the selected outfit is a normal outfit;
|
||||
//an object if the selected outfit is a custom outfit
|
||||
var/datum/outfit/selected_outfit = /datum/outfit
|
||||
//serializable string for the UI to keep track of which outfit is selected
|
||||
var/selected_identifier = "/datum/outfit"
|
||||
|
||||
/datum/select_equipment/New(_user, mob/target)
|
||||
user = CLIENT_FROM_VAR(_user)
|
||||
|
||||
if(!ishuman(target) && !isobserver(target))
|
||||
alert("Invalid mob")
|
||||
return
|
||||
target_mob = target
|
||||
|
||||
/datum/select_equipment/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "SelectEquipment", "Select Equipment")
|
||||
ui.open()
|
||||
ui.set_autoupdate(FALSE)
|
||||
|
||||
/datum/select_equipment/ui_state(mob/user)
|
||||
return GLOB.admin_state
|
||||
|
||||
/datum/select_equipment/ui_status(mob/user, datum/ui_state/state)
|
||||
if(QDELETED(target_mob))
|
||||
return UI_CLOSE
|
||||
return ..()
|
||||
|
||||
/datum/select_equipment/ui_close(mob/user)
|
||||
clear_human_dummy(dummy_key)
|
||||
qdel(src)
|
||||
|
||||
/datum/select_equipment/proc/init_dummy()
|
||||
dummy_key = "selectequipmentUI_[target_mob]"
|
||||
generate_dummy_lookalike(dummy_key, target_mob)
|
||||
unset_busy_human_dummy(dummy_key)
|
||||
return
|
||||
|
||||
/**
|
||||
* Packs up data about an outfit as an assoc list to send to the UI as an outfit entry.
|
||||
*
|
||||
* Args:
|
||||
* * category (string) - The tab it will be under
|
||||
*
|
||||
* * identifier (typepath or ref) - This will sent this back to ui_act to preview or spawn in an outfit.
|
||||
* * Must be unique between all entries.
|
||||
*
|
||||
* * name (string) - Will be the text on the button
|
||||
*
|
||||
* * priority (bool)(optional) - If True, the UI will sort the entry to the top, right below favorites.
|
||||
*
|
||||
* * custom_entry (bool)(optional) - Send the identifier with a "ref" keyword instead of "path",
|
||||
* * for the UI to tell apart custom outfits from normal ones.
|
||||
*
|
||||
* Returns (list) An outfit entry
|
||||
*/
|
||||
|
||||
/datum/select_equipment/proc/outfit_entry(category, identifier, name, priority=FALSE, custom_entry=FALSE)
|
||||
if(custom_entry)
|
||||
return list("category" = category, "ref" = identifier, "name" = name, "priority" = priority)
|
||||
return list("category" = category, "path" = identifier, "name" = name, "priority" = priority)
|
||||
|
||||
/datum/select_equipment/proc/make_outfit_entries(category="General", list/outfit_list)
|
||||
var/list/entries = list()
|
||||
for(var/path as anything in outfit_list)
|
||||
var/datum/outfit/outfit = path
|
||||
entries += list(outfit_entry(category, path, initial(outfit.name)))
|
||||
return entries
|
||||
|
||||
//GLOB.custom_outfits lists outfit *objects* so we'll need to do some custom handling for it
|
||||
/datum/select_equipment/proc/make_custom_outfit_entries(list/outfit_list)
|
||||
var/list/entries = list()
|
||||
for(var/datum/outfit/outfit as anything in outfit_list)
|
||||
entries += list(outfit_entry("Custom", REF(outfit), outfit.name, custom_entry=TRUE)) //it's either this or special handling on the UI side
|
||||
return entries
|
||||
|
||||
/datum/select_equipment/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
if(!dummy_key)
|
||||
init_dummy()
|
||||
|
||||
var/icon/dummysprite = get_flat_human_icon(null,
|
||||
dummy_key = dummy_key,
|
||||
outfit_override = selected_outfit,
|
||||
no_anim = TRUE)
|
||||
data["icon64"] = icon2base64(dummysprite)
|
||||
data["name"] = target_mob
|
||||
|
||||
var/datum/preferences/prefs = user?.client?.prefs
|
||||
data["favorites"] = list()
|
||||
if(prefs)
|
||||
data["favorites"] = prefs.favorite_outfits
|
||||
|
||||
var/list/custom
|
||||
custom += make_custom_outfit_entries(GLOB.custom_outfits)
|
||||
data["custom_outfits"] = custom
|
||||
data["current_outfit"] = selected_identifier
|
||||
return data
|
||||
|
||||
|
||||
/datum/select_equipment/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
if(!cached_outfits)
|
||||
cached_outfits = list()
|
||||
cached_outfits += list(outfit_entry("General", /datum/outfit, "Naked", priority=TRUE))
|
||||
cached_outfits += make_outfit_entries("General", subtypesof(/datum/outfit) - typesof(/datum/outfit/job) - typesof(/datum/outfit/plasmaman))
|
||||
cached_outfits += make_outfit_entries("Jobs", typesof(/datum/outfit/job))
|
||||
cached_outfits += make_outfit_entries("Plasmamen Outfits", typesof(/datum/outfit/plasmaman))
|
||||
|
||||
data["outfits"] = cached_outfits
|
||||
return data
|
||||
|
||||
|
||||
/datum/select_equipment/proc/resolve_outfit(text)
|
||||
|
||||
var/path = text2path(text)
|
||||
if(ispath(path, /datum/outfit))
|
||||
return path
|
||||
|
||||
else //don't bail yet - could be a custom outfit
|
||||
var/datum/outfit/custom_outfit = locate(text)
|
||||
if(istype(custom_outfit))
|
||||
return custom_outfit
|
||||
|
||||
|
||||
/datum/select_equipment/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("preview")
|
||||
var/datum/outfit/new_outfit = resolve_outfit(params["path"])
|
||||
|
||||
if(ispath(new_outfit)) //got a typepath - that means we're dealing with a normal outfit
|
||||
selected_identifier = new_outfit //these are keyed by type
|
||||
//by the way, no, they can't be keyed by name because many of them have duplicate names
|
||||
|
||||
else if(istype(new_outfit)) //got an initialized object - means it's a custom outfit
|
||||
selected_identifier = REF(new_outfit) //and the outfit will be keyed by its ref (cause its type will always be /datum/outfit)
|
||||
|
||||
else //we got nothing and should bail
|
||||
return
|
||||
|
||||
selected_outfit = new_outfit
|
||||
|
||||
if("applyoutfit")
|
||||
var/datum/outfit/new_outfit = resolve_outfit(params["path"])
|
||||
if(new_outfit && ispath(new_outfit)) //initialize it
|
||||
new_outfit = new new_outfit
|
||||
if(!istype(new_outfit))
|
||||
return
|
||||
user.admin_apply_outfit(target_mob, new_outfit)
|
||||
|
||||
if("customoutfit")
|
||||
user.outfit_manager()
|
||||
|
||||
if("togglefavorite")
|
||||
var/datum/outfit/outfit_path = resolve_outfit(params["path"])
|
||||
if(!ispath(outfit_path)) //we do *not* want custom outfits (i.e objects) here, they're not even persistent
|
||||
return
|
||||
|
||||
if(user.prefs.favorite_outfits.Find(outfit_path)) //already there, remove it
|
||||
user.prefs.favorite_outfits -= outfit_path
|
||||
else //not there, add it
|
||||
user.prefs.favorite_outfits += outfit_path
|
||||
user.prefs.save_preferences()
|
||||
|
||||
/client/proc/admin_apply_outfit(mob/target, dresscode)
|
||||
if(!ishuman(target) && !isobserver(target))
|
||||
alert("Invalid mob")
|
||||
return
|
||||
|
||||
if(!dresscode)
|
||||
return
|
||||
|
||||
var/delete_pocket
|
||||
var/mob/living/carbon/human/human_target
|
||||
if(isobserver(target))
|
||||
human_target = target.change_mob_type(/mob/living/carbon/human, delete_old_mob = TRUE)
|
||||
else
|
||||
human_target = target
|
||||
if(human_target.l_store || human_target.r_store || human_target.s_store) //saves a lot of time for admins and coders alike
|
||||
if(alert("Drop Items in Pockets? No will delete them.", "Robust quick dress shop", "Yes", "No") == "No")
|
||||
delete_pocket = TRUE
|
||||
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Select Equipment") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
for(var/obj/item/item in human_target.get_equipped_items(delete_pocket))
|
||||
qdel(item)
|
||||
if(dresscode != "Naked")
|
||||
human_target.equipOutfit(dresscode)
|
||||
|
||||
human_target.regenerate_icons()
|
||||
|
||||
log_admin("[key_name(usr)] changed the equipment of [key_name(human_target)] to [dresscode].")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] changed the equipment of [ADMIN_LOOKUPFLW(human_target)] to [dresscode].</span>")
|
||||
|
||||
return dresscode
|
||||
@@ -345,6 +345,14 @@
|
||||
InsertAll("", each, GLOB.alldirs)
|
||||
..()
|
||||
|
||||
/datum/asset/spritesheet/decals
|
||||
name = "decals"
|
||||
|
||||
/datum/asset/spritesheet/decals/register()
|
||||
for(var/each in list('icons/turf/decals.dmi'))
|
||||
InsertAll("", each, GLOB.alldirs)
|
||||
..()
|
||||
|
||||
/datum/asset/spritesheet/supplypods
|
||||
name = "supplypods"
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
cost = 250
|
||||
unit_name = "heart"
|
||||
export_types = list(/obj/item/organ/heart)
|
||||
exclude_types = list(/obj/item/organ/heart/cursed, /obj/item/organ/heart/cybernetic)
|
||||
exclude_types = list(/obj/item/organ/heart/cursed, /obj/item/organ/heart/cybernetic/tier2, /obj/item/organ/heart/cybernetic/tier3)
|
||||
|
||||
/datum/export/organs/tongue
|
||||
cost = 75
|
||||
@@ -92,29 +92,30 @@
|
||||
cost = 50 //can be replaced
|
||||
unit_name = "stomach"
|
||||
export_types = list(/obj/item/organ/stomach)
|
||||
exclude_types = list(/obj/item/organ/stomach/cybernetic/tier2, /obj/item/organ/stomach/cybernetic/tier3)
|
||||
|
||||
/datum/export/organs/lungs
|
||||
cost = 150
|
||||
unit_name = "lungs"
|
||||
export_types = list(/obj/item/organ/lungs)
|
||||
exclude_types = list(/obj/item/organ/lungs/cybernetic, /obj/item/organ/lungs/cybernetic/upgraded)
|
||||
export_types = list(/obj/item/organ/lungs,)
|
||||
exclude_types = list(/obj/item/organ/lungs/cybernetic/tier2, /obj/item/organ/lungs/cybernetic/tier3)
|
||||
|
||||
/datum/export/organs/liver
|
||||
cost = 175
|
||||
unit_name = "liver"
|
||||
export_types = list(/obj/item/organ/liver)
|
||||
exclude_types = list(/obj/item/organ/liver/cybernetic, /obj/item/organ/liver/cybernetic/upgraded)
|
||||
exclude_types = list(/obj/item/organ/liver/cybernetic/tier2, /obj/item/organ/liver/cybernetic/tier3)
|
||||
|
||||
/datum/export/organs/cybernetic
|
||||
cost = 225
|
||||
unit_name = "cybernetic organ"
|
||||
export_types = list(/obj/item/organ/liver/cybernetic, /obj/item/organ/lungs/cybernetic, /obj/item/organ/eyes/robotic, /obj/item/organ/heart/cybernetic)
|
||||
exclude_types = list(/obj/item/organ/lungs/cybernetic/upgraded, /obj/item/organ/liver/cybernetic/upgraded)
|
||||
export_types = list(/obj/item/organ/liver/cybernetic/tier2, /obj/item/organ/lungs/cybernetic/tier2, /obj/item/organ/eyes/robotic/shield, /obj/item/organ/eyes/robotic/glow, /obj/item/organ/stomach/cybernetic/tier2, /obj/item/organ/heart/cybernetic/tier2)
|
||||
exclude_types = list(/obj/item/organ/liver/cybernetic/tier3, /obj/item/organ/lungs/cybernetic/tier3, /obj/item/organ/eyes/robotic/xray, /obj/item/organ/eyes/robotic/thermals, /obj/item/organ/stomach/cybernetic/tier3, /obj/item/organ/heart/cybernetic/tier3)
|
||||
|
||||
/datum/export/organs/upgraded
|
||||
cost = 275
|
||||
unit_name = "upgraded cybernetic organ"
|
||||
export_types = list(/obj/item/organ/lungs/cybernetic/upgraded, /obj/item/organ/liver/cybernetic/upgraded)
|
||||
export_types = list(/obj/item/organ/liver/cybernetic/tier3, /obj/item/organ/lungs/cybernetic/tier3, /obj/item/organ/eyes/robotic/xray, /obj/item/organ/eyes/robotic/thermals, /obj/item/organ/stomach/cybernetic/tier3, /obj/item/organ/heart/cybernetic/tier3)
|
||||
|
||||
/datum/export/organs/tail // yeah have fun pulling this off someone without catching a bwoink
|
||||
cost = 500
|
||||
|
||||
@@ -80,15 +80,15 @@
|
||||
|
||||
/datum/supply_pack/security/russianclothing
|
||||
name = "Russian Surplus Clothing"
|
||||
desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproff armor, a few union suits and some warm hats!"
|
||||
desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproof armor, a few union suits and some warm hats!"
|
||||
contraband = TRUE
|
||||
cost = 5750 // Its basicly sec suits, good boots/gloves
|
||||
contains = list(/obj/item/clothing/suit/armor/navyblue/russian,
|
||||
/obj/item/clothing/suit/armor/navyblue/russian,
|
||||
contains = list(/obj/item/clothing/under/syndicate/rus_army,
|
||||
/obj/item/clothing/under/syndicate/rus_army,
|
||||
/obj/item/clothing/shoes/combat,
|
||||
/obj/item/clothing/shoes/combat,
|
||||
/obj/item/clothing/head/ushanka,
|
||||
/obj/item/clothing/head/ushanka,
|
||||
/obj/item/clothing/head/helmet/rus_helmet,
|
||||
/obj/item/clothing/head/helmet/rus_helmet,
|
||||
/obj/item/clothing/suit/armor/bulletproof,
|
||||
/obj/item/clothing/suit/armor/bulletproof,
|
||||
/obj/item/clothing/head/helmet/alt,
|
||||
@@ -98,23 +98,21 @@
|
||||
/obj/item/clothing/mask/gas,
|
||||
/obj/item/clothing/mask/gas)
|
||||
crate_name = "surplus russian clothing"
|
||||
crate_type = /obj/structure/closet/crate/internals
|
||||
|
||||
/datum/supply_pack/security/russian_partisan
|
||||
name = "Russian Partisan Gear"
|
||||
desc = "An old russian partisan equipment crate, comes with a full russian outfit, a loaded surplus rifle and a second magazine."
|
||||
contraband = TRUE
|
||||
access = FALSE
|
||||
cost = 6500
|
||||
contains = list(/obj/item/clothing/suit/armor/navyblue/russian,
|
||||
/obj/item/clothing/shoes/combat,
|
||||
/obj/item/clothing/head/ushanka,
|
||||
/obj/item/clothing/head/helmet/rus_helmet,
|
||||
/obj/item/clothing/suit/armor/bulletproof,
|
||||
/obj/item/clothing/head/helmet/alt,
|
||||
/obj/item/clothing/gloves/tackler/combat/insulated,
|
||||
/obj/item/clothing/under/syndicate/rus_army,
|
||||
/obj/item/clothing/mask/gas)
|
||||
crate_name = "surplus russian gear"
|
||||
crate_type = /obj/structure/closet/crate/internals
|
||||
|
||||
/datum/supply_pack/security/russian_partisan/fill(obj/structure/closet/crate/C)
|
||||
..()
|
||||
@@ -241,7 +239,7 @@
|
||||
access = FALSE
|
||||
access_any = list(ACCESS_SECURITY, ACCESS_FORENSICS_LOCKERS)
|
||||
contains = list(/obj/item/ammo_box/c38/dumdum)
|
||||
crate_name = ".38 match crate"
|
||||
crate_name = ".38 dumdum crate"
|
||||
|
||||
/datum/supply_pack/security/match
|
||||
name = ".38 Match Grade Speedloader"
|
||||
|
||||
@@ -227,6 +227,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/persistent_scars = TRUE
|
||||
///If we want to broadcast deadchat connect/disconnect messages
|
||||
var/broadcast_login_logout = TRUE
|
||||
///What outfit typepaths we've favorited in the SelectEquipment menu
|
||||
var/list/favorite_outfits = list()
|
||||
/// We have 5 slots for persistent scars, if enabled we pick a random one to load (empty by default) and scars at the end of the shift if we survived as our original person
|
||||
var/list/scars_list = list("1" = "", "2" = "", "3" = "", "4" = "", "5" = "")
|
||||
/// Which of the 5 persistent scar slots we randomly roll to load for this round, if enabled. Actually rolled in [/datum/preferences/proc/load_character(slot)]
|
||||
|
||||
@@ -406,6 +406,15 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["auto_ooc"] >> auto_ooc
|
||||
S["no_tetris_storage"] >> no_tetris_storage
|
||||
|
||||
//favorite outfits
|
||||
S["favorite_outfits"] >> favorite_outfits
|
||||
|
||||
var/list/parsed_favs = list()
|
||||
for(var/typetext in favorite_outfits)
|
||||
var/datum/outfit/path = text2path(typetext)
|
||||
if(ispath(path)) //whatever typepath fails this check probably doesn't exist anymore
|
||||
parsed_favs += path
|
||||
favorite_outfits = uniqueList(parsed_favs)
|
||||
|
||||
//try to fix any outdated data if necessary
|
||||
if(needs_update >= 0)
|
||||
@@ -455,6 +464,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
no_tetris_storage = sanitize_integer(no_tetris_storage, 0, 1, initial(no_tetris_storage))
|
||||
key_bindings = sanitize_islist(key_bindings, list())
|
||||
modless_key_bindings = sanitize_islist(modless_key_bindings, list())
|
||||
favorite_outfits = SANITIZE_LIST(favorite_outfits)
|
||||
|
||||
verify_keybindings_valid() // one of these days this will runtime and you'll be glad that i put it in a different proc so no one gets their saves wiped
|
||||
|
||||
@@ -556,6 +566,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["pda_skin"], pda_skin)
|
||||
WRITE_FILE(S["key_bindings"], key_bindings)
|
||||
WRITE_FILE(S["modless_key_bindings"], modless_key_bindings)
|
||||
WRITE_FILE(S["favorite_outfits"], favorite_outfits)
|
||||
|
||||
//citadel code
|
||||
WRITE_FILE(S["screenshake"], screenshake)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
set desc = "Authorizes your account in the panic bunker of any servers connected to this function."
|
||||
set category = "OOC"
|
||||
|
||||
if(!(prefs.db_flags & DB_FLAG_AGE_CONFIRMATION_INCOMPLETE))
|
||||
if(prefs.db_flags & DB_FLAG_AGE_CONFIRMATION_INCOMPLETE)
|
||||
to_chat(src, "<span class='danger'>You are not age verified.</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -83,8 +83,7 @@
|
||||
standard_outfit_options = list()
|
||||
for(var/path in subtypesof(/datum/outfit/job))
|
||||
var/datum/outfit/O = path
|
||||
if(initial(O.can_be_admin_equipped))
|
||||
standard_outfit_options[initial(O.name)] = path
|
||||
standard_outfit_options[initial(O.name)] = path
|
||||
sortTim(standard_outfit_options, /proc/cmp_text_asc)
|
||||
outfit_options = standard_outfit_options
|
||||
|
||||
|
||||
@@ -358,6 +358,12 @@
|
||||
..()
|
||||
user.cure_blind("blindfold_[REF(src)]")
|
||||
|
||||
/obj/item/clothing/glasses/fakeblindfold
|
||||
name = "thin blindfold"
|
||||
desc = "Covers the eyes, but not thick enough to obscure vision. Mostly for aesthetic."
|
||||
icon_state = "blindfoldwhite"
|
||||
item_state = "blindfoldwhite"
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/blindfold/white
|
||||
name = "blind personnel blindfold"
|
||||
desc = "Indicates that the wearer suffers from blindness."
|
||||
|
||||
@@ -145,7 +145,7 @@
|
||||
/obj/item/clothing/suit/armor/riot
|
||||
name = "riot suit"
|
||||
desc = "A suit of semi-flexible polycarbonate body armor with heavy padding to protect against melee attacks. Helps the wearer resist shoving in close quarters."
|
||||
icon_state = "riot"
|
||||
icon_state = "swat"
|
||||
item_state = "swat_suit"
|
||||
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
||||
cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
||||
|
||||
@@ -24,7 +24,12 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
/mob/living/carbon/human/dummy/proc/wipe_state()
|
||||
delete_equipment()
|
||||
icon_render_key = null
|
||||
cut_overlays()
|
||||
cut_overlays(TRUE)
|
||||
|
||||
/mob/living/carbon/human/dummy/setup_human_dna()
|
||||
create_dna(src)
|
||||
randomize_human(src)
|
||||
dna.initialize_dna(skip_index = TRUE) //Skip stuff that requires full round init.
|
||||
|
||||
//Inefficient pooling/caching way.
|
||||
GLOBAL_LIST_EMPTY(human_dummy_list)
|
||||
@@ -42,13 +47,48 @@ GLOBAL_LIST_EMPTY(dummy_mob_list)
|
||||
D = new
|
||||
GLOB.human_dummy_list[slotkey] = D
|
||||
GLOB.dummy_mob_list += D
|
||||
else
|
||||
D.regenerate_icons() //they were cut in wipe_state()
|
||||
D.in_use = TRUE
|
||||
return D
|
||||
|
||||
/proc/unset_busy_human_dummy(slotnumber)
|
||||
if(!slotnumber)
|
||||
/proc/generate_dummy_lookalike(slotkey, mob/target)
|
||||
if(!istype(target))
|
||||
return generate_or_wait_for_human_dummy(slotkey)
|
||||
|
||||
var/mob/living/carbon/human/dummy/copycat = generate_or_wait_for_human_dummy(slotkey)
|
||||
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/carbon_target = target
|
||||
carbon_target.dna.transfer_identity(copycat, transfer_SE = TRUE)
|
||||
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/human_target = target
|
||||
human_target.copy_clothing_prefs(copycat)
|
||||
|
||||
copycat.updateappearance(icon_update=TRUE, mutcolor_update=TRUE, mutations_overlay_update=TRUE)
|
||||
else
|
||||
//even if target isn't a carbon, if they have a client we can make the
|
||||
//dummy look like what their human would look like based on their prefs
|
||||
target?.client?.prefs?.copy_to(copycat, icon_updates=TRUE, roundstart_checks=FALSE)
|
||||
|
||||
return copycat
|
||||
|
||||
/proc/unset_busy_human_dummy(slotkey)
|
||||
if(!slotkey)
|
||||
return
|
||||
var/mob/living/carbon/human/dummy/D = GLOB.human_dummy_list[slotnumber]
|
||||
var/mob/living/carbon/human/dummy/D = GLOB.human_dummy_list[slotkey]
|
||||
if(istype(D))
|
||||
D.wipe_state()
|
||||
D.in_use = FALSE
|
||||
|
||||
/proc/clear_human_dummy(slotkey)
|
||||
if(!slotkey)
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/dummy/dummy = GLOB.human_dummy_list[slotkey]
|
||||
|
||||
GLOB.human_dummy_list -= slotkey
|
||||
if(istype(dummy))
|
||||
GLOB.dummy_mob_list -= dummy
|
||||
qdel(dummy)
|
||||
|
||||
@@ -14,10 +14,7 @@
|
||||
//initialize limbs first
|
||||
create_bodyparts()
|
||||
|
||||
//initialize dna. for spawned humans; overwritten by other code
|
||||
create_dna(src)
|
||||
randomize_human(src)
|
||||
dna.initialize_dna()
|
||||
setup_human_dna()
|
||||
|
||||
if(dna.species)
|
||||
set_species(dna.species.type)
|
||||
@@ -36,6 +33,11 @@
|
||||
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /atom.proc/clean_blood)
|
||||
GLOB.human_list += src
|
||||
|
||||
/mob/living/carbon/human/proc/setup_human_dna()
|
||||
//initialize dna. for spawned humans; overwritten by other code
|
||||
create_dna(src)
|
||||
randomize_human(src)
|
||||
dna.initialize_dna()
|
||||
|
||||
/mob/living/carbon/human/ComponentInitialize()
|
||||
. = ..()
|
||||
|
||||
@@ -176,3 +176,9 @@
|
||||
|
||||
/mob/living/carbon/human/get_biological_state()
|
||||
return dna.species.get_biological_state()
|
||||
|
||||
///copies over clothing preferences like underwear to another human
|
||||
/mob/living/carbon/human/proc/copy_clothing_prefs(mob/living/carbon/human/destination)
|
||||
destination.underwear = underwear
|
||||
destination.undershirt = undershirt
|
||||
destination.socks = socks
|
||||
|
||||
@@ -23,7 +23,7 @@ Difficulty: Hard
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum
|
||||
name = "bubblegum"
|
||||
name = "Bubblegum"
|
||||
desc = "In what passes for a hierarchy among slaughter demons, this one is king."
|
||||
health = 2500
|
||||
maxHealth = 2500
|
||||
@@ -443,7 +443,7 @@ Difficulty: Hard
|
||||
charge(chargeat, delay, chargepast)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination
|
||||
name = "bubblegum's hallucination"
|
||||
name = "Bubblegum's hallucination"
|
||||
desc = "Is that really just a hallucination?"
|
||||
health = 1
|
||||
maxHealth = 1
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
friendly_verb_simple = "groom"
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
movement_type = FLYING
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
|
||||
var/parrot_damage_upper = 10
|
||||
var/parrot_state = PARROT_WANDER //Hunt for a perch when created
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
/obj/item/ammo_casing/chemgun
|
||||
name = "dart synthesiser"
|
||||
desc = "A high-power spring, linked to an energy-based dart synthesiser."
|
||||
projectile_type = /obj/item/projectile/bullet/dart
|
||||
projectile_type = /obj/item/projectile/bullet/dart/piercing
|
||||
firing_effect_type = null
|
||||
|
||||
/obj/item/ammo_casing/chemgun/ready_proj(atom/target, mob/living/user, quiet, zone_override = "")
|
||||
@@ -35,7 +35,7 @@
|
||||
var/obj/item/gun/chem/CG = loc
|
||||
if(CG.syringes_left <= 0)
|
||||
return
|
||||
CG.reagents.trans_to(BB, 15)
|
||||
CG.reagents.trans_to(BB, 10)
|
||||
BB.name = "chemical dart"
|
||||
CG.syringes_left--
|
||||
..()
|
||||
|
||||
@@ -407,11 +407,11 @@
|
||||
fire_sound = 'sound/weapons/rifleshot.ogg'
|
||||
weapon_weight = WEAPON_HEAVY
|
||||
mag_type = /obj/item/ammo_box/magazine/m10mm/rifle
|
||||
fire_delay = 30
|
||||
fire_delay = 10
|
||||
burst_size = 1
|
||||
can_unsuppress = TRUE
|
||||
can_suppress = TRUE
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
automatic_burst_overlay = FALSE
|
||||
actions_types = list()
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
custom_materials = list(/datum/material/iron=2000)
|
||||
clumsy_check = FALSE
|
||||
fire_sound = 'sound/items/syringeproj.ogg'
|
||||
var/time_per_syringe = 250
|
||||
var/syringes_left = 4
|
||||
var/max_syringes = 4
|
||||
var/time_per_syringe = 300
|
||||
var/syringes_left = 5
|
||||
var/max_syringes = 5
|
||||
var/last_synth = 0
|
||||
|
||||
/obj/item/gun/chem/Initialize()
|
||||
|
||||
@@ -644,66 +644,109 @@
|
||||
//Cybernetic organs
|
||||
|
||||
/datum/design/cybernetic_liver
|
||||
name = "Cybernetic Liver"
|
||||
desc = "A cybernetic liver"
|
||||
name = "Basic Cybernetic Liver"
|
||||
desc = "A basic cybernetic liver."
|
||||
id = "cybernetic_liver"
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
construction_time = 40
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500)
|
||||
build_path = /obj/item/organ/liver/cybernetic
|
||||
category = list("Misc","Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/datum/design/cybernetic_heart
|
||||
name = "Cybernetic Heart"
|
||||
desc = "A cybernetic heart"
|
||||
id = "cybernetic_heart"
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500)
|
||||
build_path = /obj/item/organ/heart/cybernetic
|
||||
category = list("Misc","Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/datum/design/cybernetic_heart_u
|
||||
name = "Upgraded Cybernetic Heart"
|
||||
desc = "An upgraded cybernetic heart"
|
||||
id = "cybernetic_heart_u"
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
construction_time = 50
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 500)
|
||||
build_path = /obj/item/organ/heart/cybernetic/upgraded
|
||||
category = list("Misc", "Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/datum/design/cybernetic_liver_u
|
||||
name = "Upgraded Cybernetic Liver"
|
||||
desc = "An upgraded cybernetic liver"
|
||||
id = "cybernetic_liver_u"
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
/datum/design/cybernetic_liver/tier2
|
||||
name = "Cybernetic Liver"
|
||||
desc = "A cybernetic liver."
|
||||
id = "cybernetic_liver_tier2"
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500)
|
||||
build_path = /obj/item/organ/liver/cybernetic/upgraded
|
||||
category = list("Misc","Medical Designs")
|
||||
build_path = /obj/item/organ/liver/cybernetic/tier2
|
||||
|
||||
/datum/design/cybernetic_liver/tier3
|
||||
name = "Upgraded Cybernetic Liver"
|
||||
desc = "An upgraded cybernetic liver."
|
||||
id = "cybernetic_liver_tier3"
|
||||
construction_time = 50
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 600, /datum/material/gold = 600, /datum/material/plasma = 1000, /datum/material/diamond = 2000)
|
||||
build_path = /obj/item/organ/liver/cybernetic/tier3
|
||||
|
||||
/datum/design/cybernetic_heart
|
||||
name = "Basic Cybernetic Heart"
|
||||
desc = "A basic cybernetic heart."
|
||||
id = "cybernetic_heart"
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
construction_time = 40
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500)
|
||||
build_path = /obj/item/organ/heart/cybernetic
|
||||
category = list("Misc", "Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/datum/design/cybernetic_heart/tier2
|
||||
name = "Cybernetic Heart"
|
||||
desc = "A cybernetic heart."
|
||||
id = "cybernetic_heart_tier2"
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500)
|
||||
build_path = /obj/item/organ/heart/cybernetic/tier2
|
||||
|
||||
/datum/design/cybernetic_heart/tier3
|
||||
name = "Upgraded Cybernetic Heart"
|
||||
desc = "An upgraded cybernetic heart."
|
||||
id = "cybernetic_heart_tier3"
|
||||
construction_time = 50
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 600, /datum/material/gold = 600, /datum/material/plasma = 1000, /datum/material/diamond = 2000)
|
||||
build_path = /obj/item/organ/heart/cybernetic/tier3
|
||||
|
||||
/datum/design/cybernetic_lungs
|
||||
name = "Cybernetic Lungs"
|
||||
desc = "A pair of cybernetic lungs."
|
||||
name = "Basic Cybernetic Lungs"
|
||||
desc = "A basic pair of cybernetic lungs."
|
||||
id = "cybernetic_lungs"
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
construction_time = 40
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500)
|
||||
build_path = /obj/item/organ/lungs/cybernetic
|
||||
category = list("Misc","Medical Designs")
|
||||
category = list("Misc", "Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/datum/design/cybernetic_lungs_u
|
||||
/datum/design/cybernetic_lungs/tier2
|
||||
name = "Cybernetic Lungs"
|
||||
desc = "A pair of cybernetic lungs."
|
||||
id = "cybernetic_lungs_tier2"
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500)
|
||||
build_path = /obj/item/organ/lungs/cybernetic/tier2
|
||||
|
||||
/datum/design/cybernetic_lungs/tier3
|
||||
name = "Upgraded Cybernetic Lungs"
|
||||
desc = "A pair of upgraded cybernetic lungs."
|
||||
id = "cybernetic_lungs_u"
|
||||
id = "cybernetic_lungs_tier3"
|
||||
construction_time = 50
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 600, /datum/material/gold = 600, /datum/material/plasma = 1000, /datum/material/diamond = 2000)
|
||||
build_path = /obj/item/organ/lungs/cybernetic/tier3
|
||||
|
||||
/datum/design/cybernetic_stomach
|
||||
name = "Basic Cybernetic Stomach"
|
||||
desc = "A basic cybernetic stomach."
|
||||
id = "cybernetic_stomach"
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 500)
|
||||
build_path = /obj/item/organ/lungs/cybernetic/upgraded
|
||||
category = list("Misc","Medical Designs")
|
||||
construction_time = 40
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500)
|
||||
build_path = /obj/item/organ/stomach/cybernetic
|
||||
category = list("Misc", "Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/datum/design/cybernetic_stomach/tier2
|
||||
name = "Cybernetic Stomach"
|
||||
desc = "A cybernetic stomach."
|
||||
id = "cybernetic_stomach_tier2"
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500)
|
||||
build_path = /obj/item/organ/stomach/cybernetic/tier2
|
||||
|
||||
/datum/design/cybernetic_stomach/tier3
|
||||
name = "Upgraded Cybernetic Stomach"
|
||||
desc = "An upgraded cybernetic stomach."
|
||||
id = "cybernetic_stomach_tier3"
|
||||
construction_time = 50
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 600, /datum/material/gold = 600, /datum/material/plasma = 1000, /datum/material/diamond = 2000)
|
||||
build_path = /obj/item/organ/stomach/cybernetic/tier3
|
||||
|
||||
/datum/design/cybernetic_tongue
|
||||
name = "Cybernetic tongue"
|
||||
desc = "A fancy cybernetic tongue."
|
||||
@@ -711,7 +754,7 @@
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
materials = list(/datum/material/iron = 500, /datum/material/glass = 500)
|
||||
build_path = /obj/item/organ/tongue/cybernetic
|
||||
category = list("Misc","Medical Designs")
|
||||
category = list("Misc", "Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/datum/design/cybernetic_ears
|
||||
|
||||
@@ -67,20 +67,27 @@
|
||||
design_ids = list("implanter", "implantcase", "implant_chem", "implant_tracking", "locator", "c38_trac")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
|
||||
/datum/techweb_node/basic_cyber_organs
|
||||
id = "basic_cyber_organs"
|
||||
starting_node = TRUE
|
||||
display_name = "Basic Cybernetic Organs"
|
||||
description = "We have the techinology to force him to live a disgusting halflife."
|
||||
design_ids = list("cybernetic_liver", "cybernetic_heart", "cybernetic_lungs", "cybernetic_stomach")
|
||||
|
||||
/datum/techweb_node/cyber_organs
|
||||
id = "cyber_organs"
|
||||
display_name = "Cybernetic Organs"
|
||||
description = "We have the technology to rebuild him."
|
||||
prereq_ids = list("adv_biotech")
|
||||
design_ids = list("cybernetic_ears", "cybernetic_heart", "cybernetic_liver", "cybernetic_lungs", "cybernetic_tongue")
|
||||
prereq_ids = list("biotech")
|
||||
design_ids = list("cybernetic_ears", "cybernetic_heart_tier2", "cybernetic_liver_tier2", "cybernetic_lungs_tier2", "cybernetic_stomach_tier2")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000)
|
||||
|
||||
/datum/techweb_node/cyber_organs_upgraded
|
||||
id = "cyber_organs_upgraded"
|
||||
display_name = "Upgraded Cybernetic Organs"
|
||||
description = "We have the technology to upgrade him."
|
||||
prereq_ids = list("cyber_organs")
|
||||
design_ids = list("cybernetic_ears_u", "cybernetic_heart_u", "cybernetic_liver_u", "cybernetic_lungs_u", "ipc_stomach")
|
||||
prereq_ids = list("adv_biotech", "cyber_organs")
|
||||
design_ids = list("cybernetic_ears_u", "cybernetic_heart_tier3", "cybernetic_liver_tier3", "cybernetic_lungs_tier3", "cybernetic_stomach_tier3")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500)
|
||||
|
||||
/datum/techweb_node/cyber_implants
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
id = "advanced_illegal_ballistics"
|
||||
display_name = "Advanced Non-Standard Ballistics"
|
||||
description = "Ballistic ammunition for non-standard firearms. Usually the ones you don't have nor want to be involved with."
|
||||
design_ids = list("10mm","10mmap","10mminc","10mmhp","sl357","sl357ap","pistolm9mm","m45","bolt_clip")
|
||||
design_ids = list("10mm","10mmap","10mminc","10mmhp","sl357","sl357ap","pistolm9mm","m45","bolt_clip","m10apbox","m10firebox","m10hpbox")
|
||||
prereq_ids = list("ballistic_weapons","syndicate_basic","explosive_weapons")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 25000) //This gives sec lethal mags/clips for guns from traitors, space, or anything in between.
|
||||
|
||||
|
||||
@@ -197,45 +197,67 @@
|
||||
colour = "red"
|
||||
|
||||
/obj/item/organ/heart/cybernetic
|
||||
name = "cybernetic heart"
|
||||
desc = "An electronic device designed to mimic the functions of an organic human heart. Offers no benefit over an organic heart other than being easy to make."
|
||||
name = "basic cybernetic heart"
|
||||
desc = "A basic electronic device designed to mimic the functions of an organic human heart."
|
||||
icon_state = "heart-c"
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
maxHealth = STANDARD_ORGAN_THRESHOLD*0.75 //This also hits defib timer, so a bit higher than its less important counterparts
|
||||
|
||||
var/dose_available = FALSE
|
||||
var/rid = /datum/reagent/medicine/epinephrine
|
||||
var/ramount = 10
|
||||
var/emp_vulnerability = 1 //The value the severity of emps are divided by to determine the likelihood of permanent damage.
|
||||
|
||||
/obj/item/organ/heart/cybernetic/tier2
|
||||
name = "cybernetic heart"
|
||||
desc = "An electronic device designed to mimic the functions of an organic human heart. Also holds an emergency dose of epinephrine, used automatically after facing severe trauma."
|
||||
icon_state = "heart-c-u"
|
||||
maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD
|
||||
dose_available = TRUE
|
||||
emp_vulnerability = 2
|
||||
|
||||
/obj/item/organ/heart/cybernetic/tier3
|
||||
name = "upgraded cybernetic heart"
|
||||
desc = "An electronic device designed to mimic the functions of an organic human heart. Also holds an emergency dose of epinephrine, used automatically after facing severe trauma. This upgraded model can regenerate its dose after use."
|
||||
icon_state = "heart-c-u2"
|
||||
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
|
||||
dose_available = TRUE
|
||||
rid = /datum/reagent/medicine/atropine
|
||||
ramount = 5
|
||||
emp_vulnerability = 3
|
||||
|
||||
/obj/item/organ/heart/cybernetic/emp_act(severity)
|
||||
. = ..()
|
||||
|
||||
// If the owner doesn't need a heart, we don't need to do anything with it.
|
||||
if(!owner.needs_heart())
|
||||
return
|
||||
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
Stop()
|
||||
addtimer(CALLBACK(src, .proc/Restart), 0.2*severity SECONDS)
|
||||
damage += severity
|
||||
if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people.
|
||||
owner.Dizzy(10)
|
||||
owner.losebreath += 10
|
||||
COOLDOWN_START(src, severe_cooldown, 20 SECONDS)
|
||||
if(prob(severity/emp_vulnerability)) //Chance of permanent effects
|
||||
organ_flags |= ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon.
|
||||
Stop()
|
||||
owner.visible_message("<span class='danger'>[owner] clutches at [owner.p_their()] chest as if [owner.p_their()] heart is stopping!</span>", \
|
||||
"<span class='userdanger'>You feel a terrible pain in your chest, as if your heart has stopped!</span>")
|
||||
addtimer(CALLBACK(src, .proc/Restart), 10 SECONDS)
|
||||
|
||||
/obj/item/organ/heart/cybernetic/upgraded
|
||||
name = "upgraded cybernetic heart"
|
||||
desc = "An electronic device designed to mimic the functions of an organic human heart. Also holds an emergency dose of epinephrine, used automatically after facing severe trauma. This upgraded model can regenerate its dose after use."
|
||||
icon_state = "heart-c-u"
|
||||
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
|
||||
|
||||
//I put it on upgraded for now.
|
||||
var/dose_available = TRUE
|
||||
var/rid = /datum/reagent/medicine/epinephrine
|
||||
var/ramount = 10
|
||||
|
||||
/obj/item/organ/heart/cybernetic/upgraded/on_life()
|
||||
/obj/item/organ/heart/cybernetic/on_life(delta_time, times_fired)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(dose_available && owner.health <= owner.crit_threshold && !owner.reagents.has_reagent(rid))
|
||||
owner.reagents.add_reagent(rid, ramount)
|
||||
used_dose()
|
||||
if(ramount < 10) //eats your nutrition to regen epinephrine
|
||||
var/regen_amount = owner.nutrition/2000
|
||||
owner.adjust_nutrition(-regen_amount)
|
||||
ramount += regen_amount
|
||||
|
||||
/obj/item/organ/heart/cybernetic/upgraded/proc/used_dose()
|
||||
/obj/item/organ/heart/cybernetic/proc/used_dose()
|
||||
owner.reagents.add_reagent(rid, ramount)
|
||||
dose_available = FALSE
|
||||
|
||||
/obj/item/organ/heart/cybernetic/tier3/used_dose()
|
||||
. = ..()
|
||||
addtimer(VARSET_CALLBACK(src, dose_available, TRUE), 5 MINUTES)
|
||||
ramount = 0
|
||||
|
||||
/obj/item/organ/heart/ipc
|
||||
name = "IPC heart"
|
||||
|
||||
@@ -98,23 +98,41 @@
|
||||
icon_state = "liver-c"
|
||||
|
||||
/obj/item/organ/liver/cybernetic
|
||||
name = "cybernetic liver"
|
||||
name = "basic cybernetic liver"
|
||||
icon_state = "liver-c"
|
||||
desc = "An electronic device designed to mimic the functions of a human liver. It has no benefits over an organic liver, but is easy to produce."
|
||||
desc = "A very basic device designed to mimic the functions of a human liver. Handles toxins slightly worse than an organic liver."
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
maxHealth = 1.1 * STANDARD_ORGAN_THRESHOLD
|
||||
toxTolerance = 0.3 * LIVER_DEFAULT_TOX_TOLERANCE //little less than 1u of toxin purging
|
||||
toxLethality = 1.1 * LIVER_DEFAULT_TOX_LETHALITY
|
||||
maxHealth = STANDARD_ORGAN_THRESHOLD*0.5
|
||||
|
||||
/obj/item/organ/liver/cybernetic/upgraded
|
||||
name = "upgraded cybernetic liver"
|
||||
var/emp_vulnerability = 1 //The value the severity of emps are divided by to determine the likelihood of permanent damage.
|
||||
|
||||
/obj/item/organ/liver/cybernetic/tier2
|
||||
name = "cybernetic liver"
|
||||
icon_state = "liver-c-u"
|
||||
desc = "An upgraded version of the cybernetic liver, designed to improve upon organic livers. It is resistant to alcohol poisoning and is very robust at filtering toxins."
|
||||
desc = "An electronic device designed to mimic the functions of a human liver. Handles toxins slightly better than an organic liver."
|
||||
maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD
|
||||
toxTolerance = 2 * LIVER_DEFAULT_TOX_TOLERANCE //6 units of toxin purging
|
||||
toxLethality = 0.8 * LIVER_DEFAULT_TOX_LETHALITY //20% less damage than a normal liver
|
||||
emp_vulnerability = 2
|
||||
|
||||
/obj/item/organ/liver/cybernetic/tier3
|
||||
name = "upgraded cybernetic liver"
|
||||
icon_state = "liver-c-u2"
|
||||
desc = "An upgraded version of the cybernetic liver, designed to improve further upon organic livers. It is resistant to alcohol poisoning and is very robust at filtering toxins."
|
||||
alcohol_tolerance = 0.001
|
||||
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
|
||||
toxTolerance = 15 //can shrug off up to 15u of toxins
|
||||
toxLethality = 0.008 //20% less damage than a normal liver
|
||||
toxTolerance = 5 * LIVER_DEFAULT_TOX_TOLERANCE //15 units of toxin purging
|
||||
toxLethality = 0.4 * LIVER_DEFAULT_TOX_LETHALITY //60% less damage than a normal liver
|
||||
emp_vulnerability = 3
|
||||
|
||||
/obj/item/organ/liver/cybernetic/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
damage += severity
|
||||
if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people.
|
||||
owner.adjustToxLoss(10)
|
||||
COOLDOWN_START(src, severe_cooldown, 10 SECONDS)
|
||||
if(prob(severity/emp_vulnerability)) //Chance of permanent effects
|
||||
organ_flags |= ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon.
|
||||
|
||||
@@ -547,33 +547,52 @@
|
||||
maxHealth = INFINITY//I don't understand how plamamen work, so I'm not going to try t give them special lungs atm
|
||||
|
||||
/obj/item/organ/lungs/cybernetic
|
||||
name = "cybernetic lungs"
|
||||
desc = "A cybernetic version of the lungs found in traditional humanoid entities. It functions the same as an organic lung and is merely meant as a replacement."
|
||||
name = "basic cybernetic lungs"
|
||||
desc = "A basic cybernetic version of the lungs found in traditional humanoid entities."
|
||||
icon_state = "lungs-c"
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
maxHealth = 400
|
||||
safe_oxygen_min = 13
|
||||
maxHealth = STANDARD_ORGAN_THRESHOLD * 0.5
|
||||
|
||||
/obj/item/organ/lungs/cybernetic/emp_act()
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
owner.losebreath = 20
|
||||
owner.adjustOrganLoss(ORGAN_SLOT_LUNGS, 25)
|
||||
var/emp_vulnerability = 1 //The value the severity of emps are divided by to determine the likelihood of permanent damage.
|
||||
|
||||
/obj/item/organ/lungs/cybernetic/upgraded
|
||||
name = "upgraded cybernetic lungs"
|
||||
desc = "A more advanced version of the stock cybernetic lungs. They are capable of filtering out lower levels of toxins and carbon dioxide."
|
||||
/obj/item/organ/lungs/cybernetic/tier2
|
||||
name = "cybernetic lungs"
|
||||
desc = "A cybernetic version of the lungs found in traditional humanoid entities. Allows for greater intakes of oxygen than organic lungs, requiring slightly less pressure."
|
||||
icon_state = "lungs-c-u"
|
||||
safe_toxins_max = 20
|
||||
safe_co2_max = 20
|
||||
safe_oxygen_max = 250
|
||||
maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD
|
||||
safe_oxygen_min = 13
|
||||
safe_oxygen_max = 100
|
||||
emp_vulnerability = 2
|
||||
|
||||
/obj/item/organ/lungs/cybernetic/tier3
|
||||
name = "upgraded cybernetic lungs"
|
||||
desc = "A more advanced version of the stock cybernetic lungs. Features the ability to filter out various airbourne toxins and carbon dioxide even at heavy levels."
|
||||
icon_state = "lungs-c-u2"
|
||||
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
|
||||
safe_oxygen_min = 4 //You could literally be breathing the thinnest amount of oxygen and be fine
|
||||
safe_oxygen_max = 250 //Or be in an enriched oxygen room for that matter
|
||||
safe_toxins_max = 30
|
||||
safe_co2_max = 30
|
||||
SA_para_min = 30
|
||||
SA_sleep_min = 50
|
||||
BZ_trip_balls_min = 30
|
||||
emp_vulnerability = 3
|
||||
|
||||
cold_level_1_threshold = 200
|
||||
cold_level_2_threshold = 140
|
||||
cold_level_3_threshold = 100
|
||||
maxHealth = 550
|
||||
|
||||
/obj/item/organ/lungs/cybernetic/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people.
|
||||
owner.losebreath += 20
|
||||
COOLDOWN_START(src, severe_cooldown, 30 SECONDS)
|
||||
if(prob(severity/emp_vulnerability)) //Chance of permanent effects
|
||||
organ_flags |= ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon.
|
||||
|
||||
/obj/item/organ/lungs/ashwalker
|
||||
name = "ash lungs"
|
||||
desc = "blackened lungs identical from specimens recovered from lavaland, unsuited to higher air pressures."
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
var/decay_factor = 0 //same as above but when without a living owner, set to 0 for generic organs
|
||||
var/high_threshold = STANDARD_ORGAN_THRESHOLD * 0.45 //when severe organ damage occurs
|
||||
var/low_threshold = STANDARD_ORGAN_THRESHOLD * 0.1 //when minor organ damage occurs
|
||||
var/severe_cooldown //cooldown for severe effects, used for synthetic organ emp effects.
|
||||
|
||||
///Organ variables for determining what we alert the owner with when they pass/clear the damage thresholds
|
||||
var/prev_damage = 0
|
||||
@@ -153,6 +154,9 @@
|
||||
/obj/item/organ/proc/on_life() //repair organ damage if the organ is not failing or synthetic
|
||||
if(organ_flags & ORGAN_FAILING || !owner)
|
||||
return FALSE
|
||||
if(organ_flags & ORGAN_SYNTHETIC_EMP) //Synthetic organ has been emped, is now failing.
|
||||
applyOrganDamage(maxHealth * decay_factor)
|
||||
return
|
||||
if(!is_cold() && damage)
|
||||
///Damage decrements by a percent of its maxhealth
|
||||
var/healing_amount = -(maxHealth * healing_factor)
|
||||
|
||||
@@ -93,6 +93,40 @@
|
||||
icon_state = "stomach-p"
|
||||
desc = "A strange crystal that is responsible for metabolizing the unseen energy force that feeds plasmamen."
|
||||
|
||||
/obj/item/organ/stomach/cybernetic
|
||||
name = "basic cybernetic stomach"
|
||||
icon_state = "stomach-c"
|
||||
desc = "A basic device designed to mimic the functions of a human stomach"
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
maxHealth = STANDARD_ORGAN_THRESHOLD * 0.5
|
||||
var/emp_vulnerability = 1 //The value the severity of emps are divided by to determine the likelihood of permanent damage.
|
||||
|
||||
/obj/item/organ/stomach/cybernetic/tier2
|
||||
name = "cybernetic stomach"
|
||||
icon_state = "stomach-c-u"
|
||||
desc = "An electronic device designed to mimic the functions of a human stomach. Handles disgusting food a bit better."
|
||||
maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD
|
||||
disgust_metabolism = 2
|
||||
emp_vulnerability = 2
|
||||
|
||||
/obj/item/organ/stomach/cybernetic/tier3
|
||||
name = "upgraded cybernetic stomach"
|
||||
icon_state = "stomach-c-u2"
|
||||
desc = "An upgraded version of the cybernetic stomach, designed to improve further upon organic stomachs. Handles disgusting food very well."
|
||||
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
|
||||
disgust_metabolism = 3
|
||||
emp_vulnerability = 3
|
||||
|
||||
/obj/item/organ/stomach/cybernetic/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people.
|
||||
owner.vomit(stun = FALSE)
|
||||
COOLDOWN_START(src, severe_cooldown, 10 SECONDS)
|
||||
if(prob(severity/emp_vulnerability)) //Chance of permanent effects
|
||||
organ_flags |= ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon.
|
||||
|
||||
/obj/item/organ/stomach/ipc
|
||||
name = "ipc cell"
|
||||
icon_state = "stomach-ipc"
|
||||
|
||||
@@ -208,9 +208,10 @@
|
||||
|
||||
/datum/uplink_item/role_restricted/chemical_gun
|
||||
name = "Reagent Dartgun"
|
||||
desc = "A heavily modified syringe gun which is capable of synthesizing its own chemical darts using input reagents. Can hold 100u of reagents."
|
||||
desc = "A heavily modified syringe gun which is capable of synthesizing its own chemical darts using input reagents. \
|
||||
Synthesizes one piercing 10 unit dart every 30 seconds up to a maximum of five. Can hold 100u of reagents."
|
||||
item = /obj/item/gun/chem
|
||||
cost = 12
|
||||
cost = 10
|
||||
restricted_roles = list("Chemist", "Chief Medical Officer")
|
||||
|
||||
/datum/uplink_item/role_restricted/reverse_bear_trap
|
||||
@@ -257,4 +258,4 @@
|
||||
item = /obj/item/storage/toolbox/emergency/turret
|
||||
cost = 11
|
||||
restricted_roles = list("Station Engineer")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user