From 0660d084b9c7794d26ca2ebe167db4124ddcd4d5 Mon Sep 17 00:00:00 2001 From: MeepleMuncher <76881946+MeepleMuncher@users.noreply.github.com> Date: Mon, 8 Sep 2025 08:56:20 +0300 Subject: [PATCH] TF Verb Mergening (#18353) * Initial commit * waait a second, this isn't chomp * oop, missed those comments * also missed that * typo! * begone src. * fixes typing! * whoops! * can I get rid of this? * fixes some missed tf calls, attempts to fix ooc escape * band-aid fix for OOC escaping item tf * Update mob_tf.dm * Update living_vr.dm * no src * get rid of redundant faction swaps --------- Co-authored-by: Cameron Lennox --- code/modules/admin/player_effects.dm | 10 +- .../human/species/lleill/lleill_items.dm | 3 +- .../simple_mob/subtypes/glamour/ddraig.dm | 3 +- code/modules/mob/new_player/new_player.dm | 6 +- code/modules/reagents/reagents/medicine_vr.dm | 3 +- code/modules/vore/eating/living_vr.dm | 9 ++ code/modules/vore/mob_tf.dm | 14 +++ code/modules/vore/mouseray.dm | 2 +- .../artifacts/replicator_vr.dm | 116 +----------------- 9 files changed, 35 insertions(+), 131 deletions(-) diff --git a/code/modules/admin/player_effects.dm b/code/modules/admin/player_effects.dm index 95e75b856e..1a2b1286bc 100644 --- a/code/modules/admin/player_effects.dm +++ b/code/modules/admin/player_effects.dm @@ -294,9 +294,8 @@ return var/mob/living/new_mob = new chosen_beast(get_turf(M)) - new_mob.faction = M.faction - new_mob.mob_tf(M) + M.tf_into(new_mob) if("item_tf") var/mob/living/M = target @@ -317,11 +316,8 @@ var/obj/item/spawned_obj = new spawning(M.loc) var/obj/item/original_name = spawned_obj.name - spawned_obj.inhabit_item(M, original_name, M) - var/mob/living/possessed_voice = spawned_obj.possessed_voice - spawned_obj.trash_eatable = M.devourable - spawned_obj.unacidable = !M.digestable - M.forceMove(possessed_voice) + + M.tf_into(spawned_obj, TRUE, original_name) if("elder_smite") if(!target.ckey) diff --git a/code/modules/mob/living/carbon/human/species/lleill/lleill_items.dm b/code/modules/mob/living/carbon/human/species/lleill/lleill_items.dm index fb453f0c1e..29db8b4b77 100644 --- a/code/modules/mob/living/carbon/human/species/lleill/lleill_items.dm +++ b/code/modules/mob/living/carbon/human/species/lleill/lleill_items.dm @@ -423,9 +423,8 @@ if(M.stat == DEAD) //We can let it undo the TF, because the person will be dead, but otherwise things get weird. return var/mob/living/new_mob = spawn_mob(M) - new_mob.faction = M.faction - new_mob.mob_tf(M) + M.tf_into(new_mob) /obj/item/glamour_unstable/proc/spawn_mob(var/mob/living/target) diff --git a/code/modules/mob/living/simple_mob/subtypes/glamour/ddraig.dm b/code/modules/mob/living/simple_mob/subtypes/glamour/ddraig.dm index 6ed4b7cb64..56eb4caad9 100644 --- a/code/modules/mob/living/simple_mob/subtypes/glamour/ddraig.dm +++ b/code/modules/mob/living/simple_mob/subtypes/glamour/ddraig.dm @@ -255,9 +255,8 @@ if(M.stat == DEAD) //We can let it undo the TF, because the person will be dead, but otherwise things get weird. return var/mob/living/new_mob = spawn_mob(M) - new_mob.faction = M.faction - new_mob.mob_tf(M) + M.tf_into(new_mob) addtimer(CALLBACK(new_mob, TYPE_PROC_REF(/mob/living, revert_mob_tf)), 30 SECONDS, TIMER_DELETE_ME) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index baafc9a5c8..ac09097023 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -341,11 +341,7 @@ character.forceMove(cryst) cryst.update_icon() else if(itemtf) - itemtf.inhabit_item(character, itemtf.name, character) - var/mob/living/possessed_voice = itemtf.possessed_voice - itemtf.trash_eatable = character.devourable - itemtf.unacidable = !character.digestable - character.forceMove(possessed_voice) + character.tf_into(itemtf, TRUE, itemtf.name) else if(prey) character.copy_from_prefs_vr(1,1) //Yes I know we're reloading these, shut up var/obj/belly/gut_to_enter diff --git a/code/modules/reagents/reagents/medicine_vr.dm b/code/modules/reagents/reagents/medicine_vr.dm index 507e74374e..5974d2f105 100644 --- a/code/modules/reagents/reagents/medicine_vr.dm +++ b/code/modules/reagents/reagents/medicine_vr.dm @@ -258,9 +258,8 @@ return log_debug("polymorph not dead") var/mob/living/new_mob = spawn_mob(M) - new_mob.faction = M.faction - new_mob.mob_tf(M) + M.tf_into(new_mob) target.bloodstr.clear_reagents() //Got to clear all reagents to make sure mobs don't keep spawning. target.ingested.clear_reagents() target.touching.clear_reagents() diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm index d2233f6376..f8fe30bbd5 100644 --- a/code/modules/vore/eating/living_vr.dm +++ b/code/modules/vore/eating/living_vr.dm @@ -587,6 +587,15 @@ var/mob/living/ourmob = tf_mob_holder if(ourmob.loc != src) if(isnull(ourmob.loc)) + var/mob/living/voice/possessed_voice = src // Stupid band-aid fix for OOC escaping object TF + if(possessed_voice.item_tf) + mind.transfer_to(ourmob) + item_to_destroy.possessed_voice -= src + qdel(src) + ourmob.forceMove(item_to_destroy.loc) + qdel(item_to_destroy) + log_and_message_admins("[key_name(src)] used the OOC escape button to revert back to their original form from being TFed into an object.") + return to_chat(src,span_notice("You have no body.")) src.tf_mob_holder = null return diff --git a/code/modules/vore/mob_tf.dm b/code/modules/vore/mob_tf.dm index 82522f4ef8..6737cd5305 100644 --- a/code/modules/vore/mob_tf.dm +++ b/code/modules/vore/mob_tf.dm @@ -1,5 +1,19 @@ // Procs for living mobs based around mob transformation. Initially made for the mouseray, they are now used in various other places and the main procs are now called from here. +/mob/living/proc/tf_into(var/A, var/allow_emotes = FALSE, var/object_name) + if(!object_name) + object_name = name + if(isliving(A)) + var/mob/living/M = A + M.mob_tf(src) + return + if(isitem(A)) + var/obj/item/I = A + I.inhabit_item(src, object_name, src, allow_emotes) + var/mob/living/possessed_voice = I.possessed_voice + I.trash_eatable = devourable + I.unacidable = !digestable + forceMove(possessed_voice) /mob/living/proc/mob_tf(var/mob/living/M) if(!istype(M)) diff --git a/code/modules/vore/mouseray.dm b/code/modules/vore/mouseray.dm index dd2e1b2a00..3ab94b088c 100644 --- a/code/modules/vore/mouseray.dm +++ b/code/modules/vore/mouseray.dm @@ -132,7 +132,7 @@ return var/mob/living/new_mob = spawn_mob(M) - new_mob.mob_tf(M) + M.tf_into(new_mob) /obj/item/projectile/beam/mouselaser/proc/spawn_mob(var/mob/living/target) if(!ispath(tf_type)) diff --git a/code/modules/xenoarcheaology/artifacts/replicator_vr.dm b/code/modules/xenoarcheaology/artifacts/replicator_vr.dm index 21bc5431bb..982b6ba6a2 100644 --- a/code/modules/xenoarcheaology/artifacts/replicator_vr.dm +++ b/code/modules/xenoarcheaology/artifacts/replicator_vr.dm @@ -94,108 +94,13 @@ var/mob/mob_to_be_changed = micro_holder.held_mob var/mob/living/M = mob_to_be_changed //Start of mob code shamelessly ripped from mouseray - new_mob.faction = M.faction - - if(new_mob && isliving(new_mob)) - for(var/obj/belly/B as anything in new_mob.vore_organs) - new_mob.vore_organs -= B - qdel(B) - new_mob.vore_organs = list() - new_mob.name = M.name - new_mob.real_name = M.real_name - for(var/lang in M.languages) - new_mob.languages |= lang - M.copy_vore_prefs_to_mob(new_mob) - new_mob.vore_selected = M.vore_selected - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(ishuman(new_mob)) - var/mob/living/carbon/human/N = new_mob - N.gender = H.gender - N.identifying_gender = H.identifying_gender - else - new_mob.gender = H.identifying_gender - else - new_mob.gender = M.gender - if(ishuman(new_mob)) - var/mob/living/carbon/human/N = new_mob - N.identifying_gender = M.gender - - for(var/obj/belly/B as anything in M.vore_organs) - B.loc = new_mob - B.forceMove(new_mob) - B.owner = new_mob - M.vore_organs -= B - new_mob.vore_organs += B - - M.soulgem.transfer_self(new_mob) // Soulcatcher - - new_mob.ckey = M.ckey - if(M.ai_holder && new_mob.ai_holder) - var/datum/ai_holder/old_AI = M.ai_holder - old_AI.set_stance(STANCE_SLEEP) - var/datum/ai_holder/new_AI = new_mob.ai_holder - new_AI.hostile = old_AI.hostile - new_AI.retaliate = old_AI.retaliate - M.loc = new_mob - M.forceMove(new_mob) - new_mob.tf_mob_holder = M - ///End of mobcode. - qdel(source_material) - M.forceMove(new_mob) + M.tf_into(new_mob) //Did they put a person in it? else if(isliving(source_material)) var/mob/living/M = source_material //Start of mob code shamelessly ripped from mouseray - new_mob.faction = M.faction - - if(new_mob && isliving(new_mob)) - for(var/obj/belly/B as anything in new_mob.vore_organs) - new_mob.vore_organs -= B - qdel(B) - new_mob.vore_organs = list() - new_mob.name = M.name - new_mob.real_name = M.real_name - for(var/lang in M.languages) - new_mob.languages |= lang - M.copy_vore_prefs_to_mob(new_mob) - new_mob.vore_selected = M.vore_selected - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(ishuman(new_mob)) - var/mob/living/carbon/human/N = new_mob - N.gender = H.gender - N.identifying_gender = H.identifying_gender - else - new_mob.gender = H.identifying_gender - else - new_mob.gender = M.gender - if(ishuman(new_mob)) - var/mob/living/carbon/human/N = new_mob - N.identifying_gender = M.gender - - for(var/obj/belly/B as anything in M.vore_organs) - B.loc = new_mob - B.forceMove(new_mob) - B.owner = new_mob - M.vore_organs -= B - new_mob.vore_organs += B - - M.soulgem.transfer_self(new_mob) // Soulcatcher - - new_mob.ckey = M.ckey - if(M.ai_holder && new_mob.ai_holder) - var/datum/ai_holder/old_AI = M.ai_holder - old_AI.set_stance(STANCE_SLEEP) - var/datum/ai_holder/new_AI = new_mob.ai_holder - new_AI.hostile = old_AI.hostile - new_AI.retaliate = old_AI.retaliate - M.loc = new_mob - M.forceMove(new_mob) - new_mob.tf_mob_holder = M - ///End of mobcode. - + M.tf_into(new_mob) spawn_progress_time = 0 max_spawn_time = rand(30,100) @@ -446,24 +351,11 @@ var/obj/item/holder/micro/micro_holder = source_material //Tells the machine that a micro is the material being used var/mob/mob_to_be_changed = micro_holder.held_mob //Get the mob. var/mob/living/M = mob_to_be_changed - M.release_vore_contents(TRUE, TRUE) //Release their stomach contents. Don't spam the chat, either. - spawned_obj.inhabit_item(M, original_name, M) //Take the spawned mob and call the TF proc on it. - var/mob/living/possessed_voice = spawned_obj.possessed_voice //Get the possessed voice. - qdel(source_material) //Deletes the micro holder, we don't need it anymore. - spawned_obj.trash_eatable = M.devourable //Can this item be eaten? Let's decide based on the person's prefs! - spawned_obj.unacidable = !M.digestable //Can this item be digested? - M.forceMove(possessed_voice) //Places them in the 'voice' for later recovery! Essentially: The item contains a 'possessed voice' mob, which contains their original mob. - + M.tf_into(spawned_obj, TRUE, original_name) else if(isliving(source_material))//Did they shove a person in there normally? var/mob/living/M = source_material //If so, this cuts down the work we have to do! - M.release_vore_contents(TRUE, TRUE) //Release their stomach contents. Don't spam the chat, either. - spawned_obj.inhabit_item(M, original_name, M) - var/mob/living/possessed_voice = spawned_obj.possessed_voice - spawned_obj.trash_eatable = M.devourable - spawned_obj.unacidable = !M.digestable - M.forceMove(possessed_voice) - + M.tf_into(spawned_obj, TRUE, original_name) spawn_progress_time = 0 max_spawn_time = rand(30,100)