Polymorph retains name and equipment (where possible) (#18587)

Fixes bug where wabbajack statue's eyes didn't close

Removes indentation and tidies the wabbajack() proc

Corrected an inaccurate comment in mob.dm

Mass Polymorph no longer uses a spawn()

Adds syndicate medical borg, cak to possible forms

Polymorphed drones now have random appearances

GODMODE mobs are now immune to polymorph

Wabbajack altars now ghost their sleepers after 10 seconds, 
because they tend to just be abandoned and left there. It's 
all a dream to them, if and when they get pulled from the altar.
This commit is contained in:
coiax
2016-06-16 22:36:47 +01:00
committed by oranges
parent dfc6df579a
commit 598daee493
7 changed files with 202 additions and 163 deletions
+13 -21
View File
@@ -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("<span class='italics'>...wabbajack...wabbajack...</span>")
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("<span class='italics'>...wabbajack...wabbajack...</span>")
playsound(M.loc, 'sound/magic/Staff_Change.ogg', 50, 1, -1)
wabbajack(M)
message_admins("Mass polymorph started by [who_did_it] is complete.")
+4 -1
View File
@@ -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 << "<span class='holoparasite'>Your summoner has changed \
form to [new_mob]!</span>"
form!</span>"
@@ -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"
@@ -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))
+1 -1
View File
@@ -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
+144 -135
View File
@@ -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()]\] <font color='orange'>[M.real_name] ([M.ckey]) became [new_mob.real_name].</font>")
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 << "<B>Your form morphs into that of a [randomize].</B>"
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>[M.real_name] ([M.ckey]) became [new_mob.real_name].</font>")
qdel(M)
return new_mob
new_mob.a_intent = "harm"
M.wabbajack_act(new_mob)
new_mob << "<span class='warning'>Your form morphs into that of \
a [randomize].</span>"
qdel(M)
return new_mob
/obj/item/projectile/magic/animate
name = "bolt of animation"
+21 -4
View File
@@ -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("<span class='revenboldnotice'>\
[src] opens its eyes.</span>")
update_icon()
active = TRUE
else
if(active)
visible_message("<span class='revenboldnotice'>\
[src] closes its eyes.</span>")
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("<span class='revennotice'>A strange purple glow \
wraps itself around [L] as they suddenly fall unconcious.</span>",
"<span class='revendanger'>[desc]</span>")
// 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("<span class='revennotice'>The glow from [L] fades \
away.</span>")
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 << "<span class='revennotice'>While you slumber, you have \
the strangest dream, like you can see yourself from the outside.\
</span>"
sleeper.ghostize(TRUE)
/obj/structure/table/abductor/wabbajack/left
desc = "You sleep so it may wake."