The lifeless husk of [src] bursts open, revealing a new, intact copy in the pool of viscera.
") //Bloody hell... - clear_alert("hatch") - return - - //Don't have nutriment to hatch! Or you somehow died in between completing your revive and hitting hatch. - else - to_chat(src, "Your body was unable to regenerate, what few living cells remain require additional nutrients to complete the process.") - verbs -= /mob/living/carbon/human/proc/hatch - revive_ready = REVIVING_READY //reset their cooldown they can try again when they're given a kickstart - clear_alert("hatch") + //Reviving from ded takes extra nutrition - if it isn't provided from outside sources, it comes from you + if(!hasnutriment()) + nutrition=nutrition * 0.75 + chimera_hatch() + adjustBrainLoss(5) // if they're reviving from dead, they come back with 5 brainloss on top of whatever's unhealed. + visible_message("The former corpse staggers to its feet, all its former wounds having vanished...
") //Bloody hell... + clear_alert("hatch") + return //Alive when hatching else chimera_hatch() - visible_message("The dormant husk of [src] bursts open, revealing a new, intact copy in the pool of viscera.
") //Bloody hell... + + visible_message("[src] rises to \his feet.
") //Bloody hell... clear_alert("hatch") /mob/living/carbon/human/proc/chimera_hatch() verbs -= /mob/living/carbon/human/proc/hatch to_chat(src, "Your new body awakens, bursting free from your old skin.") - //Modify and record values (half nutrition and braindamage) - var/old_nutrition = nutrition * 0.5 - var/braindamage = (brainloss * 0.5) //Can only heal half brain damage. - + var/old_nutrition = nutrition + var/braindamage = min(5, max(0, (brainloss-1) * 0.5)) //brainloss is tricky to heal and might take a couple of goes to get rid of completely. + var/uninjured=quickcheckuninjured() //I did have special snowflake code, but this is easier. revive() mutations.Remove(HUSK) - nutrition = old_nutrition setBrainLoss(braindamage) - //Drop everything - for(var/obj/item/W in src) - drop_from_inventory(W) + if(!uninjured) + nutrition = old_nutrition * 0.5 + //Drop everything + for(var/obj/item/W in src) + drop_from_inventory(W) + //Visual effects + var/T = get_turf(src) + var/blood_color = species.blood_color + var/flesh_color = species.flesh_color + new /obj/effect/gibspawner/human/xenochimera(T, null, flesh_color, blood_color) + visible_message("The lifeless husk of [src] bursts open, revealing a new, intact copy in the pool of viscera.
") //Bloody hell... + playsound(T, 'sound/effects/mob_effects/xenochimera/hatch.ogg', 50) + else //lower cost for doing a quick cosmetic revive + nutrition = old_nutrition * 0.9 //Unfreeze some things does_not_breathe = FALSE update_canmove() weakened = 2 - //Visual effects - var/T = get_turf(src) - var/blood_color = species.blood_color - var/flesh_color = species.flesh_color - new /obj/effect/gibspawner/human/xenochimera(T, null, flesh_color, blood_color) - - playsound(T, 'sound/effects/mob_effects/xenochimera/hatch.ogg', 50) - revive_ready = world.time + 10 MINUTES //set the cooldown CHOMPEdit: Reduced this to 10 minutes, you're playing with fire if you're reviving that often. /mob/living/carbon/human/proc/revivingreset() // keep this as a debug proc or potential future use diff --git a/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm index 40827c09166..3cb0c8bcde1 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm @@ -9,7 +9,7 @@ name_plural = "Xenochimeras" icobase = 'icons/mob/human_races/r_xenochimera.dmi' deform = 'icons/mob/human_races/r_def_xenochimera.dmi' - unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp) + unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/chimera, /datum/unarmed_attack/bite/sharp) darksight = 8 //critters with instincts to hide in the dark need to see in the dark - about as good as tajara. slowdown = -0.2 //scuttly, but not as scuttly as a tajara or a teshari. brute_mod = 0.8 //About as tanky to brute as a Unathi. They'll probably snap and go feral when hurt though. @@ -55,13 +55,13 @@ genders = list(MALE, FEMALE, PLURAL, NEUTER) - has_organ = list( //Same organ list as tajarans. + has_organ = list( //Same organ list as tajarans, except for their SPECIAL BRAIN. O_HEART = /obj/item/organ/internal/heart, O_LUNGS = /obj/item/organ/internal/lungs, O_VOICE = /obj/item/organ/internal/voicebox, O_LIVER = /obj/item/organ/internal/liver, O_KIDNEYS = /obj/item/organ/internal/kidneys, - O_BRAIN = /obj/item/organ/internal/brain, + O_BRAIN = /obj/item/organ/internal/brain/xenochimera, O_EYES = /obj/item/organ/internal/eyes, O_STOMACH = /obj/item/organ/internal/stomach, O_INTESTINE = /obj/item/organ/internal/intestine @@ -97,6 +97,9 @@ //Very low pressure damage if(adjusted_pressure2 <= 20) H.take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure") + //they handle areas where they can't breathe better than most, but it still lowers their effective health as well as all the other bad stuff that comes with unbreathable environments + if(H.getOxyLoss() >= 50) + H.does_not_breathe = TRUE //Cold hurts and gives them pain messages, eventually weakening and paralysing, but doesn't damage or trigger feral. //NB: 'body_temperature' used here is the 'setpoint' species var @@ -105,17 +108,24 @@ H.shock_stage = min(H.shock_stage + (temp_diff/20), 160) // Divided by 20 is the same as previous numbers, but a full scale H.eye_blurry = max(5,H.eye_blurry) +/obj/item/organ/internal/brain/xenochimera + var/laststress = 0 /datum/species/xenochimera/proc/handle_feralness(var/mob/living/carbon/human/H) + //first, calculate how stressed the chimera is + var/laststress = 0 + var/obj/item/organ/internal/brain/xenochimera/B = H.internal_organs_by_name[O_BRAIN] + if(B) //if you don't have a chimera brain in a chimera body somehow, you don't get the feraless protection + laststress = B.laststress - //Low-ish nutrition has messages and eventually feral - var/hungry = H.nutrition <= 200 + //Low-ish nutrition has messages and can eventually cause feralness + var/hunger = max(0, 150 - H.nutrition) - //At 360 nutrition, this is 30 brute/burn, or 18 halloss. Capped at 50 brute/30 halloss - if they take THAT much, no amount of satiation will help them. Also they're fat. - var/shock = H.traumatic_shock > min(60, H.nutrition/10) + //pain makes feralness a thing + var/shock = 0.75*H.traumatic_shock - //Caffeinated xenochimera can become feral and have special messages - var/jittery = H.jitteriness >= 100 + //Caffeinated or otherwise overexcited xenochimera can become feral and have special messages + var/jittery = max(0, H.jitteriness - 100) //To reduce distant object references var/feral = H.feral @@ -124,11 +134,25 @@ var/danger = FALSE var/feral_state = FALSE - //Handle feral triggers and pre-feral messages - if(!feral && (hungry || shock || jittery)) + //finally, calculate the current stress total the chimera is operating under, and the cause + var/currentstress = (hunger + shock + jittery) + var/cause = "stress" + if(hunger > shock && hunger > jittery) + cause = "hunger" + else if (shock > hunger && shock > jittery) + cause = "shock" + else if (jittery > shock && jittery > hunger) + cause = "jittery" - // If they're hungry, give nag messages (when not bellied) - if(H.nutrition >= 100 && prob(0.5) && !isbelly(H.loc)) + //check to see if they go feral if they weren't before + if(!feral) + // if stress is below 15, no chance of snapping. Also if they weren't feral before, they won't suddenly become feral unless they get MORE stressed + if((currentstress > laststress) && prob(clamp(currentstress-15, 0, 100)) ) + go_feral(H, currentstress, cause) + feral = currentstress //update the local var + + //they didn't go feral, give 'em a chance of hunger messages + else if(H.nutrition <= 200 && prob(0.5) && !isbelly(H.loc)) switch(H.nutrition) if(150 to 200) to_chat(H,"You feel rather hungry. It might be a good idea to find some some food...") @@ -136,81 +160,26 @@ to_chat(H,"You feel like you're going to snap and give in to your hunger soon... It would be for the best to find some [pick("food","prey")] to eat...") danger = TRUE - // Going feral due to hunger - else if(H.nutrition < 100 && !isbelly(H.loc)) - to_chat(H,"Something in your mind flips, your instincts taking over, no longer able to fully comprehend your surroundings as survival becomes your primary concern - you must feed, survive, there is nothing else. Hunt. Eat. Hide. Repeat.") - log_and_message_admins("has gone feral due to hunger.", H) - feral = 5 - danger = TRUE - feral_state = TRUE - if(!H.stat) - H.emote("twitch") - - // If they're hurt, chance of snapping. - else if(shock) - - //If the majority of their shock is due to halloss, greater chance of snapping. - if(2.5*H.halloss >= H.traumatic_shock) - if(prob(min(10,(0.2 * H.traumatic_shock)))) - to_chat(H,"The pain! It stings! Got to get away! Your instincts take over, urging you to flee, to hide, to go to ground, get away from here...") - log_and_message_admins("has gone feral due to halloss.", H) - feral = 5 - danger = TRUE - feral_state = TRUE - if(!H.stat) - H.emote("twitch") - - //Majority due to other damage sources - else if(prob(min(10,(0.1 * H.traumatic_shock)))) - to_chat(H,"Your fight-or-flight response kicks in, your injuries too much to simply ignore - you need to flee, to hide, survive at all costs - or destroy whatever is threatening you.") - feral = 5 - danger = TRUE - feral_state = TRUE - log_and_message_admins("has gone feral due to injury.", H) - if(!H.stat) - H.emote("twitch") - - //No hungry or shock, but jittery - else if(jittery) - to_chat(H,"Suddenly, something flips - everything that moves is... potential prey. A plaything. This is great! Time to hunt!") - feral = 5 - danger = TRUE - feral_state = TRUE - log_and_message_admins("has gone feral due to jitteriness.", H) - if(!H.stat) - H.emote("twitch") + //now the check's done, update their brain so it remembers how stressed they were + B.laststress = currentstress // Handle being feral if(feral) //We're feral feral_state = TRUE - //Shock due to mostly halloss. More feral. - if(shock && 2.5*H.halloss >= H.traumatic_shock) + //If they're still stressed, they stay feral + if(currentstress >= 15) danger = TRUE - feral = max(feral, H.halloss) + feral = max(feral, currentstress) - //Shock due to mostly injury. More feral. - else if(shock) - danger = TRUE - feral = max(feral, H.traumatic_shock * 2) - - //Still jittery? More feral. - if(jittery) - danger = TRUE - feral = max(feral, H.jitteriness-100) - - //Still hungry? More feral. - if(H.feral + H.nutrition < 150) - danger = TRUE - feral++ else feral = max(0,--feral) - // Being in a belly or in the darkness decreases stress further. Helps mechanically reward players for staying in darkness + RP'ing appropriately. :9 - var/turf/T = get_turf(H) - if(feral && (isbelly(H.loc) || T.get_lumcount() <= 0.1)) - feral = max(0,--feral) + // Being in a belly or in the darkness decreases stress further. Helps mechanically reward players for staying in darkness + RP'ing appropriately. :9 + var/turf/T = get_turf(H) + if(feral && (isbelly(H.loc) || T.get_lumcount() <= 0.1)) + feral = max(0,--feral) //Set our real mob's var to our temp var H.feral = feral @@ -227,7 +196,7 @@ H.shock_stage = max(H.shock_stage-(feral/20), 0) //Handle light/dark areas - // var/turf/T = get_turf(H) // Moved up to before the in-belly/dark combined check, should still safely reach here just fine. + var/turf/T = get_turf(H) if(!T) update_xenochimera_hud(H, danger, feral_state) return //Nullspace @@ -257,15 +226,15 @@ // In the darkness, or "hidden", or in a belly. No need for custom scene-protection checks as it's just an occational infomessage. if(darkish || !isturf(H.loc) || isbelly(H.loc)) // Specific check for if in belly. !isturf should do this, but JUST in case. // If hurt, tell 'em to heal up - if (shock) + if (cause == "shock") to_chat(H,"This place seems safe, secure, hidden, a place to lick your wounds and recover...") //If hungry, nag them to go and find someone or something to eat. - else if(hungry) + else if(cause == "hunger") to_chat(H,"Secure in your hiding place, your hunger still gnaws at you. You need to catch some food...") //If jittery, etc - else if(jittery) + else if(cause == "jittery") to_chat(H,"sneakysneakyyesyesyescleverhidingfindthingsyessssss") //Otherwise, just tell them to keep hiding. @@ -284,16 +253,16 @@ // Someone/something nearby if(nearby.len) var/M = pick(nearby) - if(shock) + if(cause == "shock") to_chat(H,"You're hurt, in danger, exposed, and [M] looks to be a little too close for comfort...") - else if(hungry || jittery) + else to_chat(H,"Every movement, every flick, every sight and sound has your full attention, your hunting instincts on high alert... In fact, [M] looks extremely appetizing...") // Nobody around else - if(hungry) + if(cause == "hunger") to_chat(H,"Confusing sights and sounds and smells surround you - scary and disorienting it may be, but the drive to hunt, to feed, to survive, compels you.") - else if(jittery) + else if(cause == "jittery") to_chat(H,"yesyesyesyesyesyesgetthethingGETTHETHINGfindfoodsfindpreypounceyesyesyes") else to_chat(H,"Confusing sights and sounds and smells surround you, this place is wrong, confusing, frightening. You need to hide, go to ground...") @@ -301,6 +270,37 @@ // HUD update time update_xenochimera_hud(H, danger, feral_state) +/datum/species/xenochimera/proc/go_feral(var/mob/living/carbon/human/H, var/stress, var/cause) + // Going feral due to hunger + if(cause == "hunger") + to_chat(H,"Something in your mind flips, your instincts taking over, no longer able to fully comprehend your surroundings as survival becomes your primary concern - you must feed, survive, there is nothing else. Hunt. Eat. Hide. Repeat.") + log_and_message_admins("has gone feral due to hunger.", H) + + // If they're hurt, chance of snapping. + else if(cause == "shock") + //If the majority of their shock is due to halloss, give them a different message (3x multiplier on check as halloss is 2x - meaning t_s must be at least 3x for other damage sources to be the greater part) + if(3*H.halloss >= H.traumatic_shock) + to_chat(H,"The pain! It stings! Got to get away! Your instincts take over, urging you to flee, to hide, to go to ground, get away from here...") + log_and_message_admins("has gone feral due to halloss.", H) + + //Majority due to other damage sources + else + to_chat(H,"Your fight-or-flight response kicks in, your injuries too much to simply ignore - you need to flee, to hide, survive at all costs - or destroy whatever is threatening you.") + log_and_message_admins("has gone feral due to injury.", H) + + //No hungry or shock, but jittery + else if(cause == "jittery") + to_chat(H,"Suddenly, something flips - everything that moves is... potential prey. A plaything. This is great! Time to hunt!") + log_and_message_admins("has gone feral due to jitteriness.", H) + + else // catch-all just in case something weird happens + to_chat(H,"The stress of your situation is too much for you, and your survival instincts kick in!") + log_and_message_admins("has gone feral for unknown reasons.", H) + //finally, set their feral var + H.feral = stress + if(!H.stat) + H.emote("twitch") + /datum/species/xenochimera/get_race_key() var/datum/species/real = GLOB.all_species[base_species] return real.race_key diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/goose.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/goose.dm index c4f41bd3ba8..840b424994e 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/space/goose.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/goose.dm @@ -47,4 +47,12 @@ add_modifier(/datum/modifier/berserk, 30 SECONDS) /decl/mob_organ_names/goose - hit_zones = list("head", "chest", "left leg", "right leg", "left wing", "right wing", "neck") \ No newline at end of file + hit_zones = list("head", "chest", "left leg", "right leg", "left wing", "right wing", "neck") + +/mob/living/simple_mob/animal/space/goose/white + icon = 'icons/mob/animal_vr.dmi' + icon_state = "whitegoose" + icon_living = "whitegoose" + icon_dead = "whitegoose_dead" + name = "white goose" + desc = "And just when you thought it was a lovely day..." \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/vore.dm b/code/modules/mob/living/simple_mob/subtypes/vore/vore.dm index 035f287d629..48953e15a84 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/vore.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/vore.dm @@ -24,6 +24,7 @@ allowmobvore = client.prefs_vr.allowmobvore permit_healbelly = client.prefs_vr.permit_healbelly noisy = client.prefs_vr.noisy + selective_preference = client.prefs_vr.selective_preference drop_vore = client.prefs_vr.drop_vore stumble_vore = client.prefs_vr.stumble_vore diff --git a/code/modules/organs/robolimbs_custom.dm b/code/modules/organs/robolimbs_custom.dm index 2cd26b7f4b2..96d80669c1a 100644 --- a/code/modules/organs/robolimbs_custom.dm +++ b/code/modules/organs/robolimbs_custom.dm @@ -175,3 +175,31 @@ VS Edit - anyone can select these. */ /obj/item/weapon/disk/limb/dsi_teshari company = "DSI - Teshari" + +/datum/robolimb/dsi_zorren + company = "DSI - Zorren" + desc = "This limb feels soft and fluffy, realistic design and squish. Seems a little mischievous. By Darkside Incorperated." + icon = 'icons/mob/human_races/cyberlimbs/DSIZorren/dsi_zorren.dmi' + blood_color = "#ffe2ff" + lifelike = 1 + unavailable_to_build = 1 + includes_tail = 1 + skin_tone = 1 + suggested_species = "Zorren" + +/obj/item/weapon/disk/limb/dsi_zorren + company = "DSI - Zorren" + +/datum/robolimb/dsi_fennec + company = "DSI - Fennec" + desc = "This limb feels soft and fluffy, realistic design and squish. Seems a little mischievous. By Darkside Incorperated." + icon = 'icons/mob/human_races/cyberlimbs/DSIFennec/dsi_fennec.dmi' + blood_color = "#ffe2ff" + lifelike = 1 + unavailable_to_build = 1 + includes_tail = 1 + skin_tone = 1 + suggested_species = "Fennec" + +/obj/item/weapon/disk/limb/dsi_fennec + company = "DSI - Fennec" diff --git a/code/modules/projectiles/ammunition/ammo_boxes.dm b/code/modules/projectiles/ammunition/ammo_boxes.dm index 566b878c44f..533a27bc4c9 100644 --- a/code/modules/projectiles/ammunition/ammo_boxes.dm +++ b/code/modules/projectiles/ammunition/ammo_boxes.dm @@ -10,7 +10,7 @@ # # Use this format, followed by the caliber. For example, a shotgun's caliber # variable is "12g" as a result. Ergo, a shotgun round's path would have "a12g", -# or a magazine with shotgun shells would be "m12g" instead. To avoid confusion +# or a magazine with shotgun shells would be "m12g" instead. To avoid confusion // Avoid confusion my ass, when ammo is called only shells and suddenly switches to being called some obscure-ass military number # for developers and in-game admins spawning these items, stick to this format. # Likewise, when creating new rounds, the caliber variable should match whatever # the name says. diff --git a/code/modules/tgs/v5/chat_commands.dm b/code/modules/tgs/v5/chat_commands.dm index 60f209cb810..79dbe3b5ce8 100644 --- a/code/modules/tgs/v5/chat_commands.dm +++ b/code/modules/tgs/v5/chat_commands.dm @@ -21,7 +21,7 @@ else active++ - return "Current server status:\n**Web Manifest:**>1,C=23===c?o(2,-24)-o(2,-77):0,N=e<0||0===e&&1/e<0?1:0,b=0;for((e=n(e))!=e||e===Infinity?(u=e!=e?1:0,d=f):(d=r(a(e)/i),e*(s=o(2,-d))<1&&(d--,s*=2),(e+=d+h>=1?C/s:C*o(2,1-h))*s>=2&&(d++,s/=2),d+h>=f?(u=0,d=f):d+h>=1?(u=(e*s-1)*o(2,c),d+=h):(u=e*o(2,h-1)*o(2,c),d=0));c>=8;)m[b++]=255&u,u/=256,c-=8;for(d=d<