diff --git a/code/modules/vore/eating/belly_obj_vr.dm b/code/modules/vore/eating/belly_obj_vr.dm
index ba1d2cd566..2d24b8af80 100644
--- a/code/modules/vore/eating/belly_obj_vr.dm
+++ b/code/modules/vore/eating/belly_obj_vr.dm
@@ -710,10 +710,30 @@
/obj/belly/proc/digestion_death(mob/living/M)
add_attack_logs(owner, M, "Digested in [lowertext(name)]")
+ //CHOMPEdit Start - Reverts TF on death. This fixes a bug with posibrains or similar, and also makes reforming easier.
+ if(M.tf_mob_holder && M.tf_mob_holder.loc == M)
+ M.tf_mob_holder.ckey = M.ckey
+ M.tf_mob_holder.loc = M.loc
+ M.tf_mob_holder.forceMove(M.loc)
+ QDEL_LIST_NULL(M.tf_mob_holder.vore_organs)
+ M.tf_mob_holder.vore_organs = list()
+ for(var/obj/belly/B as anything in M.vore_organs)
+ B.loc = M.tf_mob_holder
+ B.forceMove(M.tf_mob_holder)
+ B.owner = M.tf_mob_holder
+ M.tf_mob_holder.vore_organs |= B
+ M.vore_organs -= B
+
+ if(M.tf_mob_holder)
+ M.tf_mob_holder = null
+ //CHOMPEdit End
+
// If digested prey is also a pred... anyone inside their bellies gets moved up.
if(is_vore_predator(M))
M.release_vore_contents(include_absorbed = TRUE, silent = TRUE)
+ var/hasMMI = FALSE // CHOMPEdit - Adjust how MMI's are handled
+
//Drop all items into the belly.
if(config.items_survive_digestion)
for(var/obj/item/W in M)
@@ -722,6 +742,7 @@
var/obj/item/device/mmi/brainbox = MMI.removed()
if(brainbox)
items_preserved += brainbox
+ hasMMI = brainbox // CHOMPEdit - Adjust how MMI's are handled
for(var/slot in slots)
var/obj/item/I = M.get_equipped_item(slot = slot)
if(I)
@@ -748,10 +769,41 @@
//Incase they have the loop going, let's double check to stop it.
M.stop_sound_channel(CHANNEL_PREYLOOP)
// Delete the digested mob
- var/mob/observer/G = M.ghostize() //CHOMPEdit start. Make sure they're out, so we can copy attack logs and such.
- if(G)
- G.forceMove(src) //CHOMPEdit end.
- qdel(M)
+ //CHOMPEdit start - Changed qdel to a forceMove to allow reforming, and... handled robots special.
+ if(isrobot(M))
+ var/mob/living/silicon/robot/R = M
+ if(R.mmi && R.mind && R.mmi.brainmob)
+ R.mmi.loc = src
+ items_preserved += R.mmi
+ var/obj/item/weapon/robot_module/MB = locate() in R.contents
+ if(MB)
+ R.mmi.brainmob.languages = MB.original_languages
+ else
+ R.mmi.brainmob.languages = R.languages
+ R.mmi.brainmob.remove_language("Robot Talk")
+ hasMMI = R.mmi
+ R.mmi = null
+ else if(!R.shell) // Shells don't have brainmobs in their MMIs.
+ to_chat(R, "Oops! Something went very wrong, your MMI was unable to receive your mind. You have been ghosted. Please make a bug report so we can fix this bug.")
+ if(R.shell) // Let the standard procedure for shells handle this.
+ qdel(R)
+ return
+
+ if(hasMMI)
+ var/obj/item/device/mmi/MMI = hasMMI
+ M.mind.transfer_to(MMI.brainmob)
+ MMI.body_backup = M
+ M.forceMove(MMI)
+ else
+ //Another CHOMPEdit started here. I left the comment here, though obviously we're doing a lot more now as well.
+ var/mob/observer/G = M.ghostize(FALSE) //CHOMPEdit start. Make sure they're out, so we can copy attack logs and such.
+ if(G)
+ G.forceMove(src)
+ G.body_backup = M
+ M.forceMove(G)
+ else
+ qdel(M)
+ //CHOMPEdit End
// Handle a mob being absorbed
/obj/belly/proc/absorb_living(mob/living/M)
diff --git a/code/modules/vore/eating/vorepanel_vr.dm b/code/modules/vore/eating/vorepanel_vr.dm
index e79ddf9b2d..a67d71fe10 100644
--- a/code/modules/vore/eating/vorepanel_vr.dm
+++ b/code/modules/vore/eating/vorepanel_vr.dm
@@ -722,6 +722,10 @@
var/list/available_options = list("Examine", "Eject", "Move", "Transfer")
if(ishuman(target))
available_options += "Transform"
+ //CHOMPEdit Begin - Add Reforming
+ if(isobserver(target) || istype(target,/obj/item/device/mmi))
+ available_options += "Reform"
+ //CHOMPEdit End
intent = tgui_input_list(user, "What would you like to do with [target]?", "Vore Pick", available_options)
switch(intent)
if("Examine")
@@ -803,6 +807,71 @@
V.tgui_interact(user)
return TRUE
+ //CHOMPEdit Begin - Add Reforming
+ if("Reform")
+ if(host.stat)
+ to_chat(user,"You can't do that in your state!")
+ return TRUE
+
+ if(isobserver(target))
+ var/mob/observer/T = target
+ if(!ismob(T.body_backup) || prevent_respawns.Find(T.mind.name))
+ to_chat(user,"They don't seem to be reformable!")
+ return TRUE
+
+ var/accepted = tgui_alert(T, "[host] is trying to reform your body! Would you like to get reformed inside [host]'s [lowertext(host.vore_selected.name)]?", "Reforming Attempt", list("Yes", "No"))
+ if(accepted != "Yes")
+ to_chat(user,"[T] refused to be reformed!")
+ return TRUE
+
+ if(isliving(T.body_backup))
+ var/mob/living/body_backup = T.body_backup
+ body_backup.revive()
+ body_backup.forceMove(T.loc)
+ body_backup.ajourn = 0
+ body_backup.key = T.key
+ body_backup.teleop = null
+ T.body_backup = null
+ host.vore_selected.release_specific_contents(T)
+ announce_ghost_joinleave(T.mind, 0, "They now occupy their body again.")
+ if(istype(target,/obj/item/device/mmi)) // A good bit of repeated code, sure, but... cleanest way to do this.
+ var/obj/item/device/mmi/MMI = target
+ if(!ismob(MMI.body_backup) || !MMI.brainmob.mind || prevent_respawns.Find(MMI.brainmob.mind.name))
+ to_chat(user,"They don't seem to be reformable!")
+ return TRUE
+ var/accepted = tgui_alert(MMI.brainmob, "[host] is trying to reform your body! Would you like to get reformed inside [host]'s [lowertext(host.vore_selected.name)]?", "Reforming Attempt", list("Yes", "No"))
+ if(accepted != "Yes")
+ to_chat(user,"[MMI] refused to be reformed!")
+ return TRUE
+
+ if(isliving(MMI.body_backup))
+ var/mob/living/body_backup = MMI.body_backup
+ body_backup.revive()
+ body_backup.forceMove(MMI.loc)
+ body_backup.ajourn = 0
+ body_backup.teleop = null
+ //And now installing the MMI into the body...
+ if(isrobot(body_backup)) //Just do the reverse of getting the MMI pulled out in /obj/belly/proc/digestion_death
+ var/mob/living/silicon/robot/R = body_backup
+ MMI.brainmob.mind.transfer_to(R)
+ MMI.loc = R
+ R.mmi = MMI
+ R.mmi.brainmob.add_language("Robot Talk")
+ else //reference /datum/surgery_step/robotics/install_mmi/end_step
+ var/obj/item/organ/internal/mmi_holder/holder = new(body_backup, 1)
+ body_backup.internal_organs_by_name["brain"] = holder
+ MMI.loc = holder
+ holder.stored_mmi = MMI
+ holder.update_from_mmi()
+
+ if(MMI.brainmob && MMI.brainmob.mind)
+ MMI.brainmob.mind.transfer_to(body_backup)
+ body_backup.languages = MMI.brainmob.languages
+ //You've hopefully already named yourself, so... not implementing that bit.
+ MMI.body_backup = null
+ return TRUE
+ //CHOMPEdit End
+
/datum/vore_look/proc/set_attr(mob/user, params)
if(!host.vore_selected)
tgui_alert_async(usr, "No belly selected to modify.")
diff --git a/modular_chomp/code/modules/mob/dead/observer/observer.dm b/modular_chomp/code/modules/mob/dead/observer/observer.dm
new file mode 100644
index 0000000000..7928b41556
--- /dev/null
+++ b/modular_chomp/code/modules/mob/dead/observer/observer.dm
@@ -0,0 +1,7 @@
+/mob/observer
+ var/mob/living/body_backup = null //add reforming
+
+/mob/observer/Destroy()
+ if(body_backup)
+ qdel(body_backup)
+ ..()
diff --git a/modular_chomp/code/modules/mob/living/carbon/brain/MMI.dm b/modular_chomp/code/modules/mob/living/carbon/brain/MMI.dm
new file mode 100644
index 0000000000..ae2da9c9d3
--- /dev/null
+++ b/modular_chomp/code/modules/mob/living/carbon/brain/MMI.dm
@@ -0,0 +1,7 @@
+/obj/item/device/mmi
+ var/mob/living/body_backup = null //add reforming
+
+/obj/item/device/mmi/Destroy()
+ if(body_backup)
+ qdel(body_backup)
+ ..()
diff --git a/vorestation.dme b/vorestation.dme
index a78e7b7db3..85ed3bef56 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -4501,7 +4501,9 @@
#include "modular_chomp\code\modules\emotes\definitions\audiable.dm"
#include "modular_chomp\code\modules\mob\holder.dm"
#include "modular_chomp\code\modules\mob\mob.dm"
+#include "modular_chomp\code\modules\mob\dead\observer\observer.dm"
#include "modular_chomp\code\modules\mob\living\emote.dm"
+#include "modular_chomp\code\modules\mob\living\carbon\brain\MMI.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\species.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\_protean_defines.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\protean_blob.dm"