diff --git a/code/citadel/hooks-defs.dm b/code/controllers/hooks-defs.dm similarity index 100% rename from code/citadel/hooks-defs.dm rename to code/controllers/hooks-defs.dm diff --git a/code/controllers/hooks.dm b/code/controllers/hooks.dm index 475537300c..f499a61ae7 100644 --- a/code/controllers/hooks.dm +++ b/code/controllers/hooks.dm @@ -26,14 +26,14 @@ /proc/callHook(hook, list/args=null) var/hook_path = text2path("/hook/[hook]") if(!hook_path) - // error("Invalid hook '/hook/[hook]' called.") + CRASH("Invalid hook '/hook/[hook]' called.") return 0 var/caller = new hook_path var/status = 1 for(var/P in typesof("[hook_path]/proc")) if(!call(caller, P)(arglist(args))) - // error("Hook '[P]' failed or runtimed.") + CRASH("Hook '[P]' failed or runtimed.") status = 0 return status diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 8a381043ba..7b6b468c38 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -327,6 +327,7 @@ var/next_external_rsc = 0 if(!tooltips) tooltips = new /datum/tooltip(src) + hook_vr("client_new",list(src)) ////////////// //DISCONNECT// diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index ae67f69c59..90fa7c6fcf 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -118,8 +118,7 @@ var/list/preferences_datums = list() var/loaded_preferences_successfully = load_preferences() if(loaded_preferences_successfully) if(load_character()) - if(load_vore_preferences()) - return + return //we couldn't load character data so just randomize the character appearance + name random_character() //let's create a random character then - rather than a fat, bald and naked man. real_name = pref_species.random_name(gender,1) @@ -1390,10 +1389,10 @@ var/list/preferences_datums = list() if("load") load_preferences() load_character() - load_vore_preferences() + attempt_vr(parent.prefs_vr,"load_vore","") if("changeslot") - load_vore_preferences(text2num(href_list["num"])) + attempt_vr(parent.prefs_vr,"load_vore","") if(!load_character(text2num(href_list["num"]))) random_character() real_name = random_unique_name(gender) @@ -1453,9 +1452,4 @@ var/list/preferences_datums = list() if(icon_updates) character.update_body() character.update_hair() - character.update_body_parts() - - //vore - character.digestable = digestable - character.devourable = devourable - character.vore_organs = belly_prefs \ No newline at end of file + character.update_body_parts() \ No newline at end of file diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index bbb4358246..fab65703b2 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -176,19 +176,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["parallax"] >> parallax S["uplink_loc"] >> uplink_spawn_loc - //vore - - S["digestable"] >> digestable - S["devourable"] >> devourable - S["belly_prefs"] >> belly_prefs - - if(isnull(digestable)) - digestable = 1 - if(isnull(devourable)) - devourable = 1 - if(isnull(belly_prefs)) - belly_prefs = list() - //try to fix any outdated data if necessary if(needs_update >= 0) update_preferences(needs_update, S) //needs_update = savefile_version if we need an update (positive integer) @@ -245,12 +232,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["clientfps"] << clientfps S["parallax"] << parallax - //vore - - S["digestable"] << digestable - S["devourable"] << devourable - S["belly_prefs"] << belly_prefs - return 1 /datum/preferences/proc/load_character(slot) @@ -497,43 +478,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car return 1 -/datum/preferences/proc/load_vore_preferences(slot) - if(!path) return 0 - if(!fexists(path)) return 0 - var/savefile/S = new /savefile(path) - if(!S) return 0 - S.cd = "/" - if(!slot) slot = default_slot - slot = sanitize_integer(slot, 1, max_save_slots, initial(default_slot)) - if(slot != default_slot) - default_slot = slot - S["default_slot"] << slot - S.cd = "/character[slot]" - - S["belly_prefs"] >> belly_prefs - S["devourable"] >> devourable - S["digestable"] >> digestable - - digestable = sanitize_integer(digestable, 0, 1, initial(digestable)) - devourable = sanitize_integer(devourable, 0, 1, initial(devourable)) - - if(!belly_prefs) - belly_prefs = list() - - return 1 - -/datum/preferences/proc/save_vore_preferences() - if(!path) return 0 - var/savefile/S = new /savefile(path) - if(!S) return 0 - S.cd = "/character[default_slot]" - - S["belly_prefs"] << belly_prefs - S["devourable"] << devourable - S["digestable"] << digestable - - return 1 - #undef SAVEFILE_VERSION_MAX #undef SAVEFILE_VERSION_MIN /* diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 1c354fca8c..cb05fbbf4a 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -17,26 +17,6 @@ medhud.add_to_hud(src) faction |= "\ref[src]" - //Tries to load prefs if a client is present otherwise gives freebie stomach - spawn(20) //Wait a couple of seconds to make sure copy_to or whatever has gone - verbs += /mob/living/proc/insidePanel - verbs += /mob/living/proc/escapeOOC - - if(!vore_organs.len) - // if(isanimal(src)) - // return 0 // No random NPC guts - // if(isbrain(src)) - // return 0 // No Brain guts - // if(issilicon(src)) - // return 0 // No guts for Silicons either - var/datum/belly/B = new /datum/belly(src) - B.owner = src - B.immutable = 1 - B.name = "Stomach" - B.inside_flavor = "It appears to be rather warm and wet. Makes sense, considering it's inside \the [name]." - vore_organs[B.name] = B - vore_selected = B.name - /mob/living/prepare_huds() ..() prepare_data_huds() @@ -568,9 +548,7 @@ resist_buckle() // climbing out of a gut - else if(ismob(loc)) - vore_process_resist(src) - return + if(attempt_vr(src,"vore_process_resist",args)) return TRUE //Breaking out of a container (Locker, sleeper, cryo...) else if(isobj(loc)) diff --git a/code/citadel/vore/appearance/preferences_vr.dm b/code/modules/vore/appearance/preferences_vr.dm similarity index 100% rename from code/citadel/vore/appearance/preferences_vr.dm rename to code/modules/vore/appearance/preferences_vr.dm diff --git a/code/citadel/vore/appearance/spider_taur_powers_vr.dm b/code/modules/vore/appearance/spider_taur_powers_vr.dm similarity index 100% rename from code/citadel/vore/appearance/spider_taur_powers_vr.dm rename to code/modules/vore/appearance/spider_taur_powers_vr.dm diff --git a/code/citadel/vore/appearance/sprite_accessories_vr.dm b/code/modules/vore/appearance/sprite_accessories_vr.dm similarity index 100% rename from code/citadel/vore/appearance/sprite_accessories_vr.dm rename to code/modules/vore/appearance/sprite_accessories_vr.dm diff --git a/code/citadel/vore/appearance/update_icons_vr.dm b/code/modules/vore/appearance/update_icons_vr.dm similarity index 100% rename from code/citadel/vore/appearance/update_icons_vr.dm rename to code/modules/vore/appearance/update_icons_vr.dm diff --git a/code/citadel/vore/eating/belly_vr.dm b/code/modules/vore/eating/belly_vr.dm similarity index 97% rename from code/citadel/vore/eating/belly_vr.dm rename to code/modules/vore/eating/belly_vr.dm index bfa6ba61e0..d2ec81bccf 100644 --- a/code/citadel/vore/eating/belly_vr.dm +++ b/code/modules/vore/eating/belly_vr.dm @@ -113,14 +113,14 @@ B.internal_contents.Add(M) owner.visible_message("[owner] expels everything from their [lowertext(name)]!") - return 1 + return TRUE // 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. /datum/belly/proc/release_specific_contents(var/atom/movable/M) if (!(M in internal_contents)) - return 0 // They weren't in this belly anyway + return FALSE // They weren't in this belly anyway M.forceMove(owner.loc) // Move the belly contents into the same location as belly's owner. src.internal_contents.Add(M) // Remove from the belly contents @@ -130,7 +130,7 @@ owner.visible_message("[owner] expels [M] from their [lowertext(name)]!") // owner.regenerate_icons() - return 1 + return TRUE // Actually perform the mechanics of devouring the tasty prey. // The purpose of this method is to avoid duplicate code, and ensure that all necessary @@ -282,10 +282,10 @@ struggle_outer_message = "" + struggle_outer_message + "" struggle_user_message = "" + struggle_user_message + "" - for(var/mob/M in hearers(4, owner)) - M.visible_message(struggle_outer_message, 2) // hearable - R << struggle_user_message - playsound(R.loc, "struggle_sounds", 50, 1, 0, 1, 1) +// for(var/mob/M in hearers(4, owner)) +// M.visible_message(struggle_outer_message) // hearable + R.visible_message( "[struggle_outer_message]", "[struggle_user_message]") + playsound(R.loc, "struggle_sounds", 50, 0, -5) if(escapable && R.a_intent != "help") //If the stomach has escapable enabled and the person is actually trying to kick out R << "You attempt to climb out of \the [name]." diff --git a/code/citadel/vore/eating/bellymodes_vr.dm b/code/modules/vore/eating/bellymodes_vr.dm similarity index 79% rename from code/citadel/vore/eating/bellymodes_vr.dm rename to code/modules/vore/eating/bellymodes_vr.dm index 1796e15902..3be8ad7ba3 100644 --- a/code/citadel/vore/eating/bellymodes_vr.dm +++ b/code/modules/vore/eating/bellymodes_vr.dm @@ -20,7 +20,7 @@ if(digest_mode == DM_DIGEST) if(prob(50)) - playsound(owner.loc, "digestion_sounds", 65, 1, 0, 1, 1) + playsound(owner.loc, "digestion_sounds", 50, 0, -5) for (var/mob/living/M in internal_contents) //Pref protection! @@ -42,11 +42,11 @@ digest_alert_prey = replacetext(digest_alert_prey,"%belly",lowertext(name)) //Send messages - owner << "" + digest_alert_owner + "" - M << "" + digest_alert_prey + "" + owner << "" + digest_alert_owner + "" + M << "" + digest_alert_prey + "" owner.nutrition += 400 // so eating dead mobs gives you *something*. - playsound(owner.loc, "death_gurgles", 70, 1, 0, 1, 1) + playsound(owner.loc, "death_gurgles", 50, 0, -5) digestion_death(M) owner.update_icons() continue @@ -62,7 +62,7 @@ if(digest_mode == DM_DIGESTF) if(prob(50)) - playsound(owner.loc, "digestion_sounds", 65, 1, 0, 1, 1) + playsound(owner.loc, "digestion_sounds", 55, 0, -3) //slightly louder 'cuz heavier gurgles for (var/mob/living/M in internal_contents) //Pref protection! @@ -84,11 +84,12 @@ digest_alert_prey = replacetext(digest_alert_prey,"%belly",lowertext(name)) //Send messages - owner << "" + digest_alert_owner + "" - M << "" + digest_alert_prey + "" - + owner << "" + digest_alert_owner + "" + M << "" + digest_alert_prey + "" + M.visible_message("[digest_alert_owner]", "[digest_alert_prey]", + "You watch as [owner]'s form lose its additions.") owner.nutrition += 400 // so eating dead mobs gives you *something*. - playsound(owner.loc, "death_gurgles", 70, 1, 0, 1, 1) + playsound(owner.loc, "death_gurgles", 50, 0, -5) digestion_death(M) owner.update_icons() continue @@ -103,7 +104,7 @@ ///////////////////////////// DM_HEAL ///////////////////////////// if(digest_mode == DM_HEAL) if(prob(50)) - playsound(owner.loc, "digestion_sounds", 50, 1, 0, 1, 1) + playsound(owner.loc, "digestion_sounds", 45, 0, -6) //very quiet gurgles, supposedly. for (var/mob/living/M in internal_contents) if(M.stat != DEAD) diff --git a/code/citadel/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm similarity index 67% rename from code/citadel/vore/eating/living_vr.dm rename to code/modules/vore/eating/living_vr.dm index f08c8f6d60..b236d8ff52 100644 --- a/code/citadel/vore/eating/living_vr.dm +++ b/code/modules/vore/eating/living_vr.dm @@ -6,6 +6,57 @@ var/devourable = 0 // Can the mob be vored at all? // var/feeding = 0 // Are we going to feed someone else? + +// +// Hook for generic creation of stuff on new creatures +// +/hook/living_new/proc/vore_setup(mob/living/M) + M.verbs += /mob/living/proc/insidePanel + M.verbs += /mob/living/proc/escapeOOC + + //Tries to load prefs if a client is present otherwise gives freebie stomach + if(!M.vore_organs || !M.vore_organs.len) + spawn(20) //Wait a couple of seconds to make sure copy_to or whatever has gone + if(!M) return + + if(M.client && M.client.prefs_vr) + if(!M.copy_from_prefs_vr()) + M << "ERROR: You seem to have saved VOREStation prefs, but they couldn't be loaded." + return 0 + if(M.vore_organs && M.vore_organs.len) + M.vore_selected = M.vore_organs[1] + + if(!M.vore_organs || !M.vore_organs.len) + if(!M.vore_organs) + M.vore_organs = list() + var/datum/belly/B = new /datum/belly(M) + B.immutable = 1 + B.name = "Stomach" + B.inside_flavor = "It appears to be rather warm and wet. Makes sense, considering it's inside \the [M.name]." + M.vore_organs[B.name] = B + M.vore_selected = B.name + + //Simple_animal gets emotes. move this to that hook instead? + if(istype(src,/mob/living/simple_animal)) + B.emote_lists[DM_HOLD] = list( + "The insides knead at you gently for a moment.", + "The guts glorp wetly around you as some air shifts.", + "Your predator takes a deep breath and sighs, shifting you somewhat.", + "The stomach squeezes you tight for a moment, then relaxes.", + "During a moment of quiet, breathing becomes the most audible thing.", + "The warm slickness surrounds and kneads on you.") + + B.emote_lists[DM_DIGEST] = list( + "The caustic acids eat away at your form.", + "The acrid air burns at your lungs.", + "Without a thought for you, the stomach grinds inwards painfully.", + "The guts treat you like food, squeezing to press more acids against you.", + "The onslaught against your body doesn't seem to be letting up; you're food now.", + "The insides work on you like they would any other food.") + + //Return 1 to hook-caller + return 1 + // // Handle being clicked, perhaps with something to devour // @@ -15,33 +66,36 @@ // Critical adjustments due to TG grab changes - Poojawa /mob/living/proc/vore_attack(var/mob/living/user, var/mob/living/prey) - if(!user) - return - if(!prey) - return - if(prey==user) + if(!user || !prey) return + if(prey == src && user.zone_selected == "mouth") //you click your target +// if(!feeding(src)) +// return if(!is_vore_predator(prey)) user << "They aren't voracious enough." - feed_self_to_grabbed(user) + return + feed_self_to_grabbed(user, src) if(user == src) //you click yourself if(!is_vore_predator(src)) user << "You aren't voracious enough." - feed_grabbed_to_self(prey, user) + return + user.feed_grabbed_to_self(src, prey) else // click someone other than you/prey +// if(!feeding(src)) +// return if(!is_vore_predator(src)) user << "They aren't voracious enough." return - feed_grabbed_to_other(user) + feed_grabbed_to_other(user, prey, src) // // Eating procs depending on who clicked what // /mob/living/proc/feed_grabbed_to_self(var/mob/living/user, var/mob/living/prey) var/belly = user.vore_selected - return perform_the_nom(prey, user, prey, belly) + 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) var/belly @@ -90,7 +144,7 @@ // Now give the prey time to escape... return if they did if(!do_mob(src, user, swallow_time)) - return 0 // Prey escaped (or user disabled) before timer expired. + return FALSE // Prey escaped (or user disabled) before timer expired. // If we got this far, nom successful! Announce it! user.visible_message(success_msg) @@ -111,7 +165,7 @@ else message_admins("[key_name(user)] forced [key_name(pred)] to eat [key_name(prey)]. ([pred ? "JMP" : "null"])") log_attack("[key_name(user)] forced [key_name(pred)] to eat [key_name(prey)].") - return 1 + return TRUE // //End vore code. @@ -164,7 +218,7 @@ //Other overridden resists go here - return 0 + return FALSE // // Proc for updating vore organs and digestion/healing/absorbing @@ -211,3 +265,59 @@ else src << "You aren't inside anything, you clod." + +// +// Verb for saving vore preferences to save file +// +/mob/living/proc/save_vore_prefs() + if(!(client || client.prefs_vr)) + return FALSE + if(!copy_to_prefs_vr()) + return FALSE + if(!client.prefs_vr.save_vore()) + return FALSE + + return TRUE + +/mob/living/proc/apply_vore_prefs() + if(!(client || client.prefs_vr)) + return FALSE + if(!client.prefs_vr.load_vore()) + return FALSE + if(!copy_from_prefs_vr()) + return FALSE + + return TRUE + +/mob/living/proc/copy_to_prefs_vr() + if(!client || !client.prefs_vr) + src << "You attempted to save your vore prefs but somehow you're in this character without a client.prefs_vr variable. Tell a dev." + return FALSE + + var/datum/vore_preferences/P = client.prefs_vr + + P.digestable = src.digestable + P.devourable = src.devourable + P.belly_prefs = src.vore_organs + + return TRUE + +// +// Proc for applying vore preferences, given bellies +// +/mob/living/proc/copy_from_prefs_vr() + if(!client || !client.prefs_vr) + src << "You attempted to apply your vore prefs but somehow you're in this character without a client.prefs_vr variable. Tell a dev." + return FALSE + + var/datum/vore_preferences/P = client.prefs_vr + + src.digestable = P.digestable + src.devourable = P.devourable + src.vore_organs = list() + + for(var/I in P.belly_prefs) + var/datum/belly/Bp = P.belly_prefs[I] + src.vore_organs[Bp.name] = Bp.copy(src) + + return TRUE \ No newline at end of file diff --git a/code/citadel/vore/eating/simple_animal_vr.dm b/code/modules/vore/eating/simple_animal_vr.dm similarity index 100% rename from code/citadel/vore/eating/simple_animal_vr.dm rename to code/modules/vore/eating/simple_animal_vr.dm diff --git a/code/citadel/vore/eating/vore_vr.dm b/code/modules/vore/eating/vore_vr.dm similarity index 53% rename from code/citadel/vore/eating/vore_vr.dm rename to code/modules/vore/eating/vore_vr.dm index 03941bfd15..e165cb132b 100644 --- a/code/citadel/vore/eating/vore_vr.dm +++ b/code/modules/vore/eating/vore_vr.dm @@ -19,11 +19,42 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE -Aro <3 */ -/datum/preferences +// +// Overrides/additions to stock defines go here, as well as hooks. Sort them by +// the object they are overriding. So all /mob/living together, etc. +// +// +// The datum type bolted onto normal preferences datums for storing Vore stuff +// +/client + var/datum/vore_preferences/prefs_vr + +/hook/client_new/proc/add_prefs_vr(client/C) + C.prefs_vr = new/datum/vore_preferences(C) + if(C.prefs_vr) + return 1 + + return 0 + +/datum/vore_preferences + //Actual preferences var/digestable = 1 - var/devourable = 1 + var/devourable = 0 var/list/belly_prefs = list() + //Mechanically required + var/path + var/slot + var/client/client + var/client_ckey + var/client/parent + +/datum/vore_preferences/New(client/C) + if(istype(C)) + client = C + client_ckey = C.ckey + load_vore(C) + // // Check if an object is capable of eating things, based on vore_organs // @@ -31,15 +62,14 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE if(istype(O,/mob/living)) if(O.vore_organs.len > 0) return 1 -// verbs -= /mob/living/proc/insidePanel -// verbs -= /mob/living/proc/escapeOOC + return 0 // // Belly searching for simplifying other procs // /proc/check_belly(atom/movable/A) - if(ismob(A.loc)) + if(istype(A.loc,/mob/living)) var/mob/living/M = A.loc for(var/I in M.vore_organs) var/datum/belly/B = M.vore_organs[I] @@ -49,26 +79,47 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE return 0 // -// Verb for saving vore preferences to save file +// Save/Load Vore Preferences // -/mob/living/proc/save_vore_prefs() - set name = "Save Vore Prefs" - set category = "Vore" +/datum/vore_preferences/proc/load_vore() + if(!client || !client_ckey) return 0 //No client, how can we save? - var/result = 0 + slot = client.prefs.default_slot - if(client.prefs) - result = client.prefs.save_vore_preferences() - else - src << "You attempted to save your vore prefs but somehow you're in this character without a client.prefs variable. Tell a dev." - log_admin("[src] tried to save vore prefs but lacks a client.prefs var.") + path = client.prefs.path - return result + if(!path) return 0 //Path couldn't be set? + if(!fexists(path)) //Never saved before + save_vore() //Make the file first + return 1 -// -// Proc for applying vore preferences, given bellies -// -/mob/living/proc/apply_vore_prefs(var/list/bellies) - if(!bellies || bellies.len == 0) - log_admin("Tried to apply bellies to [src] and failed.") + var/savefile/S = new /savefile(path) + if(!S) return 0 //Savefile object couldn't be created? + S.cd = "/character[slot]" + + S["digestable"] >> digestable + S["devourable"] >> devourable + S["belly_prefs"] >> belly_prefs + + if(isnull(digestable)) + digestable = 1 + if(isnull(devourable)) + devourable = 0 + if(isnull(belly_prefs)) + belly_prefs = list() + + return 1 + +/datum/vore_preferences/proc/save_vore() + if(!path) return 0 + if(!slot) return 0 + var/savefile/S = new /savefile(path) + if(!S) return 0 + S.cd = "/character[slot]" + + S["digestable"] << digestable + S["devourable"] << devourable + S["belly_prefs"] << belly_prefs + + return 1 \ No newline at end of file diff --git a/code/citadel/vore/eating/vorehooks_vr.dm b/code/modules/vore/eating/vorehooks_vr.dm similarity index 100% rename from code/citadel/vore/eating/vorehooks_vr.dm rename to code/modules/vore/eating/vorehooks_vr.dm diff --git a/code/citadel/vore/eating/vorepanel_vr.dm b/code/modules/vore/eating/vorepanel_vr.dm similarity index 98% rename from code/citadel/vore/eating/vorepanel_vr.dm rename to code/modules/vore/eating/vorepanel_vr.dm index e96a083866..e6d00991c8 100644 --- a/code/citadel/vore/eating/vorepanel_vr.dm +++ b/code/modules/vore/eating/vorepanel_vr.dm @@ -63,7 +63,6 @@ dat += "