diff --git a/code/datums/browser.dm b/code/datums/browser.dm
index d0fedd1316..e78833c958 100644
--- a/code/datums/browser.dm
+++ b/code/datums/browser.dm
@@ -15,9 +15,7 @@
var/content = ""
var/title_buttons = ""
-
/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null)
-
user = nuser
window_id = nwindow_id
if (ntitle)
@@ -33,6 +31,14 @@
return
add_stylesheet("common", 'html/browser/common.css') // this CSS sheet is common to all UIs
+//VOREStation Edit - Allow browser datums to be garbage collected
+/datum/browser/Destroy()
+ close()
+ ref = null
+ user = null
+ . = ..()
+//VOREStation Edit End - Allow browser datums to be garbage collected
+
/datum/browser/proc/set_title(ntitle)
title = format_text(ntitle)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index d1bd905d4d..557a3dd83b 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -57,7 +57,6 @@
for(var/organ in organs)
qdel(organ)
QDEL_NULL(nif) //VOREStation Add
- QDEL_LIST_NULL(vore_organs) //VOREStation Add
return ..()
/mob/living/carbon/human/Stat()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index b504698afe..dd2bb820ea 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -32,6 +32,8 @@
if(buckled)
buckled.unbuckle_mob(src, TRUE)
qdel(selected_image)
+ QDEL_NULL(vorePanel) //VOREStation Add
+ QDEL_LIST_NULL(vore_organs) //VOREStation Add
return ..()
//mob verbs are faster than object verbs. See mob/verb/examine.
diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm b/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm
index 74b3f3aa33..7d32b7b350 100644
--- a/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm
@@ -121,7 +121,7 @@
/mob/living/simple_mob/vore/aggressive/corrupthound/space/Process_Spacemove(var/check_drift = 0)
return TRUE
-/mob/living/simple_mob/vore/hostile/corrupthound/init_vore()
+/mob/living/simple_mob/vore/aggressive/corrupthound/init_vore()
..()
var/obj/belly/B = vore_selected
B.name = "fuel processor"
@@ -143,7 +143,7 @@
"The longer you spend stewing away in the pool of hot, clingy juices surrounding you, the weaker and weaker you seem to feel!",
"'FU3L mE A1RE@Dy, S0 sO SORrY!?', your corrupted captor growls as its synthetic innards begin oozing more potent juices, grinding down into your body with increasing fervor!")
-/mob/living/simple_mob/vore/hostile/corrupthound/prettyboi/init_vore()
+/mob/living/simple_mob/vore/aggressive/corrupthound/prettyboi/init_vore()
..()
var/obj/belly/B = vore_selected
B.name = "fuel processor"
diff --git a/code/modules/vore/eating/belly_obj_vr.dm b/code/modules/vore/eating/belly_obj_vr.dm
index a6221a4a57..c924cbcebd 100644
--- a/code/modules/vore/eating/belly_obj_vr.dm
+++ b/code/modules/vore/eating/belly_obj_vr.dm
@@ -59,7 +59,6 @@
var/tmp/list/items_preserved = list() // Stuff that wont digest so we shouldn't process it again.
var/tmp/next_emote = 0 // When we're supposed to print our next emote, as a belly controller tick #
var/tmp/recent_sound = FALSE // Prevent audio spam
- var/tmp/list/hearing_mobs
// Don't forget to watch your commas at the end of each line if you change these.
var/list/struggle_messages_outside = list(
@@ -177,7 +176,7 @@
. = ..()
// Called whenever an atom enters this belly
-/obj/belly/Entered(var/atom/movable/thing,var/atom/OldLoc)
+/obj/belly/Entered(atom/movable/thing, atom/OldLoc)
if(OldLoc in contents)
return //Someone dropping something (or being stripdigested)
@@ -207,8 +206,7 @@
// Release all contents of this belly into the owning mob's location.
// If that location is another mob, contents are transferred into whichever of its bellies the owning mob is in.
// Returns the number of mobs so released.
-/obj/belly/proc/release_all_contents(var/include_absorbed = FALSE, var/silent = FALSE)
-
+/obj/belly/proc/release_all_contents(include_absorbed = FALSE, silent = FALSE)
//Don't bother if we don't have contents
if(!contents.len)
return FALSE
@@ -246,7 +244,7 @@
// Release a specific atom from the contents of this belly into the owning mob's location.
// If that location is another mob, the atom is transferred into whichever of its bellies the owning mob is in.
// Returns the number of atoms so released.
-/obj/belly/proc/release_specific_contents(var/atom/movable/M, var/silent = FALSE)
+/obj/belly/proc/release_specific_contents(atom/movable/M, silent = FALSE)
if (!(M in contents))
return 0 // They weren't in this belly anyway
@@ -294,10 +292,10 @@
// Actually perform the mechanics of devouring the tasty prey.
// The purpose of this method is to avoid duplicate code, and ensure that all necessary
// steps are taken.
-/obj/belly/proc/nom_mob(var/mob/prey, var/mob/user)
+/obj/belly/proc/nom_mob(mob/prey, mob/user)
if(owner.stat == DEAD)
return
- if (prey.buckled)
+ if(prey.buckled)
prey.buckled.unbuckle_mob()
prey.forceMove(src)
@@ -316,9 +314,9 @@
var/raw_message = pick(examine_messages)
var/total_bulge = 0
- formatted_message = replacetext(raw_message,"%belly",lowertext(name))
- formatted_message = replacetext(formatted_message,"%pred",owner)
- formatted_message = replacetext(formatted_message,"%prey",english_list(contents))
+ formatted_message = replacetext(raw_message, "%belly" ,lowertext(name))
+ formatted_message = replacetext(formatted_message, "%pred" ,owner)
+ formatted_message = replacetext(formatted_message, "%prey" ,english_list(contents))
for(var/mob/living/P in contents)
if(!P.absorbed) //This is required first, in case there's a person absorbed and not absorbed in a stomach.
total_bulge += P.size_multiplier
@@ -330,10 +328,10 @@
// The next function gets the messages set on the belly, in human-readable format.
// This is useful in customization boxes and such. The delimiter right now is \n\n so
// in message boxes, this looks nice and is easily delimited.
-/obj/belly/proc/get_messages(var/type, var/delim = "\n\n")
+/obj/belly/proc/get_messages(type, delim = "\n\n")
ASSERT(type == "smo" || type == "smi" || type == "dmo" || type == "dmp" || type == "em")
+
var/list/raw_messages
-
switch(type)
if("smo")
raw_messages = struggle_messages_outside
@@ -346,13 +344,13 @@
if("em")
raw_messages = examine_messages
- var/messages = list2text(raw_messages,delim)
+ var/messages = list2text(raw_messages, delim)
return messages
// The next function sets the messages on the belly, from human-readable var
// replacement strings and linebreaks as delimiters (two \n\n by default).
// They also sanitize the messages.
-/obj/belly/proc/set_messages(var/raw_text, var/type, var/delim = "\n\n")
+/obj/belly/proc/set_messages(raw_text, type, delim = "\n\n")
ASSERT(type == "smo" || type == "smi" || type == "dmo" || type == "dmp" || type == "em")
var/list/raw_list = text2list(html_encode(raw_text),delim)
@@ -389,8 +387,8 @@
// Called from the process_Life() methods of bellies that digest prey.
// Default implementation calls M.death() and removes from internal contents.
// Indigestable items are removed, and M is deleted.
-/obj/belly/proc/digestion_death(var/mob/living/M)
- message_admins("[key_name(owner)] has digested [key_name(M)] in their [lowertext(name)] ([owner ? "JMP" : "null"])")
+/obj/belly/proc/digestion_death(mob/living/M)
+ message_admins("[key_name(owner)] has digested [key_name(M)] in their [lowertext(name)] ([owner ? ADMIN_JMP(owner) : "null"])")
// If digested prey is also a pred... anyone inside their bellies gets moved up.
if(is_vore_predator(M))
@@ -399,7 +397,7 @@
//Drop all items into the belly.
if(config.items_survive_digestion)
for(var/obj/item/W in M)
- if(istype(W,/obj/item/organ/internal/mmi_holder/posibrain))
+ if(istype(W, /obj/item/organ/internal/mmi_holder/posibrain))
var/obj/item/organ/internal/mmi_holder/MMI = W
var/atom/movable/brain = MMI.removed()
if(brain)
@@ -410,7 +408,7 @@
var/obj/item/I = M.get_equipped_item(slot = slot)
if(I)
M.unEquip(I,force = TRUE)
- if(contaminates || istype(I,/obj/item/weapon/card/id))
+ if(contaminates || istype(I, /obj/item/weapon/card/id))
I.gurgle_contaminate(contents, contamination_flavor, contamination_color) //We do an initial contamination pass to get stuff like IDs wet.
if(item_digest_mode == IM_HOLD)
items_preserved |= I
@@ -435,10 +433,10 @@
qdel(M)
// Handle a mob being absorbed
-/obj/belly/proc/absorb_living(var/mob/living/M)
+/obj/belly/proc/absorb_living(mob/living/M)
M.absorbed = 1
- to_chat(M,"[owner]'s [lowertext(name)] absorbs your body, making you part of them.")
- to_chat(owner,"Your [lowertext(name)] absorbs [M]'s body, making them part of you.")
+ to_chat(M, "[owner]'s [lowertext(name)] absorbs your body, making you part of them.")
+ to_chat(owner, "Your [lowertext(name)] absorbs [M]'s body, making them part of you.")
if(M.noisy) //Mute drained absorbee hunger if enabled.
M.noisy = FALSE
@@ -473,7 +471,7 @@
//Digest a single item
//Receives a return value from digest_act that's how much nutrition
//the item should be worth
-/obj/belly/proc/digest_item(var/obj/item/item)
+/obj/belly/proc/digest_item(obj/item/item)
var/digested = item.digest_act(src, owner)
if(!digested)
items_preserved |= item
@@ -482,6 +480,7 @@
if(isrobot(owner))
var/mob/living/silicon/robot/R = owner
R.cell.charge += (50 * digested)
+ return digested
//Determine where items should fall out of us into.
//Typically just to the owner's location.
@@ -499,20 +498,20 @@
/obj/belly/AllowDrop()
return TRUE
-/obj/belly/onDropInto(var/atom/movable/AM)
+/obj/belly/onDropInto(atom/movable/AM)
return null
//Handle a mob struggling
// Called from /mob/living/carbon/relaymove()
-/obj/belly/proc/relay_resist(var/mob/living/R)
+/obj/belly/proc/relay_resist(mob/living/R)
if (!(R in contents))
return // User is not in this belly
R.setClickCooldown(50)
if(owner.stat) //If owner is stat (dead, KO) we can actually escape
- to_chat(R,"You attempt to climb out of \the [lowertext(name)]. (This will take around [escapetime/10] seconds.)")
- to_chat(owner,"Someone is attempting to climb out of your [lowertext(name)]!")
+ to_chat(R, "You attempt to climb out of \the [lowertext(name)]. (This will take around [escapetime/10] seconds.)")
+ to_chat(owner, "Someone is attempting to climb out of your [lowertext(name)]!")
if(do_after(R, escapetime, owner, incapacitation_flags = INCAPACITATION_DEFAULT & ~INCAPACITATION_RESTRAINED))
if((owner.stat || escapable) && (R.loc == src)) //Can still escape?
@@ -528,20 +527,20 @@
var/struggle_outer_message = pick(struggle_messages_outside)
var/struggle_user_message = pick(struggle_messages_inside)
- struggle_outer_message = replacetext(struggle_outer_message,"%pred",owner)
- struggle_outer_message = replacetext(struggle_outer_message,"%prey",R)
- struggle_outer_message = replacetext(struggle_outer_message,"%belly",lowertext(name))
+ struggle_outer_message = replacetext(struggle_outer_message, "%pred", owner)
+ struggle_outer_message = replacetext(struggle_outer_message, "%prey", R)
+ struggle_outer_message = replacetext(struggle_outer_message, "%belly", lowertext(name))
- struggle_user_message = replacetext(struggle_user_message,"%pred",owner)
- struggle_user_message = replacetext(struggle_user_message,"%prey",R)
- struggle_user_message = replacetext(struggle_user_message,"%belly",lowertext(name))
+ struggle_user_message = replacetext(struggle_user_message, "%pred", owner)
+ struggle_user_message = replacetext(struggle_user_message, "%prey", R)
+ struggle_user_message = replacetext(struggle_user_message, "%belly", lowertext(name))
- struggle_outer_message = "" + struggle_outer_message + ""
- struggle_user_message = "" + struggle_user_message + ""
+ struggle_outer_message = "[struggle_outer_message]"
+ struggle_user_message = "[struggle_user_message]"
for(var/mob/M in hearers(4, owner))
M.show_message(struggle_outer_message, 2) // hearable
- to_chat(R,struggle_user_message)
+ to_chat(R, struggle_user_message)
var/sound/struggle_snuggle
var/sound/struggle_rustle = sound(get_sfx("rustle"))
@@ -557,8 +556,8 @@
if(escapable) //If the stomach has escapable enabled.
if(prob(escapechance)) //Let's have it check to see if the prey escapes first.
- to_chat(R,"You start to climb out of \the [lowertext(name)].")
- to_chat(owner,"Someone is attempting to climb out of your [lowertext(name)]!")
+ to_chat(R, "You start to climb out of \the [lowertext(name)].")
+ to_chat(owner, "Someone is attempting to climb out of your [lowertext(name)]!")
if(do_after(R, escapetime))
if((escapable) && (R.loc == src) && !R.absorbed) //Does the owner still have escapable enabled?
release_specific_contents(R)
@@ -588,26 +587,26 @@
transferlocation = null
return
- to_chat(R,"Your attempt to escape [lowertext(name)] has failed and your struggles only results in you sliding into [owner]'s [transferlocation]!")
- to_chat(owner,"Someone slid into your [transferlocation] due to their struggling inside your [lowertext(name)]!")
+ to_chat(R, "Your attempt to escape [lowertext(name)] has failed and your struggles only results in you sliding into [owner]'s [transferlocation]!")
+ to_chat(owner, "Someone slid into your [transferlocation] due to their struggling inside your [lowertext(name)]!")
transfer_contents(R, dest_belly)
return
else if(prob(absorbchance) && digest_mode != DM_ABSORB) //After that, let's have it run the absorb chance.
- to_chat(R,"In response to your struggling, \the [lowertext(name)] begins to cling more tightly...")
- to_chat(owner,"You feel your [lowertext(name)] start to cling onto its contents...")
+ to_chat(R, "In response to your struggling, \the [lowertext(name)] begins to cling more tightly...")
+ to_chat(owner, "You feel your [lowertext(name)] start to cling onto its contents...")
digest_mode = DM_ABSORB
return
else if(prob(digestchance) && digest_mode != DM_DIGEST) //Finally, let's see if it should run the digest chance.
- to_chat(R,"In response to your struggling, \the [lowertext(name)] begins to get more active...")
- to_chat(owner,"You feel your [lowertext(name)] beginning to become active!")
+ to_chat(R, "In response to your struggling, \the [lowertext(name)] begins to get more active...")
+ to_chat(owner, "You feel your [lowertext(name)] beginning to become active!")
digest_mode = DM_DIGEST
return
else //Nothing interesting happened.
- to_chat(R,"You make no progress in escaping [owner]'s [lowertext(name)].")
- to_chat(owner,"Your prey appears to be unable to make any progress in escaping your [lowertext(name)].")
+ to_chat(R, "You make no progress in escaping [owner]'s [lowertext(name)].")
+ to_chat(owner, "Your prey appears to be unable to make any progress in escaping your [lowertext(name)].")
return
/obj/belly/proc/get_mobs_and_objs_in_belly()
@@ -624,7 +623,7 @@
return see
//Transfers contents from one belly to another
-/obj/belly/proc/transfer_contents(var/atom/movable/content, var/obj/belly/target, silent = 0)
+/obj/belly/proc/transfer_contents(atom/movable/content, obj/belly/target, silent = 0)
if(!(content in src) || !istype(target))
return
content.forceMove(target)
@@ -636,16 +635,6 @@
I.decontaminate()
I.gurgle_contaminate(target.contents, target.contamination_flavor, target.contamination_color)
items_preserved -= content
- /* Disabling this part due to redundancy. Entered() on target belly will make the sound anyway.
- if(!silent && target.vore_sound && !recent_sound)
- var/soundfile
- if(!target.fancy_vore)
- soundfile = classic_vore_sounds[target.vore_sound]
- else
- soundfile = fancy_vore_sounds[target.vore_sound]
- if(soundfile)
- playsound(src, soundfile, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/digestion_noises)
- */
owner.updateVRPanel()
for(var/mob/living/M in contents)
M.updateVRPanel()
diff --git a/code/modules/vore/eating/bellymodes_tf_vr.dm b/code/modules/vore/eating/bellymodes_tf_vr.dm
index d2a379a336..32a6e91a4c 100644
--- a/code/modules/vore/eating/bellymodes_tf_vr.dm
+++ b/code/modules/vore/eating/bellymodes_tf_vr.dm
@@ -1,4 +1,4 @@
-/obj/belly/proc/process_tf(var/mode,var/list/touchable_mobs) //We pass mode so it's mega-ultra local.
+/obj/belly/proc/process_tf(mode, list/touchable_mobs) //We pass mode so it's mega-ultra local.
/* May not be necessary... Transform only shows up in the panel for humans.
if(!ishuman(owner))
return //Need DNA and junk for this.
@@ -7,231 +7,86 @@
//Cast here for reduced duplication
var/mob/living/carbon/human/O = owner
-///////////////////////////// DM_TRANSFORM_HAIR_AND_EYES /////////////////////////////
- if(mode == DM_TRANSFORM_HAIR_AND_EYES)
- for (var/mob/living/carbon/human/P in touchable_mobs)
- if(P.stat == DEAD)
- continue
+ var/stabilize_nutrition = FALSE
+ var/changes_eyes = FALSE
+ var/changes_hair_solo = FALSE
+ var/changes_hairandskin = FALSE
+ var/changes_gender = FALSE
+ var/changes_gender_to = null
+ var/changes_species = FALSE
+ var/changes_ears_tail_wing_nocolor = FALSE
+ var/changes_ears_tail_wing_color = FALSE
+ var/eggs = FALSE
- if(O.nutrition > 400 && P.nutrition < 400)
+ switch(mode)
+ if(DM_TRANSFORM_HAIR_AND_EYES)
+ stabilize_nutrition = TRUE
+ changes_eyes = TRUE
+ changes_hair_solo = TRUE
+ if(DM_TRANSFORM_MALE, DM_TRANSFORM_FEMALE, DM_TRANSFORM_MALE_EGG, DM_TRANSFORM_FEMALE_EGG)
+ changes_eyes = TRUE
+ changes_hairandskin = TRUE
+ changes_gender = TRUE
+ changes_gender_to = (mode == DM_TRANSFORM_MALE || mode == DM_TRANSFORM_MALE_EGG) ? MALE : FEMALE
+ stabilize_nutrition = TRUE
+ eggs = (mode == DM_TRANSFORM_MALE_EGG || mode == DM_TRANSFORM_FEMALE_EGG)
+ if(DM_TRANSFORM_KEEP_GENDER, DM_TRANSFORM_KEEP_GENDER_EGG)
+ changes_eyes = TRUE
+ changes_hairandskin = TRUE
+ stabilize_nutrition = TRUE
+ eggs = (mode == DM_TRANSFORM_KEEP_GENDER_EGG)
+ if(DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR, DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG)
+ changes_species = TRUE
+ changes_ears_tail_wing_nocolor = TRUE
+ stabilize_nutrition = TRUE
+ eggs = (mode == DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG)
+ if(DM_TRANSFORM_REPLICA, DM_TRANSFORM_REPLICA_EGG)
+ changes_eyes = TRUE
+ changes_hairandskin = TRUE
+ changes_species = TRUE
+ changes_ears_tail_wing_color = TRUE
+ eggs = (mode == DM_TRANSFORM_REPLICA_EGG)
+ if(DM_EGG)
+ eggs = TRUE
+
+ /* This is designed to do *gradual* transformations.
+ * For each human in the TF belly per cycle, they can only have one "stage" of transformation applied to them.
+ * Some transformation modes have different amounts of stages than others and that's okay.
+ * All stages in order: Eyes, Hair & Skin, Ears & Tail & Wings & Species, Gender, Egg
+ */
+ for(var/mob/living/carbon/human/H in touchable_mobs)
+ if(H.stat == DEAD)
+ continue
+ if(stabilize_nutrition)
+ if(O.nutrition > 400 && H.nutrition < 400)
O.nutrition -= 2
- P.nutrition += 1.5
-
- if(check_eyes(P) || check_hair(P))
- change_eyes(P)
- change_hair(P,1)
-
-///////////////////////////// DM_TRANSFORM_MALE /////////////////////////////
- else if(mode == DM_TRANSFORM_MALE)
- for (var/mob/living/carbon/human/P in touchable_mobs)
- if(P.stat == DEAD)
+ H.nutrition += 1.5
+ if(changes_eyes && check_eyes(H))
+ change_eyes(H, 1)
+ continue
+ if(changes_hair_solo && check_hair(H))
+ change_hair(H)
+ continue
+ if(changes_hairandskin && (check_hair(H) || check_skin(H)))
+ change_hair(H)
+ change_skin(H, 1)
+ continue
+ if(changes_species)
+ if(changes_ears_tail_wing_nocolor && (check_ears(H) || check_tail_nocolor(H) || check_wing_nocolor(H) || check_species(H)))
+ change_ears(H)
+ change_tail_nocolor(H)
+ change_wing_nocolor(H)
+ change_species(H, 1, 1) // ,1) preserves coloring
continue
-
- if(O.nutrition > 400 && P.nutrition < 400)
- O.nutrition -= 2
- P.nutrition += 1.5
-
- if(check_eyes(P))
- change_eyes(P,1)
+ if(changes_ears_tail_wing_color && (check_ears(H) || check_tail(H) || check_wing(H) || check_species(H)))
+ change_ears(H)
+ change_tail(H)
+ change_wing(H)
+ change_species(H, 1, 2) // ,2) does not preserve coloring.
continue
-
- if(check_hair(P) || check_skin(P))
- change_hair(P)
- change_skin(P,1)
- continue
-
- if(check_gender(P,MALE))
- change_gender(P,MALE,1)
-
-///////////////////////////// DM_TRANSFORM_FEMALE /////////////////////////////
- else if(mode == DM_TRANSFORM_FEMALE)
- for (var/mob/living/carbon/human/P in touchable_mobs)
- if(P.stat == DEAD)
- continue
-
- if(O.nutrition > 400 && P.nutrition < 400)
- O.nutrition -= 2
- P.nutrition += 1.5
-
- if(check_eyes(P))
- change_eyes(P,1)
- continue
-
- if(check_hair(P) || check_skin(P))
- change_hair(P)
- change_skin(P,1)
- continue
-
- if(check_gender(P,FEMALE))
- change_gender(P,FEMALE,1)
-
-///////////////////////////// DM_TRANSFORM_KEEP_GENDER /////////////////////////////
- else if(mode == DM_TRANSFORM_KEEP_GENDER)
- for (var/mob/living/carbon/human/P in touchable_mobs)
- if(P.stat == DEAD)
- continue
-
- if(O.nutrition > 400 && P.nutrition < 400)
- O.nutrition -= 2
- P.nutrition += 1.5
-
- if(check_eyes(P))
- change_eyes(P,1)
- continue
-
- if(check_hair(P) || check_skin(P))
- change_hair(P)
- change_skin(P,1)
-
-///////////////////////////// DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR /////////////////////////////
- else if(mode == DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR)
- for (var/mob/living/carbon/human/P in touchable_mobs)
- if(P.stat == DEAD)
- continue
-
- if(O.nutrition > 400 && P.nutrition < 400)
- O.nutrition -= 2
- P.nutrition += 1.5
-
- if(check_ears(P) || check_tail_nocolor(P) || check_wing_nocolor(P) || check_species(P))
- change_ears(P)
- change_tail_nocolor(P)
- change_wing_nocolor(P)
- change_species(P,1,1)
-
-///////////////////////////// DM_TRANSFORM_REPLICA /////////////////////////////
- else if(mode == DM_TRANSFORM_REPLICA)
- for (var/mob/living/carbon/human/P in touchable_mobs)
- if(P.stat == DEAD)
- continue
-
- if(O.nutrition > 400 && P.nutrition < 400)
- O.nutrition -= 2
- P.nutrition += 1.5
-
- if(check_eyes(P))
- change_eyes(P,1)
- continue
-
- if(check_hair(P) || check_skin(P))
- change_hair(P)
- change_skin(P,1)
- continue
-
- if(check_ears(P) || check_tail(P) || check_wing(P) || check_species(P))
- change_ears(P)
- change_tail(P)
- change_wing(P)
- change_species(P,1,2)
-
-///////////////////////////// DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG /////////////////////////////
- else if(mode == DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG)
- for (var/mob/living/carbon/human/P in touchable_mobs)
- if(P.stat == DEAD)
- continue
-
- if(check_ears(P) || check_tail_nocolor(P) || check_wing_nocolor(P)|| check_species(P))
- change_ears(P)
- change_tail_nocolor(P)
- change_wing_nocolor(P)
- change_species(P,1,1)
- continue
-
- if(!P.absorbed)
- put_in_egg(P,1)
-
-///////////////////////////// DM_TRANSFORM_KEEP_GENDER_EGG /////////////////////////////
- else if(mode == DM_TRANSFORM_KEEP_GENDER_EGG)
- for (var/mob/living/carbon/human/P in touchable_mobs)
- if(P.stat == DEAD)
- continue
-
- if(check_eyes(P))
- change_eyes(P,1)
- continue
-
- if(check_hair(P) || check_skin(P))
- change_hair(P)
- change_skin(P,1)
- continue
-
- if(!P.absorbed)
- put_in_egg(P,1)
-
-///////////////////////////// DM_TRANSFORM_REPLICA_EGG /////////////////////////////
- else if(mode == DM_TRANSFORM_REPLICA_EGG)
- for (var/mob/living/carbon/human/P in touchable_mobs)
- if(P.stat == DEAD)
- continue
-
- if(check_eyes(P))
- change_eyes(P,1)
- continue
-
- if(check_hair(P) || check_skin(P))
- change_hair(P)
- change_skin(P,1)
- continue
-
- if(check_ears(P) || check_tail(P) || check_wing(P) || check_species(P))
- change_ears(P)
- change_tail(P)
- change_wing(P)
- change_species(P,1,2)
- continue
-
- if(!P.absorbed)
- put_in_egg(P,1)
-
-///////////////////////////// DM_TRANSFORM_MALE_EGG /////////////////////////////
- else if(mode == DM_TRANSFORM_MALE_EGG)
- for (var/mob/living/carbon/human/P in touchable_mobs)
- if(P.stat == DEAD)
- continue
-
- if(check_eyes(P))
- change_eyes(P,1)
- continue
-
- if(check_hair(P) || check_skin(P))
- change_hair(P)
- change_skin(P,1)
- continue
-
- if(check_gender(P,MALE))
- change_gender(P,MALE,1)
- continue
-
- if(!P.absorbed)
- put_in_egg(P,1)
-
-///////////////////////////// DM_TRANSFORM_FEMALE_EGG /////////////////////////////
- else if(mode == DM_TRANSFORM_FEMALE_EGG)
- for (var/mob/living/carbon/human/P in touchable_mobs)
- if(P.stat == DEAD)
- continue
-
- if(check_eyes(P))
- change_eyes(P,1)
- continue
-
- if(check_hair(P) || check_skin(P))
- change_hair(P)
- change_skin(P,1)
- continue
-
- if(check_gender(P,MALE))
- change_gender(P,MALE,1)
- continue
-
- if(!P.absorbed)
- put_in_egg(P,1)
-
-///////////////////////////// DM_EGG /////////////////////////////
- else if(mode == DM_EGG)
- for (var/mob/living/carbon/human/P in touchable_mobs)
- if(P.absorbed || P.stat == DEAD)
- continue
-
- put_in_egg(P,1)
-
+ if(changes_gender && check_gender(H, changes_gender_to))
+ change_gender(H, changes_gender_to, 1)
+ continue
+ if(eggs && (!H.absorbed))
+ put_in_egg(H, 1)
+ continue
\ No newline at end of file
diff --git a/code/modules/vore/eating/bellymodes_vr.dm b/code/modules/vore/eating/bellymodes_vr.dm
index 605fea6cd9..6bb6620c95 100644
--- a/code/modules/vore/eating/bellymodes_vr.dm
+++ b/code/modules/vore/eating/bellymodes_vr.dm
@@ -1,5 +1,5 @@
// Process the predator's effects upon the contents of its belly (i.e digestion/transformation etc)
-/obj/belly/proc/process_belly(var/times_fired,var/wait) //Passed by controller
+/obj/belly/proc/process_belly(times_fired, wait) //Passed by controller
if((times_fired < next_process) || !contents.len)
recent_sound = FALSE
return SSBELLIES_IGNORED
@@ -11,31 +11,13 @@
qdel(src)
return SSBELLIES_PROCESSED
- next_process = times_fired + (6 SECONDS/wait) //Set up our next process time.
+ next_process = times_fired + (6 SECONDS / wait) //Set up our next process time.
+
var/play_sound //Potential sound to play at the end to avoid code duplication.
var/to_update = FALSE //Did anything update worthy happen?
-/////////////////////////// Auto-Emotes ///////////////////////////
- if(contents.len && next_emote <= times_fired)
- next_emote = times_fired + round(emote_time/wait,1)
- var/list/EL = emote_lists[digest_mode]
- if(LAZYLEN(EL))
- for(var/mob/living/M in contents)
- if(M.digestable || digest_mode != DM_DIGEST) // don't give digesty messages to indigestible people
- to_chat(M,"[pick(EL)]")
-
///////////////////// Prey Loop Refresh/hack //////////////////////
- for(var/mob/living/M in contents)
- M.stop_sound_channel(CHANNEL_PREYLOOP) // sanity just in case, because byond is whack and you can't trust it
- if(isbelly(M.loc)) //sanity check
- if(world.time > M.next_preyloop) //We don't want it to overlap, but we also want it to replay.
- if(is_wet && wet_loop) // Is it a fleshy environment, and does the pred have a fleshy heartbeat loop to play?
- if(!M.client)
- continue
- if(M.is_preference_enabled(/datum/client_preference/digestion_noises)) //then we check if the mob has sounds enabled at all
- var/sound/preyloop = sound('sound/vore/sunesound/prey/loop.ogg')
- M.playsound_local(get_turf(src),preyloop, 80,0, channel = CHANNEL_PREYLOOP)
- M.next_preyloop = (world.time + (52 SECONDS))
+ prey_loop()
/////////////////////////// Sound Selections ///////////////////////////
var/sound/prey_digest
@@ -61,31 +43,30 @@
var/list/touchable_mobs = list()
///////////////////// Early Non-Mode Handling /////////////////////
- var/did_an_item = FALSE
+ if(contents.len && next_emote <= times_fired)
+ next_emote = times_fired + round(emote_time/wait,1)
+ var/list/EL = emote_lists[digest_mode]
+ if(LAZYLEN(EL))
+ for(var/mob/living/M in contents)
+ if(M.digestable || digest_mode != DM_DIGEST) // don't give digesty messages to indigestible people
+ to_chat(M, "[pick(EL)]")
+
+ var/did_an_item = FALSE // Only do one item per cycle.
+ var/digestion_noise_chance = 0
+
for(var/A in touchable_atoms)
//Handle stray items
if(isitem(A) && !did_an_item)
- var/obj/item/I = A
- if(contaminates || istype(I,/obj/item/weapon/card/id))
- I.gurgle_contaminate(src, contamination_flavor, contamination_color)
- if(item_digest_mode == IM_HOLD)
- items_preserved |= I
- else if(item_digest_mode == IM_DIGEST_FOOD)
- if(istype(I,/obj/item/weapon/reagent_containers/food) || istype(I,/obj/item/organ))
- digest_item(I)
- else
- items_preserved |= I
- if(prob(25)) //Less often than with normal digestion
- play_sound = pick(pred_digest)
- else if(item_digest_mode == IM_DIGEST)
- if(I.digest_stage && I.digest_stage > 0)
- digest_item(I)
- else
- digest_item(I)
- did_an_item = TRUE
+ did_an_item = handle_digesting_item(A)
+ if(did_an_item)
to_update = TRUE
- if(prob(25)) //Less often than with normal digestion
- play_sound = pick(pred_digest)
+
+ //Less often than with normal digestion
+ if((item_digest_mode == IM_DIGEST_FOOD || item_digest_mode == IM_DIGEST) && prob(25))
+ // This is a little weird, but the point of it is that we don't want to repeat code
+ // but we also want the prob(25) chance to run for -every- item we look at, not just once
+ // More gurgles the better~
+ digestion_noise_chance = 25
//Handle eaten mobs
else if(isliving(A))
@@ -105,278 +86,218 @@
H.bloodstr.add_reagent("numbenzyme",4)
//Thickbelly flag
- if(mode_flags & DM_FLAG_THICKBELLY)
- if(!(H.muffled))
- H.muffled = 1
+ if((mode_flags & DM_FLAG_THICKBELLY) && !H.muffled)
+ H.muffled = TRUE
//Stripping flag
if(mode_flags & DM_FLAG_STRIPPING)
for(var/slot in slots)
var/obj/item/I = H.get_equipped_item(slot = slot)
- if(I)
- H.unEquip(I,force = FALSE)
- if(contaminates || istype(I,/obj/item/weapon/card/id))
- I.gurgle_contaminate(contents, contamination_flavor, contamination_color)
- if(item_digest_mode == IM_HOLD)
- items_preserved |= I
- else if(item_digest_mode == IM_DIGEST_FOOD)
- if(istype(I,/obj/item/weapon/reagent_containers/food) || istype(I,/obj/item/organ))
- digest_item(I)
- else
- items_preserved |= I
- if(prob(25)) //Less often than with normal digestion
- if(L && L.client && L.is_preference_enabled(/datum/client_preference/digestion_noises))
- SEND_SOUND(L,prey_digest)
- play_sound = pick(pred_digest)
- else if(item_digest_mode == IM_DIGEST)
- digest_item(I)
- if(prob(25)) //Less often than with normal digestion
- if(L && L.client && L.is_preference_enabled(/datum/client_preference/digestion_noises))
- SEND_SOUND(L,prey_digest)
- play_sound = pick(pred_digest)
+ if(I && H.unEquip(I, force = FALSE))
+ handle_digesting_item(I)
+ digestion_noise_chance = 25
to_update = TRUE
- break
+ break // Digest off one by one, not all at once
+
//get rid of things like blood drops and gibs that end up in there
- else if(istype(A,/obj/effect/decal/cleanable/))
+ else if(istype(A, /obj/effect/decal/cleanable))
qdel(A)
-///////////////////////////// DM_HOLD /////////////////////////////
if(digest_mode == DM_HOLD)
- return SSBELLIES_PROCESSED //Pretty boring, huh
+ //We deliberately do not want any gurgly noises if the belly is in DM_HOLD
+ if(to_update)
+ updateVRPanels()
+ return SSBELLIES_PROCESSED
-//////////////////////////// DM_DIGEST ////////////////////////////
- else if(digest_mode == DM_DIGEST)
-
- if(prob(50)) //Was SO OFTEN. AAAA.
- for(var/mob/M in contents)
- if(M && M.client && M.is_preference_enabled(/datum/client_preference/digestion_noises))
- SEND_SOUND(M,prey_digest)
- play_sound = pick(pred_digest)
-
- for (var/target in touchable_mobs)
- var/mob/living/M = target
- //Pref protection!
- if (!M.digestable || M.absorbed)
- continue
-
- //Person just died in guts!
- if(M.stat == DEAD)
- var/digest_alert_owner = pick(digest_messages_owner)
- var/digest_alert_prey = pick(digest_messages_prey)
- var/compensation = M.getOxyLoss() //How much of the prey's damage was caused by passive crit oxyloss to compensate the lost nutrition.
-
- //Replace placeholder vars
- digest_alert_owner = replacetext(digest_alert_owner,"%pred",owner)
- digest_alert_owner = replacetext(digest_alert_owner,"%prey",M)
- digest_alert_owner = replacetext(digest_alert_owner,"%belly",lowertext(name))
-
- digest_alert_prey = replacetext(digest_alert_prey,"%pred",owner)
- digest_alert_prey = replacetext(digest_alert_prey,"%prey",M)
- digest_alert_prey = replacetext(digest_alert_prey,"%belly",lowertext(name))
-
- //Send messages
- to_chat(owner,"" + digest_alert_owner + "")
- to_chat(M,"" + digest_alert_prey + "")
-
- play_sound = pick(pred_death)
- if(M && M.client && M.is_preference_enabled(/datum/client_preference/digestion_noises))
- SEND_SOUND(M,prey_death)
- if((mode_flags & DM_FLAG_LEAVEREMAINS) && M.digest_leave_remains)
- handle_remains_leaving(M)
- digestion_death(M)
- if(!ishuman(owner))
- owner.update_icons()
- if(compensation == 0) //Slightly sloppy way at making sure certain mobs don't give ZERO nutrition (fish and so on)
- compensation = 21 //This reads as 20*4.5 due to the calculations afterward, making the backup nutrition value 94.5 per mob. Not op compared to regular prey.
- if(compensation > 0)
- if(isrobot(owner))
- var/mob/living/silicon/robot/R = owner
- R.cell.charge += 25*compensation
- else
- owner.nutrition += (nutrition_percent / 100)*4.5*compensation
- to_update = TRUE
-
- continue
-
- // Deal digestion damage (and feed the pred)
- var/old_brute = M.getBruteLoss()
- var/old_burn = M.getFireLoss()
- M.adjustBruteLoss(digest_brute)
- M.adjustFireLoss(digest_burn)
- var/actual_brute = M.getBruteLoss() - old_brute
- var/actual_burn = M.getFireLoss() - old_burn
- var/damage_gain = actual_brute + actual_burn
-
- var/offset = (1 + ((M.weight - 137) / 137)) // 130 pounds = .95 140 pounds = 1.02
- var/difference = owner.size_multiplier / M.size_multiplier
- if(isrobot(owner))
- var/mob/living/silicon/robot/R = owner
- R.cell.charge += 25*damage_gain
- if(offset) // If any different than default weight, multiply the % of offset.
- owner.nutrition += offset*((nutrition_percent / 100)*4.5*(damage_gain)/difference) //4.5 nutrition points per health point. Normal same size 100+100 health prey with average weight would give 900 points if the digestion was instant. With all the size/weight offset taxes plus over time oxyloss+hunger taxes deducted with non-instant digestion, this should be enough to not leave the pred starved.
- else
- owner.nutrition += (nutrition_percent / 100)*4.5*(damage_gain)/difference
-
-
-//////////////////////////// DM_ABSORB ////////////////////////////
- else if(digest_mode == DM_ABSORB)
-
- for (var/target in touchable_mobs)
- var/mob/living/M = target
- if(M.absorbable == FALSE)
- return
- else
- if(prob(10)) //Less often than gurgles. People might leave this on forever.
- if(M && M.client && M.is_preference_enabled(/datum/client_preference/digestion_noises))
- SEND_SOUND(M,prey_digest)
- play_sound = pick(pred_digest)
-
- if(M.absorbed)
- continue
-
- if(M.nutrition >= 100) //Drain them until there's no nutrients left. Slowly "absorb" them.
- var/oldnutrition = (M.nutrition * 0.05)
- M.nutrition = (M.nutrition * 0.95)
- owner.nutrition += oldnutrition
- else if(M.nutrition < 100) //When they're finally drained.
- absorb_living(M)
- to_update = TRUE
-
-//////////////////////////// DM_UNABSORB ////////////////////////////
- else if(digest_mode == DM_UNABSORB)
-
- for (var/target in touchable_mobs)
- var/mob/living/M = target
-
- if(M.absorbed && owner.nutrition >= 100)
- M.absorbed = 0
- to_chat(M,"You suddenly feel solid again ")
- to_chat(owner,"You feel like a part of you is missing.")
- owner.nutrition -= 100
- to_update = TRUE
-
-//////////////////////////// DM_DRAIN ////////////////////////////
- else if(digest_mode == DM_DRAIN)
-
- for (var/target in touchable_mobs)
- var/mob/living/M = target
-
- if(prob(10)) //Less often than gurgles. People might leave this on forever.
- if(M && M.client && M.is_preference_enabled(/datum/client_preference/digestion_noises))
- SEND_SOUND(M,prey_digest)
- play_sound = pick(pred_digest)
-
- if(M.nutrition >= 100) //Drain them until there's no nutrients left.
- var/oldnutrition = (M.nutrition * 0.05)
- M.nutrition = (M.nutrition * 0.95)
- owner.nutrition += oldnutrition
-
-//////////////////////////// DM_SHRINK ////////////////////////////
- else if(digest_mode == DM_SHRINK)
-
- for (var/target in touchable_mobs)
- var/mob/living/M = target
-
- if(prob(10)) //Infinite gurgles!
- if(M && M.client && M.is_preference_enabled(/datum/client_preference/digestion_noises))
- SEND_SOUND(M,prey_digest)
- play_sound = pick(pred_digest)
-
- if(M.size_multiplier > shrink_grow_size) //Shrink until smol.
- M.resize(M.size_multiplier-0.01) //Shrink by 1% per tick.
-
- if(M.nutrition >= 100) //Absorbing bodymass results in nutrition if possible.
- var/oldnutrition = (M.nutrition * 0.05)
- M.nutrition = (M.nutrition * 0.95)
- owner.nutrition += oldnutrition
-
-//////////////////////////// DM_GROW ////////////////////////////
- else if(digest_mode == DM_GROW)
-
- for (var/target in touchable_mobs)
- var/mob/living/M = target
-
- if(prob(10))
- if(M && M.client && M.is_preference_enabled(/datum/client_preference/digestion_noises))
- SEND_SOUND(M,prey_digest)
- play_sound = pick(pred_digest)
-
- if(M.size_multiplier < shrink_grow_size) //Grow until large.
- M.resize(M.size_multiplier+0.01) //Grow by 1% per tick.
- if(M.nutrition >= 100)
- owner.nutrition = (owner.nutrition * 0.95)
-
-//////////////////////////// DM_SIZE_STEAL ////////////////////////////
- else if(digest_mode == DM_SIZE_STEAL)
-
- for (var/target in touchable_mobs)
- var/mob/living/M = target
-
- if(prob(10))
- if(M && M.client && M.is_preference_enabled(/datum/client_preference/digestion_noises))
- SEND_SOUND(M,prey_digest)
- play_sound = pick(pred_digest)
-
- if(M.size_multiplier > shrink_grow_size && owner.size_multiplier < 2) //Grow until either pred is large or prey is small.
- owner.resize(owner.size_multiplier+0.01) //Grow by 1% per tick.
- M.resize(M.size_multiplier-0.01) //Shrink by 1% per tick
-
- if(M.nutrition >= 100)
- var/oldnutrition = (M.nutrition * 0.05)
- M.nutrition = (M.nutrition * 0.95)
- owner.nutrition += oldnutrition
-
-///////////////////////////// DM_HEAL /////////////////////////////
- else if(digest_mode == DM_HEAL)
-
- if(prob(50)) //Wet heals! The secret is you can leave this on for gurgle noises for fun.
- for(var/mob/M in contents)
- if(M && M.client && M.is_preference_enabled(/datum/client_preference/digestion_noises))
- SEND_SOUND(M,prey_digest)
- play_sound = pick(pred_digest)
-
- for (var/target in touchable_mobs)
- var/mob/living/M = target
-
- if(M.stat == DEAD)
- continue
-
- if(owner.nutrition > 90 && (M.health < M.maxHealth))
- M.adjustBruteLoss(-2.5)
- M.adjustFireLoss(-2.5)
- M.adjustToxLoss(-5)
- M.adjustOxyLoss(-5)
- M.adjustCloneLoss(-1.25)
- owner.nutrition -= 2
- if(M.nutrition <= 400)
- M.nutrition += 1
- else if(owner.nutrition > 90 && (M.nutrition <= 400))
- owner.nutrition -= 1
- M.nutrition += 1
-
-/////////////////////////// DM_TRANSFORM ///////////////////////////
- else if(digest_mode == DM_TRANSFORM)
+ if(digest_mode == DM_TRANSFORM)
process_tf(tf_mode, touchable_mobs)
+ for(var/target in touchable_mobs)
+ var/mob/living/L = target
+ if(!istype(L))
+ continue
+ switch(digest_mode)
+ if(DM_DIGEST)
+ digestion_noise_chance = 50
+ //Pref protection!
+ if(!L.digestable || L.absorbed)
+ continue
+
+ //Person just died in guts!
+ if(L.stat == DEAD)
+ play_sound = pred_death
+ if(L.is_preference_enabled(/datum/client_preference/digestion_noises))
+ SEND_SOUND(L, prey_death)
+ handle_digestion_death(L)
+ to_update = TRUE
+ continue
+
+ // Deal digestion damage (and feed the pred)
+ var/old_brute = L.getBruteLoss()
+ var/old_burn = L.getFireLoss()
+ L.adjustBruteLoss(digest_brute)
+ L.adjustFireLoss(digest_burn)
+ var/actual_brute = L.getBruteLoss() - old_brute
+ var/actual_burn = L.getFireLoss() - old_burn
+ var/damage_gain = actual_brute + actual_burn
+
+ var/offset = (1 + ((L.weight - 137) / 137)) // 130 pounds = .95 140 pounds = 1.02
+ var/difference = owner.size_multiplier / L.size_multiplier
+ if(isrobot(owner))
+ var/mob/living/silicon/robot/R = owner
+ R.cell.charge += 25 * damage_gain
+ if(offset) // If any different than default weight, multiply the % of offset.
+ owner.nutrition += offset*((nutrition_percent / 100) * 4.5 * (damage_gain) / difference) //4.5 nutrition points per health point. Normal same size 100+100 health prey with average weight would give 900 points if the digestion was instant. With all the size/weight offset taxes plus over time oxyloss+hunger taxes deducted with non-instant digestion, this should be enough to not leave the pred starved.
+ else
+ owner.nutrition += (nutrition_percent / 100) * 4.5 * (damage_gain) / difference
+ if(DM_ABSORB)
+ if(!L.absorbable || L.absorbed)
+ continue
+ digestion_noise_chance = 10
+ steal_nutrition(L)
+ if(L.nutrition < 100)
+ absorb_living(L)
+ to_update = TRUE
+ if(DM_UNABSORB)
+ if(L.absorbed && owner.nutrition >= 100)
+ L.absorbed = FALSE
+ to_chat(L, "You suddenly feel solid again.")
+ to_chat(owner,"You feel like a part of you is missing.")
+ owner.nutrition -= 100
+ to_update = TRUE
+ if(DM_DRAIN)
+ digestion_noise_chance = 10
+ steal_nutrition(L)
+ if(DM_SHRINK)
+ digestion_noise_chance = 10
+ if(L.size_multiplier > shrink_grow_size)
+ L.resize(L.size_multiplier - 0.01) // Shrink by 1% per tick
+ steal_nutrition(L)
+ if(DM_GROW)
+ digestion_noise_chance = 10
+ if(L.size_multiplier < shrink_grow_size)
+ L.resize(L.size_multiplier - 0.01) // Grow by 1% per tick
+ if(DM_SIZE_STEAL)
+ digestion_noise_chance = 10
+ if(L.size_multiplier > shrink_grow_size && owner.size_multiplier < 2) //Grow until either pred is large or prey is small.
+ owner.resize(owner.size_multiplier+0.01) //Grow by 1% per tick.
+ L.resize(L.size_multiplier-0.01) //Shrink by 1% per tick
+ steal_nutrition(L)
+ if(DM_HEAL)
+ digestion_noise_chance = 50 //Wet heals! The secret is you can leave this on for gurgle noises for fun.
+ if(L.stat == DEAD)
+ continue // Can't heal the dead with healbelly
+ if(owner.nutrition > 90 && (L.health < L.maxHealth))
+ L.adjustBruteLoss(-2.5)
+ L.adjustFireLoss(-2.5)
+ L.adjustToxLoss(-5)
+ L.adjustOxyLoss(-5)
+ L.adjustCloneLoss(-1.25)
+ owner.nutrition -= 2
+ if(L.nutrition <= 400)
+ L.nutrition += 1
+ else if(owner.nutrition > 90 && (L.nutrition <= 400))
+ owner.nutrition -= 1
+ L.nutrition += 1
+
/////////////////////////// Make any noise ///////////////////////////
+ if(digestion_noise_chance && prob(digestion_noise_chance))
+ for(var/mob/M in contents)
+ if(M && M.is_preference_enabled(/datum/client_preference/digestion_noises))
+ SEND_SOUND(M, prey_digest)
+ play_sound = pred_digest
+
if(play_sound)
- LAZYCLEARLIST(hearing_mobs)
- for(var/mob/M in hearers(VORE_SOUND_RANGE, owner))
- if(!M.client || !(M.is_preference_enabled(/datum/client_preference/digestion_noises)))
+ for(var/mob/M in hearers(VORE_SOUND_RANGE, owner)) //so we don't fill the whole room with the sound effect
+ if(!M.is_preference_enabled(/datum/client_preference/digestion_noises))
continue
- LAZYADD(hearing_mobs, M)
- for(var/mob/M in hearing_mobs) //so we don't fill the whole room with the sound effect
- if(M && M.client && (isturf(M.loc) || (M.loc != src.contents))) //to avoid people on the inside getting the outside sounds and their direct sounds + built in sound pref check
+ if(isturf(M.loc) || (M.loc != src)) //to avoid people on the inside getting the outside sounds and their direct sounds + built in sound pref check
if(fancy_vore)
M.playsound_local(owner.loc, play_sound, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF)
else
M.playsound_local(owner.loc, play_sound, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF)
//these are all external sound triggers now, so it's ok.
+
if(to_update)
- for(var/mob/living/M in contents)
- if(M.client)
- M.updateVRPanel()
- if(owner.client)
- owner.updateVRPanel()
+ updateVRPanels()
return SSBELLIES_PROCESSED
+
+/obj/belly/proc/prey_loop()
+ for(var/mob/living/M in contents)
+ //We don't bother executing any other code if the prey doesn't want to hear the noises.
+ if(!M.is_preference_enabled(/datum/client_preference/digestion_noises))
+ M.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(isbelly(M.loc) && is_wet && wet_loop && (world.time > M.next_preyloop))
+ M.stop_sound_channel(CHANNEL_PREYLOOP)
+ var/sound/preyloop = sound('sound/vore/sunesound/prey/loop.ogg')
+ M.playsound_local(get_turf(src), preyloop, 80, 0, channel = CHANNEL_PREYLOOP)
+ M.next_preyloop = (world.time + (52 SECONDS))
+
+/obj/belly/proc/handle_digesting_item(obj/item/I)
+ var/did_an_item = FALSE
+ // We always contaminate IDs.
+ if(contaminates || istype(I, /obj/item/weapon/card/id))
+ I.gurgle_contaminate(src, contamination_flavor, contamination_color)
+
+ switch(item_digest_mode)
+ if(IM_HOLD)
+ items_preserved |= I
+ if(IM_DIGEST_FOOD)
+ if(istype(I,/obj/item/weapon/reagent_containers/food) || istype(I, /obj/item/organ))
+ did_an_item = digest_item(I)
+ else
+ items_preserved |= I
+ if(IM_DIGEST)
+ did_an_item = digest_item(I)
+ return did_an_item
+
+/obj/belly/proc/handle_digestion_death(mob/living/M)
+ var/digest_alert_owner = pick(digest_messages_owner)
+ var/digest_alert_prey = pick(digest_messages_prey)
+ var/compensation = M.getOxyLoss() //How much of the prey's damage was caused by passive crit oxyloss to compensate the lost nutrition.
+
+ //Replace placeholder vars
+ digest_alert_owner = replacetext(digest_alert_owner, "%pred", owner)
+ digest_alert_owner = replacetext(digest_alert_owner, "%prey", M)
+ digest_alert_owner = replacetext(digest_alert_owner, "%belly", lowertext(name))
+
+ digest_alert_prey = replacetext(digest_alert_prey, "%pred", owner)
+ digest_alert_prey = replacetext(digest_alert_prey, "%prey", M)
+ digest_alert_prey = replacetext(digest_alert_prey, "%belly", lowertext(name))
+
+ //Send messages
+ to_chat(owner, "[digest_alert_owner]")
+ to_chat(M, "[digest_alert_prey]")
+
+ if((mode_flags & DM_FLAG_LEAVEREMAINS) && M.digest_leave_remains)
+ handle_remains_leaving(M)
+ digestion_death(M)
+ if(!ishuman(owner))
+ owner.update_icons()
+ if(compensation == 0) //Slightly sloppy way at making sure certain mobs don't give ZERO nutrition (fish and so on)
+ compensation = 21 //This reads as 20*4.5 due to the calculations afterward, making the backup nutrition value 94.5 per mob. Not op compared to regular prey.
+ if(compensation > 0)
+ if(isrobot(owner))
+ var/mob/living/silicon/robot/R = owner
+ R.cell.charge += 25*compensation
+ else
+ owner.nutrition += (nutrition_percent / 100)*4.5*compensation
+
+/obj/belly/proc/steal_nutrition(mob/living/L)
+ if(L.nutrition >= 100)
+ var/oldnutrition = (L.nutrition * 0.05)
+ L.nutrition = (L.nutrition * 0.95)
+ owner.nutrition += oldnutrition
+
+/obj/belly/proc/updateVRPanels()
+ for(var/mob/living/M in contents)
+ if(M.client)
+ M.updateVRPanel()
+ if(owner.client)
+ owner.updateVRPanel()
\ No newline at end of file
diff --git a/code/modules/vore/eating/contaminate_vr.dm b/code/modules/vore/eating/contaminate_vr.dm
index 774d33331a..5bbbe902c7 100644
--- a/code/modules/vore/eating/contaminate_vr.dm
+++ b/code/modules/vore/eating/contaminate_vr.dm
@@ -22,7 +22,7 @@ var/list/gurgled_overlays = list(
var/cleandesc
var/gurgled_color
-/obj/item/proc/gurgle_contaminate(var/atom/movable/item_storage = null, var/contamination_flavor = "Generic", var/contamination_color = "green")
+/obj/item/proc/gurgle_contaminate(atom/movable/item_storage = null, contamination_flavor = "Generic", contamination_color = "green")
if(!can_gurgle())
return FALSE
@@ -65,28 +65,16 @@ var/list/gurgled_overlays = list(
if(gurgled)
decontaminate()
-/obj/structure/sink/attackby(obj/item/O as obj, mob/user as mob) //Wash the soggy item before it can interact with the sink.
- if(O.gurgled)
- var/turf/location = user.loc
- if(!isturf(location)) return
-
- var/obj/item/I = O
- if(!I || !istype(I,/obj/item)) return
-
- to_chat(usr, "You start washing \the [I].")
+/obj/structure/sink/attackby(obj/item/I, mob/user) //Wash the soggy item before it can interact with the sink.
+ if(istype(I) && I.gurgled)
+ to_chat(user, "You start washing [I].")
busy = TRUE
- sleep(40)
+ if(do_after(user, 40, src))
+ I.clean_blood()
+ user.visible_message("[user] washes [I] using [src].",
+ "You wash [I] using [src].")
busy = FALSE
-
- if(user.loc != location) return //User has moved
- if(!I) return //Item's been destroyed while washing
- if(user.get_active_hand() != I) return //Person has switched hands or the item in their hands
-
- O.clean_blood()
- user.visible_message( \
- "[user] washes \a [I] using \the [src].", \
- "You wash \a [I] using \the [src].")
else
..()
diff --git a/code/modules/vore/eating/digest_act_vr.dm b/code/modules/vore/eating/digest_act_vr.dm
index e9cf239e66..df59ffb35d 100644
--- a/code/modules/vore/eating/digest_act_vr.dm
+++ b/code/modules/vore/eating/digest_act_vr.dm
@@ -3,10 +3,10 @@
//return non-negative integer: Amount of nutrition/charge gained (scaled to nutrition, other end can multiply for charge scale).
// Ye default implementation.
-/obj/item/proc/digest_act(var/atom/movable/item_storage = null)
- if(istype(item_storage,/obj/item/device/dogborg/sleeper))
+/obj/item/proc/digest_act(atom/movable/item_storage = null)
+ if(istype(item_storage, /obj/item/device/dogborg/sleeper))
for(var/obj/item/O in contents)
- if(istype(O,/obj/item/weapon/storage/internal)) //Dump contents from dummy pockets.
+ if(istype(O, /obj/item/weapon/storage/internal)) //Dump contents from dummy pockets.
for(var/obj/item/SO in O)
if(item_storage)
SO.forceMove(item_storage)
@@ -15,12 +15,15 @@
O.forceMove(item_storage)
qdel(src)
return w_class
+
var/g_damage = 1
if(digest_stage == null)
digest_stage = w_class
+
if(isbelly(item_storage))
var/obj/belly/B = item_storage
g_damage = 0.25 * (B.digest_brute + B.digest_burn)
+
if(digest_stage > 0)
if(g_damage > digest_stage)
g_damage = digest_stage
@@ -65,16 +68,16 @@
// Some special treatment
/////////////
//PDAs need to lose their ID to not take it with them, so we can get a digested ID
-/obj/item/device/pda/digest_act(var/atom/movable/item_storage = null)
+/obj/item/device/pda/digest_act(atom/movable/item_storage = null)
if(id)
- if(istype(item_storage,/obj/item/device/dogborg/sleeper) || (!isnull(digest_stage) && digest_stage <= 0))
+ if(istype(item_storage, /obj/item/device/dogborg/sleeper) || (!isnull(digest_stage) && digest_stage <= 0))
id = null
. = ..()
/obj/item/weapon/card/id
var/lost_access = list()
-/obj/item/weapon/card/id/digest_act(var/atom/movable/item_storage = null)
+/obj/item/weapon/card/id/digest_act(atom/movable/item_storage = null)
desc = "A partially digested card that has seen better days. The damage appears to be only cosmetic, but the access codes need to be reprogrammed at the HoP office."
icon = 'icons/obj/card_vr.dmi'
icon_state = "[initial(icon_state)]_digested"
@@ -83,7 +86,7 @@
access = list() // Then lose it
return FALSE
-/obj/item/weapon/reagent_containers/food/digest_act(var/atom/movable/item_storage = null)
+/obj/item/weapon/reagent_containers/food/digest_act(atom/movable/item_storage = null)
if(isbelly(item_storage))
var/obj/belly/B = item_storage
if(ishuman(B.owner))
@@ -96,7 +99,7 @@
return w_class
. = ..()
-/obj/item/weapon/holder/digest_act(var/atom/movable/item_storage = null)
+/obj/item/weapon/holder/digest_act(atom/movable/item_storage = null)
for(var/mob/living/M in contents)
if(item_storage)
M.forceMove(item_storage)
@@ -104,7 +107,7 @@
. = ..()
-/obj/item/organ/digest_act(var/atom/movable/item_storage = null)
+/obj/item/organ/digest_act(atom/movable/item_storage = null)
if((. = ..()))
if(isbelly(item_storage))
var/obj/belly/B = item_storage
@@ -112,7 +115,7 @@
else
. += 30 //Organs give a little more
-/obj/item/weapon/storage/digest_act(var/atom/movable/item_storage = null)
+/obj/item/weapon/storage/digest_act(atom/movable/item_storage = null)
for(var/obj/item/I in contents)
I.screen_loc = null
@@ -121,7 +124,7 @@
/////////////
// Some more complicated stuff
/////////////
-/obj/item/device/mmi/digital/posibrain/digest_act(var/atom/movable/item_storage = null)
+/obj/item/device/mmi/digital/posibrain/digest_act(atom/movable/item_storage = null)
//Replace this with a VORE setting so all types of posibrains can/can't be digested on a whim
return FALSE
diff --git a/code/modules/vore/eating/leave_remains_vr.dm b/code/modules/vore/eating/leave_remains_vr.dm
index 84374b44fe..a95adb094b 100644
--- a/code/modules/vore/eating/leave_remains_vr.dm
+++ b/code/modules/vore/eating/leave_remains_vr.dm
@@ -1,72 +1,62 @@
+/datum/species
+ var/skull_type = /obj/item/weapon/digestion_remains/skull
+/datum/species/tajaran
+ skull_type = /obj/item/weapon/digestion_remains/skull/tajaran
+/datum/species/unathi
+ skull_type = /obj/item/weapon/digestion_remains/skull/unathi
+/datum/species/skrell
+ skull_type = /obj/item/weapon/digestion_remains/skull/skrell
+/datum/species/spider
+ skull_type = /obj/item/weapon/digestion_remains/skull/vasilissan
+/datum/species/akula
+ skull_type = /obj/item/weapon/digestion_remains/skull/akula
+/datum/species/harpy
+ skull_type = /obj/item/weapon/digestion_remains/skull/rapala
+/datum/species/vulpkanin
+ skull_type = /obj/item/weapon/digestion_remains/skull/vulpkanin
+/datum/species/sergal
+ skull_type = /obj/item/weapon/digestion_remains/skull/sergal
+/datum/species/hi_zorren
+ skull_type = /obj/item/weapon/digestion_remains/skull/zorren
+/datum/species/nevrean
+ skull_type = /obj/item/weapon/digestion_remains/skull/nevrean
+/datum/species/teshari
+ skull_type = /obj/item/weapon/digestion_remains/skull/teshari
+/datum/species/vox
+ skull_type = /obj/item/weapon/digestion_remains/skull/vox
+
/obj/belly/proc/handle_remains_leaving(var/mob/living/M)
-
- if(istype(M,/mob/living/carbon/human)) //Are we even humanoid?
- var/mob/living/carbon/human/H = M
-
- if((H.species.name in remainless_species) || H.isSynthetic()) //Don't leave anything if there is nothing to leave
- return
-
- else
- var/bones_amount = rand(2,3) //some random variety in amount of bones left
-
- if(prob(20)) //ribcage surviving whole is some luck
- new /obj/item/weapon/digestion_remains/ribcage(src,owner)
- bones_amount--
-
- while(bones_amount) //throw in the rest
- new /obj/item/weapon/digestion_remains(src,owner)
- bones_amount--
-
- var/skull_amount = 1
- switch(H.species.name) //oh boy here we go, finding us a right skull
- if(SPECIES_HUMAN)
- new /obj/item/weapon/digestion_remains/skull(src,owner)
- skull_amount--
- if(SPECIES_TAJ)
- new /obj/item/weapon/digestion_remains/skull/tajaran(src,owner)
- skull_amount--
- if(SPECIES_UNATHI)
- new /obj/item/weapon/digestion_remains/skull/unathi(src,owner)
- skull_amount--
- if(SPECIES_SKRELL)
- new /obj/item/weapon/digestion_remains/skull/skrell(src,owner)
- skull_amount--
- if(SPECIES_VASILISSAN)
- new /obj/item/weapon/digestion_remains/skull/vasilissan(src,owner)
- skull_amount--
- if(SPECIES_AKULA)
- new /obj/item/weapon/digestion_remains/skull/akula(src,owner)
- skull_amount--
- if(SPECIES_RAPALA)
- new /obj/item/weapon/digestion_remains/skull/rapala(src,owner)
- skull_amount--
- if(SPECIES_VULPKANIN)
- new /obj/item/weapon/digestion_remains/skull/vulpkanin(src,owner)
- skull_amount--
- if(SPECIES_SERGAL)
- new /obj/item/weapon/digestion_remains/skull/sergal(src,owner)
- skull_amount--
- if(SPECIES_ZORREN_HIGH)
- new /obj/item/weapon/digestion_remains/skull/zorren(src,owner)
- skull_amount--
- if(SPECIES_NEVREAN)
- new /obj/item/weapon/digestion_remains/skull/nevrean(src,owner)
- skull_amount--
- if(SPECIES_TESHARI)
- new /obj/item/weapon/digestion_remains/skull/teshari(src,owner)
- skull_amount--
- if(SPECIES_VOX)
- new /obj/item/weapon/digestion_remains/skull/vox(src,owner)
- skull_amount--
- if(skull_amount && H.species.selects_bodytype) //We still haven't found correct skull...
- if(H.species.base_species == SPECIES_HUMAN)
- new /obj/item/weapon/digestion_remains/skull/unknown(src,owner)
- else
- new /obj/item/weapon/digestion_remains/skull/unknown/anthro(src,owner)
- else if(skull_amount) //Something entirely different...
- new /obj/item/weapon/digestion_remains/skull/unknown(src,owner)
- else
+ if(!ishuman(M)) //Are we even humanoid?
return
+ var/mob/living/carbon/human/H = M
+
+ if((H.species.name in remainless_species) || H.isSynthetic()) //Don't leave anything if there is nothing to leave
+ return
+
+ var/bones_amount = rand(2,3) //some random variety in amount of bones left
+ if(prob(20)) //ribcage surviving whole is some luck
+ new /obj/item/weapon/digestion_remains/ribcage(src,owner)
+ bones_amount--
+
+ while(bones_amount) //throw in the rest
+ new /obj/item/weapon/digestion_remains(src,owner)
+ bones_amount--
+
+ var/skull_amount = 1
+ if(H.species.skull_type)
+ new H.species.skull_type(src, owner)
+ skull_amount--
+
+ if(skull_amount && H.species.selects_bodytype)
+ // We still haven't found correct skull...
+ if(H.species.base_species == SPECIES_HUMAN)
+ new /obj/item/weapon/digestion_remains/skull/unknown(src,owner)
+ else
+ new /obj/item/weapon/digestion_remains/skull/unknown/anthro(src,owner)
+ else if(skull_amount)
+ // Something entirely different...
+ new /obj/item/weapon/digestion_remains/skull/unknown(src,owner)
+
/obj/item/weapon/digestion_remains
name = "bone"
@@ -80,7 +70,7 @@
var/pred_ckey
var/pred_name
-/obj/item/weapon/digestion_remains/New(var/newloc,var/mob/living/pred)
+/obj/item/weapon/digestion_remains/New(newloc, mob/living/pred)
..(newloc)
pred_ckey = pred.ckey
pred_name = pred.name
diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm
index 3a100d212e..e890b00883 100644
--- a/code/modules/vore/eating/living_vr.dm
+++ b/code/modules/vore/eating/living_vr.dm
@@ -19,7 +19,6 @@
var/metabolism = 0.0015
var/vore_taste = null // What the character tastes like
var/no_vore = FALSE // If the character/mob can vore.
- var/openpanel = FALSE // Is the vore panel open?
var/noisy = FALSE // Toggle audible hunger.
var/absorbing_prey = 0 // Determines if the person is using the succubus drain or not. See station_special_abilities_vr.
var/drain_finalized = 0 // Determines if the succubus drain will be KO'd/absorbed. Can be toggled on at any time.
@@ -41,6 +40,7 @@
M.verbs += /mob/living/proc/switch_scaling
if(M.no_vore) //If the mob isn't supposed to have a stomach, let's not give it an insidepanel so it can make one for itself, or a stomach.
return TRUE
+ M.vorePanel = new
M.verbs += /mob/living/proc/insidePanel
//Tries to load prefs if a client is present otherwise gives freebie stomach
@@ -88,26 +88,25 @@
//
// Handle being clicked, perhaps with something to devour
//
-/mob/living/proc/vore_attackby(obj/item/I,mob/user)
+/mob/living/proc/vore_attackby(obj/item/I, mob/user)
//Handle case: /obj/item/weapon/grab
- if(istype(I,/obj/item/weapon/grab))
+ if(istype(I, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = I
//Has to be aggressive grab, has to be living click-er and non-silicon grabbed
- if((G.state >= GRAB_AGGRESSIVE) && (isliving(user) && !issilicon(G.affecting)))
-
+ if(G.state >= GRAB_AGGRESSIVE && (isliving(user) && !issilicon(G.affecting)))
var/mob/living/attacker = user // Typecast to living
// src is the mob clicked on and attempted predator
///// If user clicked on themselves
- if((src == G.assailant) && (is_vore_predator(src)))
- if(!(G.affecting.devourable))
+ if(src == G.assailant && is_vore_predator(src))
+ if(!G.affecting.devourable)
to_chat(user, "They aren't able to be devoured.")
- log_and_message_admins("[key_name(src)] ([src.real_name]) attempted to devour [key_name(G.affecting)] ([G.affecting.real_name]) against their prefs ([G.affecting ? "JMP" : "null"])")
-
+ log_and_message_admins("[key_name_admin(src)] attempted to devour [key_name_admin(G.affecting)] against their prefs ([G.affecting ? ADMIN_JMP(G.affecting) : "null"])")
return FALSE
- if(src.feed_grabbed_to_self(src, G.affecting))
+
+ if(feed_grabbed_to_self(src, G.affecting))
qdel(G)
return TRUE
else
@@ -115,57 +114,62 @@
///// If user clicked on their grabbed target
else if((src == G.affecting) && (attacker.a_intent == I_GRAB) && (attacker.zone_sel.selecting == BP_TORSO) && (is_vore_predator(G.affecting)))
- if(!(G.affecting.feeding))
+ if(!G.affecting.feeding)
to_chat(user, "[G.affecting] isn't willing to be fed.")
- log_and_message_admins("[key_name(src)] ([src.real_name]) attempted to feed themselves to [key_name(G.affecting)] ([G.affecting.real_name]) against their prefs ([G.affecting ? "JMP" : "null"])")
+ log_and_message_admins("[key_name_admin(src)] attempted to feed themselves to [key_name_admin(G.affecting)] against their prefs ([G.affecting ? ADMIN_JMP(G.affecting) : "null"])")
return FALSE
- if (attacker.feed_self_to_grabbed(attacker, G.affecting))
+
+ if(attacker.feed_self_to_grabbed(attacker, G.affecting))
qdel(G)
return TRUE
else
- log_debug("[attacker] attempted to feed [user] to [G.affecting] ([G.affecting.type]) but it failed.")
+ log_debug("[attacker] attempted to feed [user] to [G.affecting] ([G.affecting ? G.affecting.type : "null"]) but it failed.")
///// If user clicked on anyone else but their grabbed target
else if((src != G.affecting) && (src != G.assailant) && (is_vore_predator(src)))
- if(!(src.feeding))
+ if(!feeding)
to_chat(user, "[src] isn't willing to be fed.")
- log_and_message_admins("[key_name(attacker)] ([attacker.real_name]) attempted to feed [key_name(G.affecting)] ([G.affecting.real_name]) to [key_name(src)] ([src.real_name]) against predator's prefs ([src ? "JMP" : "null"])")
+ log_and_message_admins("[key_name_admin(attacker)] attempted to feed [key_name_admin(G.affecting)] to [key_name_admin(src)] against predator's prefs ([src ? ADMIN_JMP(src) : "null"])")
return FALSE
if(!(G.affecting.devourable))
to_chat(user, "[G.affecting] isn't able to be devoured.")
- log_and_message_admins("[key_name(attacker)] ([attacker.real_name]) attempted to feed [key_name(G.affecting)] ([G.affecting.real_name]) to [key_name(src)] ([src.real_name]) against prey's prefs ([G.affecting ? "JMP" : "null"])")
+ log_and_message_admins("[key_name_admin(attacker)] attempted to feed [key_name_admin(G.affecting)] to [key_name_admin(src)] against prey's prefs ([G.affecting ? ADMIN_JMP(G.affecting) : "null"])")
return FALSE
-
- if (attacker.feed_grabbed_to_other(attacker, G.affecting, src))
+ if(attacker.feed_grabbed_to_other(attacker, G.affecting, src))
qdel(G)
return TRUE
else
- log_debug("[attacker] attempted to feed [G.affecting] to [src] ([src.type]) but it failed.")
+ log_debug("[attacker] attempted to feed [G.affecting] to [src] ([type]) but it failed.")
//Handle case: /obj/item/weapon/holder
- else if(istype(I,/obj/item/weapon/holder))
+ else if(istype(I, /obj/item/weapon/holder))
var/obj/item/weapon/holder/H = I
- if(!isliving(user)) return FALSE // return FALSE to continue upper procs
+ if(!isliving(user))
+ return FALSE // return FALSE to continue upper procs
+
var/mob/living/attacker = user // Typecast to living
-
- if (is_vore_predator(src))
- for (var/mob/living/M in H.contents)
- if (attacker.eat_held_mob(attacker, M, src))
- if (H.held_mob == M)
+ if(is_vore_predator(src))
+ for(var/mob/living/M in H.contents)
+ if(attacker.eat_held_mob(attacker, M, src))
+ if(H.held_mob == M)
H.held_mob = null
return TRUE //return TRUE to exit upper procs
else
- log_debug("[attacker] attempted to feed [H.contents] to [src] ([src.type]) but it failed.")
+ log_debug("[attacker] attempted to feed [H.contents] to [src] ([type]) but it failed.")
//Handle case: /obj/item/device/radio/beacon
else if(istype(I,/obj/item/device/radio/beacon))
- var/confirm = alert(user, "[src == user ? "Eat the beacon?" : "Feed the beacon to [src]?"]", "Confirmation", "Yes!", "Cancel")
+ var/confirm = alert(user,
+ "[src == user ? "Eat the beacon?" : "Feed the beacon to [src]?"]",
+ "Confirmation",
+ "Yes!", "Cancel")
if(confirm == "Yes!")
- var/obj/belly/B = input("Which belly?","Select A Belly") as null|anything in vore_organs
+ var/obj/belly/B = input("Which belly?", "Select A Belly") as null|anything in vore_organs
if(!istype(B))
return TRUE
- visible_message("[user] is trying to stuff a beacon into [src]'s [lowertext(B.name)]!","[user] is trying to stuff a beacon into you!")
+ visible_message("[user] is trying to stuff a beacon into [src]'s [lowertext(B.name)]!",
+ "[user] is trying to stuff a beacon into you!")
if(do_after(user,30,src))
user.drop_item()
I.forceMove(B)
@@ -179,7 +183,6 @@
// Our custom resist catches for /mob/living
//
/mob/living/proc/vore_process_resist()
-
//Are we resisting from inside a belly?
if(isbelly(loc))
var/obj/belly/B = loc
@@ -187,7 +190,6 @@
return TRUE //resist() on living does this TRUE thing.
//Other overridden resists go here
-
return FALSE
//
@@ -310,13 +312,12 @@
if(suit.hides_bulges)
return FALSE
-
return ..()
//
// Clearly super important. Obviously.
//
-/mob/living/proc/lick(var/mob/living/tasted in living_mobs(1))
+/mob/living/proc/lick(mob/living/tasted in living_mobs(1))
set name = "Lick"
set category = "IC"
set desc = "Lick someone nearby!"
@@ -402,11 +403,11 @@
//
// Eating procs depending on who clicked what
//
-/mob/living/proc/feed_grabbed_to_self(var/mob/living/user, var/mob/living/prey)
+/mob/living/proc/feed_grabbed_to_self(mob/living/user, mob/living/prey)
var/belly = user.vore_selected
return perform_the_nom(user, prey, user, belly)
-/mob/living/proc/eat_held_mob(var/mob/living/user, var/mob/living/prey, var/mob/living/pred)
+/mob/living/proc/eat_held_mob(mob/living/user, mob/living/prey, mob/living/pred)
var/belly
if(user != pred)
belly = input("Choose Belly") in pred.vore_organs
@@ -414,18 +415,18 @@
belly = pred.vore_selected
return perform_the_nom(user, prey, pred, belly)
-/mob/living/proc/feed_self_to_grabbed(var/mob/living/user, var/mob/living/pred)
+/mob/living/proc/feed_self_to_grabbed(mob/living/user, mob/living/pred)
var/belly = input("Choose Belly") in pred.vore_organs
return perform_the_nom(user, user, pred, belly)
-/mob/living/proc/feed_grabbed_to_other(var/mob/living/user, var/mob/living/prey, var/mob/living/pred)
+/mob/living/proc/feed_grabbed_to_other(mob/living/user, mob/living/prey, mob/living/pred)
var/belly = input("Choose Belly") in pred.vore_organs
return perform_the_nom(user, prey, pred, belly)
//
// Master vore proc that actually does vore procedures
//
-/mob/living/proc/perform_the_nom(var/mob/living/user, var/mob/living/prey, var/mob/living/pred, var/obj/belly/belly, var/delay)
+/mob/living/proc/perform_the_nom(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly, delay)
//Sanity
if(!user || !prey || !pred || !istype(belly) || !(belly in pred.vore_organs))
log_debug("[user] attempted to feed [prey] to [pred], via [belly ? lowertext(belly.name) : "*null*"] but it went wrong.")
@@ -444,11 +445,11 @@
// Prepare messages
if(user == pred) //Feeding someone to yourself
- attempt_msg = text("[] is attempting to [] [] into their []!",pred,lowertext(belly.vore_verb),prey,lowertext(belly.name))
- success_msg = text("[] manages to [] [] into their []!",pred,lowertext(belly.vore_verb),prey,lowertext(belly.name))
+ attempt_msg = "[pred] is attempting to [lowertext(belly.vore_verb)] [prey] into their [lowertext(belly.name)]!"
+ success_msg = "[pred] manages to [lowertext(belly.vore_verb)] [prey] into their [lowertext(belly.name)]!"
else //Feeding someone to another person
- attempt_msg = text("[] is attempting to make [] [] [] into their []!",user,pred,lowertext(belly.vore_verb),prey,lowertext(belly.name))
- success_msg = text("[] manages to make [] [] [] into their []!",user,pred,lowertext(belly.vore_verb),prey,lowertext(belly.name))
+ attempt_msg = "[user] is attempting to make [pred] [lowertext(belly.vore_verb)] [prey] into their [lowertext(belly.name)]!"
+ success_msg = "[user] manages to make [pred] [lowertext(belly.vore_verb)] [prey] into their [lowertext(belly.name)]!"
// Announce that we start the attempt!
user.visible_message(attempt_msg)
@@ -477,10 +478,10 @@
to_chat(belly.owner, "[prey] tastes of [prey.get_taste_message(FALSE)].")
// Inform Admins
- if (pred == user)
- add_attack_logs(pred,prey,"Eaten via [belly.name]")
+ if(pred == user)
+ add_attack_logs(pred, prey, "Eaten via [belly.name]")
else
- add_attack_logs(user,pred,"Forced to eat [key_name(prey)]")
+ add_attack_logs(user, pred, "Forced to eat [key_name(prey)]")
return TRUE
//
@@ -522,7 +523,7 @@
to_chat(src,"You're pinned back underfoot!")
to_chat(H,"You pin the escapee back underfoot!")
return
- if(src.loc != C)
+ if(loc != C)
return
sleep(1)
@@ -538,7 +539,7 @@
to_chat(src,"You're pinned underfoot!")
to_chat(H,"You pin the escapee underfoot!")
return
- if(src.loc != C)
+ if(loc != C)
return
sleep(1)
to_chat(src,"You manage to escape \the [C]!")
@@ -599,7 +600,7 @@
if(is_type_in_list(I,edible_trash) | adminbus_trash)
if(I.hidden_uplink)
to_chat(src, "You really should not be eating this.")
- message_admins("[key_name(src)] has attempted to ingest an uplink item. ([src ? "JMP" : "null"])")
+ message_admins("[key_name(src)] has attempted to ingest an uplink item. ([src ? ADMIN_JMP(src) : "null"])")
return
if(istype(I,/obj/item/device/pda))
var/obj/item/device/pda/P = I
diff --git a/code/modules/vore/eating/silicon_vr.dm b/code/modules/vore/eating/silicon_vr.dm
index 9c8b2b3387..ba9e279043 100644
--- a/code/modules/vore/eating/silicon_vr.dm
+++ b/code/modules/vore/eating/silicon_vr.dm
@@ -37,7 +37,7 @@
playsound('sound/effects/stealthoff.ogg',50,0)
bellied.forceMove(get_turf(src))
bellied.Weaken(2)
- bellied.visible_message("[bellied] flops out of \the [src].","You flop out of \the [src].","You hear a thud.")
+ bellied.visible_message("[bellied] flops out of [src].","You flop out of [src].","You hear a thud.")
bellied = null
desc = "[initial(desc)]"
@@ -64,7 +64,7 @@
//Already full
if (hologram.bellied)
- var/choice = alert("You can only contain one person. [hologram.bellied] is in you.","Already Full","Drop Mob","Cancel")
+ var/choice = alert("You can only contain one person. [hologram.bellied] is in you.", "Already Full", "Drop Mob", "Cancel")
if(choice == "Drop Mob")
hologram.drop_prey()
return
@@ -93,7 +93,7 @@
/mob/living/AIShiftClick(var/mob/user) //Shift-click as AI overridden on mobs to examine.
if(user.client)
- src.examine(user)
+ examine(user)
return
//This can go here with all the references.
diff --git a/code/modules/vore/eating/simple_animal_vr.dm b/code/modules/vore/eating/simple_animal_vr.dm
index 05e8e84601..9e68ad631a 100644
--- a/code/modules/vore/eating/simple_animal_vr.dm
+++ b/code/modules/vore/eating/simple_animal_vr.dm
@@ -6,21 +6,22 @@
//
// Simple nom proc for if you get ckey'd into a simple_mob mob! Avoids grabs.
//
-/mob/living/simple_mob/proc/animal_nom(var/mob/living/T in living_mobs(1))
+/mob/living/simple_mob/proc/animal_nom(mob/living/T in living_mobs(1))
set name = "Animal Nom"
set category = "IC"
set desc = "Since you can't grab, you get a verb!"
- if (stat != CONSCIOUS)
+ if(stat != CONSCIOUS)
return
- if (istype(src,/mob/living/simple_mob/animal/passive/mouse) && T.ckey == null)
+ // Verbs are horrifying. They don't call overrides. So we're stuck with this.
+ if(istype(src, /mob/living/simple_mob/animal/passive/mouse) && !T.ckey)
+ // Mice can't eat logged out players!
return
- if (client && IsAdvancedToolUser())
+ if(client && IsAdvancedToolUser())
to_chat(src, "Put your hands to good use instead!")
return
feed_grabbed_to_self(src,T)
update_icon()
- return
//
// Simple proc for animals to have their digestion toggled on/off externally
@@ -45,8 +46,7 @@
var/confirm = alert(user, "Enabling digestion on [name] will cause it to digest all stomach contents. Using this to break OOC prefs is against the rules. Digestion will reset after 20 minutes.", "Enabling [name]'s Digestion", "Enable", "Cancel")
if(confirm == "Enable")
vore_selected.digest_mode = DM_DIGEST
- spawn(20 MINUTES)
- if(src) vore_selected.digest_mode = vore_default_mode
+ addtimer(VARSET_CALLBACK(vore_selected, digest_mode, vore_default_mode), 20 MINUTES)
else
var/confirm = alert(user, "This mob is currently set to process all stomach contents. Do you want to disable this?", "Disabling [name]'s Digestion", "Disable", "Cancel")
if(confirm == "Disable")
@@ -69,28 +69,31 @@
to_chat(user, "[src] is now using [vore_selected.fancy_vore ? "Fancy" : "Classic"] vore sounds.")
/mob/living/simple_mob/attackby(var/obj/item/O, var/mob/user)
- if (istype(O, /obj/item/weapon/newspaper) && !(ckey || (ai_holder.hostile && faction != user.faction)) && isturf(user.loc))
- if (ai_holder.retaliate && prob(vore_pounce_chance/2)) // This is a gamble!
+ if(istype(O, /obj/item/weapon/newspaper) && !(ckey || (ai_holder.hostile && faction != user.faction)) && isturf(user.loc))
+ if(ai_holder.retaliate && prob(vore_pounce_chance/2)) // This is a gamble!
user.Weaken(5) //They get tackled anyway whether they're edible or not.
- user.visible_message("\the [user] swats \the [src] with \the [O] and promptly gets tackled!!")
- if (will_eat(user))
+ user.visible_message("[user] swats [src] with [O] and promptly gets tackled!!")
+ if(will_eat(user))
set_AI_busy(TRUE)
animal_nom(user)
update_icon()
set_AI_busy(FALSE)
- else if (!ai_holder.target) // no using this to clear a retaliate mob's target
+ else if(!ai_holder.target) // no using this to clear a retaliate mob's target
ai_holder.target = user //just because you're not tasty doesn't mean you get off the hook. A swat for a swat.
//AttackTarget() //VOREStation AI Temporary Removal
//LoseTarget() // only make one attempt at an attack rather than going into full rage mode
else
- user.visible_message("\the [user] swats \the [src] with \the [O]!!")
+ user.visible_message("[user] swats [src] with [O]!")
release_vore_contents()
for(var/mob/living/L in living_mobs(0)) //add everyone on the tile to the do-not-eat list for a while
if(!(L in prey_excludes)) // Unless they're already on it, just to avoid fuckery.
prey_excludes += L
- spawn(5 MINUTES)
- if(src && L)
- prey_excludes -= L
+ addtimer(CALLBACK(src, .proc/removeMobFromPreyExcludes, weakref(L)), 5 MINUTES)
else
..()
+/mob/living/simple_mob/proc/removeMobFromPreyExcludes(weakref/target)
+ if(isweakref(target))
+ var/mob/living/L = target.resolve()
+ if(L)
+ LAZYREMOVE(prey_excludes, L)
diff --git a/code/modules/vore/eating/transforming_vr.dm b/code/modules/vore/eating/transforming_vr.dm
index 2f261980ec..3e78920419 100644
--- a/code/modules/vore/eating/transforming_vr.dm
+++ b/code/modules/vore/eating/transforming_vr.dm
@@ -241,7 +241,6 @@
BI.forceMove(torso)
torso.implants += BI
-
if(message)
to_chat(M, "You lose sensation of your body, feeling only the warmth of everything around you... ")
to_chat(O, "Your body shifts as you make dramatic changes to your captive's body.")
diff --git a/code/modules/vore/eating/vore_vr.dm b/code/modules/vore/eating/vore_vr.dm
index ea77dd5c6b..9aaa4b0cef 100644
--- a/code/modules/vore/eating/vore_vr.dm
+++ b/code/modules/vore/eating/vore_vr.dm
@@ -70,7 +70,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
//
// Check if an object is capable of eating things, based on vore_organs
//
-/proc/is_vore_predator(var/mob/living/O)
+/proc/is_vore_predator(mob/living/O)
if(istype(O,/mob/living))
if(O.vore_organs.len > 0)
return TRUE
@@ -87,8 +87,9 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
//
// Save/Load Vore Preferences
//
-/datum/vore_preferences/proc/load_path(ckey,slot,filename="character",ext="json")
- if(!ckey || !slot) return
+/datum/vore_preferences/proc/load_path(ckey, slot, filename="character", ext="json")
+ if(!ckey || !slot)
+ return
path = "data/player_saves/[copytext(ckey,1,2)]/[ckey]/vore/[filename][slot].[ext]"
@@ -102,7 +103,8 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
load_path(client_ckey,slot)
- if(!path) return FALSE //Path couldn't be set?
+ if(!path)
+ return FALSE //Path couldn't be set?
if(!fexists(path)) //Never saved before
save_vore() //Make the file first
return TRUE
@@ -151,7 +153,8 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
return TRUE
/datum/vore_preferences/proc/save_vore()
- if(!path) return FALSE
+ if(!path)
+ return FALSE
var/version = VORE_VERSION //For "good times" use in the future
var/list/settings_list = list(
diff --git a/code/modules/vore/eating/vorepanel_vr.dm b/code/modules/vore/eating/vorepanel_vr.dm
index fe0b86d9de..5caf70d602 100644
--- a/code/modules/vore/eating/vorepanel_vr.dm
+++ b/code/modules/vore/eating/vorepanel_vr.dm
@@ -8,68 +8,72 @@
#define BELLIES_DESC_MAX 2048
#define FLAVOR_MAX 40
+/mob/living
+ var/datum/vore_look/vorePanel
+
/mob/living/proc/insidePanel()
set name = "Vore Panel"
set category = "IC"
- var/datum/vore_look/picker_holder = new()
- picker_holder.loop = picker_holder
- picker_holder.selected = vore_selected
+ if(!vorePanel)
+ log_debug("[src] ([type], \ref[src]) didn't have a vorePanel and tried to use the verb.")
+ vorePanel = new
- var/dat = picker_holder.gen_ui(src)
-
- picker_holder.popup = new(src, "insidePanel","Inside!", 450, 700, picker_holder)
- picker_holder.popup.set_content(dat)
- picker_holder.popup.open()
- src.openpanel = 1
+ vorePanel.selected = vore_selected
+ vorePanel.show(src)
/mob/living/proc/updateVRPanel() //Panel popup update call from belly events.
- if(src.openpanel == 1)
- var/datum/vore_look/picker_holder = new()
- picker_holder.loop = picker_holder
- picker_holder.selected = vore_selected
+ if(!vorePanel)
+ log_debug("[src] ([type], \ref[src]) didn't have a vorePanel and something tried to update it.")
+ vorePanel = new
- var/dat = picker_holder.gen_ui(src)
-
- picker_holder.popup = new(src, "insidePanel","Inside!", 450, 700, picker_holder)
- picker_holder.popup.set_content(dat)
- picker_holder.popup.open()
+ if(vorePanel.open)
+ vorePanel.selected = vore_selected
+ vorePanel.show(src)
//
// Callback Handler for the Inside form
//
/datum/vore_look
+ var/datum/browser/popup
var/obj/belly/selected
var/show_interacts = 0
- var/datum/browser/popup
- var/loop = null; // Magic self-reference to stop the handler from being GC'd before user takes action.
+ var/open = FALSE
/datum/vore_look/Destroy()
- loop = null
selected = null
- return QDEL_HINT_HARDDEL // TODO - Until I can better analyze how this weird thing works, lets be safe
+ QDEL_NULL(popup)
+ . = ..()
/datum/vore_look/Topic(href,href_list[])
- if (vp_interact(href, href_list))
+ if(vp_interact(href, href_list))
popup.set_content(gen_ui(usr))
usr << output(popup.get_content(), "insidePanel.browser")
+/datum/vore_look/proc/show(mob/living/user)
+ if(popup)
+ QDEL_NULL(popup)
+ popup = new(user, "insidePanel", "Inside!", 450, 700, src)
+ popup.set_content(gen_ui(user))
+ popup.open()
+ open = TRUE
+
/datum/vore_look/proc/gen_ui(var/mob/living/user)
var/dat
var/atom/userloc = user.loc
- if (isbelly(userloc))
+ if(isbelly(userloc))
var/obj/belly/inside_belly = userloc
var/mob/living/eater = inside_belly.owner
//Don't display this part if we couldn't find the belly since could be held in hand.
if(inside_belly)
- dat += "You are currently [user.absorbed ? "absorbed into " : "inside "] [eater]'s [inside_belly]!
"
+ dat += "You are currently [user.absorbed ? "absorbed into " : "inside "] [eater]'s [inside_belly]!
"
if(inside_belly.desc)
dat += "[inside_belly.desc]
"
- if (inside_belly.contents.len > 1)
+ if(inside_belly.contents.len > 1)
dat += "You can see the following around you:
"
for (var/atom/movable/O in inside_belly)
if(istype(O,/mob/living))
@@ -374,11 +378,9 @@
/datum/vore_look/proc/vp_interact(href, href_list)
var/mob/living/user = usr
- for(var/H in href_list)
-
if(href_list["close"])
- qdel(src) // Cleanup
- user.openpanel = 0
+ open = FALSE
+ QDEL_NULL(popup)
return
if(href_list["show_int"])
diff --git a/code/modules/vore/resizing/grav_pull_vr.dm b/code/modules/vore/resizing/grav_pull_vr.dm
index 921d1ab2b9..64b8581aff 100644
--- a/code/modules/vore/resizing/grav_pull_vr.dm
+++ b/code/modules/vore/resizing/grav_pull_vr.dm
@@ -18,8 +18,8 @@
/datum/effect/effect/system/grav_pull/start()
spawn(0)
if(holder)
- src.location = get_turf(holder)
- for(var/i=0, i < number, i++)
+ location = get_turf(holder)
+ for(var/i = 0, i < number, i++)
do_pull()
sleep(25)
@@ -29,35 +29,35 @@
defer_powernet_rebuild = 1
// Let's just make this one loop.
- for(var/atom/X in orange(pull_radius, location))
+ for(var/X in orange(pull_radius, location))
// Movable atoms only
- if(istype(X, /atom/movable))
- if(istype(X, /obj/effect/overlay)) continue
- if(X && !istype(X, /mob/living/carbon/human))
- if(break_windows && istype(X, /obj/structure/window)) //shatter windows
- var/obj/structure/window/W = X
- W.ex_act(2.0)
+ if(!ismovableatom(X) || istype(X, /obj/effect/overlay))
+ continue
- if(istype(X, /obj))
- var/obj/O = X
- if(O.anchored)
- if (!pull_anchored) continue // Don't pull anchored stuff unless configured
- step_towards(X, location) // step just once if anchored
- continue
+ if(ishuman(X))
+ var/mob/living/carbon/human/H = X
+ if(istype(H.shoes, /obj/item/clothing/shoes/magboots))
+ var/obj/item/clothing/shoes/magboots/M = H.shoes
+ if(M.magpulse)
+ step_towards(H, location) //step just once with magboots
+ continue
+ step_towards(H, location) //step twice
+ step_towards(H, location)
+ else
+ if(break_windows && istype(X, /obj/structure/window)) //shatter windows
+ var/obj/structure/window/W = X
+ W.ex_act(2.0)
- step_towards(X, location) // Step twice
- step_towards(X, location)
+ if(isobj(X))
+ var/obj/O = X
+ if(O.anchored)
+ if(!pull_anchored)
+ continue // Don't pull anchored stuff unless configured
+ step_towards(X, location) // step just once if anchored
+ continue
- else if(istype(X,/mob/living/carbon/human))
- var/mob/living/carbon/human/H = X
- if(istype(H.shoes,/obj/item/clothing/shoes/magboots))
- var/obj/item/clothing/shoes/magboots/M = H.shoes
- if(M.magpulse)
- step_towards(H, location) //step just once with magboots
- continue
- step_towards(H, location) //step twice
- step_towards(H, location)
+ step_towards(X, location) // Step twice
+ step_towards(X, location)
if(defer_powernet_rebuild != 2)
defer_powernet_rebuild = 0
- return
diff --git a/code/modules/vore/resizing/holder_micro_vr.dm b/code/modules/vore/resizing/holder_micro_vr.dm
index 574be02e0f..b797ef4f5f 100644
--- a/code/modules/vore/resizing/holder_micro_vr.dm
+++ b/code/modules/vore/resizing/holder_micro_vr.dm
@@ -10,36 +10,34 @@
item_icons = list() // No in-hand sprites (for now, anyway, we could totally add some)
pixel_y = 0 // Override value from parent.
-/obj/item/weapon/holder/micro/examine(var/mob/user)
+/obj/item/weapon/holder/micro/examine(mob/user)
for(var/mob/living/M in contents)
M.examine(user)
-/obj/item/weapon/holder/MouseDrop(mob/M as mob)
+/obj/item/weapon/holder/MouseDrop(mob/M)
..()
if(M != usr) return
if(usr == src) return
if(!Adjacent(usr)) return
- if(istype(M,/mob/living/silicon/ai)) return
+ if(isAI(M)) return
for(var/mob/living/carbon/human/O in contents)
O.show_inv(usr)
/obj/item/weapon/holder/micro/attack_self(mob/living/carbon/user) //reworked so it works w/ nonhumans
for(var/L in contents)
- if(!isliving(L))
- continue
- if(ishuman(L) && user.canClick())
+ if(ishuman(L) && user.canClick()) // These canClicks() are repeated here to make sure users can't avoid the click delay
var/mob/living/carbon/human/H = L
H.help_shake_act(user)
user.setClickCooldown(user.get_attack_speed()) //uses the same cooldown as regular attack_hand
return
- if(istype(L, /mob/living/simple_mob) && user.canClick())
+ if(isanimal(L) && user.canClick())
var/mob/living/simple_mob/S = L
user.visible_message("[user] [S.response_help] \the [S].")
user.setClickCooldown(user.get_attack_speed())
/obj/item/weapon/holder/micro/update_state()
- if(istype(loc,/turf) || !(held_mob) || !(held_mob.loc == src))
+ if(isturf(loc) || !held_mob || held_mob.loc != src)
qdel(src)
/obj/item/weapon/holder/micro/Destroy()
diff --git a/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm
index e43ce011d0..f30ba72251 100644
--- a/code/modules/vore/resizing/resize_vr.dm
+++ b/code/modules/vore/resizing/resize_vr.dm
@@ -43,7 +43,7 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2
var/matrix/M = matrix()
M.Scale(size_multiplier)
M.Translate(0, 16*(size_multiplier-1))
- src.transform = M
+ transform = M
/**
* Get the effective size of a mob.
@@ -55,7 +55,7 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2
return 100000 //Whatever it is, it's too big to pick up, or it's a ghost, or something.
/mob/living/get_effective_size()
- return src.size_multiplier
+ return size_multiplier
/**
* Resizes the mob immediately to the desired mod, animating it growing/shrinking.
@@ -111,10 +111,11 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2
var/nagmessage = "Adjust your mass to be a size between 25 to 200% (DO NOT ABUSE)"
var/new_size = input(nagmessage, "Pick a Size") as num|null
- if(new_size && ISINRANGE(new_size,25,200))
- src.resize(new_size/100)
- message_admins("[key_name(src)] used the resize command in-game to be [new_size]% size. \
- ([src ? "JMP" : "null"])")
+ if(new_size && ISINRANGE(new_size, 25, 200))
+ resize(new_size/100)
+ // I'm not entirely convinced that `src ? ADMIN_JMP(src) : "null"` here does anything
+ // but just in case it does, I'm leaving the null-src checking
+ message_admins("[key_name(src)] used the resize command in-game to be [new_size]% size. [src ? ADMIN_JMP(src) : "null"]")
/*
//Add the set_size() proc to usable verbs. By commenting this out, we can leave the proc and hand it to species that need it.
@@ -127,7 +128,7 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2
* Attempt to scoop up this mob up into H's hands, if the size difference is large enough.
* @return false if normal code should continue, 1 to prevent normal code.
*/
-/mob/living/proc/attempt_to_scoop(var/mob/living/M, var/mob/living/G) //second one is for the Grabber, only exists for animals to self-grab
+/mob/living/proc/attempt_to_scoop(mob/living/M, mob/living/G) //second one is for the Grabber, only exists for animals to self-grab
var/size_diff = M.get_effective_size() - get_effective_size()
if(!holder_default && holder_type)
holder_default = holder_type
@@ -156,37 +157,42 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2
* Called from /mob/living/Bump() in the 'brohugs all around' section.
* @return false if normal code should continue, true to prevent normal code.
*/
-/mob/living/proc/handle_micro_bump_helping(var/mob/living/tmob)
+/mob/living/proc/handle_micro_bump_helping(mob/living/tmob)
//Both small! Go ahead and go.
- if(src.get_effective_size() <= RESIZE_A_SMALLTINY && tmob.get_effective_size() <= RESIZE_A_SMALLTINY)
+ if(get_effective_size() <= RESIZE_A_SMALLTINY && tmob.get_effective_size() <= RESIZE_A_SMALLTINY)
return TRUE
//Worthy of doing messages at all
if(abs(get_effective_size() - tmob.get_effective_size()) >= 0.50)
+ var/src_message = null
+ var/tmob_message = null
//Smaller person being stepped onto
if(get_effective_size() > tmob.get_effective_size() && ishuman(src))
+ src_message = "You carefully step over [tmob]."
+ tmob_message = "[src] steps over you carefully!"
var/mob/living/carbon/human/H = src
if(H.flying)
return TRUE //Silently pass without a message.
if(isTaurTail(H.tail_style))
var/datum/sprite_accessory/tail/taur/tail = H.tail_style
- to_chat(src,STEP_TEXT_OWNER(tail.msg_owner_help_run))
- to_chat(tmob,STEP_TEXT_PREY(tail.msg_prey_help_run))
- else
- to_chat(src,"You carefully step over [tmob].")
- to_chat(tmob,"[src] steps over you carefully!")
+ src_message = tail.msg_owner_help_run
+ tmob_message = tail.msg_prey_help_run
//Smaller person stepping under larger person
- else if(tmob.get_effective_size() > get_effective_size() && ishuman(tmob))
+ else if(get_effective_size() < tmob.get_effective_size() && ishuman(tmob))
+ src_message = "You run between [tmob]'s legs."
+ tmob_message = "[src] runs between your legs."
var/mob/living/carbon/human/H = tmob
if(isTaurTail(H.tail_style))
var/datum/sprite_accessory/tail/taur/tail = H.tail_style
- to_chat(src,STEP_TEXT_OWNER(tail.msg_prey_stepunder))
- to_chat(tmob,STEP_TEXT_PREY(tail.msg_owner_stepunder))
- else
- to_chat(src,"You run between [tmob]'s legs.")
- to_chat(tmob,"[src] runs between your legs.")
+ src_message = tail.msg_prey_stepunder
+ tmob_message = tail.msg_owner_stepunder
+
+ if(src_message)
+ to_chat(src, STEP_TEXT_OWNER(src_message))
+ if(tmob_message)
+ to_chat(tmob, STEP_TEXT_PREY(tmob_message))
return TRUE
return FALSE
@@ -196,202 +202,124 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2
*
* @return false if normal code should continue, 1 to prevent normal code.
*/
-/mob/living/proc/handle_micro_bump_other(var/mob/living/tmob)
+/mob/living/proc/handle_micro_bump_other(mob/living/tmob)
ASSERT(istype(tmob))
-
- //If they're flying, don't do any special interactions.
- if(ishuman(src))
- var/mob/living/carbon/human/P = src
- if(P.flying)
- return
-
+ //If we're flying, don't do any special interactions.
+ if(flying)
+ return
//If the prey is flying, don't smush them.
- if(ishuman(tmob))
- var/mob/living/carbon/human/D = tmob
- if(D.flying)
- return
-
- //They can't be stepping on anyone
+ if(tmob.flying)
+ return
+ //We can't be stepping on anyone
if(!canmove || buckled)
return
//Test/set if human
- var/mob/living/carbon/human/H
- if(ishuman(src))
- H = src
- else
+ var/mob/living/carbon/human/pred = src
+ if(!istype(pred))
//If we're not human, can't do the steppy
return FALSE
- var/mob/living/carbon/human/Ht
- if(ishuman(tmob))
- Ht = tmob
- else
+ var/mob/living/carbon/human/prey = tmob
+ if(!istype(prey))
//If they're not human, steppy shouldn't happen
return FALSE
- //Depending on intent...
- switch(a_intent)
+ // We need to be above a certain size ratio in order to do anything to the prey.
+ // For DISARM and HURT intent, this is >=0.75, for GRAB it is >=0.5
+ var/size_ratio = get_effective_size() - tmob.get_effective_size()
+ if(a_intent == I_GRAB && size_ratio < 0.5)
+ return FALSE
+ if((a_intent == I_DISARM || a_intent == I_HURT) && size_ratio < 0.75)
+ return FALSE
+ if(a_intent == I_HELP) // Theoretically not possible, but just in case.
+ return FALSE
- //src stepped on someone with disarm intent
- if(I_DISARM)
- // If bigger than them by at least 0.75, move onto them and print message.
- if((get_effective_size() - tmob.get_effective_size()) >= 0.75)
- now_pushing = 0
- forceMove(tmob.loc)
+ now_pushing = 0
+ forceMove(tmob.loc)
+ if(a_intent == I_GRAB || a_intent == I_DISARM)
+ tmob.resting = 1
- //Running on I_DISARM
- if(m_intent == "run")
- tmob.resting = 1 //Force them down to the ground.
+ var/size_damage_multiplier = size_multiplier - tmob.size_multiplier
+ // This technically means that I_GRAB will set this value to the same as I_HARM, but
+ // I_GRAB won't ever trigger the damage-giving code, so it doesn't matter.
+ // I_HARM: Rand 1-3 multiplied by 1 min or 1.75 max. 1 min 5.25 max damage to each limb.
+ // I_DISARM: Perform some HALLOSS damage to the smaller.
+ // Since stunned is broken, let's do this. Rand 15-30 multiplied by 1 min or 1.75 max. 15 holo to 52.5 holo, depending on RNG and size differnece.
+ var/damage = (a_intent == I_DISARM) ? (rand(15, 30) * size_damage_multiplier) : (rand(1, 3) * size_damage_multiplier)
+ // I_HARM only
+ var/calculated_damage = damage / 2 //This will sting, but not kill. Does .5 to 2.625 damage, randomly, to each limb.
- //Log it for admins (as opposed to walk which logs damage)
- add_attack_logs(src,tmob,"Pinned underfoot (run, no halloss)")
+ var/message_pred = null
+ var/message_prey = null
+ var/datum/sprite_accessory/tail/taur/tail = null
+ if(isTaurTail(pred.tail_style))
+ tail = pred.tail_style
- //Not a human, or not a taur, generic message only
- if(!H || !isTaurTail(H.tail_style))
- to_chat(src,"You quickly push [tmob] to the ground with your foot!")
- to_chat(tmob,"[src] pushes you down to the ground with their foot!")
+ if(a_intent == I_GRAB)
+ // You can only grab prey if you have no shoes on.
+ if(pred.shoes)
+ message_pred = "You step down onto [prey], squishing them and forcing them down to the ground!"
+ message_prey = "[pred] steps down and squishes you with their foot, forcing you down to the ground!"
+ if(tail)
+ message_pred = STEP_TEXT_OWNER(tail.msg_owner_grab_fail)
+ message_prey = STEP_TEXT_PREY(tail.msg_prey_grab_fail)
+ add_attack_logs(pred, prey,"Grabbed underfoot ([tail ? "taur" : "nontaur"], shoes)")
+ else
+ message_pred = "You pin [prey] down onto the floor with your foot and curl your toes up around their body, trapping them inbetween them!"
+ message_prey = "[pred] pins you down to the floor with their foot and curls their toes up around your body, trapping you inbetween them!"
+ if(tail)
+ message_pred = STEP_TEXT_OWNER(tail.msg_owner_grab_success)
+ message_prey = STEP_TEXT_PREY(tail.msg_prey_grab_success)
+ equip_to_slot_if_possible(prey.get_scooped(pred), slot_shoes, 0, 1)
+ add_attack_logs(pred, prey, "Grabbed underfoot ([tail ? "taur" : "nontaur"], no shoes)")
- //Human with taur tail, special messages are sent
- else
- var/datum/sprite_accessory/tail/taur/tail = H.tail_style
- to_chat(src,STEP_TEXT_OWNER("[tail.msg_owner_disarm_run]"))
- to_chat(tmob,STEP_TEXT_PREY("[tail.msg_prey_disarm_run]"))
+ if(m_intent == "run")
+ switch(a_intent)
+ if(I_DISARM)
+ message_pred = "You quickly push [prey] to the ground with your foot!"
+ message_prey = "[pred] pushes you down to the ground with their foot!"
+ if(tail)
+ message_pred = STEP_TEXT_OWNER(tail.msg_owner_disarm_run)
+ message_prey = STEP_TEXT_PREY(tail.msg_prey_disarm_run)
+ add_attack_logs(pred, prey, "Pinned underfoot (run, no halloss)")
+ if(I_HURT)
+ message_pred = "You carelessly step down onto [prey], crushing them!"
+ message_prey = "[pred] steps carelessly on your body, crushing you!"
+ if(tail)
+ message_pred = STEP_TEXT_OWNER(tail.msg_owner_harm_run)
+ message_prey = STEP_TEXT_PREY(tail.msg_prey_harm_run)
- //Walking on I_DISARM
- else
- //Perform some HALLOSS damage to the smaller.
- var/size_damage_multiplier = (src.size_multiplier - tmob.size_multiplier)
- var/damage = (rand(15,30)* size_damage_multiplier) //Since stunned is broken, let's do this. Rand 15-30 multiplied by 1 min or 1.75 max. 15 holo to 52.5 holo, depending on RNG and size differnece.
- tmob.apply_damage(damage, HALLOSS)
- tmob.resting = 1
+ for(var/obj/item/organ/external/I in prey.organs)
+ I.take_damage(calculated_damage, 0) // 5 damage min, 26.25 damage max, depending on size & RNG. If they're only stepped on once, the damage will (probably not...) heal over time.
+ prey.drip(0.1)
+ add_attack_logs(pred, prey, "Crushed underfoot (run, about [calculated_damage] damage)")
+ else
+ switch(a_intent)
+ if(I_DISARM)
+ message_pred = "You firmly push your foot down on [prey], painfully but harmlessly pinning them to the ground!"
+ message_prey = "[pred] firmly pushes their foot down on you, quite painfully but harmlessly pinning you to the ground!"
+ if(tail)
+ message_pred = STEP_TEXT_OWNER(tail.msg_owner_disarm_walk)
+ message_prey = STEP_TEXT_PREY(tail.msg_prey_disarm_walk)
+ add_attack_logs(pred, prey, "Pinned underfoot (walk, about [damage] halloss)")
+ tmob.apply_damage(damage, HALLOSS)
+ if(I_HURT)
+ message_pred = "You methodically place your foot down upon [prey]'s body, slowly applying pressure, crushing them against the floor below!"
+ message_prey = "[pred] methodically places their foot upon your body, slowly applying pressure, crushing you against the floor below!"
+ if(tail)
+ message_pred = STEP_TEXT_OWNER(tail.msg_owner_harm_walk)
+ message_prey = STEP_TEXT_PREY(tail.msg_prey_harm_walk)
+ // Multiplies the above damage by 3.5. This means a min of 1.75 damage, or a max of 9.1875. damage to each limb, depending on size and RNG.
+ calculated_damage *= 3.5
+ for(var/obj/item/organ/I in prey.organs)
+ I.take_damage(calculated_damage, 0)
+ prey.drip(3)
+ add_attack_logs(pred, prey, "Crushed underfoot (walk, about [calculated_damage] damage)")
- //Log it for admins (as opposed to run which logs no damage)
- add_attack_logs(src,tmob,"Pinned underfoot (walk, about [damage] halloss)")
-
- //Not a human, or not a taur, generic message only
- if(!H || !isTaurTail(H.tail_style))
- to_chat(src,"You firmly push your foot down on [tmob], painfully but harmlessly pinning them to the ground!")
- to_chat(tmob,"[src] firmly pushes their foot down on you, quite painfully but harmlessly pinning you to the ground!")
-
- //Human with taur tail, special messages are sent
- else
- var/datum/sprite_accessory/tail/taur/tail = H.tail_style
- to_chat(src,STEP_TEXT_OWNER("[tail.msg_owner_disarm_walk]"))
- to_chat(tmob,STEP_TEXT_PREY("[tail.msg_prey_disarm_walk]"))
-
- //Return true, the sizediff was enough that we handled it.
- return TRUE
-
- //Not enough sizediff for I_DISARM to do anything.
- else
- return FALSE
-
- //src stepped on someone with harm intent
- if(I_HURT)
- // If bigger than them by at least 0.75, move onto them and print message.
- if((get_effective_size() - tmob.get_effective_size()) >= 0.75)
- now_pushing = 0
- forceMove(tmob.loc)
-
- //Precalculate base damage
- var/size_damage_multiplier = (src.size_multiplier - tmob.size_multiplier)
- var/damage = (rand(1,3)* size_damage_multiplier) //Rand 1-3 multiplied by 1 min or 1.75 max. 1 min 5.25 max damage to each limb.
- var/calculated_damage = damage/2 //This will sting, but not kill. Does .5 to 2.625 damage, randomly, to each limb.
-
- //Running on I_HURT
- if(m_intent == "run")
-
- //Not a human, or not a taur, generic message only
- if(!H || !isTaurTail(H.tail_style))
- to_chat(src,"You carelessly step down onto [tmob], crushing them!")
- to_chat(tmob,"[src] steps carelessly on your body, crushing you!")
-
- //Human with taur tail, special messages are sent
- else
- var/datum/sprite_accessory/tail/taur/tail = H.tail_style
- to_chat(src,STEP_TEXT_OWNER("[tail.msg_owner_harm_run]"))
- to_chat(tmob,STEP_TEXT_PREY("[tail.msg_prey_harm_run]"))
-
- //If they are a human, do damage (doesn't hurt other mobs...?)
- if(Ht)
- for(var/obj/item/organ/external/I in Ht.organs)
- I.take_damage(calculated_damage, 0) // 5 damage min, 26.25 damage max, depending on size & RNG. If they're only stepped on once, the damage will (probably not...) heal over time.
- Ht.drip(0.1)
- add_attack_logs(src,tmob,"Crushed underfoot (run, about [calculated_damage] damage)")
-
- //Walking on I_HURT
- else
- //Multiplies the above damage by 3.5. This means a min of 1.75 damage, or a max of 9.1875. damage to each limb, depending on size and RNG.
- calculated_damage *= 3.5
-
- //If they are a human, do damage (doesn't hurt other mobs...?)
- if(Ht)
- for(var/obj/item/organ/I in Ht.organs)
- I.take_damage(calculated_damage, 0)
- Ht.drip(3)
- add_attack_logs(src,tmob,"Crushed underfoot (walk, about [calculated_damage] damage)")
-
- //Not a human, or not a taur, generic message only
- if(!H || !isTaurTail(H.tail_style))
- to_chat(src,"You methodically place your foot down upon [tmob]'s body, slowly applying pressure, crushing them against the floor below!")
- to_chat(tmob,"[src] methodically places their foot upon your body, slowly applying pressure, crushing you against the floor below!")
-
- //Human with taur tail, special messages are sent
- else
- var/datum/sprite_accessory/tail/taur/tail = H.tail_style
- to_chat(src,STEP_TEXT_OWNER("[tail.msg_owner_harm_walk]"))
- to_chat(tmob,STEP_TEXT_PREY("[tail.msg_prey_harm_walk]"))
-
- //Return true, the sizediff was enough that we handled it.
- return TRUE
-
- //Not enough sizediff for I_HURT to do anything.
- else
- return FALSE
-
- //src stepped on someone with grab intent
- if(I_GRAB)
- // If bigger than them by at least 0.50, move onto them and print message.
- if((get_effective_size() - tmob.get_effective_size()) >= 0.50)
- now_pushing = 0
- tmob.resting = 1
- forceMove(tmob.loc)
-
- //Not a human, or not a taur while wearing shoes = no grab
- if(!H || (!isTaurTail(H.tail_style) && H.shoes))
- to_chat(src,"You step down onto [tmob], squishing them and forcing them down to the ground!")
- to_chat(tmob,"[src] steps down and squishes you with their foot, forcing you down to the ground!")
- add_attack_logs(src,tmob,"Grabbed underfoot (nontaur, shoes)")
-
- //Human, not a taur, but not wearing shoes = yes grab
- else if(H && (!isTaurTail(H.tail_style) && !H.shoes))
- to_chat(src,"You pin [tmob] down onto the floor with your foot and curl your toes up around their body, trapping them inbetween them!")
- to_chat(tmob,"[src] pins you down to the floor with their foot and curls their toes up around your body, trapping you inbetween them!")
- equip_to_slot_if_possible(tmob.get_scooped(H), slot_shoes, 0, 1)
- add_attack_logs(src,tmob,"Grabbed underfoot (nontaur, no shoes)")
-
- //Human, taur, shoes = no grab, special message
- else if(H.shoes)
- var/datum/sprite_accessory/tail/taur/tail = H.tail_style
- to_chat(src,STEP_TEXT_OWNER("[tail.msg_owner_grab_fail]"))
- to_chat(tmob,STEP_TEXT_PREY("[tail.msg_prey_grab_fail]"))
- add_attack_logs(src,tmob,"Grabbed underfoot (taur, shoes)")
-
- //Human, taur, no shoes = yes grab, special message
- else
- var/datum/sprite_accessory/tail/taur/tail = H.tail_style
- to_chat(src,STEP_TEXT_OWNER("[tail.msg_owner_grab_success]"))
- to_chat(tmob,STEP_TEXT_PREY("[tail.msg_prey_grab_success]"))
- equip_to_slot_if_possible(tmob.get_scooped(H), slot_shoes, 0, 1)
- add_attack_logs(src,tmob,"Grabbed underfoot (taur, no shoes)")
-
- //Return true, the sizediff was enough that we handled it.
- return TRUE
-
- //Not enough sizediff for I_GRAB to do anything.
- else
- return FALSE
+ to_chat(pred, "[message_pred]")
+ to_chat(prey, "[message_prey]")
+ return TRUE
#undef STEP_TEXT_OWNER
#undef STEP_TEXT_PREY
\ No newline at end of file
diff --git a/code/modules/vore/resizing/sizegun_vr.dm b/code/modules/vore/resizing/sizegun_vr.dm
index 2c1dbe8d04..491ffdf7de 100644
--- a/code/modules/vore/resizing/sizegun_vr.dm
+++ b/code/modules/vore/resizing/sizegun_vr.dm
@@ -41,8 +41,8 @@
set category = "Object"
set src in view(1)
- var/size_select = input("Put the desired size (25-200%)", "Set Size", size_set_to*100) as num
- if(size_select>200 || size_select<25)
+ var/size_select = input("Put the desired size (25-200%)", "Set Size", size_set_to * 100) as num
+ if(size_select > 200 || size_select < 25)
to_chat(usr, "Invalid size.")
return
size_set_to = (size_select/100)
@@ -69,24 +69,17 @@
tracer_type = /obj/effect/projectile/tracer/xray
impact_type = /obj/effect/projectile/impact/xray
- on_hit(var/atom/target)
- var/mob/living/M = target
- if(ishuman(target))
- var/mob/living/carbon/human/H = M
- H.resize(set_size)
- H.show_message(" The beam fires into your body, changing your size!")
- H.updateicon()
- else if (istype(target, /mob/living/))
- var/mob/living/H = M
- H.resize(set_size)
- H.updateicon()
- else
- return 1
-
+/obj/item/projectile/beam/sizelaser/on_hit(var/atom/target)
+ var/mob/living/M = target
+ if(istype(M))
+ M.resize(set_size)
+ to_chat(M, " The beam fires into your body, changing your size!")
+ M.updateicon()
+ return
+ return 1
/obj/item/projectile/beam/sizelaser/shrink
set_size = 0.5 //50% of current size
-
/obj/item/projectile/beam/sizelaser/grow
- set_size = 2.0 //200% of current size
\ No newline at end of file
+ set_size = 2.0 //200% of current size
diff --git a/code/modules/vore/weight/fitness_machines_vr.dm b/code/modules/vore/weight/fitness_machines_vr.dm
index 4a7c5fe2bb..82d2b9910b 100644
--- a/code/modules/vore/weight/fitness_machines_vr.dm
+++ b/code/modules/vore/weight/fitness_machines_vr.dm
@@ -11,7 +11,7 @@
var/cooldown = 10
var/weightloss_power = 1
-/obj/machinery/fitness/attack_hand(var/mob/living/user)
+/obj/machinery/fitness/attack_hand(mob/living/user)
if(user.nutrition < 70)
to_chat(user, "You need more energy to workout with the [src]!")
@@ -21,12 +21,12 @@
else //If they have enough nutrition and body weight, they can exercise.
user.setClickCooldown(cooldown)
user.nutrition -= 10 * weightloss_power
- user.weight -= 0.025 * weightloss_power * (0.01*user.weight_loss)
- flick("[icon_state]2",src)
+ user.weight -= 0.025 * weightloss_power * (0.01 * user.weight_loss)
+ flick("[icon_state]2", src)
var/message = pick(messages)
to_chat(user, "[message].")
for(var/s in workout_sounds)
- playsound(src.loc, s, 50, 1)
+ playsound(loc, s, 50, 1)
/obj/machinery/fitness/punching_bag
name = "punching bag"
@@ -54,20 +54,20 @@
"You hammer the clown right in it's face with your fist",
"A honk emits from the punching bag as you hit it")
-/obj/machinery/fitness/heavy/attackby(obj/item/W, var/mob/living/user)
+/obj/machinery/fitness/heavy/attackby(obj/item/W, mob/living/user)
if(W.is_wrench())
- src.add_fingerprint(user)
+ add_fingerprint(user)
user.visible_message("[user] has [anchored ? "un" : ""]secured \the [src].", "You [anchored ? "un" : ""]secure \the [src].")
anchored = !anchored
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
return
-/obj/machinery/fitness/heavy/attack_hand(var/mob/living/user)
+/obj/machinery/fitness/heavy/attack_hand(mob/living/user)
if(!anchored)
to_chat(user, "For safety reasons, you are required to have this equipment wrenched down before using it!")
return
- else if(user.loc != src.loc)
+ else if(user.loc != loc)
to_chat(user, "For safety reasons, you need to be sitting in the [src] for it to work!")
return