mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-01-04 14:33:10 +00:00
Merge remote-tracking branch 'origin/dev' into ofBotsAndMobs
This commit is contained in:
@@ -670,6 +670,16 @@ var/global/floorIsLava = 0
|
||||
if(check_rights(R_SERVER,0))
|
||||
dat += "<A href='?src=\ref[src];secretsfun=togglebombcap'>Toggle bomb cap</A><BR>"
|
||||
|
||||
if(check_rights(R_SERVER|R_FUN,0))
|
||||
dat += {"
|
||||
<BR>
|
||||
<B>Final Solutions</B><BR>
|
||||
<I>(Warning, these will end the round!)</I><BR>
|
||||
<BR>
|
||||
<A href='?src=\ref[src];secretsfun=hellonearth'>Summon Nar-Sie</A><BR>
|
||||
<A href='?src=\ref[src];secretsfun=supermattercascade'>Start a Supermatter Cascade</A><BR>
|
||||
"}
|
||||
|
||||
dat += "<BR>"
|
||||
|
||||
if(check_rights(R_DEBUG,0))
|
||||
@@ -1245,3 +1255,28 @@ var/global/floorIsLava = 0
|
||||
//ALL DONE
|
||||
//*********************************************************************************************************
|
||||
//
|
||||
|
||||
/datum/admins/proc/cmd_ghost_drag(var/mob/dead/observer/frommob, var/mob/living/tomob)
|
||||
if(!istype(frommob))
|
||||
return //Extra sanity check to make sure only observers are shoved into things
|
||||
|
||||
//Same as assume-direct-control perm requirements.
|
||||
if (!check_rights(R_VAREDIT,0) || !check_rights(R_ADMIN|R_DEBUG,0))
|
||||
return 0
|
||||
if (!frommob.ckey)
|
||||
return 0
|
||||
var/question = ""
|
||||
if (tomob.ckey)
|
||||
question = "This mob already has a user ([tomob.key]) in control of it! "
|
||||
question += "Are you sure you want to place [frommob.name]([frommob.key]) in control of [tomob.name]?"
|
||||
var/ask = alert(question, "Place ghost in control of mob?", "Yes", "No")
|
||||
if (ask != "Yes")
|
||||
return 1
|
||||
if(tomob.client) //No need to ghostize if there is no client
|
||||
tomob.ghostize(0)
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has put [frommob.ckey] in control of [tomob.name].</span>")
|
||||
log_admin("[key_name(usr)] stuffed [frommob.ckey] into [tomob.name].")
|
||||
feedback_add_details("admin_verb","CGD")
|
||||
tomob.ckey = frommob.ckey
|
||||
qdel(frommob)
|
||||
return 1
|
||||
|
||||
@@ -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"])
|
||||
@@ -2251,6 +2257,33 @@
|
||||
feedback_add_details("admin_secrets_fun_used","OO")
|
||||
only_one()
|
||||
message_admins("[key_name_admin(usr)] has triggered a battle to the death (only one)")
|
||||
|
||||
if("togglenarsie")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","NA")
|
||||
var/choice = input("How do you wish for narsie to interact with her surroundings?") in list("CultStation13", "Nar-Singulo")
|
||||
if(choice == "CultStation13")
|
||||
message_admins("[key_name_admin(usr)] has set narsie's behaviour to \"CultStation13\".")
|
||||
narsie_behaviour = "CultStation13"
|
||||
if(choice == "Nar-Singulo")
|
||||
message_admins("[key_name_admin(usr)] has set narsie's behaviour to \"Nar-Singulo\".")
|
||||
narsie_behaviour = "Nar-Singulo"
|
||||
if("hellonearth")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","NS")
|
||||
var/choice = input("You sure you want to end the round and summon narsie at your location? Misuse of this could result in removal of flags or halarity.") in list("PRAISE SATAN", "Cancel")
|
||||
if(choice == "PRAISE SATAN")
|
||||
new /obj/machinery/singularity/narsie/large(get_turf(usr))
|
||||
message_admins("[key_name_admin(usr)] has summoned narsie and brought about a new realm of suffering.")
|
||||
if("supermattercascade")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","SC")
|
||||
var/choice = input("You sure you want to destroy the universe and create a large explosion at your location? Misuse of this could result in removal of flags or halarity.") in list("NO TIME TO EXPLAIN", "Cancel")
|
||||
if(choice == "NO TIME TO EXPLAIN")
|
||||
explosion(get_turf(usr), 8, 16, 24, 32, 1)
|
||||
new /turf/unsimulated/wall/supermatter(get_turf(usr))
|
||||
SetUniversalState(/datum/universal_state/supermatter_cascade)
|
||||
message_admins("[key_name_admin(usr)] has managed to destroy the universe with a supermatter cascade. Good job, [key_name_admin(usr)]")
|
||||
if(usr)
|
||||
log_admin("[key_name(usr)] used secret [href_list["secretsfun"]]")
|
||||
if (ok)
|
||||
@@ -2619,3 +2652,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"
|
||||
@@ -105,6 +107,9 @@
|
||||
max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
species_restricted = null
|
||||
|
||||
/obj/item/clothing/shoes/cult/cultify()
|
||||
return
|
||||
|
||||
/obj/item/clothing/shoes/cyborg
|
||||
name = "cyborg boots"
|
||||
desc = "Shoes for a cyborg costume"
|
||||
|
||||
@@ -105,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
|
||||
|
||||
@@ -303,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -55,6 +55,21 @@
|
||||
//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/examine(user)
|
||||
..(user)
|
||||
if(boots || helmet || tank)
|
||||
var/D = "Installed equipment: "
|
||||
var/first = 1
|
||||
for(var/obj/item/I in list(helmet,boots,tank))
|
||||
if (I)
|
||||
D += "[first?"":", "]\the [I]\icon[I]"
|
||||
first = 0
|
||||
D += "."
|
||||
user << D
|
||||
if(tank && in_range(src,user))
|
||||
user << "<span class='notice'>The wrist-mounted pressure gauge reads [max(round(tank.air_contents.return_pressure()),0)] kPa remaining in \the [tank].</span>"
|
||||
|
||||
/obj/item/clothing/suit/space/void/refit_for_species(var/target_species)
|
||||
..()
|
||||
@@ -87,6 +102,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()
|
||||
..()
|
||||
|
||||
@@ -108,6 +130,10 @@
|
||||
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()
|
||||
|
||||
set name = "Toggle Helmet"
|
||||
@@ -127,7 +153,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 +164,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 +199,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 +232,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"
|
||||
|
||||
@@ -29,6 +29,7 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
|
||||
var/image/ghostimage = null //this mobs ghost image, for deleting and stuff
|
||||
var/ghostvision = 1 //is the ghost able to see things humans can't?
|
||||
var/seedarkness = 1
|
||||
incorporeal_move = 1
|
||||
|
||||
/mob/dead/observer/New(mob/body)
|
||||
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
|
||||
@@ -193,29 +194,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
ghost.timeofdeath = world.time // Because the living mob won't have a time of death and we want the respawn timer to work properly.
|
||||
announce_ghost_joinleave(ghost)
|
||||
|
||||
|
||||
/mob/dead/observer/Move(NewLoc, direct)
|
||||
following = null
|
||||
set_dir(direct)
|
||||
if(NewLoc)
|
||||
loc = NewLoc
|
||||
for(var/obj/effect/step_trigger/S in NewLoc)
|
||||
S.Crossed(src)
|
||||
|
||||
return
|
||||
loc = get_turf(src) //Get out of closets and such as a ghost
|
||||
if((direct & NORTH) && y < world.maxy)
|
||||
y++
|
||||
else if((direct & SOUTH) && y > 1)
|
||||
y--
|
||||
if((direct & EAST) && x < world.maxx)
|
||||
x++
|
||||
else if((direct & WEST) && x > 1)
|
||||
x--
|
||||
|
||||
for(var/obj/effect/step_trigger/S in locate(x, y, z)) //<-- this is dumb
|
||||
S.Crossed(src)
|
||||
|
||||
/mob/dead/observer/can_use_hands() return 0
|
||||
/mob/dead/observer/is_active() return 0
|
||||
|
||||
@@ -316,11 +294,23 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if(!thearea) return
|
||||
|
||||
var/list/L = list()
|
||||
for(var/turf/T in get_area_turfs(thearea.type))
|
||||
L+=T
|
||||
var/holyblock = 0
|
||||
|
||||
if(usr.invisibility <= SEE_INVISIBLE_LIVING || (usr.mind in cult.current_antagonists))
|
||||
for(var/turf/T in get_area_turfs(thearea.type))
|
||||
if(!T.holy)
|
||||
L+=T
|
||||
else
|
||||
holyblock = 1
|
||||
else
|
||||
for(var/turf/T in get_area_turfs(thearea.type))
|
||||
L+=T
|
||||
|
||||
if(!L || !L.len)
|
||||
usr << "No area available."
|
||||
if(holyblock)
|
||||
usr << "<span class='warning'>This area has been entirely made into sacred grounds, you cannot enter it while you are in this plane of existence!</span>"
|
||||
else
|
||||
usr << "No area available."
|
||||
|
||||
usr.loc = pick(L)
|
||||
following = null
|
||||
@@ -336,7 +326,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
// This is the ghost's follow verb with an argument
|
||||
/mob/dead/observer/proc/ManualFollow(var/atom/movable/target)
|
||||
if(target && target != src)
|
||||
if(!target)
|
||||
return
|
||||
|
||||
var/turf/targetloc = get_turf(target)
|
||||
if(check_holy(targetloc))
|
||||
usr << "<span class='warning'>You cannot follow a mob standing on holy grounds!</span>"
|
||||
return
|
||||
if(target != src)
|
||||
if(following && following == target)
|
||||
return
|
||||
following = target
|
||||
@@ -351,6 +348,15 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
loc = T
|
||||
sleep(15)
|
||||
|
||||
/mob/proc/check_holy(var/turf/T)
|
||||
return 0
|
||||
|
||||
/mob/dead/observer/check_holy(var/turf/T)
|
||||
if(check_rights(R_ADMIN|R_FUN, 0, src))
|
||||
return 0
|
||||
|
||||
return (T && T.holy) && (invisibility <= SEE_INVISIBLE_LIVING || (mind in cult.current_antagonists))
|
||||
|
||||
/mob/dead/observer/verb/jumptomob(target in getmobs()) //Moves the ghost instead of just changing the ghosts's eye -Nodrak
|
||||
set category = "Ghost"
|
||||
set name = "Jump to Mob"
|
||||
@@ -393,6 +399,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set hidden = 1
|
||||
src << "\red You are dead! You have no mind to store memory!"
|
||||
|
||||
/mob/dead/observer/Post_Incorpmove()
|
||||
following = null
|
||||
|
||||
/mob/dead/observer/verb/analyze_air()
|
||||
set name = "Analyze Air"
|
||||
set category = "Ghost"
|
||||
@@ -473,6 +482,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
src << browse(dat, "window=manifest;size=370x420;can_close=1")
|
||||
|
||||
//This is called when a ghost is drag clicked to something.
|
||||
/mob/dead/observer/MouseDrop(atom/over)
|
||||
if (isobserver(usr) && usr.client && usr.client.holder && isliving(over))
|
||||
if (usr.client.holder.cmd_ghost_drag(src,over))
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
//Used for drawing on walls with blood puddles as a spooky ghost.
|
||||
/mob/dead/verb/bloody_doodle()
|
||||
|
||||
|
||||
@@ -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(gibbed, deathmessage="seizes up and falls limp...")
|
||||
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)
|
||||
@@ -214,25 +214,18 @@
|
||||
w_uniform.add_fingerprint(M)
|
||||
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
|
||||
|
||||
if(istype(r_hand,/obj/item/weapon/gun) || istype(l_hand,/obj/item/weapon/gun))
|
||||
var/obj/item/weapon/gun/W = null
|
||||
var/chance = 0
|
||||
var/list/holding = list(get_active_hand() = 40, get_inactive_hand = 20)
|
||||
|
||||
if (istype(l_hand,/obj/item/weapon/gun))
|
||||
W = l_hand
|
||||
chance = hand ? 40 : 20
|
||||
|
||||
if (istype(r_hand,/obj/item/weapon/gun))
|
||||
W = r_hand
|
||||
chance = !hand ? 40 : 20
|
||||
|
||||
if (prob(chance))
|
||||
visible_message("<span class='danger'>[src]'s [W] goes off during struggle!</span>")
|
||||
//See if they have any guns that might go off
|
||||
for(var/obj/item/weapon/gun/W in holding)
|
||||
if(W && prob(holding[W]))
|
||||
var/list/turfs = list()
|
||||
for(var/turf/T in view())
|
||||
turfs += T
|
||||
var/turf/target = pick(turfs)
|
||||
return W.afterattack(target,src)
|
||||
if(turfs.len)
|
||||
var/turf/target = pick(turfs)
|
||||
visible_message("<span class='danger'>[src]'s [W] goes off during the struggle!</span>")
|
||||
return W.afterattack(target,src)
|
||||
|
||||
var/randn = rand(1, 100)
|
||||
if(!(species.flags & NO_SLIP) && randn <= 25)
|
||||
@@ -245,39 +238,25 @@
|
||||
visible_message("<span class='warning'>[M] attempted to push [src]!</span>")
|
||||
return
|
||||
|
||||
var/talked = 0 // BubbleWrap
|
||||
|
||||
if(randn <= 60)
|
||||
//BubbleWrap: Disarming breaks a pull
|
||||
if(pulling)
|
||||
visible_message("\red <b>[M] has broken [src]'s grip on [pulling]!</B>")
|
||||
talked = 1
|
||||
stop_pulling()
|
||||
//See about breaking grips or pulls
|
||||
if(break_all_grabs(M))
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
return
|
||||
|
||||
//BubbleWrap: Disarming also breaks a grab - this will also stop someone being choked, won't it?
|
||||
if(istype(l_hand, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/lgrab = l_hand
|
||||
if(lgrab.affecting)
|
||||
visible_message("\red <b>[M] has broken [src]'s grip on [lgrab.affecting]!</B>")
|
||||
talked = 1
|
||||
spawn(1)
|
||||
del(lgrab)
|
||||
if(istype(r_hand, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/rgrab = r_hand
|
||||
if(rgrab.affecting)
|
||||
visible_message("\red <b>[M] has broken [src]'s grip on [rgrab.affecting]!</B>")
|
||||
talked = 1
|
||||
spawn(1)
|
||||
del(rgrab)
|
||||
//End BubbleWrap
|
||||
|
||||
if(!talked) //BubbleWrap
|
||||
drop_item()
|
||||
visible_message("\red <B>[M] has disarmed [src]!</B>")
|
||||
//Actually disarm them
|
||||
for(var/obj/item/I in holding)
|
||||
if(I)
|
||||
drop_from_inventory(I)
|
||||
visible_message("<span class='danger'>[M] has disarmed [src]!</span>")
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
return
|
||||
|
||||
//if M (and only M) has a grab on src, start dislocating limbs
|
||||
if(grab_joint(M))
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
return
|
||||
|
||||
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("\red <B>[M] attempted to disarm [src]!</B>")
|
||||
return
|
||||
@@ -302,16 +281,68 @@
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/attack_joint(var/obj/item/W, var/mob/living/user, var/def_zone)
|
||||
var/target_zone = def_zone? check_zone(def_zone) : get_zone_with_miss_chance(user.zone_sel.selecting, src)
|
||||
if(!def_zone) def_zone = user.zone_sel.selecting
|
||||
var/target_zone = get_zone_with_miss_chance(check_zone(def_zone), src)
|
||||
|
||||
if(user == src) // Attacking yourself can't miss
|
||||
target_zone = user.zone_sel.selecting
|
||||
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))
|
||||
dislocation_str = "[src]'s [organ.joint] [pick("gives way","caves in","crumbles","collapses")] with a grisly crunch!"
|
||||
dislocation_str = "[src]'s [organ.joint] [pick("gives way","caves in","crumbles","collapses")]!"
|
||||
organ.dislocate()
|
||||
return dislocation_str
|
||||
|
||||
//Used to attack a joint through grabbing
|
||||
/mob/living/carbon/human/proc/grab_joint(var/mob/living/user, var/def_zone)
|
||||
var/has_grab = 0
|
||||
for(var/obj/item/weapon/grab/G in list(user.l_hand, user.r_hand))
|
||||
if(G.affecting == src && G.state == GRAB_NECK)
|
||||
has_grab = 1
|
||||
break
|
||||
|
||||
if(!has_grab)
|
||||
return 0
|
||||
|
||||
if(!def_zone) def_zone = user.zone_sel.selecting
|
||||
var/target_zone = check_zone(def_zone)
|
||||
if(!target_zone)
|
||||
return 0
|
||||
var/obj/item/organ/external/organ = get_organ(check_zone(target_zone))
|
||||
if(!organ || organ.is_dislocated() || organ.dislocated == -1)
|
||||
return 0
|
||||
|
||||
user.visible_message("<span class='warning'>[user] begins to dislocate [src]'s [organ.joint]!</span>")
|
||||
if(do_after(user, 100))
|
||||
organ.dislocate()
|
||||
src.visible_message("<span class='danger'>[src]'s [organ.joint] [pick("gives way","caves in","crumbles","collapses")]!</span>")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//Breaks all grips and pulls that the mob currently has.
|
||||
/mob/living/carbon/human/proc/break_all_grabs(mob/living/carbon/user)
|
||||
var/success = 0
|
||||
if(pulling)
|
||||
visible_message("<span class='danger'>[user] has broken [src]'s grip on [pulling]!</span>")
|
||||
success = 1
|
||||
stop_pulling()
|
||||
|
||||
if(istype(l_hand, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/lgrab = l_hand
|
||||
if(lgrab.affecting)
|
||||
visible_message("<span class='danger'>[user] has broken [src]'s grip on [lgrab.affecting]!</span>")
|
||||
success = 1
|
||||
spawn(1)
|
||||
del(lgrab)
|
||||
if(istype(r_hand, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/rgrab = r_hand
|
||||
if(rgrab.affecting)
|
||||
visible_message("<span class='danger'>[user] has broken [src]'s grip on [rgrab.affecting]!</span>")
|
||||
success = 1
|
||||
spawn(1)
|
||||
del(rgrab)
|
||||
return success
|
||||
|
||||
@@ -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.status & ORGAN_SPLINTED)) || !E.is_usable())
|
||||
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
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
if(name != GetVoice())
|
||||
alt_name = "(as [get_id_name("Unknown")])"
|
||||
|
||||
if (istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
|
||||
src << "<span class='danger'>You're muzzled and cannot speak!</span>"
|
||||
return
|
||||
|
||||
message = sanitize(message)
|
||||
..(message, alt_name = alt_name) //ohgod we should really be passing a datum here.
|
||||
..(message, alt_name = alt_name)
|
||||
|
||||
/mob/living/carbon/human/is_muzzled()
|
||||
return istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
|
||||
|
||||
/mob/living/carbon/human/proc/forcesay(list/append)
|
||||
if(stat == CONSCIOUS)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -36,12 +36,8 @@
|
||||
if(istype(src,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/M = src
|
||||
for(var/obj/item/organ/external/organ in M.organs)
|
||||
if (!organ)
|
||||
continue
|
||||
else if(organ.status & ORGAN_BROKEN || organ.open)
|
||||
if(organ && (organ.is_broken() || organ.open))
|
||||
src.traumatic_shock += 30
|
||||
if(organ.status & ORGAN_SPLINTED)
|
||||
src.traumatic_shock -= 25
|
||||
|
||||
if(src.traumatic_shock < 0)
|
||||
src.traumatic_shock = 0
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
|
||||
var/last_special = 0 //Used by the resist verb, likely used to prevent players from bypassing next_move by logging in/out.
|
||||
|
||||
//Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
|
||||
var/incorporeal_move = 0 //0 is off, 1 is normal, 2 is for ninjas.
|
||||
|
||||
var/t_phoron = null
|
||||
var/t_oxygen = null
|
||||
var/t_sl_gas = null
|
||||
|
||||
@@ -80,7 +80,10 @@ 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/is_muzzled()
|
||||
return 0
|
||||
|
||||
/mob/living/proc/handle_speech_problems(var/message, var/verb)
|
||||
var/list/returns[3]
|
||||
@@ -135,6 +138,10 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
return say_dead(message)
|
||||
return
|
||||
|
||||
if(is_muzzled())
|
||||
src << "<span class='danger'>You're muzzled and cannot speak!</span>"
|
||||
return
|
||||
|
||||
var/message_mode = parse_message_mode(message, "headset")
|
||||
|
||||
switch(copytext(message,1,2))
|
||||
|
||||
@@ -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,
|
||||
@@ -45,7 +46,7 @@ var/list/ai_verbs_default = list(
|
||||
density = 1
|
||||
status_flags = CANSTUN|CANPARALYSE|CANPUSH
|
||||
shouldnt_see = list(/obj/effect/rune)
|
||||
var/list/network = list("SS13")
|
||||
var/list/network = list("Exodus")
|
||||
var/obj/machinery/camera/camera = null
|
||||
var/list/connected_robots = list()
|
||||
var/aiRestorePowerRoutine = 0
|
||||
@@ -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,41 @@ 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
|
||||
|
||||
src.network = network
|
||||
|
||||
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 +693,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
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
/mob/living/silicon/ai/Login() //ThisIsDumb(TM) TODO: tidy this up <20>_<EFBFBD> ~Carn
|
||||
..()
|
||||
for(var/obj/effect/rune/rune in world)
|
||||
var/image/blood = image(loc = rune)
|
||||
blood.override = 1
|
||||
client.images += blood
|
||||
for(var/obj/effect/rune/rune in rune_list)
|
||||
client.images += rune.blood_image
|
||||
regenerate_icons()
|
||||
flash = new /obj/screen()
|
||||
flash.icon_state = "blank"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/mob/living/simple_animal/construct
|
||||
name = "Construct"
|
||||
real_name = "Construct"
|
||||
@@ -6,8 +5,8 @@
|
||||
speak_emote = list("hisses")
|
||||
emote_hear = list("wails","screeches")
|
||||
response_help = "thinks better of touching"
|
||||
response_disarm = "flails at"
|
||||
response_harm = "punches"
|
||||
response_disarm = "flailed at"
|
||||
response_harm = "punched"
|
||||
icon_dead = "shade_dead"
|
||||
speed = -1
|
||||
a_intent = I_HURT
|
||||
@@ -15,7 +14,7 @@
|
||||
status_flags = CANPUSH
|
||||
universal_speak = 0
|
||||
universal_understand = 1
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
attack_sound = 'sound/weapons/spiderlunge.ogg'
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
@@ -25,7 +24,7 @@
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
minbodytemp = 0
|
||||
show_stat_health = 0
|
||||
show_stat_health = 1
|
||||
faction = "cult"
|
||||
supernatural = 1
|
||||
var/nullblock = 0
|
||||
@@ -35,6 +34,9 @@
|
||||
|
||||
var/list/construct_spells = list()
|
||||
|
||||
/mob/living/simple_animal/construct/cultify()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/construct/New()
|
||||
..()
|
||||
name = text("[initial(name)] ([rand(1, 1000)])")
|
||||
@@ -42,8 +44,9 @@
|
||||
add_language("Cult")
|
||||
add_language("Occult")
|
||||
for(var/spell in construct_spells)
|
||||
spell_list += new spell(src)
|
||||
src.add_spell(new spell, "const_spell_ready")
|
||||
updateicon()
|
||||
add_glow()
|
||||
|
||||
/mob/living/simple_animal/construct/death()
|
||||
new /obj/item/weapon/ectoplasm (src.loc)
|
||||
@@ -97,10 +100,10 @@
|
||||
mob_size = 20
|
||||
speed = 3
|
||||
environment_smash = 2
|
||||
attack_sound = 'sound/weapons/punch3.ogg'
|
||||
attack_sound = 'sound/weapons/heavysmash.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
|
||||
@@ -148,8 +151,8 @@
|
||||
speed = -1
|
||||
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)
|
||||
attack_sound = 'sound/weapons/rapidslice.ogg'
|
||||
construct_spells = list(/spell/targeted/ethereal_jaunt/shift)
|
||||
|
||||
|
||||
/////////////////////////////Artificer/////////////////////////
|
||||
@@ -165,18 +168,20 @@
|
||||
icon_living = "artificer"
|
||||
maxHealth = 50
|
||||
health = 50
|
||||
response_harm = "viciously beats"
|
||||
response_harm = "viciously beaten"
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 5
|
||||
attacktext = "rammed"
|
||||
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,)
|
||||
environment_smash = 1
|
||||
attack_sound = 'sound/weapons/rapidslice.ogg'
|
||||
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/////////////////////////
|
||||
@@ -192,17 +197,18 @@
|
||||
maxHealth = 750
|
||||
health = 750
|
||||
speak_emote = list("rumbles")
|
||||
response_harm = "harmlessly punches"
|
||||
response_harm = "harmlessly punched"
|
||||
harm_intent_damage = 0
|
||||
melee_damage_lower = 50
|
||||
melee_damage_upper = 50
|
||||
attacktext = "brutally crushed"
|
||||
speed = 5
|
||||
environment_smash = 2
|
||||
attack_sound = 'sound/weapons/punch4.ogg'
|
||||
attack_sound = 'sound/weapons/heavysmash.ogg'
|
||||
resistance = 10
|
||||
var/energy = 0
|
||||
var/max_energy = 1000
|
||||
construct_spells = list(/spell/aoe_turf/conjure/forcewall/lesser)
|
||||
|
||||
////////////////////////Harvester////////////////////////////////
|
||||
|
||||
@@ -219,14 +225,110 @@
|
||||
health = 150
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 25
|
||||
attacktext = "violently stabs"
|
||||
attacktext = "violently stabbed"
|
||||
speed = -1
|
||||
environment_smash = 1
|
||||
see_in_dark = 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
|
||||
)
|
||||
|
||||
////////////////Glow//////////////////
|
||||
/mob/living/simple_animal/construct/proc/add_glow()
|
||||
overlays = 0
|
||||
var/overlay_layer = LIGHTING_LAYER+1
|
||||
if(layer != MOB_LAYER)
|
||||
overlay_layer=TURF_LAYER+0.2
|
||||
|
||||
overlays += image(icon,"glow-[icon_state]",overlay_layer)
|
||||
|
||||
////////////////HUD//////////////////////
|
||||
|
||||
/mob/living/simple_animal/construct/Life()
|
||||
. = ..()
|
||||
if(.)
|
||||
if(fire)
|
||||
if(fire_alert) fire.icon_state = "fire1"
|
||||
else fire.icon_state = "fire0"
|
||||
if(pullin)
|
||||
if(pulling) pullin.icon_state = "pull1"
|
||||
else pullin.icon_state = "pull0"
|
||||
|
||||
if(purged)
|
||||
if(purge > 0) purged.icon_state = "purge1"
|
||||
else purged.icon_state = "purge0"
|
||||
|
||||
silence_spells(purge)
|
||||
|
||||
/mob/living/simple_animal/construct/armoured/Life()
|
||||
..()
|
||||
if(healths)
|
||||
switch(health)
|
||||
if(250 to INFINITY) healths.icon_state = "juggernaut_health0"
|
||||
if(208 to 249) healths.icon_state = "juggernaut_health1"
|
||||
if(167 to 207) healths.icon_state = "juggernaut_health2"
|
||||
if(125 to 166) healths.icon_state = "juggernaut_health3"
|
||||
if(84 to 124) healths.icon_state = "juggernaut_health4"
|
||||
if(42 to 83) healths.icon_state = "juggernaut_health5"
|
||||
if(1 to 41) healths.icon_state = "juggernaut_health6"
|
||||
else healths.icon_state = "juggernaut_health7"
|
||||
|
||||
|
||||
/mob/living/simple_animal/construct/behemoth/Life()
|
||||
..()
|
||||
if(healths)
|
||||
switch(health)
|
||||
if(750 to INFINITY) healths.icon_state = "juggernaut_health0"
|
||||
if(625 to 749) healths.icon_state = "juggernaut_health1"
|
||||
if(500 to 624) healths.icon_state = "juggernaut_health2"
|
||||
if(375 to 499) healths.icon_state = "juggernaut_health3"
|
||||
if(250 to 374) healths.icon_state = "juggernaut_health4"
|
||||
if(125 to 249) healths.icon_state = "juggernaut_health5"
|
||||
if(1 to 124) healths.icon_state = "juggernaut_health6"
|
||||
else healths.icon_state = "juggernaut_health7"
|
||||
|
||||
/mob/living/simple_animal/construct/builder/Life()
|
||||
..()
|
||||
if(healths)
|
||||
switch(health)
|
||||
if(50 to INFINITY) healths.icon_state = "artificer_health0"
|
||||
if(42 to 49) healths.icon_state = "artificer_health1"
|
||||
if(34 to 41) healths.icon_state = "artificer_health2"
|
||||
if(26 to 33) healths.icon_state = "artificer_health3"
|
||||
if(18 to 25) healths.icon_state = "artificer_health4"
|
||||
if(10 to 17) healths.icon_state = "artificer_health5"
|
||||
if(1 to 9) healths.icon_state = "artificer_health6"
|
||||
else healths.icon_state = "artificer_health7"
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/construct/wraith/Life()
|
||||
..()
|
||||
if(healths)
|
||||
switch(health)
|
||||
if(75 to INFINITY) healths.icon_state = "wraith_health0"
|
||||
if(62 to 74) healths.icon_state = "wraith_health1"
|
||||
if(50 to 61) healths.icon_state = "wraith_health2"
|
||||
if(37 to 49) healths.icon_state = "wraith_health3"
|
||||
if(25 to 36) healths.icon_state = "wraith_health4"
|
||||
if(12 to 24) healths.icon_state = "wraith_health5"
|
||||
if(1 to 11) healths.icon_state = "wraith_health6"
|
||||
else healths.icon_state = "wraith_health7"
|
||||
|
||||
|
||||
/mob/living/simple_animal/construct/harvester/Life()
|
||||
..()
|
||||
if(healths)
|
||||
switch(health)
|
||||
if(150 to INFINITY) healths.icon_state = "harvester_health0"
|
||||
if(125 to 149) healths.icon_state = "harvester_health1"
|
||||
if(100 to 124) healths.icon_state = "harvester_health2"
|
||||
if(75 to 99) healths.icon_state = "harvester_health3"
|
||||
if(50 to 74) healths.icon_state = "harvester_health4"
|
||||
if(25 to 49) healths.icon_state = "harvester_health5"
|
||||
if(1 to 24) healths.icon_state = "harvester_health6"
|
||||
else healths.icon_state = "harvester_health7"
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/obj/item/device/soulstone/cultify()
|
||||
return
|
||||
|
||||
/obj/item/device/soulstone
|
||||
name = "Soul Stone Shard"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
@@ -9,7 +12,6 @@
|
||||
origin_tech = "bluespace=4;materials=4"
|
||||
var/imprinted = "empty"
|
||||
|
||||
|
||||
//////////////////////////////Capturing////////////////////////////////////////////////////////
|
||||
|
||||
attack(mob/living/carbon/human/M as mob, mob/user as mob)
|
||||
@@ -86,7 +88,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))
|
||||
|
||||
76
code/modules/mob/living/simple_animal/hostile/bat.dm
Normal file
76
code/modules/mob/living/simple_animal/hostile/bat.dm
Normal file
@@ -0,0 +1,76 @@
|
||||
/mob/living/simple_animal/hostile/scarybat
|
||||
name = "space bats"
|
||||
desc = "A swarm of cute little blood sucking bats that looks pretty upset."
|
||||
icon = 'icons/mob/bats.dmi'
|
||||
icon_state = "bat"
|
||||
icon_living = "bat"
|
||||
icon_dead = "bat_dead"
|
||||
icon_gib = "bat_dead"
|
||||
speak_chance = 0
|
||||
turns_per_move = 3
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "hits the"
|
||||
speed = 4
|
||||
maxHealth = 20
|
||||
health = 20
|
||||
|
||||
harm_intent_damage = 8
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 10
|
||||
attacktext = "bites"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
|
||||
//Space carp aren't affected by atmos.
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
minbodytemp = 0
|
||||
|
||||
environment_smash = 1
|
||||
|
||||
faction = "scarybat"
|
||||
var/mob/living/owner
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/New(loc, mob/living/L as mob)
|
||||
..()
|
||||
if(istype(L))
|
||||
owner = L
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/Process_Spacemove(var/check_drift = 0)
|
||||
return ..() //No drifting in space for space carp! //original comments do not steal
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/FindTarget()
|
||||
. = ..()
|
||||
if(.)
|
||||
emote("flutters towards [.]")
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/Found(var/atom/A)//This is here as a potential override to pick a specific target if available
|
||||
if(istype(A) && A == owner)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/AttackingTarget()
|
||||
. =..()
|
||||
var/mob/living/L = .
|
||||
if(istype(L))
|
||||
if(prob(15))
|
||||
L.Stun(1)
|
||||
L.visible_message("<span class='danger'>\the [src] scares \the [L]!</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/cult
|
||||
faction = "cult"
|
||||
supernatural = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/cult/cultify()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/cult/Life()
|
||||
..()
|
||||
check_horde()
|
||||
@@ -13,4 +13,26 @@
|
||||
attacktext = "chomped"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
faction = "creature"
|
||||
speed = 4
|
||||
speed = 4
|
||||
|
||||
/mob/living/simple_animal/hostile/creature/cult
|
||||
faction = "cult"
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
minbodytemp = 0
|
||||
|
||||
supernatural = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/creature/cult/cultify()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/creature/cult/Life()
|
||||
..()
|
||||
check_horde()
|
||||
|
||||
@@ -46,4 +46,14 @@
|
||||
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>")
|
||||
|
||||
/mob/living/simple_animal/hostile/faithless/cult
|
||||
faction = "cult"
|
||||
|
||||
/mob/living/simple_animal/hostile/faithless/cult/cultify()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/faithless/cult/Life()
|
||||
..()
|
||||
check_horde()
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
stop_automated_movement_when_pulled = 0
|
||||
var/destroy_surroundings = 1
|
||||
|
||||
var/shuttletarget = null
|
||||
var/enroute = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/FindTarget()
|
||||
|
||||
var/atom/T = null
|
||||
@@ -113,11 +116,11 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/ListTargets(var/dist = 7)
|
||||
var/list/L = hearers(src, dist)
|
||||
|
||||
|
||||
for (var/obj/mecha/M in mechas_list)
|
||||
if (get_dist(src, M) <= dist)
|
||||
L += M
|
||||
|
||||
|
||||
return L
|
||||
|
||||
/mob/living/simple_animal/hostile/death()
|
||||
@@ -206,3 +209,40 @@
|
||||
var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir))
|
||||
if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille))
|
||||
obstacle.attack_generic(src,rand(melee_damage_lower,melee_damage_upper),attacktext)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/check_horde()
|
||||
if(emergency_shuttle.shuttle.location)
|
||||
if(!enroute && !target_mob) //The shuttle docked, all monsters rush for the escape hallway
|
||||
if(!shuttletarget || (get_dist(src, shuttletarget) >= 2))
|
||||
shuttletarget = pick(escape_list)
|
||||
enroute = 1
|
||||
stop_automated_movement = 1
|
||||
spawn()
|
||||
if(!src.stat)
|
||||
horde()
|
||||
|
||||
if(get_dist(src, shuttletarget) <= 2) //The monster reached the escape hallway
|
||||
enroute = 0
|
||||
stop_automated_movement = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/horde()
|
||||
var/turf/T = get_step_to(src, shuttletarget)
|
||||
for(var/atom/A in T)
|
||||
if(istype(A,/obj/machinery/door/airlock))
|
||||
var/obj/machinery/door/airlock/D = A
|
||||
D.open(1)
|
||||
else if(istype(A,/obj/structure/mineral_door))
|
||||
var/obj/structure/mineral_door/D = A
|
||||
if(D.density)
|
||||
D.Open()
|
||||
else if(istype(A,/obj/structure/cult/pylon))
|
||||
A.attack_generic(src, rand(melee_damage_lower, melee_damage_upper))
|
||||
else if(istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || istype(A, /obj/structure/table) || istype(A, /obj/structure/grille) || istype(A, /obj/structure/table/rack))
|
||||
A.attack_generic(src, rand(melee_damage_lower, melee_damage_upper))
|
||||
Move(T)
|
||||
FindTarget()
|
||||
if(!target_mob || enroute)
|
||||
spawn(10)
|
||||
if(!src.stat)
|
||||
horde()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -28,8 +28,19 @@
|
||||
faction = "cult"
|
||||
status_flags = CANPUSH
|
||||
|
||||
/mob/living/simple_animal/shade/cultify()
|
||||
return
|
||||
|
||||
/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 +49,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 ..()
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
var/maxbodytemp = 350
|
||||
var/heat_damage_per_tick = 3 //amount of damage applied if animal's body temperature is higher than maxbodytemp
|
||||
var/cold_damage_per_tick = 2 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
|
||||
var/fire_alert = 0
|
||||
|
||||
//Atmos effect - Yes, you can make creatures that require phoron or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage
|
||||
var/min_oxy = 5
|
||||
@@ -78,6 +79,7 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/Life()
|
||||
..()
|
||||
|
||||
//Health
|
||||
if(stat == DEAD)
|
||||
@@ -191,9 +193,13 @@
|
||||
|
||||
//Atmos effect
|
||||
if(bodytemperature < minbodytemp)
|
||||
fire_alert = 2
|
||||
adjustBruteLoss(cold_damage_per_tick)
|
||||
else if(bodytemperature > maxbodytemp)
|
||||
fire_alert = 1
|
||||
adjustBruteLoss(heat_damage_per_tick)
|
||||
else
|
||||
fire_alert = 0
|
||||
|
||||
if(!atmos_suitable)
|
||||
adjustBruteLoss(unsuitable_atoms_damage)
|
||||
@@ -313,10 +319,10 @@
|
||||
if(statpanel("Status") && show_stat_health)
|
||||
stat(null, "Health: [round((health / maxHealth) * 100)]%")
|
||||
|
||||
/mob/living/simple_animal/death()
|
||||
/mob/living/simple_animal/death(gibbed, deathmessage="")
|
||||
icon_state = icon_dead
|
||||
density = 0
|
||||
return ..(deathmessage = "no message")
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/ex_act(severity)
|
||||
if(!blinded)
|
||||
@@ -350,7 +356,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
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
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).
|
||||
@@ -84,6 +87,8 @@
|
||||
var/lying = 0
|
||||
var/lying_prev = 0
|
||||
var/canmove = 1
|
||||
//Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
|
||||
var/incorporeal_move = 0 //0 is off, 1 is normal, 2 is for ninjas.
|
||||
var/lastpuke = 0
|
||||
var/unacidable = 0
|
||||
var/small = 0
|
||||
@@ -183,7 +188,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
|
||||
|
||||
@@ -170,23 +170,27 @@
|
||||
|
||||
|
||||
/client/Move(n, direct)
|
||||
if(!mob)
|
||||
return // Moved here to avoid nullrefs below
|
||||
|
||||
if(mob.control_object) Move_object(direct)
|
||||
|
||||
if(isobserver(mob)) return mob.Move(n,direct)
|
||||
if(mob.incorporeal_move && isobserver(mob))
|
||||
Process_Incorpmove(direct)
|
||||
return
|
||||
|
||||
if(moving) return 0
|
||||
|
||||
if(world.time < move_delay) return
|
||||
|
||||
if(!mob) return
|
||||
|
||||
if(locate(/obj/effect/stop/, mob.loc))
|
||||
for(var/obj/effect/stop/S in mob.loc)
|
||||
if(S.victim == mob)
|
||||
return
|
||||
|
||||
if(mob.stat==2) return
|
||||
if(mob.stat==2)
|
||||
mob.ghostize()
|
||||
return
|
||||
|
||||
// handle possible Eye movement
|
||||
if(mob.eyeobj)
|
||||
@@ -364,13 +368,16 @@
|
||||
///Allows mobs to run though walls
|
||||
/client/proc/Process_Incorpmove(direct)
|
||||
var/turf/mobloc = get_turf(mob)
|
||||
if(!isliving(mob))
|
||||
return
|
||||
var/mob/living/L = mob
|
||||
switch(L.incorporeal_move)
|
||||
|
||||
switch(mob.incorporeal_move)
|
||||
if(1)
|
||||
L.loc = get_step(L, direct)
|
||||
L.dir = direct
|
||||
var/turf/T = get_step(mob, direct)
|
||||
if(mob.check_holy(T))
|
||||
mob << "<span class='warning'>You cannot get past holy grounds while you are in this plane of existence!</span>"
|
||||
return
|
||||
else
|
||||
mob.loc = get_step(mob, direct)
|
||||
mob.dir = direct
|
||||
if(2)
|
||||
if(prob(50))
|
||||
var/locx
|
||||
@@ -398,21 +405,35 @@
|
||||
return
|
||||
else
|
||||
return
|
||||
L.loc = locate(locx,locy,mobloc.z)
|
||||
mob.loc = locate(locx,locy,mobloc.z)
|
||||
spawn(0)
|
||||
var/limit = 2//For only two trailing shadows.
|
||||
for(var/turf/T in getline(mobloc, L.loc))
|
||||
for(var/turf/T in getline(mobloc, mob.loc))
|
||||
spawn(0)
|
||||
anim(T,L,'icons/mob/mob.dmi',,"shadow",,L.dir)
|
||||
anim(T,mob,'icons/mob/mob.dmi',,"shadow",,mob.dir)
|
||||
limit--
|
||||
if(limit<=0) break
|
||||
else
|
||||
spawn(0)
|
||||
anim(mobloc,mob,'icons/mob/mob.dmi',,"shadow",,L.dir)
|
||||
L.loc = get_step(L, direct)
|
||||
L.dir = direct
|
||||
anim(mobloc,mob,'icons/mob/mob.dmi',,"shadow",,mob.dir)
|
||||
mob.loc = get_step(mob, direct)
|
||||
mob.dir = direct
|
||||
// Crossed is always a bit iffy
|
||||
for(var/obj/S in mob.loc)
|
||||
if(istype(S,/obj/effect/step_trigger) || istype(S,/obj/effect/beam))
|
||||
S.Crossed(mob)
|
||||
|
||||
var/area/A = get_area_master(mob)
|
||||
if(A)
|
||||
A.Entered(mob)
|
||||
if(isturf(mob.loc))
|
||||
var/turf/T = mob.loc
|
||||
T.Entered(mob)
|
||||
mob.Post_Incorpmove()
|
||||
return 1
|
||||
|
||||
/mob/proc/Post_Incorpmove()
|
||||
return
|
||||
|
||||
///Process_Spacemove
|
||||
///Called by /client/Move()
|
||||
|
||||
@@ -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_CLOSE
|
||||
|
||||
/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/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()
|
||||
@@ -145,7 +146,7 @@ var/list/organ_cache = list()
|
||||
return damage >= min_bruised_damage
|
||||
|
||||
/obj/item/organ/proc/is_broken()
|
||||
return (damage >= min_broken_damage || (status & ORGAN_CUT_AWAY) || ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED)))
|
||||
return (damage >= min_broken_damage || (status & ORGAN_CUT_AWAY) || (status & ORGAN_BROKEN))
|
||||
|
||||
//Germs
|
||||
/obj/item/organ/proc/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()
|
||||
@@ -333,8 +340,12 @@ This function completely restores a damaged organ to perfect condition.
|
||||
PROCESSING & UPDATING
|
||||
****************************************************/
|
||||
|
||||
//Determines if we even need to process this organ.
|
||||
//external organs handle brokenness a bit differently when it comes to damage. Instead brute_dam is checked inside process()
|
||||
//this also ensures that an external organ cannot be "broken" without broken_description being set.
|
||||
/obj/item/organ/external/is_broken()
|
||||
return ((status & ORGAN_CUT_AWAY) || ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED)))
|
||||
|
||||
//Determines if we even need to process this organ.
|
||||
/obj/item/organ/external/proc/need_process()
|
||||
if(status && status != ORGAN_ROBOT) // If it's robotic, that's fine it will have a status.
|
||||
return 1
|
||||
@@ -634,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)
|
||||
@@ -649,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
|
||||
@@ -675,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)
|
||||
|
||||
@@ -699,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
|
||||
@@ -813,7 +821,7 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
name = "[R.company] [initial(name)]"
|
||||
desc = "[R.desc]"
|
||||
|
||||
dislocated = -1
|
||||
dislocated = -1 //TODO, make robotic limbs a separate type, remove snowflake
|
||||
cannot_break = 1
|
||||
get_icon()
|
||||
for (var/obj/item/organ/external/T in children)
|
||||
@@ -838,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))
|
||||
@@ -859,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)
|
||||
@@ -880,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()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user