mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-17 13:42:44 +00:00
Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into dislocation
Conflicts: code/modules/mob/living/carbon/human/human_attackhand.dm code/modules/mob/living/carbon/human/human_organs.dm
This commit is contained in:
@@ -296,7 +296,7 @@ var/list/admin_verbs_mentor = list(
|
||||
if(holder.rights & R_SERVER) verbs += admin_verbs_server
|
||||
if(holder.rights & R_DEBUG)
|
||||
verbs += admin_verbs_debug
|
||||
if(config.debugparanoid && !check_rights(R_ADMIN))
|
||||
if(config.debugparanoid && !(holder.rights & R_ADMIN))
|
||||
verbs.Remove(admin_verbs_paranoid_debug) //Right now it's just callproc but we can easily add others later on.
|
||||
if(holder.rights & R_POSSESS) verbs += admin_verbs_possess
|
||||
if(holder.rights & R_PERMISSIONS) verbs += admin_verbs_permissions
|
||||
@@ -724,7 +724,8 @@ var/list/admin_verbs_mentor = list(
|
||||
return
|
||||
|
||||
if(holder)
|
||||
S.subsystem_law_manager()
|
||||
var/obj/nano_module/law_manager/L = new(S)
|
||||
L.ui_interact(usr, state = admin_state)
|
||||
admin_log_and_message_admins("has opened [S]'s law manager.")
|
||||
feedback_add_details("admin_verb","MSL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -738,7 +739,7 @@ var/list/admin_verbs_mentor = list(
|
||||
|
||||
if(holder)
|
||||
admin_log_and_message_admins("is altering the appearance of [H].")
|
||||
H.change_appearance(APPEARANCE_ALL, usr, usr, check_species_whitelist = 0)
|
||||
H.change_appearance(APPEARANCE_ALL, usr, usr, check_species_whitelist = 0, state = admin_state)
|
||||
feedback_add_details("admin_verb","CHAA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/change_human_appearance_self(mob/living/carbon/human/H in mob_list)
|
||||
@@ -944,3 +945,14 @@ var/list/admin_verbs_mentor = list(
|
||||
|
||||
log_admin("[key_name(usr)] told everyone to man up and deal with it.")
|
||||
message_admins("\blue [key_name_admin(usr)] told everyone to man up and deal with it.", 1)
|
||||
|
||||
/client/proc/give_spell(mob/T as mob in mob_list) // -- Urist
|
||||
set category = "Fun"
|
||||
set name = "Give Spell"
|
||||
set desc = "Gives a spell to a mob."
|
||||
var/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spells
|
||||
if(!S) return
|
||||
T.spell_list += new S
|
||||
feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] gave [key_name(T)] the spell [S].")
|
||||
message_admins("\blue [key_name_admin(usr)] gave [key_name(T)] the spell [S].", 1)
|
||||
|
||||
@@ -1317,21 +1317,27 @@
|
||||
M.stuttering = 20
|
||||
|
||||
else if(href_list["CentcommReply"])
|
||||
var/mob/living/carbon/human/H = locate(href_list["CentcommReply"])
|
||||
if(!istype(H))
|
||||
usr << "This can only be used on instances of type /mob/living/carbon/human"
|
||||
return
|
||||
if(!istype(H.l_ear, /obj/item/device/radio/headset) && !istype(H.r_ear, /obj/item/device/radio/headset))
|
||||
usr << "The person you are trying to contact is not wearing a headset"
|
||||
var/mob/living/L = locate(href_list["CentcommReply"])
|
||||
if(!istype(L))
|
||||
usr << "This can only be used on instances of type /mob/living/"
|
||||
return
|
||||
|
||||
var/input = sanitize(input(src.owner, "Please enter a message to reply to [key_name(H)] via their headset.","Outgoing message from Centcomm", ""))
|
||||
if(!input) return
|
||||
if(L.can_centcom_reply())
|
||||
var/input = input(src.owner, "Please enter a message to reply to [key_name(L)] via their headset.","Outgoing message from Centcomm", "")
|
||||
if(!input) return
|
||||
|
||||
src.owner << "You sent [input] to [L] via a secure channel."
|
||||
log_admin("[src.owner] replied to [key_name(L)]'s Centcomm message with the message [input].")
|
||||
message_admins("[src.owner] replied to [key_name(L)]'s Centcom message with: \"[input]\"")
|
||||
if(!L.isAI())
|
||||
L << "<span class='info'>You hear something crackle in your headset for a moment before a voice speaks.</span>"
|
||||
L << "<span class='info'>Please stand by for a message from Central Command.</span>"
|
||||
L << "<span class='info'>Message as follows.</span>"
|
||||
L << "<span class='notice'>[input]</span>"
|
||||
L << "<span class='info'>Message ends.</span>"
|
||||
else
|
||||
src.owner << "The person you are trying to contact does not have functional radio equipment."
|
||||
|
||||
src.owner << "You sent [input] to [H] via a secure channel."
|
||||
log_admin("[src.owner] replied to [key_name(H)]'s Centcomm message with the message [input].")
|
||||
message_admins("[src.owner] replied to [key_name(H)]'s Centcom message with: \"[input]\"")
|
||||
H << "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from Central Command. Message as follows. <b>\"[input]\"</b> Message ends.\""
|
||||
|
||||
else if(href_list["SyndicateReply"])
|
||||
var/mob/living/carbon/human/H = locate(href_list["SyndicateReply"])
|
||||
@@ -2619,3 +2625,12 @@
|
||||
if("list")
|
||||
PlayerNotesPage(text2num(href_list["index"]))
|
||||
return
|
||||
|
||||
mob/living/proc/can_centcom_reply()
|
||||
return 0
|
||||
|
||||
mob/living/carbon/human/can_centcom_reply()
|
||||
return istype(l_ear, /obj/item/device/radio/headset) || istype(r_ear, /obj/item/device/radio/headset)
|
||||
|
||||
mob/living/silicon/ai/can_centcom_reply()
|
||||
return common_radio != null && !check_unable(2)
|
||||
@@ -590,7 +590,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
|
||||
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/det_suit(M), slot_wear_suit)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(M), slot_glasses)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/plain/monocle(M), slot_glasses)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/head/det_hat(M), slot_head)
|
||||
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/cloaking_device(M), slot_r_store)
|
||||
@@ -660,7 +660,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(M), slot_wear_mask)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/head/chaplain_hood(M), slot_head)
|
||||
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(M), slot_glasses)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/plain/monocle(M), slot_glasses)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/suit/chaplain_hoodie(M), slot_wear_suit)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/bikehorn(M), slot_r_store)
|
||||
|
||||
@@ -681,7 +681,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(M), slot_wear_mask)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/head/welding(M), slot_head)
|
||||
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(M), slot_glasses)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/plain/monocle(M), slot_glasses)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/suit/apron(M), slot_wear_suit)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/kitchenknife(M), slot_l_store)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/scalpel(M), slot_r_store)
|
||||
@@ -832,7 +832,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
|
||||
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/plain/eyepatch(M), slot_glasses)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/mask/smokable/cigarette/cigar/havana(M), slot_wear_mask)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad/beret(M), slot_head)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/M1911(M), slot_belt)
|
||||
@@ -888,7 +888,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
|
||||
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/plain/eyepatch(M), slot_glasses)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/suit/hgpirate(M), slot_wear_suit)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/mateba(M), slot_belt)
|
||||
|
||||
@@ -661,6 +661,12 @@ var/global/list/gear_datums = list()
|
||||
cost = 2
|
||||
slot = slot_shoes
|
||||
|
||||
/datum/gear/toeless_jackboots
|
||||
display_name = "toe-less jackboots"
|
||||
path = /obj/item/clothing/shoes/jackboots/fluff/kecer_eldraran //permisson of owner of custom item was granted
|
||||
cost = 2
|
||||
slot = slot_shoes
|
||||
|
||||
/datum/gear/sandal
|
||||
display_name = "sandals"
|
||||
path = /obj/item/clothing/shoes/sandal
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
//var/invisa_view = 0
|
||||
var/prescription = 0
|
||||
var/toggleable = 0
|
||||
var/off_state = "degoggles"
|
||||
var/active = 1
|
||||
var/activation_sound = 'sound/items/goggles_charge.ogg'
|
||||
var/obj/screen/overlay = null
|
||||
body_parts_covered = EYES
|
||||
|
||||
@@ -18,13 +20,15 @@
|
||||
if(toggleable)
|
||||
if(active)
|
||||
active = 0
|
||||
icon_state = "degoggles"
|
||||
icon_state = off_state
|
||||
user.update_inv_glasses()
|
||||
usr << "You deactivate the optical matrix on the [src]."
|
||||
else
|
||||
active = 1
|
||||
icon_state = initial(icon_state)
|
||||
user.update_inv_glasses()
|
||||
if(activation_sound)
|
||||
usr << activation_sound
|
||||
usr << "You activate the optical matrix on the [src]."
|
||||
|
||||
/obj/item/clothing/glasses/meson
|
||||
@@ -51,6 +55,8 @@
|
||||
desc = "The goggles do nothing!"
|
||||
icon_state = "purple"
|
||||
item_state = "glasses"
|
||||
toggleable = 1
|
||||
icon_action_button = "action_science"
|
||||
|
||||
/obj/item/clothing/glasses/science/New()
|
||||
..()
|
||||
@@ -63,6 +69,9 @@
|
||||
item_state = "glasses"
|
||||
origin_tech = "magnets=2"
|
||||
darkness_view = 7
|
||||
toggleable = 1
|
||||
icon_action_button = "action_nvg"
|
||||
off_state = "denight"
|
||||
|
||||
/obj/item/clothing/glasses/night/New()
|
||||
..()
|
||||
@@ -208,6 +217,7 @@
|
||||
item_state = "glasses"
|
||||
origin_tech = "magnets=3"
|
||||
toggleable = 1
|
||||
icon_action_button = "action_thermal"
|
||||
vision_flags = SEE_MOBS
|
||||
invisa_view = 2
|
||||
|
||||
@@ -218,9 +228,11 @@
|
||||
if(M.glasses == src)
|
||||
M.eye_blind = 3
|
||||
M.eye_blurry = 5
|
||||
M.disabilities |= NEARSIGHTED
|
||||
spawn(100)
|
||||
M.disabilities &= ~NEARSIGHTED
|
||||
// Don't cure being nearsighted
|
||||
if(!(M.disabilities & NEARSIGHTED))
|
||||
M.disabilities |= NEARSIGHTED
|
||||
spawn(100)
|
||||
M.disabilities &= ~NEARSIGHTED
|
||||
..()
|
||||
|
||||
/obj/item/clothing/glasses/thermal/New()
|
||||
@@ -231,28 +243,30 @@
|
||||
name = "Optical Meson Scanner"
|
||||
desc = "Used for seeing walls, floors, and stuff through anything."
|
||||
icon_state = "meson"
|
||||
icon_action_button = "action_meson"
|
||||
origin_tech = "magnets=3;syndicate=4"
|
||||
|
||||
/obj/item/clothing/glasses/thermal/monocle
|
||||
/obj/item/clothing/glasses/thermal/plain
|
||||
toggleable = 0
|
||||
activation_sound = null
|
||||
icon_action_button = ""
|
||||
|
||||
/obj/item/clothing/glasses/thermal/plain/monocle
|
||||
name = "Thermoncle"
|
||||
desc = "A monocle thermal."
|
||||
icon_state = "thermoncle"
|
||||
flags = null //doesn't protect eyes because it's a monocle, duh
|
||||
toggleable = 0
|
||||
|
||||
body_parts_covered = 0
|
||||
|
||||
/obj/item/clothing/glasses/thermal/eyepatch
|
||||
/obj/item/clothing/glasses/thermal/plain/eyepatch
|
||||
name = "Optical Thermal Eyepatch"
|
||||
desc = "An eyepatch with built-in thermal optics"
|
||||
icon_state = "eyepatch"
|
||||
item_state = "eyepatch"
|
||||
toggleable = 0
|
||||
body_parts_covered = 0
|
||||
|
||||
/obj/item/clothing/glasses/thermal/jensen
|
||||
/obj/item/clothing/glasses/thermal/plain/jensen
|
||||
name = "Optical Thermal Implants"
|
||||
desc = "A set of implantable lenses designed to augment your vision"
|
||||
icon_state = "thermalimplants"
|
||||
item_state = "syringe_kit"
|
||||
toggleable = 0
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
species_restricted = null
|
||||
body_parts_covered = 0
|
||||
|
||||
wizard_garb = 1
|
||||
|
||||
/obj/item/clothing/shoes/sandal/marisa
|
||||
desc = "A pair of magic, black shoes."
|
||||
name = "magic shoes"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
name = "mounted grenade launcher"
|
||||
desc = "A shoulder-mounted micro-explosive dispenser."
|
||||
selectable = 1
|
||||
icon_state = "grenade_launcher"
|
||||
|
||||
interface_name = "integrated grenade launcher"
|
||||
interface_desc = "Discharges loaded grenades against the wearer's location."
|
||||
@@ -86,6 +87,7 @@
|
||||
selectable = 1
|
||||
usable = 1
|
||||
module_cooldown = 0
|
||||
icon_state = "lcannon"
|
||||
|
||||
engage_string = "Configure"
|
||||
|
||||
@@ -115,6 +117,7 @@
|
||||
|
||||
name = "mounted energy gun"
|
||||
desc = "A forearm-mounted energy projector."
|
||||
icon_state = "egun"
|
||||
|
||||
interface_name = "mounted energy gun"
|
||||
interface_desc = "A forearm-mounted suit-powered energy gun."
|
||||
@@ -124,7 +127,8 @@
|
||||
/obj/item/rig_module/mounted/taser
|
||||
|
||||
name = "mounted taser"
|
||||
desc = "A shoulder-mounted energy projector."
|
||||
desc = "A palm-mounted nonlethal energy projector."
|
||||
icon_state = "taser"
|
||||
|
||||
usable = 0
|
||||
|
||||
@@ -140,6 +144,7 @@
|
||||
|
||||
name = "energy blade projector"
|
||||
desc = "A powerful cutting beam projector."
|
||||
icon_state = "eblade"
|
||||
|
||||
activate_string = "Project Blade"
|
||||
deactivate_string = "Cancel Blade"
|
||||
@@ -200,6 +205,7 @@
|
||||
selectable = 1
|
||||
usable = 1
|
||||
use_power_cost = 15
|
||||
icon_state = "enet"
|
||||
|
||||
engage_string = "Fabricate Star"
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
name = "IIS module"
|
||||
desc = "An integrated intelligence system module suitable for most hardsuits."
|
||||
icon_state = "IIS"
|
||||
toggleable = 1
|
||||
usable = 1
|
||||
disruptive = 0
|
||||
@@ -104,7 +105,14 @@
|
||||
|
||||
// Okay, it wasn't a terminal being touched, check for all the simple insertions.
|
||||
if(input_device.type in list(/obj/item/device/paicard, /obj/item/device/mmi, /obj/item/device/mmi/digital/posibrain))
|
||||
integrate_ai(input_device,user)
|
||||
if(integrated_ai)
|
||||
integrated_ai.attackby(input_device,user)
|
||||
// If the transfer was successful, we can clear out our vars.
|
||||
if(integrated_ai.loc != src)
|
||||
integrated_ai = null
|
||||
eject_ai()
|
||||
else
|
||||
integrate_ai(input_device,user)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
@@ -202,6 +210,7 @@
|
||||
|
||||
name = "datajack module"
|
||||
desc = "A simple induction datalink module."
|
||||
icon_state = "datajack"
|
||||
toggleable = 1
|
||||
activates_on_touch = 1
|
||||
usable = 0
|
||||
@@ -292,6 +301,7 @@
|
||||
|
||||
name = "electrowarfare module"
|
||||
desc = "A bewilderingly complex bundle of fiber optics and chips."
|
||||
icon_state = "ewar"
|
||||
toggleable = 1
|
||||
usable = 0
|
||||
|
||||
@@ -322,6 +332,7 @@
|
||||
|
||||
name = "hardsuit power sink"
|
||||
desc = "An heavy-duty power sink."
|
||||
icon_state = "powersink"
|
||||
toggleable = 1
|
||||
activates_on_touch = 1
|
||||
disruptive = 0
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
|
||||
name = "teleportation module"
|
||||
desc = "A complex, sleek-looking, hardsuit-integrated teleportation module."
|
||||
icon_state = "teleporter"
|
||||
use_power_cost = 40
|
||||
redundant = 1
|
||||
usable = 1
|
||||
@@ -126,6 +127,7 @@
|
||||
|
||||
name = "net projector"
|
||||
desc = "Some kind of complex energy projector with a hardsuit mount."
|
||||
icon_state = "enet"
|
||||
|
||||
interface_name = "energy net launcher"
|
||||
interface_desc = "An advanced energy-patterning projector used to capture targets."
|
||||
@@ -147,6 +149,7 @@
|
||||
|
||||
name = "self-destruct module"
|
||||
desc = "Oh my God, Captain. A bomb."
|
||||
icon_state = "deadman"
|
||||
usable = 1
|
||||
active = 1
|
||||
permanent = 1
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
/obj/item/rig_module/device/plasmacutter
|
||||
name = "hardsuit plasma cutter"
|
||||
desc = "A lethal-looking industrial cutter."
|
||||
icon_state = "plasmacutter"
|
||||
interface_name = "plasma cutter"
|
||||
interface_desc = "A self-sustaining plasma arc capable of cutting through walls."
|
||||
suit_overlay_active = "plasmacutter"
|
||||
@@ -38,6 +39,7 @@
|
||||
/obj/item/rig_module/device/healthscanner
|
||||
name = "health scanner module"
|
||||
desc = "A hardsuit-mounted health scanner."
|
||||
icon_state = "scanner"
|
||||
interface_name = "health scanner"
|
||||
interface_desc = "Shows an informative health readout when used on a subject."
|
||||
|
||||
@@ -46,6 +48,7 @@
|
||||
/obj/item/rig_module/device/drill
|
||||
name = "hardsuit drill mount"
|
||||
desc = "A very heavy diamond-tipped drill."
|
||||
icon_state = "drill"
|
||||
interface_name = "mounted drill"
|
||||
interface_desc = "A diamond-tipped industrial drill."
|
||||
suit_overlay_active = "mounted-drill"
|
||||
@@ -56,6 +59,7 @@
|
||||
/obj/item/rig_module/device/anomaly_scanner
|
||||
name = "hardsuit anomaly scanner"
|
||||
desc = "You think it's called an Elder Sarsparilla or something."
|
||||
icon_state = "eldersasparilla"
|
||||
interface_name = "Alden-Saraspova counter"
|
||||
interface_desc = "An exotic particle detector commonly used by xenoarchaeologists."
|
||||
engage_string = "Begin Scan"
|
||||
@@ -66,6 +70,7 @@
|
||||
/obj/item/rig_module/device/orescanner
|
||||
name = "ore scanner module"
|
||||
desc = "A clunky old ore scanner."
|
||||
icon_state = "scanner"
|
||||
interface_name = "ore detector"
|
||||
interface_desc = "A sonar system for detecting large masses of ore."
|
||||
engage_string = "Begin Scan"
|
||||
@@ -76,6 +81,7 @@
|
||||
/obj/item/rig_module/device/rcd
|
||||
name = "RCD mount"
|
||||
desc = "A cell-powered rapid construction device for a hardsuit."
|
||||
icon_state = "rcd"
|
||||
interface_name = "mounted RCD"
|
||||
interface_desc = "A device for building or removing walls. Cell-powered."
|
||||
usable = 1
|
||||
@@ -105,9 +111,12 @@
|
||||
device.afterattack(target,holder.wearer,1)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/obj/item/rig_module/chem_dispenser
|
||||
name = "mounted chemical dispenser"
|
||||
desc = "A complex web of tubing and needles suitable for hardsuit use."
|
||||
icon_state = "injector"
|
||||
usable = 1
|
||||
selectable = 0
|
||||
toggleable = 0
|
||||
@@ -223,6 +232,19 @@
|
||||
|
||||
/obj/item/rig_module/chem_dispenser/combat
|
||||
|
||||
name = "combat chemical injector"
|
||||
desc = "A complex web of tubing and needles suitable for hardsuit use."
|
||||
|
||||
charges = list(
|
||||
list("synaptizine", "synaptizine", 0, 30),
|
||||
list("hyperzine", "hyperzine", 0, 30),
|
||||
list("oxycodone", "oxycodone", 0, 30),
|
||||
list("nutrients", "nutriment", 0, 80),
|
||||
)
|
||||
|
||||
interface_name = "combat chem dispenser"
|
||||
interface_desc = "Dispenses loaded chemicals directly into the bloodstream."
|
||||
|
||||
|
||||
/obj/item/rig_module/chem_dispenser/injector
|
||||
|
||||
@@ -239,6 +261,7 @@
|
||||
|
||||
name = "hardsuit voice synthesiser"
|
||||
desc = "A speaker box and sound processor."
|
||||
icon_state = "megaphone"
|
||||
usable = 1
|
||||
selectable = 0
|
||||
toggleable = 0
|
||||
@@ -280,7 +303,7 @@
|
||||
voice_holder.active = 0
|
||||
usr << "<font color='blue'>You disable the speech synthesiser.</font>"
|
||||
if("Set Name")
|
||||
var/raw_choice = sanitize(input(usr, "Please enter a new name.") as text|null)
|
||||
var/raw_choice = sanitize(input(usr, "Please enter a new name.") as text|null, MAX_NAME_LEN)
|
||||
if(!raw_choice)
|
||||
return 0
|
||||
voice_holder.voice = raw_choice
|
||||
@@ -291,6 +314,7 @@
|
||||
|
||||
name = "hardsuit maneuvering jets"
|
||||
desc = "A compact gas thruster system for a hardsuit."
|
||||
icon_state = "thrusters"
|
||||
usable = 1
|
||||
toggleable = 1
|
||||
selectable = 0
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
/*
|
||||
* Contains
|
||||
* /obj/item/rig_module/vision
|
||||
* /obj/item/rig_module/vision/multi
|
||||
* /obj/item/rig_module/vision/meson
|
||||
* /obj/item/rig_module/vision/thermal
|
||||
* /obj/item/rig_module/vision/nvg
|
||||
* /obj/item/rig_module/vision/medhud
|
||||
* /obj/item/rig_module/vision/sechud
|
||||
*/
|
||||
|
||||
/datum/rig_vision
|
||||
@@ -24,10 +28,21 @@
|
||||
/datum/rig_vision/meson/New()
|
||||
glasses = new /obj/item/clothing/glasses/meson
|
||||
|
||||
/datum/rig_vision/sechud
|
||||
mode = "security HUD"
|
||||
/datum/rig_vision/sechud/New()
|
||||
glasses = new /obj/item/clothing/glasses/hud/security
|
||||
|
||||
/datum/rig_vision/medhud
|
||||
mode = "medical HUD"
|
||||
/datum/rig_vision/medhud/New()
|
||||
glasses = new /obj/item/clothing/glasses/hud/health
|
||||
|
||||
/obj/item/rig_module/vision
|
||||
|
||||
name = "hardsuit visor"
|
||||
desc = "A layered, translucent visor system for a hardsuit."
|
||||
icon_state = "optics"
|
||||
|
||||
interface_name = "optical scanners"
|
||||
interface_desc = "An integrated multi-mode vision system."
|
||||
@@ -49,10 +64,27 @@
|
||||
|
||||
var/vision_index
|
||||
|
||||
/obj/item/rig_module/vision/multi
|
||||
|
||||
name = "hardsuit optical package"
|
||||
desc = "A complete visor system of optical scanners and vision modes."
|
||||
icon_state = "fulloptics"
|
||||
|
||||
|
||||
interface_name = "multi optical visor"
|
||||
interface_desc = "An integrated multi-mode vision system."
|
||||
|
||||
vision_modes = list(/datum/rig_vision/meson,
|
||||
/datum/rig_vision/nvg,
|
||||
/datum/rig_vision/thermal,
|
||||
/datum/rig_vision/sechud,
|
||||
/datum/rig_vision/medhud)
|
||||
|
||||
/obj/item/rig_module/vision/meson
|
||||
|
||||
name = "hardsuit meson scanner"
|
||||
desc = "A layered, translucent visor system for a hardsuit."
|
||||
icon_state = "meson"
|
||||
|
||||
usable = 0
|
||||
|
||||
@@ -65,6 +97,7 @@
|
||||
|
||||
name = "hardsuit thermal scanner"
|
||||
desc = "A layered, translucent visor system for a hardsuit."
|
||||
icon_state = "thermal"
|
||||
|
||||
usable = 0
|
||||
|
||||
@@ -73,6 +106,46 @@
|
||||
|
||||
vision_modes = list(/datum/rig_vision/thermal)
|
||||
|
||||
/obj/item/rig_module/vision/nvg
|
||||
|
||||
name = "hardsuit night vision interface"
|
||||
desc = "A multi input night vision system for a hardsuit."
|
||||
icon_state = "night"
|
||||
|
||||
usable = 0
|
||||
|
||||
interface_name = "night vision interface"
|
||||
interface_desc = "An integrated night vision system."
|
||||
|
||||
vision_modes = list(/datum/rig_vision/nvg)
|
||||
|
||||
/obj/item/rig_module/vision/sechud
|
||||
|
||||
name = "hardsuit security hud"
|
||||
desc = "A simple tactical information system for a hardsuit."
|
||||
icon_state = "securityhud"
|
||||
|
||||
usable = 0
|
||||
|
||||
interface_name = "security HUD"
|
||||
interface_desc = "An integrated security heads up display."
|
||||
|
||||
vision_modes = list(/datum/rig_vision/sechud)
|
||||
|
||||
/obj/item/rig_module/vision/medhud
|
||||
|
||||
name = "hardsuit medical hud"
|
||||
desc = "A simple medical status indicator for a hardsuit."
|
||||
icon_state = "healthhud"
|
||||
|
||||
usable = 0
|
||||
|
||||
interface_name = "medical HUD"
|
||||
interface_desc = "An integrated medical heads up display."
|
||||
|
||||
vision_modes = list(/datum/rig_vision/medhud)
|
||||
|
||||
|
||||
// There should only ever be one vision module installed in a suit.
|
||||
/obj/item/rig_module/vision/installed()
|
||||
..()
|
||||
|
||||
@@ -459,7 +459,7 @@
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, ((src.loc != user) ? ai_interface_path : interface_path), interface_title, 480, 550)
|
||||
ui = new(user, src, ui_key, ((src.loc != user) ? ai_interface_path : interface_path), interface_title, 480, 550, data["ai"] ? contained_state : inventory_state)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
@@ -631,8 +631,9 @@
|
||||
use_obj.loc = src
|
||||
|
||||
else if (deploy_mode != ONLY_RETRACT)
|
||||
if(check_slot && check_slot != use_obj)
|
||||
H << "<span class='danger'>You are unable to deploy \the [piece] as \the [check_slot] [check_slot.gender == PLURAL ? "are" : "is"] in the way.</span>"
|
||||
if(check_slot)
|
||||
if(check_slot != use_obj)
|
||||
H << "<span class='danger'>You are unable to deploy \the [piece] as \the [check_slot] [check_slot.gender == PLURAL ? "are" : "is"] in the way.</span>"
|
||||
return
|
||||
else
|
||||
use_obj.loc = H
|
||||
|
||||
@@ -8,11 +8,16 @@
|
||||
suit_type = "combat hardsuit"
|
||||
armor = list(melee = 80, bullet = 65, laser = 50, energy = 15, bomb = 80, bio = 100, rad = 60)
|
||||
slowdown = 1
|
||||
offline_slowdown = 3
|
||||
offline_vision_restriction = 1
|
||||
|
||||
helm_type = /obj/item/clothing/head/helmet/space/rig/combat
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton)
|
||||
|
||||
|
||||
/obj/item/weapon/rig/combat/equipped
|
||||
|
||||
|
||||
initial_modules = list(
|
||||
/obj/item/rig_module/mounted,
|
||||
/obj/item/rig_module/vision/thermal,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/item/clothing/head/helmet/space/rig/ert
|
||||
light_overlay = "helmet_light_dual"
|
||||
camera_networks = list("ERT","SS13")
|
||||
camera_networks = list("ERT")
|
||||
|
||||
/obj/item/weapon/rig/ert
|
||||
name = "ERT-C hardsuit control module"
|
||||
@@ -12,11 +12,11 @@
|
||||
|
||||
req_access = list(access_cent_specops)
|
||||
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 60)
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 100)
|
||||
allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/crowbar, \
|
||||
/obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, /obj/item/device/multitool, \
|
||||
/obj/item/device/radio, /obj/item/device/analyzer, /obj/item/weapon/gun/energy/laser, /obj/item/weapon/gun/energy/pulse_rifle, \
|
||||
/obj/item/weapon/gun/energy/taser, /obj/item/weapon/melee/baton, /obj/item/weapon/gun, /obj/item/weapon/storage/firstaid, /obj/item/weapon/reagent_containers/hypospray, /obj/item/roller)
|
||||
/obj/item/device/radio, /obj/item/device/analyzer,/obj/item/weapon/storage/briefcase/inflatable, /obj/item/weapon/melee/baton, /obj/item/weapon/gun, \
|
||||
/obj/item/weapon/storage/firstaid, /obj/item/weapon/reagent_containers/hypospray, /obj/item/roller)
|
||||
|
||||
initial_modules = list(
|
||||
/obj/item/rig_module/ai_container,
|
||||
@@ -29,7 +29,6 @@
|
||||
desc = "A suit worn by the engineering division of a NanoTrasen Emergency Response Team. Has orange highlights. Armoured and space ready."
|
||||
suit_type = "ERT engineer"
|
||||
icon_state = "ert_engineer_rig"
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 100)
|
||||
|
||||
glove_type = /obj/item/clothing/gloves/rig/ert_engineer
|
||||
|
||||
@@ -68,4 +67,23 @@
|
||||
/obj/item/rig_module/maneuvering_jets,
|
||||
/obj/item/rig_module/grenade_launcher,
|
||||
/obj/item/rig_module/mounted/egun,
|
||||
)
|
||||
|
||||
/obj/item/weapon/rig/ert/assetprotection
|
||||
name = "Heavy Asset Protection suit control module"
|
||||
desc = "A heavy suit worn by the highest level of Nanotrasen Asset Protection, don't mess with the person wearing this. Armoured and space ready."
|
||||
suit_type = "heavy asset protection"
|
||||
icon_state = "asset_protection_rig"
|
||||
armor = list(melee = 60, bullet = 50, laser = 50,energy = 40, bomb = 40, bio = 100, rad = 100)
|
||||
|
||||
initial_modules = list(
|
||||
/obj/item/rig_module/ai_container,
|
||||
/obj/item/rig_module/maneuvering_jets,
|
||||
/obj/item/rig_module/grenade_launcher,
|
||||
/obj/item/rig_module/vision/multi,
|
||||
/obj/item/rig_module/mounted/egun,
|
||||
/obj/item/rig_module/chem_dispenser/injector,
|
||||
/obj/item/rig_module/device/plasmacutter,
|
||||
/obj/item/rig_module/device/rcd,
|
||||
/obj/item/rig_module/datajack
|
||||
)
|
||||
@@ -9,6 +9,7 @@
|
||||
suit_type = "crimson hardsuit"
|
||||
armor = list(melee = 80, bullet = 65, laser = 50, energy = 15, bomb = 80, bio = 100, rad = 60)
|
||||
slowdown = 1
|
||||
offline_slowdown = 3
|
||||
offline_vision_restriction = 1
|
||||
|
||||
helm_type = /obj/item/clothing/head/helmet/space/rig/merc
|
||||
|
||||
@@ -1,19 +1,45 @@
|
||||
/obj/item/clothing/head/helmet/space/rig/industrial
|
||||
camera_networks = list("Mine")
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/ce
|
||||
camera_networks = list("Engineering")
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/eva
|
||||
light_overlay = "helmet_light_dual"
|
||||
camera_networks = list("Engineering")
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/hazmat
|
||||
light_overlay = "hardhat_light"
|
||||
camera_networks = list("Research")
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/medical
|
||||
camera_networks = list("Medbay")
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/hazard
|
||||
light_overlay = "helmet_light_dual"
|
||||
camera_networks = list("Security")
|
||||
|
||||
/obj/item/weapon/rig/industrial
|
||||
name = "industrial suit control module"
|
||||
suit_type = "industrial hardsuit"
|
||||
desc = "A heavy, powerful rig used by construction crews and mining corporations."
|
||||
icon_state = "engineering_rig"
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 50)
|
||||
slowdown = 3
|
||||
offline_slowdown = 10
|
||||
offline_vision_restriction = 2
|
||||
emp_protection = -20
|
||||
|
||||
helm_type = /obj/item/clothing/head/helmet/space/rig/industrial
|
||||
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
|
||||
|
||||
req_access = list()
|
||||
req_one_access = list()
|
||||
|
||||
|
||||
/obj/item/weapon/rig/industrial/equipped
|
||||
|
||||
initial_modules = list(
|
||||
/obj/item/rig_module/device/plasmacutter,
|
||||
/obj/item/rig_module/device/drill,
|
||||
@@ -22,6 +48,32 @@
|
||||
/obj/item/rig_module/vision/meson
|
||||
)
|
||||
|
||||
/obj/item/weapon/rig/eva
|
||||
name = "EVA suit control module"
|
||||
suit_type = "EVA hardsuit"
|
||||
desc = "A light rig for repairs and maintenance to the outside of habitats and vessels."
|
||||
icon_state = "eva_rig"
|
||||
armor = list(melee = 30, bullet = 10, laser = 20,energy = 25, bomb = 20, bio = 100, rad = 100)
|
||||
slowdown = 0
|
||||
offline_slowdown = 1
|
||||
offline_vision_restriction = 1
|
||||
|
||||
helm_type = /obj/item/clothing/head/helmet/space/rig/eva
|
||||
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/toolbox,/obj/item/weapon/storage/briefcase/inflatable,/obj/item/device/t_scanner,/obj/item/weapon/rcd)
|
||||
|
||||
req_access = list()
|
||||
req_one_access = list()
|
||||
|
||||
/obj/item/weapon/rig/eva/equipped
|
||||
|
||||
initial_modules = list(
|
||||
/obj/item/rig_module/device/plasmacutter,
|
||||
/obj/item/rig_module/maneuvering_jets,
|
||||
/obj/item/rig_module/device/rcd,
|
||||
/obj/item/rig_module/vision/meson
|
||||
)
|
||||
|
||||
//Chief Engineer's rig. This is sort of a halfway point between the old hardsuits (voidsuits) and the rig class.
|
||||
/obj/item/weapon/rig/ce
|
||||
|
||||
@@ -29,13 +81,24 @@
|
||||
suit_type = "advanced voidsuit"
|
||||
desc = "An advanced voidsuit that protects against hazardous, low pressure environments. Shines with a high polish."
|
||||
icon_state = "ce_rig"
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
armor = list(melee = 40, bullet = 10, laser = 30,energy = 25, bomb = 40, bio = 100, rad = 100)
|
||||
slowdown = 0
|
||||
offline_slowdown = 0
|
||||
offline_vision_restriction = 0
|
||||
|
||||
helm_type = /obj/item/clothing/head/helmet/space/rig/ce
|
||||
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
|
||||
|
||||
|
||||
req_access = list()
|
||||
req_one_access = list()
|
||||
|
||||
boot_type = null
|
||||
glove_type = null
|
||||
|
||||
/obj/item/weapon/rig/ce/equipped
|
||||
|
||||
req_access = list(access_ce)
|
||||
|
||||
initial_modules = list(
|
||||
@@ -55,14 +118,21 @@
|
||||
suit_type = "hazmat hardsuit"
|
||||
desc = "An Anomalous Material Interaction hardsuit that protects against the strangest energies the universe can throw at it."
|
||||
icon_state = "science_rig"
|
||||
armor = list(melee = 15, bullet = 15, laser = 80, energy = 80, bomb = 60, bio = 100, rad = 100)
|
||||
armor = list(melee = 45, bullet = 5, laser = 45, energy = 80, bomb = 60, bio = 100, rad = 100)
|
||||
slowdown = 1
|
||||
offline_vision_restriction = 1
|
||||
|
||||
helm_type = /obj/item/clothing/head/helmet/space/rig/hazmat
|
||||
|
||||
helm_type = /obj/item/clothing/head/helmet/space/rig/ert
|
||||
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/stack/flag,/obj/item/weapon/storage/box/excavation,/obj/item/weapon/pickaxe,/obj/item/device/healthanalyzer,/obj/item/device/measuring_tape,/obj/item/device/ano_scanner,/obj/item/device/depth_scanner,/obj/item/device/core_sampler,/obj/item/device/gps,/obj/item/device/beacon_locator,/obj/item/device/radio/beacon,/obj/item/weapon/pickaxe/hand,/obj/item/weapon/storage/bag/fossils)
|
||||
|
||||
req_access = list()
|
||||
req_one_access = list()
|
||||
|
||||
/obj/item/weapon/rig/hazmat/equipped
|
||||
|
||||
req_access = list(access_rd)
|
||||
|
||||
initial_modules = list(
|
||||
@@ -81,30 +151,45 @@
|
||||
slowdown = 1
|
||||
offline_vision_restriction = 1
|
||||
|
||||
helm_type = /obj/item/clothing/head/helmet/space/rig/medical
|
||||
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical,/obj/item/roller )
|
||||
|
||||
req_access = list()
|
||||
req_one_access = list()
|
||||
|
||||
/obj/item/weapon/rig/medical/equipped
|
||||
|
||||
initial_modules = list(
|
||||
/obj/item/rig_module/chem_dispenser/injector,
|
||||
/obj/item/rig_module/maneuvering_jets,
|
||||
/obj/item/rig_module/device/healthscanner
|
||||
/obj/item/rig_module/device/healthscanner,
|
||||
/obj/item/rig_module/vision/medhud
|
||||
)
|
||||
|
||||
/obj/item/weapon/rig/hazard
|
||||
name = "hazard hardsuit control module"
|
||||
suit_type = "hazard hardsuit"
|
||||
desc = "A Nanotrasen security hardsuit designed for prolonged EVA in dangerous environments. The name HARPER is printed on the control unit."
|
||||
desc = "A Nanotrasen security hardsuit designed for prolonged EVA in dangerous environments."
|
||||
icon_state = "hazard_rig"
|
||||
armor = list(melee = 60, bullet = 10, laser = 30, energy = 5, bomb = 45, bio = 100, rad = 10)
|
||||
armor = list(melee = 60, bullet = 40, laser = 30, energy = 15, bomb = 60, bio = 100, rad = 30)
|
||||
slowdown = 1
|
||||
offline_slowdown = 3
|
||||
offline_vision_restriction = 1
|
||||
|
||||
helm_type = /obj/item/clothing/head/helmet/space/rig/ert
|
||||
helm_type = /obj/item/clothing/head/helmet/space/rig/hazard
|
||||
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton)
|
||||
|
||||
req_access = list()
|
||||
req_one_access = list()
|
||||
|
||||
|
||||
/obj/item/weapon/rig/hazard/equipped
|
||||
|
||||
initial_modules = list(
|
||||
/obj/item/rig_module/vision/sechud,
|
||||
/obj/item/rig_module/maneuvering_jets,
|
||||
/obj/item/rig_module/grenade_launcher,
|
||||
/obj/item/rig_module/mounted/taser
|
||||
)
|
||||
@@ -55,6 +55,7 @@
|
||||
//Inbuilt devices.
|
||||
var/obj/item/clothing/shoes/magboots/boots = null // Deployable boots, if any.
|
||||
var/obj/item/clothing/head/helmet/helmet = null // Deployable helmet, if any.
|
||||
var/obj/item/weapon/tank/tank = null // Deployable tank, if any.
|
||||
|
||||
/obj/item/clothing/suit/space/void/refit_for_species(var/target_species)
|
||||
..()
|
||||
@@ -87,6 +88,13 @@
|
||||
M << "Your suit's boots deploy with a hiss."
|
||||
boots.canremove = 0
|
||||
|
||||
if(tank)
|
||||
if(H.s_store) //In case someone finds a way.
|
||||
M << "Alarmingly, the valve on your suit's installed tank fails to engage."
|
||||
else if (H.equip_to_slot_if_possible(tank, slot_s_store))
|
||||
M << "The valve on your suit's installed tank safely engages."
|
||||
tank.canremove = 0
|
||||
|
||||
/obj/item/clothing/suit/space/void/dropped()
|
||||
..()
|
||||
|
||||
@@ -107,6 +115,10 @@
|
||||
boots.canremove = 1
|
||||
H.drop_from_inventory(boots)
|
||||
boots.loc = src
|
||||
|
||||
if(tank)
|
||||
tank.canremove = 1
|
||||
tank.loc = src
|
||||
|
||||
/obj/item/clothing/suit/space/void/verb/toggle_helmet()
|
||||
|
||||
@@ -127,7 +139,7 @@
|
||||
if(H.wear_suit != src) return
|
||||
|
||||
if(H.head == helmet)
|
||||
H << "\blue You retract your suit helmet."
|
||||
H << "<span class='notice'>You retract your suit helmet.</span>"
|
||||
helmet.canremove = 1
|
||||
H.drop_from_inventory(helmet)
|
||||
helmet.loc = src
|
||||
@@ -138,9 +150,32 @@
|
||||
if(H.equip_to_slot_if_possible(helmet, slot_head))
|
||||
helmet.pickup(H)
|
||||
helmet.canremove = 0
|
||||
H << "<font color='blue'><b>You deploy your suit helmet, sealing you off from the world.</b></font>"
|
||||
H << "<span class='info'>You deploy your suit helmet, sealing you off from the world.</span>"
|
||||
helmet.update_light(H)
|
||||
|
||||
/obj/item/clothing/suit/space/void/verb/eject_tank()
|
||||
|
||||
set name = "Eject Tank"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
|
||||
if(!istype(src.loc,/mob/living)) return
|
||||
|
||||
if(!tank)
|
||||
usr << "There is no tank inserted."
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = usr
|
||||
|
||||
if(!istype(H)) return
|
||||
if(H.stat) return
|
||||
if(H.wear_suit != src) return
|
||||
|
||||
H << "<span class='info'>You press the emergency release, ejecting \the [tank] from your suit.</span>"
|
||||
tank.canremove = 1
|
||||
H.drop_from_inventory(tank)
|
||||
src.tank = null
|
||||
|
||||
/obj/item/clothing/suit/space/void/attackby(obj/item/W as obj, mob/user as mob)
|
||||
|
||||
if(!istype(user,/mob/living)) return
|
||||
@@ -150,7 +185,11 @@
|
||||
return
|
||||
|
||||
if(istype(W,/obj/item/weapon/screwdriver))
|
||||
if(helmet)
|
||||
if(tank)
|
||||
user << "You pop \the [tank] out of \the [src]'s storage compartment."
|
||||
tank.loc = get_turf(src)
|
||||
src.tank = null
|
||||
else if(helmet)
|
||||
user << "You detatch \the [helmet] from \the [src]'s helmet mount."
|
||||
helmet.loc = get_turf(src)
|
||||
src.helmet = null
|
||||
@@ -179,5 +218,16 @@
|
||||
W.loc = src
|
||||
boots = W
|
||||
return
|
||||
else if(istype(W,/obj/item/weapon/tank))
|
||||
if(tank)
|
||||
user << "\The [src] already has an airtank installed."
|
||||
else if(istype(W,/obj/item/weapon/tank/phoron))
|
||||
user << "\The [W] cannot be inserted into \the [src]'s storage compartment."
|
||||
else
|
||||
user << "You insert \the [W] into \the [src]'s storage compartment."
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
tank = W
|
||||
return
|
||||
|
||||
..()
|
||||
@@ -10,6 +10,7 @@
|
||||
siemens_coefficient = 0.7
|
||||
sprite_sheets_refit = null
|
||||
sprite_sheets_obj = null
|
||||
wizard_garb = 1
|
||||
|
||||
/obj/item/clothing/suit/space/void/wizard
|
||||
icon_state = "rig-wiz"
|
||||
@@ -22,4 +23,5 @@
|
||||
armor = list(melee = 40, bullet = 20, laser = 20,energy = 20, bomb = 35, bio = 100, rad = 60)
|
||||
siemens_coefficient = 0.7
|
||||
sprite_sheets_refit = null
|
||||
sprite_sheets_obj = null
|
||||
sprite_sheets_obj = null
|
||||
wizard_garb = 1
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
//Not given any special protective value since the magic robes are full-body protection --NEO
|
||||
siemens_coefficient = 0.8
|
||||
body_parts_covered = 0
|
||||
wizard_garb = 1
|
||||
|
||||
/obj/item/clothing/head/wizard/red
|
||||
name = "red wizard hat"
|
||||
@@ -55,6 +56,7 @@
|
||||
allowed = list(/obj/item/weapon/teleportation_scroll)
|
||||
flags_inv = HIDEJUMPSUIT
|
||||
siemens_coefficient = 0.8
|
||||
wizard_garb = 1
|
||||
|
||||
/obj/item/clothing/suit/wizrobe/red
|
||||
name = "red wizard robe"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/item/device/eftpos
|
||||
name = "EFTPOS scanner"
|
||||
name = "\improper EFTPOS scanner"
|
||||
desc = "Swipe your ID card to make purchases electronically."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "eftpos"
|
||||
@@ -110,11 +110,13 @@
|
||||
else
|
||||
user << browse(null,"window=eftpos")
|
||||
|
||||
/obj/item/device/eftpos/attackby(O as obj, user as mob)
|
||||
if(istype(O, /obj/item/weapon/card))
|
||||
/obj/item/device/eftpos/attackby(obj/item/O as obj, user as mob)
|
||||
|
||||
var/obj/item/weapon/card/id/I = O.GetID()
|
||||
|
||||
if(I)
|
||||
if(linked_account)
|
||||
var/obj/item/weapon/card/I = O
|
||||
scan_card(I)
|
||||
scan_card(I, O)
|
||||
else
|
||||
usr << "\icon[src]<span class='warning'>Unable to connect to linked account.</span>"
|
||||
else if (istype(O, /obj/item/weapon/spacecash/ewallet))
|
||||
@@ -124,7 +126,7 @@
|
||||
if(transaction_locked && !transaction_paid)
|
||||
if(transaction_amount <= E.worth)
|
||||
playsound(src, 'sound/machines/chime.ogg', 50, 1)
|
||||
src.visible_message("\icon[src] The [src] chimes.")
|
||||
src.visible_message("\icon[src] \The [src] chimes.")
|
||||
transaction_paid = 1
|
||||
|
||||
//transfer the money
|
||||
@@ -141,7 +143,7 @@
|
||||
T.time = worldtime2text()
|
||||
linked_account.transaction_log.Add(T)
|
||||
else
|
||||
usr << "\icon[src]<span class='warning'>The charge card doesn't have that much money!</span>"
|
||||
usr << "\icon[src]<span class='warning'>\The [O] doesn't have that much money!</span>"
|
||||
else
|
||||
usr << "\icon[src]<span class='warning'>Connected account has been suspended.</span>"
|
||||
else
|
||||
@@ -167,7 +169,7 @@
|
||||
if("change_id")
|
||||
var/attempt_code = text2num(input("Re-enter the current EFTPOS access code", "Confirm EFTPOS code"))
|
||||
if(attempt_code == access_code)
|
||||
eftpos_name = sanitize(input("Enter a new terminal ID for this device", "Enter new EFTPOS ID")) + " EFTPOS scanner"
|
||||
eftpos_name = sanitize(input("Enter a new terminal ID for this device", "Enter new EFTPOS ID"), MAX_NAME_LEN) + " EFTPOS scanner"
|
||||
print_reference()
|
||||
else
|
||||
usr << "\icon[src]<span class='warning'>Incorrect code entered.</span>"
|
||||
@@ -225,10 +227,13 @@
|
||||
|
||||
src.attack_self(usr)
|
||||
|
||||
/obj/item/device/eftpos/proc/scan_card(var/obj/item/weapon/card/I)
|
||||
/obj/item/device/eftpos/proc/scan_card(var/obj/item/weapon/card/I, var/obj/item/ID_container)
|
||||
if (istype(I, /obj/item/weapon/card/id))
|
||||
var/obj/item/weapon/card/id/C = I
|
||||
visible_message("<span class='info'>[usr] swipes a card through [src].</span>")
|
||||
if(I==ID_container || ID_container == null)
|
||||
usr.visible_message("<span class='info'>\The [usr] swipes a card through \the [src].</span>")
|
||||
else
|
||||
usr.visible_message("<span class='info'>\The [usr] swipes \the [ID_container] through \the [src].</span>")
|
||||
if(transaction_locked && !transaction_paid)
|
||||
if(linked_account)
|
||||
if(!linked_account.suspended)
|
||||
@@ -242,7 +247,7 @@
|
||||
if(!D.suspended)
|
||||
if(transaction_amount <= D.money)
|
||||
playsound(src, 'sound/machines/chime.ogg', 50, 1)
|
||||
src.visible_message("\icon[src] The [src] chimes.")
|
||||
src.visible_message("\icon[src] \The [src] chimes.")
|
||||
transaction_paid = 1
|
||||
|
||||
//transfer the money
|
||||
@@ -283,13 +288,13 @@
|
||||
else if (istype(I, /obj/item/weapon/card/emag))
|
||||
if(transaction_locked)
|
||||
if(transaction_paid)
|
||||
usr << "\icon[src]<span class='info'>You stealthily swipe [I] through [src].</span>"
|
||||
usr << "\icon[src]<span class='info'>You stealthily swipe \the [I] through \the [src].</span>"
|
||||
transaction_locked = 0
|
||||
transaction_paid = 0
|
||||
else
|
||||
visible_message("<span class='info'>[usr] swipes a card through [src].</span>")
|
||||
usr.visible_message("<span class='info'>\The [usr] swipes a card through \the [src].</span>")
|
||||
playsound(src, 'sound/machines/chime.ogg', 50, 1)
|
||||
src.visible_message("\icon[src] The [src] chimes.")
|
||||
src.visible_message("\icon[src] \The [src] chimes.")
|
||||
transaction_paid = 1
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/New(newloc,planttype)
|
||||
|
||||
..()
|
||||
|
||||
if(!dried_type)
|
||||
dried_type = type
|
||||
src.pixel_x = rand(-5.0, 5)
|
||||
src.pixel_y = rand(-5.0, 5)
|
||||
|
||||
@@ -354,9 +355,8 @@
|
||||
seed.do_sting(H,src,pick("r_hand","l_hand"))
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/dropped(mob/user)
|
||||
if(!..() || !seed)
|
||||
return
|
||||
if(seed.get_trait(TRAIT_BIOLUM))
|
||||
..()
|
||||
if(seed && seed.get_trait(TRAIT_BIOLUM))
|
||||
user.SetLuminosity(user.luminosity - seed.get_trait(TRAIT_BIOLUM))
|
||||
SetLuminosity(seed.get_trait(TRAIT_BIOLUM))
|
||||
|
||||
|
||||
@@ -73,8 +73,7 @@
|
||||
host << "<B>You are [host], one of a race of drifting interstellar plantlike creatures that sometimes share their seeds with human traders.</B>"
|
||||
host << "<B>Too much darkness will send you into shock and starve you, but light will help you heal.</B>"
|
||||
|
||||
var/newname = input(host,"Enter a name, or leave blank for the default name.", "Name change","") as text
|
||||
newname = sanitize(newname)
|
||||
var/newname = sanitizeSafe(input(host,"Enter a name, or leave blank for the default name.", "Name change","") as text, MAX_NAME_LEN)
|
||||
if (newname != "")
|
||||
host.real_name = newname
|
||||
host.name = host.real_name
|
||||
@@ -31,7 +31,7 @@
|
||||
O.loc = src
|
||||
update_icon()
|
||||
else if(istype(O, /obj/item/weapon/pen))
|
||||
var/newname = sanitizeSafe(input("What would you like to title this bookshelf?"), MAX_MESSAGE_LEN)
|
||||
var/newname = sanitizeSafe(input("What would you like to title this bookshelf?"), MAX_NAME_LEN)
|
||||
if(!newname)
|
||||
return
|
||||
else
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
matter = list("metal" = 3750)
|
||||
var/digspeed = 40 //moving the delay to an item var so R&D can make improved picks. --NEO
|
||||
origin_tech = "materials=1;engineering=1"
|
||||
attack_verb = list("hit", "pierced", "sliced", "attacked", "drilled")
|
||||
attack_verb = list("hit", "pierced", "sliced", "attacked")
|
||||
var/drill_sound = 'sound/weapons/Genhit.ogg'
|
||||
var/drill_verb = "drilling"
|
||||
sharp = 1
|
||||
@@ -107,6 +107,7 @@
|
||||
digspeed = 20
|
||||
origin_tech = "materials=4"
|
||||
desc = "This makes no metallurgic sense."
|
||||
drill_verb = "picking"
|
||||
|
||||
/obj/item/weapon/pickaxe/plasmacutter
|
||||
name = "plasma cutter"
|
||||
@@ -127,7 +128,8 @@
|
||||
item_state = "dpickaxe"
|
||||
digspeed = 10
|
||||
origin_tech = "materials=6;engineering=4"
|
||||
desc = "A pickaxe with a diamond pick head, this is just like minecraft."
|
||||
desc = "A pickaxe with a diamond pick head."
|
||||
drill_verb = "picking"
|
||||
|
||||
/obj/item/weapon/pickaxe/diamonddrill //When people ask about the badass leader of the mining tools, they are talking about ME!
|
||||
name = "diamond mining drill"
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
|
||||
/mob/dead/observer/emote(var/act, var/type, var/message)
|
||||
message = sanitize(message)
|
||||
//message = sanitize(message) - already sanitized in verb/me_verb()
|
||||
|
||||
if(!message)
|
||||
return
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
//
|
||||
// The datum containing all the chunks.
|
||||
|
||||
var/datum/visualnet/camera/cameranet = new()
|
||||
|
||||
/datum/visualnet/camera
|
||||
// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del().
|
||||
var/list/cameras = list()
|
||||
@@ -36,11 +36,13 @@
|
||||
eyeobj.owner = src
|
||||
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
|
||||
spawn(5)
|
||||
eyeobj.loc = src.loc
|
||||
if(eyeobj)
|
||||
eyeobj.loc = src.loc
|
||||
|
||||
/mob/living/silicon/ai/Del()
|
||||
eyeobj.owner = null
|
||||
del(eyeobj) // No AI, no Eye
|
||||
if(eyeobj)
|
||||
eyeobj.owner = null
|
||||
del(eyeobj) // No AI, no Eye
|
||||
..()
|
||||
|
||||
/atom/proc/move_camera_by_click()
|
||||
@@ -101,7 +101,7 @@
|
||||
var/turf/t = turf
|
||||
if(obscuredTurfs[t])
|
||||
if(!t.obfuscations[obfuscation.type])
|
||||
t.obfuscations[obfuscation.type] = image(obfuscation.icon, t, obfuscation.icon_state, 15)
|
||||
t.obfuscations[obfuscation.type] = image(obfuscation.icon, t, obfuscation.icon_state, OBFUSCATION_LAYER)
|
||||
|
||||
obscured += t.obfuscations[obfuscation.type]
|
||||
for(var/eye in seenby)
|
||||
@@ -140,7 +140,7 @@
|
||||
for(var/turf in obscuredTurfs)
|
||||
var/turf/t = turf
|
||||
if(!t.obfuscations[obfuscation.type])
|
||||
t.obfuscations[obfuscation.type] = image(obfuscation.icon, t, obfuscation.icon_state, 15)
|
||||
t.obfuscations[obfuscation.type] = image(obfuscation.icon, t, obfuscation.icon_state, OBFUSCATION_LAYER)
|
||||
obscured += t.obfuscations[obfuscation.type]
|
||||
|
||||
#undef UPDATE_BUFFER
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
var/sprint = 10
|
||||
var/cooldown = 0
|
||||
var/acceleration = 1
|
||||
var/owner_follows_eye = 0
|
||||
|
||||
see_in_dark = 7
|
||||
status_flags = GODMODE
|
||||
@@ -35,12 +36,14 @@ mob/eye/Del()
|
||||
ghost_darkness_images -= ghostimage
|
||||
ghost_sightless_images -= ghostimage
|
||||
del(ghostimage)
|
||||
ghostimage = null;
|
||||
ghostimage = null
|
||||
updateallghostimages()
|
||||
..()
|
||||
|
||||
// Movement code. Returns 0 to stop air movement from moving it.
|
||||
/mob/eye/Move()
|
||||
/mob/eye/Move(n, direct)
|
||||
if(owner == src)
|
||||
EyeMove(n, direct)
|
||||
return 0
|
||||
|
||||
/mob/eye/examinate()
|
||||
@@ -60,15 +63,35 @@ mob/eye/Del()
|
||||
/mob/eye/proc/setLoc(var/T)
|
||||
if(owner)
|
||||
T = get_turf(T)
|
||||
loc = T
|
||||
if(T != loc)
|
||||
loc = T
|
||||
|
||||
if(owner.client)
|
||||
owner.client.eye = src
|
||||
if(owner.client)
|
||||
owner.client.eye = src
|
||||
|
||||
visualnet.visibility(src)
|
||||
return 1
|
||||
if(owner_follows_eye)
|
||||
visualnet.updateVisibility(owner, 0)
|
||||
owner.loc = loc
|
||||
visualnet.updateVisibility(owner, 0)
|
||||
|
||||
visualnet.visibility(src)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/eye/proc/getLoc()
|
||||
if(owner)
|
||||
if(!isturf(owner.loc) || !owner.client)
|
||||
return
|
||||
return loc
|
||||
/mob
|
||||
var/mob/eye/eyeobj
|
||||
|
||||
/mob/proc/EyeMove(n, direct)
|
||||
if(!eyeobj)
|
||||
return
|
||||
|
||||
return eyeobj.EyeMove(n, direct)
|
||||
|
||||
/mob/eye/EyeMove(n, direct)
|
||||
var/initial = initial(sprint)
|
||||
var/max_sprint = 50
|
||||
@@ -86,18 +109,3 @@ mob/eye/Del()
|
||||
sprint = min(sprint + 0.5, max_sprint)
|
||||
else
|
||||
sprint = initial
|
||||
|
||||
/mob/eye/proc/getLoc()
|
||||
if(owner)
|
||||
if(!isturf(owner.loc) || !owner.client)
|
||||
return
|
||||
return loc
|
||||
|
||||
/mob
|
||||
var/mob/eye/eyeobj
|
||||
|
||||
/mob/proc/EyeMove(n, direct)
|
||||
if(!eyeobj)
|
||||
return
|
||||
|
||||
return eyeobj.EyeMove(n, direct)
|
||||
|
||||
7
code/modules/mob/freelook/life.dm
Normal file
7
code/modules/mob/freelook/life.dm
Normal file
@@ -0,0 +1,7 @@
|
||||
/mob/eye/Life()
|
||||
..()
|
||||
// If we lost our client, reset the list of visible chunks so they update properly on return
|
||||
if(owner == src && !client)
|
||||
visibleChunks.Cut()
|
||||
/*else if(owner && !owner.client)
|
||||
visibleChunks.Cut()*/
|
||||
39
code/modules/mob/freelook/mask/chunk.dm
Normal file
39
code/modules/mob/freelook/mask/chunk.dm
Normal file
@@ -0,0 +1,39 @@
|
||||
// CULT CHUNK
|
||||
//
|
||||
// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
|
||||
// Allows the Eye to stream these chunks and know what it can and cannot see.
|
||||
|
||||
/datum/obfuscation/cult
|
||||
icon_state = "white"
|
||||
|
||||
/datum/chunk/cult
|
||||
obfuscation = new /datum/obfuscation/cult()
|
||||
|
||||
/datum/chunk/cult/acquireVisibleTurfs(var/list/visible)
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
for(var/turf/t in L.seen_turfs())
|
||||
visible[t] = t
|
||||
|
||||
/mob/living/proc/seen_turfs()
|
||||
return seen_turfs_in_range(src, 3)
|
||||
|
||||
/mob/living/carbon/human/seen_turfs()
|
||||
/*if(src.isSynthetic())
|
||||
return list()*/
|
||||
|
||||
if(mind in cult.current_antagonists)
|
||||
return seen_turfs_in_range(src, client ? client.view : 7)
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/seen_turfs()
|
||||
return list()
|
||||
|
||||
/mob/living/simple_animal/seen_turfs()
|
||||
return seen_turfs_in_range(src, 1)
|
||||
|
||||
/mob/living/simple_animal/shade/narsie/seen_turfs()
|
||||
return view(2, src)
|
||||
|
||||
/proc/seen_turfs_in_range(var/source, var/range)
|
||||
var/turf/pos = get_turf(source)
|
||||
return hear(range, pos)
|
||||
15
code/modules/mob/freelook/mask/cultnet.dm
Normal file
15
code/modules/mob/freelook/mask/cultnet.dm
Normal file
@@ -0,0 +1,15 @@
|
||||
// CULT NET
|
||||
//
|
||||
// The datum containing all the chunks.
|
||||
|
||||
/datum/visualnet/cult
|
||||
chunk_type = /datum/chunk/cult
|
||||
|
||||
/datum/visualnet/cult/proc/provides_vision(var/mob/living/L)
|
||||
return L.provides_cult_vision()
|
||||
|
||||
/mob/living/proc/provides_cult_vision()
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/provides_cult_vision()
|
||||
return 0
|
||||
13
code/modules/mob/freelook/mask/eye.dm
Normal file
13
code/modules/mob/freelook/mask/eye.dm
Normal file
@@ -0,0 +1,13 @@
|
||||
// MASK EYE
|
||||
//
|
||||
// A mob that a cultists controls to look around the station with.
|
||||
// It streams chunks as it moves around, which will show it what the cultist can and cannot see.
|
||||
|
||||
/mob/eye/maskEye
|
||||
name = "Eye of Nar-Sie"
|
||||
acceleration = 0
|
||||
owner_follows_eye = 1
|
||||
|
||||
/mob/eye/maskEye/New()
|
||||
..()
|
||||
visualnet = cultnet
|
||||
50
code/modules/mob/freelook/mask/update_triggers.dm
Normal file
50
code/modules/mob/freelook/mask/update_triggers.dm
Normal file
@@ -0,0 +1,50 @@
|
||||
//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update.
|
||||
|
||||
#define CULT_UPDATE_BUFFER 30
|
||||
|
||||
/mob/living/var/updating_cult_vision = 0
|
||||
|
||||
/mob/living/Move()
|
||||
var/oldLoc = src.loc
|
||||
. = ..()
|
||||
if(.)
|
||||
if(cultnet.provides_vision(src))
|
||||
if(!updating_cult_vision)
|
||||
updating_cult_vision = 1
|
||||
spawn(CULT_UPDATE_BUFFER)
|
||||
if(oldLoc != src.loc)
|
||||
cultnet.updateVisibility(oldLoc, 0)
|
||||
cultnet.updateVisibility(loc, 0)
|
||||
updating_cult_vision = 0
|
||||
|
||||
#undef CULT_UPDATE_BUFFER
|
||||
|
||||
/mob/living/New()
|
||||
..()
|
||||
cultnet.updateVisibility(src, 0)
|
||||
|
||||
/mob/living/Del()
|
||||
cultnet.updateVisibility(src, 0)
|
||||
..()
|
||||
|
||||
/mob/living/rejuvenate()
|
||||
var/was_dead = stat == DEAD
|
||||
..()
|
||||
if(was_dead && stat != DEAD)
|
||||
// Arise!
|
||||
cultnet.updateVisibility(src, 0)
|
||||
|
||||
/mob/living/death()
|
||||
if(..())
|
||||
// If true, the mob went from living to dead (assuming everyone has been overriding as they should...)
|
||||
cultnet.updateVisibility(src)
|
||||
|
||||
/datum/antagonist/add_antagonist(var/datum/mind/player)
|
||||
..()
|
||||
if(src == cult)
|
||||
cultnet.updateVisibility(player.current, 0)
|
||||
|
||||
/datum/antagonist/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted)
|
||||
..()
|
||||
if(src == cult)
|
||||
cultnet.updateVisibility(player.current, 0)
|
||||
@@ -2,8 +2,6 @@
|
||||
//
|
||||
// The datum containing all the chunks.
|
||||
|
||||
var/global/list/visual_nets = new()
|
||||
|
||||
/datum/visualnet
|
||||
// The chunks of the map, mapping the areas that an object can see.
|
||||
var/list/chunks = list()
|
||||
|
||||
@@ -134,6 +134,12 @@
|
||||
. = (L in languages)
|
||||
languages.Remove(L)
|
||||
|
||||
/mob/living/remove_language(rem_language)
|
||||
var/datum/language/L = all_languages[rem_language]
|
||||
if(default_language == L)
|
||||
default_language = null
|
||||
return ..()
|
||||
|
||||
// Can we speak this language, as opposed to just understanding it?
|
||||
/mob/proc/can_speak(datum/language/speaking)
|
||||
|
||||
@@ -154,4 +160,32 @@
|
||||
src << browse(dat, "window=checklanguage")
|
||||
return
|
||||
|
||||
/mob/living/check_languages()
|
||||
var/dat = "<b><font size = 5>Known Languages</font></b><br/><br/>"
|
||||
|
||||
if(default_language)
|
||||
dat += "Current default language: [default_language] - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a><br/><br/>"
|
||||
|
||||
for(var/datum/language/L in languages)
|
||||
if(!(L.flags & NONGLOBAL))
|
||||
if(L == default_language)
|
||||
dat += "<b>[L.name] (:[L.key])</b> - default - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a><br/>[L.desc]<br/><br/>"
|
||||
else
|
||||
dat += "<b>[L.name] (:[L.key])</b> - <a href='byond://?src=\ref[src];default_lang=[L]'>set default</a><br/>[L.desc]<br/><br/>"
|
||||
|
||||
src << browse(dat, "window=checklanguage")
|
||||
|
||||
/mob/living/Topic(href, href_list)
|
||||
if(href_list["default_lang"])
|
||||
if(href_list["default_lang"] == "reset")
|
||||
set_default_language(null)
|
||||
else
|
||||
var/datum/language/L = all_languages[href_list["default_lang"]]
|
||||
if(L)
|
||||
set_default_language(L)
|
||||
check_languages()
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
#undef SCRAMBLE_CACHE_LEN
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
if (silent)
|
||||
return
|
||||
|
||||
message = sanitize(message)
|
||||
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))
|
||||
return //No MMI, can't speak, bucko./N
|
||||
else
|
||||
|
||||
@@ -456,6 +456,9 @@
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/get_default_language()
|
||||
if(default_language)
|
||||
return default_language
|
||||
|
||||
if(!species)
|
||||
return null
|
||||
return species.default_language ? all_languages[species.default_language] : null
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR, var/location = src, var/mob/user = src, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list())
|
||||
/mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR, var/location = src, var/mob/user = src, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list(), var/datum/topic_state/state = default_state)
|
||||
var/obj/nano_module/appearance_changer/AC = new(location, src, check_species_whitelist, species_whitelist, species_blacklist)
|
||||
AC.flags = flags
|
||||
AC.ui_interact(user)
|
||||
AC.ui_interact(user, state = state)
|
||||
|
||||
/mob/living/carbon/human/proc/change_species(var/new_species)
|
||||
if(!new_species)
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
mutations.Add(HUSK)
|
||||
status_flags |= DISFIGURED //makes them unknown without fucking up other stuff like admintools
|
||||
update_body(0)
|
||||
update_body(1)
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/Drain()
|
||||
|
||||
@@ -21,7 +21,10 @@
|
||||
set_species()
|
||||
|
||||
if(species)
|
||||
name = species.get_random_name(gender)
|
||||
real_name = species.get_random_name(gender)
|
||||
name = real_name
|
||||
if(mind)
|
||||
mind.name = real_name
|
||||
|
||||
var/datum/reagents/R = new/datum/reagents(1000)
|
||||
reagents = R
|
||||
@@ -863,11 +866,11 @@
|
||||
var/list/creatures = list()
|
||||
for(var/mob/living/carbon/h in world)
|
||||
creatures += h
|
||||
var/mob/target = input ("Who do you want to project your mind to ?") as null|anything in creatures
|
||||
var/mob/target = input("Who do you want to project your mind to ?") as null|anything in creatures
|
||||
if (isnull(target))
|
||||
return
|
||||
|
||||
var/say = input ("What do you wish to say")
|
||||
var/say = sanitize(input("What do you wish to say"))
|
||||
if(mRemotetalk in target.mutations)
|
||||
target.show_message("\blue You hear [src.real_name]'s voice: [say]")
|
||||
else
|
||||
@@ -926,23 +929,12 @@
|
||||
germ_level += n
|
||||
|
||||
/mob/living/carbon/human/revive()
|
||||
for (var/obj/item/organ/external/O in organs)
|
||||
O.status &= ~ORGAN_BROKEN
|
||||
O.status &= ~ORGAN_BLEEDING
|
||||
O.status &= ~ORGAN_SPLINTED
|
||||
O.status &= ~ORGAN_CUT_AWAY
|
||||
O.status &= ~ORGAN_ATTACHABLE
|
||||
O.wounds.Cut()
|
||||
O.heal_damage(1000,1000,1,1)
|
||||
|
||||
var/obj/item/organ/external/head/h = organs_by_name["head"]
|
||||
h.disfigured = 0
|
||||
|
||||
if(species && !(species.flags & NO_BLOOD))
|
||||
vessel.add_reagent("blood",560-vessel.total_volume)
|
||||
fixblood()
|
||||
|
||||
// Fix up any missing organs.
|
||||
// Fix up all organs.
|
||||
// This will ignore any prosthetics in the prefs currently.
|
||||
species.create_organs(src)
|
||||
|
||||
@@ -954,11 +946,9 @@
|
||||
H.brainmob.mind.transfer_to(src)
|
||||
del(H)
|
||||
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
I.damage = 0
|
||||
|
||||
for (var/datum/disease/virus in viruses)
|
||||
virus.cure()
|
||||
|
||||
for (var/ID in virus2)
|
||||
var/datum/disease2/disease/V = virus2[ID]
|
||||
V.cure(src)
|
||||
@@ -1368,4 +1358,4 @@
|
||||
/mob/living/carbon/human/drop_from_inventory(var/obj/item/W, var/atom/Target = null)
|
||||
if(W in organs)
|
||||
return
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -100,9 +100,9 @@
|
||||
var/hit_zone = H.zone_sel.selecting
|
||||
var/obj/item/organ/external/affecting = get_organ(hit_zone)
|
||||
|
||||
if(!affecting || affecting.status & ORGAN_DESTROYED)
|
||||
if(!affecting || affecting.is_stump() || (affecting.status & ORGAN_DESTROYED))
|
||||
M << "<span class='danger'>They are missing that limb!</span>"
|
||||
return
|
||||
return 1
|
||||
|
||||
switch(src.a_intent)
|
||||
if(I_HELP)
|
||||
@@ -218,7 +218,7 @@
|
||||
|
||||
//See if they have any guns that might go off
|
||||
for(var/obj/item/weapon/gun/W in holding)
|
||||
if(W && prob(holding[W]))
|
||||
if(W && prob(holding[W]))
|
||||
var/list/turfs = list()
|
||||
for(var/turf/T in view())
|
||||
turfs += T
|
||||
@@ -289,7 +289,7 @@
|
||||
if(!target_zone)
|
||||
return null
|
||||
var/obj/item/organ/external/organ = get_organ(check_zone(target_zone))
|
||||
if(!organ || organ.is_dislocated() || organ.dislocated == -1)
|
||||
if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1))
|
||||
return null
|
||||
var/dislocation_str
|
||||
if(prob(W.force))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/mob/living/carbon/human/proc/update_eyes()
|
||||
if(internal_organs_by_name["eyes"])
|
||||
var/obj/item/organ/eyes/eyes = internal_organs_by_name["eyes"]
|
||||
eyes.eye_colour = list(r_eyes,g_eyes,b_eyes)
|
||||
var/obj/item/organ/eyes/eyes = internal_organs_by_name["eyes"]
|
||||
if(eyes)
|
||||
eyes.update_colour()
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/carbon/var/list/internal_organs = list()
|
||||
@@ -70,12 +70,12 @@
|
||||
|
||||
for(var/limb_tag in list("l_leg","r_leg","l_foot","r_foot"))
|
||||
var/obj/item/organ/external/E = organs_by_name[limb_tag]
|
||||
if(!E)
|
||||
stance_damage += 2
|
||||
else if (E.status & ORGAN_DESTROYED)
|
||||
if(!E || (E.status & (ORGAN_DESTROYED|ORGAN_DEAD)))
|
||||
stance_damage += 2 // let it fail even if just foot&leg
|
||||
else if (E.is_malfunctioning() || E.is_broken() || !E.is_usable())
|
||||
stance_damage += 1
|
||||
else if (E.is_dislocated())
|
||||
stance_damage += 0.5
|
||||
|
||||
// Canes and crutches help you stand (if the latter is ever added)
|
||||
// One cane mitigates a broken leg+foot, or a missing foot.
|
||||
@@ -102,10 +102,14 @@
|
||||
if(!E || !E.can_grasp || (E.status & ORGAN_SPLINTED))
|
||||
continue
|
||||
|
||||
if(E.is_broken())
|
||||
if(E.is_broken() || E.is_dislocated())
|
||||
if(E.body_part == HAND_LEFT)
|
||||
if(!l_hand)
|
||||
continue
|
||||
drop_from_inventory(l_hand)
|
||||
else
|
||||
if(!r_hand)
|
||||
continue
|
||||
drop_from_inventory(r_hand)
|
||||
|
||||
var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ")
|
||||
|
||||
@@ -389,7 +389,7 @@
|
||||
// Lung damage increases the minimum safe pressure.
|
||||
if(species.has_organ["lungs"])
|
||||
var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"]
|
||||
if(!L)
|
||||
if(isnull(L))
|
||||
safe_pressure_min = INFINITY //No lungs, how are you breathing?
|
||||
else if(L.is_broken())
|
||||
safe_pressure_min *= 1.5
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
poison_type = "oxygen"
|
||||
siemens_coefficient = 0.2
|
||||
|
||||
flags = IS_WHITELISTED | NO_SCAN | HAS_EYE_COLOR
|
||||
flags = CAN_JOIN | IS_WHITELISTED | NO_SCAN | HAS_EYE_COLOR
|
||||
|
||||
blood_color = "#2299FC"
|
||||
flesh_color = "#808D11"
|
||||
@@ -47,8 +47,7 @@
|
||||
"liver" = /obj/item/organ/liver,
|
||||
"kidneys" = /obj/item/organ/kidneys,
|
||||
"brain" = /obj/item/organ/brain,
|
||||
"eyes" = /obj/item/organ/eyes,
|
||||
"stack" = /obj/item/organ/stack/vox
|
||||
"eyes" = /obj/item/organ/eyes
|
||||
)
|
||||
|
||||
/datum/species/vox/get_random_name(var/gender)
|
||||
|
||||
@@ -168,6 +168,10 @@
|
||||
|
||||
/datum/species/proc/get_random_name(var/gender)
|
||||
var/datum/language/species_language = all_languages[language]
|
||||
if(!species_language)
|
||||
species_language = all_languages[default_language]
|
||||
if(!species_language)
|
||||
return "unknown"
|
||||
return species_language.get_random_name(gender)
|
||||
|
||||
/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs.
|
||||
|
||||
@@ -45,11 +45,8 @@
|
||||
if(prob(1))
|
||||
H.emote(pick("scratch","jump","roll","tail"))
|
||||
|
||||
/datum/species/monkey/handle_post_spawn(var/mob/living/carbon/human/H)
|
||||
H.real_name = "[lowertext(name)] ([rand(100,999)])"
|
||||
H.name = H.real_name
|
||||
|
||||
..()
|
||||
/datum/species/monkey/get_random_name()
|
||||
return "[lowertext(name)] ([rand(100,999)])"
|
||||
|
||||
/datum/species/monkey/tajaran
|
||||
name = "Farwa"
|
||||
|
||||
@@ -61,6 +61,9 @@
|
||||
var/weeds_heal_rate = 1 // Health regen on weeds.
|
||||
var/weeds_plasma_rate = 5 // Plasma regen on weeds.
|
||||
|
||||
/datum/species/xenos/get_random_name()
|
||||
return "alien [caste_name] ([alien_number])"
|
||||
|
||||
/datum/species/xenos/can_understand(var/mob/other)
|
||||
|
||||
if(istype(other,/mob/living/carbon/alien/larva))
|
||||
|
||||
@@ -41,12 +41,12 @@
|
||||
if (target.l_hand)
|
||||
// Disarm left hand
|
||||
//Urist McAssistant dropped the macguffin with a scream just sounds odd. Plus it doesn't work with NO_PAIN
|
||||
target.visible_message("<span class='danger'>\The [target.l_hand] was knocked right out of [src]'s grasp!</span>")
|
||||
target.visible_message("<span class='danger'>\The [target.l_hand] was knocked right out of [target]'s grasp!</span>")
|
||||
target.drop_l_hand()
|
||||
if("r_arm", "r_hand")
|
||||
if (target.r_hand)
|
||||
// Disarm right hand
|
||||
target.visible_message("<span class='danger'>\The [target.r_hand] was knocked right out of [src]'s grasp!</span>")
|
||||
target.visible_message("<span class='danger'>\The [target.r_hand] was knocked right out of [target]'s grasp!</span>")
|
||||
target.drop_r_hand()
|
||||
if("chest")
|
||||
if(!target.lying)
|
||||
|
||||
@@ -237,24 +237,30 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
//CACHING: Generate an index key from visible bodyparts.
|
||||
//0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic.
|
||||
|
||||
//Create a new, blank icon for our mob to use.
|
||||
if(stand_icon)
|
||||
del(stand_icon)
|
||||
stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank")
|
||||
var/icon_key = "[species.race_key][g][s_tone][r_skin][g_skin][b_skin]"
|
||||
var/obj/item/organ/eyes/eyes = internal_organs_by_name["eyes"]
|
||||
|
||||
var/icon_key = "[species.race_key][g][s_tone]"
|
||||
for(var/obj/item/organ/external/part in organs)
|
||||
if(part.is_stump() || (part.status & ORGAN_DESTROYED))
|
||||
icon_key = "[icon_key]0"
|
||||
if(eyes)
|
||||
icon_key += "[rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3])]"
|
||||
else
|
||||
icon_key += "#000000"
|
||||
|
||||
for(var/organ_tag in species.has_limbs)
|
||||
var/obj/item/organ/external/part = organs_by_name[organ_tag]
|
||||
if(isnull(part) || part.is_stump() || (part.status & ORGAN_DESTROYED))
|
||||
icon_key += "0"
|
||||
else if(part.status & ORGAN_ROBOT)
|
||||
icon_key = "[icon_key]2[part.model ? "-[part.model]": ""]"
|
||||
icon_key += "2[part.model ? "-[part.model]": ""]"
|
||||
else if(part.status & ORGAN_DEAD)
|
||||
icon_key = "[icon_key]3"
|
||||
icon_key += "3"
|
||||
else
|
||||
icon_key = "[icon_key]1"
|
||||
icon_key += "1"
|
||||
|
||||
icon_key = "[icon_key][husk ? 1 : 0][fat ? 1 : 0][hulk ? 1 : 0][skeleton ? 1 : 0][s_tone]"
|
||||
icon_key = "[icon_key][husk ? 1 : 0][fat ? 1 : 0][hulk ? 1 : 0][skeleton ? 1 : 0]"
|
||||
|
||||
var/icon/base_icon
|
||||
if(human_icon_cache[icon_key])
|
||||
@@ -784,11 +790,11 @@ var/global/list/damage_icon_parts = list()
|
||||
/mob/living/carbon/human/update_inv_r_hand(var/update_icons=1)
|
||||
if(r_hand)
|
||||
r_hand.screen_loc = ui_rhand //TODO
|
||||
|
||||
|
||||
var/t_icon = INV_R_HAND_DEF_ICON
|
||||
if(r_hand.item_icons && (icon_r_hand in r_hand.item_icons))
|
||||
t_icon = r_hand.item_icons[icon_r_hand]
|
||||
|
||||
|
||||
var/t_state = r_hand.item_state //useful for clothing that changes icon_state but retains the same sprite on the mob when held in hand
|
||||
if(!t_state) t_state = r_hand.icon_state
|
||||
if(r_hand.icon_override)
|
||||
@@ -800,18 +806,18 @@ var/global/list/damage_icon_parts = list()
|
||||
if (handcuffed) drop_r_hand()
|
||||
else
|
||||
overlays_standing[R_HAND_LAYER] = null
|
||||
|
||||
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_l_hand(var/update_icons=1)
|
||||
if(l_hand)
|
||||
l_hand.screen_loc = ui_lhand //TODO
|
||||
|
||||
|
||||
var/t_icon = INV_L_HAND_DEF_ICON
|
||||
if(l_hand.item_icons && (icon_l_hand in l_hand.item_icons))
|
||||
t_icon = l_hand.item_icons[icon_l_hand]
|
||||
|
||||
|
||||
var/t_state = l_hand.item_state //useful for clothing that changes icon_state but retains the same sprite on the mob when held in hand
|
||||
if(!t_state) t_state = l_hand.icon_state
|
||||
if(l_hand.icon_override)
|
||||
@@ -823,7 +829,7 @@ var/global/list/damage_icon_parts = list()
|
||||
if (handcuffed) drop_l_hand()
|
||||
else
|
||||
overlays_standing[L_HAND_LAYER] = null
|
||||
|
||||
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1)
|
||||
|
||||
@@ -10,14 +10,13 @@
|
||||
is_adult = 0
|
||||
maxHealth = 150
|
||||
revive()
|
||||
regenerate_icons()
|
||||
if (!client) rabid = 1
|
||||
number = rand(1, 1000)
|
||||
name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])"
|
||||
return
|
||||
|
||||
. = ..(gibbed, "seizes up and falls limp...")
|
||||
|
||||
mood = null
|
||||
regenerate_icons()
|
||||
|
||||
return
|
||||
@@ -71,6 +71,7 @@
|
||||
mutation_chance = rand(25, 35)
|
||||
var/sanitizedcolour = replacetext(colour, " ", "")
|
||||
coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]")
|
||||
regenerate_icons()
|
||||
..(location)
|
||||
|
||||
/mob/living/carbon/slime/movement_delay()
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/mob/living/carbon/slime/say(var/message)
|
||||
|
||||
message = sanitize(message)
|
||||
|
||||
var/verb = say_quote(message)
|
||||
|
||||
if(copytext(message,1,2) == "*")
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
//Monkey Overlays Indexes////////
|
||||
#define M_MASK_LAYER 1
|
||||
#define M_BACK_LAYER 2
|
||||
#define M_HANDCUFF_LAYER 3
|
||||
#define M_L_HAND_LAYER 4
|
||||
#define M_R_HAND_LAYER 5
|
||||
#define TARGETED_LAYER 6
|
||||
#define M_FIRE_LAYER 6
|
||||
#define M_TOTAL_LAYERS 7
|
||||
/////////////////////////////////
|
||||
|
||||
/mob/living/carbon/monkey
|
||||
var/list/overlays_lying[M_TOTAL_LAYERS]
|
||||
var/list/overlays_standing[M_TOTAL_LAYERS]
|
||||
|
||||
/mob/living/carbon/monkey/regenerate_icons()
|
||||
..()
|
||||
update_inv_wear_mask(0)
|
||||
update_inv_back(0)
|
||||
update_inv_r_hand(0)
|
||||
update_inv_l_hand(0)
|
||||
update_inv_handcuffed(0)
|
||||
update_fire(0)
|
||||
update_icons()
|
||||
//Hud Stuff
|
||||
update_hud()
|
||||
return
|
||||
|
||||
/mob/living/carbon/monkey/update_icons()
|
||||
update_hud()
|
||||
lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again
|
||||
overlays.Cut()
|
||||
for(var/image/I in overlays_standing)
|
||||
overlays += I
|
||||
|
||||
if(lying)
|
||||
var/matrix/M = matrix()
|
||||
M.Turn(90)
|
||||
M.Translate(1,-6)
|
||||
src.transform = M
|
||||
else
|
||||
var/matrix/M = matrix()
|
||||
src.transform = M
|
||||
|
||||
|
||||
////////
|
||||
/mob/living/carbon/monkey/update_inv_wear_mask(var/update_icons=1)
|
||||
if( wear_mask && istype(wear_mask, /obj/item/clothing/mask) )
|
||||
overlays_standing[M_MASK_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "[wear_mask.icon_state]")
|
||||
wear_mask.screen_loc = ui_monkey_mask
|
||||
else
|
||||
overlays_standing[M_MASK_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/update_inv_r_hand(var/update_icons=1)
|
||||
if(r_hand)
|
||||
var/t_icon = INV_R_HAND_DEF_ICON
|
||||
if(r_hand.item_icons && (icon_r_hand in r_hand.item_icons))
|
||||
t_icon = r_hand.item_icons[icon_r_hand]
|
||||
|
||||
var/t_state = r_hand.item_state
|
||||
if(!t_state) t_state = r_hand.icon_state
|
||||
|
||||
overlays_standing[M_R_HAND_LAYER] = image("icon" = t_icon, "icon_state" = t_state)
|
||||
r_hand.screen_loc = ui_rhand
|
||||
if (handcuffed) drop_r_hand()
|
||||
else
|
||||
overlays_standing[M_R_HAND_LAYER] = null
|
||||
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/update_inv_l_hand(var/update_icons=1)
|
||||
if(l_hand)
|
||||
var/t_icon = INV_L_HAND_DEF_ICON
|
||||
if(l_hand.item_icons && (icon_l_hand in l_hand.item_icons))
|
||||
t_icon = l_hand.item_icons[icon_l_hand]
|
||||
|
||||
var/t_state = l_hand.item_state
|
||||
if(!t_state) t_state = l_hand.icon_state
|
||||
|
||||
overlays_standing[M_L_HAND_LAYER] = image("icon" = t_icon, "icon_state" = t_state)
|
||||
l_hand.screen_loc = ui_lhand
|
||||
if (handcuffed) drop_l_hand()
|
||||
else
|
||||
overlays_standing[M_L_HAND_LAYER] = null
|
||||
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/update_inv_back(var/update_icons=1)
|
||||
if(back)
|
||||
overlays_standing[M_BACK_LAYER] = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]")
|
||||
back.screen_loc = ui_monkey_back
|
||||
else
|
||||
overlays_standing[M_BACK_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/update_inv_handcuffed(var/update_icons=1)
|
||||
if(handcuffed)
|
||||
drop_r_hand()
|
||||
drop_l_hand()
|
||||
stop_pulling()
|
||||
overlays_standing[M_HANDCUFF_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "handcuff1")
|
||||
else
|
||||
overlays_standing[M_HANDCUFF_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/update_hud()
|
||||
if (client)
|
||||
client.screen |= contents
|
||||
|
||||
//Call when target overlay should be added/removed
|
||||
/mob/living/carbon/monkey/update_targeted(var/update_icons=1)
|
||||
if (targeted_by && target_locked)
|
||||
overlays_standing[TARGETED_LAYER] = target_locked
|
||||
else if (!targeted_by && target_locked)
|
||||
del(target_locked)
|
||||
if (!targeted_by)
|
||||
overlays_standing[TARGETED_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/monkey/update_fire(var/update_icons=1)
|
||||
if(on_fire)
|
||||
overlays_standing[M_FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing", "layer"= -M_FIRE_LAYER)
|
||||
else
|
||||
overlays_standing[M_FIRE_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
//Monkey Overlays Indexes////////
|
||||
#undef M_MASK_LAYER
|
||||
#undef M_BACK_LAYER
|
||||
#undef M_HANDCUFF_LAYER
|
||||
#undef M_L_HAND_LAYER
|
||||
#undef M_R_HAND_LAYER
|
||||
#undef TARGETED_LAYER
|
||||
#undef M_FIRE_LAYER
|
||||
#undef M_TOTAL_LAYERS
|
||||
|
||||
25
code/modules/mob/living/default_language.dm
Normal file
25
code/modules/mob/living/default_language.dm
Normal file
@@ -0,0 +1,25 @@
|
||||
/mob/living
|
||||
var/datum/language/default_language
|
||||
|
||||
/mob/living/verb/set_default_language(language as null|anything in languages)
|
||||
set name = "Set Default Language"
|
||||
set category = "IC"
|
||||
|
||||
if(language)
|
||||
src << "<span class='notice'>You will now speak [language] if you do not specify a language when speaking.</span>"
|
||||
else
|
||||
src << "<span class='notice'>You will now speak whatever your standard default language is if you do not specify one when speaking.</span>"
|
||||
default_language = language
|
||||
|
||||
// Silicons can't neccessarily speak everything in their languages list
|
||||
/mob/living/silicon/set_default_language(language as null|anything in speech_synthesizer_langs)
|
||||
..()
|
||||
|
||||
/mob/living/verb/check_default_language()
|
||||
set name = "Check Default Language"
|
||||
set category = "IC"
|
||||
|
||||
if(default_language)
|
||||
src << "<span class='notice'>You are currently speaking [default_language] by default.</span>"
|
||||
else
|
||||
src << "<span class='notice'>Your current default language is your species or mob type default.</span>"
|
||||
@@ -376,7 +376,8 @@ default behaviour is:
|
||||
|
||||
/mob/living/proc/revive()
|
||||
rejuvenate()
|
||||
buckled = initial(src.buckled)
|
||||
if(buckled)
|
||||
buckled.unbuckle_mob()
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
if(dongle.translate_binary) return 1
|
||||
|
||||
/mob/living/proc/get_default_language()
|
||||
return null
|
||||
return default_language
|
||||
|
||||
/mob/living/proc/handle_speech_problems(var/message, var/verb)
|
||||
var/list/returns[3]
|
||||
|
||||
@@ -6,6 +6,7 @@ var/list/ai_verbs_default = list(
|
||||
/mob/living/silicon/ai/proc/ai_announcement,
|
||||
/mob/living/silicon/ai/proc/ai_call_shuttle,
|
||||
// /mob/living/silicon/ai/proc/ai_recall_shuttle,
|
||||
/mob/living/silicon/ai/proc/ai_emergency_message,
|
||||
/mob/living/silicon/ai/proc/ai_camera_track,
|
||||
/mob/living/silicon/ai/proc/ai_camera_list,
|
||||
/mob/living/silicon/ai/proc/ai_goto_location,
|
||||
@@ -380,6 +381,30 @@ var/list/ai_verbs_default = list(
|
||||
if(confirm == "Yes")
|
||||
cancel_call_proc(src)
|
||||
|
||||
/mob/living/silicon/ai/var/emergency_message_cooldown = 0
|
||||
/mob/living/silicon/ai/proc/ai_emergency_message()
|
||||
set category = "AI Commands"
|
||||
set name = "Send Emergency Message"
|
||||
|
||||
if(check_unable(AI_CHECK_WIRELESS))
|
||||
return
|
||||
if(!is_relay_online())
|
||||
usr <<"<span class='warning'>No Emergency Bluespace Relay detected. Unable to transmit message.</span>"
|
||||
return
|
||||
if(emergency_message_cooldown)
|
||||
usr << "<span class='warning'>Arrays recycling. Please stand by.</span>"
|
||||
return
|
||||
var/input = input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "")
|
||||
if(!input)
|
||||
return
|
||||
Centcomm_announce(input, usr)
|
||||
usr << "<span class='notice'>Message transmitted.</span>"
|
||||
log_say("[key_name(usr)] has made an IA Centcomm announcement: [input]")
|
||||
emergency_message_cooldown = 1
|
||||
spawn(300)
|
||||
emergency_message_cooldown = 0
|
||||
|
||||
|
||||
/mob/living/silicon/ai/check_eye(var/mob/user as mob)
|
||||
if (!camera)
|
||||
return null
|
||||
@@ -478,41 +503,39 @@ var/list/ai_verbs_default = list(
|
||||
//Replaces /mob/living/silicon/ai/verb/change_network() in ai.dm & camera.dm
|
||||
//Adds in /mob/living/silicon/ai/proc/ai_network_change() instead
|
||||
//Addition by Mord_Sith to define AI's network change ability
|
||||
/mob/living/silicon/ai/proc/ai_network_change()
|
||||
set category = "AI Commands"
|
||||
set name = "Jump To Network"
|
||||
unset_machine()
|
||||
var/cameralist[0]
|
||||
|
||||
/mob/living/silicon/ai/proc/get_camera_network_list()
|
||||
if(check_unable())
|
||||
return
|
||||
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
|
||||
var/list/cameralist = new()
|
||||
for (var/obj/machinery/camera/C in cameranet.cameras)
|
||||
if(!C.can_use())
|
||||
continue
|
||||
|
||||
var/list/tempnetwork = difflist(C.network,restricted_camera_networks,1)
|
||||
if(tempnetwork.len)
|
||||
for(var/i in tempnetwork)
|
||||
cameralist[i] = i
|
||||
var/old_network = network
|
||||
network = input(U, "Which network would you like to view?") as null|anything in cameralist
|
||||
for(var/i in tempnetwork)
|
||||
cameralist[i] = i
|
||||
|
||||
if(!U.eyeobj)
|
||||
U.view_core()
|
||||
cameralist = sortAssoc(cameralist)
|
||||
return cameralist
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_network_change(var/network in get_camera_network_list())
|
||||
set category = "AI Commands"
|
||||
set name = "Jump To Network"
|
||||
unset_machine()
|
||||
|
||||
if(!network)
|
||||
return
|
||||
|
||||
if(isnull(network))
|
||||
network = old_network // If nothing is selected
|
||||
else
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
if(!C.can_use())
|
||||
continue
|
||||
if(network in C.network)
|
||||
U.eyeobj.setLoc(get_turf(C))
|
||||
break
|
||||
if(!eyeobj)
|
||||
view_core()
|
||||
return
|
||||
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
if(!C.can_use())
|
||||
continue
|
||||
if(network in C.network)
|
||||
eyeobj.setLoc(get_turf(C))
|
||||
break
|
||||
src << "\blue Switched to [network] camera network."
|
||||
//End of code by Mord_Sith
|
||||
|
||||
@@ -668,14 +691,14 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/ai/proc/check_unable(var/flags = 0)
|
||||
if(stat == DEAD)
|
||||
usr << "\red You are dead!"
|
||||
src << "<span class='warning'>You are dead!</span>"
|
||||
return 1
|
||||
|
||||
if((flags & AI_CHECK_WIRELESS) && src.control_disabled)
|
||||
usr << "\red Wireless control is disabled!"
|
||||
src << "<span class='warning'>Wireless control is disabled!</span>"
|
||||
return 1
|
||||
if((flags & AI_CHECK_RADIO) && src.aiRadio.disabledAi)
|
||||
src << "\red System Error - Transceiver Disabled!"
|
||||
src << "<span class='warning'>System Error - Transceiver Disabled!</span>"
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
@@ -117,10 +117,6 @@
|
||||
if (src.client.statpanel == "Status")
|
||||
show_silenced()
|
||||
|
||||
if (proc_holder_list.len)//Generic list for proc_holder objects.
|
||||
for(var/obj/effect/proc_holder/P in proc_holder_list)
|
||||
statpanel("[P.panel]","",P)
|
||||
|
||||
/mob/living/silicon/pai/check_eye(var/mob/user as mob)
|
||||
if (!src.current)
|
||||
return null
|
||||
|
||||
@@ -55,9 +55,9 @@ var/datum/paiController/paiController // Global handler for pAI candidates
|
||||
|
||||
switch(option)
|
||||
if("name")
|
||||
t = input("Enter a name for your pAI", "pAI Name", candidate.name) as text
|
||||
t = sanitizeSafe(input("Enter a name for your pAI", "pAI Name", candidate.name) as text, MAX_NAME_LEN)
|
||||
if(t)
|
||||
candidate.name = sanitizeSafe(t, MAX_NAME_LEN)
|
||||
candidate.name = t
|
||||
if("desc")
|
||||
t = input("Enter a description for your pAI", "pAI Description", candidate.description) as message
|
||||
if(t)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
lawupdate = 0
|
||||
density = 1
|
||||
req_access = list(access_engine, access_robotics)
|
||||
integrated_light_power = 2
|
||||
integrated_light_power = 3
|
||||
local_transmit = 1
|
||||
|
||||
mob_bump_flag = SIMPLE_ANIMAL
|
||||
@@ -24,6 +24,11 @@
|
||||
|
||||
//Used for self-mailing.
|
||||
var/mail_destination = ""
|
||||
var/obj/machinery/drone_fabricator/master_fabricator
|
||||
var/law_type = /datum/ai_laws/drone
|
||||
var/module_type = /obj/item/weapon/robot_module/drone
|
||||
var/can_pull_size = 2
|
||||
var/can_pull_mobs
|
||||
|
||||
holder_type = /obj/item/weapon/holder/drone
|
||||
|
||||
@@ -36,9 +41,6 @@
|
||||
add_language("Robot Talk", 0)
|
||||
add_language("Drone Talk", 1)
|
||||
|
||||
if(camera && "Robots" in camera.network)
|
||||
camera.add_network("Engineering")
|
||||
|
||||
//They are unable to be upgraded, so let's give them a bit of a better battery.
|
||||
cell.maxcharge = 10000
|
||||
cell.charge = 10000
|
||||
@@ -52,16 +54,18 @@
|
||||
C.max_damage = 10
|
||||
|
||||
verbs -= /mob/living/silicon/robot/verb/Namepick
|
||||
module = new /obj/item/weapon/robot_module/drone(src)
|
||||
|
||||
//Some tidying-up.
|
||||
flavor_text = "It's a tiny little repair drone. The casing is stamped with an NT logo and the subscript: 'NanoTrasen Recursive Repair Systems: Fixing Tomorrow's Problem, Today!'"
|
||||
updateicon()
|
||||
|
||||
/mob/living/silicon/robot/drone/init()
|
||||
laws = new /datum/ai_laws/drone()
|
||||
if(!laws) laws = new law_type
|
||||
if(!module) module = new module_type(src)
|
||||
|
||||
aiCamera = new/obj/item/device/camera/siliconcam/drone_camera(src)
|
||||
flavor_text = "It's a tiny little repair drone. The casing is stamped with an NT logo and the subscript: 'NanoTrasen Recursive Repair Systems: Fixing Tomorrow's Problem, Today!'"
|
||||
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
|
||||
spawn(1)
|
||||
if(camera && ("Robots" in camera.network))
|
||||
camera.add_network("Engineering")
|
||||
|
||||
//Redefining some robot procs...
|
||||
/mob/living/silicon/robot/drone/SetName(pickedName as text)
|
||||
@@ -91,26 +95,26 @@
|
||||
/mob/living/silicon/robot/drone/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
|
||||
if(istype(W, /obj/item/borg/upgrade/))
|
||||
user << "\red The maintenance drone chassis not compatible with \the [W]."
|
||||
user << "<span class='danger'>\The [src] is not compatible with \the [W].</span>"
|
||||
return
|
||||
|
||||
else if (istype(W, /obj/item/weapon/crowbar))
|
||||
user << "The machine is hermetically sealed. You can't open the case."
|
||||
user << "<span class='danger'>\The [src] is hermetically sealed. You can't open the case.</span>"
|
||||
return
|
||||
|
||||
else if (istype(W, /obj/item/weapon/card/emag))
|
||||
|
||||
if(!client || stat == 2)
|
||||
user << "\red There's not much point subverting this heap of junk."
|
||||
user << "<span class='danger'>There's not much point subverting this heap of junk.</span>"
|
||||
return
|
||||
|
||||
if(emagged)
|
||||
src << "\red [user] attempts to load subversive software into you, but your hacked subroutined ignore the attempt."
|
||||
user << "\red You attempt to subvert [src], but the sequencer has no effect."
|
||||
src << "<span class='danger'>\The [user] attempts to load subversive software into you, but your hacked subroutines ignore the attempt.</span>"
|
||||
user << "<span class='danger'>You attempt to subvert [src], but the sequencer has no effect.</span>"
|
||||
return
|
||||
|
||||
user << "\red You swipe the sequencer across [src]'s interface and watch its eyes flicker."
|
||||
src << "\red You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script."
|
||||
user << "<span class='danger'>You swipe the sequencer across [src]'s interface and watch its eyes flicker.</span>"
|
||||
src << "<span class='danger'>You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script.</span>"
|
||||
|
||||
var/obj/item/weapon/card/emag/emag = W
|
||||
emag.uses--
|
||||
@@ -130,7 +134,7 @@
|
||||
|
||||
src << "<b>Obey these laws:</b>"
|
||||
laws.show_laws(src)
|
||||
src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands."
|
||||
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and his commands.</span>"
|
||||
return
|
||||
|
||||
else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
|
||||
@@ -138,14 +142,14 @@
|
||||
if(stat == 2)
|
||||
|
||||
if(!config.allow_drone_spawn || emagged || health < -35) //It's dead, Dave.
|
||||
user << "\red The interface is fried, and a distressing burned smell wafts from the robot's interior. You're not rebooting this one."
|
||||
user << "<span class='danger'>The interface is fried, and a distressing burned smell wafts from the robot's interior. You're not rebooting this one.</span>"
|
||||
return
|
||||
|
||||
if(!allowed(usr))
|
||||
user << "\red Access denied."
|
||||
user << "<span class='danger'>Access denied.</span>"
|
||||
return
|
||||
|
||||
user.visible_message("\red \the [user] swipes \his ID card through \the [src], attempting to reboot it.", "\red You swipe your ID card through \the [src], attempting to reboot it.")
|
||||
user.visible_message("<span class='danger'>\The [user] swipes \his ID card through \the [src], attempting to reboot it.</span>", "<span class='danger'>>You swipe your ID card through \the [src], attempting to reboot it.</span>")
|
||||
var/drones = 0
|
||||
for(var/mob/living/silicon/robot/drone/D in world)
|
||||
if(D.key && D.client)
|
||||
@@ -155,7 +159,7 @@
|
||||
return
|
||||
|
||||
else
|
||||
user.visible_message("\red \the [user] swipes \his ID card through \the [src], attempting to shut it down.", "\red You swipe your ID card through \the [src], attempting to shut it down.")
|
||||
user.visible_message("<span class='danger'>\The [user] swipes \his ID card through \the [src], attempting to shut it down.</span>", "<span class='danger'>You swipe your ID card through \the [src], attempting to shut it down.</span>")
|
||||
|
||||
if(emagged)
|
||||
return
|
||||
@@ -163,7 +167,7 @@
|
||||
if(allowed(usr))
|
||||
shut_down()
|
||||
else
|
||||
user << "\red Access denied."
|
||||
user << "<span class='danger'>Access denied.</span>"
|
||||
|
||||
return
|
||||
|
||||
@@ -185,7 +189,7 @@
|
||||
//Drones killed by damage will gib.
|
||||
/mob/living/silicon/robot/drone/handle_regular_status_updates()
|
||||
|
||||
if(health <= -35 && src.stat != 2)
|
||||
if((health <= -35 || (master_fabricator && src.z != master_fabricator.z)) && src.stat != 2)
|
||||
timeofdeath = world.time
|
||||
death() //Possibly redundant, having trouble making death() cooperate.
|
||||
gib()
|
||||
@@ -194,32 +198,31 @@
|
||||
|
||||
//DRONE MOVEMENT.
|
||||
/mob/living/silicon/robot/drone/Process_Spaceslipping(var/prob_slip)
|
||||
//TODO: Consider making a magboot item for drones to equip. ~Z
|
||||
return 0
|
||||
|
||||
//CONSOLE PROCS
|
||||
/mob/living/silicon/robot/drone/proc/law_resync()
|
||||
if(stat != 2)
|
||||
if(emagged)
|
||||
src << "\red You feel something attempting to modify your programming, but your hacked subroutines are unaffected."
|
||||
src << "<span class='danger'>You feel something attempting to modify your programming, but your hacked subroutines are unaffected.</span>"
|
||||
else
|
||||
src << "\red A reset-to-factory directive packet filters through your data connection, and you obediently modify your programming to suit it."
|
||||
src << "<span class='danger'>A reset-to-factory directive packet filters through your data connection, and you obediently modify your programming to suit it.</span>"
|
||||
full_law_reset()
|
||||
show_laws()
|
||||
|
||||
/mob/living/silicon/robot/drone/proc/shut_down()
|
||||
if(stat != 2)
|
||||
if(emagged)
|
||||
src << "\red You feel a system kill order percolate through your tiny brain, but it doesn't seem like a good idea to you."
|
||||
src << "<span class='danger'>You feel a system kill order percolate through your tiny brain, but it doesn't seem like a good idea to you.</span>"
|
||||
else
|
||||
src << "\red You feel a system kill order percolate through your tiny brain, and you obediently destroy yourself."
|
||||
src << "<span class='danger'>You feel a system kill order percolate through your tiny brain, and you obediently destroy yourself.</span>"
|
||||
death()
|
||||
|
||||
/mob/living/silicon/robot/drone/proc/full_law_reset()
|
||||
clear_supplied_laws()
|
||||
clear_inherent_laws()
|
||||
clear_ion_laws()
|
||||
laws = new /datum/ai_laws/drone
|
||||
laws = new law_type
|
||||
|
||||
//Reboot procs.
|
||||
|
||||
@@ -267,17 +270,32 @@
|
||||
..()
|
||||
else if(istype(AM,/obj/item))
|
||||
var/obj/item/O = AM
|
||||
if(O.w_class > 2)
|
||||
if(O.w_class > can_pull_size)
|
||||
src << "<span class='warning'>You are too small to pull that.</span>"
|
||||
return
|
||||
else
|
||||
..()
|
||||
else
|
||||
src << "<span class='warning'>You are too small to pull that.</span>"
|
||||
return
|
||||
if(!can_pull_mobs)
|
||||
src << "<span class='warning'>You are too small to pull that.</span>"
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/drone/add_robot_verbs()
|
||||
src.verbs |= silicon_verbs_subsystems
|
||||
|
||||
/mob/living/silicon/robot/drone/remove_robot_verbs()
|
||||
src.verbs -= silicon_verbs_subsystems
|
||||
|
||||
/mob/living/silicon/robot/drone/construction
|
||||
law_type = /datum/ai_laws/construction_drone
|
||||
module_type = /obj/item/weapon/robot_module/drone/construction
|
||||
can_pull_size = 5
|
||||
can_pull_mobs = 1
|
||||
|
||||
/mob/living/silicon/robot/drone/construction/init()
|
||||
..()
|
||||
flavor_text = "It's a bulky construction drone stamped with a Sol Central glyph."
|
||||
|
||||
/mob/living/silicon/robot/drone/construction/updatename()
|
||||
real_name = "construction drone ([rand(100,999)])"
|
||||
name = real_name
|
||||
@@ -19,7 +19,7 @@
|
||||
return
|
||||
|
||||
if(!allowed(user))
|
||||
user << "\red Access denied."
|
||||
user << "<span class='danger'>Access denied.</span>"
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
@@ -27,6 +27,8 @@
|
||||
dat += "<B>Maintenance Units</B><BR>"
|
||||
|
||||
for(var/mob/living/silicon/robot/drone/D in world)
|
||||
if(D.z != src.z)
|
||||
continue
|
||||
dat += "<BR>[D.real_name] ([D.stat == 2 ? "<font color='red'>INACTIVE" : "<font color='green'>ACTIVE"]</FONT>)"
|
||||
dat += "<font dize = 9><BR>Cell charge: [D.cell.charge]/[D.cell.maxcharge]."
|
||||
dat += "<BR>Currently located in: [get_area(D)]."
|
||||
@@ -46,7 +48,7 @@
|
||||
return
|
||||
|
||||
if(!allowed(usr))
|
||||
usr << "\red Access denied."
|
||||
usr << "<span class='danger'>Access denied.</span>"
|
||||
return
|
||||
|
||||
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
|
||||
@@ -61,11 +63,11 @@
|
||||
return
|
||||
|
||||
drone_call_area = t_area
|
||||
usr << "\blue You set the area selector to [drone_call_area]."
|
||||
usr << "<span class='notice'>You set the area selector to [drone_call_area].</span>"
|
||||
|
||||
else if (href_list["ping"])
|
||||
|
||||
usr << "\blue You issue a maintenance request for all active drones, highlighting [drone_call_area]."
|
||||
usr << "<span class='notice'>You issue a maintenance request for all active drones, highlighting [drone_call_area].</span>"
|
||||
for(var/mob/living/silicon/robot/drone/D in world)
|
||||
if(D.client && D.stat == 0)
|
||||
D << "-- Maintenance drone presence requested in: [drone_call_area]."
|
||||
@@ -75,7 +77,7 @@
|
||||
var/mob/living/silicon/robot/drone/D = locate(href_list["resync"])
|
||||
|
||||
if(D.stat != 2)
|
||||
usr << "\red You issue a law synchronization directive for the drone."
|
||||
usr << "<span class='danger'>You issue a law synchronization directive for the drone.</span>"
|
||||
D.law_resync()
|
||||
|
||||
else if (href_list["shutdown"])
|
||||
@@ -83,7 +85,7 @@
|
||||
var/mob/living/silicon/robot/drone/D = locate(href_list["shutdown"])
|
||||
|
||||
if(D.stat != 2)
|
||||
usr << "\red You issue a kill command for the unfortunate drone."
|
||||
usr << "<span class='danger'>You issue a kill command for the unfortunate drone.</span>"
|
||||
message_admins("[key_name_admin(usr)] issued kill order for drone [key_name_admin(D)] from control console.")
|
||||
log_game("[key_name(usr)] issued kill order for [key_name(src)] from control console.")
|
||||
D.shut_down()
|
||||
@@ -98,10 +100,10 @@
|
||||
continue
|
||||
|
||||
dronefab = fab
|
||||
usr << "\blue Drone fabricator located."
|
||||
usr << "<span class='notice'>Drone fabricator located.</span>"
|
||||
return
|
||||
|
||||
usr << "\red Unable to locate drone fabricator."
|
||||
usr << "<span class='danger'>Unable to locate drone fabricator.</span>"
|
||||
|
||||
else if (href_list["toggle_fab"])
|
||||
|
||||
@@ -110,10 +112,10 @@
|
||||
|
||||
if(get_dist(src,dronefab) > 3)
|
||||
dronefab = null
|
||||
usr << "\red Unable to locate drone fabricator."
|
||||
usr << "<span class='danger'>Unable to locate drone fabricator.</span>"
|
||||
return
|
||||
|
||||
dronefab.produce_drones = !dronefab.produce_drones
|
||||
usr << "\blue You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator."
|
||||
usr << "<span class='notice'>You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.</span>"
|
||||
|
||||
src.updateUsrDialog()
|
||||
@@ -2,10 +2,12 @@
|
||||
//Limited use.
|
||||
/obj/item/weapon/gripper
|
||||
name = "magnetic gripper"
|
||||
desc = "A simple grasping tool for synthetic assets."
|
||||
desc = "A simple grasping tool specialized in construction and engineering work."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "gripper"
|
||||
|
||||
flags = NOBLUDGEON
|
||||
|
||||
//Has a list of items that it can hold.
|
||||
var/list/can_hold = list(
|
||||
/obj/item/weapon/cell,
|
||||
@@ -28,8 +30,14 @@
|
||||
|
||||
var/obj/item/wrapped = null // Item currently being held.
|
||||
|
||||
var/force_holder = null //
|
||||
|
||||
// VEEEEERY limited version for mining borgs. Basically only for swapping cells and upgrading the drills.
|
||||
/obj/item/weapon/gripper/miner
|
||||
name = "drill maintenance gripper"
|
||||
desc = "A simple grasping tool for the maintenance of heavy drilling machines."
|
||||
icon_state = "gripper-mining"
|
||||
|
||||
can_hold = list(
|
||||
/obj/item/weapon/cell,
|
||||
/obj/item/weapon/stock_parts
|
||||
@@ -38,14 +46,58 @@
|
||||
/obj/item/weapon/gripper/paperwork
|
||||
name = "paperwork gripper"
|
||||
desc = "A simple grasping tool for clerical work."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "gripper"
|
||||
|
||||
can_hold = list(
|
||||
/obj/item/weapon/clipboard,
|
||||
/obj/item/weapon/paper,
|
||||
/obj/item/weapon/paper_bundle,
|
||||
/obj/item/weapon/card/id
|
||||
/obj/item/weapon/card/id,
|
||||
/obj/item/weapon/book,
|
||||
/obj/item/weapon/newspaper
|
||||
)
|
||||
|
||||
/obj/item/weapon/gripper/research //A general usage gripper, used for toxins/robotics/xenobio/etc
|
||||
name = "scientific gripper"
|
||||
icon_state = "gripper-sci"
|
||||
desc = "A simple grasping tool suited to assist in a wide array of research applications."
|
||||
|
||||
can_hold = list(
|
||||
/obj/item/weapon/cell,
|
||||
/obj/item/weapon/stock_parts,
|
||||
/obj/item/device/mmi,
|
||||
/obj/item/robot_parts,
|
||||
/obj/item/borg/upgrade,
|
||||
/obj/item/device/flash, //to build borgs
|
||||
/obj/item/organ/brain, //to insert into MMIs.
|
||||
/obj/item/stack/cable_coil, //again, for borg building
|
||||
/obj/item/weapon/circuitboard,
|
||||
/obj/item/slime_extract,
|
||||
/obj/item/weapon/reagent_containers/glass,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube
|
||||
|
||||
)
|
||||
|
||||
/obj/item/weapon/gripper/service //Used to handle food, drinks, and seeds.
|
||||
name = "service gripper"
|
||||
icon_state = "gripper"
|
||||
desc = "A simple grasping tool used to perform tasks in the service sector, such as handling food, drinks, and seeds."
|
||||
|
||||
can_hold = list(
|
||||
/obj/item/weapon/reagent_containers/glass,
|
||||
/obj/item/weapon/reagent_containers/food,
|
||||
/obj/item/seeds,
|
||||
/obj/item/weapon/grown
|
||||
)
|
||||
|
||||
/obj/item/weapon/gripper/no_use //Used when you want to hold and put items in other things, but not able to 'use' the item
|
||||
|
||||
/obj/item/weapon/gripper/no_use/loader //This is used to disallow building with metal.
|
||||
name = "sheet loader"
|
||||
desc = "A specialized loading device, designed to pick up and insert sheets of materials inside machines."
|
||||
icon_state = "gripper-sheet"
|
||||
|
||||
can_hold = list(
|
||||
/obj/item/stack/sheet
|
||||
)
|
||||
|
||||
/obj/item/weapon/gripper/attack_self(mob/user as mob)
|
||||
@@ -53,6 +105,9 @@
|
||||
return wrapped.attack_self(user)
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gripper/no_use/attack_self(mob/user as mob)
|
||||
return
|
||||
|
||||
/obj/item/weapon/gripper/verb/drop_item()
|
||||
|
||||
set name = "Drop Item"
|
||||
@@ -75,7 +130,12 @@
|
||||
//update_icon()
|
||||
|
||||
/obj/item/weapon/gripper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
return (wrapped ? wrapped.attack(M,user) : 0)
|
||||
if(wrapped) //The force of the wrapped obj gets set to zero during the attack() and afterattack().
|
||||
force_holder = wrapped.force
|
||||
wrapped.force = 0.0
|
||||
wrapped.attack(M,user)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/gripper/afterattack(var/atom/target, var/mob/living/user, proximity, params)
|
||||
|
||||
@@ -97,6 +157,9 @@
|
||||
if(!resolved && wrapped && target)
|
||||
wrapped.afterattack(target,user,1)
|
||||
|
||||
//wrapped's force was set to zero. This resets it to the value it had before.
|
||||
wrapped.force = force_holder
|
||||
force_holder = null
|
||||
//If wrapped was neither deleted nor put into target, put it back into the gripper.
|
||||
if(wrapped && user && (wrapped.loc == user))
|
||||
wrapped.loc = src
|
||||
@@ -145,6 +208,21 @@
|
||||
|
||||
user.visible_message("<span class='danger'>[user] removes the power cell from [A]!</span>", "You remove the power cell.")
|
||||
|
||||
else if(istype(target,/mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/A = target
|
||||
if(A.opened)
|
||||
if(A.cell)
|
||||
|
||||
wrapped = A.cell
|
||||
|
||||
A.cell.add_fingerprint(user)
|
||||
A.cell.updateicon()
|
||||
A.updateicon()
|
||||
A.cell.loc = src
|
||||
A.cell = null
|
||||
|
||||
user.visible_message("<span class='danger'>[user] removes the power cell from [A]!</span>", "You remove the power cell.")
|
||||
|
||||
//TODO: Matter decompiler.
|
||||
/obj/item/weapon/matter_decompiler
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/proc/count_drones()
|
||||
var/drones = 0
|
||||
for(var/mob/living/silicon/robot/drone/D in world)
|
||||
if(D.key && D.client)
|
||||
drones++
|
||||
return drones
|
||||
|
||||
/obj/machinery/drone_fabricator
|
||||
name = "drone fabricator"
|
||||
desc = "A large automated factory for producing maintenance drones."
|
||||
@@ -8,13 +15,20 @@
|
||||
idle_power_usage = 20
|
||||
active_power_usage = 5000
|
||||
|
||||
var/fabricator_tag = "Exodus"
|
||||
var/drone_progress = 0
|
||||
var/produce_drones = 1
|
||||
var/time_last_drone = 500
|
||||
var/drone_type = /mob/living/silicon/robot/drone
|
||||
|
||||
icon = 'icons/obj/machines/drone_fab.dmi'
|
||||
icon_state = "drone_fab_idle"
|
||||
|
||||
/obj/machinery/drone_fabricator/derelict
|
||||
name = "construction drone fabricator"
|
||||
fabricator_tag = "Derelict"
|
||||
drone_type = /mob/living/silicon/robot/drone/construction
|
||||
|
||||
/obj/machinery/drone_fabricator/New()
|
||||
..()
|
||||
|
||||
@@ -48,13 +62,6 @@
|
||||
if(produce_drones && drone_progress >= 100 && istype(user,/mob/dead) && config.allow_drone_spawn && count_drones() < config.max_maint_drones)
|
||||
user << "<BR><B>A drone is prepared. Select 'Join As Drone' from the Ghost tab to spawn as a maintenance drone.</B>"
|
||||
|
||||
/obj/machinery/drone_fabricator/proc/count_drones()
|
||||
var/drones = 0
|
||||
for(var/mob/living/silicon/robot/drone/D in world)
|
||||
if(D.key && D.client)
|
||||
drones++
|
||||
return drones
|
||||
|
||||
/obj/machinery/drone_fabricator/proc/create_drone(var/client/player)
|
||||
|
||||
if(stat & NOPOWER)
|
||||
@@ -71,13 +78,12 @@
|
||||
flick("h_lathe_leave",src)
|
||||
|
||||
time_last_drone = world.time
|
||||
var/mob/living/silicon/robot/drone/new_drone = new(get_turf(src))
|
||||
var/mob/living/silicon/robot/drone/new_drone = new drone_type(get_turf(src))
|
||||
new_drone.transfer_personality(player)
|
||||
new_drone.master_fabricator = src
|
||||
|
||||
drone_progress = 0
|
||||
|
||||
|
||||
|
||||
/mob/dead/verb/join_as_drone()
|
||||
|
||||
set category = "Ghost"
|
||||
@@ -86,11 +92,11 @@
|
||||
|
||||
|
||||
if(ticker.current_state < GAME_STATE_PLAYING)
|
||||
src << "\red The game hasn't started yet!"
|
||||
src << "<span class='danger'>The game hasn't started yet!</span>"
|
||||
return
|
||||
|
||||
if(!(config.allow_drone_spawn))
|
||||
src << "\red That verb is not currently permitted."
|
||||
src << "<span class='danger'>That verb is not currently permitted.</span>"
|
||||
return
|
||||
|
||||
if (!src.stat)
|
||||
@@ -100,14 +106,14 @@
|
||||
return 0 //something is terribly wrong
|
||||
|
||||
if(jobban_isbanned(src,"Cyborg"))
|
||||
usr << "\red You are banned from playing synthetics and cannot spawn as a drone."
|
||||
usr << "<span class='danger'>You are banned from playing synthetics and cannot spawn as a drone.</span>"
|
||||
return
|
||||
|
||||
var/deathtime = world.time - src.timeofdeath
|
||||
if(istype(src,/mob/dead/observer))
|
||||
var/mob/dead/observer/G = src
|
||||
if(G.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
|
||||
usr << "\blue <B>Upon using the antagHUD you forfeighted the ability to join the round.</B>"
|
||||
usr << "<span class='notice'>Upon using the antagHUD you forfeighted the ability to join the round.</span>"
|
||||
return
|
||||
|
||||
var/deathtimeminutes = round(deathtime / 600)
|
||||
@@ -125,16 +131,18 @@
|
||||
usr << "You must wait 10 minutes to respawn as a drone!"
|
||||
return
|
||||
|
||||
var/list/all_fabricators = list()
|
||||
for(var/obj/machinery/drone_fabricator/DF in world)
|
||||
if(DF.stat & NOPOWER || !DF.produce_drones)
|
||||
continue
|
||||
|
||||
if(DF.count_drones() >= config.max_maint_drones)
|
||||
src << "\red There are too many active drones in the world for you to spawn."
|
||||
return
|
||||
|
||||
if(DF.drone_progress >= 100)
|
||||
DF.create_drone(src.client)
|
||||
return
|
||||
all_fabricators[DF.fabricator_tag] = DF
|
||||
|
||||
src << "\red There are no available drone spawn points, sorry."
|
||||
if(!all_fabricators.len)
|
||||
src << "<span class='danger'>There are no available drone spawn points, sorry.</span>"
|
||||
return
|
||||
|
||||
var/choice = input(src,"Which fabricator do you wish to use?") as null|anything in all_fabricators
|
||||
if(choice)
|
||||
var/obj/machinery/drone_fabricator/chosen_fabricator = all_fabricators[choice]
|
||||
chosen_fabricator.create_drone(src.client)
|
||||
@@ -130,10 +130,11 @@
|
||||
if (src.stat != 0)
|
||||
uneq_all()
|
||||
|
||||
if(!is_component_functioning("radio"))
|
||||
radio.on = 0
|
||||
else
|
||||
radio.on = 1
|
||||
if(radio)
|
||||
if(!is_component_functioning("radio"))
|
||||
radio.on = 0
|
||||
else
|
||||
radio.on = 1
|
||||
|
||||
if(is_component_functioning("camera"))
|
||||
src.blinded = 0
|
||||
|
||||
@@ -265,7 +265,8 @@
|
||||
module_sprites["Bro"] = "Brobot"
|
||||
module_sprites["Rich"] = "maximillion"
|
||||
module_sprites["Default"] = "Service2"
|
||||
module_sprites["Drone"] = "drone-service" // How does this even work...? Oh well.
|
||||
module_sprites["Drone - Service"] = "drone-service"
|
||||
module_sprites["Drone - Hydro"] = "drone-hydro"
|
||||
|
||||
if("Clerical")
|
||||
module = new /obj/item/weapon/robot_module/clerical(src)
|
||||
@@ -277,6 +278,12 @@
|
||||
module_sprites["Default"] = "Service2"
|
||||
module_sprites["Drone"] = "drone-service"
|
||||
|
||||
if("Research")
|
||||
module = new /obj/item/weapon/robot_module/research(src)
|
||||
module.channels = list("Science" = 1)
|
||||
module_sprites["Droid"] = "droid-science"
|
||||
module_sprites["Drone"] = "drone-science"
|
||||
|
||||
if("Miner")
|
||||
module = new /obj/item/weapon/robot_module/miner(src)
|
||||
module.channels = list("Supply" = 1)
|
||||
@@ -296,7 +303,8 @@
|
||||
module_sprites["Standard"] = "surgeon"
|
||||
module_sprites["Advanced Droid"] = "droid-medical"
|
||||
module_sprites["Needles"] = "medicalrobot"
|
||||
module_sprites["Drone" ] = "drone-medical"
|
||||
module_sprites["Drone - Medical" ] = "drone-medical"
|
||||
module_sprites["Drone - Chemistry" ] = "drone-chemistry"
|
||||
|
||||
if("Surgeon")
|
||||
module = new /obj/item/weapon/robot_module/surgeon(src)
|
||||
@@ -731,7 +739,7 @@
|
||||
else
|
||||
user << "Unable to locate a radio."
|
||||
|
||||
else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) // trying to unlock the interface with an ID card
|
||||
else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)||istype(W, /obj/item/weapon/card/robot)) // trying to unlock the interface with an ID card
|
||||
if(emagged)//still allow them to open the cover
|
||||
user << "The interface seems slightly damaged"
|
||||
if(opened)
|
||||
@@ -868,6 +876,10 @@
|
||||
//if they are holding or wearing a card that has access, that works
|
||||
if(check_access(H.get_active_hand()) || check_access(H.wear_id))
|
||||
return 1
|
||||
else if(istype(M, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = M
|
||||
if(check_access(R.get_active_hand()) || istype(R.get_active_hand(), /obj/item/weapon/card/robot))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/robot/proc/check_access(obj/item/weapon/card/id/I)
|
||||
|
||||
@@ -1,3 +1,138 @@
|
||||
//A portable analyzer, for research borgs. This is better then giving them a gripper which can hold anything and letting them use the normal analyzer.
|
||||
/obj/item/weapon/portable_destructive_analyzer
|
||||
name = "Portable Destructive Analyzer"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "portable_analyzer"
|
||||
desc = "Similar to the stationary version, this rather unwieldy device allows you to break down objects in the name of science."
|
||||
|
||||
var/min_reliability = 90 //Can't upgrade, call it laziness or a drawback
|
||||
|
||||
var/datum/research/techonly/files //The device uses the same datum structure as the R&D computer/server.
|
||||
//This analyzer can only store tech levels, however.
|
||||
|
||||
var/obj/item/weapon/loaded_item //What is currently inside the analyzer.
|
||||
|
||||
/obj/item/weapon/portable_destructive_analyzer/New()
|
||||
..()
|
||||
files = new /datum/research/techonly(src) //Setup the research data holder.
|
||||
|
||||
/obj/item/weapon/portable_destructive_analyzer/attack_self(user as mob)
|
||||
var/response = alert(user, "Analyzing the item inside will *DESTROY* the item for good.\n\
|
||||
Syncing to the research server will send the data that is stored inside to research.\n\
|
||||
Ejecting will place the loaded item onto the floor.",
|
||||
"What would you like to do?", "Analyze", "Sync", "Eject")
|
||||
if(response == "Analyze")
|
||||
if(loaded_item)
|
||||
var/confirm = alert(user, "This will destroy the item inside forever. Are you sure?","Confirm Analyze","Yes","No")
|
||||
if(confirm == "Yes") //This is pretty copypasta-y
|
||||
user << "You activate the analyzer's microlaser, analyzing \the [loaded_item] and breaking it down."
|
||||
flick("portable_analyzer_scan", src)
|
||||
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
|
||||
if(loaded_item.reliability >= min_reliability)
|
||||
var/list/temp_tech = ConvertReqString2List(loaded_item.origin_tech)
|
||||
for(var/T in temp_tech)
|
||||
files.UpdateTech(T, temp_tech[T])
|
||||
user << "\The [loaded_item] had level [temp_tech[T]] in [T]."
|
||||
loaded_item = null
|
||||
for(var/obj/I in contents)
|
||||
for(var/mob/M in I.contents)
|
||||
M.death()
|
||||
if(istype(I,/obj/item/stack/sheet))//Only deconsturcts one sheet at a time instead of the entire stack
|
||||
var/obj/item/stack/sheet/S = I
|
||||
if(S.get_amount() > 1)
|
||||
S.use(1)
|
||||
loaded_item = S
|
||||
else
|
||||
del(S)
|
||||
desc = initial(desc)
|
||||
icon_state = initial(icon_state)
|
||||
else
|
||||
del(I)
|
||||
desc = initial(desc)
|
||||
icon_state = initial(icon_state)
|
||||
else
|
||||
return
|
||||
else
|
||||
user << "The [src] is empty. Put something inside it first."
|
||||
if(response == "Sync")
|
||||
var/success = 0
|
||||
for(var/obj/machinery/r_n_d/server/S in machines)
|
||||
if(S.disabled)
|
||||
continue
|
||||
for(var/datum/tech/T in files.known_tech) //Uploading
|
||||
S.files.AddTech2Known(T)
|
||||
for(var/datum/tech/T in S.files.known_tech) //Downloading
|
||||
files.AddTech2Known(T)
|
||||
success = 1
|
||||
files.RefreshResearch()
|
||||
if(success)
|
||||
user << "You connect to the research server, push your data upstream to it, then pull the resulting merged data from the master branch."
|
||||
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
else
|
||||
user << "Reserch server ping response timed out. Unable to connect. Please contact the system administrator."
|
||||
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 1)
|
||||
if(response == "Eject")
|
||||
if(loaded_item)
|
||||
loaded_item.loc = get_turf(src)
|
||||
desc = initial(desc)
|
||||
icon_state = initial(icon_state)
|
||||
loaded_item = null
|
||||
else
|
||||
user << "The [src] is already empty."
|
||||
|
||||
|
||||
/obj/item/weapon/portable_destructive_analyzer/afterattack(var/atom/target, var/mob/living/user, proximity)
|
||||
if(!target)
|
||||
return
|
||||
if(!proximity)
|
||||
return
|
||||
if(!isturf(target.loc)) // Don't load up stuff if it's inside a container or mob!
|
||||
return
|
||||
if(istype(target,/obj/item))
|
||||
if(loaded_item)
|
||||
user << "Your [src] already has something inside. Analyze or eject it first."
|
||||
return
|
||||
var/obj/item/I = target
|
||||
I.loc = src
|
||||
loaded_item = I
|
||||
for(var/mob/M in viewers())
|
||||
M.show_message(text("<span class='notice'>[user] adds the [I] to the [src].</span>"), 1)
|
||||
desc = initial(desc) + "<br>It is holding \the [loaded_item]."
|
||||
flick("portable_analyzer_load", src)
|
||||
icon_state = "portable_analyzer_full"
|
||||
|
||||
//This is used to unlock other borg covers.
|
||||
/obj/item/weapon/card/robot //This is not a child of id cards, as to avoid dumb typechecks on computers.
|
||||
name = "access code transmission device"
|
||||
icon_state = "id-robot"
|
||||
desc = "A circuit grafted onto the bottom of an ID card. It is used to transmit access codes into other robot chassis, \
|
||||
allowing you to lock and unlock other robots' panels."
|
||||
|
||||
/obj/item/weapon/card/id/robot/attack_self() //override so borgs can't flash their IDs.
|
||||
return
|
||||
|
||||
/obj/item/weapon/card/id/robot/read()
|
||||
usr << "The ID card does not appear to have any writing on it."
|
||||
return
|
||||
|
||||
//A harvest item for serviceborgs.
|
||||
/obj/item/weapon/robot_harvester
|
||||
name = "auto harvester"
|
||||
desc = "A hand-held harvest tool that resembles a sickle. It uses energy to cut plant matter very efficently."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "autoharvester"
|
||||
|
||||
/obj/item/weapon/robot_harvester/afterattack(var/atom/target, var/mob/living/user, proximity)
|
||||
if(!target)
|
||||
return
|
||||
if(!proximity)
|
||||
return
|
||||
if(istype(target,/obj/machinery/portable_atmospherics/hydroponics))
|
||||
var/obj/machinery/portable_atmospherics/hydroponics/T = target
|
||||
T.harvest(user)
|
||||
else
|
||||
user << "Harvesting \a [target] is not the purpose of this tool. The [src] is for plants being grown."
|
||||
|
||||
// A special tray for the service droid. Allow droid to pick up and drop items as if they were using the tray normally
|
||||
// Click on table to unload, click on item to load. Otherwise works identically to a tray.
|
||||
// Unlike the base item "tray", robotrays ONLY pick up food, drinks and condiments.
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
src.modules += R
|
||||
|
||||
var/obj/item/stack/sheet/plasteel/cyborg/S = new /obj/item/stack/sheet/plasteel/cyborg(src)
|
||||
S.synths = list(metal)
|
||||
S.synths = list(plasteel)
|
||||
src.modules += S
|
||||
|
||||
var/obj/item/stack/sheet/glass/reinforced/cyborg/RG = new /obj/item/stack/sheet/glass/reinforced/cyborg(src)
|
||||
@@ -314,8 +314,13 @@
|
||||
/obj/item/weapon/robot_module/butler/New()
|
||||
..()
|
||||
src.modules += new /obj/item/device/flash(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/food/condiment/enzyme(src)
|
||||
src.modules += new /obj/item/weapon/gripper/service(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/glass/bucket(src)
|
||||
src.modules += new /obj/item/weapon/minihoe(src)
|
||||
src.modules += new /obj/item/weapon/hatchet(src)
|
||||
src.modules += new /obj/item/device/analyzer/plant_analyzer(src)
|
||||
src.modules += new /obj/item/weapon/storage/bag/plants(src)
|
||||
src.modules += new /obj/item/weapon/robot_harvester(src)
|
||||
|
||||
var/obj/item/weapon/rsf/M = new /obj/item/weapon/rsf(src)
|
||||
M.stored_matter = 30
|
||||
@@ -358,6 +363,7 @@
|
||||
src.modules += new /obj/item/weapon/pen/robopen(src)
|
||||
src.modules += new /obj/item/weapon/form_printer(src)
|
||||
src.modules += new /obj/item/weapon/gripper/paperwork(src)
|
||||
src.modules += new /obj/item/weapon/hand_labeler(src)
|
||||
src.emag = new /obj/item/weapon/stamp/denied(src)
|
||||
|
||||
/obj/item/weapon/robot_module/clerical/add_languages(var/mob/living/silicon/robot/R)
|
||||
@@ -395,6 +401,38 @@
|
||||
src.emag = new /obj/item/weapon/pickaxe/plasmacutter(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/research
|
||||
name = "research module"
|
||||
|
||||
/obj/item/weapon/robot_module/research/New()
|
||||
..()
|
||||
src.modules += new /obj/item/device/flash(src)
|
||||
src.modules += new /obj/item/weapon/portable_destructive_analyzer(src)
|
||||
src.modules += new /obj/item/weapon/gripper/research(src)
|
||||
src.modules += new /obj/item/weapon/gripper/no_use/loader(src)
|
||||
src.modules += new /obj/item/device/robotanalyzer(src)
|
||||
src.modules += new /obj/item/weapon/card/robot(src)
|
||||
src.modules += new /obj/item/weapon/wrench(src)
|
||||
src.modules += new /obj/item/weapon/screwdriver(src)
|
||||
src.modules += new /obj/item/weapon/crowbar(src)
|
||||
src.modules += new /obj/item/weapon/scalpel(src)
|
||||
src.modules += new /obj/item/weapon/circular_saw(src)
|
||||
src.modules += new /obj/item/weapon/extinguisher/mini(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/syringe(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
|
||||
src.emag = new /obj/item/weapon/hand_tele(src)
|
||||
|
||||
var/datum/matter_synth/nanite = new /datum/matter_synth/nanite(10000)
|
||||
synths += nanite
|
||||
|
||||
var/obj/item/stack/nanopaste/N = new /obj/item/stack/nanopaste(src)
|
||||
N.uses_charge = 1
|
||||
N.charge_costs = list(1000)
|
||||
N.synths = list(nanite)
|
||||
src.modules += N
|
||||
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/syndicate
|
||||
name = "illegal robot module"
|
||||
|
||||
@@ -446,7 +484,7 @@
|
||||
src.modules += new /obj/item/device/multitool(src)
|
||||
src.modules += new /obj/item/device/lightreplacer(src)
|
||||
src.modules += new /obj/item/weapon/gripper(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/spray/cleaner/drone(src)
|
||||
src.modules += new /obj/item/weapon/soap(src)
|
||||
src.emag = new /obj/item/weapon/pickaxe/plasmacutter(src)
|
||||
src.emag.name = "Plasma Cutter"
|
||||
|
||||
@@ -504,16 +542,19 @@
|
||||
P.synths = list(plastic)
|
||||
src.modules += P
|
||||
|
||||
/obj/item/weapon/robot_module/drone/construction
|
||||
name = "construction drone module"
|
||||
|
||||
/obj/item/weapon/robot_module/drone/construction/New()
|
||||
..()
|
||||
src.modules += new /obj/item/weapon/rcd/borg(src)
|
||||
|
||||
/obj/item/weapon/robot_module/drone/add_languages(var/mob/living/silicon/robot/R)
|
||||
return //not much ROM to spare in that tiny microprocessor!
|
||||
|
||||
/obj/item/weapon/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
|
||||
var/obj/item/weapon/reagent_containers/spray/cleaner/C = locate() in src.modules
|
||||
C.reagents.add_reagent("cleaner", 3 * amount)
|
||||
|
||||
var/obj/item/device/lightreplacer/LR = locate() in src.modules
|
||||
LR.Charge(R, amount)
|
||||
|
||||
..()
|
||||
return
|
||||
|
||||
@@ -521,7 +562,5 @@
|
||||
/obj/item/proc/is_robot_module()
|
||||
if (!istype(src.loc, /mob/living/silicon/robot))
|
||||
return 0
|
||||
|
||||
var/mob/living/silicon/robot/R = src.loc
|
||||
|
||||
return (src in R.module.modules)
|
||||
|
||||
@@ -210,9 +210,19 @@
|
||||
|
||||
var/dat = "<b><font size = 5>Known Languages</font></b><br/><br/>"
|
||||
|
||||
if(default_language)
|
||||
dat += "Current default language: [default_language] - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a><br/><br/>"
|
||||
|
||||
for(var/datum/language/L in languages)
|
||||
if(!(L.flags & NONGLOBAL))
|
||||
dat += "<b>[L.name] (:[L.key])</b><br/>Speech Synthesizer: <i>[(L in speech_synthesizer_langs)? "YES":"NOT SUPPORTED"]</i><br/>[L.desc]<br/><br/>"
|
||||
var/default_str
|
||||
if(L == default_language)
|
||||
default_str = " - default - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a>"
|
||||
else
|
||||
default_str = " - <a href='byond://?src=\ref[src];default_lang=[L]'>set default</a>"
|
||||
|
||||
var/synth = (L in speech_synthesizer_langs)
|
||||
dat += "<b>[L.name] (:[L.key])</b>[synth ? default_str : null]<br/>Speech Synthesizer: <i>[synth ? "YES" : "NOT SUPPORTED"]</i><br/>[L.desc]<br/><br/>"
|
||||
|
||||
src << browse(dat, "window=checklanguage")
|
||||
return
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
attack_sound = 'sound/weapons/punch3.ogg'
|
||||
status_flags = 0
|
||||
resistance = 10
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall)
|
||||
construct_spells = list(/spell/aoe_turf/conjure/forcewall/lesser)
|
||||
|
||||
/mob/living/simple_animal/construct/armoured/Life()
|
||||
weakened = 0
|
||||
@@ -149,7 +149,7 @@
|
||||
environment_smash = 1
|
||||
see_in_dark = 7
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
|
||||
construct_spells = list(/spell/targeted/ethereal_jaunt/shift)
|
||||
|
||||
|
||||
/////////////////////////////Artificer/////////////////////////
|
||||
@@ -173,10 +173,12 @@
|
||||
speed = 0
|
||||
environment_smash = 2
|
||||
attack_sound = 'sound/weapons/punch2.ogg'
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/floor,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone,)
|
||||
construct_spells = list(/spell/aoe_turf/conjure/construct/lesser,
|
||||
/spell/aoe_turf/conjure/wall,
|
||||
/spell/aoe_turf/conjure/floor,
|
||||
/spell/aoe_turf/conjure/soulstone,
|
||||
/spell/aoe_turf/conjure/pylon
|
||||
)
|
||||
|
||||
|
||||
/////////////////////////////Behemoth/////////////////////////
|
||||
@@ -203,6 +205,7 @@
|
||||
resistance = 10
|
||||
var/energy = 0
|
||||
var/max_energy = 1000
|
||||
construct_spells = list(/spell/aoe_turf/conjure/forcewall/lesser)
|
||||
|
||||
////////////////////////Harvester////////////////////////////////
|
||||
|
||||
@@ -226,7 +229,7 @@
|
||||
attack_sound = 'sound/weapons/pierce.ogg'
|
||||
|
||||
construct_spells = list(
|
||||
//spell/targeted/harvest,
|
||||
//spell/aoe_turf/knock/harvester,
|
||||
//spell/rune_write
|
||||
/spell/targeted/harvest,
|
||||
/spell/aoe_turf/knock/harvester,
|
||||
/spell/rune_write
|
||||
)
|
||||
|
||||
@@ -86,7 +86,14 @@
|
||||
name = "empty shell"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "construct"
|
||||
desc = "A wicked machine used by those skilled in magical arts. It is inactive"
|
||||
desc = "A wicked machine used by those skilled in magical arts. It is inactive."
|
||||
|
||||
/obj/structure/constructshell/cultify()
|
||||
return
|
||||
|
||||
/obj/structure/constructshell/cult
|
||||
icon_state = "construct-cult"
|
||||
desc = "This eerie contraption looks like it would come alive if supplied with a missing ingredient."
|
||||
|
||||
/obj/structure/constructshell/attackby(obj/item/O as obj, mob/user as mob)
|
||||
if(istype(O, /obj/item/device/soulstone))
|
||||
|
||||
@@ -46,4 +46,4 @@
|
||||
if(istype(L))
|
||||
if(prob(12))
|
||||
L.Weaken(3)
|
||||
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
|
||||
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
|
||||
|
||||
@@ -714,7 +714,7 @@
|
||||
if(message_mode)
|
||||
if(message_mode in radiochannels)
|
||||
if(ears && istype(ears,/obj/item/device/radio))
|
||||
ears.talk_into(src,message, message_mode, verb, null)
|
||||
ears.talk_into(src,sanitize(message), message_mode, verb, null)
|
||||
|
||||
|
||||
..(message)
|
||||
|
||||
@@ -30,6 +30,14 @@
|
||||
|
||||
/mob/living/simple_animal/shade/Life()
|
||||
..()
|
||||
OnDeathInLife()
|
||||
|
||||
/mob/living/simple_animal/shade/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
|
||||
if(istype(O, /obj/item/device/soulstone))
|
||||
O.transfer_soul("SHADE", src, user)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/shade/proc/OnDeathInLife()
|
||||
if(stat == 2)
|
||||
new /obj/item/weapon/ectoplasm (src.loc)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
@@ -38,10 +46,3 @@
|
||||
ghostize()
|
||||
del src
|
||||
return
|
||||
|
||||
|
||||
/mob/living/simple_animal/shade/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
|
||||
if(istype(O, /obj/item/device/soulstone))
|
||||
O.transfer_soul("SHADE", src, user)
|
||||
return
|
||||
return ..()
|
||||
|
||||
@@ -350,7 +350,7 @@
|
||||
var/obj/machinery/bot/B = target_mob
|
||||
if(B.health > 0)
|
||||
return (0)
|
||||
return (1)
|
||||
return 1
|
||||
|
||||
//Call when target overlay should be added/removed
|
||||
/mob/living/simple_animal/update_targeted()
|
||||
|
||||
@@ -263,7 +263,6 @@
|
||||
set name = "Add Note"
|
||||
set category = "IC"
|
||||
|
||||
msg = copytext(msg, 1, MAX_MESSAGE_LEN)
|
||||
msg = sanitize(msg)
|
||||
|
||||
if(mind)
|
||||
@@ -732,25 +731,31 @@ note dizziness decrements automatically in the mob's Life() proc.
|
||||
if(statpanel("Status") && processScheduler && processScheduler.getIsRunning())
|
||||
var/datum/controller/process/process
|
||||
|
||||
process = processScheduler.getProcess("ticker")
|
||||
stat(null, "[getStatName(process)]\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("air")
|
||||
stat(null, "[getStatName(process)]\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("lighting")
|
||||
stat(null, "[getStatName(process)]\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("alarm")
|
||||
var/list/alarms = alarm_manager.active_alarms()
|
||||
stat(null, "[getStatName(process)]([alarms.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("mob")
|
||||
stat(null, "[getStatName(process)]([mob_list.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
process = processScheduler.getProcess("disease")
|
||||
stat(null, "[getStatName(process)]([active_diseases.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("garbage")
|
||||
stat(null, "[getStatName(process)]([garbage_collector.destroyed.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("machinery")
|
||||
stat(null, "[getStatName(process)]([machines.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("mob")
|
||||
stat(null, "[getStatName(process)]([mob_list.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("nanoui")
|
||||
stat(null, "[getStatName(process)]([nanomanager.processing_uis.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("lighting")
|
||||
stat(null, "[getStatName(process)]\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("obj")
|
||||
stat(null, "[getStatName(process)]([processing_objects.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
@@ -760,15 +765,12 @@ note dizziness decrements automatically in the mob's Life() proc.
|
||||
process = processScheduler.getProcess("powernet")
|
||||
stat(null, "[getStatName(process)]([powernets.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("nanoui")
|
||||
stat(null, "[getStatName(process)]([nanomanager.processing_uis.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("disease")
|
||||
stat(null, "[getStatName(process)]([active_diseases.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("sun")
|
||||
stat(null, "[getStatName(process)]\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
process = processScheduler.getProcess("ticker")
|
||||
stat(null, "[getStatName(process)]\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
|
||||
|
||||
else
|
||||
stat(null, "processScheduler is not running.")
|
||||
|
||||
@@ -785,19 +787,6 @@ note dizziness decrements automatically in the mob's Life() proc.
|
||||
continue
|
||||
statpanel(listed_turf.name, null, A)
|
||||
|
||||
if(spell_list && spell_list.len)
|
||||
for(var/obj/effect/proc_holder/spell/S in spell_list)
|
||||
switch(S.charge_type)
|
||||
if("recharge")
|
||||
statpanel("Spells","[S.charge_counter/10.0]/[S.charge_max/10]",S)
|
||||
if("charges")
|
||||
statpanel("Spells","[S.charge_counter]/[S.charge_max]",S)
|
||||
if("holdervar")
|
||||
statpanel("Spells","[S.holder_var_type] [S.holder_var_amount]",S)
|
||||
|
||||
|
||||
|
||||
|
||||
// facing verbs
|
||||
/mob/proc/canface()
|
||||
if(!canmove) return 0
|
||||
|
||||
@@ -29,10 +29,14 @@
|
||||
var/obj/screen/damageoverlay = null
|
||||
var/obj/screen/pain = null
|
||||
var/obj/screen/gun/item/item_use_icon = null
|
||||
var/obj/screen/gun/radio/radio_use_icon = null
|
||||
var/obj/screen/gun/move/gun_move_icon = null
|
||||
var/obj/screen/gun/run/gun_run_icon = null
|
||||
var/obj/screen/gun/mode/gun_setting_icon = null
|
||||
|
||||
//spells hud icons - this interacts with add_spell and remove_spell
|
||||
var/list/obj/screen/movable/spell_master/spell_masters = null
|
||||
|
||||
/*A bunch of this stuff really needs to go under their own defines instead of being globally attached to mob.
|
||||
A variable should only be globally attached to turfs/objects/whatever, when it is in fact needed as such.
|
||||
The current method unnecessarily clusters up the variable list, especially for humans (although rearranging won't really clean it up a lot but the difference will be noticable for other mobs).
|
||||
@@ -182,7 +186,7 @@
|
||||
var/mob/living/carbon/LAssailant = null
|
||||
|
||||
//Wizard mode, but can be used in other modes thanks to the brand new "Give Spell" badmin button
|
||||
var/obj/effect/proc_holder/spell/list/spell_list = list()
|
||||
var/spell/list/spell_list = list()
|
||||
|
||||
//Changlings, but can be used in other modes
|
||||
// var/obj/effect/proc_holder/changpower/list/power_list = list()
|
||||
|
||||
@@ -92,8 +92,8 @@
|
||||
|
||||
/mob/living/silicon/ai/isAI()
|
||||
return 1
|
||||
|
||||
/mob/proc/isRobot()
|
||||
|
||||
/mob/proc/isRobot()
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/robot/isRobot()
|
||||
@@ -108,6 +108,15 @@
|
||||
/mob/living/silicon/isSynthetic()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/isMonkey()
|
||||
return istype(species, /datum/species/monkey)
|
||||
|
||||
/mob/proc/isMonkey()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/isMonkey()
|
||||
return istype(species, /datum/species/monkey)
|
||||
|
||||
/proc/ispAI(A)
|
||||
if(istype(A, /mob/living/silicon/pai))
|
||||
return 1
|
||||
|
||||
@@ -474,6 +474,7 @@
|
||||
|
||||
// Do the initial caching of the player's body icons.
|
||||
new_character.force_update_limbs()
|
||||
new_character.update_eyes()
|
||||
new_character.regenerate_icons()
|
||||
|
||||
new_character.key = key //Manually transfer the key to log them in
|
||||
|
||||
7
code/modules/nano/interaction/admin.dm
Normal file
7
code/modules/nano/interaction/admin.dm
Normal file
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
This state checks that the user is an admin, end of story
|
||||
*/
|
||||
/var/global/datum/topic_state/admin_state/admin_state = new()
|
||||
|
||||
/datum/topic_state/admin_state/can_use_topic(var/src_object, var/mob/user)
|
||||
return check_rights(R_ADMIN, 0, user) ? STATUS_INTERACTIVE : STATUS_CLOSE
|
||||
19
code/modules/nano/interaction/base.dm
Normal file
19
code/modules/nano/interaction/base.dm
Normal file
@@ -0,0 +1,19 @@
|
||||
/atom/proc/nano_host()
|
||||
return src
|
||||
|
||||
/atom/proc/CanUseTopic(var/mob/user, var/datum/topic_state/state)
|
||||
var/src_object = nano_host()
|
||||
return state.can_use_topic(src_object, user)
|
||||
|
||||
/datum/topic_state/proc/href_list(var/mob/user)
|
||||
return list()
|
||||
|
||||
/datum/topic_state/proc/can_use_topic(var/src_object, var/mob/user)
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
/mob/proc/shared_nano_interaction()
|
||||
if (src.stat || !client)
|
||||
return STATUS_CLOSE // no updates, close the interface
|
||||
else if (restrained() || lying || stat || stunned || weakened)
|
||||
return STATUS_UPDATE // update only (orange visibility)
|
||||
return STATUS_INTERACTIVE
|
||||
18
code/modules/nano/interaction/contained.dm
Normal file
18
code/modules/nano/interaction/contained.dm
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
This state checks if user is somewhere within src_object, as well as the default NanoUI interaction.
|
||||
*/
|
||||
/var/global/datum/topic_state/contained_state/contained_state = new()
|
||||
|
||||
/datum/topic_state/contained_state/can_use_topic(var/atom/src_object, var/mob/user)
|
||||
if(!src_object.contains(src))
|
||||
return STATUS_CLOSE
|
||||
|
||||
return user.shared_nano_interaction()
|
||||
|
||||
/atom/proc/contains(var/atom/location)
|
||||
if(!location)
|
||||
return 0
|
||||
if(location == src)
|
||||
return 1
|
||||
|
||||
return contains(location.loc)
|
||||
@@ -1,41 +1,36 @@
|
||||
/atom/proc/nano_host()
|
||||
return src
|
||||
/var/global/datum/topic_state/default_state = new()
|
||||
|
||||
/obj/nano_module/nano_host()
|
||||
return loc
|
||||
/datum/topic_state/default/href_list(var/mob/user)
|
||||
return list()
|
||||
|
||||
/datum/topic_state/default/can_use_topic(var/src_object, var/mob/user)
|
||||
return user.default_can_use_topic(src_object)
|
||||
|
||||
/atom/proc/CanUseTopic(var/mob/user, href_list, var/datum/topic_state/custom_state)
|
||||
return user.can_use_topic(nano_host(), custom_state)
|
||||
|
||||
|
||||
/mob/proc/can_use_topic(var/mob/user, var/datum/topic_state/custom_state)
|
||||
/mob/proc/default_can_use_topic(var/src_object)
|
||||
return STATUS_CLOSE // By default no mob can do anything with NanoUI
|
||||
|
||||
/mob/dead/observer/can_use_topic()
|
||||
/mob/dead/observer/default_can_use_topic()
|
||||
if(check_rights(R_ADMIN, 0, src))
|
||||
return STATUS_INTERACTIVE // Admins are more equal
|
||||
return STATUS_UPDATE // Ghosts can view updates
|
||||
|
||||
/mob/living/silicon/pai/can_use_topic(var/src_object)
|
||||
/mob/living/silicon/pai/default_can_use_topic(var/src_object)
|
||||
if(src_object == src && !stat)
|
||||
return STATUS_INTERACTIVE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/can_use_topic(var/src_object, var/datum/topic_state/custom_state)
|
||||
/mob/living/silicon/robot/default_can_use_topic(var/src_object)
|
||||
if(stat || !client)
|
||||
return STATUS_CLOSE
|
||||
if(lockcharge || stunned || weakened)
|
||||
return STATUS_DISABLED
|
||||
if(custom_state.flags & NANO_IGNORE_DISTANCE)
|
||||
return STATUS_INTERACTIVE
|
||||
// robots can interact with things they can see within their view range
|
||||
if((src_object in view(src)) && get_dist(src_object, src) <= src.client.view)
|
||||
return STATUS_INTERACTIVE // interactive (green visibility)
|
||||
return STATUS_DISABLED // no updates, completely disabled (red visibility)
|
||||
|
||||
/mob/living/silicon/robot/syndicate/can_use_topic(var/src_object)
|
||||
/mob/living/silicon/robot/syndicate/default_can_use_topic(var/src_object)
|
||||
. = ..()
|
||||
if(. != STATUS_INTERACTIVE)
|
||||
return
|
||||
@@ -50,7 +45,7 @@
|
||||
return STATUS_INTERACTIVE
|
||||
return STATUS_UPDATE
|
||||
|
||||
/mob/living/silicon/ai/can_use_topic(var/src_object)
|
||||
/mob/living/silicon/ai/default_can_use_topic(var/src_object)
|
||||
if(!client || check_unable(1))
|
||||
return STATUS_CLOSE
|
||||
// Prevents the AI from using Topic on admin levels (by for example viewing through the court/thunderdome cameras)
|
||||
@@ -70,27 +65,16 @@
|
||||
if(cameranet && !cameranet.checkTurfVis(get_turf(src_object)))
|
||||
return apc_override ? STATUS_INTERACTIVE : STATUS_CLOSE
|
||||
return STATUS_INTERACTIVE
|
||||
else if(get_dist(src_object, src) <= client.view) // View does not return what one would expect while installed in an inteliCard
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
return STATUS_CLOSE
|
||||
|
||||
/mob/living/proc/shared_living_nano_interaction(var/src_object)
|
||||
if (src.stat != CONSCIOUS)
|
||||
return STATUS_CLOSE // no updates, close the interface
|
||||
else if (restrained() || lying || stat || stunned || weakened)
|
||||
return STATUS_UPDATE // update only (orange visibility)
|
||||
return STATUS_INTERACTIVE
|
||||
return STATUS_CLOSE
|
||||
|
||||
//Some atoms such as vehicles might have special rules for how mobs inside them interact with NanoUI.
|
||||
/atom/proc/contents_nano_distance(var/src_object, var/mob/living/user)
|
||||
return user.shared_living_nano_distance(src_object)
|
||||
|
||||
/mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object)
|
||||
if(!isturf(src_object.loc))
|
||||
if(src_object.loc == src) // Item in the inventory
|
||||
return STATUS_INTERACTIVE
|
||||
if(src.contents.Find(src_object.loc)) // A hidden uplink inside an item
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
if (!(src_object in view(4, src))) // If the src object is not in visable, disable updates
|
||||
return STATUS_CLOSE
|
||||
|
||||
@@ -103,27 +87,17 @@
|
||||
return STATUS_DISABLED // no updates, completely disabled (red visibility)
|
||||
return STATUS_CLOSE
|
||||
|
||||
/mob/living/can_use_topic(var/src_object, var/datum/topic_state/custom_state)
|
||||
. = shared_living_nano_interaction(src_object)
|
||||
if(. == STATUS_INTERACTIVE && !(custom_state.flags & NANO_IGNORE_DISTANCE))
|
||||
/mob/living/default_can_use_topic(var/src_object)
|
||||
. = shared_nano_interaction(src_object)
|
||||
if(. == STATUS_INTERACTIVE)
|
||||
if(loc)
|
||||
. = loc.contents_nano_distance(src_object, src)
|
||||
else
|
||||
. = shared_living_nano_distance(src_object)
|
||||
if(STATUS_INTERACTIVE)
|
||||
return STATUS_UPDATE
|
||||
|
||||
/mob/living/carbon/human/can_use_topic(var/src_object, var/datum/topic_state/custom_state)
|
||||
. = shared_living_nano_interaction(src_object)
|
||||
if(. == STATUS_INTERACTIVE && !(custom_state.flags & NANO_IGNORE_DISTANCE))
|
||||
/mob/living/carbon/human/default_can_use_topic(var/src_object)
|
||||
. = shared_nano_interaction(src_object)
|
||||
if(. == STATUS_INTERACTIVE)
|
||||
. = shared_living_nano_distance(src_object)
|
||||
if(. == STATUS_UPDATE && (TK in mutations)) // If we have telekinesis and remain close enough, allow interaction.
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
/var/global/datum/topic_state/default_state = new()
|
||||
|
||||
/datum/topic_state
|
||||
var/flags = 0
|
||||
|
||||
/datum/topic_state/proc/href_list(var/mob/user)
|
||||
return list()
|
||||
10
code/modules/nano/interaction/inventory.dm
Normal file
10
code/modules/nano/interaction/inventory.dm
Normal file
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
This state checks that the src_object is somewhere in the user's first-level inventory (in hands, on ear, etc.), but not further down (such as in bags).
|
||||
*/
|
||||
/var/global/datum/topic_state/inventory_state/inventory_state = new()
|
||||
|
||||
/datum/topic_state/inventory_state/can_use_topic(var/src_object, var/mob/user)
|
||||
if(!(src_object in src))
|
||||
return STATUS_CLOSE
|
||||
|
||||
return user.shared_nano_interaction()
|
||||
13
code/modules/nano/interaction/zlevel.dm
Normal file
13
code/modules/nano/interaction/zlevel.dm
Normal file
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
This state checks that the user is on the same Z-level as src_object
|
||||
*/
|
||||
|
||||
/var/global/datum/topic_state/z_state/z_state = new()
|
||||
|
||||
/datum/topic_state/z_state/can_use_topic(var/src_object, var/mob/user)
|
||||
var/turf/turf_obj = get_turf(src_object)
|
||||
var/turf/turf_usr = get_turf(user)
|
||||
if(!turf_obj || !turf_usr)
|
||||
return STATUS_CLOSE
|
||||
|
||||
return turf_obj.z == turf_usr.z ? STATUS_INTERACTIVE : STATUS_CLOSE
|
||||
@@ -85,7 +85,7 @@
|
||||
"origin_lost" = A.origin == null,
|
||||
"has_cameras" = cameras.len,
|
||||
"cameras" = cameras,
|
||||
"lost_sources" = sanitize(english_list(lost_sources, nothing_text = "", and_text = ", "))))
|
||||
"lost_sources" = lost_sources.len ? sanitize(english_list(lost_sources, nothing_text = "", and_text = ", ")) : ""))
|
||||
data["categories"] = categories
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
src.whitelist = species_whitelist
|
||||
src.blacklist = species_blacklist
|
||||
|
||||
/obj/nano_module/appearance_changer/Topic(ref, href_list)
|
||||
/obj/nano_module/appearance_changer/Topic(ref, href_list, var/nowindow, var/datum/topic_state/state = default_state)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
@@ -35,13 +35,13 @@
|
||||
if(href_list["skin_tone"])
|
||||
if(can_change_skin_tone())
|
||||
var/new_s_tone = input(usr, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Skin Tone", owner.s_tone) as num|null
|
||||
if(isnum(new_s_tone) && CanUseTopic(usr) == STATUS_INTERACTIVE)
|
||||
if(isnum(new_s_tone) && can_still_topic(state))
|
||||
new_s_tone = 35 - max(min( round(new_s_tone), 220),1)
|
||||
return owner.change_skin_tone(new_s_tone)
|
||||
if(href_list["skin_color"])
|
||||
if(can_change_skin_color())
|
||||
var/new_skin = input(usr, "Choose your character's skin colour: ", "Skin Color", rgb(owner.r_skin, owner.g_skin, owner.b_skin)) as color|null
|
||||
if(new_skin && can_still_topic())
|
||||
if(new_skin && can_still_topic(state))
|
||||
var/r_skin = hex2num(copytext(new_skin, 2, 4))
|
||||
var/g_skin = hex2num(copytext(new_skin, 4, 6))
|
||||
var/b_skin = hex2num(copytext(new_skin, 6, 8))
|
||||
@@ -56,7 +56,7 @@
|
||||
if(href_list["hair_color"])
|
||||
if(can_change(APPEARANCE_HAIR_COLOR))
|
||||
var/new_hair = input("Please select hair color.", "Hair Color", rgb(owner.r_hair, owner.g_hair, owner.b_hair)) as color|null
|
||||
if(new_hair && can_still_topic())
|
||||
if(new_hair && can_still_topic(state))
|
||||
var/r_hair = hex2num(copytext(new_hair, 2, 4))
|
||||
var/g_hair = hex2num(copytext(new_hair, 4, 6))
|
||||
var/b_hair = hex2num(copytext(new_hair, 6, 8))
|
||||
@@ -71,7 +71,7 @@
|
||||
if(href_list["facial_hair_color"])
|
||||
if(can_change(APPEARANCE_FACIAL_HAIR_COLOR))
|
||||
var/new_facial = input("Please select facial hair color.", "Facial Hair Color", rgb(owner.r_facial, owner.g_facial, owner.b_facial)) as color|null
|
||||
if(new_facial && can_still_topic())
|
||||
if(new_facial && can_still_topic(state))
|
||||
var/r_facial = hex2num(copytext(new_facial, 2, 4))
|
||||
var/g_facial = hex2num(copytext(new_facial, 4, 6))
|
||||
var/b_facial = hex2num(copytext(new_facial, 6, 8))
|
||||
@@ -81,7 +81,7 @@
|
||||
if(href_list["eye_color"])
|
||||
if(can_change(APPEARANCE_EYE_COLOR))
|
||||
var/new_eyes = input("Please select eye color.", "Eye Color", rgb(owner.r_eyes, owner.g_eyes, owner.b_eyes)) as color|null
|
||||
if(new_eyes && can_still_topic())
|
||||
if(new_eyes && can_still_topic(state))
|
||||
var/r_eyes = hex2num(copytext(new_eyes, 2, 4))
|
||||
var/g_eyes = hex2num(copytext(new_eyes, 4, 6))
|
||||
var/b_eyes = hex2num(copytext(new_eyes, 6, 8))
|
||||
@@ -91,7 +91,7 @@
|
||||
|
||||
return 0
|
||||
|
||||
/obj/nano_module/appearance_changer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
/obj/nano_module/appearance_changer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
generate_data(check_whitelist, whitelist, blacklist)
|
||||
var/data[0]
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR)
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "appearance_changer.tmpl", "[src.name]", 800, 450)
|
||||
ui = new(user, src, ui_key, "appearance_changer.tmpl", "[src.name]", 800, 450, state = state)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
|
||||
return 0
|
||||
|
||||
/obj/nano_module/law_manager/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
/obj/nano_module/law_manager/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
var/data[0]
|
||||
owner.lawsync()
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "law_manager.tmpl", sanitize("[src] - [owner]"), 800, is_malf(user) ? 600 : 400)
|
||||
ui = new(user, src, ui_key, "law_manager.tmpl", sanitize("[src] - [owner]"), 800, is_malf(user) ? 600 : 400, state = state)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
/obj/nano_module/proc/can_still_topic()
|
||||
return CanUseTopic(usr, list(), default_state) == STATUS_INTERACTIVE
|
||||
/obj/nano_module/nano_host()
|
||||
return loc
|
||||
|
||||
/obj/nano_module/proc/can_still_topic(var/datum/topic_state/state = default_state)
|
||||
return CanUseTopic(usr, state) == STATUS_INTERACTIVE
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/atom/movable/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/nano_ui/master_ui = null, var/datum/topic_state/custom_state = null)
|
||||
/atom/movable/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/nano_ui/master_ui = null, var/datum/topic_state/state = default_state)
|
||||
return
|
||||
|
||||
// Used by the Nano UI Manager (/datum/nanomanager) to track UIs opened by this mob
|
||||
|
||||
@@ -55,7 +55,7 @@ nanoui is used to open and update nano browser uis
|
||||
// Relationship between a master interface and its children. Used in update_status
|
||||
var/datum/nanoui/master_ui
|
||||
var/list/datum/nanoui/children = list()
|
||||
var/datum/topic_state/custom_state = null
|
||||
var/datum/topic_state/state = null
|
||||
|
||||
var/cached_data = null
|
||||
|
||||
@@ -73,7 +73,7 @@ nanoui is used to open and update nano browser uis
|
||||
*
|
||||
* @return /nanoui new nanoui object
|
||||
*/
|
||||
/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, var/datum/nanoui/master_ui = null, var/datum/topic_state/custom_state = default_state)
|
||||
/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, var/datum/nanoui/master_ui = null, var/datum/topic_state/state = default_state)
|
||||
user = nuser
|
||||
src_object = nsrc_object
|
||||
ui_key = nui_key
|
||||
@@ -82,7 +82,7 @@ nanoui is used to open and update nano browser uis
|
||||
src.master_ui = master_ui
|
||||
if(master_ui)
|
||||
master_ui.children += src
|
||||
src.custom_state = custom_state
|
||||
src.state = state
|
||||
|
||||
// add the passed template filename as the "main" template, this is required
|
||||
add_template("main", ntemplate_filename)
|
||||
@@ -142,8 +142,7 @@ nanoui is used to open and update nano browser uis
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/update_status(var/push_update = 0)
|
||||
var/atom/movable/host = src_object.nano_host()
|
||||
var/new_status = host.CanUseTopic(user, list(), custom_state)
|
||||
var/new_status = src_object.CanUseTopic(user, state)
|
||||
if(master_ui)
|
||||
new_status = min(new_status, master_ui.status)
|
||||
|
||||
@@ -483,7 +482,7 @@ nanoui is used to open and update nano browser uis
|
||||
set_map_z_level(text2num(href_list["mapZLevel"]))
|
||||
map_update = 1
|
||||
|
||||
if ((src_object && src_object.Topic(href, href_list, 0, custom_state)) || map_update)
|
||||
if ((src_object && src_object.Topic(href, href_list, 0, state)) || map_update)
|
||||
nanomanager.update_uis(src_object) // update all UIs attached to src_object
|
||||
|
||||
/**
|
||||
@@ -510,4 +509,4 @@ nanoui is used to open and update nano browser uis
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/update(var/force_open = 0)
|
||||
src_object.ui_interact(user, ui_key, src, force_open, master_ui, custom_state)
|
||||
src_object.ui_interact(user, ui_key, src, force_open, master_ui, state)
|
||||
|
||||
@@ -3,7 +3,7 @@ var/list/organ_cache = list()
|
||||
/obj/item/organ
|
||||
name = "organ"
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
|
||||
var/dead_icon
|
||||
var/mob/living/carbon/human/owner = null
|
||||
var/status = 0
|
||||
var/vital //Lose a vital limb, die immediately.
|
||||
@@ -50,11 +50,12 @@ var/list/organ_cache = list()
|
||||
holder.internal_organs |= src
|
||||
|
||||
/obj/item/organ/proc/die()
|
||||
name = "dead [initial(name)]"
|
||||
health = 0
|
||||
if(status & ORGAN_ROBOT)
|
||||
return
|
||||
damage = max_damage
|
||||
processing_objects -= src
|
||||
//TODO: Grey out the icon state.
|
||||
//TODO: Inject an organ with peridaxon to make it alive again.
|
||||
if(dead_icon)
|
||||
icon_state = dead_icon
|
||||
|
||||
/obj/item/organ/process()
|
||||
|
||||
@@ -75,10 +76,10 @@ var/list/organ_cache = list()
|
||||
if(B && prob(40))
|
||||
reagents.remove_reagent("blood",0.1)
|
||||
blood_splatter(src,B,1)
|
||||
|
||||
health -= rand(1,3)
|
||||
if(health <= 0)
|
||||
damage += rand(1,3)
|
||||
if(damage >= max_damage)
|
||||
die()
|
||||
|
||||
else if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
|
||||
//** Handle antibiotics and curing infections
|
||||
handle_antibiotics()
|
||||
@@ -179,9 +180,10 @@ var/list/organ_cache = list()
|
||||
else
|
||||
src.damage += amount
|
||||
|
||||
var/obj/item/organ/external/parent = owner.get_organ(parent_organ)
|
||||
if (!silent)
|
||||
owner.custom_pain("Something inside your [parent.name] hurts a lot.", 1)
|
||||
if(owner && parent_organ)
|
||||
var/obj/item/organ/external/parent = owner.get_organ(parent_organ)
|
||||
if(parent && !silent)
|
||||
owner.custom_pain("Something inside your [parent.name] hurts a lot.", 1)
|
||||
|
||||
/obj/item/organ/proc/robotize() //Being used to make robutt hearts, etc
|
||||
robotic = 2
|
||||
@@ -241,7 +243,7 @@ var/list/organ_cache = list()
|
||||
var/obj/item/organ/external/affected = owner.get_organ(parent_organ)
|
||||
if(affected) affected.internal_organs -= src
|
||||
|
||||
loc = owner.loc
|
||||
loc = get_turf(owner)
|
||||
processing_objects |= src
|
||||
rejecting = null
|
||||
var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in reagents.reagent_list
|
||||
@@ -255,6 +257,8 @@ var/list/organ_cache = list()
|
||||
msg_admin_attack("[user.name] ([user.ckey]) removed a vital organ ([src]) from [owner.name] ([owner.ckey]) (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
owner.death()
|
||||
|
||||
owner = null
|
||||
|
||||
/obj/item/organ/proc/replaced(var/mob/living/carbon/human/target,var/obj/item/organ/external/affected)
|
||||
|
||||
if(!istype(target)) return
|
||||
@@ -271,13 +275,13 @@ var/list/organ_cache = list()
|
||||
transplant_data["blood_DNA"] = transplant_blood.data["blood_DNA"]
|
||||
|
||||
owner = target
|
||||
loc = owner
|
||||
processing_objects -= src
|
||||
target.internal_organs |= src
|
||||
affected.internal_organs |= src
|
||||
target.internal_organs_by_name[organ_tag] = src
|
||||
status |= ORGAN_CUT_AWAY
|
||||
|
||||
del(src)
|
||||
if(robotic)
|
||||
status |= ORGAN_ROBOT
|
||||
|
||||
/obj/item/organ/eyes/replaced(var/mob/living/carbon/human/target)
|
||||
|
||||
@@ -286,7 +290,7 @@ var/list/organ_cache = list()
|
||||
target.r_eyes = eye_colour[1]
|
||||
target.g_eyes = eye_colour[2]
|
||||
target.b_eyes = eye_colour[3]
|
||||
target.update_body()
|
||||
target.update_eyes()
|
||||
..()
|
||||
|
||||
/obj/item/organ/proc/bitten(mob/user)
|
||||
@@ -298,7 +302,6 @@ var/list/organ_cache = list()
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list
|
||||
blood_splatter(src,B,1)
|
||||
|
||||
|
||||
user.drop_from_inventory(src)
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/organ/O = new(get_turf(src))
|
||||
O.name = name
|
||||
|
||||
@@ -96,9 +96,14 @@
|
||||
dislocated = 0
|
||||
if(children && children.len)
|
||||
for(var/obj/item/organ/external/child in children)
|
||||
child.undislocate()
|
||||
if(child.dislocated == 1)
|
||||
child.undislocate()
|
||||
if(owner)
|
||||
owner.shock_stage += 20
|
||||
for(var/obj/item/organ/external/limb in owner.organs)
|
||||
if(limb.dislocated == 2)
|
||||
return
|
||||
owner.verbs -= /mob/living/carbon/human/proc/undislocate
|
||||
|
||||
/obj/item/organ/external/update_health()
|
||||
damage = min(max_damage, (brute_dam + burn_dam))
|
||||
@@ -110,6 +115,8 @@
|
||||
if(owner)
|
||||
replaced(owner)
|
||||
sync_colour_to_human(owner)
|
||||
spawn(1)
|
||||
get_icon()
|
||||
|
||||
/obj/item/organ/external/replaced(var/mob/living/carbon/human/target)
|
||||
owner = target
|
||||
@@ -243,10 +250,10 @@
|
||||
status &= ~ORGAN_BROKEN
|
||||
perma_injury = 0
|
||||
|
||||
if((brute || burn) && children && children.len && (owner.species.flags & REGENERATES_LIMBS))
|
||||
/*if((brute || burn) && children && children.len && (owner.species.flags & REGENERATES_LIMBS))
|
||||
var/obj/item/organ/external/stump/S = locate() in children
|
||||
if(S)
|
||||
world << "Extra healing to go around ([brute+burn]) and [owner] needs a replacement limb."
|
||||
world << "Extra healing to go around ([brute+burn]) and [owner] needs a replacement limb."*/
|
||||
|
||||
//Sync the organ's damage with its wounds
|
||||
src.update_damages()
|
||||
@@ -638,8 +645,9 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
"<span class='moderate'><b>Your [src.name] explodes in a shower of gore!</b></span>",\
|
||||
"<span class='danger'>You hear the sickening splatter of gore.</span>")
|
||||
|
||||
src.removed(null, ignore_children)
|
||||
owner.traumatic_shock += 60
|
||||
var/mob/living/carbon/human/victim = owner //Keep a reference for post-removed().
|
||||
removed(null, ignore_children)
|
||||
victim.traumatic_shock += 60
|
||||
|
||||
wounds.Cut()
|
||||
if(parent)
|
||||
@@ -653,22 +661,22 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
parent.wounds |= W
|
||||
parent.update_damages()
|
||||
else
|
||||
var/obj/item/organ/external/stump/stump = new (owner, 0, src)
|
||||
var/obj/item/organ/external/stump/stump = new (victim, 0, src)
|
||||
stump.wounds |= W
|
||||
owner.organs |= stump
|
||||
victim.organs |= stump
|
||||
stump.update_damages()
|
||||
parent = null
|
||||
|
||||
spawn(1)
|
||||
owner.update_body()
|
||||
owner.updatehealth()
|
||||
owner.UpdateDamageIcon()
|
||||
victim.updatehealth()
|
||||
victim.UpdateDamageIcon()
|
||||
victim.regenerate_icons()
|
||||
dir = 2
|
||||
|
||||
switch(disintegrate)
|
||||
if(DROPLIMB_EDGE)
|
||||
compile_icon()
|
||||
add_blood(owner)
|
||||
add_blood(victim)
|
||||
var/matrix/M = matrix()
|
||||
M.Turn(rand(180))
|
||||
src.transform = M
|
||||
@@ -679,13 +687,13 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
dir = 2
|
||||
return
|
||||
if(DROPLIMB_BURN)
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(owner))
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(victim))
|
||||
if(DROPLIMB_BLUNT)
|
||||
var/obj/effect/decal/cleanable/blood/gibs/gore = new owner.species.single_gib_type(get_turf(owner))
|
||||
if(owner.species.flesh_color)
|
||||
gore.fleshcolor = owner.species.flesh_color
|
||||
if(owner.species.blood_color)
|
||||
gore.basecolor = owner.species.blood_color
|
||||
var/obj/effect/decal/cleanable/blood/gibs/gore = new owner.species.single_gib_type(get_turf(victim))
|
||||
if(victim.species.flesh_color)
|
||||
gore.fleshcolor = victim.species.flesh_color
|
||||
if(victim.species.blood_color)
|
||||
gore.basecolor = victim.species.blood_color
|
||||
gore.update_icon()
|
||||
gore.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
|
||||
|
||||
@@ -703,25 +711,21 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
/obj/item/organ/external/proc/is_stump()
|
||||
return 0
|
||||
|
||||
/obj/item/organ/external/replaced()
|
||||
get_icon()
|
||||
icon = mob_icon
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/external/proc/release_restraints()
|
||||
if (owner.handcuffed && body_part in list(ARM_LEFT, ARM_RIGHT, HAND_LEFT, HAND_RIGHT))
|
||||
owner.visible_message(\
|
||||
"\The [owner.handcuffed.name] falls off of [owner.name].",\
|
||||
"\The [owner.handcuffed.name] falls off you.")
|
||||
|
||||
owner.drop_from_inventory(owner.handcuffed)
|
||||
|
||||
if (owner.legcuffed && body_part in list(FOOT_LEFT, FOOT_RIGHT, LEG_LEFT, LEG_RIGHT))
|
||||
owner.visible_message(\
|
||||
"\The [owner.legcuffed.name] falls off of [owner.name].",\
|
||||
"\The [owner.legcuffed.name] falls off you.")
|
||||
|
||||
owner.drop_from_inventory(owner.legcuffed)
|
||||
/obj/item/organ/external/proc/release_restraints(var/mob/living/carbon/human/holder)
|
||||
if(!holder)
|
||||
holder = owner
|
||||
if(!holder)
|
||||
return
|
||||
if (holder.handcuffed && body_part in list(ARM_LEFT, ARM_RIGHT, HAND_LEFT, HAND_RIGHT))
|
||||
holder.visible_message(\
|
||||
"\The [holder.handcuffed.name] falls off of [holder.name].",\
|
||||
"\The [holder.handcuffed.name] falls off you.")
|
||||
holder.drop_from_inventory(holder.handcuffed)
|
||||
if (holder.legcuffed && body_part in list(FOOT_LEFT, FOOT_RIGHT, LEG_LEFT, LEG_RIGHT))
|
||||
holder.visible_message(\
|
||||
"\The [holder.legcuffed.name] falls off of [holder.name].",\
|
||||
"\The [holder.legcuffed.name] falls off you.")
|
||||
holder.drop_from_inventory(holder.legcuffed)
|
||||
|
||||
/obj/item/organ/external/proc/bandage()
|
||||
var/rval = 0
|
||||
@@ -842,7 +846,7 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
return 0
|
||||
|
||||
/obj/item/organ/external/proc/is_usable()
|
||||
return !(status & (ORGAN_DESTROYED|ORGAN_MUTATED|ORGAN_DEAD))
|
||||
return !is_dislocated() && !(status & (ORGAN_DESTROYED|ORGAN_MUTATED|ORGAN_DEAD))
|
||||
|
||||
/obj/item/organ/external/proc/is_malfunctioning()
|
||||
return ((status & ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam))
|
||||
@@ -863,11 +867,15 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
|
||||
/obj/item/organ/external/removed(var/mob/living/user, var/ignore_children)
|
||||
|
||||
if(!owner)
|
||||
return
|
||||
var/is_robotic = status & ORGAN_ROBOT
|
||||
var/mob/living/carbon/human/victim = owner
|
||||
|
||||
..()
|
||||
|
||||
status |= ORGAN_DESTROYED
|
||||
owner.bad_external_organs -= src
|
||||
victim.bad_external_organs -= src
|
||||
|
||||
for(var/implant in implants) //todo: check if this can be left alone
|
||||
del(implant)
|
||||
@@ -884,19 +892,19 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
organ.removed()
|
||||
organ.loc = src
|
||||
|
||||
release_restraints()
|
||||
owner.organs -= src
|
||||
owner.organs_by_name[limb_name] = null // Remove from owner's vars.
|
||||
release_restraints(victim)
|
||||
victim.organs -= src
|
||||
victim.organs_by_name[limb_name] = null // Remove from owner's vars.
|
||||
|
||||
//Robotic limbs explode if sabotaged.
|
||||
if(is_robotic && sabotaged)
|
||||
owner.visible_message(
|
||||
"<span class='danger'>\The [owner]'s [src.name] explodes violently!</span>",\
|
||||
victim.visible_message(
|
||||
"<span class='danger'>\The [victim]'s [src.name] explodes violently!</span>",\
|
||||
"<span class='danger'>Your [src.name] explodes!</span>",\
|
||||
"<span class='danger'>You hear an explosion!</span>")
|
||||
explosion(get_turf(owner),-1,-1,2,3)
|
||||
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
|
||||
spark_system.set_up(5, 0, owner)
|
||||
spark_system.set_up(5, 0, victim)
|
||||
spark_system.attach(owner)
|
||||
spark_system.start()
|
||||
spawn(10)
|
||||
|
||||
@@ -5,13 +5,12 @@ var/global/list/limb_icon_cache = list()
|
||||
|
||||
/obj/item/organ/external/proc/compile_icon()
|
||||
overlays.Cut()
|
||||
get_icon()
|
||||
// This is a kludge, only one icon has more than one generation of children though.
|
||||
for(var/obj/item/organ/external/organ in contents)
|
||||
if(organ.children && organ.children.len)
|
||||
for(var/obj/item/organ/external/child in organ.children)
|
||||
overlays += child.get_icon()
|
||||
overlays += organ.get_icon()
|
||||
overlays += child.mob_icon
|
||||
overlays += organ.mob_icon
|
||||
|
||||
/obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/human)
|
||||
s_tone = null
|
||||
@@ -23,6 +22,49 @@ var/global/list/limb_icon_cache = list()
|
||||
if(human.species.flags & HAS_SKIN_COLOR)
|
||||
s_col = list(human.r_skin, human.g_skin, human.b_skin)
|
||||
|
||||
/obj/item/organ/external/head/sync_colour_to_human(var/mob/living/carbon/human/human)
|
||||
..()
|
||||
var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"]
|
||||
if(eyes) eyes.update_colour()
|
||||
|
||||
/obj/item/organ/external/head/removed()
|
||||
get_icon()
|
||||
..()
|
||||
|
||||
/obj/item/organ/external/head/get_icon()
|
||||
|
||||
..()
|
||||
if(owner.species.has_organ["eyes"])
|
||||
var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"]
|
||||
if(owner.species.eyes)
|
||||
var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', owner.species.eyes)
|
||||
if(eyes)
|
||||
eyes_icon.Blend(rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3]), ICON_ADD)
|
||||
else
|
||||
eyes_icon.Blend(rgb(128,0,0), ICON_ADD)
|
||||
mob_icon.Blend(eyes_icon, ICON_OVERLAY)
|
||||
|
||||
if(owner.lip_style && (owner.species && (owner.species.flags & HAS_LIPS)))
|
||||
mob_icon.Blend(new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s"), ICON_OVERLAY)
|
||||
|
||||
if(owner.f_style)
|
||||
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style]
|
||||
if(facial_hair_style && facial_hair_style.species_allowed && (owner.species.name in facial_hair_style.species_allowed))
|
||||
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
|
||||
if(facial_hair_style.do_colouration)
|
||||
facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD)
|
||||
overlays |= facial_s
|
||||
|
||||
if(owner.h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR)))
|
||||
var/datum/sprite_accessory/hair_style = hair_styles_list[owner.h_style]
|
||||
if(hair_style && (owner.species.name in hair_style.species_allowed))
|
||||
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
|
||||
if(hair_style.do_colouration)
|
||||
hair_s.Blend(rgb(owner.r_hair, owner.g_hair, owner.b_hair), ICON_ADD)
|
||||
overlays |= hair_s
|
||||
|
||||
return mob_icon
|
||||
|
||||
/obj/item/organ/external/proc/get_icon(var/skeletal)
|
||||
|
||||
var/gender
|
||||
@@ -66,43 +108,6 @@ var/global/list/limb_icon_cache = list()
|
||||
|
||||
return mob_icon
|
||||
|
||||
/obj/item/organ/external/head/get_icon(var/skeletal)
|
||||
|
||||
if(skeletal || !owner)
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
if(owner.species.has_organ["eyes"])
|
||||
var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"]
|
||||
if(eyes && owner.species.eyes)
|
||||
var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', owner.species.eyes)
|
||||
eyes_icon.Blend(rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3]), ICON_ADD)
|
||||
mob_icon.Blend(eyes_icon, ICON_OVERLAY)
|
||||
|
||||
if(owner.lip_style && (owner.species && (owner.species.flags & HAS_LIPS)))
|
||||
mob_icon.Blend(new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s"), ICON_OVERLAY)
|
||||
|
||||
if(owner.f_style)
|
||||
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style]
|
||||
if(facial_hair_style)
|
||||
var/icon/facial = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
|
||||
if(facial_hair_style.do_colouration)
|
||||
facial.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD)
|
||||
mob_icon.Blend(facial, ICON_OVERLAY)
|
||||
|
||||
if(owner.h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR)))
|
||||
var/datum/sprite_accessory/hair_style = hair_styles_list[owner.h_style]
|
||||
if(hair_style)
|
||||
var/icon/hair = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
|
||||
if(hair_style.do_colouration)
|
||||
hair.Blend(rgb(owner.r_hair, owner.g_hair, owner.b_hair), ICON_ADD)
|
||||
|
||||
mob_icon.Blend(hair, ICON_OVERLAY)
|
||||
|
||||
icon = mob_icon
|
||||
return mob_icon
|
||||
|
||||
// new damage icon system
|
||||
// adjusted to set damage_state to brute/burn code only (without r_name0 as before)
|
||||
/obj/item/organ/external/update_icon()
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
icon_state = "heart-on"
|
||||
organ_tag = "heart"
|
||||
parent_organ = "chest"
|
||||
dead_icon = "heart-off"
|
||||
|
||||
/obj/item/organ/lungs
|
||||
name = "lungs"
|
||||
@@ -69,6 +70,15 @@
|
||||
parent_organ = "head"
|
||||
var/list/eye_colour = list(0,0,0)
|
||||
|
||||
/obj/item/organ/eyes/proc/update_colour()
|
||||
if(!owner)
|
||||
return
|
||||
eye_colour = list(
|
||||
owner.r_eyes ? owner.r_eyes : 0,
|
||||
owner.g_eyes ? owner.g_eyes : 0,
|
||||
owner.b_eyes ? owner.b_eyes : 0
|
||||
)
|
||||
|
||||
/obj/item/organ/eyes/process() //Eye damage replaces the old eye_stat var.
|
||||
..()
|
||||
if(!owner)
|
||||
@@ -78,36 +88,6 @@
|
||||
if(is_broken())
|
||||
owner.eye_blind = 20
|
||||
|
||||
/obj/item/organ/eyes/New()
|
||||
..()
|
||||
if(owner)
|
||||
eye_colour = list(
|
||||
owner.r_eyes ? owner.r_eyes : 0,
|
||||
owner.g_eyes ? owner.g_eyes : 0,
|
||||
owner.b_eyes ? owner.b_eyes : 0
|
||||
)
|
||||
|
||||
/obj/item/organ/eyes/removed(var/mob/living/target,var/mob/living/user)
|
||||
|
||||
if(!eye_colour)
|
||||
eye_colour = list(0,0,0)
|
||||
|
||||
..() //Make sure target is set so we can steal their eye colour for later.
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(istype(H))
|
||||
eye_colour = list(
|
||||
H.r_eyes ? H.r_eyes : 0,
|
||||
H.g_eyes ? H.g_eyes : 0,
|
||||
H.b_eyes ? H.b_eyes : 0
|
||||
)
|
||||
|
||||
// Leave bloody red pits behind!
|
||||
H.r_eyes = 128
|
||||
H.g_eyes = 0
|
||||
H.b_eyes = 0
|
||||
H.update_body()
|
||||
|
||||
|
||||
/obj/item/organ/liver
|
||||
name = "liver"
|
||||
icon_state = "liver"
|
||||
@@ -178,14 +158,13 @@
|
||||
|
||||
/obj/item/organ/appendix/removed()
|
||||
|
||||
..()
|
||||
|
||||
var/inflamed = 0
|
||||
for(var/datum/disease/appendicitis/appendicitis in owner.viruses)
|
||||
inflamed = 1
|
||||
appendicitis.cure()
|
||||
owner.resistances += appendicitis
|
||||
|
||||
if(inflamed)
|
||||
icon_state = "appendixinflamed"
|
||||
name = "inflamed appendix"
|
||||
if(owner)
|
||||
var/inflamed = 0
|
||||
for(var/datum/disease/appendicitis/appendicitis in owner.viruses)
|
||||
inflamed = 1
|
||||
appendicitis.cure()
|
||||
owner.resistances += appendicitis
|
||||
if(inflamed)
|
||||
icon_state = "appendixinflamed"
|
||||
name = "inflamed appendix"
|
||||
..()
|
||||
@@ -209,9 +209,9 @@
|
||||
|
||||
/** WOUND DEFINITIONS **/
|
||||
|
||||
//Note that the MINIMUM damage before a wound can be applied should correspond to
|
||||
//Note that the MINIMUM damage before a wound can be applied should correspond to
|
||||
//the damage amount for the stage with the same name as the wound.
|
||||
//e.g. /datum/wound/cut/deep should only be applied for 15 damage and up,
|
||||
//e.g. /datum/wound/cut/deep should only be applied for 15 damage and up,
|
||||
//because in it's stages list, "deep cut" = 15.
|
||||
/proc/get_wound_type(var/type = CUT, var/damage)
|
||||
switch(type)
|
||||
@@ -323,4 +323,4 @@ datum/wound/cut/massive
|
||||
return 0 //cannot be merged
|
||||
|
||||
/datum/wound/lost_limb/small
|
||||
stages = list("ripped stump" = 40, "bloody stump" = 30, "clotted stump" = 15, "scarred stump" = 0)
|
||||
stages = list("ripped hole" = 40, "bloody hole" = 30, "clotted hole" = 15, "scarred hole" = 0)
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
if(mode)
|
||||
user << "<span class='notice'>You turn on \the [src].</span>"
|
||||
//Now let them chose the text.
|
||||
var/str = copytext(reject_bad_text(input(user,"Label text?","Set label","")),1,MAX_NAME_LEN)
|
||||
var/str = sanitizeSafe(input(user,"Label text?","Set label",""), MAX_NAME_LEN)
|
||||
if(!str || !length(str))
|
||||
user << "<span class='notice'>Invalid text.</span>"
|
||||
return
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user