diff --git a/code/modules/spells/spell_types/shapeshift.dm b/code/modules/spells/spell_types/shapeshift.dm
index 853aab8b9b..f4969cd698 100644
--- a/code/modules/spells/spell_types/shapeshift.dm
+++ b/code/modules/spells/spell_types/shapeshift.dm
@@ -11,9 +11,10 @@
invocation_type = "shout"
action_icon_state = "shapeshift"
+ var/revert_on_death = TRUE
+ var/die_with_shapeshifted_form = TRUE
+
var/shapeshift_type
- var/list/current_shapes = list()
- var/list/current_casters = list()
var/list/possible_shapes = list(/mob/living/simple_animal/mouse,\
/mob/living/simple_animal/pet/dog/corgi,\
/mob/living/simple_animal/hostile/carp/ranged/chaos,\
@@ -40,46 +41,45 @@
if(!shapeshift_type) //If you aren't gonna decide I am!
shapeshift_type = pick(animal_list)
shapeshift_type = animal_list[shapeshift_type]
- if(M in current_shapes)
+
+ var/obj/shapeshift_holder/S = locate() in M
+ if(S)
Restore(M)
else
Shapeshift(M)
+
/obj/effect/proc_holder/spell/targeted/shapeshift/proc/Shapeshift(mob/living/caster)
- for(var/mob/living/M in caster)
- if(M.status_flags & GODMODE)
- to_chat(caster, "You're already shapeshifted!")
- return
+ var/obj/shapeshift_holder/H = locate() in caster
+ if(H)
+ to_chat(caster, "You're already shapeshifted!")
+ return
var/mob/living/shape = new shapeshift_type(caster.loc)
+<<<<<<< HEAD
caster.loc = shape
caster.status_flags |= GODMODE
+=======
+ H = new(shape,src,caster)
+>>>>>>> 28bd643... Shapeshift tweaks. (#32260)
- current_shapes |= shape
- current_casters |= caster
clothes_req = 0
human_req = 0
- caster.mind.transfer_to(shape)
-
/obj/effect/proc_holder/spell/targeted/shapeshift/proc/Restore(mob/living/shape)
- var/mob/living/caster
- for(var/mob/living/M in shape)
- if(M in current_casters)
- caster = M
- break
- if(!caster)
+ var/obj/shapeshift_holder/H = locate() in shape
+ if(!H)
return
+<<<<<<< HEAD
caster.loc = shape.loc
caster.status_flags &= ~GODMODE
+=======
+
+ H.restore()
+>>>>>>> 28bd643... Shapeshift tweaks. (#32260)
clothes_req = initial(clothes_req)
human_req = initial(human_req)
- current_casters.Remove(caster)
- current_shapes.Remove(shape)
-
- shape.mind.transfer_to(caster)
- qdel(shape) //Gib it maybe ?
/obj/effect/proc_holder/spell/targeted/shapeshift/dragon
name = "Dragon Form"
@@ -87,6 +87,85 @@
invocation = "RAAAAAAAAWR!"
shapeshift_type = /mob/living/simple_animal/hostile/megafauna/dragon/lesser
- list/current_shapes = list(/mob/living/simple_animal/hostile/megafauna/dragon/lesser)
- list/current_casters = list()
- list/possible_shapes = list(/mob/living/simple_animal/hostile/megafauna/dragon/lesser)
+
+
+/obj/shapeshift_holder
+ name = "Shapeshift holder"
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ON_FIRE | UNACIDABLE | ACID_PROOF
+ var/mob/living/stored
+ var/mob/living/shape
+ var/restoring = FALSE
+ var/datum/soullink/shapeshift/slink
+ var/obj/effect/proc_holder/spell/targeted/shapeshift/source
+
+/obj/shapeshift_holder/Initialize(mapload,obj/effect/proc_holder/spell/targeted/shapeshift/source,mob/living/caster)
+ . = ..()
+ src.source = source
+ shape = loc
+ if(!istype(shape))
+ CRASH("shapeshift holder created outside mob/living")
+ stored = caster
+ if(stored.mind)
+ stored.mind.transfer_to(shape)
+ stored.forceMove(src)
+ stored.notransform = TRUE
+ slink = soullink(/datum/soullink/shapeshift, stored , shape)
+ slink.source = src
+
+/obj/shapeshift_holder/Destroy()
+ if(!restoring)
+ restore()
+ stored = null
+ shape = null
+ . = ..()
+
+/obj/shapeshift_holder/Moved()
+ . = ..()
+ if(!restoring || QDELETED(src))
+ restore()
+
+/obj/shapeshift_holder/handle_atom_del(atom/A)
+ if(A == stored && !restoring)
+ restore()
+
+/obj/shapeshift_holder/Exited(atom/movable/AM)
+ if(AM == stored && !restoring)
+ restore()
+
+/obj/shapeshift_holder/proc/casterDeath()
+ //Something kills the stored caster through direct damage.
+ if(source.revert_on_death)
+ restore(death=TRUE)
+ else
+ shape.death()
+
+/obj/shapeshift_holder/proc/shapeDeath()
+ //Shape dies.
+ if(source.die_with_shapeshifted_form)
+ if(source.revert_on_death)
+ restore(death=TRUE)
+ else
+ restore()
+
+/obj/shapeshift_holder/proc/restore(death=FALSE)
+ restoring = TRUE
+ qdel(slink)
+ stored.forceMove(get_turf(src))
+ stored.notransform = FALSE
+ if(shape.mind)
+ shape.mind.transfer_to(stored)
+ if(death)
+ stored.death()
+ qdel(shape)
+ qdel(src)
+
+/datum/soullink/shapeshift
+ var/obj/shapeshift_holder/source
+
+/datum/soullink/shapeshift/ownerDies(gibbed, mob/living/owner)
+ if(source)
+ source.casterDeath(gibbed)
+
+/datum/soullink/shapeshift/sharerDies(gibbed, mob/living/sharer)
+ if(source)
+ source.shapeDeath(gibbed)
\ No newline at end of file