diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index b20cdb3823f..c11d84451f9 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -93,6 +93,8 @@
var/show_ssd = 1
var/can_revive_by_healing // Determines whether or not this species can be revived by simply healing them
var/has_gender = TRUE
+ var/blacklisted = FALSE
+ var/dangerous_existence = FALSE
//Death vars.
var/death_message = "seizes up and falls limp, their eyes dead and lifeless..."
@@ -704,4 +706,15 @@ It'll return null if the organ doesn't correspond, so include null checks when u
/datum/species/proc/water_act(mob/living/carbon/human/M, volume, temperature, source)
if(abs(temperature - M.bodytemperature) > 10) //If our water and mob temperature varies by more than 10K, cool or/ heat them appropriately
- M.bodytemperature = (temperature + M.bodytemperature) * 0.5 //Approximation for gradual heating or cooling
\ No newline at end of file
+ M.bodytemperature = (temperature + M.bodytemperature) * 0.5 //Approximation for gradual heating or cooling
+
+/proc/get_random_species(species_name = FALSE) // Returns a random non black-listed or hazardous species, either as a string or datum
+ var/static/list/random_species = list()
+ if(!random_species.len)
+ for(var/thing in subtypesof(/datum/species))
+ var/datum/species/S = thing
+ if(!initial(S.dangerous_existence) && !initial(S.blacklisted))
+ random_species += initial(S.name)
+ var/picked_species = pick(random_species)
+ var/datum/species/selected_species = GLOB.all_species[picked_species]
+ return species_name ? picked_species : selected_species.type
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species/nucleation.dm b/code/modules/mob/living/carbon/human/species/nucleation.dm
index faf81ea875b..21d8a5c0012 100644
--- a/code/modules/mob/living/carbon/human/species/nucleation.dm
+++ b/code/modules/mob/living/carbon/human/species/nucleation.dm
@@ -2,6 +2,7 @@
name = "Nucleation"
name_plural = "Nucleations"
icobase = 'icons/mob/human_races/r_nucleation.dmi'
+ blacklisted = TRUE
blurb = "A sub-race of unfortunates who have been exposed to too much supermatter radiation. As a result, \
supermatter crystal clusters have begun to grow across their bodies. Research to find a cure for this ailment \
has been slow, and so this is a common fate for veteran engineers. The supermatter crystals produce oxygen, \
diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm
index dcbdc7d17be..b49dd88d8e6 100644
--- a/code/modules/mob/living/carbon/human/species/plasmaman.dm
+++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm
@@ -3,6 +3,7 @@
name_plural = "Plasmamen"
icobase = 'icons/mob/human_races/r_plasmaman_sb.dmi'
deform = 'icons/mob/human_races/r_plasmaman_pb.dmi' // TODO: Need deform.
+ dangerous_existence = TRUE //So so much
//language = "Clatter"
species_traits = list(IS_WHITELISTED, NO_BLOOD, NOTRANSSTING)
diff --git a/code/modules/mob/living/carbon/human/species/shadow.dm b/code/modules/mob/living/carbon/human/species/shadow.dm
index 03956f81cb0..df1ecd61484 100644
--- a/code/modules/mob/living/carbon/human/species/shadow.dm
+++ b/code/modules/mob/living/carbon/human/species/shadow.dm
@@ -4,6 +4,7 @@
icobase = 'icons/mob/human_races/r_shadow.dmi'
deform = 'icons/mob/human_races/r_shadow.dmi'
+ dangerous_existence = TRUE
unarmed_type = /datum/unarmed_attack/claws
diff --git a/code/modules/mob/living/carbon/human/species/shadowling.dm b/code/modules/mob/living/carbon/human/species/shadowling.dm
index b87d7565d23..1ce7b5cd0e0 100644
--- a/code/modules/mob/living/carbon/human/species/shadowling.dm
+++ b/code/modules/mob/living/carbon/human/species/shadowling.dm
@@ -4,6 +4,7 @@
icobase = 'icons/mob/human_races/r_shadowling.dmi'
deform = 'icons/mob/human_races/r_shadowling.dmi'
+ blacklisted = TRUE
blood_color = "#555555"
flesh_color = "#222222"
@@ -60,7 +61,7 @@
blood_color = "#CCCCCC"
flesh_color = "#AAAAAA"
- species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE)
+ species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE, NO_EXAMINE)
burn_mod = 1.1
oxy_mod = 0
heatmod = 1.1
diff --git a/code/modules/mob/living/carbon/human/species/vox.dm b/code/modules/mob/living/carbon/human/species/vox.dm
index 799c71af735..1bc0b8b3b9e 100644
--- a/code/modules/mob/living/carbon/human/species/vox.dm
+++ b/code/modules/mob/living/carbon/human/species/vox.dm
@@ -3,6 +3,7 @@
name_plural = "Vox"
icobase = 'icons/mob/human_races/vox/r_vox.dmi'
deform = 'icons/mob/human_races/vox/r_def_vox.dmi'
+ dangerous_existence = TRUE
language = "Vox-pidgin"
tail = "voxtail"
speech_sounds = list('sound/voice/shriek1.ogg')
@@ -145,6 +146,7 @@
icobase = 'icons/mob/human_races/r_armalis.dmi'
deform = 'icons/mob/human_races/r_armalis.dmi'
unarmed_type = /datum/unarmed_attack/claws/armalis
+ blacklisted = TRUE
warning_low_pressure = 50
hazard_low_pressure = 0
diff --git a/code/modules/mob/living/carbon/human/species/wryn.dm b/code/modules/mob/living/carbon/human/species/wryn.dm
index 04060071ae8..219be4111b3 100644
--- a/code/modules/mob/living/carbon/human/species/wryn.dm
+++ b/code/modules/mob/living/carbon/human/species/wryn.dm
@@ -3,6 +3,7 @@
name_plural = "Wryn"
icobase = 'icons/mob/human_races/r_wryn.dmi'
deform = 'icons/mob/human_races/r_wryn.dmi'
+ blacklisted = TRUE
language = "Wryn Hivemind"
tail = "wryntail"
punchdamagelow = 0
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index 1df45dbe064..854fd1edbaf 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -146,114 +146,120 @@
. = ..()
wabbajack(change)
-proc/wabbajack(mob/living/M)
- if(istype(M))
- if(istype(M, /mob/living) && M.stat != DEAD)
- if(M.notransform)
- return
- M.notransform = 1
- M.canmove = 0
- M.icon = null
- M.overlays.Cut()
- M.invisibility = 101
+/proc/wabbajack(mob/living/M)
+ if(istype(M) && M.stat != DEAD && !M.notransform)
+ M.notransform = TRUE
+ M.canmove = FALSE
+ M.icon = null
+ M.overlays.Cut()
+ M.invisibility = 101
- if(istype(M, /mob/living/silicon/robot))
- var/mob/living/silicon/robot/Robot = M
- if(Robot.mmi)
- qdel(Robot.mmi)
- Robot.notify_ai(1)
- else
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- // Make sure there are no organs or limbs to drop
- for(var/t in H.bodyparts)
- qdel(t)
- for(var/i in H.internal_organs)
- qdel(i)
- for(var/obj/item/W in M)
- M.unEquip(W, 1)
- qdel(W)
+ if(isrobot(M))
+ var/mob/living/silicon/robot/Robot = M
+ QDEL_NULL(Robot.mmi)
+ Robot.notify_ai(1)
+ else
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ // Make sure there are no organs or limbs to drop
+ for(var/t in H.bodyparts)
+ qdel(t)
+ for(var/i in H.internal_organs)
+ qdel(i)
+ for(var/obj/item/W in M)
+ M.unEquip(W, 1)
+ qdel(W)
- var/mob/living/new_mob
+ var/mob/living/new_mob
- var/randomize = pick("robot","slime","xeno","human","animal")
- switch(randomize)
- if("robot")
- if(prob(30))
- new_mob = new /mob/living/silicon/robot/syndicate(M.loc)
- else
- new_mob = new /mob/living/silicon/robot(M.loc)
- new_mob.gender = M.gender
- new_mob.invisibility = 0
- new_mob.job = "Cyborg"
- var/mob/living/silicon/robot/Robot = new_mob
- Robot.mmi = new /obj/item/mmi(new_mob)
- if(ishuman(M))
- Robot.mmi.transfer_identity(M) //Does not transfer key/client.
- if("slime")
- new_mob = new /mob/living/carbon/slime/random(M.loc)
- new_mob.universal_speak = 1
- if("xeno")
- if(prob(50))
- new_mob = new /mob/living/carbon/alien/humanoid/hunter(M.loc)
- else
- new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc)
- new_mob.universal_speak = 1
- if("animal")
- if(prob(50))
- var/beast = pick("carp","bear","mushroom","statue", "bat", "goat", "tomato")
- switch(beast)
- if("carp") new_mob = new /mob/living/simple_animal/hostile/carp(M.loc)
- if("bear") new_mob = new /mob/living/simple_animal/hostile/bear(M.loc)
- if("mushroom") new_mob = new /mob/living/simple_animal/hostile/mushroom(M.loc)
- if("statue") new_mob = new /mob/living/simple_animal/hostile/statue(M.loc)
- if("bat") new_mob = new /mob/living/simple_animal/hostile/scarybat(M.loc)
- if("goat") new_mob = new /mob/living/simple_animal/hostile/retaliate/goat(M.loc)
- if("tomato") new_mob = new /mob/living/simple_animal/hostile/killertomato(M.loc)
- else
- var/animal = pick("parrot","corgi","crab","pug","cat","mouse","chicken","cow","lizard","chick","fox")
- switch(animal)
- if("parrot") new_mob = new /mob/living/simple_animal/parrot(M.loc)
- if("corgi") new_mob = new /mob/living/simple_animal/pet/corgi(M.loc)
- if("crab") new_mob = new /mob/living/simple_animal/crab(M.loc)
- if("cat") new_mob = new /mob/living/simple_animal/pet/cat(M.loc)
- if("mouse") new_mob = new /mob/living/simple_animal/mouse(M.loc)
- if("chicken") new_mob = new /mob/living/simple_animal/chicken(M.loc)
- if("cow") new_mob = new /mob/living/simple_animal/cow(M.loc)
- if("lizard") new_mob = new /mob/living/simple_animal/lizard(M.loc)
- if("fox") new_mob = new /mob/living/simple_animal/pet/fox(M.loc)
- else new_mob = new /mob/living/simple_animal/chick(M.loc)
- new_mob.universal_speak = 1
- if("human")
- new_mob = new /mob/living/carbon/human(M.loc)
- // Include standard, whitelisted, and monkey species...
- var/list/new_species = list()
- for(var/datum/species/S in subtypesof(/datum/species))
- if(istype(S, /datum/species/vox/armalis))
- continue
- new_species.Add(S)
- var/mob/living/carbon/human/H = new_mob
- var/datum/species/S = pick(new_species)
- H.set_species(S)
- randomize = initial(S.name)
- var/datum/preferences/A = new() //Randomize appearance for the human
- A.copy_to(new_mob)
+ var/randomize = pick("robot", "slime", "xeno", "human", "animal")
+ switch(randomize)
+ if("robot")
+ if(prob(30))
+ new_mob = new /mob/living/silicon/robot/syndicate(M.loc)
else
- return
-
- M.create_attack_log("[key_name(M)] became [new_mob.real_name].")
- new_mob.attack_log = M.attack_log
-
- new_mob.a_intent = INTENT_HARM
- if(M.mind)
- M.mind.transfer_to(new_mob)
+ new_mob = new /mob/living/silicon/robot(M.loc)
+ new_mob.gender = M.gender
+ new_mob.invisibility = 0
+ new_mob.job = "Cyborg"
+ var/mob/living/silicon/robot/Robot = new_mob
+ Robot.mmi = new /obj/item/mmi(new_mob)
+ if(ishuman(M))
+ Robot.mmi.transfer_identity(M) //Does not transfer key/client.
+ if("slime")
+ new_mob = new /mob/living/carbon/slime/random(M.loc)
+ new_mob.universal_speak = TRUE
+ if("xeno")
+ if(prob(50))
+ new_mob = new /mob/living/carbon/alien/humanoid/hunter(M.loc)
+ else
+ new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc)
+ new_mob.universal_speak = TRUE
+ if("animal")
+ if(prob(50))
+ var/beast = pick("carp","bear","mushroom","statue", "bat", "goat", "tomato")
+ switch(beast)
+ if("carp")
+ new_mob = new /mob/living/simple_animal/hostile/carp(M.loc)
+ if("bear")
+ new_mob = new /mob/living/simple_animal/hostile/bear(M.loc)
+ if("mushroom")
+ new_mob = new /mob/living/simple_animal/hostile/mushroom(M.loc)
+ if("statue")
+ new_mob = new /mob/living/simple_animal/hostile/statue(M.loc)
+ if("bat")
+ new_mob = new /mob/living/simple_animal/hostile/scarybat(M.loc)
+ if("goat")
+ new_mob = new /mob/living/simple_animal/hostile/retaliate/goat(M.loc)
+ if("tomato")
+ new_mob = new /mob/living/simple_animal/hostile/killertomato(M.loc)
+ else
+ var/animal = pick("parrot", "corgi", "crab", "pug", "cat", "mouse", "chicken", "cow", "lizard", "chick", "fox")
+ switch(animal)
+ if("parrot")
+ new_mob = new /mob/living/simple_animal/parrot(M.loc)
+ if("corgi")
+ new_mob = new /mob/living/simple_animal/pet/corgi(M.loc)
+ if("crab")
+ new_mob = new /mob/living/simple_animal/crab(M.loc)
+ if("cat")
+ new_mob = new /mob/living/simple_animal/pet/cat(M.loc)
+ if("mouse")
+ new_mob = new /mob/living/simple_animal/mouse(M.loc)
+ if("chicken")
+ new_mob = new /mob/living/simple_animal/chicken(M.loc)
+ if("cow")
+ new_mob = new /mob/living/simple_animal/cow(M.loc)
+ if("lizard")
+ new_mob = new /mob/living/simple_animal/lizard(M.loc)
+ if("fox")
+ new_mob = new /mob/living/simple_animal/pet/fox(M.loc)
+ else
+ new_mob = new /mob/living/simple_animal/chick(M.loc)
+ new_mob.universal_speak = TRUE
+ if("human")
+ new_mob = new /mob/living/carbon/human(M.loc)
+ var/mob/living/carbon/human/H = new_mob
+ var/datum/preferences/A = new() //Randomize appearance for the human
+ A.species = get_random_species(TRUE)
+ A.copy_to(new_mob)
+ randomize = H.dna.species.name
else
- new_mob.key = M.key
+ return
- to_chat(new_mob, "Your form morphs into that of a [randomize].")
+ M.create_attack_log("[key_name(M)] became [new_mob.real_name].")
+ new_mob.attack_log = M.attack_log
- qdel(M)
- return new_mob
+ new_mob.a_intent = INTENT_HARM
+ if(M.mind)
+ M.mind.transfer_to(new_mob)
+ else
+ new_mob.key = M.key
+
+ to_chat(new_mob, "Your form morphs into that of a [randomize].")
+
+ qdel(M)
+ return new_mob
/obj/item/projectile/magic/animate
name = "bolt of animation"