"
- return output
-*/
\ No newline at end of file
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index cead6e33ffd..4c61393d9f7 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -29,6 +29,11 @@
. = ..()
unbuckle_mob()
+/atom/movable/proc/has_buckled_mobs()
+ if(buckled_mob)
+ return TRUE
+ return FALSE
+
//procs that handle the actual buckling and unbuckling
/atom/movable/proc/buckle_mob(mob/living/M)
if(!can_buckle || !istype(M) || (M.loc != loc) || M.buckled || M.buckled_mob || buckled_mob || (buckle_requires_restraints && !M.restrained()) || M == src)
diff --git a/code/game/objects/effects/decals/remains.dm b/code/game/objects/effects/decals/remains.dm
index d50d595d3ea..8835d31c6c2 100644
--- a/code/game/objects/effects/decals/remains.dm
+++ b/code/game/objects/effects/decals/remains.dm
@@ -1,7 +1,9 @@
+/obj/effect/decal/remains
+ gender = PLURAL
+
/obj/effect/decal/remains/human
name = "remains"
desc = "They look like human remains. They have a strange aura about them."
- gender = PLURAL
icon = 'icons/effects/blood.dmi'
icon_state = "remains"
anchored = 1
@@ -9,7 +11,6 @@
/obj/effect/decal/remains/xeno
name = "remains"
desc = "They look like the remains of something... alien. They have a strange aura about them."
- gender = PLURAL
icon = 'icons/effects/blood.dmi'
icon_state = "remainsxeno"
anchored = 1
@@ -17,7 +18,29 @@
/obj/effect/decal/remains/robot
name = "remains"
desc = "They look like the remains of something mechanical. They have a strange aura about them."
- gender = PLURAL
icon = 'icons/mob/robots.dmi'
icon_state = "remainsrobot"
- anchored = 1
\ No newline at end of file
+ anchored = 1
+
+/obj/effect/decal/remains/robot/New()
+ ..()
+ var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
+ s.set_up(3, 1, src)
+ s.start()
+
+/obj/effect/decal/remains/slime
+ name = "You shouldn't see this"
+ desc = "Noooooooooooooooooooooo"
+ icon = 'icons/effects/blood.dmi'
+ icon_state = "remains"
+ anchored = 1
+
+/obj/effect/decal/remains/slime/New()
+ ..()
+ var/datum/reagents/R = new/datum/reagents(5)
+ var/obj/effect/effect/water/W = new(get_turf(src))
+ W.reagents = R
+ R.my_atom = W
+ R.add_reagent("water", 5)
+ R.reaction(get_turf(src))
+ qdel(src)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 82412c8e883..a764cf54fc0 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -564,4 +564,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
clean_blood()
user.visible_message("[user] washes [src] using [source].", \
"You wash [src] using [source].")
- return 1
\ No newline at end of file
+ return 1
+
+/obj/item/proc/is_crutch() //Does an item prop up a human mob and allow them to stand if they are missing a leg/foot?
+ return 0
\ No newline at end of file
diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm
index 9dec685efb8..664bd07f8ad 100644
--- a/code/game/objects/items/devices/lightreplacer.dm
+++ b/code/game/objects/items/devices/lightreplacer.dm
@@ -53,6 +53,8 @@
var/max_uses = 20
var/uses = 0
+ var/shards = 0
+ var/recycle = 3
var/emagged = 0
var/failmsg = ""
// How much to increase per each glass?
@@ -68,7 +70,7 @@
/obj/item/device/lightreplacer/examine(mob/user)
if(..(user, 2))
- to_chat(user, "It has [uses] lights remaining.")
+ to_chat(user, "It has [uses] lights and [shards] shards remaining.")
/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/stack/sheet/glass))
@@ -89,14 +91,46 @@
if(istype(W, /obj/item/weapon/light))
var/obj/item/weapon/light/L = W
if(L.status == 0) // LIGHT OKAY
+ if(!user.drop_item())
+ to_chat(user, "[L] is stuck to your hand!")
+ return
if(uses < max_uses)
AddUses(1)
to_chat(user, "You insert the [L.name] into the [src.name]. You have [uses] lights remaining.")
user.drop_item()
qdel(L)
return
- else
- to_chat(user, "You need a working light.")
+ else if(L.status == 2 || L.status == 3)
+ if(!user.drop_item())
+ to_chat(user, "[L] is stuck to your hand!")
+ return
+ else
+ AddShards(1)
+ to_chat(user, "You insert [L] into [src]. You have [shards] shards remaining.")
+ user.drop_item()
+ qdel(L)
+ return
+
+ if(istype(W, /obj/item/weapon/storage))
+ var/obj/item/weapon/storage/S = W
+ var/found_lightbulbs = 0
+
+ for(var/obj/item/I in S.contents)
+ if(istype(I,/obj/item/weapon/light))
+ var/obj/item/weapon/light/L = I
+ found_lightbulbs = 1
+ if(uses >= max_uses)
+ to_chat(user, "[src] is full!")
+ break
+ if(L.status == 0)
+ AddUses(1)
+ qdel(L)
+ else if(L.status == 2 || L.status == 3)
+ AddShards(1)
+ qdel(L)
+ to_chat(user, "You fill [src] with lights from [S].")
+ if(!found_lightbulbs)
+ to_chat(user, "[S] contains no bulbs.")
return
/obj/item/device/lightreplacer/emag_act(user as mob)
@@ -128,6 +162,14 @@
/obj/item/device/lightreplacer/proc/AddUses(var/amount = 1)
uses = min(max(uses + amount, 0), max_uses)
+/obj/item/device/lightreplacer/proc/AddShards(amount = 1)
+ shards += amount
+ var/recycled_lights = round(shards / recycle)
+ if(recycled_lights > 0)
+ AddUses(recycled_lights)
+ shards = shards % recycle
+ return recycled_lights
+
/obj/item/device/lightreplacer/proc/Charge(var/mob/user)
charge += 1
if(charge > 7)
@@ -206,4 +248,4 @@
#undef LIGHT_OK
#undef LIGHT_EMPTY
#undef LIGHT_BROKEN
-#undef LIGHT_BURNED
\ No newline at end of file
+#undef LIGHT_BURNED
diff --git a/code/game/objects/items/weapons/holosign.dm b/code/game/objects/items/weapons/holosign.dm
index 5912a055a34..dac93f9cb04 100644
--- a/code/game/objects/items/weapons/holosign.dm
+++ b/code/game/objects/items/weapons/holosign.dm
@@ -11,7 +11,7 @@
throw_range = 7
origin_tech = "programming=3"
var/list/signs = list()
- var/max_signs = 10
+ var/max_signs = 20
/obj/item/weapon/holosign_creator/afterattack(atom/target, mob/user, flag)
if(flag)
@@ -45,4 +45,4 @@
desc = "The words flicker as if they mean nothing."
icon = 'icons/obj/janitor.dmi'
icon_state = "holosign"
- anchored = 1
\ No newline at end of file
+ anchored = 1
diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm
index ae6e8b7888c..600ff934a8f 100644
--- a/code/game/objects/items/weapons/holy_weapons.dm
+++ b/code/game/objects/items/weapons/holy_weapons.dm
@@ -9,6 +9,7 @@
throwforce = 10
w_class = 1
var/reskinned = FALSE
+ var/reskin_selectable = TRUE //set to FALSE if a subtype is meant to not normally be available as a reskin option (fluff ones will get re-added through their list)
var/list/fluff_transformations = list() //does it have any special transformations only accessible to it? Should only be subtypes of /obj/item/weapon/nullrod
/obj/item/weapon/nullrod/suicide_act(mob/user)
@@ -31,7 +32,11 @@
reskin_holy_weapon(user)
/obj/item/weapon/nullrod/proc/reskin_holy_weapon(mob/M)
- var/list/holy_weapons_list = typesof(/obj/item/weapon/nullrod) - typesof(/obj/item/weapon/nullrod/fluff)
+ var/list/holy_weapons_list = typesof(/obj/item/weapon/nullrod)
+ for(var/entry in holy_weapons_list)
+ var/obj/item/weapon/nullrod/variant = entry
+ if(!initial(variant.reskin_selectable))
+ holy_weapons_list -= variant
if(fluff_transformations.len)
for(var/thing in fluff_transformations)
holy_weapons_list += thing
@@ -57,10 +62,13 @@
M.put_in_active_hand(holy_weapon)
qdel(src)
+/obj/item/weapon/nullrod/fluff //fluff subtype to be used for all donator nullrods
+ reskin_selectable = FALSE
+
/obj/item/weapon/nullrod/godhand
+ name = "god hand"
icon_state = "disintegrate"
item_state = "disintegrate"
- name = "god hand"
desc = "This hand of yours glows with an awesome power!"
flags = ABSTRACT | NODROP
w_class = 5
@@ -69,9 +77,9 @@
attack_verb = list("punched", "cross countered", "pummeled")
/obj/item/weapon/nullrod/staff
+ name = "red holy staff"
icon_state = "godstaff-red"
item_state = "godstaff-red"
- name = "red holy staff"
desc = "It has a mysterious, protective aura."
w_class = 5
force = 5
@@ -84,9 +92,9 @@
item_state = "godstaff-blue"
/obj/item/weapon/nullrod/claymore
+ name = "holy claymore"
icon_state = "claymore"
item_state = "claymore"
- name = "holy claymore"
desc = "A weapon fit for a crusade!"
w_class = 4
slot_flags = SLOT_BACK|SLOT_BELT
@@ -102,26 +110,26 @@
return ..()
/obj/item/weapon/nullrod/claymore/darkblade
+ name = "dark blade"
icon_state = "cultblade"
item_state = "cultblade"
- name = "dark blade"
desc = "Spread the glory of the dark gods!"
slot_flags = SLOT_BELT
hitsound = 'sound/hallucinations/growl1.ogg'
/obj/item/weapon/nullrod/claymore/chainsaw_sword
+ name = "sacred chainsaw sword"
icon_state = "chainswordon"
item_state = "chainswordon"
- name = "sacred chainsaw sword"
desc = "Suffer not a heretic to live."
slot_flags = SLOT_BELT
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = 'sound/weapons/chainsaw.ogg'
/obj/item/weapon/nullrod/claymore/glowing
+ name = "force weapon"
icon_state = "swordon"
item_state = "swordon"
- name = "force weapon"
desc = "The blade glows with the power of faith. Or possibly a battery."
slot_flags = SLOT_BELT
@@ -171,9 +179,9 @@
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
/obj/item/weapon/nullrod/scythe
+ name = "reaper scythe"
icon_state = "scythe0"
item_state = "scythe0"
- name = "reaper scythe"
desc = "Ask not for whom the bell tolls..."
w_class = 4
armour_penetration = 35
@@ -184,16 +192,16 @@
hitsound = 'sound/weapons/bladeslice.ogg'
/obj/item/weapon/nullrod/scythe/vibro
+ name = "high frequency blade"
icon_state = "hfrequency0"
item_state = "hfrequency1"
- name = "high frequency blade"
desc = "Bad references are the DNA of the soul."
attack_verb = list("chopped", "sliced", "cut", "zandatsu'd")
/obj/item/weapon/nullrod/scythe/talking
+ name = "possessed blade"
icon_state = "talking_sword"
item_state = "talking_sword"
- name = "possessed blade"
desc = "When the station falls into chaos, it's nice to have a friend by your side."
attack_verb = list("chopped", "sliced", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
@@ -234,9 +242,9 @@
return ..()
/obj/item/weapon/nullrod/hammmer
+ name = "relic war hammer"
icon_state = "hammeron"
item_state = "hammeron"
- name = "relic war hammer"
desc = "This war hammer cost the chaplain fourty thousand space dollars."
slot_flags = SLOT_BELT
w_class = 5
@@ -255,10 +263,10 @@
hitsound = 'sound/weapons/chainsaw.ogg'
/obj/item/weapon/nullrod/clown
+ name = "clown dagger"
icon = 'icons/obj/wizard.dmi'
icon_state = "clownrender"
item_state = "gold_horn"
- name = "clown dagger"
desc = "Used for absolutely hilarious sacrifices."
hitsound = 'sound/items/bikehorn.ogg'
sharp = 1
@@ -342,9 +350,9 @@
item_state = "bostaff0"
/obj/item/weapon/nullrod/tribal_knife
+ name = "arrhythmic knife"
icon_state = "crysknife"
item_state = "crysknife"
- name = "arrhythmic knife"
w_class = 5
desc = "They say fear is the true mind killer, but stabbing them in the head works too. Honour compels you to not sheathe it once drawn."
sharp = 1
@@ -366,9 +374,9 @@
slowdown = rand(-2, 2)
/obj/item/weapon/nullrod/pitchfork
+ name = "unholy pitchfork"
icon_state = "pitchfork0"
item_state = "pitchfork0"
- name = "unholy pitchfork"
w_class = 3
desc = "Holding this makes you look absolutely devilish."
attack_verb = list("poked", "impaled", "pierced", "jabbed")
@@ -377,9 +385,9 @@
edge = 1
/obj/item/weapon/nullrod/rosary
+ name = "prayer beads"
icon_state = "rosary"
item_state = null
- name = "prayer beads"
desc = "A set of prayer beads used by many of the more traditional religions in space. Vampires and other unholy abominations have learned to fear these."
force = 0
throwforce = 0
@@ -445,5 +453,122 @@
if(prob(10))
to_chat(M, "Being in the presence of [holder]'s [src] is interfering with your powers!")
+/obj/item/weapon/nullrod/missionary_staff
+ name = "holy staff"
+ desc = "It has a mysterious, protective aura."
+ description_antag = "This seemingly standard holy staff is actually a disguised neurotransmitter capable of inducing blind zealotry in its victims. It must be allowed to recharge in the presence of a linked set of missionary robes. Activate the staff while wearing robes to link, then aim the staff at your victim to try and convert them."
+ reskinned = TRUE
+ reskin_selectable = FALSE
+ icon_state = "godstaff-red"
+ item_state = "godstaff-red"
+ w_class = 5
+ force = 5
+ slot_flags = SLOT_BACK
+ block_chance = 50
+ var/team_color = "red"
+ var/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe/robes = null //the robes linked with this staff
+ var/faith = 99 //a conversion requires 100 faith to attempt. faith recharges over time while you are wearing missionary robes that have been linked to the staff.
+/obj/item/weapon/nullrod/missionary_staff/New()
+ team_color = pick("red", "blue")
+ icon_state = "godstaff-[team_color]"
+ item_state = "godstaff-[team_color]"
+ name = "[team_color] holy staff"
+
+/obj/item/weapon/nullrod/missionary_staff/Destroy()
+ if(robes) //delink on destruction
+ robes.linked_staff = null
+ robes = null
+ return ..()
+
+/obj/item/weapon/nullrod/missionary_staff/attack_self(mob/user)
+ if(robes) //as long as it is linked, sec can't try to meta by stealing your staff and seeing if they get the link error message
+ return 0
+ if(!ishuman(user)) //prevents the horror (runtimes) of missionary xenos and other non-human mobs that might be able to activate the item
+ return 0
+ var/mob/living/carbon/human/missionary = user
+ if(missionary.wear_suit && istype(missionary.wear_suit, /obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe))
+ var/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe/robe_to_link = missionary.wear_suit
+ if(robe_to_link.linked_staff)
+ to_chat(missionary, "These robes are already linked with a staff and cannot support another. Connection refused.")
+ return 0
+ robes = robe_to_link
+ robes.linked_staff = src
+ to_chat(missionary, "Link established. Faith generators initialized. Go spread the word.")
+ faith = 100 //full charge when a fresh link is made (can't be delinked without destroying the robes so this shouldn't be an exploitable thing)
+ return 1
+ else
+ to_chat(missionary, "You must be wearing the missionary robes you wish to link with this staff.")
+ return 0
+
+/obj/item/weapon/nullrod/missionary_staff/afterattack(mob/living/carbon/human/target, mob/living/carbon/human/missionary, flag, params)
+ if(!istype(target) || !istype(missionary)) //ishuman checks effectively
+ return
+ if(target == missionary) //you can't convert yourself, that would raise too many questions about your own dedication to the cause
+ return
+ if(!robes) //staff must be linked to convert
+ to_chat(missionary, "You must link your staff to a set of missionary robes before attempting conversions.")
+ return
+ if(!missionary.wear_suit || missionary.wear_suit != robes) //must be wearing the robes to convert
+ return
+ if(faith < 100)
+ to_chat(missionary, "You don't have enough faith to attempt a conversion right now.")
+ return
+ to_chat(missionary, "You concentrate on [target] and begin the conversion ritual...")
+ if(!target.mind) //no mind means no conversion, but also means no faith lost.
+ to_chat(missionary, "You halt the conversion as you realize [target] is mindless! Best to save your faith for someone more worthwhile.")
+ return
+ if(do_after(missionary, 40)) //4 seconds to temporarily convert, roughly 1 second faster than a vampire's enthrall ability
+ if(faith < 100) //to stop people from trying to exploit the do_after system to multi-convert, we check again if you have enough faith when it completes
+ to_chat(missionary, "You don't have enough faith to complete the conversion on [target]!")
+ return
+ if(missionary in viewers(target)) //missionary must maintain line of sight to target, but the target doesn't necessary need to be able to see the missionary
+ do_convert(target, missionary)
+ else
+ to_chat(missionary, "You lost sight of the target before they could be converted!")
+ faith -= 25 //they escaped, so you only lost a little faith (to prevent spamming)
+ else //the do_after failed, probably because you moved or dropped the staff
+ to_chat(missionary, "Your concentration was broken!")
+
+/obj/item/weapon/nullrod/missionary_staff/proc/do_convert(mob/living/carbon/human/target, mob/living/carbon/human/missionary)
+ var/convert_duration = 6000 //10 min
+ if(!target || !istype(target) || !missionary || !istype(missionary))
+ return
+ if(ismindslave(target) || target.mind.zealot_master) //mindslaves and zealots override the staff because the staff is just a temporary mindslave
+ to_chat(missionary, "Your faith is strong, but their mind is already slaved to someone else's ideals. Perhaps an inquisition would reveal more...")
+ faith -= 25 //same faith cost as losing sight of them mid-conversion, but did you just find someone who can lead you to a fellow traitor?
+ return
+ if(isloyal(target))
+ if(prob(20)) //loyalty implants typically overpower this, but you CAN get lucky and convert still (20% chance of success)
+ faith -= 125 //yes, this puts it negative. it's gonna take longer to recharge if you manage to convert a one of these people to balance the new power you gained through them
+ to_chat(missionary, "Through sheer willpower, you overcome their closed mind and rally [target] to your cause! You may need a bit longer than usual before your faith is fully recharged, and they won't remain loyal to you for long ...")
+ convert_duration = 3000 //5 min, because the loyalty implant will attempt to counteract the subversion
+ else //80% chance to fail
+ faith -= 75
+ to_chat(missionary, "Your faith is strong, but their mind remains closed to your ideals. Your resolve helps you retain a bit of faith though.")
+ return
+ else if(target.mind.assigned_role == "Psychiatrist" || target.mind.assigned_role == "Librarian") //fancy book lernin helps counter religion (day 0 job love, what madness!)
+ if(prob(35)) //35% chance to fail
+ to_chat(missionary, "This one is well trained in matters of the mind... They will not be swayed as easily as you thought...")
+ faith -=50 //lose half your faith to the book-readers
+ return
+ else
+ to_chat(missionary, "You successfully convert [target] to your cause. The following grows because of your faith!")
+ faith -= 100
+ else if(target.mind.assigned_role == "Civilian")
+ if(prob(55)) //55% chance to take LESS faith than normal, because civies are stupid and easily manipulated
+ to_chat(missionary, "Your message seems to resound well with [target]; converting them was much easier than expected.")
+ faith -= 50
+ else //45% chance to take the normal 100 faith cost
+ to_chat(missionary, "You successfully convert [target] to your cause. The following grows because of your faith!")
+ faith -= 100
+ else //everyone else takes 100 faith cost because they are normal
+ to_chat(missionary, "You successfully convert [target] to your cause. The following grows because of your faith!")
+ faith -= 100
+ //if you made it this far: congratulations! you are now a religious zealot!
+ target.mind.make_zealot(missionary, convert_duration, team_color)
+
+ target << sound('sound/misc/wololo.ogg', 0, 1, 25)
+ missionary.say("WOLOLO!")
+ missionary << sound('sound/misc/wololo.ogg', 0, 1, 25)
diff --git a/code/game/objects/items/weapons/implants/implant_explosive.dm b/code/game/objects/items/weapons/implants/implant_explosive.dm
index 23d35d59995..c02c3ba9fcc 100644
--- a/code/game/objects/items/weapons/implants/implant_explosive.dm
+++ b/code/game/objects/items/weapons/implants/implant_explosive.dm
@@ -133,6 +133,8 @@
/obj/item/weapon/implant/dust
name = "duster implant"
desc = "An alarm which monitors host vital signs, transmitting a radio message and dusting the corpse on death."
+ icon = 'icons/effects/blood.dmi'
+ icon_state = "remains"
/obj/item/weapon/implant/dust/get_data()
var/dat = {"Implant Specifications:
diff --git a/code/game/objects/items/weapons/implants/implant_traitor.dm b/code/game/objects/items/weapons/implants/implant_traitor.dm
index 65aa155c8cb..bb80d50845d 100644
--- a/code/game/objects/items/weapons/implants/implant_traitor.dm
+++ b/code/game/objects/items/weapons/implants/implant_traitor.dm
@@ -45,21 +45,21 @@
return -1
H.implanting = 1
to_chat(H, "You feel completely loyal to [user.name].")
- if(!(user.mind in ticker.mode:implanter))
- ticker.mode:implanter[ref] = list()
- implanters = ticker.mode:implanter[ref]
+ if(!(user.mind in ticker.mode.implanter))
+ ticker.mode.implanter[ref] = list()
+ implanters = ticker.mode.implanter[ref]
implanters.Add(H.mind)
ticker.mode.implanted.Add(H.mind)
ticker.mode.implanted[H.mind] = user.mind
- //ticker.mode:implanter[user.mind] += H.mind
- ticker.mode:implanter[ref] = implanters
+ //ticker.mode.implanter[user.mind] += H.mind
+ ticker.mode.implanter[ref] = implanters
ticker.mode.traitors += H.mind
H.mind.special_role = SPECIAL_ROLE_TRAITOR
to_chat(H, "You're now completely loyal to [user.name]! You now must lay down your life to protect them and assist in their goals at any cost.")
var/datum/objective/protect/mindslave/MS = new
MS.owner = H.mind
- MS.target = user:mind
- MS.explanation_text = "Obey every order from and protect [user:real_name], the [user:mind:assigned_role=="MODE" ? (user:mind:special_role) : (user:mind:assigned_role)]."
+ MS.target = user.mind
+ MS.explanation_text = "Obey every order from and protect [user.real_name], the [user.mind.assigned_role=="MODE" ? (user.mind.special_role) : (user.mind.assigned_role)]."
H.mind.objectives += MS
for(var/datum/objective/objective in H.mind.objectives)
to_chat(H, "Objective #1: [objective.explanation_text]")
diff --git a/code/game/objects/items/weapons/misc.dm b/code/game/objects/items/weapons/misc.dm
index 2ff41257ea1..c230c033437 100644
--- a/code/game/objects/items/weapons/misc.dm
+++ b/code/game/objects/items/weapons/misc.dm
@@ -34,6 +34,9 @@
materials = list(MAT_METAL=50)
attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed")
+/obj/item/weapon/cane/is_crutch()
+ return 1
+
/obj/item/weapon/c_tube
name = "cardboard tube"
desc = "A tube... of cardboard."
diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm
index 12219eadd0b..06bb11dd59e 100644
--- a/code/game/objects/items/weapons/mop.dm
+++ b/code/game/objects/items/weapons/mop.dm
@@ -73,13 +73,13 @@
/obj/item/weapon/mop/advanced
desc = "The most advanced tool in a custodian's arsenal. Just think of all the viscera you will clean up with this!"
name = "advanced mop"
- mopcap = 10
+ mopcap = 15
icon_state = "advmop"
item_state = "mop" //meh will do for now until TG makes one
force = 6
throwforce = 8
throw_range = 4
- mopspeed = 20
+ mopspeed = 10
/obj/item/weapon/mop/advanced/cyborg
mopcap = 40
@@ -90,4 +90,4 @@
/obj/item/weapon/mop/advanced/cyborg/examine(mob/user)
..(user)
- to_chat(user, "The mop's water tank has [round(reagents.get_reagent_amount("water"))] units of water left.")
\ No newline at end of file
+ to_chat(user, "The mop's water tank has [round(reagents.get_reagent_amount("water"))] units of water left.")
diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm
index 395d27d0300..937cc3214a3 100644
--- a/code/game/objects/items/weapons/storage/bags.dm
+++ b/code/game/objects/items/weapons/storage/bags.dm
@@ -33,7 +33,7 @@
icon_state = "trashbag"
item_state = "trashbag"
- w_class = 4
+ w_class = 1
max_w_class = 2
storage_slots = 30
can_hold = list() // any
@@ -46,12 +46,17 @@
/obj/item/weapon/storage/bag/trash/update_icon()
if(contents.len == 0)
+ w_class = 1
icon_state = "[initial(icon_state)]"
else if(contents.len < 12)
+ w_class = 4
icon_state = "[initial(icon_state)]1"
else if(contents.len < 21)
+ w_class = 4
icon_state = "[initial(icon_state)]2"
- else icon_state = "[initial(icon_state)]3"
+ else
+ w_class = 4
+ icon_state = "[initial(icon_state)]3"
/obj/item/weapon/storage/bag/trash/cyborg
@@ -499,4 +504,4 @@
max_combined_w_class = 200
w_class = 1
can_hold = list("/obj/item/slime_extract","/obj/item/weapon/reagent_containers/food/snacks/monkeycube","/obj/item/weapon/reagent_containers/syringe","/obj/item/weapon/reagent_containers/glass/beaker","/obj/item/weapon/reagent_containers/glass/bottle","/obj/item/weapon/reagent_containers/blood","/obj/item/weapon/reagent_containers/hypospray/autoinjector")
- burn_state = FLAMMABLE
\ No newline at end of file
+ burn_state = FLAMMABLE
diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index ac994fe4b77..e3f21a93d30 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -77,8 +77,7 @@
new /obj/item/weapon/melee/energy/sword/saber(src)
new /obj/item/weapon/melee/energy/sword/saber(src)
new /obj/item/weapon/dnainjector/telemut/darkbundle(src)
- new /obj/item/clothing/head/chaplain_hood(src)
- new /obj/item/clothing/suit/chaplain_hoodie(src)
+ new /obj/item/clothing/suit/hooded/chaplain_hoodie(src)
new /obj/item/weapon/card/id/syndicate(src)
return
@@ -205,3 +204,16 @@
..()
new /obj/item/weapon/grenade/clusterbuster/plasma(src)
new /obj/item/weapon/grenade/clusterbuster/n2o(src)
+
+/obj/item/weapon/storage/box/syndie_kit/missionary_set
+ name = "Missionary Starter Kit"
+
+/obj/item/weapon/storage/box/syndie_kit/missionary_set/New()
+ ..()
+ new /obj/item/weapon/nullrod/missionary_staff(src)
+ new /obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe(src)
+ var/obj/item/weapon/storage/bible/B = new /obj/item/weapon/storage/bible(src)
+ if(prob(25)) //an omen of success to come?
+ B.deity_name = "Success"
+ B.icon_state = "greentext"
+ B.item_state = "greentext"
diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm
index 55f7c4d5eb8..e6fcf144013 100644
--- a/code/game/objects/items/weapons/swords_axes_etc.dm
+++ b/code/game/objects/items/weapons/swords_axes_etc.dm
@@ -79,6 +79,9 @@
item_state = "cane_nt"
needs_permit = 0
+/obj/item/weapon/melee/classic_baton/ntcane/is_crutch()
+ return 1
+
//Telescopic baton
/obj/item/weapon/melee/classic_baton/telescopic
name = "telescopic baton"
diff --git a/code/game/response_team.dm b/code/game/response_team.dm
index 9e5605c3b28..81e800a2b00 100644
--- a/code/game/response_team.dm
+++ b/code/game/response_team.dm
@@ -173,9 +173,10 @@ var/ert_request_answered = 0
head_organ.r_hair = hex2num(copytext(hair_c, 2, 4))
head_organ.g_hair = hex2num(copytext(hair_c, 4, 6))
head_organ.b_hair = hex2num(copytext(hair_c, 6, 8))
- M.r_eyes = hex2num(copytext(eye_c, 2, 4))
- M.g_eyes = hex2num(copytext(eye_c, 4, 6))
- M.b_eyes = hex2num(copytext(eye_c, 6, 8))
+ var/eyes_red = hex2num(copytext(eye_c, 2, 4))
+ var/eyes_green = hex2num(copytext(eye_c, 4, 6))
+ var/eyes_blue = hex2num(copytext(eye_c, 6, 8))
+ M.change_eye_color(eyes_red, eyes_green, eyes_blue)
M.s_tone = skin_tone
head_organ.h_style = hair_style
head_organ.f_style = facial_hair_style
diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm
index 3bce2fcfe3d..c1b6d7d2122 100644
--- a/code/game/turfs/simulated.dm
+++ b/code/game/turfs/simulated.dm
@@ -54,17 +54,16 @@
/turf/simulated/Entered(atom/A, atom/OL, ignoreRest = 0)
..()
if(!ignoreRest)
- if(ismob(A)) //only mobs make dirt
- if(prob(80))
- dirt++
+ if(isliving(A) && prob(50))
+ dirt++
- var/obj/effect/decal/cleanable/dirt/dirtoverlay = locate(/obj/effect/decal/cleanable/dirt) in src
- if(dirt >= 100)
- if(!dirtoverlay)
- dirtoverlay = new/obj/effect/decal/cleanable/dirt(src)
- dirtoverlay.alpha = 10
- else if(dirt > 100)
- dirtoverlay.alpha = min(dirtoverlay.alpha + 10, 200)
+ var/obj/effect/decal/cleanable/dirt/dirtoverlay = locate(/obj/effect/decal/cleanable/dirt) in src
+ if(dirt >= 100)
+ if(!dirtoverlay)
+ dirtoverlay = new/obj/effect/decal/cleanable/dirt(src)
+ dirtoverlay.alpha = 10
+ else if(dirt > 100)
+ dirtoverlay.alpha = min(dirtoverlay.alpha + 10, 200)
if(ishuman(A))
var/mob/living/carbon/human/M = A
@@ -138,4 +137,4 @@
. = ..()
smooth_icon_neighbors(src)
-/turf/simulated/proc/is_shielded()
\ No newline at end of file
+/turf/simulated/proc/is_shielded()
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 5946ef77f0a..3a04a11f9e6 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -200,6 +200,9 @@
levelupdate()
CalculateAdjacentTurfs()
+ if(air_master && !ignore_air)
+ air_master.add_to_active(src)
+
if(!keep_cabling && !can_have_cabling())
for(var/obj/structure/cable/C in contents)
qdel(C)
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index b8a1bda8c4c..30b8c8bb8e9 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -893,9 +893,6 @@ var/gamma_ship_location = 1 // 0 = station , 1 = space
toArea = locate(/area/shuttle/gamma/space)
fromArea.move_contents_to(toArea)
- for(var/turf/simulated/floor/mech_bay_recharge_floor/F in toArea)
- F.init_devices()
-
for(var/obj/machinery/power/apc/A in toArea)
A.init()
diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm
index 929e224494c..65721c2bb26 100644
--- a/code/modules/admin/secrets.dm
+++ b/code/modules/admin/secrets.dm
@@ -67,8 +67,9 @@
IC Events
Teams
- Send in the Deathsquad
- Send in a syndicate strike team
+ Send SIT - Syndicate Infiltration Team
+ Send in the Deathsquad
+ Send in a Syndie Strike TeamSend in a HONKsquad Change Security Level Security Level - Green
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 57f1f145f62..9548e189695 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -2260,6 +2260,10 @@
if(usr.client.syndicate_strike_team())
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","Strike")
+ if("infiltrators_syndicate")
+ if(usr.client.syndicate_infiltration_team())
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","SyndieInfiltrationTeam")
if("tripleAI")
usr.client.triple_ai()
feedback_inc("admin_secrets_fun_used",1)
diff --git a/code/modules/admin/verbs/SDQL2/useful_procs.dm b/code/modules/admin/verbs/SDQL2/useful_procs.dm
new file mode 100644
index 00000000000..5dd8d657118
--- /dev/null
+++ b/code/modules/admin/verbs/SDQL2/useful_procs.dm
@@ -0,0 +1,29 @@
+// This one's for you, SDQL fans
+
+// Give this a string and a location to create the object. Examples of using
+// this function:
+/*
+CALL global.json_to_object_arbitrary_vars("{'type':'/obj/item/weapon/crowbar', 'color':'#FF0000','force':5000,'name':'Greytides Gravedigger'}", loc) ON /mob/living/carbon/human WHERE ckey == 'crazylemon'".
+*/
+// This is a bit more flexible than the serialization interface because that interface
+// expects a rigid structure for the data
+/proc/json_to_object_arbitrary_vars(json_data, position)
+ var/data = json_decode(json_data)
+ return list_to_object_arbitrary_vars(data, position)
+
+
+/proc/list_to_object_arbitrary_vars(list/data, position)
+ if(!islist(data))
+ throw EXCEPTION("Not a list.")
+ if(!("type" in data))
+ throw EXCEPTION("No 'type' field in the data")
+ var/path = text2path(data["type"])
+ if(!path)
+ throw EXCEPTION("Path not found: [path]")
+
+ var/atom/movable/thing = new path(position)
+ data -= "type"
+ for(var/attribute in data)
+ thing.vars[attribute] = data[attribute]
+
+ return thing
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 6620d204619..276922e24c5 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -780,11 +780,10 @@ 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/clown_shoes(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves)
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/weapon/storage/belt/utility/full/multitool(M), slot_belt)
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/suit/chaplain_hoodie(M), slot_wear_suit)
+ M.equip_to_slot_or_del(new /obj/item/clothing/suit/hooded/chaplain_hoodie(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/food/snacks/grown/banana(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/weapon/bikehorn(M), slot_r_store)
equip_special_id(M,list(access_clown, access_theatre, access_maint_tunnels), "Tunnel Clown", /obj/item/weapon/card/id)
@@ -913,11 +912,9 @@ 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/device/flashlight(M), slot_in_backpack)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/syndicate(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/weapon/twohanded/dualsaber/red(M), slot_l_hand)
- var/obj/item/clothing/head/chaplain_hood/hood = new(M)
- hood.name = "dark lord hood"
- M.equip_to_slot_or_del(hood, slot_head)
- var/obj/item/clothing/suit/chaplain_hoodie/robe = new(M)
+ var/obj/item/clothing/suit/hooded/chaplain_hoodie/robe = new /obj/item/clothing/suit/hooded/chaplain_hoodie(M)
robe.name = "dark lord robes"
+ robe.hood.name = "dark lord hood"
M.equip_to_slot_or_del(robe, slot_wear_suit)
equip_special_id(M,get_all_accesses(), "Dark Lord", /obj/item/weapon/card/id/syndicate, "syndie")
diff --git a/code/modules/admin/verbs/infiltratorteam_syndicate.dm b/code/modules/admin/verbs/infiltratorteam_syndicate.dm
new file mode 100644
index 00000000000..3babf7d44e3
--- /dev/null
+++ b/code/modules/admin/verbs/infiltratorteam_syndicate.dm
@@ -0,0 +1,219 @@
+// Syndicate Infiltration Team (SIT)
+// A little like Syndicate Strike Team (SST) but geared towards stealthy team missions rather than murderbone.
+
+var/global/sent_syndicate_infiltration_team = 0
+
+/client/proc/syndicate_infiltration_team()
+ set category = "Event"
+ set name = "Send Syndicate Infiltration Team"
+ set desc = "Spawns a squad of syndicate infiltrators on the Syndicate Mothership if you want to run an admin event."
+ if(!check_rights(R_ADMIN))
+ to_chat(src, "Only administrators may use this command.")
+ return
+ if(!ticker)
+ alert("The game hasn't started yet!")
+ return
+ if(alert("Do you want to send in the Syndicate Infiltration Team?",,"Yes","No")=="No")
+ return
+ var/spawn_dummies = 0
+ if(alert("Spawn full-size team, even if there aren't enough ghosts to populate them?",,"Yes","No")=="Yes")
+ spawn_dummies = 1
+ var/pick_manually = 0
+ if(alert("Pick the team members manually? If you select yes, you pick from ghosts. If you select no, ghosts get offered the chance to join.",,"Yes","No")=="Yes")
+ pick_manually = 1
+ var/list/teamsizeoptions = list(1,2,3,4,5)
+ var/teamsize = input(src, "How many team members, not counting the team leader?") as null|anything in teamsizeoptions
+ if(!(teamsize in teamsizeoptions))
+ alert("Invalid team size specified. Aborting.")
+ return
+ var/input = null
+ while(!input)
+ input = sanitize(copytext(input(src, "Please specify which mission the syndicate infiltration team shall undertake.", "Specify Mission", ""),1,MAX_MESSAGE_LEN))
+ if(!input)
+ alert("No mission specified. Aborting.")
+ return
+ var/tctext = input(src, "How much TC do you want to give each team member? Suggested: 20-30. They cannot trade TC.") as num
+ var/tcamount = text2num(tctext)
+ tcamount = between(0, tcamount, 1000)
+ var/spawn_sit_mgmt = 0
+ if(alert("Spawn a syndicate mob for you, so you can brief them before they go?",,"Yes","No")=="Yes")
+ spawn_sit_mgmt = 1
+ if(sent_syndicate_infiltration_team == 1)
+ if(alert("A Syndicate Infiltration Team has already been sent. Sure you want to send another?",,"Yes","No")=="No")
+ return
+
+ var/syndicate_leader_selected = 0
+
+ var/list/infiltrators = list()
+
+ if(pick_manually)
+ var/list/possible_ghosts = list()
+ for(var/mob/dead/observer/G in player_list)
+ if(!G.client.is_afk())
+ if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
+ possible_ghosts += G
+ for(var/i=teamsize,(i>0&&possible_ghosts.len),i--) //Decrease with every SIT member selected.
+ var/candidate = input("Pick characters to spawn as a SIT member. This will go on until there either no more ghosts to pick from, or the slots are full.", "Active Players") as null|anything in possible_ghosts // auto-picks if only one candidate
+ possible_ghosts -= candidate
+ infiltrators += candidate
+ else
+ to_chat(src, "Polling candidates...")
+ infiltrators = pollCandidates("Do you want to play as a SYNDICATE INFILTRATOR?") // ROLE_TRAITOR, 7
+
+ if(!infiltrators.len)
+ to_chat(src, "Nobody volunteered.")
+ return 0
+
+ sent_syndicate_infiltration_team = 1
+
+ var/list/sit_spawns = list()
+ var/list/sit_spawns_leader = list()
+ var/list/sit_spawns_mgmt = list()
+ for(var/obj/effect/landmark/L in landmarks_list)
+ if(L.name == "Syndicate-Infiltrator")
+ sit_spawns += L
+ if(L.name == "Syndicate-Infiltrator-Leader")
+ sit_spawns_leader += L
+ if(L.name == "Syndicate-Infiltrator-Admin")
+ sit_spawns_mgmt += L
+
+ var/num_spawned = 1
+ var/team_leader = null
+ for(var/obj/effect/landmark/L in sit_spawns)
+ if(!infiltrators.len && !spawn_dummies) break
+ syndicate_leader_selected = num_spawned == 1?1:0
+ var/mob/living/carbon/human/new_syndicate_infiltrator = create_syndicate_infiltrator(L, syndicate_leader_selected, tcamount, 0)
+ if(infiltrators.len)
+ var/mob/theguy = pick(infiltrators)
+ if(!spawn_sit_mgmt || theguy.key != key)
+ new_syndicate_infiltrator.key = theguy.key
+ new_syndicate_infiltrator.internal = new_syndicate_infiltrator.s_store
+ new_syndicate_infiltrator.update_internals_hud_icon(1)
+ infiltrators -= theguy
+ to_chat(new_syndicate_infiltrator, "You are a [!syndicate_leader_selected?"Infiltrator":"Lead Infiltrator"] in the service of the Syndicate. \nYour current mission is: [input]")
+ to_chat(new_syndicate_infiltrator, "You are equipped with an uplink implant to help you achieve your objectives. ((activate it via button in top left of screen))")
+ new_syndicate_infiltrator.faction += "syndicate"
+ data_core.manifest_inject(new_syndicate_infiltrator)
+ if(syndicate_leader_selected)
+ var/obj/effect/landmark/warpto = pick(sit_spawns_leader)
+ new_syndicate_infiltrator.loc = warpto.loc
+ sit_spawns_leader -= warpto
+ team_leader = new_syndicate_infiltrator
+ to_chat(new_syndicate_infiltrator, "As team leader, it is up to you to organize your team! Give the job to someone else if you can't handle it. Only your ID opens the exit door.")
+ else
+ to_chat(new_syndicate_infiltrator, "Your team leader is: [team_leader]. They are in charge!")
+ teamsize--
+ to_chat(new_syndicate_infiltrator, "You have more helpful information stored in your Notes.")
+ new_syndicate_infiltrator.mind.store_memory("Mission: [input] ")
+ new_syndicate_infiltrator.mind.store_memory("Team Leader: [team_leader] ")
+ new_syndicate_infiltrator.mind.store_memory("Starting Equipment: - Chameleon Jumpsuit ((right click to Change Color)) - Agent ID card ((disguise as another job)) - Uplink Implant ((top left of screen)) - Dust Implant ((destroys your body on death)) - Combat Gloves ((insulated, disguised as black gloves)) - Anything bought with your uplink implant")
+ var/datum/atom_hud/antag/opshud = huds[ANTAG_HUD_OPS]
+ opshud.join_hud(new_syndicate_infiltrator.mind.current)
+ ticker.mode.set_antag_hud(new_syndicate_infiltrator.mind.current, "hudoperative")
+ new_syndicate_infiltrator.regenerate_icons()
+ num_spawned++
+ if(!teamsize)
+ break
+ if(spawn_sit_mgmt)
+ for(var/obj/effect/landmark/L in sit_spawns_mgmt)
+ var/mob/living/carbon/human/syndimgmtmob = create_syndicate_infiltrator(L, 1, 100, 1)
+ syndimgmtmob.key = key
+ syndimgmtmob.internal = syndimgmtmob.s_store
+ syndimgmtmob.update_internals_hud_icon(1)
+ syndimgmtmob.faction += "syndicate"
+ syndimgmtmob.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(src), slot_glasses)
+ syndimgmtmob.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/syndi/elite, slot_wear_suit)
+ syndimgmtmob.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/syndi/elite, slot_head)
+ syndimgmtmob.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate, slot_wear_mask)
+ var/datum/atom_hud/antag/opshud = huds[ANTAG_HUD_OPS]
+ opshud.join_hud(syndimgmtmob.mind.current)
+ ticker.mode.set_antag_hud(syndimgmtmob.mind.current, "hudoperative")
+ syndimgmtmob.mind.special_role = "Syndicate Management Consultant"
+ syndimgmtmob.regenerate_icons()
+ to_chat(syndimgmtmob, "You have spawned as Syndicate Management. You should brief them on their mission before they go.")
+ message_admins("[key_name_admin(src)] has spawned a Syndicate Infiltration Team.", 1)
+ log_admin("[key_name(src)] used Spawn Syndicate Infiltration Team.")
+ feedback_add_details("admin_verb","SPAWNSIT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+// ---------------------------------------------------------------------------------------------------------
+
+/client/proc/create_syndicate_infiltrator(obj/spawn_location, syndicate_leader_selected = 0, uplink_tc = 20, is_mgmt = 0)
+ var/mob/living/carbon/human/new_syndicate_infiltrator = new(spawn_location.loc)
+
+ var/syndicate_infiltrator_name = random_name(pick(MALE,FEMALE))
+
+ var/datum/preferences/A = new() //Randomize appearance
+ A.real_name = syndicate_infiltrator_name
+ A.copy_to(new_syndicate_infiltrator)
+
+ new_syndicate_infiltrator.dna.ready_dna(new_syndicate_infiltrator) //Creates DNA.
+
+ //Creates mind stuff.
+ new_syndicate_infiltrator.mind_initialize()
+ new_syndicate_infiltrator.mind.assigned_role = "MODE"
+ new_syndicate_infiltrator.mind.special_role = "Syndicate Infiltrator"
+ ticker.mode.traitors |= new_syndicate_infiltrator.mind //Adds them to extra antag list
+ new_syndicate_infiltrator.equip_syndicate_infiltrator(syndicate_leader_selected, uplink_tc, is_mgmt)
+ qdel(spawn_location)
+ return new_syndicate_infiltrator
+
+// ---------------------------------------------------------------------------------------------------------
+
+/mob/living/carbon/human/proc/equip_syndicate_infiltrator(syndicate_leader_selected = 0, num_tc, flag_mgmt)
+ // Storage items
+ equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(src), slot_back)
+ equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(src), slot_in_backpack)
+ equip_to_slot_or_del(new /obj/item/clothing/under/chameleon(src), slot_w_uniform)
+ if(!flag_mgmt)
+ equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_in_backpack)
+ equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full/multitool(src), slot_belt)
+
+ var/obj/item/clothing/gloves/combat/G = new /obj/item/clothing/gloves/combat(src)
+ G.name = "black gloves"
+ equip_to_slot_or_del(G, slot_gloves)
+
+ // Implants:
+ // Uplink
+ var/obj/item/weapon/implant/uplink/U = new /obj/item/weapon/implant/uplink(src)
+ U.implant(src)
+ if (flag_mgmt)
+ U.hidden_uplink.uses = 500
+ else
+ U.hidden_uplink.uses = num_tc
+ // Storage
+ //var/obj/item/weapon/implant/storage/T = new /obj/item/weapon/implant/storage(src)
+ //T.implant(src)
+ // Dust
+ var/obj/item/weapon/implant/dust/D = new /obj/item/weapon/implant/dust(src)
+ D.implant(src)
+
+ // Radio & PDA
+ var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate(src)
+ R.set_frequency(SYND_FREQ) //Same frequency as the syndicate team in Nuke mode.
+ equip_to_slot_or_del(R, slot_l_ear)
+ equip_or_collect(new /obj/item/device/pda(src), slot_in_backpack)
+
+ // Other gear
+ equip_to_slot_or_del(new /obj/item/clothing/shoes/syndigaloshes(src), slot_shoes)
+
+ var/obj/item/weapon/card/id/syndicate/W = new(src) //Untrackable by AI
+ if (flag_mgmt)
+ W.icon_state = "commander"
+ else
+ W.icon_state = "id"
+ W.access = list(access_maint_tunnels,access_external_airlocks)
+ W.assignment = "Civilian"
+ W.access += get_access("Civilian")
+ W.access += list(access_medical, access_engine, access_cargo, access_research)
+ if(flag_mgmt)
+ W.assignment = "Syndicate Management Consultant"
+ W.access += get_syndicate_access("Syndicate Commando")
+ else if(syndicate_leader_selected)
+ W.access += get_syndicate_access("Syndicate Commando")
+ else
+ W.access += get_syndicate_access("Syndicate Operative")
+ W.name = "[real_name]'s ID Card ([W.assignment])"
+ W.registered_name = real_name
+ equip_to_slot_or_del(W, slot_wear_id)
+
+ return 1
diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm
index aec910f5bb6..5460d90dd6a 100644
--- a/code/modules/admin/verbs/striketeam_syndicate.dm
+++ b/code/modules/admin/verbs/striketeam_syndicate.dm
@@ -79,7 +79,7 @@ var/global/sent_syndicate_strike_team = 0
new_syndicate_commando.mind.store_memory("Mission: \red [input].")
to_chat(new_syndicate_commando, "\blue You are an Elite Syndicate. [!syndicate_leader_selected?"commando":"LEADER"] in the service of the Syndicate. \nYour current mission is: [input]")
-
+ new_syndicate_commando.faction += "syndicate"
syndicate_commando_number--
//Spawns the rest of the commando gear.
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index 2a23732a90b..baf1a9a950d 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -174,7 +174,7 @@
return
dir = turn(dir, 90)
-
+
if(usr.machine == src)
interact(usr)
@@ -246,7 +246,9 @@
hit()
/obj/effect/beam/i_beam/Crossed(atom/movable/AM as mob|obj)
- if(istype(AM, /obj/effect/beam) || !AM.density)
+ if(!isobj(AM) && !isliving(AM))
+ return
+ if(istype(AM, /obj/effect))
return
hit()
@@ -259,4 +261,4 @@
if(previous)
previous.next = null
master.last = previous
- return ..()
\ No newline at end of file
+ return ..()
diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm
index 267d1600523..3b1e5b3a6c7 100644
--- a/code/modules/assembly/proximity.dm
+++ b/code/modules/assembly/proximity.dm
@@ -42,7 +42,9 @@
HasProximity(atom/movable/AM as mob|obj)
- if(istype(AM, /obj/effect/beam)) return
+ if(!isobj(AM) && !isliving(AM))
+ return
+ if(istype(AM, /obj/effect)) return
if(AM.move_speed < 12) sense()
return
diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm
index d8491b4a38b..635169bf89b 100644
--- a/code/modules/client/preference/preferences.dm
+++ b/code/modules/client/preference/preferences.dm
@@ -1850,10 +1850,6 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
character.age = age
character.b_type = b_type
- character.r_eyes = r_eyes
- character.g_eyes = g_eyes
- character.b_eyes = b_eyes
-
//Head-specific
var/obj/item/organ/external/head/H = character.get_organ("head")
H.r_hair = r_hair
@@ -1973,6 +1969,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
message_admins("[key_name_admin(character)] has spawned with their gender as plural or neuter. Please notify coders.")
character.change_gender(MALE)
+ character.change_eye_color(r_eyes, g_eyes, b_eyes)
+
character.dna.ready_dna(character, flatten_SE = 0)
character.sync_organ_dna(assimilate=1)
character.UpdateAppearance()
@@ -2015,4 +2013,4 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
popup.open(0)
/datum/preferences/proc/close_load_dialog(mob/user)
- user << browse(null, "window=saves")
\ No newline at end of file
+ user << browse(null, "window=saves")
diff --git a/code/modules/client/preference/preferences_toggles.dm b/code/modules/client/preference/preferences_toggles.dm
index 541dee07242..10f6c58982f 100644
--- a/code/modules/client/preference/preferences_toggles.dm
+++ b/code/modules/client/preference/preferences_toggles.dm
@@ -194,20 +194,6 @@
to_chat(src, "You will no longer hear musical instruments.")
feedback_add_details("admin_verb","TInstru") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/client/verb/toggle_media()
- set name = "Hear/Silence Streaming"
- set category = "Preferences"
- set desc = "Toggle hearing streaming media (radios, jukeboxes, etc)"
-
- prefs.sound ^= SOUND_STREAMING
- prefs.save_preferences(src)
- to_chat(usr, "You will [(prefs.sound & SOUND_STREAMING) ? "now" : "no longer"] hear streamed media.")
- if(!media) return
- if(prefs.sound & SOUND_STREAMING)
- media.update_music()
- else
- media.stop_music()
-
/client/verb/setup_character()
set name = "Game Preferences"
set category = "Preferences"
diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm
index 2133fe98e48..98e5026ae81 100644
--- a/code/modules/clothing/head/misc.dm
+++ b/code/modules/clothing/head/misc.dm
@@ -177,21 +177,25 @@
desc = "There's a new sheriff in town. Pass the whiskey."
/obj/item/clothing/head/fedora
- name = "\improper fedora"
+ name = "fedora"
icon_state = "fedora"
item_state = "fedora"
desc = "A great hat ruined by being within fifty yards of you."
+ actions_types = list(/datum/action/item_action/tip_fedora)
-//TIPS FEDORA
-/obj/item/clothing/head/fedora/verb/tip_fedora()
- set name = "Tip Fedora"
- set category = "Object"
- set desc = "Show that CIS SCUM who's boss."
+/obj/item/clothing/head/fedora/attack_self(mob/user)
+ tip_fedora(user)
+
+/obj/item/clothing/head/fedora/item_action_slot_check(slot)
+ if(slot == slot_head)
+ return 1
+
+/obj/item/clothing/head/fedora/proc/tip_fedora(mob/user)
+ user.visible_message("[user] tips their fedora.", "You tip your fedora")
- usr.visible_message("[usr] tips their fedora.","You tip your fedora")
/obj/item/clothing/head/fez
- name = "\improper fez"
+ name = "fez"
icon_state = "fez"
item_state = "fez"
desc = "Put it on your monkey, make lots of cash money."
diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm
index e7dae7d04da..8727065fb5b 100644
--- a/code/modules/clothing/head/soft_caps.dm
+++ b/code/modules/clothing/head/soft_caps.dm
@@ -5,25 +5,29 @@
item_state = "helmet"
item_color = "cargo"
var/flipped = 0
+ actions_types = list(/datum/action/item_action/flip_cap)
- dropped()
- src.icon_state = "[item_color]soft"
- src.flipped=0
- ..()
+/obj/item/clothing/head/soft/dropped()
+ icon_state = "[item_color]soft"
+ flipped = 0
+ ..()
- verb/flip()
- set category = "Object"
- set name = "Flip cap"
- set src in usr
- if(usr.canmove && !usr.stat && !usr.restrained())
- src.flipped = !src.flipped
- if(src.flipped)
- icon_state = "[item_color]soft_flipped"
- to_chat(usr, "You flip the hat backwards.")
- else
- icon_state = "[item_color]soft"
- to_chat(usr, "You flip the hat back in normal position.")
- usr.update_inv_head() //so our mob-overlays update
+/obj/item/clothing/head/soft/attack_self(mob/user)
+ flip(user)
+
+/obj/item/clothing/head/soft/proc/flip(mob/user)
+ flipped = !flipped
+ if(flipped)
+ icon_state = "[item_color]soft_flipped"
+ to_chat(usr, "You flip the hat backwards.")
+ else
+ icon_state = "[item_color]soft"
+ to_chat(user, "You flip the hat back in normal position.")
+ user.update_inv_head() //so our mob-overlays update
+
+ for(var/X in actions)
+ var/datum/action/A = X
+ A.UpdateButtonIcon()
/obj/item/clothing/head/soft/red
name = "red cap"
diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm
index dd66740f966..f299419ed09 100644
--- a/code/modules/clothing/masks/miscellaneous.dm
+++ b/code/modules/clothing/masks/miscellaneous.dm
@@ -82,6 +82,7 @@
desc = "moustache is totally real."
icon_state = "fake-moustache"
flags_inv = HIDEFACE
+ actions_types = list(/datum/action/item_action/pontificate)
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/mask.dmi',
@@ -90,12 +91,15 @@
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi'
)
-/obj/item/clothing/mask/fakemoustache/verb/pontificate()
- set name = "Pontificate Evilly"
- set category = "Object"
- set desc = "Devise evil plans of evilness."
+/obj/item/clothing/mask/fakemoustache/attack_self(mob/user)
+ pontificate(user)
- usr.visible_message("\ [usr] twirls \his moustache and laughs [pick("fiendishly","maniacally","diabolically","evilly")]!")
+/obj/item/clothing/mask/fakemoustache/item_action_slot_check(slot)
+ if(slot == slot_wear_mask)
+ return 1
+
+/obj/item/clothing/mask/fakemoustache/proc/pontificate(mob/user)
+ user.visible_message("\ [user] twirls \his moustache and laughs [pick("fiendishly","maniacally","diabolically","evilly")]!")
//scarves (fit in in mask slot)
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index 7f75043bf96..8798caf2e06 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -857,3 +857,45 @@
user.reagents.add_reagent("syndicate_nanites", 15)
else
processing_objects.Remove(src)
+
+//Syndicate Chaplain Robe (WOLOLO!)
+/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe
+ description_antag = "This robe is made of reinforced fibers, granting it superior protection. The robes also wirelessly generate power for the neurotransmitter in the linked missionary staff while being worn."
+ armor = list(melee = 10, bullet = 10, laser = 5, energy = 5, bomb = 0, bio = 0, rad = 15)
+ var/obj/item/weapon/nullrod/missionary_staff/linked_staff = null
+
+/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe/Destroy()
+ if(linked_staff) //delink on destruction
+ linked_staff.robes = null
+ linked_staff = null
+ processing_objects -= src //probably is cleared in a parent call already, but just in case we're gonna do it here
+ return ..()
+
+/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe/equipped(mob/living/carbon/human/H, slot)
+ if(!istype(H) || slot != slot_wear_suit)
+ processing_objects -= src
+ return
+ else
+ processing_objects |= src
+
+/obj/item/clothing/suit/hooded/chaplain_hoodie/missionary_robe/process()
+ if(!linked_staff) //if we don't have a linked staff, the rest of this is useless
+ return
+
+ if(!ishuman(loc)) //if we somehow try to process while not on a human, remove ourselves from processing and return
+ processing_objects -= src
+ return
+
+ var/mob/living/carbon/human/H = loc
+
+ if(linked_staff.faith >= 100) //if the linked staff is fully recharged, do nothing
+ return
+
+ if(!linked_staff in range(3, get_turf(src))) //staff won't charge at range (to prevent it from being handed off / stolen and used)
+ if(prob(10)) //10% chance per process should avoid being too spammy, can tweak if it ends up still being too frequent.
+ to_chat(H, "Your staff is unable to charge at this range. Get closer!")
+ return
+
+ linked_staff.faith += 5
+ if(linked_staff.faith >= 100) //if this charge puts the staff at or above full, notify the wearer
+ to_chat(H, "Faith renewed; ready to convert new followers.")
\ No newline at end of file
diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm
index 5b83cfb0415..668737dd1dd 100644
--- a/code/modules/customitems/item_defines.dm
+++ b/code/modules/customitems/item_defines.dm
@@ -326,6 +326,11 @@
if(H.head == src)
H.slurring = max(3, H.slurring) //always slur
+/obj/item/clothing/head/beret/fluff/linda //Epic_Charger: Linda Clark
+ name = "Green beret"
+ desc = "A beret, an artist's favorite headwear. This one has two holes cut on the edges."
+ icon_state = "linda_beret"
+
//////////// Suits ////////////
/obj/item/clothing/suit/storage/labcoat/fluff/aeneas_rinil //Socialsystem: Lynn Fea
name = "Robotics labcoat"
@@ -392,6 +397,16 @@
icon = 'icons/obj/custom_items.dmi'
icon_state = "stobarico_jacket"
+
+/obj/item/clothing/suit/hooded/hoodie/fluff/linda // Epic_Charger: Linda Clark
+ name = "Green Nanotrasen Hoodie"
+ desc = "A green hoodie with the Nanotrasen logo on the back. It looks weathered."
+ icon_state = "linda_hoodie"
+ hoodtype = /obj/item/clothing/head/hood/fluff/linda
+
+/obj/item/clothing/head/hood/fluff/linda //Epic_Charger: Linda Clark
+ icon_state = "greenhood"
+
//////////// Uniforms ////////////
/obj/item/clothing/under/fluff/kharshai // Kharshai: Athena Castile
name = "Castile formal outfit"
diff --git a/code/modules/detective_work/scanner.dm b/code/modules/detective_work/scanner.dm
index 58c1c31a3b8..be8e7d147a2 100644
--- a/code/modules/detective_work/scanner.dm
+++ b/code/modules/detective_work/scanner.dm
@@ -14,6 +14,7 @@
origin_tech = "magnets=4;biotech=2"
var/scanning = 0
var/list/log = list()
+ actions_types = list(/datum/action/item_action/print_report)
/obj/item/device/detective_scanner/attack_self(var/mob/user)
var/search = input(user, "Enter name, fingerprint or blood DNA.", "Find record", "")
@@ -58,11 +59,10 @@
to_chat(user, "No match found in station records.")
+/obj/item/device/detective_scanner/ui_action_click()
+ print_scanner_report()
-/obj/item/device/detective_scanner/verb/print_scanner_report()
- set name = "Print Scanner Report"
- set category = "Object"
-
+/obj/item/device/detective_scanner/proc/print_scanner_report()
if(log.len && !scanning)
scanning = 1
to_chat(usr, "Printing report, please wait...")
diff --git a/code/modules/garbage_collection/garbage_collector.dm b/code/modules/garbage_collection/garbage_collector.dm
index 29db9198ae4..c33190d4203 100644
--- a/code/modules/garbage_collection/garbage_collector.dm
+++ b/code/modules/garbage_collection/garbage_collector.dm
@@ -60,8 +60,6 @@ var/global/datum/controller/process/garbage_collector/garbageCollector
queue.Cut(1, 2)
remainingForceDelPerTick--
- // Sleep check more aggressively when force deleting.
- calls_since_last_scheck += 9
else // Otherwise, it was GC'd - remove it from the queue
queue.Cut(1, 2)
soft_dels++
diff --git a/code/modules/media/broadcast/receiver.dm b/code/modules/media/broadcast/receiver.dm
deleted file mode 100644
index e4f083bdc6d..00000000000
--- a/code/modules/media/broadcast/receiver.dm
+++ /dev/null
@@ -1,46 +0,0 @@
-// frequency => list(listeners)
-var/global/media_receivers=list()
-
-
-///////////////////////
-// RECEIVERS
-///////////////////////
-
-/obj/machinery/media/receiver
- var/media_frequency = 1015 // 123.4 MHz
- var/media_crypto = null // Crypto key
-
-/obj/machinery/media/receiver/New()
- ..()
- connect_frequency()
-
-/obj/machinery/media/receiver/proc/receive_broadcast(var/url="", var/start_time=0)
- media_url = url
- media_start_time = start_time
- update_music()
-
-/obj/machinery/media/receiver/proc/connect_frequency()
- // This is basically media_receivers["[media_frequency]"] += src
- var/list/receivers=list()
- var/freq = num2text(media_frequency)
- if(freq in media_receivers)
- receivers = media_receivers[freq]
- receivers.Add(src)
- media_receivers[freq]=receivers
-
- // Check if there's a broadcast to tune into.
- if(freq in media_transmitters)
- // Pick a random broadcast in that frequency.
- var/obj/machinery/media/transmitter/B = pick(media_transmitters[freq])
- if(B.media_crypto == media_crypto) // Crypto-key check, if needed.
- receive_broadcast(B.media_url,B.media_start_time)
-
-/obj/machinery/media/receiver/proc/disconnect_frequency()
- var/list/receivers=list()
- var/freq = num2text(media_frequency)
- if(freq in media_receivers)
- receivers = media_receivers[freq]
- receivers.Remove(src)
- media_receivers[freq]=receivers
-
- receive_broadcast()
diff --git a/code/modules/media/broadcast/receivers/radio.dm b/code/modules/media/broadcast/receivers/radio.dm
deleted file mode 100644
index a0d94dcbf31..00000000000
--- a/code/modules/media/broadcast/receivers/radio.dm
+++ /dev/null
@@ -1,84 +0,0 @@
-/obj/machinery/media/receiver/boombox
- name = "Boombox"
- desc = "Tune in and tune out."
-
- icon='icons/obj/radio.dmi'
- icon_state="radio"
-
- var/on=0
-
-/obj/machinery/media/receiver/boombox/initialize()
- ..()
- if(on)
- update_on()
- update_icon()
-
-/obj/machinery/media/receiver/boombox/attack_hand(var/mob/user)
- if(stat & (NOPOWER|BROKEN))
- to_chat(usr, "\red You don't see anything to mess with.")
- return
- user.set_machine(src)
- interact(user)
-
-/obj/machinery/media/receiver/boombox/interact(var/mob/user)
- var/dat = "[src]"
- dat += {"
- Power: [on ? "On" : "Off"]
- Frequency: [format_frequency(media_frequency)]
- "}
- dat+={""}
- user << browse(dat, "window=radio-recv")
- onclose(user, "radio-recv")
- return
-
-/obj/machinery/media/receiver/boombox/proc/update_on()
- if(on)
- visible_message("\The [src] hisses to life!")
- playing=1
- connect_frequency()
- else
- visible_message("\The [src] falls quiet.")
- playing=0
- disconnect_frequency()
-
-/obj/machinery/media/receiver/boombox/Topic(href,href_list)
- ..()
- if("power" in href_list)
- on = !on
- update_on()
- if("set_freq" in href_list)
- var/newfreq=media_frequency
- if(href_list["set_freq"]!="-1")
- newfreq = text2num(href_list["set_freq"])
- else
- newfreq = input(usr, "Set a new frequency (MHz, 90.0, 200.0).", src, media_frequency) as null|num
- if(newfreq)
- if(findtext(num2text(newfreq), "."))
- newfreq *= 10 // shift the decimal one place
- if(newfreq > 900 && newfreq < 2000) // Between (90.0 and 100.0)
- disconnect_frequency()
- media_frequency = newfreq
- connect_frequency()
- else
- to_chat(usr, "\red Invalid FM frequency. (90.0, 200.0)")
- updateDialog()
-
-
-/obj/machinery/media/receiver/boombox/wallmount
- name = "Sound System"
- desc = "This plays music for this room."
-
- icon='icons/obj/radio.dmi'
- icon_state="wallradio"
- anchored=1
-
-/obj/machinery/media/receiver/boombox/wallmount/muzak
- on=1
- media_frequency=1015
-
-/obj/machinery/media/receiver/boombox/wallmount/update_on()
- ..()
- if(on)
- icon_state="wallradio-p"
- else
- icon_state="wallradio"
diff --git a/code/modules/media/broadcast/transmitter.dm b/code/modules/media/broadcast/transmitter.dm
deleted file mode 100644
index 92c37f9d917..00000000000
--- a/code/modules/media/broadcast/transmitter.dm
+++ /dev/null
@@ -1,46 +0,0 @@
-var/global/media_transmitters=list()
-
-///////////////////////
-// BROADCASTERS
-///////////////////////
-
-/obj/machinery/media/transmitter
- var/media_frequency = 1234 // 123.4 MHz
- var/media_crypto = null // No crypto keys.
-
-/obj/machinery/media/transmitter/New()
- ..()
- connect_frequency()
-
-/obj/machinery/media/transmitter/proc/broadcast(var/url="", var/start_time=0)
- media_url = url
- media_start_time = start_time
- update_music()
-
-/obj/machinery/media/transmitter/proc/connect_frequency()
- var/list/transmitters=list()
- var/freq = num2text(media_frequency)
- if(freq in media_transmitters)
- transmitters = media_transmitters[freq]
- transmitters.Add(src)
- media_transmitters[freq]=transmitters
-
-
-/obj/machinery/media/transmitter/update_music()
- //..()
- var/freq = num2text(media_frequency)
- if(freq in media_receivers)
- for(var/obj/machinery/media/receiver/R in media_receivers[freq])
- if(R.media_crypto == media_crypto)
- R.receive_broadcast(media_url,media_start_time)
- //testing("[src]: Sending music to [R]")
-
-/obj/machinery/media/transmitter/proc/disconnect_frequency()
- var/list/transmitters=list()
- var/freq = num2text(media_frequency)
- if(freq in media_transmitters)
- transmitters = media_transmitters[freq]
- transmitters.Remove(src)
- media_transmitters[freq]=transmitters
-
- broadcast()
diff --git a/code/modules/media/broadcast/transmitters/broadcast.dm b/code/modules/media/broadcast/transmitters/broadcast.dm
deleted file mode 100644
index 898771b496d..00000000000
--- a/code/modules/media/broadcast/transmitters/broadcast.dm
+++ /dev/null
@@ -1,221 +0,0 @@
-/obj/machinery/media/transmitter/broadcast
- name = "Radio Transmitter"
- desc = "A huge hulk of steel containing high-powered phase-modulating radio transmitting equipment."
-
- icon = 'icons/obj/machines/broadcast.dmi'
- icon_state = "broadcaster"
- light_color="#4285F4"
- use_power = 1
- idle_power_usage = 50
- active_power_usage = 1000
-
- var/on=0
- var/integrity=100
- var/list/obj/machinery/media/sources=list()
- var/heating_power=40000
- var/list/autolink = null
-
- var/const/RADS_PER_TICK=150
- var/const/MAX_TEMP=70 // Celsius
-
-/obj/machinery/media/transmitter/broadcast/initialize()
- ..()
- testing("[type]/initialize() called!")
- if(autolink && autolink.len)
- for(var/obj/machinery/media/source in orange(20, src))
- if(source.id_tag in autolink)
- sources.Add(source)
- testing("Autolinked [source] -> [src]")
- hook_media_sources()
- if(on)
- update_on()
- update_icon()
-
-/obj/machinery/media/transmitter/broadcast/proc/hook_media_sources()
- if(!sources.len)
- return
-
- for(var/obj/machinery/media/source in sources)
- // Hook into output
- source.hookMediaOutput(src,exclusive=1) // Don't hook into the room media sources.
- source.update_music() // Request music update
-
-/obj/machinery/media/transmitter/broadcast/proc/unhook_media_sources()
- if(!sources.len)
- return
-
- for(var/obj/machinery/media/source in sources)
- source.unhookMediaOutput(src)
-
- broadcast() // Bzzt
-/*
-/obj/machinery/media/transmitter/broadcast/attackby(var/obj/item/W, mob/user, params)
- if(istype(W, /obj/item/device/multitool))
- update_multitool_menu(user)
- return 1
-
-/obj/machinery/media/transmitter/broadcast/attack_ai(var/mob/user as mob)
- src.add_hiddenprint(user)
- attack_hand(user)
-
-/obj/machinery/media/transmitter/broadcast/attack_hand(var/mob/user as mob)
- update_multitool_menu(user)
-
-/obj/machinery/media/transmitter/broadcast/multitool_menu(var/mob/user,var/obj/item/device/multitool/P)
- // You need a multitool to use this, or be silicon
- if(!issilicon(user))
- // istype returns false if the value is null
- if(!istype(user.get_active_hand(), /obj/item/device/multitool))
- return
-
- if(stat & (BROKEN|NOPOWER))
- return
-
- var/screen = {"
-
"
- user.set_machine(src)
- var/datum/browser/popup = new (user,"jukebox",name,420,700)
- popup.set_content(t)
- popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
- popup.open()
-
-
-/obj/machinery/media/jukebox/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/weapon/card/emag))
- current_song=0
- if(!emagged)
- playlist_id = "emagged"
- last_reload=world.time
- playlist=null
- loop_mode = JUKEMODE_SHUFFLE
- emagged = 1
- playing = 1
- user.visible_message("\red [user.name] slides something into the [src.name]'s card-reader.","\red You short out the [src.name].")
- update_icon()
- update_music()
- else if(istype(W,/obj/item/weapon/wrench))
- var/un = !anchored ? "" : "un"
- user.visible_message("\blue [user.name] begins [un]locking \the [src.name]'s casters.","\blue You begin [un]locking \the [src.name]'s casters.")
- if(do_after(user,30, target = src))
- playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
- anchored = !anchored
- user.visible_message("\blue [user.name] [un]locks \the [src.name]'s casters.","\red You [un]lock \the [src.name]'s casters.")
- playing = emagged
- update_music()
- update_icon()
-
-/obj/machinery/media/jukebox/Topic(href, href_list)
- ..()
- if(emagged)
- to_chat(usr, "\red You touch the bluescreened menu. Nothing happens. You feel dumber.")
- return
-
- if(href_list["power"])
- playing=!playing
- update_music()
- update_icon()
-
- if(href_list["playlist"])
- if(!check_reload())
- to_chat(usr, "\red You must wait 60 seconds between playlist reloads.")
- return
- playlist_id=href_list["playlist"]
- last_reload=world.time
- playlist=null
- current_song=0
- update_music()
- update_icon()
-
- if(href_list["song"])
- current_song=Clamp(text2num(href_list["song"]),1,playlist.len)
- update_music()
- update_icon()
-
- if(href_list["mode"])
- loop_mode = (loop_mode % JUKEMODE_COUNT) + 1
-
- return attack_hand(usr)
-
-/obj/machinery/media/jukebox/process()
- if(!playlist)
- var/url="[config.media_base_url]/index.php?playlist=[playlist_id]"
- //testing("[src] - Updating playlist from [url]...")
- var/response = world.Export(url)
- playlist=list()
- if(response)
- var/json = file2text(response["CONTENT"])
- if("/>" in json)
- visible_message("[bicon(src)] \The [src] buzzes, unable to update its playlist.","You hear a buzz.")
- stat &= BROKEN
- update_icon()
- return
- var/songdata = json_decode(json)
- for(var/list/record in songdata)
- playlist += new /datum/song_info(record)
- if(playlist.len==0)
- visible_message("[bicon(src)] \The [src] buzzes, unable to update its playlist.","You hear a buzz.")
- stat &= BROKEN
- update_icon()
- return
- visible_message("[bicon(src)] \The [src] beeps, and the menu on its front fills with [playlist.len] items.","You hear a beep.")
- if(autoplay)
- playing=1
- autoplay=0
- else
- //testing("[src] failed to update playlist: Response null.")
- stat &= BROKEN
- update_icon()
- return
- if(playing)
- var/datum/song_info/song
- if(current_song)
- song = playlist[current_song]
- if(!current_song || (song && world.time >= media_start_time + song.length))
- current_song=1
- switch(loop_mode)
- if(JUKEMODE_SHUFFLE)
- current_song=rand(1,playlist.len)
- if(JUKEMODE_REPEAT_SONG)
- current_song=current_song
- if(JUKEMODE_PLAY_ONCE)
- playing=0
- update_icon()
- return
- update_music()
-
-/obj/machinery/media/jukebox/update_music()
- if(current_song && playing)
- var/datum/song_info/song = playlist[current_song]
- media_url = song.url
- media_start_time = world.time
- visible_message("[bicon(src)] \The [src] begins to play [song.display()].","You hear music.")
- //visible_message("[bicon(src)] \The [src] warbles: [song.length/10]s @ [song.url]")
- else
- media_url=""
- media_start_time = 0
- ..()
-
-/obj/machinery/media/jukebox/proc/stop_playing()
- //current_song=0
- playing=0
- update_music()
- return
-
-/obj/machinery/media/jukebox/bar
- playlist_id="bar"
- // Must be defined on your server.
- playlists=list(
- "bar" = "Bar Mix",
- "aussie" = "Aussie",
- "club" = "Club",
- "lounge" = "Portishead - Dummy",
- "customs" = "Customs Music",
- )
-
-// Relaxing elevator music~
-/obj/machinery/media/jukebox/dj
-
- playlist_id="bar"
- autoplay = 1
-
- id_tag="DJ Satellite" // For autolink
-
- // Must be defined on your server.
- playlists=list(
- "bar" = "Bar Mix",
- "aussie" = "Aussie",
- "club" = "Club",
- "lounge" = "Portishead - Dummy",
- "customs" = "Customs Music",
- )
-
-/obj/machinery/media/jukebox/techno
- name = "Techno disc"
- desc = "Looks like an oldschool mixing board that somehow plays music, don't ask us how, we don't know."
- state_base = "mixer"
- playlist_id="club"
-
- playlists=list(
- "club" = "Club Mix",
-
- )
-
-/obj/machinery/media/jukebox/shuttle
- playlist_id="shuttle"
- // Must be defined on your server.
- playlists=list(
- "shuttle" = "Shuttle Mix"
- )
- invisibility=101 // FAK U NO SONG 4 U
-
-/obj/machinery/media/jukebox/lobby
- playlist_id="lobby"
- // Must be defined on your server.
- playlists=list(
- "lobby" = "Lobby Mix"
- )
- playlist_id = "lobby"
- use_power = 0
- invisibility=101
- autoplay = 1
diff --git a/code/modules/media/machinery.dm b/code/modules/media/machinery.dm
deleted file mode 100644
index cf46c8dcdf8..00000000000
--- a/code/modules/media/machinery.dm
+++ /dev/null
@@ -1,104 +0,0 @@
-// Machinery serving as a media source.
-/obj/machinery/media
- var/playing=0
- var/media_url=""
- var/media_start_time=0
-
- var/area/master_area
-
- var/list/obj/machinery/media/transmitter/hooked = list()
- var/exclusive_hook=null // Disables output to the room
-
- // Media system autolink.
- var/id_tag = "???"
-
-/obj/machinery/media/proc/hookMediaOutput(var/obj/machinery/media/transmitter/T, exclusive=0)
- if(exclusive)
- exclusive_hook=T
- hooked.Add(T)
- return 1
-
-/obj/machinery/media/proc/unhookMediaOutput(var/obj/machinery/media/transmitter/T)
- if(exclusive_hook==T)
- exclusive_hook=null
- hooked.Remove(T)
- return 1
-
-// Notify everyone in the area of new music.
-// YOU MUST SET MEDIA_URL AND MEDIA_START_TIME YOURSELF!
-/obj/machinery/media/proc/update_music()
- // Broadcasting shit
- for(var/obj/machinery/media/transmitter/T in hooked)
- testing("[src] Writing media to [T].")
- T.broadcast(media_url,media_start_time)
-
- if(exclusive_hook)
- disconnect_media_source() // Just to be sure.
- return
-
- update_media_source()
-
- // Bail if we lost connection to master.
- if(!master_area)
- return
-
- // Send update to clients.
- for(var/mob/M in mobs_in_area(master_area))
- if(M && M.client)
- M.update_music()
-
-/obj/machinery/media/proc/update_media_source()
- var/area/A = get_area_master(src)
-
- // Check if there's a media source already.
- if(A.media_source && A.media_source!=src)
- master_area=null
- return
-
- // Update Media Source.
- if(!A.media_source)
- A.media_source=src
-
- master_area=A
-
-/obj/machinery/media/proc/disconnect_media_source()
- var/area/A = get_area_master(src)
-
- // Sanity
- if(!A)
- master_area=null
- return
-
- // Check if there's a media source already.
- if(A && A.media_source && A.media_source!=src)
- master_area=null
- return
-
- // Update Media Source.
- A.media_source=null
-
- // Clients
- for(var/mob/M in mobs_in_area(A))
- if(M && M.client)
- M.update_music()
-
- master_area=null
-
-/obj/machinery/media/Move()
- ..()
- if(anchored)
- update_music()
-
-/obj/machinery/media/setLoc(var/turf/T, var/teleported=0)
- disconnect_media_source()
- ..(T)
- if(anchored)
- update_music()
-
-/obj/machinery/media/New()
- ..()
- update_media_source()
-
-/obj/machinery/media/Destroy()
- disconnect_media_source()
- return ..()
\ No newline at end of file
diff --git a/code/modules/media/mediamanager.dm b/code/modules/media/mediamanager.dm
deleted file mode 100644
index 125b224c8ea..00000000000
--- a/code/modules/media/mediamanager.dm
+++ /dev/null
@@ -1,160 +0,0 @@
-/**********************
- * AWW SHIT IT'S TIME FOR RADIO
- *
- * Concept stolen from D2K5
- *
- * Rewritten (except for player HTML) by N3X15
- ***********************/
-
-// Open up VLC and play musique.
-// Converted to VLC for cross-platform and ogg support. - N3X
-var/const/PLAYER_HTML={"
-
-
-
-"}
-
-// Hook into the events we desire.
-/hook/mob_login/proc/init_media_manager(client/client, mob/mob)
- client.media = new /datum/media_manager(mob)
- client.media.open()
- spawn(20)
- client.media.update_music()
- return 1
-
- // Update when moving between areas.
-/hook/mob_area_change/proc/update_media(mob/mob, area/newarea, area/oldarea)
- if(mob.client)
- mob.update_music()
- return 1
-
-/mob/proc/update_music()
- if(client && client.media)
- client.media.update_music()
- //else
- // testing("[src] - client: [client?"Y":"N"]; client.media: [client && client.media ? "Y":"N"]")
-
-/area
- // One media source per area.
- var/obj/machinery/media/media_source = null
-
-
-#ifdef DEBUG_MEDIAPLAYER
-to_chat(#define MP_DEBUG(x) owner, x)
-#warning Please comment out #define DEBUG_MEDIAPLAYER before committing.
-#else
-#define MP_DEBUG(x)
-#endif
-
-
-/datum/media_manager
- var/url = ""
- var/start_time = 0
-
- var/client/owner
- var/mob/mob
-
- var/const/window = "rpane.hosttracker"
- //var/const/window = "mediaplayer" // For debugging.
-
- New(var/mob/holder)
- src.mob=holder
- owner=src.mob.client
-
- // Actually pop open the player in the background.
- proc/open()
- owner << browse(PLAYER_HTML, "window=[window]")
- send_update()
-
- // Tell the player to play something via JS.
- proc/send_update()
- if(!(owner.prefs.sound & SOUND_STREAMING) && url != "")
- return // Nope.
- MP_DEBUG("\green Sending update to WMP ([url])...")
- owner << output(list2params(list(url, (world.time - start_time) / 10, get_volume())), "[window]:SetMusic")
-
- proc/stop_music()
- url=""
- start_time=world.time
- send_update()
-
- // Scan for media sources and use them.
- proc/update_music()
- var/targetURL = ""
- var/targetStartTime = 0
-
- if(!owner)
- //testing("owner is null")
- return
-
- var/area/A = get_area_master(mob)
- if(!A)
- //testing("[owner] in [mob.loc]. Aborting.")
- stop_music()
- return
- var/obj/machinery/media/M = A.media_source
- if(M && M.playing)
- targetURL = M.media_url
- targetStartTime = M.media_start_time
-// to_chat(owner, "Found audio source: [M.media_url] @ [(world.time - start_time) / 10]s.")
- //else
- // testing("M is not playing or null.")
-
- if(url != targetURL || abs(targetStartTime - start_time) > 1)
- url = targetURL
- start_time = targetStartTime
- send_update()
-
- proc/get_volume()
- return (owner && owner.prefs) ? owner.prefs.volume : 25
-
-/client/verb/change_volume()
- set name = "Set Volume"
- set category = "Preferences"
- set desc = "Set jukebox volume"
-
- if(!media || !istype(media))
- to_chat(usr, "You have no media datum to change, if you're not in the lobby tell an admin.")
- return
- var/value = input("Choose your Jukebox volume.", "Jukebox volume", media.get_volume())
- value = round(max(0, min(100, value)))
- if(prefs)
- prefs.volume = value
- prefs.save_preferences(src)
- media.send_update()
\ No newline at end of file
diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm
index a76dfa9a699..0c24daf977c 100644
--- a/code/modules/mining/mine_turfs.dm
+++ b/code/modules/mining/mine_turfs.dm
@@ -436,10 +436,9 @@ var/global/list/rockTurfEdgeCache = list(
else if(istype(AM,/obj/mecha))
var/obj/mecha/M = AM
- if(istype(M.selected,/obj/item/mecha_parts/mecha_equipment/tool/drill))
+ if(istype(M.selected,/obj/item/mecha_parts/mecha_equipment/drill))
M.selected.action(src)
- else
- return
+
/**********************Asteroid**************************/
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index c08cbc59389..4191046d2b6 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -16,7 +16,6 @@ var/list/image/ghost_darkness_images = list() //this is a list of images for thi
anchored = 1 // don't get pushed around
invisibility = INVISIBILITY_OBSERVER
var/can_reenter_corpse
- var/datum/hud/living/carbon/hud = null // hud
var/bootime = 0
var/started_as_observer //This variable is set to 1 when you enter the game as an observer.
//If you died in the game and are a ghsot - this will remain as null.
diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm
index ec0791d9e09..545be2f8613 100644
--- a/code/modules/mob/living/carbon/brain/MMI.dm
+++ b/code/modules/mob/living/carbon/brain/MMI.dm
@@ -178,4 +178,26 @@
/obj/item/device/mmi/syndie
name = "Syndicate Man-Machine Interface"
desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs created with it, but doesn't fit in Nanotrasen AI cores."
- syndiemmi = 1
\ No newline at end of file
+ syndiemmi = 1
+
+/obj/item/device/mmi/attempt_become_organ(obj/item/organ/external/parent,mob/living/carbon/human/H)
+ if(!brainmob)
+ return 0
+ if(!parent)
+ log_debug("Attempting to insert into a null parent!")
+ return 0
+ if(H.get_int_organ(/obj/item/organ/internal/brain))
+ // one brain at a time
+ return 0
+ var/obj/item/organ/internal/brain/mmi_holder/holder = new()
+ holder.parent_organ = parent.limb_name
+ forceMove(holder)
+ holder.stored_mmi = src
+ holder.update_from_mmi()
+ if(istype(src, /obj/item/device/mmi/posibrain))
+ holder.robotize()
+ if(brainmob && brainmob.mind)
+ brainmob.mind.transfer_to(H)
+ holder.insert(H)
+
+ return 1
diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm
index aac43c16ac3..996687ee4b0 100644
--- a/code/modules/mob/living/carbon/brain/brain.dm
+++ b/code/modules/mob/living/carbon/brain/brain.dm
@@ -4,7 +4,6 @@
var/obj/item/container = null
var/timeofhostdeath = 0
var/emp_damage = 0//Handles a type of MMI damage
- var/alert = null
use_me = 0 //Can't use the me verb, it's a freaking immobile brain
icon = 'icons/obj/surgery.dmi'
icon_state = "brain1"
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm
index dd2e81ed35b..621efe89ac1 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/mob/living/carbon/brain/brain_item.dm
@@ -79,7 +79,7 @@
if(istype(owner,/mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
H.update_hair(1)
- ..()
+ . = ..()
/obj/item/organ/internal/brain/insert(var/mob/living/target,special = 0)
@@ -100,7 +100,9 @@
brainmob.mind.transfer_to(target)
else
target.key = brainmob.key
- ..(target, special = special, dont_remove_slot = brain_already_exists)
+ else
+ log_debug("Multibrain shenanigans at ([target.x],[target.y],[target.z]), mob '[target]'")
+ ..(target, special = special)
/obj/item/organ/internal/brain/prepare_eat()
return // Too important to eat.
@@ -113,7 +115,7 @@
mmi_icon_state = "slime_mmi"
// parent_organ = "chest" Hello I am from the ministry of rubber forehead aliens how are you
-/obj/item/organ/brain/slime/take_damage(var/amount, var/silent = 1)
+/obj/item/organ/internal/brain/slime/take_damage(var/amount, var/silent = 1)
//Slimes are 150% more vulnerable to brain damage
damage = between(0, src.damage + (1.5*amount), max_damage) //Since they take the damage twice, this is +150%
return ..()
diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm
index ca241306f00..7802cfd53c6 100644
--- a/code/modules/mob/living/carbon/human/appearance.dm
+++ b/code/modules/mob/living/carbon/human/appearance.dm
@@ -170,14 +170,25 @@
H.ha_style = "None"
update_head_accessory()
-/mob/living/carbon/human/proc/change_eye_color(var/red, var/green, var/blue)
- if(red == r_eyes && green == g_eyes && blue == b_eyes)
- return
+/mob/living/carbon/human/proc/change_eye_color(var/red, var/green, var/blue, update_dna = 1)
+ // Update the main DNA datum, then sync the change across the organs
+ var/obj/item/organ/internal/eyes/eyes_organ = get_int_organ(/obj/item/organ/internal/eyes)
+ if(eyes_organ)
+ var/eyes_red = eyes_organ.eye_colour[1]
+ var/eyes_green = eyes_organ.eye_colour[2]
+ var/eyes_blue = eyes_organ.eye_colour[3]
+ if(red == eyes_red && green == eyes_green && blue == eyes_blue)
+ return
- r_eyes = red
- g_eyes = green
- b_eyes = blue
+ eyes_organ.eye_colour[1] = red
+ eyes_organ.eye_colour[2] = green
+ eyes_organ.eye_colour[3] = blue
+ dna.eye_color_to_dna(eyes_organ)
+ eyes_organ.set_dna(dna)
+ if(update_dna)
+ update_dna()
+ sync_organ_dna(assimilate=0)
update_eyes()
update_body()
return 1
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index d3606b12b8a..384f581cce3 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -12,13 +12,15 @@
animation.master = src
playsound(src.loc, 'sound/goonstation/effects/gib.ogg', 50, 1)
+ else
+ playsound(src.loc, 'sound/goonstation/effects/robogib.ogg', 50, 1)
for(var/obj/item/organ/internal/I in internal_organs)
if(isturf(loc))
- I.remove(src)
- I.forceMove(get_turf(src))
+ var/atom/movable/thing = I.remove(src)
+ thing.forceMove(get_turf(src))
spawn()
- I.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
+ thing.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
for(var/obj/item/organ/external/E in src.organs)
if(istype(E, /obj/item/organ/external/chest))
@@ -38,7 +40,7 @@
flick("gibbed-h", animation)
hgibs(loc, viruses, dna)
else
- new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc)
+ new /obj/effect/decal/cleanable/blood/gibs/robot(loc)
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
@@ -61,7 +63,7 @@
animation.master = src
flick("dust-h", animation)
- new /obj/effect/decal/remains/human(loc)
+ new species.remains_type(get_turf(src))
spawn(15)
if(animation) qdel(animation)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 5f2de47752c..48111b46d8a 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -2081,7 +2081,6 @@
dna.deserialize(data["dna"])
real_name = dna.real_name
name = real_name
- UpdateAppearance()
set_species(dna.species)
age = data["age"]
undershirt = data["ushirt"]
@@ -2105,6 +2104,7 @@
// As above, "New" code handles insertion, DNA sync
list_to_object(organs_list[organ], src)
+ UpdateAppearance()
// De-serialize equipment
// #1: Jumpsuit
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index 2ca74f02c86..e382768722f 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -13,7 +13,7 @@
if(H.hand)
temp = H.organs_by_name["l_hand"]
if(!temp || !temp.is_usable())
- to_chat(H, "\red You can't use your hand.")
+ to_chat(H, "You can't use your hand.")
return
..()
@@ -62,10 +62,9 @@
for(var/datum/surgery/S in src.surgeries)
if(S.next_step(M, src))
return 1
- else
- help_shake_act(M)
- add_logs(src, M, "shaked")
- return 1
+ help_shake_act(M)
+ add_logs(src, M, "shaked")
+ return 1
if(health >= config.health_threshold_crit)
help_shake_act(M)
add_logs(src, M, "shaked")
@@ -231,4 +230,4 @@
return
/mob/living/carbon/human/proc/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, inrange, params)
- return
\ No newline at end of file
+ return
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index a74409a9b44..272cb65e33a 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -9,11 +9,6 @@ var/global/default_martial_art = new/datum/martial_art
var/b_markings = 0
var/m_style = "None"
- //Eye colour
- var/r_eyes = 0
- var/g_eyes = 0
- var/b_eyes = 0
-
var/s_tone = 0 //Skin tone
//Skin colour
@@ -58,7 +53,6 @@ var/global/default_martial_art = new/datum/martial_art
var/datum/martial_art/martial_art = null
var/special_voice = "" // For changing our voice. Used by a symptom.
- var/said_last_words=0
var/last_dam = -1 //Used for determining if we need to process all organs or just some or even none.
var/list/bad_external_organs = list()// organs we check until they are good.
@@ -73,12 +67,9 @@ var/global/default_martial_art = new/datum/martial_art
var/meatleft = 3 //For chef item
var/decaylevel = 0 // For rotting bodies
var/max_blood = BLOOD_VOLUME_NORMAL // For stuff in the vessel
- var/slime_color = "blue" //For slime people this defines their color, it's blue by default to pay tribute to the old icons
var/check_mutations=0 // Check mutations on next life tick
- var/lastFart = 0 // Toxic fart cooldown.
-
var/fire_dmi = 'icons/mob/OnFire.dmi'
var/fire_sprite = "Standing"
diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm
index f8d612aadba..96a23acf5c7 100644
--- a/code/modules/mob/living/carbon/human/human_organs.dm
+++ b/code/modules/mob/living/carbon/human/human_organs.dm
@@ -78,9 +78,9 @@
// Canes and crutches help you stand (if the latter is ever added)
// One cane mitigates a broken leg+foot, or a missing foot.
// Two canes are needed for a lost leg. If you are missing both legs, canes aren't gonna help you.
- if(l_hand && istype(l_hand, /obj/item/weapon/cane))
+ if(l_hand && l_hand.is_crutch())
stance_damage -= 2
- if(r_hand && istype(r_hand, /obj/item/weapon/cane))
+ if(r_hand && r_hand.is_crutch())
stance_damage -= 2
if(stance_damage < 0)
@@ -137,6 +137,36 @@
spawn(10)
qdel(spark_system)
+/mob/living/carbon/human/proc/becomeSlim()
+ to_chat(src, "You feel fit again!")
+ var/obj/item/organ/external/chest/C = get_organ("chest")
+ if(istype(C))
+ C.makeSlim(0)
+ else
+ to_chat(src, "Err, well, you *would*, but you don't have a torso. Yell at a coder.")
+ log_debug("[src] at ([x],[y],[z]) doesn't have a torso.")
+ mutations.Remove(FAT)
+ update_mutantrace(0)
+ update_mutations(0)
+ update_body(0)
+ update_inv_w_uniform(0)
+ update_inv_wear_suit()
+
+/mob/living/carbon/human/proc/becomeFat()
+ to_chat(src, "You suddenly feel blubbery!")
+ var/obj/item/organ/external/chest/C = get_organ("chest")
+ if(istype(C))
+ C.makeFat()
+ else
+ to_chat(src, "Err, well, you *would*, but you don't have a torso. Yell at a coder.")
+ log_debug("[src] at ([x],[y],[z]) doesn't have a torso.")
+ mutations.Add(FAT)
+ update_mutantrace(0)
+ update_mutations(0)
+ update_body(0)
+ update_inv_w_uniform(0)
+ update_inv_wear_suit()
+
//Handles chem traces
/mob/living/carbon/human/proc/handle_trace_chems()
//New are added for reagents to random organs.
@@ -166,4 +196,4 @@ I use this to standardize shadowling dethrall code
if(!get_int_organ(organ_name))
return null
var/obj/item/organ/internal/O = get_int_organ(organ_name)
- return O.parent_organ
\ No newline at end of file
+ return O.parent_organ
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index d557fb65fed..8951b21bc74 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -675,20 +675,10 @@
if(species.flags & CAN_BE_FAT)
if(FAT in mutations)
if(overeatduration < 100)
- to_chat(src, "You feel fit again!")
- mutations.Remove(FAT)
- update_mutantrace(0)
- update_mutations(0)
- update_inv_w_uniform(0)
- update_inv_wear_suit()
+ becomeSlim()
else
if(overeatduration > 500)
- to_chat(src, "You suddenly feel blubbery!")
- mutations.Add(FAT)
- update_mutantrace(0)
- update_mutations(0)
- update_inv_w_uniform(0)
- update_inv_wear_suit()
+ becomeFat()
// nutrition decrease
if(nutrition > 0 && stat != 2)
@@ -1113,7 +1103,8 @@
return
if(H.species && H.species.flags & NO_BREATHE)
return //no puking if you can't smell!
- if(H.mind.assigned_role == "Detective")
+ // Humans can lack a mind datum, y'know
+ if(H.mind && H.mind.assigned_role == "Detective")
return //too cool for puke
to_chat(H, "You smell something foul...")
H.fakevomit()
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index 521505b703e..7c14584eee9 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -90,6 +90,7 @@
var/blood_color = "#A10808" //Red.
var/flesh_color = "#FFC896" //Pink.
var/single_gib_type = /obj/effect/decal/cleanable/blood/gibs
+ var/remains_type = /obj/effect/decal/remains/human //What sort of remains is left behind when the species dusts
var/base_color //Used when setting species.
//Used in icon caching.
@@ -192,10 +193,8 @@
for(var/index in has_organ)
var/organ = has_organ[index]
- H.internal_organs |= new organ(H)
-
- for(var/obj/item/organ/internal/I in H.internal_organs)
- I.insert(H)
+ // organ new code calls `insert` on its own
+ new organ(H)
for(var/name in H.organs_by_name)
H.organs |= H.organs_by_name[name]
diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm
index 6268652f828..0cef74044ce 100644
--- a/code/modules/mob/living/carbon/human/species/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station.dm
@@ -500,6 +500,7 @@
deform = 'icons/mob/human_races/r_slime.dmi'
path = /mob/living/carbon/human/slime
unarmed_type = /datum/unarmed_attack/punch
+ remains_type = /obj/effect/decal/remains/slime
// More sensitive to the cold
cold_level_1 = 280
@@ -730,6 +731,7 @@
unarmed_type = /datum/unarmed_attack/diona
//primitive_form = "Nymph"
slowdown = 5
+ remains_type = /obj/effect/decal/cleanable/ash
warning_low_pressure = 50
hazard_low_pressure = -1
@@ -844,6 +846,7 @@
default_language = "Galactic Common"
language = "Trinary"
unarmed_type = /datum/unarmed_attack/punch
+ remains_type = /obj/effect/decal/remains/robot
eyes = "blank_eyes"
brute_mod = 2.5 // 100% * 2.5 * 0.6 (robolimbs) ~= 150%
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index b919912a6c1..8f7ed81a5fa 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -1301,43 +1301,6 @@ var/global/list/damage_icon_parts = list()
if(update_icons) update_icons()
-
-// Used mostly for creating head items
-/mob/living/carbon/human/proc/generate_head_icon()
-//gender no longer matters for the mouth, although there should probably be seperate base head icons.
-// var/g = "m"
-// if(gender == FEMALE) g = "f"
- var/obj/item/organ/external/head/H = get_organ("head")
- //base icons
- var/icon/face_lying = new /icon('icons/mob/human_face.dmi',"bald_l")
-
-
- if(H.f_style)
- var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[H.f_style]
- if(facial_hair_style)
- var/icon/facial_l = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_l")
- facial_l.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD)
- face_lying.Blend(facial_l, ICON_OVERLAY)
-
- if(H.h_style)
- var/datum/sprite_accessory/hair_style = hair_styles_list[H.h_style]
- if(hair_style)
- var/icon/hair_l = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_l")
- hair_l.Blend(rgb(H.r_hair, H.g_hair, H.b_hair), ICON_ADD)
- face_lying.Blend(hair_l, ICON_OVERLAY)
-
- //Eyes
- // Note: These used to be in update_face(), and the fact they're here will make it difficult to create a disembodied head
- var/icon/eyes_l = new/icon('icons/mob/human_face.dmi', "eyes_l")
- eyes_l.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD)
- face_lying.Blend(eyes_l, ICON_OVERLAY)
-
- if(lip_style)
- face_lying.Blend(new/icon('icons/mob/human_face.dmi', "lips_[lip_style]_l"), ICON_OVERLAY)
-
- var/image/face_lying_image = new /image(icon = face_lying)
- return face_lying_image
-
/mob/living/carbon/human/proc/force_update_limbs()
for(var/obj/item/organ/external/O in organs)
O.sync_colour_to_human(src)
diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm
index 862a44eb57b..60e1cd82654 100644
--- a/code/modules/mob/living/carbon/superheroes.dm
+++ b/code/modules/mob/living/carbon/superheroes.dm
@@ -215,9 +215,8 @@
head_organ.h_style = "Bald"
head_organ.f_style = "Shaved"
target.s_tone = 35
- target.r_eyes = 1
- target.b_eyes = 1
- target.g_eyes = 1
+ // No `update_dna=0` here because the character is being over-written
+ target.change_eye_color(1,1,1)
for(var/obj/item/W in target)
if(istype(W,/obj/item/organ)) continue
target.unEquip(W)
@@ -233,4 +232,3 @@
target.equip_to_slot_or_del(W, slot_wear_id)
target.equip_to_slot_or_del(new /obj/item/device/radio/headset(target), slot_l_ear)
target.regenerate_icons()
-
diff --git a/code/modules/mob/living/silicon/pai/personality.dm b/code/modules/mob/living/silicon/pai/personality.dm
index d089b76a3fb..1abf61e633b 100644
--- a/code/modules/mob/living/silicon/pai/personality.dm
+++ b/code/modules/mob/living/silicon/pai/personality.dm
@@ -17,10 +17,10 @@
var/savefile/F = new /savefile(src.savefile_path(user))
- to_chat(F["name"], src.name)
- to_chat(F["description"], src.description)
- to_chat(F["role"], src.role)
- to_chat(F["comments"], src.comments)
+ F["name"] << src.name
+ F["description"] << src.description
+ F["role"] << src.role
+ F["comments"] << src.comments
F["version"] << 1
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index bd2712cdcdb..d99bad202d7 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -23,14 +23,12 @@
if(emag)
emag.emp_act(severity)
..()
- return
/obj/item/weapon/robot_module/New()
- src.modules += new /obj/item/device/flashlight(src)
- src.modules += new /obj/item/device/flash/cyborg(src)
- src.emag = new /obj/item/toy/sword(src)
- src.emag.name = "Placeholder Emag Item"
+ modules += new /obj/item/device/flash/cyborg(src)
+ emag = new /obj/item/toy/sword(src)
+ emag.name = "Placeholder Emag Item"
/obj/item/weapon/robot_module/Destroy()
for(var/module in modules)
@@ -48,18 +46,19 @@
emag.flags |= NODROP
emag.mouse_opacity = 2
-/obj/item/weapon/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/R)
- if(!stacktypes || !stacktypes.len) return
+/obj/item/weapon/robot_module/proc/respawn_consumable(mob/living/silicon/robot/R)
+ if(!stacktypes || !stacktypes.len)
+ return
var/stack_respawned = 0
for(var/T in stacktypes)
- var/O = locate(T) in src.modules
+ var/O = locate(T) in modules
var/obj/item/stack/S = O
if(!S)
- src.modules -= null
+ modules -= null
S = new T(src)
- src.modules += S
+ modules += S
S.amount = 1
stack_respawned = 1
@@ -75,7 +74,7 @@
if(O)
modules += O
-/obj/item/weapon/robot_module/proc/add_languages(var/mob/living/silicon/robot/R)
+/obj/item/weapon/robot_module/proc/add_languages(mob/living/silicon/robot/R)
//full set of languages
R.add_language("Galactic Common", 1)
R.add_language("Sol Common", 1)
@@ -93,10 +92,10 @@
R.add_language("Orluum", 0)
R.add_language("Clownish",0)
-/obj/item/weapon/robot_module/proc/add_subsystems(var/mob/living/silicon/robot/R)
+/obj/item/weapon/robot_module/proc/add_subsystems(mob/living/silicon/robot/R)
R.verbs |= subsystems
-/obj/item/weapon/robot_module/proc/remove_subsystems(var/mob/living/silicon/robot/R)
+/obj/item/weapon/robot_module/proc/remove_subsystems(mob/living/silicon/robot/R)
R.verbs -= subsystems
/obj/item/weapon/robot_module/standard
@@ -104,13 +103,13 @@
module_type = "Standard"
/obj/item/weapon/robot_module/standard/New()
- src.modules += new /obj/item/device/flash/cyborg(src)
- src.modules += new /obj/item/weapon/melee/baton/loaded(src)
- src.modules += new /obj/item/weapon/extinguisher(src)
- src.modules += new /obj/item/weapon/wrench(src)
- src.modules += new /obj/item/weapon/crowbar(src)
- src.modules += new /obj/item/device/healthanalyzer(src)
- src.emag = new /obj/item/weapon/melee/energy/sword/cyborg(src)
+ ..()
+ modules += new /obj/item/weapon/melee/baton/loaded(src)
+ modules += new /obj/item/weapon/extinguisher(src)
+ modules += new /obj/item/weapon/wrench(src)
+ modules += new /obj/item/weapon/crowbar(src)
+ modules += new /obj/item/device/healthanalyzer(src)
+ emag = new /obj/item/weapon/melee/energy/sword/cyborg(src)
fix_modules()
@@ -126,40 +125,40 @@
)
/obj/item/weapon/robot_module/medical/New()
- src.modules += new /obj/item/device/flash/cyborg(src)
- src.modules += new /obj/item/device/healthanalyzer/advanced(src)
- src.modules += new /obj/item/device/reagent_scanner/adv(src)
- src.modules += new /obj/item/weapon/borg_defib(src)
- src.modules += new /obj/item/roller_holder(src)
- src.modules += new /obj/item/weapon/reagent_containers/borghypo(src)
- src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
- src.modules += new /obj/item/weapon/reagent_containers/dropper(src)
- src.modules += new /obj/item/weapon/reagent_containers/syringe(src)
- src.modules += new /obj/item/weapon/extinguisher/mini(src)
- src.modules += new /obj/item/stack/medical/bruise_pack/advanced(src)
- src.modules += new /obj/item/stack/medical/ointment/advanced(src)
- src.modules += new /obj/item/stack/medical/splint(src)
- src.modules += new /obj/item/stack/nanopaste(src)
- src.modules += new /obj/item/weapon/scalpel(src)
- src.modules += new /obj/item/weapon/hemostat(src)
- src.modules += new /obj/item/weapon/retractor(src)
- src.modules += new /obj/item/weapon/cautery(src)
- src.modules += new /obj/item/weapon/bonegel(src)
- src.modules += new /obj/item/weapon/FixOVein(src)
- src.modules += new /obj/item/weapon/bonesetter(src)
- src.modules += new /obj/item/weapon/circular_saw(src)
- src.modules += new /obj/item/weapon/surgicaldrill(src)
+ ..()
+ modules += new /obj/item/device/healthanalyzer/advanced(src)
+ modules += new /obj/item/device/reagent_scanner/adv(src)
+ modules += new /obj/item/weapon/borg_defib(src)
+ modules += new /obj/item/roller_holder(src)
+ modules += new /obj/item/weapon/reagent_containers/borghypo(src)
+ modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
+ modules += new /obj/item/weapon/reagent_containers/dropper(src)
+ modules += new /obj/item/weapon/reagent_containers/syringe(src)
+ modules += new /obj/item/weapon/extinguisher/mini(src)
+ modules += new /obj/item/stack/medical/bruise_pack/advanced(src)
+ modules += new /obj/item/stack/medical/ointment/advanced(src)
+ modules += new /obj/item/stack/medical/splint(src)
+ modules += new /obj/item/stack/nanopaste(src)
+ modules += new /obj/item/weapon/scalpel(src)
+ modules += new /obj/item/weapon/hemostat(src)
+ modules += new /obj/item/weapon/retractor(src)
+ modules += new /obj/item/weapon/cautery(src)
+ modules += new /obj/item/weapon/bonegel(src)
+ modules += new /obj/item/weapon/FixOVein(src)
+ modules += new /obj/item/weapon/bonesetter(src)
+ modules += new /obj/item/weapon/circular_saw(src)
+ modules += new /obj/item/weapon/surgicaldrill(src)
- src.emag = new /obj/item/weapon/reagent_containers/spray(src)
+ emag = new /obj/item/weapon/reagent_containers/spray(src)
- src.emag.reagents.add_reagent("facid", 250)
- src.emag.name = "Polyacid spray"
+ emag.reagents.add_reagent("facid", 250)
+ emag.name = "Polyacid spray"
fix_modules()
-/obj/item/weapon/robot_module/medical/respawn_consumable(var/mob/living/silicon/robot/R)
- if(src.emag)
- var/obj/item/weapon/reagent_containers/spray/PS = src.emag
+/obj/item/weapon/robot_module/medical/respawn_consumable(mob/living/silicon/robot/R)
+ if(emag)
+ var/obj/item/weapon/reagent_containers/spray/PS = emag
PS.reagents.add_reagent("facid", 2)
..()
@@ -178,28 +177,29 @@
)
/obj/item/weapon/robot_module/engineering/New()
- src.modules += new /obj/item/device/flash/cyborg(src)
- src.modules += new /obj/item/borg/sight/meson(src)
- src.modules += new /obj/item/weapon/rcd/borg(src)
- src.modules += new /obj/item/weapon/extinguisher(src)
- src.modules += new /obj/item/weapon/weldingtool/largetank/cyborg(src)
- src.modules += new /obj/item/weapon/screwdriver(src)
- src.modules += new /obj/item/weapon/wrench(src)
- src.modules += new /obj/item/weapon/crowbar(src)
- src.modules += new /obj/item/weapon/wirecutters(src)
- src.modules += new /obj/item/device/multitool(src)
- src.modules += new /obj/item/device/t_scanner(src)
- src.modules += new /obj/item/device/analyzer(src)
- src.modules += new /obj/item/taperoll/engineering(src)
- src.modules += new /obj/item/weapon/gripper(src)
- src.modules += new /obj/item/weapon/matter_decompiler(src)
+ ..()
+ modules += new /obj/item/borg/sight/meson(src)
+ modules += new /obj/item/weapon/rcd/borg(src)
+ modules += new /obj/item/weapon/extinguisher(src)
+ modules += new /obj/item/weapon/weldingtool/largetank/cyborg(src)
+ modules += new /obj/item/weapon/screwdriver(src)
+ modules += new /obj/item/weapon/wrench(src)
+ modules += new /obj/item/weapon/crowbar(src)
+ modules += new /obj/item/weapon/wirecutters(src)
+ modules += new /obj/item/device/multitool(src)
+ modules += new /obj/item/device/t_scanner(src)
+ modules += new /obj/item/device/analyzer(src)
+ modules += new /obj/item/taperoll/engineering(src)
+ modules += new /obj/item/weapon/gripper(src)
+ modules += new /obj/item/weapon/matter_decompiler(src)
+ modules += new /obj/item/device/floor_painter(src)
- src.emag = new /obj/item/borg/stun(src)
+ emag = new /obj/item/borg/stun(src)
for(var/G in stacktypes) //Attempt to unify Engi-Borg material stacks into fewer lines. See Line 492 for example. Variables changed out of paranoia.
var/obj/item/stack/sheet/M = new G(src)
M.amount = stacktypes[G]
- src.modules += M
+ modules += M
fix_modules()
@@ -209,13 +209,13 @@
subsystems = list(/mob/living/silicon/proc/subsystem_crew_monitor)
/obj/item/weapon/robot_module/security/New()
- src.modules += new /obj/item/device/flash/cyborg(src)
- src.modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src)
- src.modules += new /obj/item/weapon/melee/baton/loaded/robot(src)
- src.modules += new /obj/item/weapon/gun/energy/disabler/cyborg(src)
- src.modules += new /obj/item/taperoll/police(src)
- src.modules += new /obj/item/clothing/mask/gas/sechailer/cyborg(src)
- src.emag = new /obj/item/weapon/gun/energy/laser/cyborg(src)
+ ..()
+ modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src)
+ modules += new /obj/item/weapon/melee/baton/loaded/robot(src)
+ modules += new /obj/item/weapon/gun/energy/disabler/cyborg(src)
+ modules += new /obj/item/taperoll/police(src)
+ modules += new /obj/item/clothing/mask/gas/sechailer/cyborg(src)
+ emag = new /obj/item/weapon/gun/energy/laser/cyborg(src)
fix_modules()
@@ -224,16 +224,16 @@
module_type = "Janitor"
/obj/item/weapon/robot_module/janitor/New()
- src.modules += new /obj/item/device/flash/cyborg(src)
- src.modules += new /obj/item/weapon/soap/nanotrasen(src)
- src.modules += new /obj/item/weapon/storage/bag/trash/cyborg(src)
- src.modules += new /obj/item/weapon/mop/advanced/cyborg(src)
- src.modules += new /obj/item/device/lightreplacer(src)
- src.modules += new /obj/item/weapon/holosign_creator(src)
- src.emag = new /obj/item/weapon/reagent_containers/spray(src)
+ ..()
+ modules += new /obj/item/weapon/soap/nanotrasen(src)
+ modules += new /obj/item/weapon/storage/bag/trash/cyborg(src)
+ modules += new /obj/item/weapon/mop/advanced/cyborg(src)
+ modules += new /obj/item/device/lightreplacer(src)
+ modules += new /obj/item/weapon/holosign_creator(src)
+ emag = new /obj/item/weapon/reagent_containers/spray(src)
- src.emag.reagents.add_reagent("lube", 250)
- src.emag.name = "Lube spray"
+ emag.reagents.add_reagent("lube", 250)
+ emag.name = "Lube spray"
fix_modules()
@@ -242,37 +242,37 @@
module_type = "Service"
/obj/item/weapon/robot_module/butler/New()
- src.modules += new /obj/item/device/flash/cyborg(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/pen(src)
- src.modules += new /obj/item/weapon/razor(src)
- src.modules += new /obj/item/device/violin(src)
- src.modules += new /obj/item/device/guitar(src)
+ ..()
+ modules += new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
+ modules += new /obj/item/weapon/reagent_containers/food/condiment/enzyme(src)
+ modules += new /obj/item/weapon/pen(src)
+ modules += new /obj/item/weapon/razor(src)
+ modules += new /obj/item/device/violin(src)
+ modules += new /obj/item/device/guitar(src)
var/obj/item/weapon/rsf/M = new /obj/item/weapon/rsf(src)
M.matter = 30
- src.modules += M
+ modules += M
- src.modules += new /obj/item/weapon/reagent_containers/dropper/cyborg(src)
- src.modules += new /obj/item/weapon/lighter/zippo(src)
- src.modules += new /obj/item/weapon/storage/bag/tray/cyborg(src)
- src.modules += new /obj/item/weapon/reagent_containers/food/drinks/shaker(src)
- src.emag = new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
+ modules += new /obj/item/weapon/reagent_containers/dropper/cyborg(src)
+ modules += new /obj/item/weapon/lighter/zippo(src)
+ modules += new /obj/item/weapon/storage/bag/tray/cyborg(src)
+ modules += new /obj/item/weapon/reagent_containers/food/drinks/shaker(src)
+ emag = new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
var/datum/reagents/R = new/datum/reagents(50)
- src.emag.reagents = R
- R.my_atom = src.emag
+ emag.reagents = R
+ R.my_atom = emag
R.add_reagent("beer2", 50)
- src.emag.name = "Mickey Finn's Special Brew"
+ emag.name = "Mickey Finn's Special Brew"
fix_modules()
/obj/item/weapon/robot_module/butler/respawn_consumable(var/mob/living/silicon/robot/R)
- var/obj/item/weapon/reagent_containers/food/condiment/enzyme/E = locate() in src.modules
+ var/obj/item/weapon/reagent_containers/food/condiment/enzyme/E = locate() in modules
E.reagents.add_reagent("enzyme", 2)
- if(src.emag)
- var/obj/item/weapon/reagent_containers/food/drinks/cans/beer/B = src.emag
+ if(emag)
+ var/obj/item/weapon/reagent_containers/food/drinks/cans/beer/B = emag
B.reagents.add_reagent("beer2", 2)
..()
@@ -293,27 +293,13 @@
R.add_language("Bubblish", 1)
R.add_language("Clownish",1)
-/*
-/obj/item/weapon/robot_module/clerical //Whyyyyy?
- name = "clerical robot module"
-
- New()
- src.modules += new /obj/item/device/flashlight(src)
- src.modules += new /obj/item/device/flash/cyborg(src)
- src.modules += new /obj/item/weapon/pen/multi/robopen(src)
- src.modules += new /obj/item/weapon/form_printer(src)
- src.modules += new /obj/item/device/taperecorder(src)
- src.modules += new /obj/item/weapon/gripper/paperwork(src)
-
- src.emag = new /obj/item/weapon/stamp/denied(src)
-*/
/obj/item/weapon/robot_module/miner
name = "miner robot module"
module_type = "Miner"
/obj/item/weapon/robot_module/miner/New()
- modules += new /obj/item/device/flash/cyborg(src)
+ ..()
modules += new /obj/item/borg/sight/meson(src)
modules += new /obj/item/weapon/storage/bag/ore/cyborg(src)
modules += new /obj/item/weapon/pickaxe/drill/cyborg(src)
@@ -333,12 +319,12 @@
module_type = "Malf"
/obj/item/weapon/robot_module/deathsquad/New()
- src.modules += new /obj/item/device/flash/cyborg(src)
- src.modules += new /obj/item/borg/sight/thermal(src)
- src.modules += new /obj/item/weapon/melee/energy/sword/cyborg(src)
- src.modules += new /obj/item/weapon/gun/energy/pulse/cyborg(src)
- src.modules += new /obj/item/weapon/crowbar(src)
- src.emag = null
+ ..()
+ modules += new /obj/item/borg/sight/thermal(src)
+ modules += new /obj/item/weapon/melee/energy/sword/cyborg(src)
+ modules += new /obj/item/weapon/gun/energy/pulse/cyborg(src)
+ modules += new /obj/item/weapon/crowbar(src)
+ emag = null
fix_modules()
@@ -347,14 +333,14 @@
module_type = "Malf" // cuz it looks cool
/obj/item/weapon/robot_module/syndicate/New()
- src.modules += new /obj/item/device/flash/cyborg(src)
- src.modules += new /obj/item/weapon/melee/energy/sword/cyborg(src)
- src.modules += new /obj/item/weapon/gun/energy/printer(src)
- src.modules += new /obj/item/weapon/gun/projectile/revolver/grenadelauncher/multi/cyborg(src)
- src.modules += new /obj/item/weapon/card/emag(src)
- src.modules += new /obj/item/weapon/crowbar(src)
- src.modules += new /obj/item/weapon/pinpointer/operative(src)
- src.emag = null
+ ..()
+ modules += new /obj/item/weapon/melee/energy/sword/cyborg(src)
+ modules += new /obj/item/weapon/gun/energy/printer(src)
+ modules += new /obj/item/weapon/gun/projectile/revolver/grenadelauncher/multi/cyborg(src)
+ modules += new /obj/item/weapon/card/emag(src)
+ modules += new /obj/item/weapon/crowbar(src)
+ modules += new /obj/item/weapon/pinpointer/operative(src)
+ emag = null
fix_modules()
@@ -369,30 +355,30 @@
)
/obj/item/weapon/robot_module/syndicate_medical/New()
- src.modules += new /obj/item/device/flash/cyborg(src)
- src.modules += new /obj/item/device/healthanalyzer/advanced(src)
- src.modules += new /obj/item/device/reagent_scanner/adv(src)
- src.modules += new /obj/item/weapon/borg_defib(src)
- src.modules += new /obj/item/roller_holder(src)
- src.modules += new /obj/item/weapon/reagent_containers/borghypo/syndicate(src)
- src.modules += new /obj/item/weapon/extinguisher/mini(src)
- src.modules += new /obj/item/stack/medical/bruise_pack/advanced(src)
- src.modules += new /obj/item/stack/medical/ointment/advanced(src)
- src.modules += new /obj/item/stack/medical/splint(src)
- src.modules += new /obj/item/stack/nanopaste(src)
- src.modules += new /obj/item/weapon/scalpel(src)
- src.modules += new /obj/item/weapon/hemostat(src)
- src.modules += new /obj/item/weapon/retractor(src)
- src.modules += new /obj/item/weapon/cautery(src)
- src.modules += new /obj/item/weapon/bonegel(src)
- src.modules += new /obj/item/weapon/FixOVein(src)
- src.modules += new /obj/item/weapon/bonesetter(src)
- src.modules += new /obj/item/weapon/surgicaldrill(src)
- src.modules += new /obj/item/weapon/melee/energy/sword/cyborg/saw(src) //Energy saw -- primary weapon
- src.modules += new /obj/item/weapon/card/emag(src)
- src.modules += new /obj/item/weapon/crowbar(src)
- src.modules += new /obj/item/weapon/pinpointer/operative(src)
- src.emag = null
+ ..()
+ modules += new /obj/item/device/healthanalyzer/advanced(src)
+ modules += new /obj/item/device/reagent_scanner/adv(src)
+ modules += new /obj/item/weapon/borg_defib(src)
+ modules += new /obj/item/roller_holder(src)
+ modules += new /obj/item/weapon/reagent_containers/borghypo/syndicate(src)
+ modules += new /obj/item/weapon/extinguisher/mini(src)
+ modules += new /obj/item/stack/medical/bruise_pack/advanced(src)
+ modules += new /obj/item/stack/medical/ointment/advanced(src)
+ modules += new /obj/item/stack/medical/splint(src)
+ modules += new /obj/item/stack/nanopaste(src)
+ modules += new /obj/item/weapon/scalpel(src)
+ modules += new /obj/item/weapon/hemostat(src)
+ modules += new /obj/item/weapon/retractor(src)
+ modules += new /obj/item/weapon/cautery(src)
+ modules += new /obj/item/weapon/bonegel(src)
+ modules += new /obj/item/weapon/FixOVein(src)
+ modules += new /obj/item/weapon/bonesetter(src)
+ modules += new /obj/item/weapon/surgicaldrill(src)
+ modules += new /obj/item/weapon/melee/energy/sword/cyborg/saw(src) //Energy saw -- primary weapon
+ modules += new /obj/item/weapon/card/emag(src)
+ modules += new /obj/item/weapon/crowbar(src)
+ modules += new /obj/item/weapon/pinpointer/operative(src)
+ emag = null
fix_modules()
@@ -401,15 +387,15 @@
module_type = "Malf"
/obj/item/weapon/robot_module/combat/New()
- src.modules += new /obj/item/device/flash/cyborg(src)
- src.modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src)
- src.modules += new /obj/item/borg/sight/thermal(src)
- src.modules += new /obj/item/weapon/gun/energy/gun/cyborg(src)
- src.modules += new /obj/item/weapon/pickaxe/drill/jackhammer(src)
- src.modules += new /obj/item/borg/combat/shield(src)
- src.modules += new /obj/item/borg/combat/mobility(src)
- src.modules += new /obj/item/weapon/wrench(src)
- src.emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
+ ..()
+ modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src)
+ modules += new /obj/item/borg/sight/thermal(src)
+ modules += new /obj/item/weapon/gun/energy/gun/cyborg(src)
+ modules += new /obj/item/weapon/pickaxe/drill/jackhammer(src)
+ modules += new /obj/item/borg/combat/shield(src)
+ modules += new /obj/item/borg/combat/mobility(src)
+ modules += new /obj/item/weapon/wrench(src)
+ emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
fix_modules()
@@ -418,14 +404,14 @@
module_type = "Malf"
/obj/item/weapon/robot_module/peacekeeper/New()
- src.modules += new /obj/item/device/flash/cyborg(src)
- src.modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src)
- src.modules += new /obj/item/weapon/gun/energy/gun/cyborg(src)
- src.modules += new /obj/item/weapon/pickaxe/drill/jackhammer(src)
- src.modules += new /obj/item/borg/combat/shield(src)
- src.modules += new /obj/item/borg/combat/mobility(src)
- src.modules += new /obj/item/weapon/wrench(src)
- src.emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
+ ..()
+ modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src)
+ modules += new /obj/item/weapon/gun/energy/gun/cyborg(src)
+ modules += new /obj/item/weapon/pickaxe/drill/jackhammer(src)
+ modules += new /obj/item/borg/combat/shield(src)
+ modules += new /obj/item/borg/combat/mobility(src)
+ modules += new /obj/item/weapon/wrench(src)
+ emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
fix_modules()
@@ -434,18 +420,18 @@
module_type = "Standard"
/obj/item/weapon/robot_module/alien/hunter/New()
- src.modules += new /obj/item/weapon/melee/energy/alien/claws(src)
- src.modules += new /obj/item/device/flash/cyborg/alien(src)
- src.modules += new /obj/item/borg/sight/thermal/alien(src)
+ modules += new /obj/item/weapon/melee/energy/alien/claws(src)
+ modules += new /obj/item/device/flash/cyborg/alien(src)
+ modules += new /obj/item/borg/sight/thermal/alien(src)
var/obj/item/weapon/reagent_containers/spray/alien/stun/S = new /obj/item/weapon/reagent_containers/spray/alien/stun(src)
S.reagents.add_reagent("ether",250) //nerfed to sleeptoxin to make it less instant drop.
- src.modules += S
+ modules += S
var/obj/item/weapon/reagent_containers/spray/alien/smoke/A = new /obj/item/weapon/reagent_containers/spray/alien/smoke(src)
S.reagents.add_reagent("water",50) //Water is used as a dummy reagent for the smoke bombs. More of an ammo counter.
- src.modules += A
- src.emag = new /obj/item/weapon/reagent_containers/spray/alien/acid(src)
- src.emag.reagents.add_reagent("facid", 125)
- src.emag.reagents.add_reagent("sacid", 125)
+ modules += A
+ emag = new /obj/item/weapon/reagent_containers/spray/alien/acid(src)
+ emag.reagents.add_reagent("facid", 125)
+ emag.reagents.add_reagent("sacid", 125)
fix_modules()
@@ -468,44 +454,42 @@
)
/obj/item/weapon/robot_module/drone/New()
- src.modules += new /obj/item/weapon/weldingtool/largetank/cyborg(src)
- src.modules += new /obj/item/weapon/screwdriver(src)
- src.modules += new /obj/item/weapon/wrench(src)
- src.modules += new /obj/item/weapon/crowbar(src)
- src.modules += new /obj/item/weapon/wirecutters(src)
- 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/matter_decompiler(src)
- src.modules += new /obj/item/weapon/reagent_containers/spray/cleaner/drone(src)
- src.modules += new /obj/item/weapon/soap(src)
- src.modules += new /obj/item/device/t_scanner(src)
+ modules += new /obj/item/weapon/weldingtool/largetank/cyborg(src)
+ modules += new /obj/item/weapon/screwdriver(src)
+ modules += new /obj/item/weapon/wrench(src)
+ modules += new /obj/item/weapon/crowbar(src)
+ modules += new /obj/item/weapon/wirecutters(src)
+ modules += new /obj/item/device/multitool(src)
+ modules += new /obj/item/device/lightreplacer(src)
+ modules += new /obj/item/weapon/gripper(src)
+ modules += new /obj/item/weapon/matter_decompiler(src)
+ modules += new /obj/item/weapon/reagent_containers/spray/cleaner/drone(src)
+ modules += new /obj/item/weapon/soap(src)
+ modules += new /obj/item/device/t_scanner(src)
- src.emag = new /obj/item/weapon/pickaxe/drill/cyborg/diamond(src)
+ emag = new /obj/item/weapon/pickaxe/drill/cyborg/diamond(src)
for(var/T in stacktypes)
var/obj/item/stack/sheet/W = new T(src)
W.amount = stacktypes[T]
- src.modules += W
+ modules += W
fix_modules()
-/obj/item/weapon/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R)
- var/obj/item/weapon/reagent_containers/spray/cleaner/C = locate() in src.modules
+/obj/item/weapon/robot_module/drone/respawn_consumable(mob/living/silicon/robot/R)
+ var/obj/item/weapon/reagent_containers/spray/cleaner/C = locate() in modules
C.reagents.add_reagent("cleaner", 3)
- var/obj/item/device/lightreplacer/LR = locate() in src.modules
+ var/obj/item/device/lightreplacer/LR = locate() in modules
LR.Charge(R)
..()
- return
-
//checks whether this item is a module of the robot it is located in.
/obj/item/proc/is_robot_module()
- if(!istype(src.loc, /mob/living/silicon/robot))
+ if(!istype(loc, /mob/living/silicon/robot))
return 0
- var/mob/living/silicon/robot/R = src.loc
+ var/mob/living/silicon/robot/R = loc
return (src in R.module.modules)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 93b94e74f9e..4ebf599a189 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -90,21 +90,23 @@
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
/mob/visible_message(var/message, var/self_message, var/blind_message)
- for(var/mob/M in viewers(src))
+ for(var/mob/M in get_mobs_in_view(7, src))
if(M.see_invisible < invisibility)
continue //can't view the invisible
var/msg = message
- if(self_message && M==src)
+ if(self_message && M == src)
msg = self_message
- M.show_message( msg, 1, blind_message, 2)
+ M.show_message(msg, 1, blind_message, 2)
// Show a message to all mobs in sight of this atom
// Use for objects performing visible actions
// message is output to anyone who can see, e.g. "The [src] does something!"
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
/atom/proc/visible_message(var/message, var/blind_message)
- for(var/mob/M in viewers(src))
- M.show_message( message, 1, blind_message, 2)
+ for(var/mob/M in get_mobs_in_view(7, src))
+ if(!M.client)
+ continue
+ M.show_message(message, 1, blind_message, 2)
// Show a message to all mobs in earshot of this one
// This would be for audible actions by the src mob
@@ -118,7 +120,7 @@
range = hearing_distance
var/msg = message
for(var/mob/M in get_mobs_in_view(range, src))
- if(self_message && M==src)
+ if(self_message && M == src)
msg = self_message
M.show_message(msg, 2, deaf_message, 1)
@@ -255,8 +257,8 @@
//The list of slots by priority. equip_to_appropriate_slot() uses this list. Doesn't matter if a mob type doesn't have a slot.
var/list/slot_equipment_priority = list( \
slot_back,\
- slot_wear_id,\
slot_wear_pda,\
+ slot_wear_id,\
slot_w_uniform,\
slot_wear_suit,\
slot_wear_mask,\
@@ -872,9 +874,12 @@ var/list/slot_equipment_priority = list( \
//this and stop_pulling really ought to be /mob/living procs
/mob/proc/start_pulling(atom/movable/AM)
- if( !AM || !src || src==AM || !isturf(AM.loc) ) //if there's no person pulling OR the person is pulling themself OR the object being pulled is inside something: abort!
+ if(src == AM) // Trying to pull yourself is a shortcut to stop pulling
+ stop_pulling()
return
- if(!( AM.anchored ))
+ if(!AM || !isturf(AM.loc)) //if there's no object or the object being pulled is inside something: abort!
+ return
+ if(!(AM.anchored))
AM.add_fingerprint(src)
// If we're pulling something then drop what we're currently pulling and pull this instead.
@@ -943,17 +948,7 @@ var/list/slot_equipment_priority = list( \
/mob/Stat()
..()
- if(listed_turf && client)
- if(!TurfAdjacent(listed_turf))
- listed_turf = null
- else
- statpanel(listed_turf.name, null, listed_turf)
- for(var/atom/A in listed_turf)
- if(A.invisibility > see_invisible)
- continue
- if(is_type_in_list(A, shouldnt_see))
- continue
- statpanel(listed_turf.name, null, A)
+ show_stat_turf_contents()
statpanel("Status") // We only want alt-clicked turfs to come before Status
@@ -990,6 +985,23 @@ var/list/slot_equipment_priority = list( \
if(ETA)
stat(null, "[ETA] [shuttle_master.emergency.getTimerStr()]")
+/mob/proc/show_stat_turf_contents()
+ if(listed_turf && client)
+ if(!TurfAdjacent(listed_turf))
+ listed_turf = null
+ else
+ statpanel(listed_turf.name, null, listed_turf)
+ var/list/statpanel_things = list()
+ for(var/foo in listed_turf)
+ var/atom/A = foo
+ if(A.invisibility > see_invisible)
+ continue
+ if(is_type_in_list(A, shouldnt_see))
+ continue
+ statpanel_things += A
+ statpanel(listed_turf.name, null, statpanel_things)
+
+
/mob/proc/add_stings_to_statpanel(var/list/stings)
for(var/obj/effect/proc_holder/changeling/S in stings)
if(S.chemical_cost >=0 && S.can_be_used_by(src))
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 55751e2aef9..5ab4b0644b8 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -94,7 +94,6 @@
var/intent = null//Living
var/shakecamera = 0
var/a_intent = I_HELP//Living
- var/m_int = null//Living
var/m_intent = "run"//Living
var/lastKnownIP = null
var/atom/movable/buckled = null//Living
@@ -215,4 +214,4 @@
var/list/permanent_huds = list()
- var/list/actions = list()
\ No newline at end of file
+ var/list/actions = list()
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 7be09dbed18..5057511ed02 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -403,44 +403,42 @@
///Called by /client/Move()
///For moving in space
///Return 1 for movement 0 for none
-/mob/Process_Spacemove(var/movement_dir = 0)
-
+/mob/Process_Spacemove(movement_dir = 0)
if(..())
return 1
+ var/atom/movable/backup = get_spacemove_backup()
+ if(backup)
+ if(istype(backup) && movement_dir && !backup.anchored)
+ if(backup.newtonian_move(turn(movement_dir, 180))) //You're pushing off something movable, so it moves
+ src << "You push off of [backup] to propel yourself."
+ return 1
+ return 0
+/mob/get_spacemove_backup()
var/atom/movable/dense_object_backup
- for(var/atom/A in orange(1, get_turf(src)))
+ for(var/A in orange(1, get_turf(src)))
if(isarea(A))
continue
-
else if(isturf(A))
var/turf/turf = A
- if(istype(turf,/turf/space))
+ if(istype(turf, /turf/space))
continue
-
if(!turf.density && !mob_negates_gravity())
continue
-
- return 1
-
+ return A
else
var/atom/movable/AM = A
if(AM == buckled) //Kind of unnecessary but let's just be sure
continue
- if(AM.density)
+ if(!AM.CanPass(src) || AM.density)
if(AM.anchored)
- return 1
+ return AM
if(pulling == AM)
continue
dense_object_backup = AM
+ break
+ . = dense_object_backup
- if(movement_dir && dense_object_backup)
- if(dense_object_backup.newtonian_move(turn(movement_dir, 180))) //You're pushing off something movable, so it moves
- to_chat(src, "You push off of [dense_object_backup] to propel yourself.")
-
-
- return 1
- return 0
/mob/proc/mob_has_gravity(turf/T)
return has_gravity(src, T)
diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm
index ee289cfec9b..5a60d261c91 100644
--- a/code/modules/nano/modules/human_appearance.dm
+++ b/code/modules/nano/modules/human_appearance.dm
@@ -30,6 +30,8 @@
if(can_change(APPEARANCE_RACE) && (href_list["race"] in valid_species))
if(owner.change_species(href_list["race"]))
cut_and_generate_data()
+ // Species change creates new organs - runtimes ahoy if we forget this
+ head_organ = owner.get_organ("head")
return 1
if(href_list["gender"])
if(can_change(APPEARANCE_GENDER))
@@ -102,7 +104,15 @@
return 1
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
+ var/obj/item/organ/internal/eyes/eyes_organ = owner.get_int_organ(/obj/item/organ/internal/eyes)
+ var/eyes_red = 0
+ var/eyes_green = 0
+ var/eyes_blue = 0
+ if(eyes_organ)
+ eyes_red = eyes_organ.eye_colour[1]
+ eyes_green = eyes_organ.eye_colour[2]
+ eyes_blue = eyes_organ.eye_colour[3]
+ var/new_eyes = input("Please select eye color.", "Eye Color", rgb(eyes_red, eyes_green, eyes_blue)) as color|null
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))
@@ -158,7 +168,7 @@
if(data["change_race"])
var/species[0]
for(var/specimen in valid_species)
- species[++species.len] = list("specimen" = specimen)
+ species[++species.len] = list("specimen" = specimen)
data["species"] = species
data["change_gender"] = can_change(APPEARANCE_GENDER)
@@ -171,7 +181,7 @@
for(var/head_accessory_style in valid_head_accessories)
head_accessory_styles[++head_accessory_styles.len] = list("headaccessorystyle" = head_accessory_style)
data["head_accessory_styles"] = head_accessory_styles
- data["head_accessory_style"] = head_organ.ha_style
+ data["head_accessory_style"] = (head_organ ? head_organ.ha_style : "None")
data["change_hair"] = can_change(APPEARANCE_HAIR)
if(data["change_hair"])
@@ -179,7 +189,7 @@
for(var/hair_style in valid_hairstyles)
hair_styles[++hair_styles.len] = list("hairstyle" = hair_style)
data["hair_styles"] = hair_styles
- data["hair_style"] = head_organ.h_style
+ data["hair_style"] = (head_organ ? head_organ.h_style : "Skinhead")
data["change_facial_hair"] = can_change(APPEARANCE_FACIAL_HAIR)
if(data["change_facial_hair"])
@@ -187,7 +197,7 @@
for(var/facial_hair_style in valid_facial_hairstyles)
facial_hair_styles[++facial_hair_styles.len] = list("facialhairstyle" = facial_hair_style)
data["facial_hair_styles"] = facial_hair_styles
- data["facial_hair_style"] = head_organ.f_style
+ data["facial_hair_style"] = (head_organ ? head_organ.f_style : "Shaved")
data["change_markings"] = can_change_markings()
if(data["change_markings"])
@@ -233,6 +243,9 @@
return owner && (flags & APPEARANCE_SKIN) && (owner.species.bodyflags & HAS_SKIN_COLOR)
/datum/nano_module/appearance_changer/proc/can_change_head_accessory()
+ if(!head_organ)
+ log_debug("Missing head!")
+ return 0
return owner && (flags & APPEARANCE_HEAD_ACCESSORY) && (head_organ.species.bodyflags & HAS_HEAD_ACCESSORY)
/datum/nano_module/appearance_changer/proc/can_change_markings()
diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm
index 45849f584ef..affc16de296 100644
--- a/code/modules/projectiles/guns/projectile/revolver.dm
+++ b/code/modules/projectiles/guns/projectile/revolver.dm
@@ -389,6 +389,9 @@
suppressed = 1
needs_permit = 0 //its just a cane beepsky.....
+/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/cane/is_crutch()
+ return 1
+
/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/cane/update_icon()
return
diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm
index f292209ac3e..1a26599b93a 100644
--- a/code/modules/research/designs/mechfabricator_designs.dm
+++ b/code/modules/research/designs/mechfabricator_designs.dm
@@ -601,7 +601,7 @@
name = "Exosuit Engineering Equipment (Cable Layer)"
id = "mech_cable_layer"
build_type = MECHFAB
- build_path = /obj/item/mecha_parts/mecha_equipment/tool/cable_layer
+ build_path = /obj/item/mecha_parts/mecha_equipment/cable_layer
materials = list(MAT_METAL=10000)
construction_time = 100
category = list("Exosuit Equipment")
@@ -610,7 +610,7 @@
name = "Exosuit Engineering Equipment (Drill)"
id = "mech_drill"
build_type = MECHFAB
- build_path = /obj/item/mecha_parts/mecha_equipment/tool/drill
+ build_path = /obj/item/mecha_parts/mecha_equipment/drill
materials = list(MAT_METAL=10000)
construction_time = 100
category = list("Exosuit Equipment")
@@ -619,7 +619,7 @@
name = "Exosuit Engineering Equipment (Extinguisher)"
id = "mech_extinguisher"
build_type = MECHFAB
- build_path = /obj/item/mecha_parts/mecha_equipment/tool/extinguisher
+ build_path = /obj/item/mecha_parts/mecha_equipment/extinguisher
materials = list(MAT_METAL=10000)
construction_time = 100
category = list("Exosuit Equipment")
@@ -628,7 +628,7 @@
name = "Exosuit Engineering Equipment (Hydraulic Clamp)"
id = "mech_hydraulic_clamp"
build_type = MECHFAB
- build_path = /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp
+ build_path = /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp
materials = list(MAT_METAL=10000)
construction_time = 100
category = list("Exosuit Equipment")
@@ -638,7 +638,7 @@
id = "mech_sleeper"
build_type = MECHFAB
req_tech = list("biotech" = 2)
- build_path = /obj/item/mecha_parts/mecha_equipment/tool/sleeper
+ build_path = /obj/item/mecha_parts/mecha_equipment/medical/sleeper
materials = list(MAT_METAL=5000,MAT_GLASS=10000)
construction_time = 100
category = list("Exosuit Equipment")
@@ -648,7 +648,7 @@
id = "mech_syringe_gun"
build_type = MECHFAB
req_tech = list("magnets" = 3,"biotech" = 3)
- build_path = /obj/item/mecha_parts/mecha_equipment/tool/syringe_gun
+ build_path = /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun
materials = list(MAT_METAL=3000,MAT_GLASS=2000)
construction_time = 200
category = list("Exosuit Equipment")
@@ -723,7 +723,7 @@
desc = "An exosuit-mounted Mime Rapid Construction Device."
id = "mech_mrcd"
build_type = MECHFAB
- build_path = /obj/item/mecha_parts/mecha_equipment/tool/mimercd
+ build_path = /obj/item/mecha_parts/mecha_equipment/mimercd
materials = list(MAT_METAL=30000,MAT_TRANQUILLITE=10000)
construction_time = 700
category = list("Exosuit Equipment")
@@ -735,7 +735,7 @@
id = "mech_diamond_drill"
build_type = MECHFAB
req_tech = list("materials" = 4, "engineering" = 3)
- build_path = /obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill
+ build_path = /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill
materials = list(MAT_METAL=10000,MAT_DIAMOND=6500)
construction_time = 100
category = list("Exosuit Equipment")
@@ -744,7 +744,7 @@
name = "Exosuit Engineering Equipement (Mining Scanner)"
id = "mech_mscanner"
build_type = MECHFAB
- build_path = /obj/item/mecha_parts/mecha_equipment/tool/mining_scanner
+ build_path = /obj/item/mecha_parts/mecha_equipment/mining_scanner
materials = list(MAT_METAL=5000,MAT_GLASS=2500)
construction_time = 50
category = list("Exosuit Equipment")
@@ -788,7 +788,7 @@
id = "mech_rcd"
build_type = MECHFAB
req_tech = list("materials" = 4, "bluespace" = 3, "magnets" = 4, "powerstorage"=4, "engineering" = 4)
- build_path = /obj/item/mecha_parts/mecha_equipment/tool/rcd
+ build_path = /obj/item/mecha_parts/mecha_equipment/rcd
materials = list(MAT_METAL=30000,MAT_GOLD=20000,MAT_PLASMA=25000,MAT_SILVER=20000)
construction_time = 1200
category = list("Exosuit Equipment")
diff --git a/code/modules/research/xenoarchaeology/artifact/artifact.dm b/code/modules/research/xenoarchaeology/artifact/artifact.dm
index 82caa2b9be5..57759308aee 100644
--- a/code/modules/research/xenoarchaeology/artifact/artifact.dm
+++ b/code/modules/research/xenoarchaeology/artifact/artifact.dm
@@ -59,7 +59,7 @@
else if(istype(AM,/obj/mecha))
var/obj/mecha/M = AM
- if(istype(M.selected,/obj/item/mecha_parts/mecha_equipment/tool/drill))
+ if(istype(M.selected,/obj/item/mecha_parts/mecha_equipment/drill))
M.selected.action(src)
/obj/structure/boulder/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_hoverpod.dm b/code/modules/research/xenoarchaeology/artifact/artifact_hoverpod.dm
index 4b16c25aeea..6544deb1d68 100644
--- a/code/modules/research/xenoarchaeology/artifact/artifact_hoverpod.dm
+++ b/code/modules/research/xenoarchaeology/artifact/artifact_hoverpod.dm
@@ -3,40 +3,11 @@
icon_state = "engineering_pod"
desc = "Stubby and round, it has a human sized access hatch on the top."
wreckage = /obj/effect/decal/mecha_wreckage/hoverpod
+ stepsound = 'sound/machines/hiss.ogg'
/obj/mecha/working/hoverpod/Process_Spacemove(var/movement_dir = 0)
return 1 // puts the hover in hoverpod
-//these three procs overriden to play different sounds
-/obj/mecha/working/hoverpod/mechturn(direction)
- dir = direction
- //playsound(src,'sound/machines/hiss.ogg',40,1)
- return 1
-
-/obj/mecha/working/hoverpod/mechstep(direction)
- var/result = step(src,direction)
- if(result)
- playsound(src,'sound/machines/hiss.ogg',40,1)
- return result
-
-
-/obj/mecha/working/hoverpod/mechsteprand()
- var/result = step_rand(src)
- if(result)
- playsound(src,'sound/machines/hiss.ogg',40,1)
- return result
-
/obj/effect/decal/mecha_wreckage/hoverpod
name = "Hover pod wreckage"
icon_state = "engineering_pod-broken"
-
- /*New()
- ..()
- var/list/parts = list(
-
- for(var/i=0;i<2;i++)
- if(!isemptylist(parts) && prob(40))
- var/part = pick(parts)
- welder_salvage += part
- parts -= part
- return*/
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index 9122c9983eb..20ae10dccbc 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -787,6 +787,14 @@
shuttleId = "sst"
possible_destinations = "sst_home;sst_away"
+/obj/machinery/computer/shuttle/sit
+ req_access = list(access_syndicate)
+ name = "Syndicate Infiltration Team Shuttle Console"
+ desc = "Used to call and send the SIT shuttle."
+ shuttleId = "sit"
+ possible_destinations = "sit_arrivals;sit_scimaint;sit_engshuttle;sit_away"
+
+
var/global/trade_dock_timelimit = 0
var/global/trade_dockrequest_timelimit = 0
diff --git a/code/modules/space_management/space_chunk.dm b/code/modules/space_management/space_chunk.dm
index b7764e5673e..a150d25d2f3 100644
--- a/code/modules/space_management/space_chunk.dm
+++ b/code/modules/space_management/space_chunk.dm
@@ -1,3 +1,9 @@
+// I'd use consts here, but our coding standard is silly and demonizes usage
+// of that.
+#define BOTTOM_LEFT_CHUNK 1
+#define BOTTOM_RIGHT_CHUNK 2
+#define TOP_LEFT_CHUNK 3
+#define TOP_RIGHT_CHUNK 4
/datum/space_chunk
var/x
var/y
@@ -22,3 +28,8 @@
/datum/space_chunk/proc/return_turfs()
return
+
+#undef BOTTOM_LEFT_CHUNK
+#undef BOTTOM_RIGHT_CHUNK
+#undef TOP_LEFT_CHUNK
+#undef TOP_RIGHT_CHUNK
diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm
index a32186f2827..fc7f631c10e 100644
--- a/code/modules/surgery/bones.dm
+++ b/code/modules/surgery/bones.dm
@@ -4,12 +4,12 @@
//////////////////////////////////////////////////////////////////
///Surgery Datums
/datum/surgery/bone_repair
- name = "bone repair"
+ name = "Bone Repair"
steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/glue_bone, /datum/surgery_step/set_bone, /datum/surgery_step/finish_bone, /datum/surgery_step/generic/cauterize)
possible_locs = list("chest", "l_arm", "l_hand", "r_arm", "r_hand","r_leg", "r_foot", "l_leg", "l_foot", "groin")
/datum/surgery/bone_repair/skull
- name = "bone repair"
+ name = "Skull Repair"
steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/glue_bone, /datum/surgery_step/mend_skull, /datum/surgery_step/finish_bone, /datum/surgery_step/generic/cauterize)
possible_locs = list("head")
@@ -17,14 +17,14 @@
if(istype(target,/mob/living/carbon/human))
var/mob/living/carbon/human/H = target
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
- if(affected && (affected.status & ORGAN_ROBOT))
+ if(!affected)
return 0
- if(affected && (affected.status & ORGAN_BROKEN))
+ if(affected.status & ORGAN_ROBOT)
+ return 0
+ if(affected.cannot_break)
+ return 0
+ if(affected.status & ORGAN_BROKEN)
return 1
- if(target.get_species() == "Machine")
- return 0
- if(target.get_species() == "Diona")
- return 0
return 1
@@ -43,13 +43,12 @@
/datum/surgery_step/glue_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return affected && !(affected.status & ORGAN_ROBOT) && !(affected.cannot_break) && affected.open == 2 && affected.stage == 0
+ return affected && !(affected.status & ORGAN_ROBOT) && !(affected.cannot_break)
/datum/surgery_step/glue_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- if(affected.stage == 0)
- user.visible_message("[user] starts applying medication to the damaged bones in [target]'s [affected.name] with \the [tool]." , \
- "You start applying medication to the damaged bones in [target]'s [affected.name] with \the [tool].")
+ user.visible_message("[user] starts applying medication to the damaged bones in [target]'s [affected.name] with \the [tool]." , \
+ "You start applying medication to the damaged bones in [target]'s [affected.name] with \the [tool].")
target.custom_pain("Something in your [affected.name] is causing you a lot of pain!",1)
..()
@@ -57,7 +56,6 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(" [user] applies some [tool] to [target]'s bone in [affected.name]", \
" You apply some [tool] to [target]'s bone in [affected.name] with \the [tool].")
- affected.stage = 1
return 1
@@ -79,7 +77,7 @@
/datum/surgery_step/set_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return affected && !(affected.status & ORGAN_ROBOT) && affected.limb_name != "head" && affected.open == 2 && affected.stage == 1
+ return affected && !(affected.status & ORGAN_ROBOT)
/datum/surgery_step/set_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
@@ -93,7 +91,6 @@
if(affected.status & ORGAN_BROKEN)
user.visible_message(" [user] sets the bone in [target]'s [affected.name] in place with \the [tool].", \
" You set the bone in [target]'s [affected.name] in place with \the [tool].")
- affected.stage = 2
return 1
else
user.visible_message(" [user] sets the bone in [target]'s [affected.name] in place with \the [tool].", \
@@ -119,7 +116,7 @@
/datum/surgery_step/mend_skull/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return affected && !(affected.status & ORGAN_ROBOT) && affected.limb_name == "head" && affected.open == 2 && affected.stage == 1
+ return affected && !(affected.status & ORGAN_ROBOT) && affected.limb_name == "head"
/datum/surgery_step/mend_skull/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("[user] is beginning piece together [target]'s skull with \the [tool]." , \
@@ -128,16 +125,15 @@
/datum/surgery_step/mend_skull/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message(" [user] sets [target]'s skull with \the [tool]." , \
- " You set [target]'s skull with \the [tool].")
- affected.stage = 2
+ user.visible_message(" [user] sets [target]'s [affected.encased] with \the [tool]." , \
+ " You set [target]'s [affected.encased] with \the [tool].")
return 1
/datum/surgery_step/mend_skull/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message(" [user]'s hand slips, damaging [target]'s face with \the [tool]!" , \
- " Your hand slips, damaging [target]'s face with \the [tool]!")
+ user.visible_message("[user]'s hand slips, damaging [target]'s face with \the [tool]!" , \
+ "Your hand slips, damaging [target]'s face with \the [tool]!")
var/obj/item/organ/external/head/h = affected
h.createwound(BRUISE, 10)
h.disfigured = 1
@@ -157,7 +153,7 @@
/datum/surgery_step/finish_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return affected && !(affected.status & ORGAN_ROBOT) && affected.open == 2 && affected.stage == 2
+ return affected && !(affected.status & ORGAN_ROBOT)
/datum/surgery_step/finish_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
@@ -165,14 +161,14 @@
"You start to finish mending the damaged bones in [target]'s [affected.name] with \the [tool].")
..()
-/datum/surgery_step/finish_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+/datum/surgery_step/finish_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(" [user] has mended the damaged bones in [target]'s [affected.name] with \the [tool]." , \
" You have mended the damaged bones in [target]'s [affected.name] with \the [tool]." )
affected.status &= ~ORGAN_BROKEN
affected.status &= ~ORGAN_SPLINTED
- affected.stage = 0
affected.perma_injury = 0
+ surgery.can_cancel = 1
return 1
@@ -180,4 +176,4 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(" [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.name]!" , \
" Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!")
- return 0
\ No newline at end of file
+ return 0
diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm
index 90460f34c21..a1ea245d138 100644
--- a/code/modules/surgery/encased.dm
+++ b/code/modules/surgery/encased.dm
@@ -52,6 +52,8 @@
user.visible_message(" [user] has cut [target]'s [affected.encased] open with \the [tool].", \
" You have cut [target]'s [affected.encased] open with \the [tool].")
affected.open = 2.5
+ // crossin' the rubicon
+ surgery.can_cancel = 0
return 1
/datum/surgery_step/open_encased/saw/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -223,5 +225,6 @@
user.visible_message(msg, self_msg)
affected.open = 2
+ surgery.can_cancel = 1
- return 1
\ No newline at end of file
+ return 1
diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm
index 6e947511dd6..406c1f83083 100644
--- a/code/modules/surgery/face.dm
+++ b/code/modules/surgery/face.dm
@@ -3,7 +3,7 @@
// FACE SURGERY //
//////////////////////////////////////////////////////////////////
/datum/surgery/plastic_surgery
- name = "face repair"
+ name = "Face Repair"
steps = list(/datum/surgery_step/generic/cut_face, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/face/mend_vocal, /datum/surgery_step/face/fix_face,/datum/surgery_step/face/cauterize)
possible_locs = list("head")
@@ -13,9 +13,11 @@
if(istype(target,/mob/living/carbon/human))
var/mob/living/carbon/human/H = target
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
- if(affected && (affected.status & ORGAN_ROBOT))
+ if(!affected)
return 0
- if((target.get_species() == "Machine"))
+ if(affected.status & ORGAN_ROBOT)
+ return 0
+ if(!affected.disfigured)
return 0
return 1
@@ -23,14 +25,6 @@
priority = 2
can_infect = 0
-/datum/surgery_step/face/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- if(!hasorgans(target))
- return 0
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- if(!affected || (affected.status & ORGAN_ROBOT))
- return 0
- return target_zone == "mouth"
-
/datum/surgery_step/generic/cut_face
name = "make incision"
allowed_tools = list(
@@ -45,9 +39,6 @@
time = 16
-/datum/surgery_step/generic/cut_face/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- return ..() && target_zone == "mouth" //&& target.op_stage.face == 0//I NEED TO REPLACE THE OPSTAGE SHIT!
-
/datum/surgery_step/generic/cut_face/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
user.visible_message("[user] starts to cut open [target]'s face and neck with \the [tool].", \
"You start to cut open [target]'s face and neck with \the [tool].")
@@ -56,7 +47,6 @@
/datum/surgery_step/generic/cut_face/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
user.visible_message(" [user] has cut open [target]'s face and neck with \the [tool]." , \
" You have cut open [target]'s face and neck with \the [tool].",)
- //target.op_stage.face = 1//DID I MENTION I NEED TO REPLACE THE OPSTAGE SHIT!
return 1
@@ -80,9 +70,6 @@
time = 24
-/datum/surgery_step/face/mend_vocal/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- return ..()// && target.op_stage.face == 1 //NO REALLY NED TO REPLACE, MAYBE WITH FUCKING istype(S.get_surgery_step(), /datum/surgery_step/cut_face)) OR SOMETHING
-
/datum/surgery_step/face/mend_vocal/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
user.visible_message("[user] starts mending [target]'s vocal cords with \the [tool].", \
"You start mending [target]'s vocal cords with \the [tool].")
@@ -91,7 +78,6 @@
/datum/surgery_step/face/mend_vocal/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
user.visible_message(" [user] mends [target]'s vocal cords with \the [tool].", \
" You mend [target]'s vocal cords with \the [tool].")
- //target.op_stage.face = 2//I NEED TO REPLACE THE OPSTAGE SHIT!
return 1
/datum/surgery_step/face/mend_vocal/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -110,9 +96,6 @@
time = 64
-/datum/surgery_step/face/fix_face/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- return ..() //&& target.op_stage.face == 2//I NEED TO REPLACE THE OPSTAGE SHIT!
-
/datum/surgery_step/face/fix_face/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
user.visible_message("[user] starts pulling skin on [target]'s face back in place with \the [tool].", \
"You start pulling skin on [target]'s face back in place with \the [tool].")
@@ -121,7 +104,6 @@
/datum/surgery_step/face/fix_face/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
user.visible_message(" [user] pulls skin on [target]'s face back in place with \the [tool].", \
" You pull skin on [target]'s face back in place with \the [tool].")
- //target.op_stage.face = 3//I NEED TO REPLACE THE OPSTAGE SHIT!
return 1
/datum/surgery_step/face/fix_face/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -145,9 +127,6 @@
time = 24
-/datum/surgery_step/face/cauterize/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- return ..()// && target.op_stage.face > 0//I NEED TO REPLACE THE OPSTAGE SHIT!
-
/datum/surgery_step/face/cauterize/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
user.visible_message("[user] is beginning to cauterize the incision on [target]'s face and neck with \the [tool]." , \
"You are beginning to cauterize the incision on [target]'s face and neck with \the [tool].")
@@ -159,12 +138,10 @@
" You cauterize the incision on [target]'s face and neck with \the [tool].")
affected.open = 0
affected.status &= ~ORGAN_BLEEDING
- //if(target.op_stage.face == 3)//I NEED TO REPLACE THE OPSTAGE SHIT!
var/obj/item/organ/external/head/h = affected
h.disfigured = 0
h.update_icon()
target.regenerate_icons()
- //target.op_stage.face = 0//I NEED TO REPLACE THE OPSTAGE SHIT!
return 1
@@ -174,4 +151,4 @@
" Your hand slips, leaving a small burn on [target]'s face with \the [tool]!")
target.apply_damage(4, BURN, affected)
- return 0
\ No newline at end of file
+ return 0
diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm
index d02787eb3b5..51ba3a9b2d6 100644
--- a/code/modules/surgery/generic.dm
+++ b/code/modules/surgery/generic.dm
@@ -83,11 +83,6 @@
time = 24
-/datum/surgery_step/generic/clamp_bleeders/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return ..() && affected.open && (affected.status & ORGAN_BLEEDING)
-
-
/datum/surgery_step/generic/clamp_bleeders/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts clamping bleeders in [target]'s [affected.name] with \the [tool].", \
@@ -122,10 +117,6 @@
time = 24
-/datum/surgery_step/generic/retract_skin/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return ..() && affected.open == 1 && !(affected.status & ORGAN_BLEEDING)
-
/datum/surgery_step/generic/retract_skin/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
var/msg = "[user] starts to pry open the incision on [target]'s [affected.name] with \the [tool]."
@@ -214,7 +205,7 @@
//drill bone
/datum/surgery_step/generic/drill
name = "drill bone"
- allowed_tools = list(/obj/item/weapon/surgicaldrill = 100, /obj/item/weapon/pickaxe/drill = 60, /obj/item/mecha_parts/mecha_equipment/tool/drill = 60, /obj/item/weapon/screwdriver = 20)
+ allowed_tools = list(/obj/item/weapon/surgicaldrill = 100, /obj/item/weapon/pickaxe/drill = 60, /obj/item/mecha_parts/mecha_equipment/drill = 60, /obj/item/weapon/screwdriver = 20)
time = 30
/datum/surgery_step/generic/drill/begin_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -264,7 +255,9 @@
add_logs(target,user ,"surgically removed [affected.name] from", addition="INTENT: [uppertext(user.a_intent)]")//log it
- affected.droplimb(1,DROPLIMB_EDGE)
+ var/atom/movable/thing = affected.droplimb(1,DROPLIMB_EDGE)
+ if(istype(thing,/obj/item))
+ user.put_in_hands(thing)
return 1
/datum/surgery_step/generic/amputate/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -273,4 +266,4 @@
" Your hand slips, sawwing through the bone in [target]'s [affected.name] with \the [tool]!")
affected.createwound(CUT, 30)
affected.fracture()
- return 0
\ No newline at end of file
+ return 0
diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm
index a21a7422696..1991ce8ec21 100644
--- a/code/modules/surgery/helpers.dm
+++ b/code/modules/surgery/helpers.dm
@@ -28,19 +28,26 @@
for(var/path in S.allowed_mob)
if(istype(M, path))
+ // If there are multiple surgeries with the same name,
+ // prepare to cry
available_surgeries[S.name] = S
break
if(override)
+ var/datum/surgery/S
if(istype(I,/obj/item/robot_parts))
- var/datum/surgery/S = available_surgeries["robotic limb attachment"]
- if(S)
- var/datum/surgery/procedure = new S.type
- if(procedure)
- procedure.location = selected_zone
- M.surgeries += procedure
- procedure.organ_ref = affecting
- procedure.next_step(user, M)
+ S = available_surgeries["Apply Robotic Prosthetic"]
+ if(istype(I,/obj/item/organ/external))
+ var/obj/item/organ/external/E = I
+ if(E.robotic == 2)
+ S = available_surgeries["Synthetic Limb Reattachment"]
+ if(S)
+ var/datum/surgery/procedure = new S.type
+ if(procedure)
+ procedure.location = selected_zone
+ M.surgeries += procedure
+ procedure.organ_ref = affecting
+ procedure.next_step(user, M)
else
var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries
@@ -77,7 +84,7 @@
-proc/get_location_modifier(mob/M)
+/proc/get_location_modifier(mob/M)
var/turf/T = get_turf(M)
if(locate(/obj/machinery/optable, T))
return 1
@@ -86,4 +93,8 @@ proc/get_location_modifier(mob/M)
else if(locate(/obj/structure/stool/bed, T))
return 0.7
else
- return 0.5
\ No newline at end of file
+ return 0.5
+
+// Called when a limb containing this object is placed back on a body
+/atom/movable/proc/attempt_become_organ(obj/item/organ/external/parent,mob/living/carbon/human/H)
+ return 0
diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm
index 1aec72f1d63..a3b7ec2d908 100644
--- a/code/modules/surgery/implant.dm
+++ b/code/modules/surgery/implant.dm
@@ -6,41 +6,45 @@
//////////////////////////////////////////////////////////////////
/datum/surgery/cavity_implant
- name = "cavity implant/removal"
+ name = "Cavity Implant/Removal"
steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/open_encased/saw,
/datum/surgery_step/open_encased/retract, /datum/surgery_step/cavity/make_space,/datum/surgery_step/cavity/place_item,/datum/surgery_step/cavity/close_space,/datum/surgery_step/open_encased/close,/datum/surgery_step/glue_bone, /datum/surgery_step/set_bone,/datum/surgery_step/finish_bone,/datum/surgery_step/generic/cauterize)
-
+ can_cancel = 0
possible_locs = list("chest","head")
/datum/surgery/cavity_implant/soft
- name = "cavity implant/removal"
+ name = "Cavity Implant/Removal"
steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/generic/cut_open, /datum/surgery_step/cavity/make_space,/datum/surgery_step/cavity/place_item,/datum/surgery_step/cavity/close_space,/datum/surgery_step/generic/cauterize)
possible_locs = list("groin")
/datum/surgery/cavity_implant/synth
- name = "robotic cavity implant"
+ name = "Robotic Cavity Implant/Removal"
steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/cavity/place_item,/datum/surgery_step/robotics/external/close_hatch)
possible_locs = list("chest","head","groin")
-/datum/surgery/cavity_implant/can_start(mob/user, mob/living/carbon/target)
- if(target.get_species() == "Machine")
+/datum/surgery/cavity_implant/can_start(mob/user, mob/living/carbon/human/target)
+ if(!istype(target))
+ return 0
+ var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting)
+ if(!affected)
+ return 0
+ if(affected.status & ORGAN_ROBOT)
return 0
return 1
-/datum/surgery/cavity_implant/synth/can_start(mob/user, mob/living/carbon/target)
- return target.get_species() == "Machine"
+/datum/surgery/cavity_implant/synth/can_start(mob/user, mob/living/carbon/human/target)
+ if(!istype(target))
+ return 0
+ var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting)
+ if(!affected)
+ return 0
+ return (affected.status & ORGAN_ROBOT)
/datum/surgery_step/cavity
priority = 1
-/datum/surgery_step/cavity/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- if(!hasorgans(target))
- return 0
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return affected && affected.open == (affected.encased ? 3 : 2) && !(affected.status & ORGAN_BLEEDING)
-
/datum/surgery_step/cavity/proc/get_max_wclass(obj/item/organ/external/affected)
switch(affected.limb_name)
if("head")
@@ -77,16 +81,11 @@
time = 54
-/datum/surgery_step/cavity/make_space/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return ..() && !affected.cavity && !affected.hidden
-
/datum/surgery_step/cavity/make_space/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \
"You start making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." )
target.custom_pain("The pain in your chest is living hell!",1)
- affected.cavity = 1
..()
/datum/surgery_step/cavity/make_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -111,16 +110,11 @@
time = 24
-/datum/surgery_step/cavity/close_space/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return ..() && affected.cavity
-
/datum/surgery_step/cavity/close_space/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts mending [target]'s [get_cavity(affected)] cavity wall with \the [tool].", \
"You start mending [target]'s [get_cavity(affected)] cavity wall with \the [tool]." )
target.custom_pain("The pain in your chest is living hell!",1)
- affected.cavity = 0
..()
/datum/surgery_step/cavity/close_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -145,17 +139,24 @@
if(!ishuman(target))
return 0
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- var/can_fit = affected && !affected.hidden && affected.cavity && tool.w_class <= get_max_wclass(affected)
- return ..() && can_fit
+ if(!affected)
+ to_chat(user, "\The [target] lacks a [parse_zone(target_zone)]!")
+ return 0
+ if(tool)
+ var/can_fit = !affected.hidden && tool.w_class <= get_max_wclass(affected)
+ if(!can_fit)
+ to_chat(user, "\The [tool] won't fit in \The [affected.name]!")
+ return 0
+ return ..()
/datum/surgery_step/cavity/place_item/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- for(var/obj/item/I in target.internal_organs)
+ for(var/obj/item/I in affected.contents)
if(!istype(I, /obj/item/organ))
IC = I
break
if(istype(tool,/obj/item/weapon/cautery))
- to_chat(user, "you prepare to close the cavity wall.")
+ to_chat(user, "You prepare to close the cavity wall.")
else if(tool)
user.visible_message("[user] starts putting \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \
"You start putting \the [tool] inside [target]'s [get_cavity(affected)] cavity." )
@@ -203,8 +204,7 @@
affected.owner.custom_pain("You feel something rip in your [affected.name]!", 1)
user.drop_item()
target.internal_organs += tool
- tool.loc = target
- affected.cavity = 0
+ tool.forceMove(affected)
return 1
else
if(IC)
@@ -222,22 +222,35 @@
//////////////////////////////////////////////////////////////////
/datum/surgery/cavity_implant_rem
- name = "implant removal"
+ name = "Implant Removal"
steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin,/datum/surgery_step/cavity/implant_removal,/datum/surgery_step/cavity/close_space,/datum/surgery_step/generic/cauterize/)
possible_locs = list("chest")//head is for borers..i can put it elsewhere
/datum/surgery/cavity_implant_rem/synth
- name = "implant removal"
+ name = "Implant Removal"
steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/cavity/implant_removal,/datum/surgery_step/robotics/external/close_hatch)
possible_locs = list("chest")//head is for borers..i can put it elsewhere
-/datum/surgery/cavity_implant_rem/can_start(mob/user, mob/living/carbon/target)
- if(target.get_species() == "Machine")
+/datum/surgery/cavity_implant_rem/can_start(mob/user, mob/living/carbon/human/target)
+ if(!istype(target))
+ return 0
+ var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting)
+ if(!affected)
+ return 0
+ if(affected.status & ORGAN_ROBOT)
return 0
return 1
-/datum/surgery/cavity_implant_rem/synth/can_start(mob/user, mob/living/carbon/target)
- return target.get_species() == "Machine"
+/datum/surgery/cavity_implant_rem/synth/can_start(mob/user, mob/living/carbon/human/target)
+ if(!istype(target))
+ return 0
+ var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting)
+ if(!affected)
+ return 0
+ if(!(affected.status & ORGAN_ROBOT))
+ return 0
+
+ return 1
/datum/surgery_step/cavity/implant_removal
name = "extract implant"
@@ -309,25 +322,34 @@
//////////////////////////////////////////////////////////////////
/datum/surgery/embedded_removal
- name = "removal of embedded objects"
+ name = "Removal of Embedded Objects"
steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/remove_object, /datum/surgery_step/generic/cauterize)
possible_locs = list("r_arm","l_arm","r_leg","l_leg","r_hand","r_foot","l_hand","l_foot","groin","chest","head")
/datum/surgery/embedded_removal/synth
- name = "removal of embedded objects"
steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch, /datum/surgery_step/remove_object, /datum/surgery_step/robotics/external/close_hatch)
possible_locs = list("r_arm","l_arm","r_leg","l_leg","r_hand","r_foot","l_hand","l_foot","groin","chest","head")
-/datum/surgery/embedded_removal/can_start(mob/user, mob/living/carbon/target)
- if(target.get_species() == "Machine")
+/datum/surgery/embedded_removal/can_start(mob/user, mob/living/carbon/human/target)
+ if(!istype(target))
+ return 0
+ var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting)
+ if(!affected)
+ return 0
+ if(affected.status & ORGAN_ROBOT)
return 0
return 1
-/datum/surgery/embedded_removal/synth/can_start(mob/user, mob/living/carbon/target)
- if(target.get_species() == "Machine")
- return 1
- return 0
+/datum/surgery/embedded_removal/synth/can_start(mob/user, mob/living/carbon/human/target)
+ if(!istype(target))
+ return 0
+ var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting)
+ if(!affected)
+ return 0
+ if(!(affected.status & ORGAN_ROBOT))
+ return 0
+ return 1
/datum/surgery_step/remove_object
name = "remove embedded objects"
diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm
index ad0a1973b8f..a0dcd29525f 100644
--- a/code/modules/surgery/limb_reattach.dm
+++ b/code/modules/surgery/limb_reattach.dm
@@ -4,7 +4,7 @@
//////////////////////////////////////////////////////////////////
/datum/surgery/amputation
- name = "amputation"
+ name = "Amputation"
steps = list(/datum/surgery_step/generic/amputate)
possible_locs = list("head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin")
@@ -13,16 +13,18 @@
if(ishuman(target))
var/mob/living/carbon/human/H = target
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
- if((target.get_species() == "Machine"))
- return 0
if(!affected)
return 0
+ if(affected.status & ORGAN_ROBOT)
+ return 0
+ if(affected.cannot_amputate)
+ return 0
return 1
/datum/surgery/reattach
- name = "limb attachment"
+ name = "Limb Reattachment"
steps = list(/datum/surgery_step/limb/attach,/datum/surgery_step/limb/connect)
possible_locs = list("head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin")
@@ -30,29 +32,30 @@
if(ishuman(target))
var/mob/living/carbon/human/H = target
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
+ if(target.get_species() == "Machine")
+ // RIP bi-centennial man
+ return 0
if(!affected)
return 1
- if((target.get_species() == "Machine"))
- return 0
- return 0
+ return 0
/datum/surgery/reattach_synth
- name = "limb attachment"
- steps = list(/datum/surgery_step/limb/attach)
+ name = "Synthetic Limb Reattachment"
+ steps = list(/datum/surgery_step/limb/attach/robo)
possible_locs = list("head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin")
/datum/surgery/reattach_synth/can_start(mob/user, mob/living/carbon/target)
if(ishuman(target))
var/mob/living/carbon/human/H = target
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
- if(!affected && (target.get_species() == "Machine"))
+ if(!affected)
return 1
return 0
/datum/surgery/robo_attach
- name = "robotic limb attachment"
+ name = "Apply Robotic Prosthetic"
steps = list(/datum/surgery_step/limb/mechanize)
possible_locs = list("head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin")
@@ -67,14 +70,14 @@
/datum/surgery_step/limb/
can_infect = 0
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- if(!hasorgans(target))
- return 0
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- if(affected)
- return 0
- var/list/organ_data = target.species.has_limbs["[target_zone]"]
- return !isnull(organ_data)
+/datum/surgery_step/limb/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if(!hasorgans(target))
+ return 0
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ if(affected)
+ return 0
+ var/list/organ_data = target.species.has_limbs["[target_zone]"]
+ return !isnull(organ_data)
/datum/surgery_step/limb/attach
name = "attach limb"
@@ -82,6 +85,31 @@
time = 32
+/datum/surgery_step/limb/attach/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if(!..())
+ return 0
+ if(!istype(tool, /obj/item/organ/external))
+ return 0
+ var/obj/item/organ/external/E = tool
+ if(target.get_organ(E.limb_name))
+ // This catches attaching an arm to a missing hand while the arm is still there
+ to_chat(user, "[target] already has an [E.name]!")
+ return 0
+ if(E.limb_name != target_zone)
+ // This ensures you must be aiming at the appropriate location to attach
+ // this limb. (Can't aim at a missing foot to re-attach a missing arm)
+ to_chat(user, "The [E.name] does not go there.")
+ return 0
+ // if(E.parent_organ && !target.get_organ(E.parent_organ))
+ // // No rayman allowed
+ // return 0
+ if(!is_correct_limb(E))
+ to_chat(user, "This is not the correct limb type for this surgery!")
+ return 0
+
+ return 1
+
+
/datum/surgery_step/limb/attach/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/E = tool
user.visible_message("[user] starts attaching [E.name] to [target]'s [E.amputation_point].", \
@@ -91,29 +119,7 @@
var/obj/item/organ/external/E = tool
user.visible_message("[user] has attached [target]'s [E.name] to the [E.amputation_point].", \
"You have attached [target]'s [E.name] to the [E.amputation_point].")
- user.unEquip(E)
- E.replaced(target)
- E.forceMove(target)
- if(target.get_species() == "Machine")//as this is the only step needed for ipc put togethers
- if(!(E.dna) && E.robotic == 2 && target.dna)
- E.dna = target.dna.Clone()
- if(!E.blood_DNA)
- E.blood_DNA = list()
- E.blood_DNA[target.dna.unique_enzymes] = target.dna.b_type
- if(target_zone == "head")
- var/obj/item/organ/external/head/H = target.get_organ("head")
- var/datum/robolimb/robohead = all_robolimbs[H.model]
- if(robohead.is_monitor) //Ensures that if an IPC gets a head that's got a human hair wig attached to their body, the hair won't wipe.
- H.h_style = ""
- H.f_style = ""
- target.m_style = ""
- E.status &= ~ORGAN_DESTROYED
- if(E.children)
- for(var/obj/item/organ/external/C in E.children)
- C.status &= ~ORGAN_DESTROYED
- target.update_body()
- target.updatehealth()
- target.UpdateDamageIcon()
+ attach_limb(user, target, E)
return 1
/datum/surgery_step/limb/attach/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -123,6 +129,48 @@
target.apply_damage(10, BRUTE, null, sharp=1)
return 0
+
+/datum/surgery_step/limb/attach/proc/is_correct_limb(obj/item/organ/external/E)
+ if(E.status & ORGAN_ROBOT)
+ return 0
+ return 1
+
+/datum/surgery_step/limb/attach/proc/attach_limb(mob/living/user, mob/living/carbon/human/target, obj/item/organ/external/E)
+ user.unEquip(E)
+ E.replaced(target)
+ target.update_body()
+ target.updatehealth()
+ target.UpdateDamageIcon()
+
+
+// This is a step that handles robotic limb attachment while skipping the "connect" step
+// THIS IS DISTINCT FROM USING A CYBORG LIMB TO CREATE A NEW LIMB ORGAN
+/datum/surgery_step/limb/attach/robo
+ name = "attach robotic limb"
+
+/datum/surgery_step/limb/attach/robo/is_correct_limb(obj/item/organ/external/E)
+ if(!(E.status & ORGAN_ROBOT))
+ return 0
+ return 1
+
+/datum/surgery_step/limb/attach/robo/attach_limb(mob/living/user, mob/living/carbon/human/target, obj/item/organ/external/E)
+ // Fixes fabricator IPC heads
+ if(!(E.dna) && E.robotic == 2 && target.dna)
+ E.set_dna(target.dna)
+ ..()
+ if(E.limb_name == "head")
+ var/obj/item/organ/external/head/H = target.get_organ("head")
+ var/datum/robolimb/robohead = all_robolimbs[H.model]
+ if(robohead.is_monitor) //Ensures that if an IPC gets a head that's got a human hair wig attached to their body, the hair won't wipe.
+ H.h_style = ""
+ H.f_style = ""
+ target.m_style = ""
+ E.status &= ~ORGAN_DESTROYED
+ if(E.children)
+ for(var/obj/item/organ/external/C in E.children)
+ C.status &= ~ORGAN_DESTROYED
+
+
/datum/surgery_step/limb/connect
name = "connect limb"
allowed_tools = list(
@@ -134,9 +182,11 @@
time = 32
+
/datum/surgery_step/limb/connect/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/external/E = target.get_organ(target_zone)
- return E && !E.is_stump() && (E.status & ORGAN_DESTROYED)
+ if(!hasorgans(target))
+ return 0
+ return 1
/datum/surgery_step/limb/connect/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/E = target.get_organ(target_zone)
@@ -167,7 +217,7 @@
return 0
/datum/surgery_step/limb/mechanize
- name = "attach robotic limb"
+ name = "apply robotic prosthetic"
allowed_tools = list(/obj/item/robot_parts = 100)
time = 32
@@ -177,6 +227,7 @@
var/obj/item/robot_parts/p = tool
if(p.part)
if(!(target_zone in p.part))
+ to_chat(user, "\The [tool] does not go there!")
return 0
return isnull(target.get_organ(target_zone))
@@ -196,13 +247,13 @@
var/list/organ_data = target.species.has_limbs["[part_name]"]
if(!organ_data)
continue
+ // This will break if there's more than one stump ever
var/obj/item/organ/external/stump = target.organs_by_name["limb stump"]
if(stump)
stump.remove(target)
var/new_limb_type = organ_data["path"]
var/obj/item/organ/external/new_limb = new new_limb_type(target)
new_limb.robotize(L.model_info)
- new_limb.replaced(target)
new_limb.status &= ~ORGAN_DESTROYED
if(new_limb.children)
for(var/obj/item/organ/external/C in new_limb.children)
diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm
index 679a98c98f4..407a6b02777 100644
--- a/code/modules/surgery/organs/augments_eyes.dm
+++ b/code/modules/surgery/organs/augments_eyes.dm
@@ -13,41 +13,16 @@
var/flash_protect = 0
var/aug_message = "Your vision is augmented!"
-/obj/item/organ/internal/cyberimp/eyes/proc/update_colour()
- if(!owner)
- return
- eye_colour = list(
- owner.r_eyes ? owner.r_eyes : 0,
- owner.g_eyes ? owner.g_eyes : 0,
- owner.b_eyes ? owner.b_eyes : 0
- )
-
/obj/item/organ/internal/cyberimp/eyes/insert(var/mob/living/carbon/M, var/special = 0)
..()
- if(istype(owner, /mob/living/carbon/human) && eye_colour)
- var/mob/living/carbon/human/HMN = owner
- old_eye_colour[1] = HMN.r_eyes
- old_eye_colour[2] = HMN.g_eyes
- old_eye_colour[2] = HMN.b_eyes
-
- HMN.r_eyes = eye_colour[1]
- HMN.g_eyes = eye_colour[2]
- HMN.b_eyes = eye_colour[3]
- HMN.update_eyes()
if(aug_message && !special)
to_chat(owner, "[aug_message]")
M.sight |= vision_flags
/obj/item/organ/internal/cyberimp/eyes/remove(var/mob/living/carbon/M, var/special = 0)
- ..()
+ . = ..()
M.sight ^= vision_flags
- if(istype(owner,/mob/living/carbon/human) && eye_colour)
- var/mob/living/carbon/human/HMN = owner
- HMN.r_eyes = old_eye_colour[1]
- HMN.g_eyes = old_eye_colour[2]
- HMN.b_eyes = old_eye_colour[3]
- HMN.update_eyes()
/obj/item/organ/internal/cyberimp/eyes/on_life()
..()
@@ -97,7 +72,7 @@
M.permanent_huds |= H
/obj/item/organ/internal/cyberimp/eyes/hud/remove(var/mob/living/carbon/M, var/special = 0)
- ..()
+ . = ..()
if(HUD_type)
var/datum/atom_hud/H = huds[HUD_type]
M.permanent_huds ^= H
@@ -132,4 +107,4 @@
// Welding with thermals will still hurt your eyes a bit.
/obj/item/organ/internal/cyberimp/eyes/shield/emp_act(severity)
- return
\ No newline at end of file
+ return
diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm
index 2fa12d1a0dc..b860e3f062c 100644
--- a/code/modules/surgery/organs/augments_internal.dm
+++ b/code/modules/surgery/organs/augments_internal.dm
@@ -116,7 +116,7 @@
r_hand_obj.flags ^= NODROP
/obj/item/organ/internal/cyberimp/brain/anti_drop/remove(var/mob/living/carbon/M, special = 0)
- ..()
+ . = ..()
if(active)
ui_action_click()
diff --git a/code/modules/surgery/organs/body_egg.dm b/code/modules/surgery/organs/body_egg.dm
index 3653e3df327..335d4e5b751 100644
--- a/code/modules/surgery/organs/body_egg.dm
+++ b/code/modules/surgery/organs/body_egg.dm
@@ -25,7 +25,7 @@
owner.med_hud_set_status()
spawn(0)
RemoveInfectionImages(owner)
- ..()
+ . = ..()
/obj/item/organ/internal/body_egg/process()
if(!owner)
@@ -46,4 +46,4 @@
return
/obj/item/organ/internal/body_egg/proc/RemoveInfectionImages()
- return
\ No newline at end of file
+ return
diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm
index b49ccc6a838..26d50abaa75 100644
--- a/code/modules/surgery/organs/organ.dm
+++ b/code/modules/surgery/organs/organ.dm
@@ -314,6 +314,7 @@ var/list/organ_cache = list()
msg_admin_attack("[key_name_admin(user)] removed a vital organ ([src]) from [key_name_admin(owner)]")
owner.death()
owner = null
+ return src
/obj/item/organ/proc/replaced(var/mob/living/carbon/human/target,var/obj/item/organ/external/affected)
diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm
index 8ec993c8db8..e2702b36afe 100644
--- a/code/modules/surgery/organs/organ_external.dm
+++ b/code/modules/surgery/organs/organ_external.dm
@@ -51,8 +51,6 @@
var/broken_description
var/open = 0
- var/stage = 0
- var/cavity = 0
var/sabotaged = 0 //If a prosthetic limb is emagged, it will detonate when it fails.
var/encased // Needs to be opened with a saw to access the organs.
@@ -71,6 +69,9 @@
if(parent && parent.children)
parent.children -= src
+ if(owner)
+ owner.organs_by_name[limb_name] = null
+
if(internal_organs)
for(var/obj/item/organ/internal/O in internal_organs)
internal_organs -= O
@@ -87,38 +88,35 @@
return ..()
/obj/item/organ/external/attackby(obj/item/weapon/W as obj, mob/user as mob)
- switch(stage)
+ switch(open)
if(0)
if(istype(W,/obj/item/weapon/scalpel))
spread_germs_to_organ(src,user)
- user.visible_message("[user] cuts [src] open with [W]!")
- stage++
+ user.visible_message("[user] cuts [src] open with [W]!")
+ open++
return
if(1)
if(istype(W,/obj/item/weapon/retractor))
spread_germs_to_organ(src,user)
- user.visible_message("[user] cracks [src] open like an egg with [W]!")
- stage++
+ user.visible_message("[user] cracks [src] open like an egg with [W]!")
+ open++
return
if(2)
if(istype(W,/obj/item/weapon/hemostat))
spread_germs_to_organ(src,user)
if(contents.len)
var/obj/item/removing = pick(contents)
- removing.loc = get_turf(user.loc)
var/obj/item/organ/internal/O = removing
if(istype(O))
O.status |= ORGAN_CUT_AWAY
if(!O.sterile)
spread_germs_to_organ(O,user) // This wouldn't be any cleaner than the actual surgery
- O.forceMove(get_turf(src))
- if(!(user.l_hand && user.r_hand))
- user.put_in_hands(removing)
- user.visible_message("[user] extracts [removing] from [src] with [W]!")
+ user.put_in_hands(removing)
+ user.visible_message("[user] extracts [removing] from [src] with [W]!")
else
- user.visible_message("[user] fishes around fruitlessly in [src] with [W].")
+ user.visible_message("[user] fishes around fruitlessly in [src] with [W].")
return
- ..()
+ . = ..()
/obj/item/organ/external/update_health()
@@ -139,14 +137,12 @@
status = status & ~ORGAN_DESTROYED
forceMove(owner)
if(istype(owner))
+ if(!isnull(owner.organs_by_name[limb_name]))
+ log_debug("Duplicate organ in slot \"[limb_name]\", mob '[target]'")
owner.organs_by_name[limb_name] = src
owner.organs |= src
- for(var/obj/item/organ/organ in src)
- if(istype(src, /obj/item/organ/internal))
- var/obj/item/organ/internal/I = organ
- if(target.get_organ_slot(I.slot))
- continue // Just leave it inside its limb, so brains with brainmobs in them don't get voided.
- organ.replaced(owner,src)
+ for(var/atom/movable/stuff in src)
+ stuff.attempt_become_organ(src, owner)
if(parent_organ)
parent = owner.organs_by_name[src.parent_organ]
@@ -161,6 +157,12 @@
break
parent.update_damages()
+/obj/item/organ/external/attempt_become_organ(obj/item/organ/external/parent,mob/living/carbon/human/H)
+ if(parent_organ != parent.limb_name)
+ return 0
+ replaced(H)
+ return 1
+
/****************************************************
DAMAGE PROCS
****************************************************/
@@ -691,7 +693,8 @@ Note that amputating the affected organ does in fact remove the infection from t
"You hear the [gore_sound].")
var/mob/living/carbon/human/victim = owner //Keep a reference for post-removed().
- remove(null, ignore_children)
+ // Let people make limbs become fun things when removed
+ var/atom/movable/dropped_part = remove(null, ignore_children)
victim.traumatic_shock += 30
wounds.Cut()
@@ -726,12 +729,12 @@ Note that amputating the affected organ does in fact remove the infection from t
if(!clean)
// Throw limb around.
if(src && istype(loc,/turf))
- throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
+ dropped_part.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
dir = 2
- return
+ return dropped_part
else
qdel(src) // If you flashed away to ashes, YOU FLASHED AWAY TO ASHES
- return
+ return null
/****************************************************
HELPERS
@@ -903,7 +906,7 @@ Note that amputating the affected organ does in fact remove the infection from t
var/is_robotic = status & ORGAN_ROBOT
var/mob/living/carbon/human/victim = owner
- ..()
+ . = ..()
status |= ORGAN_DESTROYED
victim.bad_external_organs -= src
@@ -914,14 +917,14 @@ Note that amputating the affected organ does in fact remove the infection from t
// Attached organs also fly off.
if(!ignore_children)
for(var/obj/item/organ/external/O in children)
- O.remove(victim)
- if(O)
- O.forceMove(src)
+ var/atom/movable/thing = O.remove(victim)
+ if(thing)
+ thing.forceMove(src)
// Grab all the internal giblets too.
for(var/obj/item/organ/internal/organ in internal_organs)
- organ.remove(victim)
- organ.forceMove(src)
+ var/atom/movable/thing = organ.remove(victim)
+ thing.forceMove(src)
release_restraints(victim)
victim.organs -= src
diff --git a/code/modules/surgery/organs/organ_icon.dm b/code/modules/surgery/organs/organ_icon.dm
index 49777aa4a5c..31ef55f4919 100644
--- a/code/modules/surgery/organs/organ_icon.dm
+++ b/code/modules/surgery/organs/organ_icon.dm
@@ -47,7 +47,39 @@ var/global/list/limb_icon_cache = list()
/obj/item/organ/external/head/remove()
get_icon()
- ..()
+ . = ..()
+
+/obj/item/organ/external/proc/get_icon(skeletal, fat)
+ // Kasparrov, you monster
+ if(istext(species))
+ species = all_species[species]
+ if(force_icon)
+ mob_icon = new /icon(force_icon, "[icon_name]")
+ if(species && species.name == "Machine") //snowflake for IPC's, sorry.
+ if(s_col && s_col.len >= 3)
+ mob_icon.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD)
+ else
+ var/new_icons = get_icon_state(skeletal)
+ var/icon_file = new_icons[1]
+ var/new_icon_state = new_icons[2]
+ mob_icon = new /icon(icon_file, new_icon_state)
+ if(!skeletal && !(status & ORGAN_ROBOT))
+ if(status & ORGAN_DEAD)
+ mob_icon.ColorTone(rgb(10,50,0))
+ mob_icon.SetIntensity(0.7)
+
+ if(!isnull(s_tone))
+ if(s_tone >= 0)
+ mob_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
+ else
+ mob_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
+ else if(s_col && s_col.len >= 3)
+ mob_icon.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD)
+
+ dir = EAST
+ icon = mob_icon
+
+ return mob_icon
/obj/item/organ/external/head/get_icon()
@@ -55,13 +87,15 @@ var/global/list/limb_icon_cache = list()
overlays.Cut()
if(!owner)
return
- var/obj/item/organ/external/head/H = owner.get_organ("head")
if(species.has_organ["eyes"])
- var/obj/item/organ/internal/eyes/eyes = owner.get_int_organ(/obj/item/organ/internal/eyes)//owner.internal_organs_by_name["eyes"]
+ var/obj/item/organ/internal/eyes/eyes = owner.get_int_organ(/obj/item/organ/internal/eyes)
+ var/obj/item/organ/internal/cyberimp/eyes/eye_implant = owner.get_int_organ(/obj/item/organ/internal/cyberimp/eyes)
if(species.eyes)
var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', species.eyes)
- if(eyes)
+ if(eye_implant) // Eye implants override native DNA eye color
+ eyes_icon.Blend(rgb(eye_implant.eye_colour[1],eye_implant.eye_colour[2],eye_implant.eye_colour[3]), ICON_ADD)
+ else 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)
@@ -81,81 +115,69 @@ var/global/list/limb_icon_cache = list()
markings_s.Blend(rgb(owner.r_markings, owner.g_markings, owner.b_markings), ICON_ADD)
overlays |= markings_s
- if(H.ha_style)
- var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[H.ha_style]
- if(head_accessory_style && head_accessory_style.species_allowed && (H.species.name in head_accessory_style.species_allowed))
+ if(ha_style)
+ var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[ha_style]
+ if(head_accessory_style && head_accessory_style.species_allowed && (species.name in head_accessory_style.species_allowed))
var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s")
if(head_accessory_style.do_colouration)
- head_accessory_s.Blend(rgb(H.r_headacc, H.g_headacc, H.b_headacc), ICON_ADD)
+ head_accessory_s.Blend(rgb(r_headacc, g_headacc, b_headacc), ICON_ADD)
overlays |= head_accessory_s
- if(H.f_style)
- var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[H.f_style]
- if(facial_hair_style && ((facial_hair_style.species_allowed && (H.species.name in facial_hair_style.species_allowed)) || (src.species.flags & ALL_RPARTS)))
+ if(f_style)
+ var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style]
+ if(facial_hair_style && ((facial_hair_style.species_allowed && (species.name in facial_hair_style.species_allowed)) || (src.species.flags & ALL_RPARTS)))
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
- if(H.species.name == "Slime People") // I am el worstos
+ if(species.name == "Slime People") // I am el worstos
facial_s.Blend(rgb(owner.r_skin, owner.g_skin, owner.b_skin, 160), ICON_AND)
else if(facial_hair_style.do_colouration)
- facial_s.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD)
+ facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
overlays |= facial_s
- if(H.h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR)))
- var/datum/sprite_accessory/hair_style = hair_styles_list[H.h_style]
- if(hair_style && ((H.species.name in hair_style.species_allowed) || (src.species.flags & ALL_RPARTS)))
+ if(h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR)))
+ var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
+ if(hair_style && ((species.name in hair_style.species_allowed) || (src.species.flags & ALL_RPARTS)))
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
- if(H.species.name == "Slime People") // I am el worstos
+ if(species.name == "Slime People") // I am el worstos
hair_s.Blend(rgb(owner.r_skin, owner.g_skin, owner.b_skin, 160), ICON_AND)
else if(hair_style.do_colouration)
- hair_s.Blend(rgb(H.r_hair, H.g_hair, H.b_hair), ICON_ADD)
+ hair_s.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
overlays |= hair_s
return mob_icon
-/obj/item/organ/external/proc/get_icon(var/skeletal)
+/obj/item/organ/external/proc/get_icon_state(skeletal)
var/gender
- if(istext(species))
- species = all_species[species]
- if(force_icon)
- mob_icon = new /icon(force_icon, "[icon_name]")
- if(species && species.name == "Machine") //snowflake for IPC's, sorry.
- if(s_col && s_col.len >= 3)
- mob_icon.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD)
+ var/icon_file
+ var/new_icon_state
+ if(!dna)
+ icon_file = 'icons/mob/human_races/r_human.dmi'
+ new_icon_state = "[icon_name][gendered_icon ? "_f" : ""]"
else
- if(!dna)
- mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_f" : ""]")
- else
- if(gendered_icon)
- if(dna.GetUIState(DNA_UI_GENDER))
- gender = "f"
- else
- gender = "m"
-
- if(skeletal)
- mob_icon = new /icon('icons/mob/human_races/r_skeleton.dmi', "[icon_name][gender ? "_[gender]" : ""]")
- else if(status & ORGAN_ROBOT)
- mob_icon = new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]")
+ if(gendered_icon)
+ if(dna.GetUIState(DNA_UI_GENDER))
+ gender = "f"
else
- if(status & ORGAN_MUTATED)
- mob_icon = new /icon(species.deform, "[icon_name][gender ? "_[gender]" : ""]")
- else
- mob_icon = new /icon(species.icobase, "[icon_name][gender ? "_[gender]" : ""]")
+ gender = "m"
+ new_icon_state = "[icon_name][gender ? "_[gender]" : ""]"
- if(status & ORGAN_DEAD)
- mob_icon.ColorTone(rgb(10,50,0))
- mob_icon.SetIntensity(0.7)
+ if(skeletal)
+ icon_file = 'icons/mob/human_races/r_skeleton.dmi'
+ else if(status & ORGAN_ROBOT)
+ icon_file = 'icons/mob/human_races/robotic.dmi'
+ else
+ if(status & ORGAN_MUTATED)
+ icon_file = species.deform
+ else
+ // Congratulations, you are normal
+ icon_file = species.icobase
+ return list(icon_file, new_icon_state)
- if(!isnull(s_tone))
- if(s_tone >= 0)
- mob_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
- else
- mob_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
- else if(s_col && s_col.len >= 3)
- mob_icon.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD)
+/obj/item/organ/external/chest/get_icon_state(skeletal)
+ var/result = ..()
+ if(fat && !skeletal && !(status & ORGAN_ROBOT) && (species.flags & CAN_BE_FAT))
+ result[2] += "_fat"
+ return result
- dir = EAST
- 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)
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index 9c28a60b055..a902dc55afa 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -15,6 +15,11 @@
insert(holder)
..()
+/obj/item/organ/internal/Destroy()
+ if(owner)
+ remove(owner, 1)
+ return ..()
+
/obj/item/organ/internal/proc/insert(mob/living/carbon/M, special = 0, var/dont_remove_slot = 0)
if(!iscarbon(M) || owner == M)
return
@@ -43,7 +48,9 @@
var/datum/action/A = X
A.Grant(M)
-
+// Removes the given organ from its owner.
+// Returns the removed object, which is usually just itself
+// However, you MUST set the object's positiion yourself when you call this!
/obj/item/organ/internal/remove(mob/living/carbon/M, special = 0)
owner = null
if(M)
@@ -63,7 +70,7 @@
for(var/X in actions)
var/datum/action/A = X
A.Remove(M)
-
+ return src
/obj/item/organ/internal/replaced(var/mob/living/carbon/human/target,var/obj/item/organ/external/affected)
insert(target)
@@ -78,11 +85,6 @@
/obj/item/organ/internal/proc/on_life()
return
-/obj/item/organ/internal/Destroy()
- if(owner)
- remove(owner, 1)
- return ..()
-
/obj/item/organ/internal/proc/prepare_eat()
if(status == ORGAN_ROBOT)
return //no eating cybernetic implants!
@@ -96,6 +98,12 @@
return S
+/obj/item/organ/internal/attempt_become_organ(obj/item/organ/external/parent,mob/living/carbon/human/H)
+ if(parent_organ != parent.limb_name)
+ return 0
+ insert(H)
+ return 1
+
/obj/item/weapon/reagent_containers/food/snacks/organ
name = "appendix"
icon_state = "appendix"
@@ -149,7 +157,7 @@
icon_state = "[icon_base]-off"
/obj/item/organ/internal/heart/remove(mob/living/carbon/M, special = 0)
- ..()
+ . = ..()
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.stat == DEAD || H.heart_attack)
@@ -279,7 +287,7 @@
///obj/item/organ/internal/lungs/remove(mob/living/carbon/M, special = 0)
// owner.losebreath += 10
//insert oxy damage extream here.
-// ..()
+// . = ..()
/obj/item/organ/internal/lungs/process()
@@ -335,23 +343,14 @@
var/list/eye_colour = list(0,0,0)
/obj/item/organ/internal/eyes/proc/update_colour()
- if(!owner)
- return
- eye_colour = list(
- owner.r_eyes ? owner.r_eyes : 0,
- owner.g_eyes ? owner.g_eyes : 0,
- owner.b_eyes ? owner.b_eyes : 0
- )
+ dna.write_eyes_attributes(src)
/obj/item/organ/internal/eyes/insert(mob/living/carbon/M, special = 0)
-// Apply our eye colour to the target.
- if(istype(M) && eye_colour)
- var/mob/living/carbon/human/eyes = M
- eyes.r_eyes = eye_colour[1]
- eyes.g_eyes = eye_colour[2]
- eyes.b_eyes = eye_colour[3]
- eyes.update_eyes()
..()
+ if(istype(M) && eye_colour)
+ var/mob/living/carbon/human/H = M
+ // Apply our eye colour to the target.
+ H.update_body()
/obj/item/organ/internal/eyes/surgeryize()
if(!owner)
@@ -436,7 +435,7 @@
A.cure()
inflamed = 1
update_icon()
- ..()
+ . = ..()
/obj/item/organ/internal/appendix/insert(mob/living/carbon/M, special = 0)
..()
@@ -508,7 +507,7 @@
organhonked = world.time
/obj/item/organ/internal/honktumor/remove(mob/living/carbon/M, special = 0)
- ..()
+ . = ..()
M.mutations.Remove(CLUMSY)
M.mutations.Remove(COMICBLOCK)
@@ -561,7 +560,7 @@
/obj/item/organ/internal/honktumor/cursed
/obj/item/organ/internal/honktumor/cursed/remove(mob/living/carbon/M, special = 0, clean_remove = 0)
- ..()
+ . = ..()
if(!clean_remove)
visible_message("[src] vanishes into dust, and a [M] emits a loud honk!", "You hear a loud honk.")
insert(M) //You're not getting away that easily!
diff --git a/code/modules/surgery/organs/organ_stump.dm b/code/modules/surgery/organs/organ_stump.dm
index b310a5862fc..9d6c0183cb8 100644
--- a/code/modules/surgery/organs/organ_stump.dm
+++ b/code/modules/surgery/organs/organ_stump.dm
@@ -22,7 +22,7 @@
/obj/item/organ/external/stump/remove()
..()
qdel(src)
+ return null
/obj/item/organ/external/stump/is_usable()
return 0
-
diff --git a/code/modules/surgery/organs/parasites.dm b/code/modules/surgery/organs/parasites.dm
index 2d15efdd041..61e72743464 100644
--- a/code/modules/surgery/organs/parasites.dm
+++ b/code/modules/surgery/organs/parasites.dm
@@ -32,4 +32,5 @@
/obj/item/organ/internal/body_egg/spider_eggs/remove(var/mob/living/carbon/M, var/special = 0)
..()
M.reagents.del_reagent("spidereggs") //purge all remaining spider eggs reagent if caught, in time.
- qdel(src) //We don't want people re-implanting these for near instant gibbings.
\ No newline at end of file
+ qdel(src) //We don't want people re-implanting these for near instant gibbings.
+ return null
diff --git a/code/modules/surgery/organs/subtypes/grey.dm b/code/modules/surgery/organs/subtypes/grey.dm
index 7c84bdc2019..a47ab801d6f 100644
--- a/code/modules/surgery/organs/subtypes/grey.dm
+++ b/code/modules/surgery/organs/subtypes/grey.dm
@@ -12,5 +12,5 @@
M.add_language("Psionic Communication")
/obj/item/organ/internal/brain/grey/remove(var/mob/living/carbon/M, var/special = 0)
- ..()
+ . = ..()
M.remove_language("Psionic Communication")
diff --git a/code/modules/surgery/organs/subtypes/machine.dm b/code/modules/surgery/organs/subtypes/machine.dm
index d64fbf70e3d..828bf39a004 100644
--- a/code/modules/surgery/organs/subtypes/machine.dm
+++ b/code/modules/surgery/organs/subtypes/machine.dm
@@ -117,13 +117,6 @@
robotize()
..()
-/obj/item/organ/internal/cell/insert()
- ..()
- // This is very ghetto way of rebooting an IPC. TODO better way.
- if(owner && owner.stat == DEAD)
- owner.stat = CONSCIOUS
- owner.visible_message("\The [owner] twitches visibly!")
-
/obj/item/organ/internal/optical_sensor
name = "optical sensor"
organ_tag = "eyes"
@@ -167,20 +160,25 @@
species = "Machine"
var/obj/item/device/mmi/stored_mmi
-/obj/item/organ/internal/brain/mmi_holder/proc/update_from_mmi()
- if(!stored_mmi)
- return
- name = stored_mmi.name
- desc = stored_mmi.desc
- icon = stored_mmi.icon
- icon_state = stored_mmi.icon_state
+
+/obj/item/organ/internal/brain/mmi_holder/Destroy()
+ if(stored_mmi)
+ qdel(stored_mmi)
+ return ..()
+
+/obj/item/organ/internal/brain/mmi_holder/insert(var/mob/living/target,special = 0)
+ ..()
+ // To supersede the over-writing of the MMI's name from `insert`
+ update_from_mmi()
/obj/item/organ/internal/brain/mmi_holder/remove(var/mob/living/user,special = 0)
if(!special)
if(stored_mmi)
- stored_mmi.forceMove(get_turf(owner))
+ . = stored_mmi
if(owner.mind)
owner.mind.transfer_to(stored_mmi.brainmob)
+ stored_mmi.forceMove(get_turf(src))
+ stored_mmi = null
..()
var/mob/living/holder_mob = loc
@@ -188,13 +186,14 @@
holder_mob.unEquip(src)
qdel(src)
-/obj/item/organ/internal/brain/mmi_holder/New()
- ..()
- // This is very ghetto way of rebooting an IPC. TODO better way.
- spawn(1)
- if(owner && owner.stat == DEAD)
- owner.stat = CONSCIOUS
- owner.visible_message("\The [owner] twitches visibly!")
+/obj/item/organ/internal/brain/mmi_holder/proc/update_from_mmi()
+ if(!stored_mmi)
+ return
+ name = stored_mmi.name
+ desc = stored_mmi.desc
+ icon = stored_mmi.icon
+ icon_state = stored_mmi.icon_state
+ set_dna(stored_mmi.brainmob.dna)
/obj/item/organ/internal/brain/mmi_holder/posibrain/New()
robotize()
diff --git a/code/modules/surgery/organs/subtypes/misc.dm b/code/modules/surgery/organs/subtypes/misc.dm
index 240a36149f8..be76fa907dc 100644
--- a/code/modules/surgery/organs/subtypes/misc.dm
+++ b/code/modules/surgery/organs/subtypes/misc.dm
@@ -41,6 +41,7 @@
spawn(0)
qdel(src)
+ return null
//VOX ORGANS.
/obj/item/organ/internal/stack
diff --git a/code/modules/surgery/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm
index 1c6240318fe..02351f523a8 100644
--- a/code/modules/surgery/organs/subtypes/standard.dm
+++ b/code/modules/surgery/organs/subtypes/standard.dm
@@ -16,6 +16,25 @@
cannot_amputate = 1
parent_organ = null
encased = "ribcage"
+ var/fat = FALSE
+
+/obj/item/organ/external/chest/proc/makeFat(update_body_icon = 1)
+ fat = TRUE
+ if(owner)
+ owner.update_body(update_body_icon)
+ else
+ // get_icon updates the sprite icon, update_icon updates the injuries overlay.
+ // Madness.
+ get_icon()
+
+/obj/item/organ/external/chest/proc/makeSlim(update_body_icon = 1)
+ fat = FALSE
+ if(owner)
+ owner.update_body(update_body_icon)
+ else
+ // get_icon updates the sprite icon, update_icon updates the injuries overlay.
+ // Madness.
+ get_icon()
/obj/item/organ/external/groin
name = "lower body"
@@ -85,7 +104,7 @@
/obj/item/organ/external/foot/remove()
if(owner.shoes) owner.unEquip(owner.shoes)
- ..()
+ . = ..()
/obj/item/organ/external/foot/right
limb_name = "r_foot"
@@ -116,7 +135,7 @@
if(owner.r_hand)
owner.unEquip(owner.r_hand,1)
- ..()
+ . = ..()
/obj/item/organ/external/hand/right
limb_name = "r_hand"
@@ -178,7 +197,7 @@
if(owner)//runtimer no runtiming
owner.update_hair()
owner.update_fhair()
- ..()
+ . = ..()
/obj/item/organ/external/head/replaced()
name = limb_name
@@ -193,3 +212,7 @@
disfigure("brute")
if(burn_dam > 40)
disfigure("burn")
+
+/obj/item/organ/external/head/set_dna(datum/dna/new_dna)
+ ..()
+ new_dna.write_head_attributes(src)
diff --git a/code/modules/surgery/organs/subtypes/xenos.dm b/code/modules/surgery/organs/subtypes/xenos.dm
index 75de3664657..5e771931165 100644
--- a/code/modules/surgery/organs/subtypes/xenos.dm
+++ b/code/modules/surgery/organs/subtypes/xenos.dm
@@ -24,7 +24,7 @@
M.verbs -= P
//M.verbs -= alien_powers.Copy()
- ..()
+ . = ..()
/obj/item/organ/internal/xenos/prepare_eat()
var/obj/S = ..()
@@ -106,7 +106,7 @@
A.updatePlasmaDisplay()
/obj/item/organ/internal/alien/plasmavessel/remove(mob/living/carbon/M, special = 0)
- ..()
+ . =..()
if(isalien(M))
var/mob/living/carbon/alien/A = M
A.updatePlasmaDisplay()
@@ -140,7 +140,7 @@
M.faction -= "alien"
M.remove_language("Hivemind")
M.remove_language("Xenomorph")
- ..()
+ . = ..()
/obj/item/organ/internal/xenos/neurotoxin
name = "xeno neurotoxin gland"
@@ -165,4 +165,4 @@
slot = "eggsac"
w_class = 4
origin_tech = "biotech=8"
- alien_powers = list(/mob/living/carbon/alien/humanoid/queen/verb/lay_egg)
\ No newline at end of file
+ alien_powers = list(/mob/living/carbon/alien/humanoid/queen/verb/lay_egg)
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index 625f886455a..8928f52bb47 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -1,5 +1,5 @@
/datum/surgery/organ_manipulation
- name = "organ manipulation"
+ name = "Organ Manipulation"
steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/open_encased/saw,
/datum/surgery_step/open_encased/retract, /datum/surgery_step/internal/manipulate_organs, /datum/surgery_step/glue_bone, /datum/surgery_step/set_bone,/datum/surgery_step/finish_bone,/datum/surgery_step/generic/cauterize)
possible_locs = list("chest","head")
@@ -11,13 +11,13 @@
requires_organic_bodypart = 1
/datum/surgery/organ_manipulation_boneless
- name = "organ manipulation"
+ name = "Organ Manipulation"
possible_locs = list("chest","head","groin", "eyes", "mouth")
steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/internal/manipulate_organs,/datum/surgery_step/generic/cauterize)
requires_organic_bodypart = 1
/datum/surgery/organ_manipulation/alien
- name = "alien organ manipulation"
+ name = "Alien Organ Manipulation"
possible_locs = list("chest", "head", "groin", "eyes", "mouth")
allowed_mob = list(/mob/living/carbon/alien/humanoid)
steps = list(/datum/surgery_step/saw_carapace,/datum/surgery_step/cut_carapace, /datum/surgery_step/retract_carapace,/datum/surgery_step/internal/manipulate_organs)
@@ -27,11 +27,12 @@
if(istype(target,/mob/living/carbon/human))
var/mob/living/carbon/human/H = target
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
- if(affected && (affected.status & ORGAN_ROBOT))
+ if(!affected)
+ // I'd like to see you do surgery on LITERALLY NOTHING
return 0
- if(target.get_species() == "Machine")//i know organ robot might be enough but i am not taking chances...
+ if(affected.status & ORGAN_ROBOT)
return 0
- if(affected && !affected.encased) //no bone, problem.
+ if(!affected.encased) //no bone, problem.
return 0
return 1
@@ -42,6 +43,9 @@
if(affected && (affected.status & ORGAN_ROBOT))
return 0//no operating on robotic limbs in an organic surgery
+ if(!affected)
+ // I'd like to see you do surgery on LITERALLY NOTHING
+ return 0
if(affected && affected.encased) //no bones no problem.
return 0
@@ -236,8 +240,11 @@
add_logs(target,user, "surgically removed [I.name] from", addition="INTENT: [uppertext(user.a_intent)]")
spread_germs_to_organ(I, user)
I.status |= ORGAN_CUT_AWAY
- I.remove(target)
- I.loc = get_turf(target)
+ var/obj/item/thing = I.remove(target)
+ if(!istype(thing))
+ thing.forceMove(get_turf(target))
+ else
+ user.put_in_hands(thing)
else
user.visible_message("[user] can't seem to extract anything from [target]'s [parse_zone(target_zone)]!",
"You can't extract anything from [target]'s [parse_zone(target_zone)]!")
diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm
index 21328599a19..de9d096a628 100644
--- a/code/modules/surgery/other.dm
+++ b/code/modules/surgery/other.dm
@@ -4,15 +4,26 @@
//////////////////////////////////////////////////////////////////
/datum/surgery/infection
- name = "external infection treatment/autopsy"
+ name = "External Infection Treatment/Autopsy"
steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/cauterize)
possible_locs = list("chest","head","groin", "l_arm", "r_arm", "l_leg", "r_leg", "r_hand", "l_hand", "r_foot", "l_foot")
/datum/surgery/bleeding
- name = "internal bleeding"
+ name = "Internal Bleeding"
steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders,/datum/surgery_step/generic/retract_skin,/datum/surgery_step/fix_vein,/datum/surgery_step/generic/cauterize)
possible_locs = list("chest","head","groin", "l_arm", "r_arm", "l_leg", "r_leg", "r_hand", "l_hand", "r_foot", "l_foot")
+/datum/surgery/infection/can_start(mob/user, mob/living/carbon/target)
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
+ if(!affected)
+ return 0
+ if(affected.status & ORGAN_ROBOT)
+ return 0
+ return 1
+ return 0
+
/datum/surgery/bleeding/can_start(mob/user, mob/living/carbon/target)
if(ishuman(target))
var/mob/living/carbon/human/H = target
@@ -49,7 +60,7 @@
internal_bleeding = 1
break
- return affected.open == 2 && internal_bleeding
+ return internal_bleeding
/datum/surgery_step/fix_vein/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
@@ -207,35 +218,59 @@
// Dethrall Shadowling //
//////////////////////////////////////////////////////////////////
/datum/surgery/remove_thrall
- name = "cleanse contaminations"//RENAME MEH
+ name = "Remove Shadow Tumor"
steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/open_encased/saw,/datum/surgery_step/open_encased/retract, /datum/surgery_step/internal/dethrall, /datum/surgery_step/glue_bone, /datum/surgery_step/set_bone,/datum/surgery_step/finish_bone,/datum/surgery_step/generic/cauterize)
- possible_locs = list("head")
+ possible_locs = list("head", "chest", "groin")
/datum/surgery/remove_thrall/synth
- name = "cleanse contaminations"//RENAME MEH
steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/internal/dethrall,/datum/surgery_step/robotics/external/close_hatch)
- possible_locs = list("chest")
+ possible_locs = list("head", "chest", "groin")
+/datum/surgery/remove_thrall/can_start(mob/user, mob/living/carbon/human/target)
+ if(!istype(target))
+ return 0
+ if(!is_thrall(target))
+ return 0
+ var/obj/item/organ/internal/brain/B = target.get_int_organ(/obj/item/organ/internal/brain)
+ var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting)
+ if(!B)
+ // No brain to remove the tumor from
+ return 0
+ if(affected.status & ORGAN_ROBOT)
+ return 0
+ if(!(B in affected.internal_organs))
+ return 0
+ return 1
-
-/datum/surgery/remove_thrall/can_start(mob/user, mob/living/carbon/target)
- return is_thrall(target) //would this be too meta?
-
-/datum/surgery/remove_thrall/synth/can_start(mob/user, mob/living/carbon/target)
- return is_thrall(target) && target.get_species() == "Machine"
+/datum/surgery/remove_thrall/synth/can_start(mob/user, mob/living/carbon/human/target)
+ if(!istype(target))
+ return 0
+ if(!is_thrall(target))
+ return 0
+ var/obj/item/organ/internal/brain/B = target.get_int_organ(/obj/item/organ/internal/brain)
+ var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting)
+ if(!B)
+ // No brain to remove the tumor from
+ return 0
+ if(!(affected.status & ORGAN_ROBOT))
+ return 0
+ if(!(B in affected.internal_organs))
+ return 0
+ return 1
/datum/surgery_step/internal/dethrall
name = "cleanse contamination"
allowed_tools = list(/obj/item/device/flash = 100, /obj/item/device/flashlight/pen = 80, /obj/item/device/flashlight = 40)
-
+ blood_level = 0
time = 30
/datum/surgery_step/internal/dethrall/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- if(!hasorgans(target))
- return
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return ..() && affected && is_thrall(target) && affected.open_enough_for_surgery() && target_zone == target.named_organ_parent("brain")
+ if(!..())
+ return 0
+ if(!is_thrall(target))
+ return 0
+ return 1
/datum/surgery_step/internal/dethrall/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
var/braincase = target.named_organ_parent("brain")
@@ -263,11 +298,15 @@
S.apply_damage(20, BRUTE)
playsound(S, 'sound/effects/bang.ogg', 50, 1)
return 0
- user.visible_message("[user] shines light onto the tumor in [target]'s head!", "You cleanse the contamination from [target]'s brain!")
+ var/obj/item/organ/internal/brain/B = target.get_int_organ(/obj/item/organ/internal/brain)
+ var/obj/item/organ/external/E = target.get_organ(check_zone(B.parent_organ))
+ user.visible_message("[user] shines light onto the tumor in [target]'s [E]!", "You cleanse the contamination from [target]'s brain!")
if(target.vision_type) //Turns off their darksight if it's still active.
to_chat(target, "Your eyes are suddenly wrought with immense pain as your darksight is forcibly dismissed!")
target.vision_type = null
ticker.mode.remove_thrall(target.mind, 0)
- target.visible_message("A strange black mass falls from [target]'s head!")
- new /obj/item/organ/internal/shadowtumor(get_turf(target))
+ target.visible_message("A strange black mass falls from [target]'s [E]!")
+ var/obj/item/organ/thing = new /obj/item/organ/internal/shadowtumor(get_turf(target))
+ thing.set_dna(target.dna)
+ user.put_in_hands(thing)
return 1
diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm
index 4567c465678..8a07616f5fc 100644
--- a/code/modules/surgery/robotics.dm
+++ b/code/modules/surgery/robotics.dm
@@ -5,18 +5,18 @@
/datum/surgery/cybernetic_repair
name = "Cybernetic Repair"
- steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/robotics/external/repair_brute,/datum/surgery_step/robotics/external/repair_burn,/datum/surgery_step/robotics/external/close_hatch)
+ steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/robotics/external/repair)
possible_locs = list("chest","head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin")
requires_organic_bodypart = 0
/datum/surgery/cybernetic_repair/internal
- name = "Internal Cybernetic Mainpulation"
+ name = "Internal Component Manipulation"
steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/robotics/manipulate_robotic_organs)
possible_locs = list("eyes", "chest","head","groin")
requires_organic_bodypart = 0
/datum/surgery/cybernetic_amputation
- name = "robotic limb amputation"
+ name = "Robotic Limb Amputation"
steps = list(/datum/surgery_step/robotics/external/amputate)
possible_locs = list("chest","head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin")
requires_organic_bodypart = 0
@@ -33,7 +33,6 @@
return 1
/datum/surgery/cybernetic_amputation/can_start(mob/user, mob/living/carbon/target)
-
if(istype(target,/mob/living/carbon/human))
var/mob/living/carbon/human/H = target
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
@@ -41,16 +40,16 @@
return 0
if(!(affected.status & ORGAN_ROBOT))
return 0
+ if(affected.cannot_amputate)
+ return 0
return 1
-//to do, moar surgerys or condense down ala mainpulate organs.
+//to do, moar surgerys or condense down ala manipulate organs.
/datum/surgery_step/robotics
can_infect = 0
/datum/surgery_step/robotics/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- if(isslime(target))
- return 0
- if(target_zone == "eyes") //there are specific steps for eye surgery
+ if(!istype(target))
return 0
if(!hasorgans(target))
return 0
@@ -152,7 +151,7 @@
/datum/surgery_step/robotics/external/close_hatch/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
if(..())
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return affected && affected.open && target_zone != "mouth"
+ return affected && affected.open
/datum/surgery_step/robotics/external/close_hatch/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
@@ -165,7 +164,6 @@
user.visible_message(" [user] closes and secures the hatch on [target]'s [affected.name] with \the [tool].", \
" You close and secure the hatch on [target]'s [affected.name] with \the [tool].")
affected.open = 0
- affected.germ_level = 0
return 1
/datum/surgery_step/robotics/external/close_hatch/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -174,94 +172,116 @@
" Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].")
return 0
-/datum/surgery_step/robotics/external/repair_brute
- name = "Repair brute damage"
- allowed_tools = list(
+/datum/surgery_step/robotics/external/repair
+ name = "repair damage internally"
+ allowed_tools = list()
+
+ var/list/implements_finish = list(
+ /obj/item/weapon/retractor = 100,
+ /obj/item/weapon/crowbar = 100,
+ /obj/item/weapon/kitchen/utensil = 50
+ )
+ var/list/implements_heal_burn = list(
+ /obj/item/stack/cable_coil = 100
+ )
+ var/list/implements_heal_brute = list(
/obj/item/weapon/weldingtool = 100,
/obj/item/weapon/gun/energy/plasmacutter = 50
)
-
+ var/current_type
time = 32
-/datum/surgery_step/robotics/external/repair_brute/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- if(..())
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
+/datum/surgery_step/robotics/external/repair/New()
+ ..()
+ allowed_tools = implements_heal_burn + implements_heal_brute + implements_finish
+
+
+/datum/surgery_step/robotics/external/repair/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
+ var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ if(!affected)
+ return -1
+ if(affected.open != 2)
+ to_chat(user, "The [affected] needs to be open to be operated on!")
+ return -1
+
+ if(implement_type in implements_heal_burn)
+ current_type = "burn"
+ var/obj/item/stack/cable_coil/C = tool
+ if(!(affected.burn_dam > 0))
+ to_chat(user, "The [affected] does not have any burn damage!")
+ return -1
+ if(!istype(C))
+ return -1
+ if(!C.get_amount() >= 3)
+ to_chat(user, "You need three or more cable pieces to repair this damage.")
+ return -1
+ C.use(3)
+ user.visible_message("[user] begins to splice new cabling into [target]'s [affected.name]." , \
+ "You begin to splice new cabling into [target]'s [affected.name].")
+
+ else if(implement_type in implements_heal_brute)
+ current_type = "brute"
+ if(!(affected.brute_dam > 0 || affected.disfigured))
+ to_chat(user, "The [affected] does not require welding repair!")
+ return -1
if(istype(tool,/obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/welder = tool
if(!welder.isOn() || !welder.remove_fuel(1,user))
- return 0
- return affected && affected.open == 2 && (affected.brute_dam > 0 || affected.disfigured)&& target_zone != "mouth"
+ return -1
+ user.visible_message("[user] begins to patch damage to [target]'s [affected.name]'s support structure with \the [tool]." , \
+ "You begin to patch damage to [target]'s [affected.name]'s support structure with \the [tool].")
-/datum/surgery_step/robotics/external/repair_brute/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] begins to patch damage to [target]'s [affected.name]'s support structure with \the [tool]." , \
- "You begin to patch damage to [target]'s [affected.name]'s support structure with \the [tool].")
+ else if(implement_type in implements_finish)
+ current_type = "finish"
+ user.visible_message("[user] begins to close and secure the hatch on [target]'s [affected.name] with \the [tool]." , \
+ "You begin to close and secure the hatch on [target]'s [affected.name] with \the [tool].")
+ else
+ log_debug("Invalid tool: '[implement_type]'")
+ return -1
..()
-/datum/surgery_step/robotics/external/repair_brute/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
+/datum/surgery_step/robotics/external/repair/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message(" [user] finishes patching damage to [target]'s [affected.name] with \the [tool].", \
- " You finish patching damage to [target]'s [affected.name] with \the [tool].")
- affected.heal_damage(rand(30,50),0,1,1)
- if(affected.disfigured)
- affected.disfigured = 0
- affected.update_icon()
- target.regenerate_icons()
- return 1
-
-/datum/surgery_step/robotics/external/repair_brute/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message(" [user]'s [tool.name] slips, damaging the internal structure of [target]'s [affected.name].",
- " Your [tool.name] slips, damaging the internal structure of [target]'s [affected.name].")
- target.apply_damage(rand(5,10), BURN, affected)
+ switch(current_type)
+ if("brute")
+ user.visible_message(" [user] finishes patching damage to [target]'s [affected.name] with \the [tool].", \
+ " You finish patching damage to [target]'s [affected.name] with \the [tool].")
+ affected.heal_damage(rand(30,50),0,1,1)
+ if(affected.disfigured)
+ affected.disfigured = 0
+ affected.update_icon()
+ target.regenerate_icons()
+ if("burn")
+ user.visible_message(" [user] finishes splicing cable into [target]'s [affected.name].", \
+ " You finishes splicing new cable into [target]'s [affected.name].")
+ affected.heal_damage(0,rand(30,50),1,1)
+ if("finish")
+ user.visible_message(" [user] closes and secures the hatch on [target]'s [affected.name] with \the [tool].", \
+ " You close and secure the hatch on [target]'s [affected.name] with \the [tool].")
+ affected.open = 0
+ return 1
return 0
-/datum/surgery_step/robotics/external/repair_burn
- name = "repair heat damage"
- allowed_tools = list(
- /obj/item/stack/cable_coil = 100
- )
-
- time = 32
-
-/datum/surgery_step/robotics/external/repair_burn/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- if(..())
- var/obj/item/stack/cable_coil/C = tool
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- var/limb_can_operate = (affected && affected.open == 2 && affected.burn_dam > 0 && target_zone != "mouth")
- if(limb_can_operate)
- if(istype(C))
- if(!C.get_amount() >= 3)
- to_chat(user, "You need three or more cable pieces to repair this damage.")
- return 2
- C.use(3)
- return 1
- return 0
-
-/datum/surgery_step/robotics/external/repair_burn/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
+/datum/surgery_step/robotics/external/repair/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] begins to splice new cabling into [target]'s [affected.name]." , \
- "You begin to splice new cabling into [target]'s [affected.name].")
- ..()
-
-/datum/surgery_step/robotics/external/repair_burn/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message(" [user] finishes splicing cable into [target]'s [affected.name].", \
- " You finishes splicing new cable into [target]'s [affected.name].")
- affected.heal_damage(0,rand(30,50),1,1)
- return 1
-
-/datum/surgery_step/robotics/external/repair_burn/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message(" [user] causes a short circuit in [target]'s [affected.name]!",
- " You cause a short circuit in [target]'s [affected.name]!")
- target.apply_damage(rand(5,10), BURN, affected)
+ switch(current_type)
+ if("brute")
+ user.visible_message(" [user]'s [tool.name] slips, damaging the internal structure of [target]'s [affected.name].",
+ " Your [tool.name] slips, damaging the internal structure of [target]'s [affected.name].")
+ target.apply_damage(rand(5,10), BURN, affected)
+ if("burn")
+ user.visible_message(" [user] causes a short circuit in [target]'s [affected.name]!",
+ " You cause a short circuit in [target]'s [affected.name]!")
+ target.apply_damage(rand(5,10), BURN, affected)
+ if("finish")
+ user.visible_message(" [user]'s [tool.name] slips, failing to close the hatch on [target]'s [affected.name].",
+ " Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].")
return 0
///////condenseing remove/extract/repair here. /////////////
/datum/surgery_step/robotics/manipulate_robotic_organs
- name = "internal part mainpulation"
+ name = "internal part manipulation"
allowed_tools = list(/obj/item/device/mmi = 100)
var/implements_extract = list(/obj/item/device/multitool = 100)
var/implements_mend = list( /obj/item/stack/nanopaste = 100,/obj/item/weapon/bonegel = 30, /obj/item/weapon/screwdriver = 70)
@@ -423,29 +443,23 @@
" You have installed \the [tool] into [target]'s [affected.name].")
var/obj/item/device/mmi/M = tool
- var/obj/item/organ/internal/brain/mmi_holder/holder = new()
- if(istype(M, /obj/item/device/mmi/posibrain))
- holder.robotize()
- holder.insert(target)
user.unEquip(tool)
- tool.forceMove(holder)
- holder.stored_mmi = tool
- holder.update_from_mmi()
-
- if(M.brainmob && M.brainmob.mind)
- M.brainmob.mind.transfer_to(target)
+ M.attempt_become_organ(affected,target)
else if(current_type == "extract")
if(I && I.owner == target)
- user.visible_message(" [user] has decoupled [target]'s [surgery.current_organ] with \the [tool]." , \
- " You have decoupled [target]'s [surgery.current_organ] with \the [tool].")
+ user.visible_message(" [user] has decoupled [target]'s [I] with \the [tool]." , \
+ " You have decoupled [target]'s [I] with \the [tool].")
add_logs(target,user, "surgically removed [I.name] from", addition="INTENT: [uppertext(user.a_intent)]")
spread_germs_to_organ(I, user)
I.status |= ORGAN_CUT_AWAY
- I.remove(target)
- I.loc = get_turf(target)
+ var/obj/item/thing = I.remove(target)
+ if(!istype(thing))
+ thing.forceMove(get_turf(target))
+ else
+ user.put_in_hands(thing)
else
user.visible_message("[user] can't seem to extract anything from [target]'s [parse_zone(target_zone)]!",
"You can't extract anything from [target]'s [parse_zone(target_zone)]!")
@@ -490,81 +504,9 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(" [user]'s [tool.name] slips, failing to close the hatch on [target]'s [affected.name].",
" Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].")
- return -1
+ return 0
-
-/datum/surgery_step/robotics/install_mmi
- allowed_tools = list(
- /obj/item/device/mmi = 100
- )
-
- time = 64
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
-
- if(target_zone != "chest")
- return 0
-
- var/obj/item/device/mmi/M = tool
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- if(!(affected && affected.open_enough_for_surgery()))
- return 0
-
- if(!istype(M))
- return 0
-
- if(!M.brainmob || !M.brainmob.client || !M.brainmob.ckey || M.brainmob.stat >= DEAD)
- to_chat(user, "That brain is not usable.")
- return 2
-
- if(!(affected.status & ORGAN_ROBOT))
- to_chat(user, "You cannot install a computer brain into a meat enclosure.")
- return 2
-
- if(!target.species)
- to_chat(user, "You have no idea what species this person is. Report this on the bug tracker.")
- return 2
-
- if(!target.species.has_organ["brain"])
- to_chat(user, "You're pretty sure [target.species.name_plural] don't normally have a brain.")
- return 2
-
- if(target.get_int_organ(/obj/item/organ/internal/brain/))
- to_chat(user, "Your subject already has a brain.")
- return 2
-
- return 1
-
- begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] starts installing \the [tool] into [target]'s [affected.name].", \
- "You start installing \the [tool] into [target]'s [affected.name].")
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message(" [user] has installed \the [tool] into [target]'s [affected.name].", \
- " You have installed \the [tool] into [target]'s [affected.name].")
-
- var/obj/item/device/mmi/M = tool
- var/obj/item/organ/internal/brain/mmi_holder/holder = new()
- if(istype(M, /obj/item/device/mmi/posibrain))
- holder.robotize()
-
- holder.insert(target)
- user.unEquip(tool)
- tool.forceMove(holder)
- holder.stored_mmi = tool
- holder.update_from_mmi()
-
- if(M.brainmob && M.brainmob.mind)
- M.brainmob.mind.transfer_to(target)
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- user.visible_message(" [user]'s hand slips.", \
- " Your hand slips.")
-
/datum/surgery_step/robotics/external/amputate
name = "remove robotic limb"
@@ -589,11 +531,14 @@
add_logs(target,user ,"surgically removed [affected.name] from", addition="INTENT: [uppertext(user.a_intent)]")//log it
- affected.droplimb(1,DROPLIMB_EDGE)
+ var/atom/movable/thing = affected.droplimb(1,DROPLIMB_EDGE)
+ if(istype(thing,/obj/item))
+ user.put_in_hands(thing)
+
return 1
/datum/surgery_step/robotics/external/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
user.visible_message(" [user]'s hand slips!", \
" Your hand slips!")
- return 0
\ No newline at end of file
+ return 0
diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm
index 8a60718ccbf..defa57b3ca4 100644
--- a/code/modules/surgery/surgery.dm
+++ b/code/modules/surgery/surgery.dm
@@ -43,7 +43,7 @@
/datum/surgery/proc/complete(mob/living/carbon/human/target)
target.surgeries -= src
- src = null
+ qdel(src)
@@ -95,6 +95,8 @@
return 0
/datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(!can_use(user, target, target_zone, tool, surgery))
+ return
surgery.step_in_progress = 1
if(begin_step(user, target, target_zone, tool, surgery) == -1)
@@ -110,7 +112,7 @@
if(prob_chance > 100)//if we are using a super tool
time = time/prob_chance //PLACEHOLDER VALUES
-
+
if(do_after(user, time, target = target))
@@ -154,7 +156,7 @@
// checks whether this step can be applied with the given user and target
/datum/surgery_step/proc/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- return 0
+ return 1
// does stuff to begin the step, usually just printing messages. Moved germs transfering and bloodying here too
/datum/surgery_step/proc/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
diff --git a/code/world.dm b/code/world.dm
index 508591604f0..3de52993a84 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -334,11 +334,6 @@ var/world_topic_spam_protect_time = world.timeofday
fdel(F)
F << the_mode
-/hook/startup/proc/loadMusic()
- for(var/obj/machinery/media/jukebox/J in machines)
- J.process()
- return 1
-
/hook/startup/proc/loadMOTD()
world.load_motd()
return 1
diff --git a/config/example/config.txt b/config/example/config.txt
index 20fe44173b6..e25941413fd 100644
--- a/config/example/config.txt
+++ b/config/example/config.txt
@@ -179,9 +179,6 @@ GUEST_BAN
## Ban appeals URL - usually for a forum or wherever people should go to contact your admins
# BANAPPEALS http://example.org
-## Media base URL - determines where to pull the jukebox playlist from.
-# MEDIA_BASE_URL http://example.org
-
## In-game features
## spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard
# FEATURE_OBJECT_SPELL_SYSTEM
diff --git a/html/changelog.html b/html/changelog.html
index 5214279f440..a74a9abecc0 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -55,6 +55,152 @@
-->
+
18 August 2016
+
Alexshreds updated:
+
+
pAIs can see the crew manifest again.
+
Engineers and Atmos Techs have access to the ORM
+
+
Ar3nn updated:
+
+
dusting playermobs now generates remains fitting for their race.
+
+
Chakishreds updated:
+
+
You can now click on objects in a gassy room at the expense of ninja floors.
+
+
Chopchop1614 updated:
+
+
fixes transformation sting not working.
+
transformation sting now checks if the target has DNA or not
+
+
Crazylemon updated:
+
+
Alt+Click should be quicker now
+
The Alt+Click panel vanishes only when you alt click a turf distant from yourself
+
Adds `json_to_object_arbitrary_vars`, a proc intended for use with SDQL
+
Eye color is tracked on the eyes only, instead of on the body.
+
The CMA panel no longer runtimes when you change species.
+
Deserializing a human now preserves hair and eyes.
+
Associative lists in VV now display properly again
+
Admins can now click on the DI panel buttons to debug the corresponding controller in VV
+
Fat people are now fat when naked.
+
Encased mobs can now examine
+
+
Crazylemon64 updated:
+
+
Makes teleportation checks more consistent, which will ensure that teleporting in the away mission no longer works.
+
People on the space ruins level no longer count as dead for assassinate objectives.
+
Space border turfs will now regain their destination when over-written and replaced on the edge of the map
+
The space manager will no longer runtime if a space ruin writes on the edge of the map
+
+
DaveTheHeadcrab updated:
+
+
ERT gloves reverted to how they used to be.
+
+
FalseIncarnate updated:
+
+
WOLOLO! Traitor Chaplains can now WOLOLO with the new Missionary Staff and Robes. WOLOLO!
+
+
Fethas updated:
+
+
The whitelist will respect addons better, didn't even have to make a ban appeal..
+
+
FlattestGuitar updated:
+
+
Detective's coolness variable cranked up to 14.5, they will no longer vomit over corpses.
+
Now you're less likely to vomit over a corpse if you're a normal human being.
+
golems now have their master saved in attack logs
+
+
Fox McCloud updated:
+
+
Adds in formal captain's uniform and armor
+
Adds rapier to captain's locker
+
Adds lace up shoes to captain's locker
+
Adds crown to captain's locker
+
Dramatically speeds up conveyor belts
+
Appendicitis and Disease Outbreak events will no longer impact clientless mobs
+
Fixes bandolier being invisible on spawn
+
Removes the jukebox from the bar
+
Detective Scanner, Fedora Tipping, Pontificating, and Cap Flipping are now action buttons
+
Cane Gun and NT Rep's cane now acts as actual canes
+
+
FreeStylaLT updated:
+
+
Fixed missing space transition tiles in emergency shuttle transit
+
Fixed lack of prisoner access to lower part of labor camp shuttle
+
Changed UO45's and MO19's away missions' external tiles to just airless ones.
+
Changed MO19's exterior to be more rock than ground, this is to make Linda cry less when this mission is passed.
+
+
General Chaos updated:
+
+
Ports TG's mech bay recharger code.
+
+
IcyV updated:
+
+
Adds an exploding chameleon flag for traitors.
+
+
KorPhaeron and Fox McCloud updated:
+
+
Merges Malf AI into traitor AI
+
Malf AI's starting CPU reduced from 100 to 50
+
Hacking APCs gives 10 additional CPU
+
Hacking APCs throws an alert to the AI when it's hacking that automatically clears when hacking is complete (sounds too)
+
Traitor AI's start off with a syndicate headset
+
Adds doomsday device module for AI's for 130 CPU; when activated, it will purge the station of all life if the AI is not destroyed after 7.5 minutes
+
Adds in AI upgrade modules which allows you to giving hacking abilities to the AI or allow it to have increase surveillance capabilities
+
+
Krausus updated:
+
+
Karma spending is now slightly more straightforward and sanity-checked.
+
Ghosts can now see non-crew antagonists in the Award Karma listing.
+
You can now ctrl+click on yourself to stop pulling something.
+
+
Kyep updated:
+
+
Added Syndicate Infiltration Teams (SITs), which are like Syndicate Strike Teams (SSTs) but focusing on stealth rather than direct combat. Useful for getting ghosts into rounds, spicing up rounds, having traitors with teamwork, and new kinds of traitor objectives like kidnap.
+
Fixed bug that Dust implants had no icon.
+
+
LittleBigKid2000 updated:
+
+
The arrivals checkpoint camera monitor is now connected to some camera networks by default.
+
Talking swords can now be understood by their wielders, and everyone else.
+
Engineering cyborgs now have floor painters. Absolutely nothing bad can happen because of this.
+
+
Norgad updated:
+
+
Coated Reinforced Walls now have unique sprites
+
+
TullyBurnalot updated:
+
+
Trash Bags fit in satchels/bags/duffelbags, but cannot be transported after being filled up.
+
Advanced Mops clean faster, can clean more
+
Holosign Projectors can create more signs
+
Ghosts can no longer create dirt
+
Dirt creation slowed down. "Clean Station" may actually be remotely possible now
+
Janitorial Closet tidied up
+
Can fill Light Replacers with boxes directly
+
Can recycle 3 broken/burnt bulbs into a functioning one
+
Can no longer cheat around NODROP by inserting NODROP lightbulbs into Light Replacers
+
Ghosts can no longer trip Proximity Sensors
+
Ghosts can no longer trip Infrared Sensors
+
Effects (like hallucinations) can no longer trip Proximity and Infrared Sensors
+
IDs are no longer dropped if their owner cryos with the ID inside a PDA inside a bag (very specific, yes)
+
+
Ty-Omaha updated:
+
+
Allows sechailer phrases to be selectable
+
Quick-equipping a PDA will now prioritize the PDA slot before the ID slot.
+
+
taukausanake updated:
+
+
Gives proper mix_messages for Uplink, Synthignon, and Synth 'n Soda drinks