mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-19 03:55:11 +01:00
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:
@@ -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.")
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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."
|
||||
|
||||
|
||||
Reference in New Issue
Block a user