[MIRROR] Panel port test [IDB IGNORE] (#10447)

Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-03-17 00:05:24 +01:00
committed by GitHub
co-authored by Kashargul
parent 2439279209
commit 2f698760c7
389 changed files with 4764 additions and 9001 deletions
-21
View File
@@ -1,19 +1,6 @@
/obj/item
var/item_tf_spawn_allowed = FALSE
var/list/ckeys_allowed_itemspawn = list()
var/user_vars_to_edit //fun times :3 - pretty much just grabbed from tg immabehonest - list(variable_name = variable_value) eg list("name" = "Wizardly Wizard", "real_name" = "Wizardly Wizard")
var/user_vars_remembered //not needed for manual editing, just stores the original vars from the above list to make sure they go back to normal later
var/digestable = TRUE
/obj/item/proc/item_tf_spawnpoint_set()
if(!item_tf_spawn_allowed)
item_tf_spawn_allowed = TRUE
item_tf_spawnpoints += src
/obj/item/proc/item_tf_spawnpoint_used()
if(item_tf_spawn_allowed)
item_tf_spawn_allowed = FALSE
item_tf_spawnpoints -= src
/obj/item/Destroy(force, ...)
if(item_tf_spawn_allowed)
@@ -49,11 +36,3 @@
if(user.vars[variable] == user_vars_to_edit[variable])
user.vars[variable] = user_vars_remembered[variable]
user_vars_remembered = initial(user_vars_remembered)
/obj/item/verb/toggle_digestable()
set category = "Object"
set name = "Toggle Digestable"
set desc = "Toggle item's digestability."
digestable = !digestable
if(!digestable)
to_chat(usr, span_notice("[src] is now protected from digestion."))
@@ -1,231 +0,0 @@
/obj/item/capture_crystal
var/spawn_mob_name = "A mob"
var/obj/belly/in_gut = null
/* No longer need the vorefx additions as these will be handled for all indirect viewers now, including those in capture crystals
// Signals detect important procs from the host belly. Necessary to update visuals and sound loop for the player inside.
/obj/item/capture_crystal/enter_belly(obj/belly/B)
if(isbelly(B)) // Sanity
in_gut = B
RegisterSignal(in_gut, COMSIG_PARENT_QDELETING, PROC_REF(gut_was_deleted), TRUE)
RegisterSignal(in_gut, COMSIG_BELLY_UPDATE_VORE_FX, PROC_REF(capture_crystal_vfx), TRUE)
RegisterSignal(in_gut, COMSIG_BELLY_UPDATE_PREY_LOOP, PROC_REF(capture_crystal_prey_loop), TRUE)
var/juice = in_gut.reagents.total_volume
if(!juice)
juice = 0
capture_crystal_vfx(null, TRUE, juice)
capture_crystal_prey_loop()
for(var/mob/living/contained in src.contents) // For reasons I don't understand, using bound_mob here sets bound_mob to null.
var/formatted_desc
formatted_desc = replacetext(in_gut.desc, "%belly", lowertext(in_gut.name)) //replace with this belly's name
formatted_desc = replacetext(formatted_desc, "%pred", in_gut.owner) //replace with this belly's owner
formatted_desc = replacetext(formatted_desc, "%prey", contained) //replace with whatever mob entered into this belly
to_chat(contained, span_boldnotice("[formatted_desc]"))
/obj/item/capture_crystal/exit_belly()
for(var/mob/living/contained in src.contents)
contained.clear_fullscreen(ATOM_BELLY_FULLSCREEN) // Clear fullscreens.
contained.stop_sound_channel(CHANNEL_PREYLOOP) // Clear sound loop.
contained.next_preyloop = world.time
if(isbelly(in_gut)) // Sanity
UnregisterSignal(in_gut, COMSIG_PARENT_QDELETING)
UnregisterSignal(in_gut, COMSIG_BELLY_UPDATE_VORE_FX)
UnregisterSignal(in_gut, COMSIG_BELLY_UPDATE_PREY_LOOP)
in_gut = null
// Inelegant copy-pasta since I can't steal the proc from bellies.
/obj/item/capture_crystal/proc/capture_crystal_vfx(var/update, var/severity = 0)
if(isbelly(in_gut))
for(var/mob/living/contained in src.contents) // I guess this works if multi-catch crystals ever become a thing.
if(!contained.client)
return
if(!contained.show_vore_fx)
contained.clear_fullscreen(ATOM_BELLY_FULLSCREEN)
return
if(update)
contained.clear_fullscreen(ATOM_BELLY_FULLSCREEN)
if(in_gut.belly_fullscreen)
if(in_gut.colorization_enabled)
var/obj/screen/fullscreen/F = contained.overlay_fullscreen(ATOM_BELLY_FULLSCREEN, /obj/screen/fullscreen/belly, severity) //CHOMPEdit Start: preserving save data
F.icon = file("modular_chomp/icons/mob/vore_fullscreens/[in_gut.belly_fullscreen].dmi")
F.cut_overlays()
var/image/I = image(F.icon, in_gut.belly_fullscreen) //Would be cool if I could just include color and alpha in the image define so we don't have to copy paste
I.color = in_gut.belly_fullscreen_color
I.alpha = in_gut.belly_fullscreen_alpha
F.add_overlay(I)
I = image(F.icon, in_gut.belly_fullscreen+"-2")
I.color = in_gut.belly_fullscreen_color2
I.alpha = in_gut.belly_fullscreen_alpha
F.add_overlay(I)
I = image(F.icon, in_gut.belly_fullscreen+"-3")
I.color = in_gut.belly_fullscreen_color3
I.alpha = in_gut.belly_fullscreen_alpha
F.add_overlay(I)
I = image(F.icon, in_gut.belly_fullscreen+"-4")
I.color = in_gut.belly_fullscreen_color4
I.alpha = in_gut.belly_fullscreen_alpha
F.add_overlay(I)
if(contained.liquidbelly_visuals && in_gut.reagents.total_volume)
if(in_gut.digest_mode == DM_HOLD && in_gut.item_digest_mode == IM_HOLD)
I = image('modular_chomp/icons/mob/vore_fullscreens/bubbles.dmi', "calm")
else
I = image('modular_chomp/icons/mob/vore_fullscreens/bubbles.dmi', "bubbles")
I.color = in_gut.reagentcolor
I.alpha = max(150, min(in_gut.custom_max_volume, 255)) - (255 - in_gut.belly_fullscreen_alpha)
I.pixel_y = -450 + (450 / in_gut.custom_max_volume * in_gut.reagents.total_volume)
F.add_overlay(I)
F.update_for_view(contained.client.view)
else
var/obj/screen/fullscreen/F = contained.overlay_fullscreen(ATOM_BELLY_FULLSCREEN, /obj/screen/fullscreen/belly/fixed, severity) //preserving save data
F.icon = file("modular_chomp/icons/mob/vore_fullscreens/[in_gut.belly_fullscreen].dmi")
F.cut_overlays()
F.add_overlay(image(F.icon, in_gut.belly_fullscreen))
F.add_overlay(image(F.icon, in_gut.belly_fullscreen+"-2"))
F.add_overlay(image(F.icon, in_gut.belly_fullscreen+"-3"))
F.add_overlay(image(F.icon, in_gut.belly_fullscreen+"-4"))
if(contained.liquidbelly_visuals && in_gut.reagents.total_volume)
var/image/I
if(in_gut.digest_mode == DM_HOLD && in_gut.item_digest_mode == IM_HOLD)
I = image('modular_chomp/icons/mob/vore_fullscreens/bubbles.dmi', "calm")
else
I = image('modular_chomp/icons/mob/vore_fullscreens/bubbles.dmi', "bubbles")
I.color = in_gut.reagentcolor
I.alpha = max(150, min(in_gut.custom_max_volume, 255)) - (255 - in_gut.belly_fullscreen_alpha)
I.pixel_y = -450 + (450 / in_gut.custom_max_volume * in_gut.reagents.total_volume)
F.add_overlay(I)
F.update_for_view(contained.client.view)
else
contained.clear_fullscreen(ATOM_BELLY_FULLSCREEN)
/* // Disabled (and untested) for now, left to make it easier if we want to enable this later.
if(in_gut.disable_hud)
if(contained?.hud_used?.hud_shown)
to_chat(contained, span_notice("((Your pred has disabled huds in their belly. Turn off vore FX and hit F12 to get it back; or relax, and enjoy the serenity.))"))
contained.toggle_hud_vis(TRUE) */
// Inelegant copy-pasta since I can't steal the proc from bellies.
/obj/item/capture_crystal/proc/capture_crystal_prey_loop()
if(isbelly(in_gut))
for(var/mob/living/contained in src.contents) // Skip empty crystals.
//We don't bother executing any other code if the prey doesn't want to hear the noises.
if(!contained.is_preference_enabled(/datum/client_preference/digestion_noises))
contained.stop_sound_channel(CHANNEL_PREYLOOP) // sanity just in case, because byond is whack and you can't trust it
continue
// We don't want the sounds to overlap, but we do want them to steadily replay.
// We also don't want the sounds to play if the pred hasn't marked this belly as fleshy, or doesn't
// have the right sounds to play.
if(in_gut.is_wet && in_gut.wet_loop && (world.time > contained.next_preyloop))
contained.stop_sound_channel(CHANNEL_PREYLOOP)
var/sound/preyloop = sound('sound/vore/sunesound/prey/loop.ogg')
contained.playsound_local(get_turf(src), preyloop, 80, 0, channel = CHANNEL_PREYLOOP)
contained.next_preyloop = (world.time + (52 SECONDS))
//Cleanup signals if we're in a gut and it gets deleted.
/obj/item/capture_crystal/proc/gut_was_deleted()
UnregisterSignal(in_gut, COMSIG_PARENT_QDELETING)
UnregisterSignal(in_gut, COMSIG_BELLY_UPDATE_VORE_FX)
UnregisterSignal(in_gut, COMSIG_BELLY_UPDATE_PREY_LOOP)
in_gut = null
*/
/obj/item/capture_crystal/loadout
active = TRUE
/obj/item/capture_crystal/loadout/attack(mob/living/M, mob/living/user)
if(!bound_mob && M != user)
to_chat(user, span_notice("\The [src] emits an unpleasant tone..."))
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
return
. = ..()
/obj/item/capture_crystal/loadout/attack_self(mob/living/user)
if(!bound_mob)
to_chat(user, span_notice("\The [src] emits an unpleasant tone... It is not ready yet."))
playsound(src, 'sound/effects/capture-crystal-problem.ogg', 75, 1, -1)
return
. = ..()
/obj/item/capture_crystal/loadout/capture_chance()
return 0
/obj/item/capture_crystal/cheap
name = "cheap capture crystal"
desc = "A silent, unassuming crystal in what appears to be some kind of steel housing. This one seems to be cheaply made and can only handle a willing mind."
icon = 'icons/obj/capture_crystal_vr.dmi'
//The basic capture command does most of the registration work.
/obj/item/capture_crystal/cheap/capture(mob/living/M, mob/living/U)
if(!M.capture_crystal || M.capture_caught)
to_chat(U, span_warning("This creature is not suitable for capture with this crystal."))
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
return
knowyoursignals(M, U)
if(isanimal(M) || !M.client)
to_chat(U, span_warning("This creature is not suitable for capture."))
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
return
owner = U
if(!bound_mob)
bound_mob = M
bound_mob.capture_caught = TRUE
persist_storable = FALSE
desc = "A silent, unassuming crystal in what appears to be some kind of steel housing. This one seems to be cheaply made and can only handle a willing mind."
/obj/item/capture_crystal/cheap/activate(mob/living/user, target)
if(!cooldown_check()) //Are we ready to do things yet?
to_chat(thrower, span_notice("\The [src] clicks unsatisfyingly... It is not ready yet."))
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
return
if(spawn_mob_type && !bound_mob) //We don't already have a mob, but we know what kind of mob we want
bound_mob = new spawn_mob_type(src) //Well let's spawn it then!
bound_mob.faction = user.faction
spawn_mob_type = null
capture(bound_mob, user)
if(bound_mob) //We have a mob! Let's finish setting up.
user.visible_message("\The [src] clicks, and then emits a small chime.", "\The [src] grows warm in your hand, something inside is awake.")
active = TRUE
if(!owner) //Do we have an owner? It's pretty unlikely that this would ever happen! But it happens, let's claim the crystal.
owner = user
if(isanimal(bound_mob))
var/mob/living/simple_mob/S = bound_mob
S.revivedby = user.name
determine_action(user, target)
return
else if(isliving(target)) //So we don't have a mob, let's try to claim one! Is the target a mob?
var/mob/living/M = target
last_activate = world.time
if(M.capture_caught) //Can't capture things that were already caught.
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
to_chat(user, span_notice("\The [src] clicks unsatisfyingly... \The [M] is already under someone else's control."))
return
else if(M.stat == DEAD) //Is it dead? We can't influence dead things.
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
to_chat(user, span_notice("\The [src] clicks unsatisfyingly... \The [M] is not in a state to be captured."))
return
else if(M.client) //Is it player controlled?
capture_player(M, user) //We have to do things a little differently if so.
return
else if(!isanimal(M)) //So it's not player controlled, but it's also not a simplemob?
to_chat(user, span_warning("This creature is not suitable for capture."))
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
return
var/mob/living/simple_mob/S = M
if(!S.ai_holder) //We don't really want to capture simplemobs that don't have an AI
to_chat(user, span_warning("This creature is not suitable for capture."))
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
else //Shoot, it didn't work and now it's mad!!!
S.ai_holder.go_wake()
S.ai_holder.give_target(user, urgent = TRUE)
user.visible_message("\The [src] bonks into \the [S], angering it!")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
to_chat(user, span_notice("\The [src] clicks unsatisfyingly."))
update_icon()
return
//The target is not a mob, so let's not do anything.
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
to_chat(user, span_notice("\The [src] clicks unsatisfyingly."))
@@ -209,6 +209,8 @@
/mob/living/simple_mob/vore/aggressive/corrupthound/muffinmonster/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "waste hopper"
@@ -1,267 +0,0 @@
/datum/belly_overlays
var/belly_icon
/datum/belly_overlays/vbo_belly1
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_belly1.dmi'
/datum/belly_overlays/vbo_belly2
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_belly2.dmi'
/datum/belly_overlays/vbo_belly3
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_belly3.dmi'
/datum/belly_overlays/vbo_belly4
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_belly4.dmi'
/datum/belly_overlays/vbo_belly5
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_belly5.dmi'
/datum/belly_overlays/vbo_belly6
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_belly6.dmi'
/datum/belly_overlays/vbo_belly7
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_belly7.dmi'
/datum/belly_overlays/vbo_belly8
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_belly8.dmi'
/datum/belly_overlays/vbo_belly9
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_belly9.dmi'
/datum/belly_overlays/vbo_breast
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_breast.dmi'
/datum/belly_overlays/vbo_breast1
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_breast1.dmi'
/datum/belly_overlays/vbo_coils
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_coils.dmi'
/datum/belly_overlays/vbo_coils1
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_coils1.dmi'
/datum/belly_overlays/vbo_darkslit
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_darkslit.dmi'
/datum/belly_overlays/vbo_fleshs
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_fleshs.dmi'
/datum/belly_overlays/vbo_fleshs1
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_fleshs1.dmi'
/datum/belly_overlays/vbo_foot
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_foot.dmi'
/datum/belly_overlays/vbo_gematically_angular
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_gematically_angular.dmi'
/datum/belly_overlays/vbo_intestines1
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_intestines1.dmi'
/datum/belly_overlays/vbo_intestines2
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_intestines2.dmi'
/datum/belly_overlays/vbo_intestines3
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_intestines3.dmi'
/datum/belly_overlays/vbo_intestines4
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_intestines4.dmi'
/datum/belly_overlays/vbo_intestines5
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_intestines5.dmi'
/datum/belly_overlays/vbo_intestines6
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_intestines6.dmi'
/datum/belly_overlays/vbo_intestines7
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_intestines7.dmi'
/datum/belly_overlays/vbo_intestines8
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_intestines8.dmi'
/datum/belly_overlays/vbo_intestines9
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_intestines9.dmi'
/datum/belly_overlays/vbo_maw1
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw1.dmi'
/datum/belly_overlays/vbo_maw2
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw2.dmi'
/datum/belly_overlays/vbo_maw3
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw3.dmi'
/datum/belly_overlays/vbo_maw4
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw4.dmi'
/datum/belly_overlays/vbo_maw5
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw5.dmi'
/datum/belly_overlays/vbo_maw6
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw6.dmi'
/datum/belly_overlays/vbo_maw7
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw7.dmi'
/datum/belly_overlays/vbo_maw8
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw8.dmi'
/datum/belly_overlays/vbo_maw9
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw9.dmi'
/datum/belly_overlays/vbo_maw10
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw10.dmi'
/datum/belly_overlays/vbo_maw11
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw11.dmi'
/datum/belly_overlays/vbo_maw12
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw12.dmi'
/datum/belly_overlays/vbo_maw13
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw13.dmi'
/datum/belly_overlays/vbo_maw14
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw14.dmi'
/datum/belly_overlays/vbo_maw15
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw15.dmi'
/datum/belly_overlays/vbo_maw16
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw16.dmi'
/datum/belly_overlays/vbo_maw17
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw17.dmi'
/datum/belly_overlays/vbo_maw18
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw18.dmi'
/datum/belly_overlays/vbo_maw19
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw19.dmi'
/datum/belly_overlays/vbo_maw20
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw20.dmi'
/datum/belly_overlays/vbo_maw21
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw21.dmi'
/datum/belly_overlays/vbo_maw22
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw22.dmi'
/datum/belly_overlays/vbo_maw23
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw23.dmi'
/datum/belly_overlays/vbo_maw24
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw24.dmi'
/datum/belly_overlays/vbo_maw25
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw25.dmi'
/datum/belly_overlays/vbo_maw26
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_maw26.dmi'
/datum/belly_overlays/vbo_notbelly
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_notbelly.dmi'
/datum/belly_overlays/vbo_paw
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_paw.dmi'
/datum/belly_overlays/vbo_synth1
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_synth1.dmi'
/datum/belly_overlays/vbo_synth2
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_synth2.dmi'
/datum/belly_overlays/vbo_trash
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_trash.dmi'
/datum/belly_overlays/vbo_vines
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_vines.dmi'
/datum/belly_overlays/vbo_wriggly
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBO_wriggly.dmi'
/datum/belly_overlays/vboanim_belly1
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_belly1.dmi'
/datum/belly_overlays/vboanim_belly2
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_belly2.dmi'
/datum/belly_overlays/vboanim_belly3
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_belly3.dmi'
/datum/belly_overlays/vboanim_belly4
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_belly4.dmi'
/datum/belly_overlays/vboanim_belly5
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_belly5.dmi'
/datum/belly_overlays/vboanim_belly6
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_belly6.dmi'
/datum/belly_overlays/vboanim_belly7
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_belly7.dmi'
/datum/belly_overlays/vboanim_belly8
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_belly8.dmi'
/datum/belly_overlays/vboanim_belly9
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_belly9.dmi'
/datum/belly_overlays/vboanim_belly10
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_belly10.dmi'
/datum/belly_overlays/vboanim_gullet1
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_gullet1.dmi'
/datum/belly_overlays/vboanim_intestine1
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_intestine1.dmi'
/datum/belly_overlays/vboanim_intestine2
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_intestine2.dmi'
/datum/belly_overlays/vboanim_snakebelly1
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_snakebelly1.dmi'
/datum/belly_overlays/vboanim_synthbelly1
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_synthbelly1.dmi'
/datum/belly_overlays/vboanim_taurbelly1
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_taurbelly1.dmi'
/datum/belly_overlays/a_tumby
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/a_tumby.dmi'
/datum/belly_overlays/another_tumby
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/another_tumby.dmi'
/datum/belly_overlays/base
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/base.dmi'
/datum/belly_overlays/brown_internals
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/brown_internals.dmi'
/datum/belly_overlays/brown_internals_hole
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/brown_internals_hole.dmi'
/datum/belly_overlays/da_tumby
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/da_tumby.dmi'
/datum/belly_overlays/dark
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/dark.dmi'
/datum/belly_overlays/synth_flesh_mono
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/synth_flesh_mono.dmi'
/datum/belly_overlays/synth_flesh_mono_hole
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/synth_flesh_mono_hole.dmi'
/datum/belly_overlays/yet_another_tumby
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/yet_another_tumby.dmi'
//Compatibility assets due to renames...
/datum/belly_overlays/anim_belly
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_belly1.dmi'
/datum/belly_overlays/a_anim_belly
belly_icon = 'modular_chomp/icons/mob/vore_fullscreens/VBOanim_belly1.dmi'
@@ -1,65 +0,0 @@
GLOBAL_DATUM_INIT(gear_tweak_item_tf_spawn, /datum/gear_tweak/item_tf_spawn, new())
/datum/gear_tweak/item_tf_spawn
/datum/gear_tweak/item_tf_spawn/get_contents(var/metadata)
if(!islist(metadata) || metadata["state"] == "Not Enabled")
return "Item TF spawnpoint: Not Enabled"
else if(metadata["state"] == "Anyone")
return "Item TF spawnpoint: Enabled"
else
return "Item TF spawnpoint: Only ckeys [english_list(metadata["valid"], and_text = ", ")]"
/datum/gear_tweak/item_tf_spawn/get_default()
. = list()
.["state"] = "Not Enabled"
.["valid"] = list()
/datum/gear_tweak/item_tf_spawn/get_metadata(var/user, var/list/metadata)
. = get_default()
metadata = islist(metadata) ? metadata : .
var/entry = tgui_input_list(user, "Choose an entry.", "Character Preference", list("Not Enabled", "Anyone", "Only Specific Players"), metadata["state"])
if(entry)
.["state"] = entry
if(entry == "Only Specific Players")
var/ckey_input = tgui_input_text(user, "Input ckeys allowed to join on separate lines", "Allowed Players", jointext(metadata["valid"], "\n"), multiline = TRUE)
.["valid"] = splittext(lowertext(ckey_input), "\n")
else
.["valid"] = metadata["valid"]
else
return metadata
/datum/gear_tweak/item_tf_spawn/tweak_item(var/obj/item/I, var/metadata)
if(!islist(metadata))
return
if(metadata["state"] == "Not Enabled")
return
else if(metadata["state"] == "Anyone")
I.item_tf_spawnpoint_set()
else if(metadata["state"] == "Only Specific Players")
I.item_tf_spawnpoint_set()
I.ckeys_allowed_itemspawn = metadata["valid"]
/datum/gear_tweak/simplemob_picker
var/list/simplemob_list
/datum/gear_tweak/simplemob_picker/New(var/list/valid_simplemobs)
src.simplemob_list = valid_simplemobs
..()
/datum/gear_tweak/simplemob_picker/get_contents(var/metadata)
return "Type: [metadata]"
/datum/gear_tweak/simplemob_picker/get_default()
return simplemob_list[1]
/datum/gear_tweak/simplemob_picker/get_metadata(var/user, var/metadata)
return tgui_input_list(user, "Choose a type.", "Character Preference", simplemob_list, metadata)
/datum/gear_tweak/simplemob_picker/tweak_item(var/obj/item/capture_crystal/I, var/metadata)
if(!(metadata in simplemob_list))
return
if(!istype(I))
return
I.spawn_mob_type = simplemob_list[metadata]
I.spawn_mob_name = metadata
@@ -7,15 +7,6 @@
..()
turfs = GLOB.latejoin_gatewaystation
/datum/spawnpoint/vore
display_name = "Vorespawn - Prey"
msg = "has arrived on the station"
allow_offmap_spawn = TRUE
/datum/spawnpoint/vore/pred
display_name = "Vorespawn - Pred"
msg = "has arrived on the station"
/datum/spawnpoint/vore/itemtf
display_name = "Item TF spawn"
msg = "has arrived on the station"
@@ -49,4 +40,4 @@
/datum/spawnpoint/tyrspawn/New()
..()
turfs = GLOB.latejoin_tyrvillage
turfs = GLOB.latejoin_tyrvillage
@@ -1,14 +1,6 @@
/mob/observer
var/mob/living/body_backup = null //add reforming
low_priority = TRUE
/mob/observer/Destroy()
if(body_backup)
body_backup.moveToNullspace() //YEET
qdel(body_backup)
body_backup = null
return ..()
// Persistence vars not included as we probably don't want losing limbs in the game mean losing limbs in real life. Definitely can't backfire.
/mob/observer/dead/verb/fake_enter_vr()
set name = "Join virtual reality"
@@ -1,7 +0,0 @@
/obj/item/mmi
var/mob/living/body_backup = null //add reforming
/obj/item/mmi/Destroy()
if(body_backup)
qdel(body_backup)
..()
@@ -157,6 +157,8 @@
/mob/living/simple_mob/animal/synx/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
//B.human_prey_swallow_time = 6 SECONDS //doesnt work
@@ -189,6 +191,8 @@
/mob/living/simple_mob/animal/synx/ai/pet/asteri/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.desc = "The synx eagerly swallows you, taking you from its gullet into its long, serpentine stomach. The internals around you greedily press into your from all sides, keeping you coated in a slick coat of numbing fluids..."
@@ -748,6 +752,8 @@
/mob/living/simple_mob/animal/synx/ai/pet/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.vore_verb = "swallow"
@@ -757,6 +763,8 @@
/mob/living/simple_mob/animal/synx/ai/pet/holo/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.vore_verb = "swallow"
@@ -43,9 +43,11 @@
unacidable = TRUE
/mob/living/simple_mob/animal/tyr/mineral_ants/init_vore()
if(!voremob_loaded) //CHOMPAdd
return //CHOMPAdd
.=..() //CHOMPEdit
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
B.mode_flags = DM_FLAG_THICKBELLY | DM_FLAG_NUMBING
@@ -63,6 +63,8 @@
/mob/living/simple_mob/animal/tyr/groundpitcher/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.desc = "You leaned a little too close to the pitcher plant, stumbling over the lip and splashing into a puddle of liquid filling the bottom of the cramped pitcher. You squirm madly, righting yourself and scrabbling at the walls in vain as the slick surface offers no purchase. The dim light grows dark as the pitcher's cap lowers, silently sealing the exit. With a sinking feeling you realize you won't be able to push the exit open even if you could somehow climb that high, leaving you helplessly trapped in the slick, tingling fluid."
@@ -207,4 +209,4 @@
melee_damage_lower = 16
melee_damage_upper = 16
ranged_cooldown = 30
ranged_cooldown = 30
@@ -29,9 +29,11 @@
unacidable = TRUE
/mob/living/simple_mob/animal/tyr/init_vore()
if(!voremob_loaded) //CHOMPAdd
return //CHOMPAdd
.=..() //CHOMPEdit
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
B.mode_flags = DM_FLAG_THICKBELLY | DM_FLAG_NUMBING
@@ -39,4 +41,4 @@
B.digest_burn = 1
B.digestchance = 0
B.absorbchance = 0
B.escapechance = 25
B.escapechance = 25
@@ -65,6 +65,8 @@
/mob/living/simple_mob/vr/alchemistbee/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -159,6 +159,8 @@
/mob/living/simple_mob/humanoid/cultist/magus/rift/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -129,6 +129,8 @@
/mob/living/simple_mob/humanoid/cultist/human/bloodjaunt/fireball/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -169,6 +171,8 @@
/mob/living/simple_mob/humanoid/cultist/noodle/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -210,6 +214,8 @@
/mob/living/simple_mob/humanoid/cultist/tesh/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -250,6 +256,8 @@
/mob/living/simple_mob/humanoid/cultist/castertesh/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -22,6 +22,8 @@
/mob/living/simple_mob/humanoid/eclipse/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -59,6 +61,8 @@
/mob/living/simple_mob/humanoid/eclipse/head/scientist/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -99,6 +103,8 @@
/mob/living/simple_mob/humanoid/eclipse/head/security/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -140,6 +146,8 @@
/mob/living/simple_mob/humanoid/eclipse/head/captain/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -21,6 +21,8 @@
/mob/living/simple_mob/humanoid/starhunter/hunter/druid/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -59,6 +61,8 @@
/mob/living/simple_mob/humanoid/starhunter/hunter/champion/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -98,6 +102,8 @@
/mob/living/simple_mob/humanoid/starhunter/hunter/avatar/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -90,6 +90,8 @@
/mob/living/simple_mob/metroid/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.digest_brute = 1
@@ -64,6 +64,8 @@ GLOBAL_VAR_INIT(queen_amount, 0) //We only gonna want 1 queen in the world.
/mob/living/simple_mob/metroid/mine/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.digest_burn = 0.5
@@ -1,6 +1,8 @@
/mob/living/simple_mob/animal/space/carp/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
. = ..()
var/obj/belly/B = vore_selected
B.name = "Stomach"
@@ -141,6 +141,8 @@
/mob/living/simple_mob/vore/retaliate/corrupthound/janihound/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.vore_sound = "Tauric Swallow" // CHOMPedit - Fancy Vore Sounds
@@ -60,6 +60,8 @@
/mob/living/simple_mob/vore/candy/bluecabold/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -86,6 +88,8 @@
/mob/living/simple_mob/vore/candy/redcabold/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -112,6 +116,8 @@
/mob/living/simple_mob/vore/candy/yellowcabold/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -138,6 +144,8 @@
/mob/living/simple_mob/vore/candy/orangecabold/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -164,6 +172,8 @@
/mob/living/simple_mob/vore/candy/purplecabold/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -190,6 +200,8 @@
/mob/living/simple_mob/vore/candy/marshmellowserpent/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -692,6 +704,8 @@
/mob/living/simple_mob/vore/candy/worm/redcabold/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -718,6 +732,8 @@
/mob/living/simple_mob/vore/candy/peppermint/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -13,6 +13,8 @@
/mob/living/simple_mob/vore/jelly/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
. = ..()
var/obj/belly/B = vore_selected
B.name = "stomach"
@@ -109,6 +109,8 @@
/mob/living/simple_mob/vore/aggressive/panther/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.vore_sound = "Tauric Swallow"
@@ -79,6 +79,8 @@ GLOBAL_LIST_INIT(pitcher_plant_lure_messages, list(
/mob/living/simple_mob/vore/pitcher_plant/init_vore()
if(!voremob_loaded)
return
if(LAZYLEN(vore_organs))
return
.=..()
var/obj/belly/B = vore_selected
B.desc = "You leaned a little too close to the pitcher plant, stumbling over the lip and splashing into a puddle of liquid filling the bottom of the cramped pitcher. You squirm madly, righting yourself and scrabbling at the walls in vain as the slick surface offers no purchase. The dim light grows dark as the pitcher's cap lowers, silently sealing the exit. With a sinking feeling you realize you won't be able to push the exit open even if you could somehow climb that high, leaving you helplessly trapped in the slick, tingling fluid. ((You can't escape this mob without help but you may use OOC Escape if you wish.))"
-11
View File
@@ -1,11 +0,0 @@
/mob
var/voice_freq = 42500 // Preference for character voice frequency
var/list/voice_sounds_list = list() // The sound list containing our voice sounds!
var/enabled = TRUE //Pauses a mob if disabled (Prevents life ticks from happening)
var/died_in_vr = FALSE //For virtual reality sleepers
var/last_move_time = 0 //For movement smoothing
/mob/is_incorporeal()
if(incorporeal_move)
return 1
..()
@@ -1,551 +0,0 @@
/obj/soulgem
name = "Mind imprintation matrix"
desc = "A mind storage and processing system capable of capturing and supporting human-level minds in a small VR space."
var/mob/living/owner
var/datum/own_mind
var/obj/belly/linked_belly
var/taken_over_name
var/setting_flags = (NIF_SC_ALLOW_EARS|NIF_SC_ALLOW_EYES|NIF_SC_BACKUPS|NIF_SC_PROJECTING)
var/mob/selected_soul = null
var/list/brainmobs = list()
var/inside_flavor = "A small completely white room with a couch, and a window to what seems to be the outside world. A small sign in the corner says 'Configure Me'."
var/capture_message = "Your vision fades in a haze of static, before returning.\nAround you, you see...\n"
var/transit_message = "Your surroundings change to..."
var/release_message = "Release Message"
var/transfer_message = "Transfer Message"
var/delete_message = "Delete Message"
// Append the vars to save to our savefile list
/obj/soulgem/vars_to_save()
var/list/saving = list (
"setting_flags",
"inside_flavor",
"capture_message",
"transit_message",
"release_message",
"transfer_message",
"delete_message",
"linked_belly"
)
return ..() + saving
// Load the vars_to_save from the savefile
/obj/soulgem/Initialize(mapload)
. = ..()
if(ismob(loc))
owner = loc
owner.recalculate_vis()
// Store the vars_to_save into the save file
/obj/soulgem/deserialize(list/data)
. = ..()
for(var/obj/belly in owner.vore_organs)
if(belly.name == data["linked_belly"])
update_linked_belly(belly, TRUE)
return
linked_belly = null
// Allows to transfer the soulgem to the given mob
/obj/soulgem/proc/transfer_self(var/mob/target)
QDEL_NULL(target.soulgem)
owner.soulgem = null
forceMove(target)
owner = target
target.soulgem = src
// Cleaning up our refs before deletion
/obj/soulgem/Destroy()
owner = null
selected_soul = null
own_mind = null
QDEL_LIST_NULL(brainmobs)
if(istype(linked_belly))
UnregisterSignal(linked_belly, COMSIG_BELLY_UPDATE_VORE_FX)
linked_belly = null
. = ..()
// Sends messages to the owner of the soulcatcher
/obj/soulgem/proc/notify_holder(var/message)
message = span_nif(span_bold("[name]") + " displays, \"" + span_notice("[message]") + "\"")
to_chat(owner, message)
for(var/mob/living/carbon/brain/caught_soul/CS as anything in brainmobs)
to_chat(CS, message)
// Forwards the speech of captured souls
/obj/soulgem/proc/use_speech(var/message, var/mob/living/sender, var/mob/eyeobj, var/whisper)
var/sender_name = eyeobj ? eyeobj.name : sender.name
//AR Projecting
if(eyeobj)
var/speak_verb = "says"
message = span_game(span_say(span_bold("[sender_name]") + " [speak_verb], \"[message]\""))
if(whisper)
speak_verb = "whispers"
sender.eyeobj.visible_message(span_italics(message), range = 1)
else
sender.eyeobj.visible_message(message)
//Not AR Projecting
else
var/speak_verb = "speaks"
message = span_nif(span_bold("\[SC\] [sender_name]") + " [speak_verb], \"[message]\"")
to_chat(owner, message)
if(whisper)
speak_verb = "whispers"
to_chat(sender, span_italics(message))
else
for(var/mob/living/carbon/brain/caught_soul/CS as anything in brainmobs)
to_chat(CS, message)
log_nsay(message, owner.real_name, sender)
// Forwards the emotes of captured souls
/obj/soulgem/proc/use_emote(var/message, var/mob/living/sender, var/mob/eyeobj, var/whisper)
var/sender_name = eyeobj ? eyeobj.name : sender.name
//AR Projecting
if(eyeobj)
message = span_emote("[sender_name] [message]")
if(whisper)
sender.eyeobj.visible_message(span_italics(message), range = 1)
else
sender.eyeobj.visible_message(message)
//Not AR Projecting
else
message = span_nif(span_bold("[sender_name]") + " [message]")
to_chat(owner, message)
if(whisper)
to_chat(sender, span_italics(message))
else
for(var/mob/living/carbon/brain/caught_soul/CS as anything in brainmobs)
to_chat(CS, message)
log_nme(message, owner.real_name,sender)
// The capture function which transfers the given mob's mind into the soulcatcher
/obj/soulgem/proc/catch_mob(var/mob/M, var/custom_name)
if(!(M.soulcatcher_pref_flags & SOULCATCHER_ALLOW_CAPTURE) && !isobserver(M)) return // Bypass pref check for observer join
if(!M.mind) return
if(isbrain(owner)) return
//Create a new brain mob
var/mob/living/carbon/brain/caught_soul/vore/brainmob = new(src)
brainmob.gem = src
brainmob.container = src
brainmob.stat = 0
brainmob.silent = FALSE
dead_mob_list -= brainmob
brainmob.ext_deaf = !flag_check(NIF_SC_ALLOW_EARS)
brainmob.ext_blind = !flag_check(NIF_SC_ALLOW_EYES)
brainmob.add_language(LANGUAGE_GALCOM)
brainmobs |= brainmob
//Put the mind and player into the mob
M.mind.transfer_to(brainmob)
brainmob.name = custom_name ? custom_name : brainmob.mind.name
brainmob.real_name = custom_name ? custom_name : brainmob.mind.name
//If we caught our owner, special settings.
if(M == owner && !own_mind) // Need some more sanity if we allow takeover
brainmob.ext_deaf = FALSE
brainmob.ext_blind = FALSE
brainmob.parent_mob = TRUE
own_mind = brainmob.mind
remove_verb(brainmob, /mob/proc/enter_soulcatcher) //No recursive self capturing...
add_verb(brainmob, /mob/living/carbon/brain/caught_soul/vore/proc/transfer_self)
add_verb(brainmob, /mob/living/carbon/brain/caught_soul/vore/proc/reenter_body)
//If they have these values, apply them
if(isliving(M))
var/mob/living/L = M
brainmob.dna = L.dna
brainmob.ooc_notes = L.ooc_notes
brainmob.ooc_notes_likes = L.ooc_notes_likes
brainmob.ooc_notes_dislikes = L.ooc_notes_dislikes
//CHOMPEdit Start
brainmob.ooc_notes_favs = L.ooc_notes_favs
brainmob.ooc_notes_maybes = L.ooc_notes_maybes
brainmob.ooc_notes_style = L.ooc_notes_style
//CHOMPEdit End
brainmob.timeofhostdeath = L.timeofdeath
if(ishuman(L))
SStranscore.m_backup(brainmob.mind,0) //It does ONE, so medical will hear about it.
//Else maybe they're a joining ghost
else if(isobserver(M))
brainmob.transient = TRUE
qdel(M) //Bye ghost
//Give them a flavortext message
var/message = span_notice("[capture_message][inside_flavor]")
to_chat(brainmob, message)
//Reminder on how this works to host
if(brainmobs.len == 1) //Only spam this on the first one
to_chat(owner, span_notice("Your occupant's messages/actions can only be seen by you, and you can \
send messages that only they can hear/see by using the NSay and NMe verbs (or the *nsay and *nme emotes)."))
//Announce to host and other minds
notify_holder("New mind loaded: [brainmob.name]")
show_vore_fx(brainmob, TRUE)
brainmob.copy_from_prefs_vr(bellies = FALSE)
return TRUE
// Allows to adjust the interior of the soulcatcher
/obj/soulgem/proc/adjust_interior(var/new_flavor)
new_flavor = sanitize(new_flavor, MAX_MESSAGE_LEN * 2)
inside_flavor = new_flavor
notify_holder("Updating environment...")
for(var/mob/living/carbon/brain/caught_soul/vore/CS as anything in brainmobs)
to_chat(CS, span_notice("[transit_message]") + "\n[inside_flavor]")
// Allows to return to the body after being captured by one's own soulcatcher
/obj/soulgem/proc/return_to_body(var/datum/mind)
if(own_mind != mind)
to_chat(src, span_warning("You aren't in your own soulcatcher!"))
return
var/mob/self = null
for(var/mob/mob in brainmobs)
if(mob.mind == mind)
self = mob
break
if(!self)
return
if(owner.mind)
catch_mob(owner, taken_over_name)
self.mind.transfer_to(owner)
own_mind = null
taken_over_name = null
qdel(self)
// Sets the custom messages depending on the input
/obj/soulgem/proc/set_custom_message(var/message, var/target)
message = sanitize(message, MAX_MESSAGE_LEN / 4)
switch(target)
if("capture")
capture_message = message
if("transit")
transit_message = message
if("release")
release_message = message
if("transfer")
transfer_message = message
if("delete")
delete_message = message
// Allows to rename the soulgem
/obj/soulgem/proc/rename(var/new_name)
if(length(new_name) < 3 || length(new_name) > 60)
to_chat(owner, span_warning("Your soulcatcher's name needs to be between 3 and 60 characters long!"))
return
new_name = sanitize(new_name, 60)
name = new_name
// Toggles the given flag
/obj/soulgem/proc/toggle_setting(var/flag)
setting_flags ^= flag
if(flag & SOULGEM_SHOW_VORE_SFX)
soulgem_show_vfx(TRUE)
soulgem_vfx()
if(flag & NIF_SC_BACKUPS)
soulgem_backup()
if(flag & NIF_SC_ALLOW_EARS)
soulgem_hear()
if(flag & NIF_SC_ALLOW_EYES)
soulgem_sight()
if(flag & NIF_SC_PROJECTING)
soulgem_projecting()
if(flag & SOULGEM_SEE_SR_SOULS)
owner.recalculate_vis()
// Checks a single flag, or if all combined flags are true
/obj/soulgem/proc/flag_check(var/flag, var/match_all = FALSE)
if(match_all)
return (setting_flags & flag) == flag
return setting_flags & flag
// Updates the selected soul after an interaction which rleased, deleted or transferred the previous one
/obj/soulgem/proc/update_selected_soul()
if(brainmobs.len > 1)
selected_soul = brainmobs[1]
else
selected_soul = null
// Backup toggling
/obj/soulgem/proc/soulgem_backup()
if(flag_check(NIF_SC_BACKUPS))
notify_holder("External backups enabled.")
else
notify_holder("External backups disabled.")
// Deaf toggling
/obj/soulgem/proc/soulgem_hear()
for(var/mob/living/carbon/brain/caught_soul/L in brainmobs)
L.ext_deaf = !flag_check(NIF_SC_ALLOW_EARS)
if(flag_check(NIF_SC_ALLOW_EARS))
notify_holder("External sounds enabled.")
else
notify_holder("External sounds disabled.")
// Sight toggling
/obj/soulgem/proc/soulgem_sight()
for(var/mob/living/carbon/brain/caught_soul/L in brainmobs)
L.ext_blind = !flag_check(NIF_SC_ALLOW_EYES)
if(flag_check(NIF_SC_ALLOW_EYES))
notify_holder("External vision enabled.")
else
notify_holder("External vision disabled.")
// Projecting toggling
/obj/soulgem/proc/soulgem_projecting()
if(flag_check(NIF_SC_PROJECTING))
notify_holder("AR projecting enabled.")
else
notify_holder("AR projecting disabled.")
// VORE FX Section
// Updates the vore FX signal links to the new given belly
/obj/soulgem/proc/update_linked_belly(var/obj/belly, var/skip_unreg = FALSE)
if(!belly && linked_belly)
UnregisterSignal(linked_belly, COMSIG_BELLY_UPDATE_VORE_FX)
linked_belly = null
return
if(!isbelly(belly))
return
if(!linked_belly)
linked_belly = belly
RegisterSignal(linked_belly, COMSIG_BELLY_UPDATE_VORE_FX, PROC_REF(soulgem_show_vfx))
return
if(belly != linked_belly)
if(!skip_unreg)
UnregisterSignal(linked_belly, COMSIG_BELLY_UPDATE_VORE_FX)
linked_belly = belly
RegisterSignal(linked_belly, COMSIG_BELLY_UPDATE_VORE_FX, PROC_REF(soulgem_show_vfx))
// Handles the vore fx updates for the captured souls
/obj/soulgem/proc/soulgem_show_vfx(var/update, var/severity = 0)
if(linked_belly)
for(var/mob/living/L in brainmobs)
if(flag_check(SOULGEM_SHOW_VORE_SFX))
show_vore_fx(L, update, severity)
else
clear_vore_fx(L)
// Function to show the vore fx overlay
/obj/soulgem/proc/show_vore_fx(var/mob/living/L, var/update, var/severity = 0)
if(!linked_belly || !flag_check(SOULGEM_SHOW_VORE_SFX))
return
if(!istype(L) || L.eyeobj)
return
linked_belly.vore_fx(L, update, severity)
// Function to clear the vore fx overlay
/obj/soulgem/proc/clear_vore_fx(var/mob/M)
M.clear_fullscreen("belly")
if(M.hud_used && !M.hud_used.hud_shown)
M.toggle_hud_vis(TRUE)
// VFX toggling
/obj/soulgem/proc/soulgem_vfx()
if(flag_check(SOULGEM_SHOW_VORE_SFX))
notify_holder("Interior simulation enabled.")
else
notify_holder("Interior simulation disabled.")
// Takeover section
// Give control of the body to the current selected soul
/obj/soulgem/proc/take_control_selected()
if(!selected_soul) return
take_control(selected_soul)
if(owner.mind == own_mind)
own_mind = null
taken_over_name = null
// Give back control of the body to the owner
/obj/soulgem/proc/take_control_owner()
var/mob/self = null
for(var/mob/mob in brainmobs)
if(mob.mind == own_mind)
self = mob
break
if(!self)
return
take_control(self)
own_mind = null
taken_over_name = null
/obj/soulgem/proc/take_control(var/mob/M)
if(!(owner.soulcatcher_pref_flags & SOULCATCHER_ALLOW_CAPTURE) || !(owner.soulcatcher_pref_flags & SOULCATCHER_ALLOW_TAKEOVER)) return
if(!(M.soulcatcher_pref_flags & SOULCATCHER_ALLOW_CAPTURE) || !(M.soulcatcher_pref_flags & SOULCATCHER_ALLOW_TAKEOVER)) return
if(!own_mind)
if(issilicon(owner) || isanimal(owner))
taken_over_name = owner.name
catch_mob(owner, taken_over_name)
taken_over_name = M.name
M.mind.transfer_to(owner)
brainmobs -= M
if(M == selected_soul)
update_selected_soul()
qdel(M)
// Funtion to test if the owner's body has been taken over
/obj/soulgem/proc/is_taken_over()
return (own_mind && owner.mind && owner.mind != own_mind)
// Transfer section to transfer captured souls
// Returns nearby,valid transfer locations as a list
/obj/soulgem/proc/find_transfer_objects()
var/list/valid_trasfer_objects = list(
/obj/item/sleevemate,
/obj/item/mmi
)
var/list/valid_objects = list()
if(isrobot(owner))
var/mob/living/silicon/robot/R = owner
if(istype(R.module_active, /obj/item/sleevemate))
valid_objects += R.module_active
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
if(is_type_in_list(H.get_left_hand(), valid_trasfer_objects))
valid_objects += H.get_left_hand()
if(is_type_in_list(H.get_right_hand(), valid_trasfer_objects))
valid_objects += H.get_right_hand()
for(var/obj/item/I in range(0, get_turf(owner)))
if(is_type_in_list(I, valid_trasfer_objects))
valid_objects += I
for(var/mob/M in range(1, get_turf(owner)))
if(M == owner)
continue
if(!(M.soulcatcher_pref_flags & SOULCATCHER_ALLOW_TRANSFER))
continue
if(M.client && M.soulgem)
valid_objects += M.soulgem
if(!valid_objects.len)
to_chat(owner, span_warning("No valid objects found!"))
return
return valid_objects
// Transfer the selected soul to either a valid object or another soulcatcher
/obj/soulgem/proc/transfer_selected()
if(!selected_soul) return
if(!(selected_soul.soulcatcher_pref_flags & SOULCATCHER_ALLOW_TRANSFER)) return
var/list/valid_objects = find_transfer_objects()
if(!valid_objects || !valid_objects.len)
return
var/obj/target = tgui_input_list(owner, "Select where you want to store the mind into.", "Mind Transfer Target", valid_objects)
transfer_mob_selector(selected_soul, target)
// Transfer selector proc
/obj/soulgem/proc/transfer_mob_selector(var/mob/M, var/obj/target)
if(!M || !target) return
if(istype(target, /obj/soulgem))
transfer_mob_soulcatcher(M, target)
return
transfer_mob(M, target)
// Transfers a captured soul to a valid object (sleevemate, mmi)
/obj/soulgem/proc/transfer_mob(var/mob/M, var/obj/target)
if(is_taken_over()) return
if(!M || !target) return
if(istype(target, /obj/item/sleevemate))
var/obj/item/sleevemate/mate = target
if(!mate.stored_mind)
to_chat(owner, span_notice("You scan yourself to transfer the soul into the [target]!"))
to_chat(M, span_notice("[transfer_message]"))
if(M.mind == own_mind)
own_mind = null
mate.get_mind(M)
else if(istype(target, /obj/item/mmi))
var/obj/item/mmi/mm = target
if(!mm.brainmob || !mm.brainmob.mind)
if(M.mind == own_mind)
own_mind = null
to_chat(owner, span_notice("You transfer the soul into the [target]!"))
to_chat(M, span_notice("[transfer_message]"))
mm.transfer_identity(M)
if(!mm.brainmob.mind && M.mind)
M.mind.transfer_to(mm.brainmob)
else
return
brainmobs -= M
if(M == selected_soul)
update_selected_soul()
qdel(M)
// Transfers a captured soul to another soulcatcher
/obj/soulgem/proc/transfer_mob_soulcatcher(var/mob/living/carbon/brain/caught_soul/vore/M, var/obj/soulgem/gem)
if(is_taken_over()) return
if(!istype(M) || !gem) return
if(!gem.owner) return
if((tgui_alert(gem.owner, "Do you want to allow [owner] to transfer [selected_soul] to your soulcatcher?", "Allow Transfer", list("No", "Yes")) != "Yes"))
return
if(!in_range(gem.owner, owner))
return
if(!(gem.owner.soulcatcher_pref_flags & SOULCATCHER_ALLOW_TRANSFER))
return
if(M.mind == own_mind)
own_mind = null
brainmobs -= M
M.gem = gem
M.container = gem
gem.brainmobs += M
if(M == selected_soul)
update_selected_soul()
// Release section
// Release the selected soul as a ghost
/obj/soulgem/proc/release_selected()
if(!selected_soul) return
if(release_mob(selected_soul))
update_selected_soul()
// Release all captured souls as ghosts
/obj/soulgem/proc/release_mobs()
selected_soul = null
if(!brainmobs.len) return
for(var/mob/M in brainmobs)
release_mob(M)
// Proc to release the soul as ghost, returns TRUE on success
/obj/soulgem/proc/release_mob(var/mob/M)
if(is_taken_over()) return FALSE
to_chat(M, span_notice("[release_message]"))
brainmobs -= M
M.ghostize(FALSE)
qdel(M)
return TRUE
// Delete section to delete captured souls from the soulcatcher
// Delete the selected mob
/obj/soulgem/proc/delete_selected()
if(!selected_soul) return
if(delete_mob(selected_soul))
update_selected_soul()
// Delete all captured mobs
/obj/soulgem/proc/erase_mobs()
if(!brainmobs.len) return
for(var/mob/M in brainmobs)
delete_mob(M)
// The function handling the actual delete, returns TRUE on success
/obj/soulgem/proc/delete_mob(var/mob/M)
if(is_taken_over()) return FALSE
if(!(M.soulcatcher_pref_flags & SOULCATCHER_ALLOW_DELETION))
return release_mob(M)
if(!(M.soulcatcher_pref_flags & SOULCATCHER_ALLOW_DELETION_INSTANT))
if(tgui_alert(M, "Do you really want to allow [owner] to delete you? On decline, you'll be ghosted.", "Allow Deletion", list("No", "Yes"), timeout=1 MINUTES) != "Yes")
return release_mob(M)
to_chat(M, span_danger("[delete_message]"))
brainmobs -= M
var/mob/observer/dead/ghost = M.ghostize(FALSE)
ghost.abandon_mob()
qdel(M)
return TRUE
@@ -1,245 +0,0 @@
/mob/living/carbon/brain/caught_soul/vore
name = "stored soul"
desc = "A soul stored within the predator."
var/obj/soulgem/gem
// Cleaning up the refs during deletion
/mob/living/carbon/brain/caught_soul/vore/Destroy()
if(gem)
gem.notify_holder("Mind unloaded: [name]")
gem.brainmobs -= src
gem = null
if(eyeobj)
QDEL_NULL(eyeobj)
gem.notify_holder("[name] ended SR projection.")
container = null
return ..()
// Handling the automatic transcore backups in a set interval
/mob/living/carbon/brain/caught_soul/vore/Life()
. = ..()
if(QDELETED(src))
return
if(!parent_mob && !transient &&(life_tick % 150 == 0) && gem.setting_flags & NIF_SC_BACKUPS)
SStranscore.m_backup(mind,0) //Passed 0 means "Don't touch the nif fields on the mind record"
if(!client)
return
if(ext_blind)
eye_blind = 5
client.screen.Remove(global_hud.whitense)
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
else
eye_blind = 0
clear_fullscreen("blind")
if(!gem.flag_check(SOULGEM_SHOW_VORE_SFX))
client.screen.Add(global_hud.whitense)
if(gem.flag_check(SOULGEM_SHOW_VORE_SFX))
client.screen.Remove(global_hud.whitense)
// Say proc for captures souls
/mob/living/carbon/brain/caught_soul/vore/say(var/message, var/datum/language/speaking = null, var/whispering = 0)
if(silent) return FALSE
gem.use_speech(message, src, eyeobj)
// Emote proc for captured souls
/mob/living/carbon/brain/caught_soul/vore/custom_emote(var/m_type, var/message)
if(silent) return FALSE
gem.use_emote(message,src,eyeobj)
/mob/living/carbon/brain/caught_soul/vore/me_verb_subtle(message as message)
if(silent) return FALSE
gem.use_emote(message,src,eyeobj,TRUE)
/mob/living/carbon/brain/caught_soul/vore/whisper(message as text)
if(silent) return FALSE
gem.use_speech(message,src,eyeobj,TRUE)
// Resist override, only returning a message that one is stuck for now
/mob/living/carbon/brain/caught_soul/vore/resist()
set name = "Resist"
set category = "IC.Game" //CHOMPEdit
to_chat(src, span_warning("There's no way out! You're stuck inside your predator."))
// Allows the predator to enter their own soulcatcher
/mob/proc/enter_soulcatcher()
set name = "Enter Soulcatcher"
set desc = "Enter your own Soulcatcher."
set category = "IC.Vore"
if(!soulgem) // Only sanity...
return
if(soulgem && soulgem.flag_check(SOULGEM_ACTIVE))
var/to_use_custom_name = null
if(issilicon(src) || isanimal(src))
to_use_custom_name = src.name
soulgem.catch_mob(src, to_use_custom_name)
// Speak to the captured souls within the own soulcatcher
/mob/proc/nsay_vore(message as message)
set name = "NSay Vore"
set desc = "Speak into your Soulcatcher."
src.nsay_vore_act(message)
/mob/proc/nsay_vore_ch()
set name = "NSay Vore CH"
set desc = "Speak into your Soulcatcher."
set category = "IC.Vore"
src.nsay_vore_act()
/mob/proc/nsay_vore_act(var/message)
if(stat != CONSCIOUS)
to_chat(src, span_warning("You can't use NSay Vore while unconscious."))
return
if(!soulgem) // Only sanity...
return
var/obj/soulgem/gem = soulgem
if(!gem.brainmobs.len)
to_chat(src, span_warning("You need a devoured soul to use NSay Vore."))
return
if(!message)
message = tgui_input_text(usr, "Type a message to say.","Speak into Soulcatcher", multiline=TRUE)
if(message)
var/sane_message = sanitize(message)
gem.use_speech(sane_message, src)
// Emote to the captured souls within the soulcatcher
/mob/proc/nme_vore(message as message)
set name = "NMe Vore"
set desc = "Emote into your Soulcatcher."
src.nme_vore_act(message)
/mob/proc/nme_vore_ch()
set name = "NMe Vore CH"
set desc = "Emote into your Soulcatcher."
set category = "IC.Vore"
src.nme_vore_act()
/mob/proc/nme_vore_act(var/message)
if(stat != CONSCIOUS)
to_chat(src, span_warning("You can't use NMe Vore while unconscious."))
return
if(!soulgem) // Only sanity...
return
var/obj/soulgem/gem = soulgem
if(!gem.brainmobs.len)
to_chat(src, span_warning("You need a devoured soul to use NMe Vore."))
return
if(!message)
message = tgui_input_text(usr, "Type an action to perform.","Emote into Soulcatcher", multiline=TRUE)
if(message)
var/sane_message = sanitize(message)
gem.use_emote(sane_message, src)
// SR projecting mob
/mob/observer/eye/ar_soul/vore
plane = PLANE_SOULCATCHER
// SR project as captured soul
/mob/living/carbon/brain/caught_soul/vore/ar_project()
set name = "AR/SR Project"
set desc = "Project your form into Augmented Reality for those around your predator with the appearance of your loaded character."
set category = "Soulcatcher"
if(eyeobj)
to_chat(src, span_warning("You're already projecting in SR!"))
return
if(!(gem.setting_flags & NIF_SC_PROJECTING))
to_chat(src, span_warning("Projecting from this NIF has been disabled!"))
return
if(!client || !client.prefs)
return //Um...
eyeobj = new/mob/observer/eye/ar_soul/vore(src, gem.owner)
gem.notify_holder("[src] now SR projecting.")
gem.clear_vore_fx(src)
// Jump to the owner as SR projection
/mob/living/carbon/brain/caught_soul/vore/jump_to_owner()
set name = "Jump to Owner"
set desc = "Jump your projection back to the owner of the soulcatcher you're inside."
set category = "Soulcatcher"
if(!eyeobj)
to_chat(src, span_warning("You're not projecting into SR!"))
return
eyeobj.forceMove(get_turf(gem))
// End SR projecting and return to the soulcatcher containing the soul
/mob/living/carbon/brain/caught_soul/vore/reenter_soulcatcher()
set name = "Re-enter Soulcatcher"
set desc = "Leave SR projection and drop back into the soulcatcher."
set category = "Soulcatcher"
if(!eyeobj)
to_chat(src, span_warning("You're not projecting into SR!"))
return
QDEL_NULL(eyeobj)
gem.notify_holder("[src] ended SR projection.")
gem.show_vore_fx(src, TRUE)
/mob/living/carbon/brain/caught_soul/vore/nsay_brain()
set name = "NSay"
set desc = "Speak to your Soulcatcher (circumventing SR speaking)."
set category = "Soulcatcher"
var/message = tgui_input_text(usr, "Type a message to say.","Speak into Soulcatcher", multiline=TRUE)
if(message)
var/sane_message = sanitize(message)
gem.use_speech(sane_message, src)
/mob/living/carbon/brain/caught_soul/vore/nme_brain()
set name = "NMe"
set desc = "Emote to your Soulcatcher (circumventing SR speaking)."
set category = "Soulcatcher"
var/message = tgui_input_text(usr, "Type an action to perform.","Emote into Soulcatcher", multiline=TRUE)
if(message)
var/sane_message = sanitize(message)
gem.use_emote(sane_message, src)
// Allows the captured owner to transfer themselves to valid nearby objects
/mob/living/carbon/brain/caught_soul/vore/proc/transfer_self()
set name = "Transfer Self"
set desc = "Transfer youself while being in your own soulcatcher into a nearby Sleevemate or MMI."
set category = "Soulcatcher"
if(eyeobj)
to_chat(src, span_warning("You can't do that while SR projecting!"))
return
if(gem.own_mind != mind)
to_chat(src, span_warning("You aren't in your own soulcatcher!"))
return
var/list/valid_objects = gem.find_transfer_objects()
if(!valid_objects || !valid_objects.len)
return
var/obj/target = tgui_input_list(src, "Select where you want to store your own mind into.", "Mind Transfer Target", valid_objects)
gem.transfer_mob_selector(src, target)
// Allows the owner to reenter the body after being caught or having given away control
/mob/living/carbon/brain/caught_soul/vore/proc/reenter_body()
set name = "Re-enter Body"
set desc = "Return to your body after self capturing."
set category = "Soulcatcher"
if(eyeobj)
to_chat(src, span_warning("You can't do that while SR projecting!"))
return
gem.return_to_body(mind)
@@ -1,52 +0,0 @@
/mob/observer/dead/verb/soulcatcherjoin()
set category = "Ghost.Join"
set name = "Join Into Soulcatcher(Vore)"
set desc = "Select a player with enabled Soulcatcher to join."
var/list/valid_players = list()
for(var/mob/player in player_list)
if(player.soulgem?.flag_check(SOULGEM_ACTIVE | SOULGEM_CATCHING_GHOSTS, TRUE))
valid_players += player
if(!valid_players.len)
to_chat(src, span_warning("No valid players found."))
return
var/picked = tgui_input_list(usr, "Pick a friend with enabled Soulcatcher to join into. Harrass strangers, get banned.","Select a player", valid_players)
if(!picked)
return
if(!ismob(picked))
to_chat(src, span_warning("Target is no mob."))
return
var/mob/M = picked
var/obj/soulgem/gem = M.soulgem
if(!gem?.flag_check(SOULGEM_ACTIVE))
to_chat(src, span_warning("[M] has no enabled Soulcatcher."))
return
var/req_time = world.time
gem.notify_holder("Transient mindstate detected, analyzing...")
sleep(15) //So if they are typing they get interrupted by sound and message, and don't type over the box
if(tgui_alert(M,"[src.name] wants to join into your Soulcatcher.","Soulcatcher Request",list("Deny","Allow"), timeout=1 MINUTES) != "Allow")
to_chat(src, span_warning("[M] has denied your request."))
return
if((world.time - req_time) > 1 MINUTES)
to_chat(M, span_warning("The request had already expired. (1 minute waiting max)"))
return
//Final check since we waited for input a couple times.
if(M && src && src.key && !M.stat && gem?.flag_check(SOULGEM_ACTIVE | SOULGEM_CATCHING_GHOSTS, TRUE))
if(!mind) //No mind yet, aka haven't played in this round.
mind = new(key)
mind.name = name
mind.current = src
mind.active = TRUE
gem.catch_mob(src) //This will result in us being deleted so...