diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm index c3dee83a812..ff088bf3825 100644 --- a/code/modules/mob/living/carbon/human/species/_species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -1033,16 +1033,14 @@ It'll return null if the organ doesn't correspond, so include null checks when u /datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, obj/item/organ/external/affecting, intent, mob/living/carbon/human/H) return -/proc/get_random_species(species_name = FALSE) // Returns a random non black-listed or hazardous species, either as a string or datum +/// Returns a list of names of non-blacklisted or hazardous species. +/proc/get_safe_species() var/static/list/random_species = list() - if(!random_species.len) - for(var/thing in subtypesof(/datum/species)) - var/datum/species/S = thing + if(!length(random_species)) + for(var/datum/species/S as anything in subtypesof(/datum/species)) 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 + return random_species /datum/species/proc/can_hear(mob/living/carbon/human/H) . = FALSE diff --git a/code/modules/projectiles/projectile/magic_projectiles.dm b/code/modules/projectiles/projectile/magic_projectiles.dm index ff7c643a3e7..ea04347978c 100644 --- a/code/modules/projectiles/projectile/magic_projectiles.dm +++ b/code/modules/projectiles/projectile/magic_projectiles.dm @@ -181,6 +181,36 @@ . = ..() wabbajack(change) +GLOBAL_LIST_INIT(wabbajack_hostile_animals, list( + "carp" = /mob/living/simple_animal/hostile/carp, + "bear" = /mob/living/simple_animal/hostile/bear, + "mushroom" = /mob/living/simple_animal/hostile/mushroom, + "statue" = /mob/living/simple_animal/hostile/statue, + "bat" = /mob/living/simple_animal/hostile/scarybat, + "goat" = /mob/living/simple_animal/hostile/retaliate/goat, + "tomato" = /mob/living/simple_animal/hostile/killertomato, + "gorilla" = /mob/living/simple_animal/hostile/gorilla, + "kangaroo" = /mob/living/simple_animal/hostile/retaliate/kangaroo, +)) + +GLOBAL_LIST_INIT(wabbajack_docile_animals, list( + "parrot" = /mob/living/simple_animal/parrot, + "corgi" = /mob/living/simple_animal/pet/dog/corgi, + "crab" = /mob/living/simple_animal/crab, + "cat" = /mob/living/simple_animal/pet/cat, + "mouse" = /mob/living/simple_animal/mouse, + "chicken" = /mob/living/simple_animal/chicken, + "cow" = /mob/living/simple_animal/cow, + "lizard" = /mob/living/simple_animal/lizard, + "fox" = /mob/living/simple_animal/pet/dog/fox, + "chick" = /mob/living/simple_animal/chick, + "pug" = /mob/living/simple_animal/pet/dog/pug, + "turkey" = /mob/living/simple_animal/turkey, + "seal" = /mob/living/simple_animal/seal, + "bunny" = /mob/living/simple_animal/bunny, + "penguin" = /mob/living/simple_animal/pet/penguin/emperor, +)) + /proc/wabbajack(mob/living/M, force_borg = FALSE, force_animal = FALSE) if(istype(M) && M.stat != DEAD && !M.notransform) M.notransform = TRUE @@ -188,6 +218,8 @@ M.overlays.Cut() M.invisibility = 101 + var/list/random_species = get_safe_species() + if(isrobot(M)) var/mob/living/silicon/robot/Robot = M QDEL_NULL(Robot.mmi) @@ -195,6 +227,8 @@ else if(ishuman(M)) var/mob/living/carbon/human/H = M + // Don't transform back into our original species + random_species -= H.dna.species.name // Make sure there are no organs or limbs to drop for(var/t in H.bodyparts) qdel(t) @@ -206,11 +240,24 @@ var/mob/living/new_mob - var/randomize = pick("robot", "slime", "xeno", "human", "animal") + var/randomize = null + var/transform_weights = list( + "robot" = 4, + "slime" = 4, + "xeno" = 4, + "terror" = 4, + "human" = length(random_species), + // double animal weight to account for the absurd number of human species we have + "animal" = (length(GLOB.wabbajack_docile_animals) + length(GLOB.wabbajack_hostile_animals)) * 2, + ) + if(force_borg) randomize = "robot" - if(force_animal) + else if(force_animal) randomize = "animal" + else + randomize = pickweight(transform_weights) + switch(randomize) if("robot") var/path @@ -240,55 +287,30 @@ new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc) new_mob.universal_speak = TRUE to_chat(M, "Your consciousness is subsumed by a distant hivemind... you feel murderous hostility towards non-xenomorph life!") + if("terror") + var/terror_type = pick( + /mob/living/simple_animal/hostile/poison/terror_spider/red, + /mob/living/simple_animal/hostile/poison/terror_spider/brown, + /mob/living/simple_animal/hostile/poison/terror_spider/gray, + /mob/living/simple_animal/hostile/poison/terror_spider/black) + new_mob = new terror_type(M.loc) + to_chat(M, "Your consciousness is subsumed by a distant hivemind... you feel murderous hostility towards all non-terror-spider lifeforms!") if("animal") if(prob(50)) - var/beast = pick("carp","bear","mushroom","statue", "bat", "goat", "tomato", "gorilla") - 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) - if("gorilla") - new_mob = new /mob/living/simple_animal/hostile/gorilla(M.loc) + var/beast = pick(GLOB.wabbajack_hostile_animals) + var/beast_type = GLOB.wabbajack_hostile_animals[beast] + new_mob = new beast_type(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/dog/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/dog/fox(M.loc) - else - new_mob = new /mob/living/simple_animal/chick(M.loc) + var/animal = pick(GLOB.wabbajack_docile_animals) + var/animal_type = GLOB.wabbajack_docile_animals[animal] + new_mob = new animal_type(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/character_save/S = new //Randomize appearance for the human - S.species = get_random_species(TRUE) + S.species = pick(random_species) S.randomise() S.copy_to(new_mob) randomize = H.dna.species.name