The lifeless husk of [src] bursts open, revealing a new, intact copy in the pool of viscera.
") //Bloody hell... - brainloss += 10 //Reviving from dead means you take a lil' brainloss on top of whatever was healed in the revive. - return - else - return //Runtime prevention - else //don't have nutriment to hatch! Or you somehow died in between completing your revive and hitting hatch. - to_chat(src, "Your body was unable to regenerate, what few living cells remain require additional nutrients to complete the process.") - reviving = FALSE // so they can try again when they're given a kickstart + + //Dead when hatching + if(stat == DEAD) + //Check again for nutriment (necessary?) + if(hasnutriment()) + chimera_hatch() + visible_message("The lifeless husk of [src] bursts open, revealing a new, intact copy in the pool of viscera.
") //Bloody hell... return - else if(stat != DEAD) //If they're alive at the time of regenerating. + //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 + reviving = 0 //So they can try again when they're given a kickstart + + //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... - return - else - return //Runtime prevention. /mob/living/carbon/human/proc/chimera_hatch() - nutrition -= nutrition/2 //Cut their nutrition in half. - var/old_nutrition = nutrition //Since the game is being annoying. + verbs -= /mob/living/carbon/human/proc/hatch to_chat(src, "Your new body awakens, bursting free from your old skin.") - var/T = get_turf(src) - new /obj/effect/gibspawner/human/scree(T) - var/braindamage = brainloss/2 //If you have 100 brainloss, it gives you 50. - does_not_breathe = 0 //start breathing again - revive() // I did have special snowflake code, but this is easier. - weakened = 2 //Not going to let you get up immediately. 2 ticks before you get up. Overrides the above 10000 weaken. + + //Modify and record values (half nutrition and braindamage) + var/old_nutrition = nutrition * 0.5 + var/braindamage = (brainloss * 0.5) + 10 //A little damage from the process. + + //I did have special snowflake code, but this is easier. + revive() mutations.Remove(HUSK) nutrition = old_nutrition - brainloss = braindamage //Gives them half their prior brain damage. - update_canmove() + setBrainLoss(braindamage) + + //Drop everything for(var/obj/item/W in src) drop_from_inventory(W) - spawn(3600 SECONDS) //1 hour wait until you can revive. - reviving = FALSE - to_chat(src, "Your body has recovered from the strenuous effort of rebuilding itself.") - verbs -= /mob/living/carbon/human/proc/hatch - return -/obj/effect/gibspawner/human/scree - fleshcolor = "#14AD8B" //Scree blood. + //Unfreeze some things + does_not_breathe = FALSE + update_canmove() + weakened = 2 + + //Visual effects + var/T = get_turf(src) + new /obj/effect/gibspawner/human/xenochimera(T) + + reviving = REVIVING_COOLDOWN + schedule_callback_in(1 HOUR, VARSET_CALLBACK(src, reviving, 0)) + +/obj/effect/gibspawner/human/xenochimera + fleshcolor = "#14AD8B" bloodcolor = "#14AD8B" /mob/living/carbon/human/proc/getlightlevel() //easier than having the same code in like three places @@ -141,7 +151,7 @@ else return 0 /mob/living/carbon/human/proc/handle_feral() - if(handling_hal) return //avoid conflict with actual hallucinations + if(handling_hal) return handling_hal = 1 if(client && feral >= 10) // largely a copy of handle_hallucinations() without the fake attackers. Unlike hallucinations, only fires once - if they're still feral they'll get hit again anyway. 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 56a35acc96..bea2eccbe3 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 @@ -22,7 +22,7 @@ tail = "tail" //Scree's tail. Can be disabled in the vore tab by choosing "hide species specific tail sprite" icobase_tail = 1 inherent_verbs = list( - /mob/living/carbon/human/proc/begin_reconstitute_form, + /mob/living/carbon/human/proc/reconstitute_form, /mob/living/carbon/human/proc/sonar_ping, /mob/living/carbon/human/proc/succubus_drain, /mob/living/carbon/human/proc/succubus_drain_finalize, @@ -40,9 +40,9 @@ Most, if not all chimeras possess the ability to undergo some type of regeneration process, at the cost of energy." hazard_low_pressure = -1 //Prevents them from dying normally in space. Special code handled below. - cold_level_1 = -5000 // All cold debuffs are handled below in handle_environment_special - cold_level_2 = -5000 - cold_level_3 = -5000 + cold_level_1 = -1 // All cold debuffs are handled below in handle_environment_special + cold_level_2 = -1 + cold_level_3 = -1 //primitive_form = "Farwa" @@ -56,142 +56,198 @@ /datum/species/xenochimera/handle_environment_special(var/mob/living/carbon/human/H) - if(H.stat == 2) // If they're dead they won't think about being all feral and won't need all the code below. - return + //If they're KO'd/dead, they're probably not thinking a lot about much of anything. + if(!H.stat) + handle_feralness(H) -//handle feral triggers - - if(H.nutrition <= 200||H.traumatic_shock > min(60, H.nutrition/10)) // Stress factors are in play - // If they're hungry, give nag messages. - if (!istype(H.loc, /mob)) // if they're in a mob, skip the hunger stuff so it doesn't mess with drain/absorption modes. - if(H.nutrition < 200 && H.nutrition > 150) - if(prob(0.5)) //A bit of an issue, not too bad. - H << "You feel rather hungry. It might be a good idea to find some some food..." - - else if(H.nutrition <= 150 && H.nutrition > 100) - if(prob(0.5)) //Getting closer, should probably eat some food about now... - 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..." - - else if(H.nutrition <= 100) //Should've eaten sooner! - if(H.feral == 0) - 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) - H.feral += 5 //just put them over the threshold by a decent amount for the first chunk. - if(H.stat == CONSCIOUS) - H.emote("twitch") - if(H.feral + H.nutrition < 150) //Feralness increases while this hungry, capped at 50-150 depending on hunger. - H.feral += 1 - - // If they're hurt, chance of snapping. Not if they're straight-up KO'd though. - if (H.stat == CONSCIOUS && H.traumatic_shock >=min(60, H.nutrition/10)) //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. - if (2.5*H.halloss >= H.traumatic_shock) //If the majority of their shock is due to halloss, greater chance of snapping. - if(prob(min(10,(0.2 * H.traumatic_shock)))) - if(H.feral == 0) - 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) - H.feral = max(H.feral, H.halloss) //if already more feral than their halloss justifies, don't increase it. - H.emote("twitch") - else if(prob(min(10,(0.1 * H.traumatic_shock)))) - H.emote("twitch") - if(H.feral == 0) - 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." - H.feral = 2*H.traumatic_shock //Make 'em snap. - log_and_message_admins("has gone feral due to injury.", H) - else - H.feral = max(H.feral, H.traumatic_shock * 2) //keep feralness up to match the current injury state. - - else if (H.jitteriness >= 100) //No stress factors, but there's coffee. Keeps them mildly feral while they're all jittery. - if(H.feral == 0) - 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) - if(H.stat == CONSCIOUS) - H.emote("twitch") - H.feral = max(H.feral, H.jitteriness-100) //they'll be twitchy and pouncy while they're under the influence, and feralness won't wear off until they're calm. + //While regenerating + if(H.reviving && H.reviving != REVIVING_COOLDOWN) + H.weakened = 5 + H.canmove = 0 + H.does_not_breathe = TRUE + //Cold/pressure effects when not regenerating else - if (H.feral > 0) //still feral, but all stress factors are gone. Calm them down. - H.feral -= 1 - if (H.feral <=0) //check if they're unferalled - H.feral = 0 - H << "Your thoughts start clearing, your feral urges having passed - for the time being, at least." - log_and_message_admins("is no longer feral.", H) + var/datum/gas_mixture/environment = H.loc.return_air() + var/pressure2 = environment.return_pressure() + var/adjusted_pressure2 = H.calculate_affecting_pressure(pressure2) -// handle what happens while feral + //Very low pressure damage + if(adjusted_pressure2 <= 20) + H.take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure") - if(H.feral > 0) //do the following if feral, otherwise no effects. - var/light_amount = H.getlightlevel() //how much light there is in the place + //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 + var/temp_diff = body_temperature - H.bodytemperature + if(temp_diff >= 50) + 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) - H.shock_stage = max(H.shock_stage-(H.feral/20), 0) //if they lose enough health to hit softcrit, handle_shock() will keep resetting this. Otherwise, pissed off critters will lose shock faster than they gain it. - if(light_amount <= 0.5) // in the darkness. No need for custom scene-protection checks as it's just an occational infomessage. - if(prob(2)) //periodic nagmessages just to remind 'em they're still feral - if (H.traumatic_shock >=min(60, H.nutrition/10)) // if hurt, tell 'em to heal up - H << " This place seems safe, secure, hidden, a place to lick your wounds and recover..." - else if(H.nutrition <= 100) //If hungry, nag them to go and find someone or something to eat. - H << " Secure in your hiding place, your hunger still gnaws at you. You need to catch some food..." - else if(H.jitteriness >= 100) - H << " sneakysneakyyesyesyescleverhidingfindthingsyessssss" - else //otherwise, just tell them to keep hiding. - H << " ...safe..." - else // must be in a lit area - var/list/nearby = oviewers(H) - if (nearby.len) // someone's nearby - if(prob(1)) // 1 in 100 chance of doing something so as not to interrupt scenes - var/mob/M = pick(nearby) - if (H.traumatic_shock >=min(60, H.nutrition/10)) //tell 'em to be wary of a random person - H << " You're hurt, in danger, exposed, and [M] looks to be a little too close for comfort..." - else if(H.nutrition <= 250 || H.jitteriness > 0) //tell them a random person in view looks like food. It CAN happen when you're not hungry enough to be feral, especially if coffee is involved. - 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..." - if(H.stat == CONSCIOUS) +/datum/species/xenochimera/proc/handle_feralness(var/mob/living/carbon/human/H) + + //Low-ish nutrition has messages and eventually feral + var/hungry = H.nutrition <= 200 + + //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) + + //Caffeinated xenochimera can become feral and have special messages + var/jittery = H.jitteriness >= 100 + + //To reduce distant object references + var/feral = H.feral + +//Handle feral triggers and pre-feral messages + if(!feral && (hungry || shock || jittery)) + + // If they're hungry, give nag messages (when not bellied) + if(H.nutrition >= 100 && prob(0.5) && !ismob(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...") + if(100 to 150) + 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...") + + // Going feral due to hunger + else if(H.nutrition < 100) + 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 + 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 + 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 + 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 + log_and_message_admins("has gone feral due to jitteriness.", H) + if(!H.stat) + H.emote("twitch") + +// Handle being feral + if(feral) + + //Shock due to mostly halloss. More feral. + if(shock && 2.5*H.halloss >= H.traumatic_shock) + feral = max(feral, H.halloss) + + //Shock due to mostly injury. More feral. + else if(shock) + feral = max(feral, H.traumatic_shock * 2) + + //Still jittery? More feral. + if(jittery) + feral = max(feral, H.jitteriness-100) + + //Still hungry? More feral. + if(H.feral + H.nutrition < 150) + feral++ + else + feral = max(0,--feral) + + //Set our real mob's var to our temp var + H.feral = feral + + //Did we just finish being feral? + if(!feral) + to_chat(H,"Your thoughts start clearing, your feral urges having passed - for the time being, at least.") + log_and_message_admins("is no longer feral.", H) + return + + //If they lose enough health to hit softcrit, handle_shock() will keep resetting this. Otherwise, pissed off critters will lose shock faster than they gain it. + H.shock_stage = max(H.shock_stage-(feral/20), 0) + + //Handle light/dark areas + var/turf/T = get_turf(H) + if(!T) + return //Nullspace + var/darkish = T.get_lumcount() <= 0.1 + + //Don't bother doing heavy lifting if we weren't going to give emotes anyway. + if(!prob(1)) + + //This is basically the 'lite' version of the below block. + var/list/nearby = H.living_mobs(world.view) + + //Not in the dark. + if(!darkish) + + //Always handle feral if nobody's around and not in the dark. + if(!nearby.len) H.handle_feral() - else // nobody around - H.handle_feral() - if(prob(2)) //periodic nagmessages - if(H.nutrition <= 100) //If hungry, nag them to go and find someone or something to eat. - 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." - if(H.stat == CONSCIOUS) - H.emote("twitch") - else if(H.jitteriness >= 100) - H << " yesyesyesyesyesyesgetthethingGETTHETHINGfindfoodsfindpreypounceyesyesyes" - if(H.stat == CONSCIOUS) - H.emote("twitch") - else //otherwise, just tell them to hide. - H << " Confusing sights and sounds and smells surround you, this place is wrong, confusing, frightening. You need to hide, go to ground..." - if(H.stat == CONSCIOUS) - H.emote("twitch") + //Rarely handle feral if someone is around + else if(prob(1)) + H.handle_feral() -////////////////////////////////////////////////////////////////////////////////////////// -///////////WIP CODE TO MAKE XENOCHIMERAS NOT DIE IN SPACE WHILE REGENNING BELOW/////////// //I put WIP, but what I really meant to put was "Finished" -////////////////////////////////////////////////////////////////////////////////////////// + //And bail + return - var/datum/gas_mixture/environment = H.loc.return_air() - var/pressure2 = environment.return_pressure() - var/adjusted_pressure2 = H.calculate_affecting_pressure(pressure2) + // In the darkness. No need for custom scene-protection checks as it's just an occational infomessage. + if(darkish) + // If hurt, tell 'em to heal up + if (shock) + to_chat(H,"This place seems safe, secure, hidden, a place to lick your wounds and recover...") - if(adjusted_pressure2 <= 20 && H.does_not_breathe) //If they're in a enviroment with no pressure and are not breathing (See: regenerating), don't kill them. - //This is just to prevent them from taking damage if they're in stasis. + //If hungry, nag them to go and find someone or something to eat. + else if(hungry) + to_chat(H,"Secure in your hiding place, your hunger still gnaws at you. You need to catch some food...") - else if(adjusted_pressure2 <= 20) //If they're in an enviroment with no pressure and are NOT in stasis, damage them. - H.take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure") + //If jittery, etc + else if(jittery) + to_chat(H,"sneakysneakyyesyesyescleverhidingfindthingsyessssss") - if(H.bodytemperature <= 260 && H.does_not_breathe) //If they're regenerating, don't give them them the negative cold effects - //This is just here to prevent them from getting cold effects + //Otherwise, just tell them to keep hiding. + else + to_chat(H,"...safe...") + + // NOT in the darkness + else + + //Twitch twitch + if(!H.stat) + H.emote("twitch") + + var/list/nearby = H.living_mobs(world.view) + + // Someone/something nearby + if(nearby.len) + var/M = pick(nearby) + if(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) + 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) + 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) + 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...") - else if(H.bodytemperature <= 260) //If they're not in stasis and are cold. Don't really have to add in an exception to cryo cells, as the effects aren't anything /too/ horrible. - var/coldshock = 0 - if(H.bodytemperature <= 260 && H.bodytemperature >= 200) //Chilly. - coldshock = 4 //This will begin to knock them out until they run out of oxygen and suffocate or until someone finds them. - H.eye_blurry = 5 //Blurry vision in the cold. - if(H.bodytemperature <= 199 && H.bodytemperature >= 100) //Extremely cold. Even in somewhere like the server room it takes a while for bodytemp to drop this low. - coldshock = 8 - H.eye_blurry = 5 - if(H.bodytemperature <= 99) //Insanely cold. - coldshock = 16 - H.eye_blurry = 5 - H.shock_stage = min(H.shock_stage + coldshock, 160) //cold hurts and gives them pain messages, eventually weakening and paralysing, but doesn't damage or trigger feral. - return /datum/species/xenochimera/proc/produceCopy(var/datum/species/to_copy,var/list/traits,var/mob/living/carbon/human/H) ASSERT(to_copy) @@ -272,10 +328,10 @@ Before they were found they built great cities out of their silk, being united and subjugated in warring factions under great Star Queens \ Who forced the working class to build huge, towering cities to attempt to reach the stars, which they worship as gems of great spiritual and magical significance." - hazard_low_pressure = -1 //Prevents them from dying normally in space. Special code handled below. - cold_level_1 = -5000 // All cold debuffs are handled below in handle_environment_special - cold_level_2 = -5000 - cold_level_3 = -5000 + hazard_low_pressure = 20 //Prevents them from dying normally in space. Special code handled below. + cold_level_1 = -1 // All cold debuffs are handled below in handle_environment_special + cold_level_2 = -1 + cold_level_3 = -1 //primitive_form = "Monkey" //I dunno. Replace this in the future. @@ -288,16 +344,9 @@ blood_color = "#0952EF" //Spiders have blue blood. /datum/species/spider/handle_environment_special(var/mob/living/carbon/human/H) - if(H.stat == 2) // If they're dead they won't need anything. + if(H.stat == DEAD) // If they're dead they won't need anything. return - var/datum/gas_mixture/environment = H.loc.return_air() - var/pressure2 = environment.return_pressure() - var/adjusted_pressure2 = H.calculate_affecting_pressure(pressure2) - - if(adjusted_pressure2 <= 20) //If they're in an enviroment with no pressure and are NOT in stasis, like a stasis bodybag, damage them. - H.take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure") - if(H.bodytemperature <= 260) //If they're really cold, they go into stasis. var/coldshock = 0 if(H.bodytemperature <= 260 && H.bodytemperature >= 200) //Chilly. diff --git a/code/modules/reagents/Chemistry-Recipes_vr.dm b/code/modules/reagents/Chemistry-Recipes_vr.dm index fe8731a0a1..684c0ee587 100644 --- a/code/modules/reagents/Chemistry-Recipes_vr.dm +++ b/code/modules/reagents/Chemistry-Recipes_vr.dm @@ -56,7 +56,7 @@ /datum/chemical_reaction/xenolazarus/on_reaction(var/datum/reagents/holder, var/created_volume) //literally all this does is mash the regenerate button if(ishuman(holder.my_atom)) var/mob/living/carbon/human/H = holder.my_atom - if(H.stat == DEAD && (/mob/living/carbon/human/proc/begin_reconstitute_form in H.verbs)) //no magical regen for non-regenners, and can't force the reaction on live ones + if(H.stat == DEAD && (/mob/living/carbon/human/proc/reconstitute_form in H.verbs)) //no magical regen for non-regenners, and can't force the reaction on live ones if(H.hasnutriment()) // make sure it actually has the conditions to revive if(!H.reviving) // if it's not reviving, start doing so H.visible_message("[H] shudders briefly, then relaxes, faint movements stirring within.")