diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 399da8d0ca..04a6cb04b4 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -269,7 +269,7 @@
ghost.assumeform(src)
ghost.animate_towards(user)
//VORESTATION EDIT START. This handles possessed items.
- if(src.possessed_voice && src.possessed_voice.len && !(user.ckey in warned_of_possession)) //Is this item possessed?
+ if(src.possessed_voice && src.possessed_voice.len > 1 && !(user.ckey in warned_of_possession)) // CHOMPEdit Is this item possessed?
warned_of_possession |= user.ckey
tgui_alert_async(user,{"
THIS ITEM IS POSSESSED BY A PLAYER CURRENTLY IN THE ROUND. This could be by anomalous means or otherwise.
diff --git a/code/game/objects/items/contraband_vr.dm b/code/game/objects/items/contraband_vr.dm
index 804dd4b554..4b2bd64630 100644
--- a/code/game/objects/items/contraband_vr.dm
+++ b/code/game/objects/items/contraband_vr.dm
@@ -46,6 +46,7 @@
/obj/item/weapon/circuitboard/mecha/phazon/peripherals,
/obj/item/weapon/circuitboard/mecha/phazon/main,
/obj/item/device/bodysnatcher,
+ /obj/item/device/mindbinder, //CHOMPAdd
/obj/item/weapon/bluespace_harpoon,
/obj/item/clothing/accessory/permit/gun,
/obj/item/device/perfect_tele,
diff --git a/code/game/objects/items/devices/scanners/sleevemate.dm b/code/game/objects/items/devices/scanners/sleevemate.dm
index 0109335b0d..2ebb517f24 100644
--- a/code/game/objects/items/devices/scanners/sleevemate.dm
+++ b/code/game/objects/items/devices/scanners/sleevemate.dm
@@ -311,6 +311,11 @@ var/global/mob/living/carbon/human/dummy/mannequin/sleevemate_mob
icon_state = initial(icon_state)
/obj/item/device/sleevemate/emag_act(var/remaining_charges, var/mob/user)
+ //CHOMPEdit Start
+ var/list/choices = list("Body Snatcher","Mind Binder")
+ var/choice = tgui_input_list(user, "How would you like to modify the [src]?", "", choices)
+ if(!choice || !(choice in choices)) return
+ //CHOMPEdit End
to_chat(user,"You hack [src]!")
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src.loc)
@@ -320,6 +325,11 @@ var/global/mob/living/carbon/human/dummy/mannequin/sleevemate_mob
var/mob/living/L = src.loc
L.unEquip(src)
src.forceMove(get_turf(src))
- new /obj/item/device/bodysnatcher(src.loc)
+ //CHOMPEdit Start
+ if(choice == "Body Snatcher")
+ new /obj/item/device/bodysnatcher(src.loc)
+ if(choice == "Mind Binder")
+ new /obj/item/device/mindbinder(src.loc)
+ //CHOMPEdit End
qdel(src)
return 1
diff --git a/code/game/objects/items_vr.dm b/code/game/objects/items_vr.dm
index 026e346695..e1be13f59d 100644
--- a/code/game/objects/items_vr.dm
+++ b/code/game/objects/items_vr.dm
@@ -26,6 +26,12 @@
new_voice.verbs -= /mob/living/voice/verb/change_name //No changing your name! Bad!
new_voice.verbs -= /mob/living/voice/verb/hang_up //Also you can't hang up. You are the item!
src.item_tf_spawnpoint_used() //CHOMPEdit - Item TF spawnpoints
+ //CHOMPEdit Start - Let the inhabitor know what happened to them
+ if(istype(src, /obj/item/device/mindbinder))
+ to_chat(new_voice,"Your mind has been stored in [src]!")
+ else
+ to_chat(new_voice,"You have become [src]!")
+ //CHOMPEdit End
// Chomp edit
/obj/item/proc/muffled_by_belly(var/mob/user)
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index c36782c069..f2ed3d61af 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -39,6 +39,16 @@
m.visible_message("\The [m] tumbles out of \the [src]!")
//VOREStation Add End
+ //CHOMPAdd Start possessed item cleanup
+ if(istype(src, /obj/item))
+ var/obj/item/I = src
+ if(I.possessed_voice && I.possessed_voice.len)
+ for(var/mob/living/voice/V in I.possessed_voice)
+ if(!V.tf_mob_holder)
+ V.ghostize(0)
+ V.Destroy()
+ //CHOMPAdd End
+
return ..()
/obj/Topic(href, href_list, var/datum/tgui_state/state = GLOB.tgui_default_state)
diff --git a/code/game/objects/structures/trash_pile_vr.dm b/code/game/objects/structures/trash_pile_vr.dm
index a5ce39e8ea..2d786724d8 100644
--- a/code/game/objects/structures/trash_pile_vr.dm
+++ b/code/game/objects/structures/trash_pile_vr.dm
@@ -310,6 +310,7 @@
prob(1);/obj/item/device/radio_jammer,
prob(1);/obj/item/device/sleevemate,
prob(1);/obj/item/device/bodysnatcher,
+ prob(1);/obj/item/device/mindbinder, //CHOMPAdd
prob(1);/obj/item/weapon/beartrap,
prob(1);/obj/item/weapon/cell/hyper/empty,
prob(1);/obj/item/weapon/disk/nifsoft/compliance,
diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm
index 629e1a2695..728516a834 100644
--- a/code/modules/organs/internal/brain.dm
+++ b/code/modules/organs/internal/brain.dm
@@ -139,7 +139,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain)
var/obj/item/organ/internal/brain/B = src
if(istype(B) && owner)
- if(istype(owner, /mob/living/carbon))
+ if(istype(owner, /mob/living/carbon) && owner.ckey) //CHOMPEdit - Make sure owner's mind isn't elsewhere otherwise on brain removal brings them back
B.transfer_identity(owner)
..()
diff --git a/code/modules/vore/eating/belly_obj_ch.dm b/code/modules/vore/eating/belly_obj_ch.dm
index 5e767363b4..37368b5a3a 100644
--- a/code/modules/vore/eating/belly_obj_ch.dm
+++ b/code/modules/vore/eating/belly_obj_ch.dm
@@ -579,8 +579,22 @@
D.matter[mat] += modified_mats[mat]
if(O.w_class > D.w_class)
D.w_class = O.w_class
+ //CHOMPAdd Start
+ if(O.possessed_voice && O.possessed_voice.len)
+ for(var/mob/living/voice/V in O.possessed_voice)
+ D.inhabit_item(V, null, V.tf_mob_holder)
+ V.Destroy()
+ O.possessed_voice = list()
+ //CHOMPAdd End
return TRUE
- new /obj/item/debris_pack/digested(src, modified_mats)
+ var/obj/item/debris_pack/digested/D = new /obj/item/debris_pack/digested(src, modified_mats) //CHOMPEdit
+ //CHOMPAdd Start
+ if(O.possessed_voice && O.possessed_voice.len)
+ for(var/mob/living/voice/V in O.possessed_voice)
+ D.inhabit_item(V, null, V.tf_mob_holder)
+ V.Destroy()
+ O.possessed_voice = list()
+ //CHOMPAdd End
return TRUE
/obj/belly/proc/owner_adjust_nutrition(var/amount = 0)
diff --git a/code/modules/vore/eating/digest_act_vr.dm b/code/modules/vore/eating/digest_act_vr.dm
index aec9e74e0d..2948098d1e 100644
--- a/code/modules/vore/eating/digest_act_vr.dm
+++ b/code/modules/vore/eating/digest_act_vr.dm
@@ -13,6 +13,7 @@
P.id = null
for(var/mob/living/voice/V in possessed_voice) // Delete voices.
+ V.ghostize(0) //CHOMPAdd - Prevent Reenter Corpse sending observers to the shadow realm
V.Destroy() //Destroy the voice.
for(var/mob/living/M in contents)//Drop mobs from objects(shoes) before deletion
M.forceMove(item_storage)
@@ -76,8 +77,10 @@
var/obj/item/device/pda/P = src
if(P.id)
P.id = null
+ /* CHOMPEdit Start - This is handled lower down now
for(var/mob/living/voice/V in possessed_voice) // Delete voices.
V.Destroy() //Destroy the voice.
+ CHOMPEdit End */
for(var/mob/living/M in contents)//Drop mobs from objects(shoes) before deletion
if(item_storage)
M.forceMove(item_storage)
@@ -107,7 +110,14 @@
else
soundfile = pick('sound/vore/shortgurgles/gurgle_S1.ogg', 'sound/vore/shortgurgles/gurgle_S2.ogg', 'sound/vore/shortgurgles/gurgle_S3.ogg')
playsound(src, soundfile, vol = g_sound_volume, vary = 1, falloff = VORE_SOUND_FALLOFF, frequency = noise_freq, preference = /datum/client_preference/eating_noises, volume_channel = VOLUME_CHANNEL_VORE) //CHOMPEdit
- if(istype(B) && B.recycle(src))
+ //CHOMPEdit Start - Allow those turned into items to become the recycled item
+ var/recycled = B.recycle(src)
+ if(!recycled)
+ for(var/mob/living/voice/V in possessed_voice) // Delete voices.
+ V.ghostize(0) //CHOMPAdd - Prevent Reenter Corpse sending observers to the shadow realm
+ V.Destroy() //Destroy the voice.
+ if(istype(B) && recycled)
+ //CHOMPEdit End
g_damage = w_class / 2
if(B.item_digest_logs)
to_chat(B.owner,"[src] was digested inside your [lowertext(B.name)].")
diff --git a/code/modules/vore/resizing/holder_vr.dm b/code/modules/vore/resizing/holder_vr.dm
index 076b2830b9..a32d4f37f6 100644
--- a/code/modules/vore/resizing/holder_vr.dm
+++ b/code/modules/vore/resizing/holder_vr.dm
@@ -48,7 +48,7 @@
dropInto(user.drop_location())
dropped(user)
//VORESTATION EDIT START. This handles possessed items.
- if(src.possessed_voice && src.possessed_voice.len && !(user.ckey in warned_of_possession)) //Is this item possessed?
+ if(src.possessed_voice && src.possessed_voice.len > 1 && !(user.ckey in warned_of_possession)) // CHOMPEdit Is this item possessed?
warned_of_possession |= user.ckey
tgui_alert_async(user,{"
THIS ITEM IS POSSESSED BY A PLAYER CURRENTLY IN THE ROUND. This could be by anomalous means or otherwise.
diff --git a/modular_chomp/code/game/objects/items/devices/mind_binder.dm b/modular_chomp/code/game/objects/items/devices/mind_binder.dm
new file mode 100644
index 0000000000..66260b134c
--- /dev/null
+++ b/modular_chomp/code/game/objects/items/devices/mind_binder.dm
@@ -0,0 +1,178 @@
+// Another illegal hack of the sleevemate similar to the Body Snatcher. This one lets you store and bind minds to items.
+/obj/item/device/mindbinder
+ name = "\improper Mind Binder"
+ desc = "An extremely illegal tool modified from a SleeveMate. It allows the storing and transfer of minds, but can bind them to objects instead of just humanoids."
+ icon = 'icons/obj/device_alt.dmi'
+ icon_state = "sleevemate"
+ item_state = "healthanalyzer"
+ slot_flags = SLOT_BELT
+ w_class = ITEMSIZE_SMALL
+ matter = list(MAT_STEEL = 200)
+ origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2, TECH_ILLEGAL = 1)
+ possessed_voice = list()
+ var/self_bind = FALSE
+
+/obj/item/device/mindbinder/New()
+ ..()
+ flags |= NOBLUDGEON //So borgs don't spark.
+
+/obj/item/device/mindbinder/attack(mob/living/M, mob/living/user)
+ usr.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
+ return
+
+/obj/item/device/mindbinder/attack_self(mob/living/user)
+ return
+
+/obj/item/device/mindbinder/proc/toggle_self_bind()
+ if(possessed_voice.len == 1)
+ to_chat(usr,"The device beeps a warning that there is already a mind loaded!")
+ return
+ self_bind = !self_bind
+ if(self_bind)
+ to_chat(usr,"You prepare the device to use your own mind!")
+ else
+ to_chat(usr,"You disable the device from using your mind.")
+ update_icon()
+
+/obj/item/device/mindbinder/pre_attack(atom/A)
+ if(istype(A, /mob/living))
+ var/mob/living/M = A
+ if(usr == M)
+ toggle_self_bind()
+ return
+ if(possessed_voice.len == 1 || self_bind)
+ bind_mob(M)
+ else
+ store_mob(M)
+ return
+ if(istype(A, /obj/item))
+ var/obj/item/I = A
+ if(istype(I, /obj/item/weapon/holder/micro))
+ var/obj/item/weapon/holder/micro/H = I
+ if(possessed_voice.len == 1 || self_bind)
+ bind_mob(H.held_mob)
+ else
+ store_mob(H.held_mob)
+ return
+ if(possessed_voice.len == 1 || self_bind)
+ bind_item(I)
+ else
+ store_item(I)
+ return
+ return
+
+// Handle placing a mind into a mob
+/obj/item/device/mindbinder/proc/bind_mob(mob/living/target)
+ if(possessed_voice.len == 0 && !self_bind)
+ to_chat(usr,"The device beeps a warning that it doesn't contain a mind to bind!")
+ return
+
+ if(target.ckey)
+ to_chat(usr,"The device beeps a warning that the target is already sentient!")
+ return
+
+ if(self_bind)
+ var/choice = tgui_alert(usr,"This will bind YOUR mind to the target! You may not be able to go back without help. Continue?","Confirmation",list("Continue","Cancel"))
+ if(choice == "Cancel") return
+ choice = tgui_alert(usr,"No really. You cannot OOC Escape this. Are you sure?","Confirmation",list("Yes I'm sure","Cancel"))
+ if(choice == "Yes I'm sure" && usr.get_active_hand() == src && usr.Adjacent(target))
+ usr.visible_message("[usr] presses [src] against [target]. The device beginning to let out a series of beeps!","You begin to bind yourself into [target]!")
+ if(do_after(usr,30 SECONDS,target))
+ if(!target.ckey)
+ usr.mind.transfer_to(target)
+ self_bind = !self_bind
+ update_icon()
+ to_chat(usr,"Your mind as been bound to [target].")
+ return
+
+ usr.visible_message("[usr] presses [src] against [target]. The device beginning to let out a series of beeps!","You begin to bind someone's mind into [target]!")
+ if(do_after(usr,5 SECONDS,target))
+ if(possessed_voice.len == 1 && !target.ckey)
+ var/mob/living/voice/V = possessed_voice[1]
+ V.mind.transfer_to(target)
+ V.Destroy()
+ possessed_voice = list()
+ to_chat(usr,"Mind bound to [target].")
+
+ update_icon()
+
+// Handle placing a mind into an item
+/obj/item/device/mindbinder/proc/bind_item(obj/item/item)
+ if(possessed_voice.len == 0 && !self_bind)
+ to_chat(usr,"The device beeps a warning that it doesn't contain a mind to bind!")
+ return
+
+ if(item.possessed_voice && item.possessed_voice.len)
+ to_chat(usr,"The device beeps a warning that the target is already sentient!")
+ return
+
+ if(self_bind)
+ var/choice = tgui_alert(usr,"This will bind YOUR mind to the target! You will not be able to go back without help. Continue?","Confirmation",list("Continue","Cancel"))
+ if(choice == "Cancel") return
+ choice = tgui_alert(usr,"No really. You cannot OOC Escape this. Are you sure?","Confirmation",list("Yes I'm sure","Cancel"))
+ if(choice == "Yes I'm sure" && usr.get_active_hand() == src && usr.Adjacent(item))
+ usr.visible_message("[usr] presses [src] against [item]. The device beginning to let out a series of beeps!","You begin to bind yourself into [item]!")
+ if(do_after(usr,30 SECONDS,item))
+ item.inhabit_item(usr, null, null)
+ self_bind = !self_bind
+ update_icon()
+ to_chat(usr,"Your mind as been bound to [item].")
+ return
+
+ usr.visible_message("[usr] presses [src] against [item]. The device beginning to let out a series of beeps!","You begin to bind someone's mind into [item]!")
+ if(do_after(usr,5 SECONDS,item))
+ if(possessed_voice.len == 1)
+ var/mob/living/voice/V = possessed_voice[1]
+ item.inhabit_item(V, null, V.tf_mob_holder)
+ V.Destroy()
+ possessed_voice = list()
+ to_chat(usr,"Mind bound to [item].")
+
+ update_icon()
+
+// Handle taking a mind out of a mob
+/obj/item/device/mindbinder/proc/store_mob(mob/living/target)
+ if(possessed_voice.len != 0)
+ to_chat(usr,"The device beeps a warning that there is already a mind loaded!")
+ return
+
+ if(!target.mind || (target.mind.name in prevent_respawns))
+ to_chat(usr,"The device beeps a warning that the target isn't sentient.")
+ return
+
+ var/choice = tgui_alert(usr,"This will download the target's mind into the device. Once their mind is loaded you can then bind it into an item. This will result in the target being stuck until you put them back in their original body. Please make sure OOC prefs align! Continue?","Confirmation",list("Continue","Cancel"))
+ if(choice == "Continue" && usr.get_active_hand() == src && usr.Adjacent(target))
+ usr.visible_message("[usr] presses [src] against [target]'s head. The device beginning to let out a series of beeps!","You begin to download [target]'s mind!")
+ if(do_after(usr,30 SECONDS,target))
+ if(possessed_voice.len == 0 && target.mind)
+ inhabit_item(target, target.real_name, null)
+ to_chat(usr,"Mind successfully stored!")
+
+ update_icon()
+
+// Handle taking a mind out of an item
+/obj/item/device/mindbinder/proc/store_item(obj/item/item)
+ if(possessed_voice.len != 0)
+ to_chat(usr,"The device beeps a warning that there is already a mind loaded!")
+ return
+
+ if(!(item.possessed_voice && item.possessed_voice.len))
+ return
+
+ var/mob/living/voice/target = item.possessed_voice[1]
+
+ usr.visible_message("[usr] presses [src] against [item]. The device beginning to let out a series of beeps!","You begin to download someone's mind from [item]!")
+ if(do_after(usr,5 SECONDS,item))
+ if(possessed_voice.len == 0 && item.possessed_voice.Find(target))
+ inhabit_item(target, target.real_name, target.tf_mob_holder)
+ target.Destroy()
+ item.possessed_voice.Remove(target)
+ to_chat(usr,"Mind successfully stored!")
+
+ update_icon()
+
+/obj/item/device/mindbinder/update_icon()
+ if((possessed_voice && possessed_voice.len > 0) || self_bind)
+ icon_state = "[initial(icon_state)]_on"
+ else
+ icon_state = initial(icon_state)
diff --git a/modular_chomp/code/modules/research/designs/misc.dm b/modular_chomp/code/modules/research/designs/misc.dm
index 9286404bbd..1725f79dd1 100644
--- a/modular_chomp/code/modules/research/designs/misc.dm
+++ b/modular_chomp/code/modules/research/designs/misc.dm
@@ -5,4 +5,12 @@
req_tech = list(TECH_MATERIAL = 2)
materials = list(MAT_STEEL = 5000)
build_path = /obj/item/trash/rkibble
- sort_string = "KIBBB"
\ No newline at end of file
+ sort_string = "KIBBB"
+
+/datum/design/item/general/mindbinder
+ name = "Mind Binder"
+ id = "mindbinder"
+ req_tech = list(TECH_MAGNET = 3, TECH_BIO = 3, TECH_ILLEGAL = 2)
+ materials = list(MAT_STEEL = 4000, MAT_GLASS = 4000, MAT_URANIUM = 2000)
+ build_path = /obj/item/device/mindbinder
+ sort_string = "TBVAB"
diff --git a/vorestation.dme b/vorestation.dme
index 9660581002..31e24f470a 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -4653,6 +4653,7 @@
#include "modular_chomp\code\game\objects\items\petrifier.dm"
#include "modular_chomp\code\game\objects\items\clockwork\ratvarian_spear.dm"
#include "modular_chomp\code\game\objects\items\devices\flipper.dm"
+#include "modular_chomp\code\game\objects\items\devices\mind_binder.dm"
#include "modular_chomp\code\game\objects\items\devices\vacpack.dm"
#include "modular_chomp\code\game\objects\items\devices\radio\headset.dm"
#include "modular_chomp\code\game\objects\items\weapons\capture_crystal.dm"