mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-05-17 20:30:46 +01:00
de17517e42
* bunch of global vars * .
1841 lines
73 KiB
Plaintext
1841 lines
73 KiB
Plaintext
#define MAX_ENTRY_MESSAAGES 20
|
|
#define ENTRY_MESSAGE_INTERVAL 1 SECOND
|
|
|
|
//
|
|
// Belly system 2.0, now using objects instead of datums because EH at datums.
|
|
// How many times have I rewritten bellies and vore now? -Aro
|
|
//
|
|
|
|
// If you change what variables are on this, then you need to update the copy() proc.
|
|
|
|
//
|
|
// Parent type of all the various "belly" varieties.
|
|
//
|
|
|
|
/obj/belly
|
|
name = "belly" // Name of this location
|
|
desc = "It's a belly! You're in it!" // Flavor text description of inside sight/sound/smells/feels.
|
|
var/display_name = "" // Optional display name
|
|
var/message_mode = FALSE // If all options for messages are shown
|
|
var/vore_sound = "Gulp" // Sound when ingesting someone
|
|
var/vore_verb = "ingest" // Verb for eating with this in messages
|
|
var/release_verb = "expels" // Verb for releasing something from a stomach
|
|
var/human_prey_swallow_time = 100 // Time in deciseconds to swallow /mob/living/carbon/human
|
|
var/nonhuman_prey_swallow_time = 30 // Time in deciseconds to swallow anything else
|
|
var/nutrition_percent = 100 // Nutritional percentage per tick in digestion mode
|
|
var/digest_max = 36 // maximum total damage across all types
|
|
var/digest_brute = 0.5 // Brute damage per tick in digestion mode
|
|
var/digest_burn = 0.5 // Burn damage per tick in digestion mode
|
|
var/digest_oxy = 0 // Oxy damage per tick in digestion mode
|
|
var/digest_tox = 0 // Toxins damage per tick in digestion mode
|
|
var/digest_clone = 0 // Clone damage per tick in digestion mode
|
|
var/immutable = FALSE // Prevents this belly from being deleted
|
|
var/escapable = B_ESCAPABLE_NONE // Belly can be resisted out of at any time
|
|
var/escapetime = 10 SECONDS // Deciseconds, how long to escape this belly
|
|
var/selectchance = 0 // % Chance of stomach switching to selective mode if prey struggles
|
|
var/digestchance = 0 // % Chance of stomach beginning to digest if prey struggles
|
|
var/absorbchance = 0 // % Chance of stomach beginning to absorb if prey struggles
|
|
var/escapechance = 0 // % Chance of prey beginning to escape if prey struggles.
|
|
var/escapechance_absorbed = 0 // % Chance of absorbed prey finishing an escape. Requires a successful escape roll against the above as well.
|
|
var/escape_stun = 0 // AI controlled mobs with a number here will be weakened by the provided var when someone escapes, to prevent endless nom loops
|
|
var/transferchance = 0 // % Chance of prey being trasnsfered, goes from 0-100%
|
|
var/transferchance_secondary = 0 // % Chance of prey being transfered to transferchance_secondary, also goes 0-100%
|
|
var/save_digest_mode = TRUE // Whether this belly's digest mode persists across rounds
|
|
var/can_taste = FALSE // If this belly prints the flavor of prey when it eats someone.
|
|
var/bulge_size = 0.25 // The minimum size the prey has to be in order to show up on examine.
|
|
var/display_absorbed_examine = FALSE // Do we display absorption examine messages for this belly at all?
|
|
var/absorbed_desc // Desc shown to absorbed prey. Defaults to regular if left empty.
|
|
var/shrink_grow_size = 1 // This horribly named variable determines the minimum/maximum size it will shrink/grow prey to.
|
|
var/transferlocation // Location that the prey is released if they struggle and get dropped off.
|
|
var/transferlocation_secondary // Secondary location that prey is released to.
|
|
var/transferlocation_absorb // Location that prey is moved to if they get absorbed.
|
|
var/release_sound = "Splatter" // Sound for letting someone out. Replaced from True/false
|
|
var/mode_flags = 0 // Stripping, numbing, etc.
|
|
var/fancy_vore = FALSE // Using the new sounds?
|
|
var/is_wet = TRUE // Is this belly's insides made of slimy parts?
|
|
var/wet_loop = TRUE // Does the belly have a fleshy loop playing?
|
|
var/obj/item/storage/vore_egg/ownegg // Is this belly creating an egg?
|
|
var/egg_type = "Egg" // Default egg type and path.
|
|
var/egg_path = /obj/item/storage/vore_egg
|
|
var/egg_name = null // Custom egg name
|
|
var/egg_size = 0 // Custom egg size
|
|
var/list/list/emote_lists = list() // Idle emotes that happen on their own, depending on the bellymode. Contains lists of strings indexed by bellymode
|
|
var/emote_time = 60 // How long between stomach emotes at prey (in seconds)
|
|
var/emote_active = TRUE // Are we even giving emotes out at all or not?
|
|
var/next_emote = 0 // When we're supposed to print our next emote, as a world.time
|
|
var/selective_preference = DM_DIGEST // Which type of selective bellymode do we default to?
|
|
var/eating_privacy_local = "default" //Overrides eating_privacy_global if not "default". Determines if attempt/success messages are subtle/loud
|
|
var/is_feedable = TRUE // If this belly shows up in belly selections for others.
|
|
var/silicon_belly_overlay_preference = "Sleeper" //Selects between placing belly overlay in sleeper or normal vore mode. Exclusive
|
|
var/belly_mob_mult = 1 //Multiplier for how filling mob types are in borg bellies
|
|
var/belly_item_mult = 1 //Multiplier for how filling items are in borg borg bellies. Items are also weighted on item size
|
|
var/belly_overall_mult = 1 //Multiplier applied ontop of any other specific multipliers
|
|
var/private_struggle = FALSE // If struggles are made public or not
|
|
var/prevent_saving = FALSE // Can this belly be saved? For special bellies that mobs and adminbus might have.
|
|
var/absorbedrename_enabled = FALSE // If absorbed prey are renamed.
|
|
var/absorbedrename_name = "%pred's %belly" // What absorbed prey are renamed to.
|
|
|
|
|
|
var/vore_sprite_flags = DM_FLAG_VORESPRITE_BELLY
|
|
var/tmp/static/list/vore_sprite_flag_list= list(
|
|
"Normal Belly Sprite" = DM_FLAG_VORESPRITE_BELLY,
|
|
//"Tail adjustment" = DM_FLAG_VORESPRITE_TAIL,
|
|
//"Marking addition" = DM_FLAG_VORESPRITE_MARKING
|
|
"Undergarment addition" = DM_FLAG_VORESPRITE_ARTICLE,
|
|
)
|
|
var/affects_vore_sprites = FALSE
|
|
var/count_absorbed_prey_for_sprite = TRUE
|
|
var/absorbed_multiplier = 1
|
|
var/count_liquid_for_sprite = FALSE
|
|
var/liquid_multiplier = 1
|
|
var/count_items_for_sprite = FALSE
|
|
var/item_multiplier = 1
|
|
var/health_impacts_size = TRUE
|
|
var/resist_triggers_animation = TRUE
|
|
var/size_factor_for_sprite = 1
|
|
var/belly_sprite_to_affect = "stomach"
|
|
var/datum/sprite_accessory/tail/tail_to_change_to = FALSE
|
|
var/tail_colouration = FALSE
|
|
var/tail_extra_overlay = FALSE
|
|
var/tail_extra_overlay2 = FALSE
|
|
var/undergarment_chosen = "Underwear, bottom"
|
|
var/undergarment_if_none
|
|
var/undergarment_color = COLOR_GRAY
|
|
|
|
// Generally just used by AI
|
|
var/autotransferchance = 0 // % Chance of prey being autotransferred to transfer location
|
|
var/autotransferwait = 10 // Time between trying to transfer.
|
|
var/autotransferlocation // Place to send them
|
|
var/list/autotransferextralocation = list() // List of extra places this could go
|
|
var/autotransfer_whitelist = 0 // Flags for what can be transferred to the primary location
|
|
var/autotransfer_blacklist = 2 // Flags for what can not be transferred to the primary location, defaults to Absorbed
|
|
var/autotransfer_whitelist_items = 0 // Flags for what can be transferred to the primary location
|
|
var/autotransfer_blacklist_items = 0 // Flags for what can not be transferred to the primary location
|
|
var/autotransferchance_secondary = 0 // % Chance of prey being autotransferred to secondary transfer location
|
|
var/autotransferlocation_secondary // Second place to send them
|
|
var/list/autotransferextralocation_secondary = list() // List of extra places the secondary transfer could go
|
|
var/autotransfer_secondary_whitelist = 0// Flags for what can be transferred to the secondary location
|
|
var/autotransfer_secondary_blacklist = 2// Flags for what can not be transferred to the secondary location, defaults to Absorbed
|
|
var/autotransfer_secondary_whitelist_items = 0// Flags for what can be transferred to the secondary location
|
|
var/autotransfer_secondary_blacklist_items = 0// Flags for what can not be transferred to the secondary location
|
|
var/autotransfer_enabled = FALSE // Player toggle
|
|
var/autotransfer_min_amount = 0 // Minimum amount of things to pass at once.
|
|
var/autotransfer_max_amount = 0 // Maximum amount of things to pass at once.
|
|
var/tmp/list/autotransfer_queue = list()// Reserve for above things.
|
|
//Auto-transfer flags for whitelist
|
|
var/tmp/static/list/autotransfer_flags_list = list("Creatures" = AT_FLAG_CREATURES, "Absorbed" = AT_FLAG_ABSORBED, "Carbon" = AT_FLAG_CARBON, "Silicon" = AT_FLAG_SILICON, "Mobs" = AT_FLAG_MOBS, "Animals" = AT_FLAG_ANIMALS, "Mice" = AT_FLAG_MICE, "Dead" = AT_FLAG_DEAD, "Digestable Creatures" = AT_FLAG_CANDIGEST, "Absorbable Creatures" = AT_FLAG_CANABSORB, "Full Health" = AT_FLAG_HEALTHY)
|
|
var/tmp/static/list/autotransfer_flags_list_items = list("Items" = AT_FLAG_ITEMS, "Trash" = AT_FLAG_TRASH, "Eggs" = AT_FLAG_EGGS, "Remains" = AT_FLAG_REMAINS, "Indigestible Items" = AT_FLAG_INDIGESTIBLE, "Recyclable Items" = AT_FLAG_RECYCLABLE, "Ores" = AT_FLAG_ORES, "Clothes and Bags" = AT_FLAG_CLOTHES, "Food" = AT_FLAG_FOOD)
|
|
|
|
//I don't think we've ever altered these lists. making them static until someone actually overrides them somewhere.
|
|
//Actual full digest modes
|
|
var/tmp/static/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_ABSORB,DM_DRAIN,DM_SELECT,DM_UNABSORB,DM_HEAL,DM_SHRINK,DM_GROW,DM_SIZE_STEAL,DM_EGG)
|
|
//Digest mode addon flags
|
|
var/tmp/static/list/mode_flag_list = list("Numbing" = DM_FLAG_NUMBING, "Stripping" = DM_FLAG_STRIPPING, "Leave Remains" = DM_FLAG_LEAVEREMAINS, "Muffles" = DM_FLAG_THICKBELLY, "Affect Worn Items" = DM_FLAG_AFFECTWORN, "Jams Sensors" = DM_FLAG_JAMSENSORS, "Complete Absorb" = DM_FLAG_FORCEPSAY, "Spare Prosthetics" = DM_FLAG_SPARELIMB, "Slow Body Digestion" = DM_FLAG_SLOWBODY, "Muffle Items" = DM_FLAG_MUFFLEITEMS, "TURBO MODE" = DM_FLAG_TURBOMODE, "Absorbed Prey Can Devour" = DM_FLAG_ABSORBEDVORE, "Makes Prey Wet" = DM_FLAG_WETTENS)
|
|
//Item related modes
|
|
var/tmp/static/list/item_digest_modes = list(IM_HOLD,IM_DIGEST_FOOD,IM_DIGEST,IM_DIGEST_PARALLEL)
|
|
//drain modes
|
|
var/tmp/static/list/drainmodes = list(DR_NORMAL,DR_SLEEP,DR_FAKE,DR_WEIGHT)
|
|
|
|
//List of slots that stripping handles strips
|
|
var/tmp/static/list/slots = list(slot_back,slot_handcuffed,slot_l_store,slot_r_store,slot_wear_mask,slot_l_hand,slot_r_hand,slot_wear_id,slot_glasses,slot_gloves,slot_head,slot_shoes,slot_belt,slot_wear_suit,slot_w_uniform,slot_s_store,slot_l_ear,slot_r_ear)
|
|
|
|
var/tmp/mob/living/owner // The mob whose belly this is.
|
|
var/tmp/digest_mode = DM_HOLD // Current mode the belly is set to from digest_modes (+transform_modes if human)
|
|
var/tmp/list/items_preserved = list() // Stuff that wont digest so we shouldn't process it again.
|
|
var/tmp/recent_sound = FALSE // Prevent audio spam
|
|
var/tmp/drainmode = DR_NORMAL // Simply drains the prey then does nothing.
|
|
var/tmp/digested_prey_count = 0 // Amount of prey that have been digested
|
|
|
|
var/item_digest_mode = IM_DIGEST_FOOD // Current item-related mode from item_digest_modes
|
|
var/contaminates = FALSE // Whether the belly will contaminate stuff
|
|
var/contamination_flavor = "Generic" // Determines descriptions of contaminated items
|
|
var/contamination_color = "green" // Color of contamination overlay
|
|
|
|
// Lets you do a fullscreen overlay. Set to an icon_state string.
|
|
var/belly_fullscreen = ""
|
|
var/disable_hud = FALSE
|
|
var/colorization_enabled = TRUE
|
|
var/belly_fullscreen_color = "#823232"
|
|
var/belly_fullscreen_color2 = "#FFFFFF"
|
|
var/belly_fullscreen_color3 = "#823232"
|
|
var/belly_fullscreen_color4 = "#FFFFFF"
|
|
var/belly_fullscreen_alpha = 255
|
|
|
|
// Liquid belly vars
|
|
var/reagent_gen_cost_limit = 10 //Our lower percentage limit of nutrition / charge until which we produce liquids
|
|
var/reagentbellymode = FALSE // Belly has abilities to make liquids from digested/absorbed/drained prey and/or nutrition
|
|
var/reagent_mode_flags = 0
|
|
|
|
var/tmp/static/list/reagent_mode_flag_list= list(
|
|
"Produce Liquids" = DM_FLAG_REAGENTSNUTRI,
|
|
"Digestion Liquids" = DM_FLAG_REAGENTSDIGEST,
|
|
"Absorption Liquids" = DM_FLAG_REAGENTSABSORB,
|
|
"Draining Liquids" = DM_FLAG_REAGENTSDRAIN
|
|
)
|
|
|
|
var/show_liquids = FALSE //Moved from vorepanel_ch to be a belly var
|
|
var/show_fullness_messages = FALSE //Moved from vorepanel_ch to be a belly var
|
|
var/liquid_overlay = TRUE //Belly-specific liquid overlay toggle
|
|
var/max_liquid_level = 100 //Custom max level for liquid overlay
|
|
var/mush_overlay = FALSE //Toggle for nutrition mush overlay
|
|
var/reagent_touches = TRUE //If reagents touch and interact with things in belly
|
|
var/mush_color = "#664330" //Nutrition mush overlay color
|
|
var/mush_alpha = 255 //Mush overlay transparency.
|
|
var/max_mush = 500 //How much nutrition for full mush overlay
|
|
var/min_mush = 0 //Manual setting for lowest mush level
|
|
var/item_mush_val = 0 //How much solid belly contents raise mush level per item
|
|
var/metabolism_overlay = FALSE //Extra mush layer for ingested reagents currently in metabolism.
|
|
var/metabolism_mush_ratio = 15 //Metabolism reagent volume per unit compared to nutrition units.
|
|
var/max_ingested = 500 //How much metabolism content for full overlay.
|
|
var/ingested_color = "#664330" //Normal color holder for ingested layer. Blended from existing reagent colors.
|
|
var/custom_ingested_color = null //Custom color for ingested reagent layer.
|
|
var/custom_ingested_alpha = 255 //Custom alpha for ingested reagent layer if not using normal mush layer.
|
|
|
|
var/nutri_reagent_gen = FALSE //if belly produces reagent over time using nutrition, needs to be optimized to use subsystem - Jack
|
|
var/is_beneficial = FALSE //Sets a reagent as a beneficial one / healing reagents
|
|
var/list/generated_reagents = list(REAGENT_ID_WATER = 1) //Any number of reagents, the associated value is how many units are generated per process()
|
|
var/reagent_name = REAGENT_ID_WATER //What is shown when reagents are removed, doesn't need to be an actual reagent
|
|
var/reagentid = REAGENT_ID_WATER //Selected reagent's id, for use in puddle system currently
|
|
var/reagentcolor = "#0064C877" //Selected reagent's color, for use in puddle system currently
|
|
var/custom_reagentcolor //Custom reagent color. Blank for normal reagent color
|
|
var/custom_reagentalpha //Custom reagent alpha. Blank for capacity based alpha
|
|
var/gen_cost = 1 //amount of nutrient taken from the host everytime nutrition is used to make reagents
|
|
var/gen_amount = 1 //Does not actually influence amount produced, but is used as a way to tell the system how much total reagent it has to take into account when filling a belly
|
|
|
|
var/gen_interval = 0 //Interval in seconds for generating fluids, once it reaches the value of gen_time one cycle of reagents generation will occur
|
|
var/gen_time = 5 //Time it takes in seconds to produce one cycle of reagents, technically add 1 second to it for the tick where the fluid is produced
|
|
var/gen_time_display = "1 hour" //The displayed time it takes from a belly to go from 0 to 100
|
|
var/custom_max_volume = 100 //Variable for people to limit amount of liquid they can receive/produce in a belly
|
|
var/digest_nutri_gain = 0 //variable to store temporary nutrition gain from digestion and allow a seperate proc to ease up on the wall of code
|
|
var/reagent_transfer_verb = "injects" //verb for transfer of reagent from a vore belly
|
|
|
|
var/vorefootsteps_sounds = FALSE //If this belly can make sounds when someone walks around
|
|
var/liquid_fullness1_messages = FALSE
|
|
var/liquid_fullness2_messages = FALSE
|
|
var/liquid_fullness3_messages = FALSE
|
|
var/liquid_fullness4_messages = FALSE
|
|
var/liquid_fullness5_messages = FALSE
|
|
var/displayed_message_flags = ALL
|
|
var/vorespawn_blacklist = FALSE
|
|
var/vorespawn_whitelist = list()
|
|
var/vorespawn_absorbed = 0
|
|
|
|
var/list/fullness1_messages = list(
|
|
"%pred's %belly looks empty"
|
|
)
|
|
var/list/fullness2_messages = list(
|
|
"%pred's %belly looks filled"
|
|
)
|
|
var/list/fullness3_messages = list(
|
|
"%pred's %belly looks like it's full of liquid"
|
|
)
|
|
var/list/fullness4_messages = list(
|
|
"%pred's %belly is quite full!"
|
|
)
|
|
var/list/fullness5_messages = list(
|
|
"%pred's %belly is completely filled to it's limit!"
|
|
)
|
|
|
|
var/tmp/reagent_chosen = REAGENT_WATER // variable for switch to figure out what to set variables when a certain reagent is selected
|
|
var/tmp/static/list/reagent_choices = list( // List of reagents people can chose, maybe one day expand so it covers criterias like dogborgs who can make meds, booze, etc - Jack
|
|
REAGENT_WATER,
|
|
REAGENT_MILK,
|
|
REAGENT_CREAM,
|
|
REAGENT_HONEY,
|
|
REAGENT_CHERRYJELLY,
|
|
REAGENT_STOMACID,
|
|
REAGENT_DIETSTOMACID,
|
|
REAGENT_CLEANER,
|
|
REAGENT_LUBE,
|
|
REAGENT_BIOMASS,
|
|
REAGENT_CONCENTRATEDRADIUM,
|
|
REAGENT_TRICORDRAZINE,
|
|
REAGENT_ETHANOL
|
|
)
|
|
|
|
// Special var section
|
|
var/special_entrance_sound // Mob specific custom entry sound set by mob's init_vore when applicable
|
|
var/slow_digestion = FALSE // Gradual corpse digestion
|
|
var/slow_brutal = FALSE // Gradual corpse digestion: Stumpy's Special
|
|
var/sound_volume = 100 // Volume knob.
|
|
var/speedy_mob_processing = FALSE // Independent belly processing to utilize SSobj instead of SSbellies 3x speed.
|
|
var/cycle_sloshed = FALSE // Has vorgan entrance made a wet slosh this cycle? Soundspam prevention for multiple items entered.
|
|
var/egg_cycles = 0 // Process egg mode after 10 cycles.
|
|
var/recycling = FALSE // Recycling mode.
|
|
var/entrance_logs = TRUE // Belly-specific entry message toggle.
|
|
var/noise_freq = 42500 // Tasty sound prefs.
|
|
var/item_digest_logs = FALSE // Chat messages for digested items.
|
|
var/storing_nutrition = FALSE // Storing gained nutrition as paste instead of absorbing it.
|
|
var/belchchance = 0 // % Chance of pred belching on prey struggle
|
|
|
|
var/list/belly_surrounding = list() // A list of living mobs surrounded by this belly, including inside containers, food, on mobs, etc. Exclusing inside other bellies.
|
|
var/bellytemperature = T20C // Temperature applied to humans in the belly.
|
|
var/temperature_damage = FALSE // Does temperature damage prey?
|
|
var/last_transfer_log = 0 // Prevent server message spam!
|
|
var/next_transfer_log = 0 // Prevent server message spam!
|
|
var/entrance_log_count = 0 // Entrance count before spawm
|
|
flags = NOREACT // We dont want bellies to start bubling nonstop due to people mixing when transfering and making different reagents
|
|
|
|
//For serialization, keep this updated, required for bellies to save correctly.
|
|
/obj/belly/vars_to_save()
|
|
var/list/saving = list(
|
|
"name",
|
|
"desc",
|
|
"display_name",
|
|
"absorbed_desc",
|
|
"message_mode",
|
|
"vore_sound",
|
|
"vore_verb",
|
|
"release_verb",
|
|
"human_prey_swallow_time",
|
|
"nonhuman_prey_swallow_time",
|
|
"emote_time",
|
|
"nutrition_percent",
|
|
"digest_brute",
|
|
"digest_burn",
|
|
"digest_oxy",
|
|
"digest_tox",
|
|
"digest_clone",
|
|
"bellytemperature",
|
|
"temperature_damage",
|
|
"immutable",
|
|
"can_taste",
|
|
"escapable",
|
|
"escapetime",
|
|
"digestchance",
|
|
"absorbchance",
|
|
"escapechance",
|
|
"escapechance_absorbed",
|
|
"transferchance",
|
|
"transferchance_secondary",
|
|
"transferlocation",
|
|
"transferlocation_secondary",
|
|
"belchchance",
|
|
"bulge_size",
|
|
"display_absorbed_examine",
|
|
"shrink_grow_size",
|
|
"struggle_messages_outside",
|
|
"struggle_messages_inside",
|
|
"absorbed_struggle_messages_outside",
|
|
"absorbed_struggle_messages_inside",
|
|
"escape_attempt_messages_owner",
|
|
"escape_attempt_messages_prey",
|
|
"escape_messages_owner",
|
|
"escape_messages_prey",
|
|
"escape_messages_outside",
|
|
"escape_item_messages_owner",
|
|
"escape_item_messages_prey",
|
|
"escape_item_messages_outside",
|
|
"escape_fail_messages_owner",
|
|
"escape_fail_messages_prey",
|
|
"escape_attempt_absorbed_messages_owner",
|
|
"escape_attempt_absorbed_messages_prey",
|
|
"escape_absorbed_messages_owner",
|
|
"escape_absorbed_messages_prey",
|
|
"escape_absorbed_messages_outside",
|
|
"escape_fail_absorbed_messages_owner",
|
|
"escape_fail_absorbed_messages_prey",
|
|
"primary_transfer_messages_owner",
|
|
"primary_transfer_messages_prey",
|
|
"secondary_transfer_messages_owner",
|
|
"secondary_transfer_messages_prey",
|
|
"primary_autotransfer_messages_owner",
|
|
"primary_autotransfer_messages_prey",
|
|
"secondary_autotransfer_messages_owner",
|
|
"secondary_autotransfer_messages_prey",
|
|
"digest_chance_messages_owner",
|
|
"digest_chance_messages_prey",
|
|
"absorb_chance_messages_owner",
|
|
"absorb_chance_messages_prey",
|
|
"digest_messages_owner",
|
|
"digest_messages_prey",
|
|
"absorb_messages_owner",
|
|
"absorb_messages_prey",
|
|
"unabsorb_messages_owner",
|
|
"unabsorb_messages_prey",
|
|
"examine_messages",
|
|
"examine_messages_absorbed",
|
|
"emote_lists",
|
|
"emote_time",
|
|
"emote_active",
|
|
"selective_preference",
|
|
"mode_flags",
|
|
"item_digest_mode",
|
|
"contaminates",
|
|
"contamination_flavor",
|
|
"contamination_color",
|
|
"release_sound",
|
|
"fancy_vore",
|
|
"is_wet",
|
|
"wet_loop",
|
|
"belly_fullscreen",
|
|
"disable_hud",
|
|
"reagent_mode_flags",
|
|
"belly_fullscreen_color",
|
|
"belly_fullscreen_color2",
|
|
"belly_fullscreen_color3",
|
|
"belly_fullscreen_color4",
|
|
"belly_fullscreen_alpha",
|
|
"colorization_enabled",
|
|
"show_liquids",
|
|
"reagentbellymode",
|
|
"reagent_gen_cost_limit",
|
|
"liquid_fullness1_messages",
|
|
"liquid_fullness2_messages",
|
|
"liquid_fullness3_messages",
|
|
"liquid_fullness4_messages",
|
|
"liquid_fullness5_messages",
|
|
"reagent_name",
|
|
"reagent_chosen",
|
|
"reagentid",
|
|
"reagentcolor",
|
|
"liquid_overlay",
|
|
"max_liquid_level",
|
|
"reagent_touches",
|
|
"mush_overlay",
|
|
"mush_color",
|
|
"mush_alpha",
|
|
"max_mush",
|
|
"min_mush",
|
|
"item_mush_val",
|
|
"custom_reagentcolor",
|
|
"custom_reagentalpha",
|
|
"metabolism_overlay",
|
|
"metabolism_mush_ratio",
|
|
"max_ingested",
|
|
"custom_ingested_color",
|
|
"custom_ingested_alpha",
|
|
"gen_cost",
|
|
"gen_amount",
|
|
"gen_time",
|
|
"gen_time_display",
|
|
"reagent_transfer_verb",
|
|
"custom_max_volume",
|
|
"generated_reagents",
|
|
"vorefootsteps_sounds",
|
|
"fullness1_messages",
|
|
"fullness2_messages",
|
|
"fullness3_messages",
|
|
"fullness4_messages",
|
|
"fullness5_messages",
|
|
"displayed_message_flags",
|
|
"vorespawn_blacklist",
|
|
"vorespawn_whitelist",
|
|
"vorespawn_absorbed",
|
|
"absorbed_multiplier",
|
|
"count_liquid_for_sprite",
|
|
"liquid_multiplier",
|
|
"undergarment_chosen",
|
|
"undergarment_if_none",
|
|
"undergarment_color",
|
|
"autotransferchance",
|
|
"autotransferwait",
|
|
"autotransferlocation",
|
|
"autotransferextralocation",
|
|
"autotransfer_enabled",
|
|
"autotransferchance_secondary",
|
|
"autotransferextralocation_secondary",
|
|
"autotransferlocation_secondary",
|
|
"autotransfer_secondary_whitelist",
|
|
"autotransfer_secondary_blacklist",
|
|
"autotransfer_whitelist",
|
|
"autotransfer_blacklist",
|
|
"autotransfer_secondary_whitelist_items",
|
|
"autotransfer_secondary_blacklist_items",
|
|
"autotransfer_whitelist_items",
|
|
"autotransfer_blacklist_items",
|
|
"autotransfer_min_amount",
|
|
"autotransfer_max_amount",
|
|
"slow_digestion",
|
|
"slow_brutal",
|
|
"sound_volume",
|
|
"speedy_mob_processing",
|
|
"egg_name",
|
|
"egg_size",
|
|
"recycling",
|
|
"storing_nutrition",
|
|
"is_feedable",
|
|
"entrance_logs",
|
|
"noise_freq",
|
|
"private_struggle",
|
|
"absorbedrename_enabled",
|
|
"absorbedrename_name",
|
|
"item_digest_logs",
|
|
"show_fullness_messages",
|
|
"digest_max",
|
|
"egg_type",
|
|
"save_digest_mode",
|
|
"eating_privacy_local",
|
|
"silicon_belly_overlay_preference",
|
|
"belly_mob_mult",
|
|
"belly_item_mult",
|
|
"belly_overall_mult",
|
|
"drainmode",
|
|
"vore_sprite_flags",
|
|
"affects_vore_sprites",
|
|
"count_absorbed_prey_for_sprite",
|
|
"resist_triggers_animation",
|
|
"size_factor_for_sprite",
|
|
"belly_sprite_to_affect",
|
|
"health_impacts_size",
|
|
"count_items_for_sprite",
|
|
"item_multiplier",
|
|
"undergarment_chosen",
|
|
"undergarment_if_none",
|
|
"undergarment_color",
|
|
"trash_eater_in",
|
|
"trash_eater_out"
|
|
)
|
|
|
|
if (save_digest_mode == 1)
|
|
return ..() + saving + list("digest_mode")
|
|
|
|
return ..() + saving
|
|
|
|
/obj/belly/Initialize(mapload)
|
|
. = ..()
|
|
//If not, we're probably just in a prefs list or something.
|
|
if(ismob(loc))
|
|
owner = loc
|
|
owner.vore_organs += src
|
|
if(isliving(loc))
|
|
if(mode_flags & DM_FLAG_TURBOMODE)
|
|
START_PROCESSING(SSobj, src)
|
|
else
|
|
START_PROCESSING(SSbellies, src)
|
|
|
|
create_reagents(300) // So we can have some liquids in bellies
|
|
|
|
/obj/belly/Destroy()
|
|
if(mode_flags & DM_FLAG_TURBOMODE)
|
|
STOP_PROCESSING(SSobj, src)
|
|
else
|
|
STOP_PROCESSING(SSbellies, src)
|
|
owner?.vore_organs?.Remove(src)
|
|
owner = null
|
|
for(var/mob/observer/G in src)
|
|
G.forceMove(get_turf(src)) //ported from CHOMPStation PR#7132
|
|
return ..()
|
|
|
|
/obj/belly/Moved(atom/old_loc)
|
|
. = ..()
|
|
|
|
for(var/mob/living/L in src)
|
|
if(L.ckey)
|
|
log_admin("[key_name(owner)]'s belly `[src]` moved from [old_loc] ([old_loc?.x],[old_loc?.y],[old_loc?.z]) to [loc] ([loc?.x],[loc?.y],[loc?.z]) while containing [key_name(L)].")
|
|
break
|
|
|
|
// Called whenever an atom enters this belly
|
|
/obj/belly/Entered(atom/movable/thing, atom/OldLoc)
|
|
. = ..()
|
|
if(!owner)
|
|
thing.forceMove(get_turf(src))
|
|
return
|
|
thing.enter_belly(src) // Atom movable proc, does nothing by default. Overridden in children for special behavior.
|
|
if(owner && istype(owner.loc,/turf/simulated) && !cycle_sloshed && reagents.total_volume > 0)
|
|
var/S = pick(GLOB.slosh)
|
|
if(S)
|
|
playsound(owner.loc, S, sound_volume * (reagents.total_volume / 100), FALSE, frequency = noise_freq, preference = /datum/preference/toggle/digestion_noises)
|
|
cycle_sloshed = TRUE
|
|
thing.belly_cycles = 0 //reset cycle count
|
|
if(istype(thing, /mob/observer)) //Ports CHOMPStation PR#3072
|
|
if(desc) //Ports CHOMPStation PR#4772
|
|
//Allow ghosts see where they are if they're still getting squished along inside.
|
|
to_chat(thing, span_vnotice(span_bold("[belly_format_string(desc, thing)]")))
|
|
|
|
if(OldLoc in contents)
|
|
return //Someone dropping something (or being stripdigested)
|
|
if(istype(OldLoc, /mob/observer) || istype(OldLoc, /obj/item/mmi)) // Prevent reforming causing a lot of log spam/sounds
|
|
return //Someone getting reformed most likely (And if not, uh... shouldn't happen anyways?)
|
|
|
|
//Generic entered message
|
|
if(!owner.mute_entry && entrance_logs)
|
|
if(!istype(thing, /mob/observer)) //Don't have ghosts announce they're reentering the belly on death
|
|
if(world.time - last_transfer_log > ENTRY_MESSAGE_INTERVAL)
|
|
last_transfer_log = world.time
|
|
entrance_log_count = 0
|
|
if(world.time >= next_transfer_log)
|
|
to_chat(owner,span_vnotice("[thing] slides into your [lowertext(name)]."))
|
|
entrance_log_count++
|
|
if(entrance_log_count >= MAX_ENTRY_MESSAAGES)
|
|
next_transfer_log = world.time + ENTRY_MESSAGE_INTERVAL
|
|
last_transfer_log = world.time
|
|
|
|
//Sound w/ antispam flag setting
|
|
if(vore_sound && !recent_sound && !istype(thing, /mob/observer))
|
|
var/soundfile
|
|
if(!fancy_vore)
|
|
soundfile = GLOB.classic_vore_sounds[vore_sound]
|
|
else
|
|
soundfile = GLOB.fancy_vore_sounds[vore_sound]
|
|
if(special_entrance_sound) // Custom sound set by mob's init_vore or ingame varedits.
|
|
soundfile = special_entrance_sound
|
|
if(soundfile)
|
|
playsound(src, soundfile, vol = sound_volume, vary = 1, falloff = VORE_SOUND_FALLOFF, frequency = noise_freq, preference = /datum/preference/toggle/eating_noises, volume_channel = VOLUME_CHANNEL_VORE)
|
|
recent_sound = TRUE
|
|
|
|
if(reagents.total_volume >= 5 && !isliving(thing) && (item_digest_mode == IM_DIGEST || item_digest_mode == IM_DIGEST_PARALLEL))
|
|
reagents.trans_to(thing, reagents.total_volume * 0.1, 1 / max(LAZYLEN(contents), 1), FALSE)
|
|
//Messages if it's a mob
|
|
// Include indirect viewers in seeing vorefx
|
|
var/list/startfx = list()
|
|
if(isliving(thing))
|
|
var/mob/living/L = thing
|
|
startfx.Add(L)
|
|
startfx.Add(get_belly_surrounding(L.contents))
|
|
owner.handle_belly_update() // This is run whenever a belly's contents are changed.
|
|
if(istype(thing,/obj/item))
|
|
var/obj/item/I = thing
|
|
startfx.Add(get_belly_surrounding(I.contents))
|
|
|
|
for(var/mob/living/living_mob in startfx) // End of indirect vorefx changes
|
|
living_mob.updateVRPanel()
|
|
var/raw_desc //Let's use this to avoid needing to write the reformat code twice
|
|
if(absorbed_desc && living_mob.absorbed)
|
|
raw_desc = absorbed_desc
|
|
else if(desc)
|
|
raw_desc = desc
|
|
|
|
//Was there a description text? If so, it's time to format it!
|
|
if(raw_desc)
|
|
//Replace placeholder vars
|
|
to_chat(living_mob, span_vnotice(span_bold("[belly_format_string(raw_desc, living_mob)]")))
|
|
|
|
var/taste
|
|
if(can_taste && living_mob.loc == src && (taste = living_mob.get_taste_message(FALSE))) // Prevent indirect tasting
|
|
to_chat(owner, span_vnotice("[living_mob] tastes of [taste]."))
|
|
vore_fx(living_mob)
|
|
if(owner.previewing_belly == src)
|
|
vore_fx(owner)
|
|
//Stop AI processing in bellies
|
|
if(living_mob.ai_holder)
|
|
living_mob.ai_holder.go_sleep()
|
|
if(reagents.total_volume >= 5)
|
|
if(digest_mode == DM_DIGEST && living_mob.digestable)
|
|
reagents.splash_mob(living_mob, reagents.total_volume * 0.1, FALSE)
|
|
to_chat(living_mob, span_vwarning(span_bold("You splash into a pool of [reagent_name]!")))
|
|
if(!isliving(thing) && count_items_for_sprite) // If this is enabled also update fullness for non-living things
|
|
owner.handle_belly_update() // This is run whenever a belly's contents are changed.
|
|
|
|
// Called whenever an atom leaves this belly
|
|
/obj/belly/Exited(atom/movable/thing, atom/OldLoc)
|
|
. = ..()
|
|
if(QDELETED(owner))
|
|
return
|
|
thing.exit_belly(src) // atom movable proc, does nothing by default. Overridden in children for special behavior.
|
|
if(isbelly(thing.loc))
|
|
var/obj/belly/NB = thing.loc
|
|
if(count_items_for_sprite && !NB.count_items_for_sprite)
|
|
owner.handle_belly_update()
|
|
return
|
|
|
|
// Remove vorefx from all those indirectly viewing as well
|
|
var/list/endfx = list()
|
|
if(isliving(thing))
|
|
var/mob/living/L = thing
|
|
endfx.Add(L)
|
|
endfx.Add(get_belly_surrounding(L.contents))
|
|
owner.handle_belly_update() // This is run whenever a belly's contents are changed.
|
|
if(istype(thing,/obj/item))
|
|
var/obj/item/I = thing
|
|
endfx.Add(get_belly_surrounding(I.contents))
|
|
if(!isbelly(thing.loc))
|
|
for(var/mob/living/L in endfx)
|
|
if(L.surrounding_belly()) continue
|
|
L.clear_fullscreen("belly")
|
|
if(L.hud_used)
|
|
if(!L.hud_used.hud_shown)
|
|
L.toggle_hud_vis()
|
|
if((L.stat != DEAD) && L.ai_holder)
|
|
L.ai_holder.go_wake()
|
|
L.stop_sound_channel(CHANNEL_PREYLOOP) // This was on release_specific_contents proc, why is it not here on belly exit?
|
|
// End of indirect vorefx changes
|
|
if(isitem(thing) && !isbelly(thing.loc)) // Digest stage effects. Don't bother adding overlays to stuff that won't make it back out.
|
|
if(count_items_for_sprite) // If this is enabled also update fullness for non-living things
|
|
owner.handle_belly_update() // This is run whenever a belly's contents are changed.
|
|
var/obj/item/I = thing
|
|
if(I.gurgled)
|
|
I.cut_overlay(GLOB.gurgled_overlays[I.gurgled_color]) //No double-overlay for worn items.
|
|
I.add_overlay(GLOB.gurgled_overlays[I.gurgled_color])
|
|
if(I.d_mult < 1)
|
|
if(I.d_stage_overlay)
|
|
I.cut_overlay(I.d_stage_overlay)
|
|
var/image/temp = new /image(GLOB.gurgled_overlays[I.gurgled_color ? I.gurgled_color : "green"])
|
|
temp.filters += filter(type = "alpha", icon = icon(I.icon, I.icon_state))
|
|
I.d_stage_overlay = temp
|
|
for(var/count in I.d_mult to 1 step 0.25)
|
|
// Note, this should be refactored to drop priority overlays
|
|
I.add_overlay(I.d_stage_overlay, TRUE)
|
|
|
|
// 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(include_absorbed = FALSE, silent = FALSE)
|
|
//Don't bother if we don't have contents
|
|
if(!contents.len)
|
|
return FALSE
|
|
|
|
//Find where we should drop things into (certainly not the owner)
|
|
var/count = 0
|
|
|
|
//Iterate over contents and move them all
|
|
for(var/atom/movable/AM as anything in contents)
|
|
if(isliving(AM))
|
|
var/mob/living/L = AM
|
|
if(L.stat)
|
|
L.SetSleeping(min(L.sleeping,20))
|
|
if(L.absorbed && !include_absorbed)
|
|
continue
|
|
count += release_specific_contents(AM, silent = TRUE)
|
|
|
|
//Clean up our own business
|
|
items_preserved.Cut()
|
|
|
|
//Determines privacy
|
|
var/privacy_range = world.view
|
|
//var/privacy_volume = 100
|
|
switch(eating_privacy_local) //Third case of if("loud") not defined, as it'd just leave privacy_range and volume untouched
|
|
if("default")
|
|
if(owner.eating_privacy_global)
|
|
privacy_range = 1
|
|
//privacy_volume = 25
|
|
if("subtle")
|
|
privacy_range = 1
|
|
//privacy_volume = 25
|
|
|
|
//Print notifications/sound if necessary
|
|
if(!silent && count)
|
|
owner.visible_message(span_vnotice(span_green(span_bold("[owner] [release_verb] everything from their [lowertext(name)]!"))), range = privacy_range)
|
|
var/soundfile
|
|
if(!fancy_vore)
|
|
soundfile = GLOB.classic_release_sounds[release_sound]
|
|
else
|
|
soundfile = GLOB.fancy_release_sounds[release_sound]
|
|
if(soundfile)
|
|
playsound(src, soundfile, vol = sound_volume, vary = 1, falloff = VORE_SOUND_FALLOFF, frequency = noise_freq, preference = /datum/preference/toggle/eating_noises, volume_channel = VOLUME_CHANNEL_VORE)
|
|
|
|
return count
|
|
|
|
// 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(atom/movable/M, silent = FALSE)
|
|
if (!(M in contents))
|
|
return 0 // They weren't in this belly anyway
|
|
|
|
// Ventcrawlings will explode their vent to avoid exploits
|
|
if(istype(owner.loc,/obj/machinery/atmospherics))
|
|
var/obj/machinery/atmospherics/our_pipe = owner.loc
|
|
our_pipe.blowout(owner)
|
|
|
|
if(istype(M, /mob/living/simple_mob/vore/morph/dominated_prey))
|
|
var/mob/living/simple_mob/vore/morph/dominated_prey/p = M
|
|
p.undo_prey_takeover(FALSE)
|
|
return 0
|
|
for(var/mob/living/L in M.contents)
|
|
L.muffled = FALSE
|
|
L.forced_psay = FALSE
|
|
|
|
for(var/obj/item/holder/H in M.contents)
|
|
H.held_mob.muffled = FALSE
|
|
H.held_mob.forced_psay = FALSE
|
|
|
|
if(isliving(M))
|
|
var/mob/living/slip = M
|
|
slip.slip_protect = world.time + 25 // This is to prevent slipping back into your pred if they stand on soap or something.
|
|
//Place them into our drop_location
|
|
M.forceMove(drop_location())
|
|
items_preserved -= M
|
|
|
|
//Special treatment for absorbed prey
|
|
if(isliving(M))
|
|
var/mob/living/ML = M
|
|
var/mob/living/OW = owner
|
|
if(ML.client)
|
|
ML.stop_sound_channel(CHANNEL_PREYLOOP) //Stop the internal loop, it'll restart if the isbelly check on next tick anyway
|
|
if(ML.muffled)
|
|
ML.muffled = FALSE
|
|
if(ML.forced_psay)
|
|
ML.forced_psay = FALSE
|
|
if(ML.absorbed)
|
|
ML.absorbed = FALSE
|
|
handle_absorb_langs(ML, owner)
|
|
if(ishuman(M) && ishuman(OW))
|
|
var/mob/living/carbon/human/Prey = M
|
|
var/mob/living/carbon/human/Pred = OW
|
|
var/absorbed_count = 2 //Prey that we were, plus the pred gets a portion
|
|
for(var/mob/living/P in contents)
|
|
if(P.absorbed)
|
|
absorbed_count++
|
|
Pred.bloodstr.trans_to(Prey, Pred.reagents.total_volume / absorbed_count)
|
|
|
|
//Makes it so that if prey are heavily asleep, they will wake up shortly after release
|
|
if(isliving(M))
|
|
var/mob/living/ML = M
|
|
if(ML.stat)
|
|
ML.SetSleeping(min(ML.sleeping,20))
|
|
|
|
|
|
//Determines privacy
|
|
var/privacy_range = world.view
|
|
//var/privacy_volume = 100
|
|
switch(eating_privacy_local) //Third case of if("loud") not defined, as it'd just leave privacy_range and volume untouched
|
|
if("default")
|
|
if(owner.eating_privacy_global)
|
|
privacy_range = 1
|
|
//privacy_volume = 25
|
|
if("subtle")
|
|
privacy_range = 1
|
|
//privacy_volume = 25
|
|
|
|
//Print notifications/sound if necessary
|
|
if(isobserver(M))
|
|
silent = TRUE
|
|
if(!silent)
|
|
if(isitem(M))
|
|
owner.visible_message(span_vnotice(span_green(span_bold(belly_format_string(trash_eater_out, M, item=M)))),range = privacy_range) //double dip. prey = item, item = prey. sanity check in case they use %prey in the message.
|
|
else
|
|
owner.visible_message(span_vnotice(span_green(span_bold("[owner] [release_verb] [M] from their [lowertext(name)]!"))),range = privacy_range)
|
|
var/soundfile
|
|
if(!fancy_vore)
|
|
soundfile = GLOB.classic_release_sounds[release_sound]
|
|
else
|
|
soundfile = GLOB.fancy_release_sounds[release_sound]
|
|
if(soundfile)
|
|
playsound(src, soundfile, vol = sound_volume, vary = 1, falloff = VORE_SOUND_FALLOFF, frequency = noise_freq, preference = /datum/preference/toggle/eating_noises, volume_channel = VOLUME_CHANNEL_VORE)
|
|
|
|
if(!owner.ckey && escape_stun)
|
|
owner.Weaken(escape_stun)
|
|
|
|
return 1
|
|
|
|
// 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_atom(atom/movable/prey, mob/user)
|
|
if(ismob(prey))
|
|
var/mob/mob_prey = prey
|
|
if(owner.stat == DEAD)
|
|
return
|
|
if(mob_prey.buckled)
|
|
mob_prey.buckled.unbuckle_mob()
|
|
if(mob_prey.ckey)
|
|
GLOB.prey_eaten_roundstat++
|
|
if(owner.mind)
|
|
owner.mind.vore_prey_eaten++
|
|
|
|
prey.forceMove(src)
|
|
owner.updateVRPanel()
|
|
|
|
for(var/mob/living/M in contents)
|
|
M.updateVRPanel()
|
|
|
|
// new procs for handling digestion damage as a total rather than per-type
|
|
// Returns the current total digestion damage per tick of a belly.
|
|
/obj/belly/proc/get_total_digestion_damage()
|
|
return (digest_brute + digest_burn + digest_oxy + digest_tox + digest_clone)
|
|
|
|
// Returns the remaining 'budget' of digestion damage between the current and the maximum.
|
|
/obj/belly/proc/get_unused_digestion_damage()
|
|
return max(digest_max - get_total_digestion_damage(), 0)
|
|
|
|
/obj/belly/proc/set_zero_digestion_damage()
|
|
digest_brute = 0
|
|
digest_burn = 0
|
|
digest_oxy = 0
|
|
digest_tox = 0
|
|
digest_clone = 0
|
|
return
|
|
|
|
// Handle the death of a mob via digestion.
|
|
// 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(mob/living/M)
|
|
digested_prey_count++
|
|
add_attack_logs(owner, M, "Digested in [lowertext(name)]")
|
|
owner.changeling_obtain_dna(M)
|
|
|
|
// Reverts TF on death. This fixes a bug with posibrains or similar, and also makes reforming easier.
|
|
if(M.tf_mob_holder && M.tf_mob_holder.loc == M)
|
|
M.tf_mob_holder.ckey = M.ckey
|
|
M.tf_mob_holder.enabled = TRUE
|
|
M.tf_mob_holder.loc = M.loc
|
|
M.tf_mob_holder.forceMove(M.loc)
|
|
QDEL_LIST_NULL(M.tf_mob_holder.vore_organs)
|
|
M.tf_mob_holder.vore_organs = list()
|
|
M.tf_mob_holder.mob_belly_transfer(M)
|
|
|
|
if(M.tf_mob_holder)
|
|
M.tf_mob_holder = null
|
|
|
|
// If digested prey is also a pred... anyone inside their bellies gets moved up.
|
|
if(is_vore_predator(M))
|
|
M.release_vore_contents(include_absorbed = TRUE, silent = TRUE)
|
|
|
|
var/obj/item/mmi/hasMMI // Adjust how MMI's are handled
|
|
|
|
//Drop all items into the belly.
|
|
if(CONFIG_GET(flag/items_survive_digestion))
|
|
for(var/obj/item/W in M)
|
|
if(istype(W, /obj/item/organ/internal/mmi_holder/posibrain))
|
|
var/obj/item/organ/internal/mmi_holder/MMI = W
|
|
var/obj/item/mmi/brainbox = MMI.removed()
|
|
if(brainbox)
|
|
items_preserved += brainbox
|
|
hasMMI = brainbox // Adjust how MMI's are handled
|
|
for(var/slot in slots)
|
|
var/obj/item/I = M.get_equipped_item(slot = slot)
|
|
if(I)
|
|
M.unEquip(I,force = TRUE)
|
|
if(contaminates)
|
|
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
|
|
else if(item_digest_mode == IM_DIGEST_FOOD && !(istype(I,/obj/item/reagent_containers/food) || istype(I,/obj/item/organ)))
|
|
items_preserved |= I
|
|
|
|
//Reagent transfer
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/Pred = owner
|
|
if(ishuman(M))
|
|
var/mob/living/carbon/human/Prey = M
|
|
Prey.bloodstr.del_reagent(REAGENT_ID_NUMBENZYME)
|
|
Prey.bloodstr.trans_to_holder(Pred.ingested, Prey.bloodstr.total_volume, 0.5, TRUE) // Copy=TRUE because we're deleted anyway
|
|
Prey.ingested.trans_to_holder(Pred.ingested, Prey.ingested.total_volume, 0.5, TRUE) // Therefore don't bother spending cpu
|
|
//Don't need this stuff in our bloodstream.
|
|
Prey.touching.del_reagent(REAGENT_ID_STOMACID)
|
|
Prey.touching.del_reagent(REAGENT_ID_DIETSTOMACID)
|
|
Prey.touching.del_reagent(REAGENT_ID_PACID)
|
|
Prey.touching.del_reagent(REAGENT_ID_SACID)
|
|
Prey.touching.del_reagent(REAGENT_ID_CLEANER)
|
|
Prey.touching.del_reagent(REAGENT_ID_CONCENTRATEDRADIUM)
|
|
Prey.touching.del_reagent(REAGENT_ID_TRICORDRAZINE)
|
|
Prey.touching.trans_to_holder(Pred.ingested, Prey.touching.total_volume, 0.5, TRUE) // On updating the prey's reagents
|
|
else if(M.reagents)
|
|
//Don't need this stuff in our bloodstream.
|
|
M.reagents.del_reagent(REAGENT_ID_STOMACID)
|
|
M.reagents.del_reagent(REAGENT_ID_DIETSTOMACID)
|
|
M.reagents.del_reagent(REAGENT_ID_PACID)
|
|
M.reagents.del_reagent(REAGENT_ID_SACID)
|
|
M.reagents.del_reagent(REAGENT_ID_CLEANER)
|
|
M.reagents.del_reagent(REAGENT_ID_CONCENTRATEDRADIUM)
|
|
M.reagents.del_reagent(REAGENT_ID_TRICORDRAZINE)
|
|
M.reagents.del_reagent(REAGENT_ID_ETHANOL)
|
|
M.reagents.trans_to_holder(Pred.ingested, M.reagents.total_volume, 0.5, TRUE)
|
|
|
|
owner.handle_belly_update()
|
|
|
|
//Incase they have the loop going, let's double check to stop it.
|
|
M.stop_sound_channel(CHANNEL_PREYLOOP)
|
|
//Don't let glows stick
|
|
M.glow_toggle = FALSE
|
|
M.set_light(0)
|
|
// Delete the digested mob
|
|
// Changed qdel to a forceMove to allow reforming, and... handled robots special.
|
|
if(isrobot(M))
|
|
var/mob/living/silicon/robot/R = M
|
|
if(R.mmi && R.mind && R.mmi.brainmob)
|
|
if((R.soulcatcher_pref_flags & SOULCATCHER_ALLOW_CAPTURE) && owner.soulgem && owner.soulgem.flag_check(SOULGEM_ACTIVE | NIF_SC_CATCHING_OTHERS, TRUE))
|
|
owner.soulgem.catch_mob(R, R.name)
|
|
else
|
|
R.mmi.loc = src
|
|
items_preserved += R.mmi
|
|
var/obj/item/robot_module/MB = locate() in R.contents
|
|
if(MB)
|
|
R.mmi.brainmob.languages = MB.original_languages
|
|
else
|
|
R.mmi.brainmob.languages = R.languages
|
|
R.mmi.brainmob.remove_language(LANGUAGE_ROBOT_TALK)
|
|
hasMMI = R.mmi
|
|
M.mind.transfer_to(hasMMI.brainmob)
|
|
R.mmi = null
|
|
else if(!R.shell) // Shells don't have brainmobs in their MMIs.
|
|
to_chat(R, span_danger("Oops! Something went very wrong, your MMI was unable to receive your mind. You have been ghosted. Please make a bug report so we can fix this bug."))
|
|
if(R.shell) // Let the standard procedure for shells handle this.
|
|
qdel(R)
|
|
return
|
|
|
|
if(istype(hasMMI))
|
|
hasMMI.body_backup = M
|
|
M.enabled = FALSE
|
|
M.forceMove(hasMMI)
|
|
else
|
|
var/mob/observer/G = M.ghostize(FALSE) // Make sure they're out, so we can copy attack logs and such.
|
|
if(G)
|
|
G.forceMove(src)
|
|
G.body_backup = M
|
|
M.enabled = FALSE
|
|
M.forceMove(G)
|
|
else
|
|
qdel(M)
|
|
owner.handle_belly_update()
|
|
|
|
// Handle a mob being absorbed
|
|
/obj/belly/proc/absorb_living(mob/living/M)
|
|
M.absorbed = TRUE
|
|
if(M.ckey)
|
|
handle_absorb_langs(M, owner)
|
|
GLOB.prey_absorbed_roundstat++
|
|
|
|
to_chat(M, span_vnotice("[belly_format_string(absorb_messages_prey, M, use_absorbed_count = TRUE)]"))
|
|
to_chat(owner, span_vnotice("[belly_format_string(absorb_messages_owner, M, use_absorbed_count = TRUE)]"))
|
|
if(M.noisy) //Mute drained absorbee hunger if enabled.
|
|
M.noisy = FALSE
|
|
|
|
if(ishuman(M) && ishuman(owner))
|
|
var/mob/living/carbon/human/Prey = M
|
|
var/mob/living/carbon/human/Pred = owner
|
|
//Reagent sharing for absorbed with pred - Copy so both pred and prey have these reagents.
|
|
Prey.bloodstr.trans_to_holder(Pred.ingested, Prey.bloodstr.total_volume, copy = TRUE)
|
|
Prey.ingested.trans_to_holder(Pred.ingested, Prey.ingested.total_volume, copy = TRUE)
|
|
Prey.touching.del_reagent(REAGENT_ID_STOMACID)
|
|
Prey.touching.del_reagent(REAGENT_ID_DIETSTOMACID)
|
|
Prey.touching.del_reagent(REAGENT_ID_PACID)
|
|
Prey.touching.del_reagent(REAGENT_ID_SACID)
|
|
Prey.touching.del_reagent(REAGENT_ID_CLEANER)
|
|
Prey.touching.del_reagent(REAGENT_ID_CONCENTRATEDRADIUM)
|
|
Prey.touching.del_reagent(REAGENT_ID_TRICORDRAZINE)
|
|
Prey.touching.trans_to_holder(Pred.ingested, Prey.touching.total_volume, copy = TRUE)
|
|
// TODO - Find a way to make the absorbed prey share the effects with the pred.
|
|
// Currently this is infeasible because reagent containers are designed to have a single my_atom, and we get
|
|
// problems when A absorbs B, and then C absorbs A, resulting in B holding onto an invalid reagent container.
|
|
Pred.changeling_obtain_dna(Prey)
|
|
|
|
//This is probably already the case, but for sub-prey, it won't be.
|
|
if(M.loc != src)
|
|
M.forceMove(src)
|
|
|
|
//Seek out absorbed prey of the prey, absorb them too.
|
|
//This in particular will recurse oddly because if there is absorbed prey of prey of prey...
|
|
//it will just move them up one belly. This should never happen though since... when they were
|
|
//absobred, they should have been absorbed as well!
|
|
for(var/obj/belly/B as anything in M.vore_organs)
|
|
for(var/mob/living/Mm in B)
|
|
if(Mm.absorbed)
|
|
absorb_living(Mm)
|
|
|
|
if(absorbed_desc)
|
|
//Replace placeholder vars
|
|
to_chat(M, span_vnotice(span_bold("[belly_format_string(absorbed_desc, M)]")))
|
|
|
|
//Update owner
|
|
owner.updateVRPanel()
|
|
owner.handle_belly_update()
|
|
// Finally, if they're to be sent to a special pudge belly, send them there
|
|
if(transferlocation_absorb)
|
|
var/obj/belly/dest_belly
|
|
for(var/obj/belly/B as anything in owner.vore_organs)
|
|
if(B.name == transferlocation_absorb)
|
|
dest_belly = B
|
|
break
|
|
if(!dest_belly)
|
|
to_chat(owner, span_vwarning("Something went wrong with your belly transfer settings. Your <b>[lowertext(name)]</b> has had its transfer location cleared as a precaution."))
|
|
transferlocation_absorb = null
|
|
return
|
|
|
|
transfer_contents(M, dest_belly)
|
|
|
|
// Handle a mob being unabsorbed
|
|
/obj/belly/proc/unabsorb_living(mob/living/M)
|
|
M.absorbed = FALSE
|
|
handle_absorb_langs(M, owner)
|
|
to_chat(M, span_vnotice(belly_format_string(unabsorb_messages_prey, M, use_absorbed_count = TRUE)))
|
|
to_chat(owner, span_vnotice(belly_format_string(unabsorb_messages_owner, M, use_absorbed_count = TRUE)))
|
|
|
|
if(desc)
|
|
to_chat(M, span_vnotice(span_bold("[belly_format_string(desc, M)]")))
|
|
|
|
//Update owner
|
|
owner.updateVRPanel()
|
|
owner.handle_belly_update()
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
/obj/belly/proc/handle_absorb_langs()
|
|
owner.absorb_langs()
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//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(obj/item/item, touchable_amount)
|
|
var/digested = item.digest_act(src, touchable_amount)
|
|
if(digested == FALSE)
|
|
items_preserved |= item
|
|
else
|
|
owner_adjust_nutrition((nutrition_percent / 100) * 5 * digested)
|
|
digested = TRUE
|
|
return digested
|
|
|
|
//Determine where items should fall out of us into.
|
|
//Typically just to the owner's location.
|
|
/obj/belly/drop_location()
|
|
//Should be the case 99.99% of the time
|
|
if(isAI(owner))
|
|
var/mob/living/silicon/ai/AI = owner
|
|
if(AI.holo && AI.holo.masters[AI])
|
|
return AI.holo.masters[AI].drop_location()
|
|
|
|
if(owner)
|
|
return owner.drop_location()
|
|
//Sketchy fallback for safety, put them somewhere safe.
|
|
else
|
|
log_runtime("[src] (\ref[src]) doesn't have an owner, and dropped someone at a latespawn point!")
|
|
var/fallback = pick(GLOB.latejoin)
|
|
return get_turf(fallback)
|
|
|
|
//Yes, it's ""safe"" to drop items here
|
|
/obj/belly/AllowDrop()
|
|
return TRUE
|
|
|
|
/obj/belly/onDropInto(atom/movable/AM)
|
|
return null
|
|
|
|
/obj/belly/proc/get_mobs_and_objs_in_belly()
|
|
var/list/see = list()
|
|
var/list/belly_mobs = list()
|
|
see["mobs"] = belly_mobs
|
|
var/list/belly_objs = list()
|
|
see["objs"] = belly_objs
|
|
for(var/mob/living/L in loc.contents)
|
|
belly_mobs |= L
|
|
for(var/obj/O in loc.contents)
|
|
belly_objs |= O
|
|
|
|
return see
|
|
|
|
//Transfers contents from one belly to another
|
|
/obj/belly/proc/transfer_contents(atom/movable/content, obj/belly/target, silent = FALSE)
|
|
if(!(content in src) || !istype(target))
|
|
return
|
|
content.belly_cycles = 0
|
|
var/old_entrance_logs = target.entrance_logs
|
|
if(silent)
|
|
target.entrance_logs = FALSE
|
|
content.forceMove(target)
|
|
target.entrance_logs = old_entrance_logs
|
|
if(isitem(content))
|
|
var/obj/item/I = content
|
|
if(istype(I,/obj/item/card/id))
|
|
I.gurgle_contaminate(target.contents, target.contamination_flavor, target.contamination_color)
|
|
if(I.gurgled && target.contaminates)
|
|
I.wash(CLEAN_WASH)
|
|
I.gurgle_contaminate(target.contents, target.contamination_flavor, target.contamination_color)
|
|
items_preserved -= content
|
|
if(!silent)
|
|
handle_visual_update()
|
|
|
|
/obj/belly/proc/handle_visual_update()
|
|
owner.updateVRPanel()
|
|
for(var/mob/living/M in contents)
|
|
M.updateVRPanel()
|
|
owner.handle_belly_update()
|
|
|
|
//Autotransfer belly lookup
|
|
/obj/belly/proc/compile_autotransfer_bellies()
|
|
var/list/primary_bellies = list()
|
|
var/list/secondary_bellies = list()
|
|
|
|
var/list/primary_locations = autotransferextralocation.Copy()
|
|
primary_locations += autotransferlocation
|
|
var/list/secondary_locations = autotransferextralocation_secondary.Copy()
|
|
secondary_locations += autotransferlocation_secondary
|
|
for(var/obj/belly/B in owner.vore_organs)
|
|
if(B.name in primary_locations)
|
|
primary_bellies += B
|
|
if(B.name in secondary_locations)
|
|
secondary_bellies += B
|
|
|
|
if(!length(primary_bellies) && !length(secondary_bellies))
|
|
return null
|
|
|
|
return list("primary" = primary_bellies, "secondary" = secondary_bellies)
|
|
|
|
//Autotransfer callback
|
|
/obj/belly/proc/check_autotransfer(var/atom/movable/prey, var/list/transfer_locations)
|
|
if(!(prey in contents) || !prey.autotransferable)
|
|
return FALSE
|
|
var/obj/belly/dest_belly
|
|
if(length(transfer_locations["secondary"]))
|
|
if(autotransferlocation_secondary && prob(autotransferchance_secondary))
|
|
if(ismob(prey) && autotransfer_filter(prey, autotransfer_secondary_whitelist, autotransfer_secondary_blacklist))
|
|
dest_belly = pick(transfer_locations["secondary"])
|
|
if(isitem(prey) && autotransfer_filter(prey, autotransfer_secondary_whitelist_items, autotransfer_secondary_blacklist_items))
|
|
dest_belly = pick(transfer_locations["secondary"])
|
|
if(length(transfer_locations["primary"]))
|
|
if(autotransferlocation && prob(autotransferchance))
|
|
if(ismob(prey) && autotransfer_filter(prey, autotransfer_whitelist, autotransfer_blacklist))
|
|
dest_belly = pick(transfer_locations["primary"])
|
|
if(isitem(prey) && autotransfer_filter(prey, autotransfer_whitelist_items, autotransfer_blacklist_items))
|
|
dest_belly = pick(transfer_locations["primary"])
|
|
if(!dest_belly) // Didn't transfer, so wait before retrying
|
|
prey.belly_cycles = 0
|
|
return FALSE
|
|
if(ismob(prey))
|
|
var/autotransfer_owner_message
|
|
var/autotransfer_prey_message
|
|
var/dest_belly_name = dest_belly.name
|
|
if(dest_belly.name == autotransferlocation)
|
|
autotransfer_owner_message = span_vwarning(belly_format_string(primary_autotransfer_messages_owner, prey, dest = dest_belly_name))
|
|
autotransfer_prey_message = span_vwarning(belly_format_string(primary_autotransfer_messages_prey, prey, dest = dest_belly_name))
|
|
else
|
|
autotransfer_owner_message = span_vwarning(belly_format_string(secondary_autotransfer_messages_owner, prey, dest = dest_belly_name))
|
|
autotransfer_prey_message = span_vwarning(belly_format_string(secondary_autotransfer_messages_prey, prey, dest = dest_belly_name))
|
|
|
|
to_chat(prey, autotransfer_prey_message)
|
|
if(entrance_logs)
|
|
to_chat(owner, autotransfer_owner_message)
|
|
|
|
transfer_contents(prey, dest_belly, TRUE)
|
|
return TRUE
|
|
|
|
//Autotransfer filter
|
|
/obj/belly/proc/autotransfer_filter(var/atom/movable/prey, var/whitelist, var/blacklist)
|
|
if(ismob(prey))
|
|
if(blacklist & autotransfer_flags_list["Absorbed"])
|
|
if(isliving(prey))
|
|
var/mob/living/L = prey
|
|
if(L.absorbed) return FALSE
|
|
if(blacklist != 2) // Default is 2 for Absorbed, if it's not 2, check everything else
|
|
if(blacklist & autotransfer_flags_list["Creatures"])
|
|
if(isliving(prey)) return FALSE
|
|
if(blacklist & autotransfer_flags_list["Carbon"])
|
|
if(iscarbon(prey)) return FALSE
|
|
if(blacklist & autotransfer_flags_list["Silicon"])
|
|
if(issilicon(prey)) return FALSE
|
|
if(blacklist & autotransfer_flags_list["Mobs"])
|
|
if(istype(prey, /mob/living/simple_mob)) return FALSE
|
|
if(blacklist & autotransfer_flags_list["Animals"])
|
|
if(istype(prey, /mob/living/simple_mob/animal)) return FALSE
|
|
if(blacklist & autotransfer_flags_list["Mice"])
|
|
if(ismouse(prey)) return FALSE
|
|
if(blacklist & autotransfer_flags_list["Dead"])
|
|
if(isliving(prey))
|
|
var/mob/living/L = prey
|
|
if(L.stat == DEAD) return FALSE
|
|
if(blacklist & autotransfer_flags_list["Digestable Creatures"])
|
|
if(isliving(prey))
|
|
var/mob/living/L = prey
|
|
if(L.digestable) return FALSE
|
|
if(blacklist & autotransfer_flags_list["Absorbable Creatures"])
|
|
if(isliving(prey))
|
|
var/mob/living/L = prey
|
|
if(L.absorbable) return FALSE
|
|
if(blacklist & autotransfer_flags_list["Full Health"])
|
|
if(isliving(prey))
|
|
var/mob/living/L = prey
|
|
if((L.getOxyLoss() + L.getToxLoss() + L.getFireLoss() + L.getBruteLoss() + L.getCloneLoss()) == 0) return FALSE
|
|
if(whitelist == 0) return TRUE
|
|
if(whitelist & autotransfer_flags_list["Creatures"])
|
|
if(isliving(prey)) return TRUE
|
|
if(whitelist & autotransfer_flags_list["Absorbed"])
|
|
if(isliving(prey))
|
|
var/mob/living/L = prey
|
|
if(L.absorbed) return TRUE
|
|
if(whitelist & autotransfer_flags_list["Carbon"])
|
|
if(iscarbon(prey)) return TRUE
|
|
if(whitelist & autotransfer_flags_list["Silicon"])
|
|
if(issilicon(prey)) return TRUE
|
|
if(whitelist & autotransfer_flags_list["Mobs"])
|
|
if(istype(prey, /mob/living/simple_mob)) return TRUE
|
|
if(whitelist & autotransfer_flags_list["Animals"])
|
|
if(istype(prey, /mob/living/simple_mob/animal)) return TRUE
|
|
if(whitelist & autotransfer_flags_list["Mice"])
|
|
if(ismouse(prey)) return TRUE
|
|
if(whitelist & autotransfer_flags_list["Dead"])
|
|
if(isliving(prey))
|
|
var/mob/living/L = prey
|
|
if(L.stat == DEAD) return TRUE
|
|
if(whitelist & autotransfer_flags_list["Digestable Creatures"])
|
|
if(isliving(prey))
|
|
var/mob/living/L = prey
|
|
if(L.digestable) return TRUE
|
|
if(whitelist & autotransfer_flags_list["Absorbable Creatures"])
|
|
if(isliving(prey))
|
|
var/mob/living/L = prey
|
|
if(L.absorbable) return TRUE
|
|
if(whitelist & autotransfer_flags_list["Full Health"])
|
|
if(isliving(prey))
|
|
var/mob/living/L = prey
|
|
if((L.getOxyLoss() + L.getToxLoss() + L.getFireLoss() + L.getBruteLoss() + L.getCloneLoss()) == 0) return TRUE
|
|
else
|
|
if(blacklist & autotransfer_flags_list_items["Items"])
|
|
if(isitem(prey)) return FALSE
|
|
if(blacklist & autotransfer_flags_list_items["Trash"])
|
|
if(istype(prey, /obj/item/trash)) return FALSE
|
|
if(blacklist & autotransfer_flags_list_items["Eggs"])
|
|
if(istype(prey, /obj/item/storage/vore_egg)) return FALSE
|
|
if(blacklist & autotransfer_flags_list_items["Remains"])
|
|
if(istype(prey, /obj/item/digestion_remains)) return FALSE
|
|
if(blacklist & autotransfer_flags_list_items["Indigestible Items"])
|
|
if(prey in items_preserved) return FALSE
|
|
if(blacklist & autotransfer_flags_list_items["Recyclable Items"])
|
|
if(isitem(prey))
|
|
var/obj/item/I = prey
|
|
if(I.matter) return FALSE
|
|
if(blacklist & autotransfer_flags_list_items["Ores"])
|
|
if(istype(prey, /obj/item/ore)) return FALSE
|
|
if(blacklist & autotransfer_flags_list_items["Clothes and Bags"])
|
|
if(istype(prey, /obj/item/clothing) || istype(prey, /obj/item/storage)) return FALSE
|
|
if(blacklist & autotransfer_flags_list_items["Food"])
|
|
if(istype(prey, /obj/item/reagent_containers/food)) return FALSE
|
|
if(whitelist == 0) return TRUE
|
|
if(whitelist & autotransfer_flags_list_items["Items"])
|
|
if(isitem(prey)) return TRUE
|
|
if(whitelist & autotransfer_flags_list_items["Trash"])
|
|
if(istype(prey, /obj/item/trash)) return TRUE
|
|
if(whitelist & autotransfer_flags_list_items["Eggs"])
|
|
if(istype(prey, /obj/item/storage/vore_egg)) return TRUE
|
|
if(whitelist & autotransfer_flags_list_items["Remains"])
|
|
if(istype(prey, /obj/item/digestion_remains)) return TRUE
|
|
if(whitelist & autotransfer_flags_list_items["Indigestible Items"])
|
|
if(prey in items_preserved) return TRUE
|
|
if(whitelist & autotransfer_flags_list_items["Recyclable Items"])
|
|
if(isitem(prey))
|
|
var/obj/item/I = prey
|
|
if(I.matter) return TRUE
|
|
if(whitelist & autotransfer_flags_list_items["Ores"])
|
|
if(istype(prey, /obj/item/ore)) return TRUE
|
|
if(whitelist & autotransfer_flags_list_items["Clothes and Bags"])
|
|
if(istype(prey, /obj/item/clothing) || istype(prey, /obj/item/storage)) return TRUE
|
|
if(whitelist & autotransfer_flags_list_items["Food"])
|
|
if(istype(prey, /obj/item/reagent_containers/food)) return TRUE
|
|
return FALSE
|
|
|
|
// Belly copies and then returns the copy
|
|
// Needs to be updated for any var changes
|
|
/obj/belly/proc/copy(mob/new_owner)
|
|
var/obj/belly/dupe = new /obj/belly(new_owner)
|
|
|
|
//// Non-object variables
|
|
dupe.name = name
|
|
dupe.desc = desc
|
|
dupe.display_name = display_name
|
|
dupe.message_mode = message_mode
|
|
dupe.absorbed_desc = absorbed_desc
|
|
dupe.vore_sound = vore_sound
|
|
dupe.vore_verb = vore_verb
|
|
dupe.release_verb = release_verb
|
|
dupe.human_prey_swallow_time = human_prey_swallow_time
|
|
dupe.nonhuman_prey_swallow_time = nonhuman_prey_swallow_time
|
|
dupe.emote_time = emote_time
|
|
dupe.nutrition_percent = nutrition_percent
|
|
dupe.digest_brute = digest_brute
|
|
dupe.digest_burn = digest_burn
|
|
dupe.digest_oxy = digest_oxy
|
|
dupe.digest_tox = digest_tox
|
|
dupe.digest_clone = digest_clone
|
|
dupe.bellytemperature = bellytemperature
|
|
dupe.temperature_damage = temperature_damage
|
|
dupe.immutable = immutable
|
|
dupe.can_taste = can_taste
|
|
dupe.escapable = escapable
|
|
dupe.escapetime = escapetime
|
|
dupe.digestchance = digestchance
|
|
dupe.absorbchance = absorbchance
|
|
dupe.escapechance = escapechance
|
|
dupe.escapechance_absorbed = escapechance_absorbed
|
|
dupe.transferchance = transferchance
|
|
dupe.transferchance_secondary = transferchance_secondary
|
|
dupe.transferlocation = transferlocation
|
|
dupe.transferlocation_secondary = transferlocation_secondary
|
|
dupe.bulge_size = bulge_size
|
|
dupe.shrink_grow_size = shrink_grow_size
|
|
dupe.mode_flags = mode_flags
|
|
dupe.item_digest_mode = item_digest_mode
|
|
dupe.contaminates = contaminates
|
|
dupe.contamination_flavor = contamination_flavor
|
|
dupe.contamination_color = contamination_color
|
|
dupe.release_sound = release_sound
|
|
dupe.fancy_vore = fancy_vore
|
|
dupe.is_wet = is_wet
|
|
dupe.wet_loop = wet_loop
|
|
dupe.reagent_mode_flags = reagent_mode_flags
|
|
dupe.belly_fullscreen_color = belly_fullscreen_color
|
|
dupe.belly_fullscreen_color2 = belly_fullscreen_color2
|
|
dupe.belly_fullscreen_color3 = belly_fullscreen_color3
|
|
dupe.belly_fullscreen_color4 = belly_fullscreen_color4
|
|
dupe.belly_fullscreen_alpha = belly_fullscreen_alpha
|
|
dupe.show_liquids = show_liquids
|
|
dupe.reagent_gen_cost_limit = reagent_gen_cost_limit
|
|
dupe.reagentbellymode = reagentbellymode
|
|
dupe.vorefootsteps_sounds = vorefootsteps_sounds
|
|
dupe.liquid_fullness1_messages = liquid_fullness1_messages
|
|
dupe.liquid_fullness2_messages = liquid_fullness2_messages
|
|
dupe.liquid_fullness3_messages = liquid_fullness3_messages
|
|
dupe.liquid_fullness4_messages = liquid_fullness4_messages
|
|
dupe.liquid_fullness5_messages = liquid_fullness5_messages
|
|
dupe.displayed_message_flags = displayed_message_flags
|
|
dupe.reagent_name = reagent_name
|
|
dupe.reagent_chosen = reagent_chosen
|
|
dupe.reagentid = reagentid
|
|
dupe.reagentcolor = reagentcolor
|
|
dupe.liquid_overlay = liquid_overlay
|
|
dupe.max_liquid_level = max_liquid_level
|
|
dupe.reagent_touches = reagent_touches
|
|
dupe.mush_overlay = mush_overlay
|
|
dupe.mush_color = mush_color
|
|
dupe.mush_alpha = mush_alpha
|
|
dupe.max_mush = max_mush
|
|
dupe.min_mush = min_mush
|
|
dupe.item_mush_val = item_mush_val
|
|
dupe.custom_reagentcolor = custom_reagentcolor
|
|
dupe.custom_reagentalpha = custom_reagentalpha
|
|
dupe.metabolism_overlay = metabolism_overlay
|
|
dupe.metabolism_mush_ratio = metabolism_mush_ratio
|
|
dupe.max_ingested = max_ingested
|
|
dupe.custom_ingested_color = custom_ingested_color
|
|
dupe.custom_ingested_alpha = custom_ingested_alpha
|
|
dupe.gen_cost = gen_cost
|
|
dupe.gen_amount = gen_amount
|
|
dupe.gen_time = gen_time
|
|
dupe.gen_time_display = gen_time_display
|
|
dupe.reagent_transfer_verb = reagent_transfer_verb
|
|
dupe.custom_max_volume = custom_max_volume
|
|
dupe.vorespawn_blacklist = vorespawn_blacklist
|
|
dupe.vorespawn_whitelist = vorespawn_whitelist
|
|
dupe.vorespawn_absorbed = vorespawn_absorbed
|
|
dupe.absorbed_multiplier = absorbed_multiplier
|
|
dupe.count_liquid_for_sprite = count_liquid_for_sprite
|
|
dupe.liquid_multiplier = liquid_multiplier
|
|
dupe.undergarment_chosen = undergarment_chosen
|
|
dupe.undergarment_if_none = undergarment_if_none
|
|
dupe.undergarment_color = undergarment_color
|
|
dupe.autotransferchance = autotransferchance
|
|
dupe.autotransferwait = autotransferwait
|
|
dupe.autotransferlocation = autotransferlocation
|
|
dupe.autotransfer_enabled = autotransfer_enabled
|
|
dupe.autotransferchance_secondary = autotransferchance_secondary
|
|
dupe.autotransferlocation_secondary = autotransferlocation_secondary
|
|
dupe.autotransfer_min_amount = autotransfer_min_amount
|
|
dupe.autotransfer_max_amount = autotransfer_max_amount
|
|
dupe.slow_digestion = slow_digestion
|
|
dupe.slow_brutal = slow_brutal
|
|
dupe.sound_volume = sound_volume
|
|
dupe.egg_name = egg_name
|
|
dupe.egg_size = egg_size
|
|
dupe.recycling = recycling
|
|
dupe.storing_nutrition = storing_nutrition
|
|
dupe.is_feedable = is_feedable
|
|
dupe.entrance_logs = entrance_logs
|
|
dupe.noise_freq = noise_freq
|
|
dupe.item_digest_logs = item_digest_logs
|
|
dupe.show_fullness_messages = show_fullness_messages
|
|
dupe.belchchance = belchchance
|
|
dupe.digest_max = digest_max
|
|
dupe.belly_fullscreen = belly_fullscreen
|
|
dupe.disable_hud = disable_hud
|
|
dupe.colorization_enabled = colorization_enabled
|
|
dupe.egg_type = egg_type
|
|
dupe.emote_time = emote_time
|
|
dupe.emote_active = emote_active
|
|
dupe.selective_preference = selective_preference
|
|
dupe.save_digest_mode = save_digest_mode
|
|
dupe.eating_privacy_local = eating_privacy_local
|
|
dupe.silicon_belly_overlay_preference = silicon_belly_overlay_preference
|
|
dupe.belly_mob_mult = belly_mob_mult
|
|
dupe.belly_item_mult = belly_item_mult
|
|
dupe.belly_overall_mult = belly_overall_mult
|
|
dupe.vore_sprite_flags = vore_sprite_flags
|
|
dupe.affects_vore_sprites = affects_vore_sprites
|
|
dupe.count_absorbed_prey_for_sprite = count_absorbed_prey_for_sprite
|
|
dupe.resist_triggers_animation = resist_triggers_animation
|
|
dupe.size_factor_for_sprite = size_factor_for_sprite
|
|
dupe.belly_sprite_to_affect = belly_sprite_to_affect
|
|
dupe.health_impacts_size = health_impacts_size
|
|
dupe.count_items_for_sprite = count_items_for_sprite
|
|
dupe.item_multiplier = item_multiplier
|
|
dupe.undergarment_chosen = undergarment_chosen
|
|
dupe.undergarment_if_none = undergarment_if_none
|
|
dupe.undergarment_color = undergarment_color
|
|
|
|
//// Object-holding variables
|
|
//struggle_messages_outside - strings
|
|
dupe.struggle_messages_outside.Cut()
|
|
for(var/I in struggle_messages_outside)
|
|
dupe.struggle_messages_outside += I
|
|
|
|
//struggle_messages_inside - strings
|
|
dupe.struggle_messages_inside.Cut()
|
|
for(var/I in struggle_messages_inside)
|
|
dupe.struggle_messages_inside += I
|
|
|
|
//absorbed_struggle_messages_outside - strings
|
|
dupe.absorbed_struggle_messages_outside.Cut()
|
|
for(var/I in absorbed_struggle_messages_outside)
|
|
dupe.absorbed_struggle_messages_outside += I
|
|
|
|
//absorbed_struggle_messages_inside - strings
|
|
dupe.absorbed_struggle_messages_inside.Cut()
|
|
for(var/I in absorbed_struggle_messages_inside)
|
|
dupe.absorbed_struggle_messages_inside += I
|
|
|
|
//escape_attempt_messages_owner - strings
|
|
dupe.escape_attempt_messages_owner.Cut()
|
|
for(var/I in escape_attempt_messages_owner)
|
|
dupe.escape_attempt_messages_owner += I
|
|
|
|
//escape_attempt_messages_prey - strings
|
|
dupe.escape_attempt_messages_prey.Cut()
|
|
for(var/I in escape_attempt_messages_prey)
|
|
dupe.escape_attempt_messages_prey += I
|
|
|
|
//escape_messages_owner - strings
|
|
dupe.escape_messages_owner.Cut()
|
|
for(var/I in escape_messages_owner)
|
|
dupe.escape_messages_owner += I
|
|
|
|
//escape_messages_prey - strings
|
|
dupe.escape_messages_prey.Cut()
|
|
for(var/I in escape_messages_prey)
|
|
dupe.escape_messages_prey += I
|
|
|
|
//escape_messages_outside - strings
|
|
dupe.escape_messages_outside.Cut()
|
|
for(var/I in escape_messages_outside)
|
|
dupe.escape_messages_outside += I
|
|
|
|
//escape_item_messages_owner - strings
|
|
dupe.escape_item_messages_owner.Cut()
|
|
for(var/I in escape_item_messages_owner)
|
|
dupe.escape_item_messages_owner += I
|
|
|
|
//escape_item_messages_prey - strings
|
|
dupe.escape_item_messages_prey.Cut()
|
|
for(var/I in escape_item_messages_prey)
|
|
dupe.escape_item_messages_prey += I
|
|
|
|
//escape_item_messages_outside - strings
|
|
dupe.escape_item_messages_outside.Cut()
|
|
for(var/I in escape_item_messages_outside)
|
|
dupe.escape_item_messages_outside += I
|
|
|
|
//escape_fail_messages_owner - strings
|
|
dupe.escape_fail_messages_owner.Cut()
|
|
for(var/I in escape_fail_messages_owner)
|
|
dupe.escape_fail_messages_owner += I
|
|
|
|
//escape_fail_messages_prey - strings
|
|
dupe.escape_fail_messages_prey.Cut()
|
|
for(var/I in escape_fail_messages_prey)
|
|
dupe.escape_fail_messages_prey += I
|
|
|
|
//escape_attempt_absorbed_messages_owner - strings
|
|
dupe.escape_attempt_absorbed_messages_owner.Cut()
|
|
for(var/I in escape_attempt_absorbed_messages_owner)
|
|
dupe.escape_attempt_absorbed_messages_owner += I
|
|
|
|
//escape_attempt_absorbed_messages_prey - strings
|
|
dupe.escape_attempt_absorbed_messages_prey.Cut()
|
|
for(var/I in escape_attempt_absorbed_messages_prey)
|
|
dupe.escape_attempt_absorbed_messages_prey += I
|
|
|
|
//escape_absorbed_messages_owner - strings
|
|
dupe.escape_absorbed_messages_owner.Cut()
|
|
for(var/I in escape_absorbed_messages_owner)
|
|
dupe.escape_absorbed_messages_owner += I
|
|
|
|
//escape_absorbed_messages_prey - strings
|
|
dupe.escape_absorbed_messages_prey.Cut()
|
|
for(var/I in escape_absorbed_messages_prey)
|
|
dupe.escape_absorbed_messages_prey += I
|
|
|
|
//escape_absorbed_messages_outside - strings
|
|
dupe.escape_absorbed_messages_outside.Cut()
|
|
for(var/I in escape_absorbed_messages_outside)
|
|
dupe.escape_absorbed_messages_outside += I
|
|
|
|
//escape_fail_absorbed_messages_owner - strings
|
|
dupe.escape_fail_absorbed_messages_owner.Cut()
|
|
for(var/I in escape_fail_absorbed_messages_owner)
|
|
dupe.escape_fail_absorbed_messages_owner += I
|
|
|
|
//escape_fail_absorbed_messages_prey - strings
|
|
dupe.escape_fail_absorbed_messages_prey.Cut()
|
|
for(var/I in escape_fail_absorbed_messages_prey)
|
|
dupe.escape_fail_absorbed_messages_prey += I
|
|
|
|
//primary_transfer_messages_owner - strings
|
|
dupe.primary_transfer_messages_owner.Cut()
|
|
for(var/I in primary_transfer_messages_owner)
|
|
dupe.primary_transfer_messages_owner += I
|
|
|
|
//primary_transfer_messages_prey - strings
|
|
dupe.primary_transfer_messages_prey.Cut()
|
|
for(var/I in primary_transfer_messages_prey)
|
|
dupe.primary_transfer_messages_prey += I
|
|
|
|
//secondary_transfer_messages_owner - strings
|
|
dupe.secondary_transfer_messages_owner.Cut()
|
|
for(var/I in secondary_transfer_messages_owner)
|
|
dupe.secondary_transfer_messages_owner += I
|
|
|
|
//secondary_transfer_messages_prey - strings
|
|
dupe.secondary_transfer_messages_prey.Cut()
|
|
for(var/I in secondary_transfer_messages_prey)
|
|
dupe.secondary_transfer_messages_prey += I
|
|
|
|
//digest_chance_messages_owner - strings
|
|
dupe.digest_chance_messages_owner.Cut()
|
|
for(var/I in digest_chance_messages_owner)
|
|
dupe.digest_chance_messages_owner += I
|
|
|
|
//digest_chance_messages_prey - strings
|
|
dupe.digest_chance_messages_prey.Cut()
|
|
for(var/I in digest_chance_messages_prey)
|
|
dupe.digest_chance_messages_prey += I
|
|
|
|
//absorb_chance_messages_owner - strings
|
|
dupe.absorb_chance_messages_owner.Cut()
|
|
for(var/I in absorb_chance_messages_owner)
|
|
dupe.absorb_chance_messages_owner += I
|
|
|
|
//absorb_chance_messages_prey - strings
|
|
dupe.absorb_chance_messages_prey.Cut()
|
|
for(var/I in absorb_chance_messages_prey)
|
|
dupe.absorb_chance_messages_prey += I
|
|
|
|
//digest_messages_owner - strings
|
|
dupe.digest_messages_owner.Cut()
|
|
for(var/I in digest_messages_owner)
|
|
dupe.digest_messages_owner += I
|
|
|
|
//digest_messages_prey - strings
|
|
dupe.digest_messages_prey.Cut()
|
|
for(var/I in digest_messages_prey)
|
|
dupe.digest_messages_prey += I
|
|
|
|
//absorb_messages_owner - strings
|
|
dupe.absorb_messages_owner.Cut()
|
|
for(var/I in absorb_messages_owner)
|
|
dupe.absorb_messages_owner += I
|
|
|
|
//absorb_messages_prey - strings
|
|
dupe.absorb_messages_prey.Cut()
|
|
for(var/I in absorb_messages_prey)
|
|
dupe.absorb_messages_prey += I
|
|
|
|
//unabsorb_messages_owner - strings
|
|
dupe.unabsorb_messages_owner.Cut()
|
|
for(var/I in unabsorb_messages_owner)
|
|
dupe.unabsorb_messages_owner += I
|
|
|
|
//unabsorb_messages_prey - strings
|
|
dupe.unabsorb_messages_prey.Cut()
|
|
for(var/I in unabsorb_messages_prey)
|
|
dupe.unabsorb_messages_prey += I
|
|
|
|
//examine_messages - strings
|
|
dupe.examine_messages.Cut()
|
|
for(var/I in examine_messages)
|
|
dupe.examine_messages += I
|
|
|
|
//generated_reagents - strings
|
|
dupe.generated_reagents.Cut()
|
|
for(var/I in generated_reagents)
|
|
dupe.generated_reagents += I
|
|
|
|
//fullness1_messages - strings
|
|
dupe.fullness1_messages.Cut()
|
|
for(var/I in fullness1_messages)
|
|
dupe.fullness1_messages += I
|
|
|
|
//fullness2_messages - strings
|
|
dupe.fullness2_messages.Cut()
|
|
for(var/I in fullness2_messages)
|
|
dupe.fullness2_messages += I
|
|
|
|
//fullness3_messages - strings
|
|
dupe.fullness3_messages.Cut()
|
|
for(var/I in fullness3_messages)
|
|
dupe.fullness3_messages += I
|
|
|
|
//fullness4_messages - strings
|
|
dupe.fullness4_messages.Cut()
|
|
for(var/I in fullness4_messages)
|
|
dupe.fullness4_messages += I
|
|
|
|
//generated_reagents - strings
|
|
dupe.fullness5_messages.Cut()
|
|
for(var/I in fullness5_messages)
|
|
dupe.fullness5_messages += I
|
|
|
|
//examine_messages_absorbed - strings
|
|
dupe.examine_messages_absorbed.Cut()
|
|
for(var/I in examine_messages_absorbed)
|
|
dupe.examine_messages_absorbed += I
|
|
|
|
//emote_lists - index: digest mode, key: list of strings
|
|
dupe.emote_lists.Cut()
|
|
for(var/K in emote_lists)
|
|
dupe.emote_lists[K] = list()
|
|
for(var/I in emote_lists[K])
|
|
dupe.emote_lists[K] += I
|
|
|
|
return dupe
|
|
|
|
/obj/belly/container_resist(mob/M)
|
|
return relay_resist(M)
|
|
|
|
/obj/belly/proc/GetFullnessFromBelly()
|
|
if(!affects_vore_sprites)
|
|
return 0
|
|
var/belly_fullness = 0
|
|
for(var/mob/living/M in src)
|
|
if(count_absorbed_prey_for_sprite || !M.absorbed)
|
|
var/fullness_to_add = M.size_multiplier
|
|
fullness_to_add *= M.mob_size / 20
|
|
if(M.absorbed)
|
|
fullness_to_add *= absorbed_multiplier
|
|
if(health_impacts_size)
|
|
if(ishuman(M))
|
|
fullness_to_add *= (M.health + 100) / (M.getMaxHealth() + 100)
|
|
else
|
|
fullness_to_add *= M.health / M.getMaxHealth()
|
|
if(fullness_to_add > 0)
|
|
belly_fullness += fullness_to_add
|
|
if(count_liquid_for_sprite)
|
|
belly_fullness += (reagents.total_volume / 100) * liquid_multiplier
|
|
if(count_items_for_sprite)
|
|
for(var/obj/item/I in src)
|
|
var/fullness_to_add = 0
|
|
if(I.w_class == ITEMSIZE_TINY)
|
|
fullness_to_add = ITEMSIZE_COST_TINY
|
|
else if(I.w_class == ITEMSIZE_SMALL)
|
|
fullness_to_add = ITEMSIZE_COST_SMALL
|
|
else if(I.w_class == ITEMSIZE_NORMAL)
|
|
fullness_to_add = ITEMSIZE_COST_NORMAL
|
|
else if(I.w_class == ITEMSIZE_LARGE)
|
|
fullness_to_add = ITEMSIZE_COST_LARGE
|
|
else if(I.w_class == ITEMSIZE_HUGE)
|
|
fullness_to_add = ITEMSIZE_COST_HUGE
|
|
else
|
|
fullness_to_add = I.w_class
|
|
fullness_to_add /= 32
|
|
belly_fullness += fullness_to_add * item_multiplier
|
|
belly_fullness *= size_factor_for_sprite
|
|
return belly_fullness
|
|
|
|
/obj/item/debris_pack/digested
|
|
name = "digested material"
|
|
desc = "Some thoroughly digested mass of ... something. Might be useful for recycling."
|
|
icon = 'icons/obj/recycling.dmi'
|
|
icon_state = "matdust"
|
|
color = "#664330"
|
|
w_class = ITEMSIZE_SMALL
|
|
|
|
/obj/belly/proc/recycle(var/obj/item/O)
|
|
if(!recycling || (!LAZYLEN(O.matter) && !istype(O, /obj/item/ore)))
|
|
return FALSE
|
|
if(istype(O, /obj/item/ore))
|
|
var/obj/item/ore/ore = O
|
|
for(var/obj/item/ore_chunk/C in contents)
|
|
if(istype(C))
|
|
C.stored_ore[ore.material]++
|
|
return TRUE
|
|
var/obj/item/ore_chunk/newchunk = new /obj/item/ore_chunk(src)
|
|
newchunk.stored_ore[ore.material]++
|
|
return TRUE
|
|
else
|
|
var/list/modified_mats = list()
|
|
var/trash = 1
|
|
if(istype(O,/obj/item/trash))
|
|
trash = 5
|
|
if(istype(O,/obj/item/stack))
|
|
var/obj/item/stack/S = O
|
|
trash = S.amount
|
|
for(var/mat in O.matter)
|
|
modified_mats[mat] = O.matter[mat] * trash
|
|
for(var/obj/item/debris_pack/digested/D in contents)
|
|
if(istype(D))
|
|
for(var/mat in modified_mats)
|
|
D.matter[mat] += modified_mats[mat]
|
|
if(O.w_class > D.w_class)
|
|
D.w_class = O.w_class
|
|
if(O.possessed_voice && O.possessed_voice.len)
|
|
for(var/mob/living/voice/V in O.possessed_voice)
|
|
D.inhabit_item(V, null, V.tf_mob_holder)
|
|
qdel(V)
|
|
O.possessed_voice = list()
|
|
return TRUE
|
|
var/obj/item/debris_pack/digested/D = new /obj/item/debris_pack/digested(src, modified_mats)
|
|
if(O.possessed_voice && O.possessed_voice.len)
|
|
for(var/mob/living/voice/V in O.possessed_voice)
|
|
D.inhabit_item(V, null, V.tf_mob_holder)
|
|
qdel(V)
|
|
O.possessed_voice = list()
|
|
return TRUE
|
|
|
|
/obj/belly/proc/owner_adjust_nutrition(var/amount = 0)
|
|
if(storing_nutrition && amount > 0)
|
|
for(var/obj/item/reagent_containers/food/rawnutrition/R in contents)
|
|
if(istype(R))
|
|
R.stored_nutrition += amount
|
|
return
|
|
var/obj/item/reagent_containers/food/rawnutrition/NR = new /obj/item/reagent_containers/food/rawnutrition(src)
|
|
NR.stored_nutrition += amount
|
|
return
|
|
else
|
|
owner.adjust_nutrition(amount)
|
|
|
|
/obj/item/reagent_containers/food/rawnutrition
|
|
name = "raw nutrition"
|
|
desc = "A nutritious pile of converted mass ready for consumption."
|
|
icon = 'icons/obj/recycling.dmi'
|
|
icon_state = "matdust"
|
|
color = "#664330"
|
|
w_class = ITEMSIZE_SMALL
|
|
var/stored_nutrition = 0
|
|
|
|
/obj/item/reagent_containers/food/rawnutrition/standard_feed_mob(var/mob/user, var/mob/target)
|
|
if(isliving(target))
|
|
var/mob/living/L = target
|
|
L.nutrition += stored_nutrition
|
|
stored_nutrition = 0
|
|
qdel(src)
|
|
return
|
|
.=..()
|
|
|
|
// Updates the belly_surrounding list variable. Called in bellymodes_vr.dm
|
|
/obj/belly/proc/update_belly_surrounding()
|
|
if(!contents.len && !LAZYLEN(owner.soulgem?.brainmobs))
|
|
belly_surrounding = list()
|
|
return
|
|
belly_surrounding = get_belly_surrounding(contents)
|
|
if(owner.soulgem?.linked_belly == src)
|
|
belly_surrounding += owner.soulgem.brainmobs
|
|
|
|
// Recursive proc that returns all living mobs directly and indirectly inside a belly
|
|
// This can also be called more generically to get all living mobs not in bellies within any contents list
|
|
/obj/belly/proc/get_belly_surrounding(var/list/C)
|
|
var/list/surrounding = list()
|
|
for(var/thing in C)
|
|
if(istype(thing,/mob/living))
|
|
var/mob/living/L = thing
|
|
surrounding.Add(L)
|
|
surrounding.Add(get_belly_surrounding(L.contents))
|
|
if(istype(thing,/obj/item))
|
|
var/obj/item/I = thing
|
|
surrounding.Add(get_belly_surrounding(I.contents))
|
|
return surrounding
|
|
|
|
/obj/belly/proc/effective_emote_hearers()
|
|
. = list(loc)
|
|
for(var/atom/movable/AM as anything in contents)
|
|
//if(AM.atom_flags & ATOM_HEAR)
|
|
. += AM
|
|
|
|
/obj/belly/proc/get_belly_name(original)
|
|
var/display_name = ""
|
|
if(original)
|
|
return display_name ? display_name : name
|
|
return display_name ? lowertext(display_name) : lowertext(name)
|
|
|
|
/obj/belly/proc/toggle_displayed_message_flags(flags_to_set)
|
|
displayed_message_flags ^= flags_to_set
|
|
|
|
#undef MAX_ENTRY_MESSAAGES
|
|
#undef ENTRY_MESSAGE_INTERVAL
|