diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 6208b86e000..546dd4548d2 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -1043,30 +1043,22 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
if(confirm != "Yes")
return
- var/keep_name = alert(src, "Do you want mobs to retain their names?", "Keep The Names?", "Yes", "No")
-
var/list/mobs = shuffle(living_mob_list.Copy()) // might change while iterating
var/who_did_it = key_name_admin(usr)
- spawn(5) // let other things clear this tick
- for(var/mob/living/M in mobs)
- CHECK_TICK
-
- if(!M || !M.name || !M.real_name)
- continue
-
- M.audible_message("...wabbajack...wabbajack...")
- playsound(M.loc, 'sound/magic/Staff_Change.ogg', 50, 1, -1)
- var/name = M.name
- var/real_name = M.real_name
-
- var/mob/living/new_mob = wabbajack(M)
- if(keep_name == "Yes" && new_mob)
- new_mob.name = name
- new_mob.real_name = real_name
-
-
- message_admins("Mass polymorph started by [who_did_it] is complete.")
message_admins("[key_name_admin(usr)] started polymorphed all living mobs.")
log_admin("[key_name(usr)] polymorphed all living mobs.")
feedback_add_details("admin_verb","MASSWABBAJACK")
+
+ for(var/mob/living/M in mobs)
+ CHECK_TICK
+
+ if(!M)
+ continue
+
+ M.audible_message("...wabbajack...wabbajack...")
+ playsound(M.loc, 'sound/magic/Staff_Change.ogg', 50, 1, -1)
+
+ wabbajack(M)
+
+ message_admins("Mass polymorph started by [who_did_it] is complete.")
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 50435deed93..fa493a7df28 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1029,6 +1029,9 @@ Sorry Giacom. Please don't be mad :(
// Called when we are hit by a bolt of polymorph and changed
// Generally the mob we are currently in, is about to be deleted
/mob/living/proc/wabbajack_act(mob/living/new_mob)
+ new_mob.name = name
+ new_mob.real_name = real_name
+
if(mind)
mind.transfer_to(new_mob)
else
@@ -1039,4 +1042,4 @@ Sorry Giacom. Please don't be mad :(
G.summoner = new_mob
G.Recall()
G << "Your summoner has changed \
- form to [new_mob]!"
+ form!"
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
index f37da30e127..e3a1f466c33 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
@@ -5,6 +5,7 @@
//Drones with custom shells
//Drones with overriden procs
//Drones with camogear for hat related memes
+//Drone type for use with polymorph (no preloaded items, random appearance)
//More types of drones
@@ -69,3 +70,20 @@
desc = "A shell of a snowflake drone, a maintenance drone with a built in holographic projector to display hats and masks."
drone_type = /mob/living/simple_animal/drone/snowflake
+/mob/living/simple_animal/drone/polymorphed
+ default_storage = null
+ default_hatmask = null
+ picked = TRUE
+
+/mob/living/simple_animal/drone/polymorphed/New()
+ . = ..()
+ liberate()
+ visualAppearence = pick(MAINTDRONE, REPAIRDRONE, SCOUTDRONE)
+ if(visualAppearence == MAINTDRONE)
+ var/colour = pick("grey", "blue", "red", "green", "pink", "orange")
+ icon_state = "[visualAppearence]_[colour]"
+ else
+ icon_state = visualAppearence
+
+ icon_living = icon_state
+ icon_dead = "[visualAppearence]_dead"
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 62e5bc05980..f2324e83116 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -419,4 +419,4 @@ var/list/slime_colours = list("rainbow", "grey", "purple", "metal", "orange",
return 3
/mob/living/simple_animal/slime/random/New(loc, new_colour, new_is_adult)
- . = ..(loc, pick(slime_colours), new_is_adult)
+ . = ..(loc, pick(slime_colours), prob(50))
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 8d7f208a87c..49fdc9e6ed0 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -233,7 +233,7 @@ var/next_mob_id = 0
if(!istype(W)) return 0
for(var/slot in W.slot_equipment_priority)
- if(equip_to_slot_if_possible(W, slot, 0, 1, 1)) //qdel_on_fail = 0; disable_warning = 0; redraw_mob = 1
+ if(equip_to_slot_if_possible(W, slot, 0, 1, 1)) //qdel_on_fail = 0; disable_warning = 1; redraw_mob = 1
return 1
return 0
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index 464fe662962..c3c379534f0 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -134,153 +134,162 @@
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 = INVISIBILITY_ABSTRACT
+ if(!istype(M) || M.stat == DEAD || M.notransform || (GODMODE & M.status_flags))
+ return
- if(istype(M, /mob/living/silicon/robot))
- var/mob/living/silicon/robot/Robot = M
- if(Robot.mmi)
- qdel(Robot.mmi)
- Robot.notify_ai(1)
+ M.notransform = 1
+ M.canmove = 0
+ M.icon = null
+ M.overlays.Cut()
+ M.invisibility = INVISIBILITY_ABSTRACT
+
+ var/list/contents = M.contents.Copy()
+
+ 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
+ for(var/obj/item/W in contents)
+ if(!M.unEquip(W))
+ qdel(W)
+
+ var/mob/living/new_mob
+
+ var/randomize = pick("monkey","robot","slime","xeno","humanoid","animal")
+ switch(randomize)
+ if("monkey")
+ new_mob = new /mob/living/carbon/monkey(M.loc)
+ if("robot")
+ var/robot = pick("cyborg","syndiborg","drone")
+ switch(robot)
+ if("cyborg")
+ new_mob = new /mob/living/silicon/robot(M.loc)
+ if("syndiborg")
+ var/path
+ if(prob(50))
+ path = /mob/living/silicon/robot/syndicate
+ else
+ path = /mob/living/silicon/robot/syndicate/medical
+ new_mob = new path(M.loc)
+ if("drone")
+ new_mob = new /mob/living/simple_animal/drone/polymorphed(M.loc)
+ if(issilicon(new_mob))
+ new_mob.gender = M.gender
+ new_mob.invisibility = 0
+ new_mob.job = "Cyborg"
+ var/mob/living/silicon/robot/Robot = new_mob
+ Robot.mmi.transfer_identity(M) //Does not transfer key/client.
+ if("slime")
+ new_mob = new /mob/living/simple_animal/slime/random(M.loc)
+ if("xeno")
+ if(prob(50))
+ new_mob = new /mob/living/carbon/alien/humanoid/hunter(M.loc)
else
- for(var/obj/item/W in M)
- if(!M.unEquip(W))
- qdel(W)
+ new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc)
- var/mob/living/new_mob
+ if("animal")
+ var/path
+ if(prob(50))
+ var/beast = pick("carp","bear","mushroom","statue", "bat", "goat","killertomato", "spiderbase", "spiderhunter", "blobbernaut", "magicarp", "chaosmagicarp")
+ switch(beast)
+ if("carp")
+ path = /mob/living/simple_animal/hostile/carp
+ if("bear")
+ path = /mob/living/simple_animal/hostile/bear
+ if("mushroom")
+ path = /mob/living/simple_animal/hostile/mushroom
+ if("statue")
+ path = /mob/living/simple_animal/hostile/statue
+ if("bat")
+ path = /mob/living/simple_animal/hostile/retaliate/bat
+ if("goat")
+ path = /mob/living/simple_animal/hostile/retaliate/goat
+ if("killertomato")
+ path = /mob/living/simple_animal/hostile/killertomato
+ if("spiderbase")
+ path = /mob/living/simple_animal/hostile/poison/giant_spider
+ if("spiderhunter")
+ path = /mob/living/simple_animal/hostile/poison/giant_spider/hunter
+ if("blobbernaut")
+ path = /mob/living/simple_animal/hostile/blob/blobbernaut/independent
+ if("magicarp")
+ path = /mob/living/simple_animal/hostile/carp/ranged
+ if("chaosmagicarp")
+ path = /mob/living/simple_animal/hostile/carp/ranged/chaos
+ else
+ var/animal = pick("parrot","corgi","crab","pug","cat","mouse","chicken","cow","lizard","chick","fox","butterfly","cak")
+ switch(animal)
+ if("parrot")
+ path = /mob/living/simple_animal/parrot
+ if("corgi")
+ path = /mob/living/simple_animal/pet/dog/corgi
+ if("crab")
+ path = /mob/living/simple_animal/crab
+ if("pug")
+ path = /mob/living/simple_animal/pet/dog/pug
+ if("cat")
+ path = /mob/living/simple_animal/pet/cat
+ if("mouse")
+ path = /mob/living/simple_animal/mouse
+ if("chicken")
+ path = /mob/living/simple_animal/chicken
+ if("cow")
+ path = /mob/living/simple_animal/cow
+ if("lizard")
+ path = /mob/living/simple_animal/hostile/lizard
+ if("fox")
+ path = /mob/living/simple_animal/pet/fox
+ if("butterfly")
+ path = /mob/living/simple_animal/butterfly
+ if("cak")
+ path = /mob/living/simple_animal/pet/cat/cak
+ if("chick")
+ path = /mob/living/simple_animal/chick
- var/randomize = pick("monkey","robot","slime","xeno","humanoid","animal")
- switch(randomize)
- if("monkey")
- new_mob = new /mob/living/carbon/monkey(M.loc)
- new_mob.languages |= HUMAN
- if("robot")
- var/robot = pick("cyborg","syndiborg","drone")
- switch(robot)
- if("cyborg")
- new_mob = new /mob/living/silicon/robot(M.loc)
- if("syndiborg")
- new_mob = new /mob/living/silicon/robot/syndicate(M.loc)
- if("drone")
- new_mob = new /mob/living/simple_animal/drone(M.loc)
- var/mob/living/simple_animal/drone/D = new_mob
- D.liberate() // F R E E D R O N E
- if(issilicon(new_mob))
- new_mob.gender = M.gender
- new_mob.invisibility = 0
- new_mob.job = "Cyborg"
- var/mob/living/silicon/robot/Robot = new_mob
- Robot.mmi.transfer_identity(M) //Does not transfer key/client.
- else
- new_mob.languages |= HUMAN
- if("slime")
- var/mob/living/simple_animal/slime/random/slimey
- slimey = new(get_turf(M), null, new_is_adult=prob(50))
- new_mob = slimey
- new_mob.languages |= HUMAN
- 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.languages |= HUMAN
+ new_mob = new path(M.loc)
- if("animal")
- if(prob(50))
- var/beast = pick("carp","bear","mushroom","statue", "bat", "goat","killertomato", "spiderbase", "spiderhunter", "blobbernaut", "magicarp", "chaosmagicarp")
- 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/retaliate/bat(M.loc)
- if("goat")
- new_mob = new /mob/living/simple_animal/hostile/retaliate/goat(M.loc)
- if("killertomato")
- new_mob = new /mob/living/simple_animal/hostile/killertomato(M.loc)
- if("spiderbase")
- new_mob = new /mob/living/simple_animal/hostile/poison/giant_spider(M.loc)
- if("spiderhunter")
- new_mob = new /mob/living/simple_animal/hostile/poison/giant_spider/hunter(M.loc)
- if("blobbernaut")
- new_mob = new /mob/living/simple_animal/hostile/blob/blobbernaut/independent(M.loc)
- if("magicarp")
- new_mob = new /mob/living/simple_animal/hostile/carp/ranged(M.loc)
- if("chaosmagicarp")
- new_mob = new /mob/living/simple_animal/hostile/carp/ranged/chaos(M.loc)
- else
- var/animal = pick("parrot","corgi","crab","pug","cat","mouse","chicken","cow","lizard","chick","fox","butterfly")
- 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("pug")
- new_mob = new /mob/living/simple_animal/pet/dog/pug(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/hostile/lizard(M.loc)
- if("fox")
- new_mob = new /mob/living/simple_animal/pet/fox(M.loc)
- if("butterfly")
- new_mob = new /mob/living/simple_animal/butterfly(M.loc)
- else
- new_mob = new /mob/living/simple_animal/chick(M.loc)
- new_mob.languages |= HUMAN
- if("humanoid")
- new_mob = new /mob/living/carbon/human(M.loc)
+ if("humanoid")
+ new_mob = new /mob/living/carbon/human(M.loc)
- var/datum/preferences/A = new() //Randomize appearance for the human
- A.copy_to(new_mob, icon_updates=0)
+ var/datum/preferences/A = new() //Randomize appearance for the human
+ A.copy_to(new_mob, icon_updates=0)
- var/mob/living/carbon/human/H = new_mob
- if(prob(50))
- var/list/all_species = list()
- for(var/speciestype in subtypesof(/datum/species))
- var/datum/species/S = new speciestype()
- if(!S.dangerous_existence)
- all_species += speciestype
- H.set_species(pick(all_species), icon_update=0)
- H.real_name = H.dna.species.random_name(H.gender,1)
- H.update_body()
- H.update_hair()
- H.update_body_parts()
- H.dna.update_dna_identity()
- else
- return
+ var/mob/living/carbon/human/H = new_mob
+ if(prob(50))
+ var/list/all_species = list()
+ for(var/speciestype in subtypesof(/datum/species))
+ var/datum/species/S = new speciestype()
+ if(!S.dangerous_existence)
+ all_species += speciestype
+ H.set_species(pick(all_species), icon_update=0)
+ H.update_body()
+ H.update_hair()
+ H.update_body_parts()
+ H.dna.update_dna_identity()
- new_mob.attack_log = M.attack_log
- M.attack_log += text("\[[time_stamp()]\] [M.real_name] ([M.ckey]) became [new_mob.real_name].")
+ if(!new_mob)
+ return
- new_mob.a_intent = "harm"
+ new_mob.languages |= HUMAN
+ new_mob.attack_log = M.attack_log
- M.wabbajack_act(new_mob)
+ // Some forms can still wear some items
+ for(var/obj/item/W in contents)
+ new_mob.equip_to_appropriate_slot(W)
- new_mob << "Your form morphs into that of a [randomize]."
+ M.attack_log += text("\[[time_stamp()]\] [M.real_name] ([M.ckey]) became [new_mob.real_name].")
- qdel(M)
- return new_mob
+ new_mob.a_intent = "harm"
+
+ M.wabbajack_act(new_mob)
+
+ new_mob << "Your form morphs into that of \
+ a [randomize]."
+
+ qdel(M)
+ return new_mob
/obj/item/projectile/magic/animate
name = "bolt of animation"
diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm
index 5f8d9cae8d2..6e2f38b3768 100644
--- a/code/modules/shuttle/special.dm
+++ b/code/modules/shuttle/special.dm
@@ -11,6 +11,7 @@
icon_state = "wabbajack_statue"
icon_state_on = "wabbajack_statue_on"
var/list/active_tables = list()
+ var/tables_required = 2
active = FALSE
/obj/machinery/power/emitter/energycannon/magical/New()
@@ -27,18 +28,17 @@
/obj/machinery/power/emitter/energycannon/magical/process()
. = ..()
- if(active_tables.len >= 2)
+ if(active_tables.len >= tables_required)
if(!active)
visible_message("\
[src] opens its eyes.")
- update_icon()
active = TRUE
else
if(active)
visible_message("\
[src] closes its eyes.")
- update_icon()
active = FALSE
+ update_icon()
/obj/machinery/power/emitter/energycannon/magical/attack_hand(mob/user)
@@ -55,6 +55,8 @@
/obj/structure/table/abductor/wabbajack
name = "wabbajack altar"
+ desc = "Whether you're sleeping or waking, it's going to be \
+ quite chaotic."
health = 1000
verb_say = "chants"
var/obj/machinery/power/emitter/energycannon/magical/our_statue
@@ -77,6 +79,12 @@
our_statue = M
break
+ if(!our_statue)
+ name = "inert [name]"
+ return
+ else
+ name = initial(name)
+
var/turf/T = get_turf(src)
var/list/found = list()
for(var/mob/living/carbon/C in T)
@@ -90,7 +98,8 @@
L.visible_message("A strange purple glow \
wraps itself around [L] as they suddenly fall unconcious.",
"[desc]")
-
+ // Don't let them sit suround unconscious forever
+ addtimer(src, "sleeper_dreams", 100, FALSE, L)
// Existing sleepers
for(var/i in found)
@@ -103,6 +112,7 @@
L.color = initial(L.color)
L.visible_message("The glow from [L] fades \
away.")
+ L.grab_ghost()
sleepers = found
@@ -114,6 +124,13 @@
else
our_statue.active_tables -= src
+/obj/structure/table/abductor/wabbajack/proc/sleeper_dreams(mob/living/sleeper)
+ if(sleeper in sleepers)
+ sleeper << "While you slumber, you have \
+ the strangest dream, like you can see yourself from the outside.\
+ "
+ sleeper.ghostize(TRUE)
+
/obj/structure/table/abductor/wabbajack/left
desc = "You sleep so it may wake."