diff --git a/code/_onclick/hud/spell_screen_objects.dm b/code/_onclick/hud/spell_screen_objects.dm
index ecc3ca077e5..8f702cd4124 100644
--- a/code/_onclick/hud/spell_screen_objects.dm
+++ b/code/_onclick/hud/spell_screen_objects.dm
@@ -218,3 +218,12 @@
spell.perform(usr)
update_charge(1)
+
+
+
+//Xenochimera, literally just different icons
+/obj/screen/movable/spell_master/chimera
+ name = "Chimera Abilities"
+ icon_state = "cult_spell_ready"
+ open_state = "genetics_open"
+ closed_state = "genetics_closed"
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index f45f31eb34a..7a771e7b231 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -177,6 +177,7 @@
var/has_glowing_eyes = 0 // Whether the eyes are shown above all lighting
var/water_movement = 0 // How much faster or slower the species is in water
var/snow_movement = 0 // How much faster or slower the species is on snow
+ var/infect_wounds = 0 // Whether the species can infect wounds, only works with claws / bites
var/item_slowdown_mod = 1 // How affected by item slowdown the species is.
@@ -419,7 +420,6 @@ GLOBAL_LIST_INIT(species_oxygen_tank_by_gas, list(
for(var/spell_to_add in inherent_spells)
var/spell/S = new spell_to_add(H)
H.add_spell(S)
- return
/datum/species/proc/remove_inherent_spells(var/mob/living/carbon/human/H)
H.spellremove()
diff --git a/code/modules/mob/living/carbon/human/species/station/station_special.dm b/code/modules/mob/living/carbon/human/species/station/station_special.dm
index 424fe34efc5..e7ec0c509df 100644
--- a/code/modules/mob/living/carbon/human/species/station/station_special.dm
+++ b/code/modules/mob/living/carbon/human/species/station/station_special.dm
@@ -26,7 +26,6 @@
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/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,7 +39,7 @@
/mob/living/proc/eat_trash,
/mob/living/proc/glow_toggle,
/mob/living/proc/glow_color,
- /mob/living/carbon/human/proc/lick_wounds ,
+ /mob/living/carbon/human/proc/lick_wounds,
/mob/living/carbon/human/proc/resp_biomorph,
/mob/living/carbon/human/proc/biothermic_adapt,
/mob/living/carbon/human/proc/atmos_biomorph,
@@ -53,18 +52,24 @@
/mob/living/carbon/human/proc/shapeshifter_select_wings,
/mob/living/carbon/human/proc/shapeshifter_select_tail,
/mob/living/carbon/human/proc/shapeshifter_select_ears,
- /mob/living/carbon/human/proc/regenerate,
- /mob/living/carbon/human/proc/commune) //Xenochimera get all the special verbs since they can't select traits.
+ /mob/living/carbon/human/proc/shapeshifter_select_shape,
+ /mob/living/carbon/human/proc/commune
+ ) //Xenochimera get all the special verbs since they can't select traits.
inherent_spells = list(
/spell/targeted/chimera/thermal_sight,
- /spell/targeted/chimera/voice_mimic
+ /spell/targeted/chimera/voice_mimic,
+ /spell/targeted/chimera/regenerate,
+ /spell/targeted/chimera/hatch,
+ /spell/targeted/chimera/no_breathe
)
- var/feral_spells = list(
+ var/list/feral_spells = list(
/spell/aoe_turf/dissonant_shriek
)
+ var/list/removable_spells = list()
+
var/has_feral_spells = FALSE
virus_immune = 1 // They practically ARE one.
min_age = 18
@@ -112,7 +117,7 @@
"Akula","Nevrean","Highlander Zorren",
"Flatland Zorren", "Vulpkanin", "Vasilissan",
"Rapala", "Neaera", "Stok", "Farwa", "Sobaka",
- "Wolpin", "Saru", "Sparra")
+ "Wolpin", "Saru", "Sparra", "Vox")
//primitive_form = "Farwa"
@@ -133,6 +138,7 @@
)
heal_rate = 0.5
+ infect_wounds = 1
flesh_color = "#AFA59E"
base_color = "#333333"
blood_color = "#14AD8B"
@@ -168,19 +174,47 @@
H.eye_blurry = max(5,H.eye_blurry)
..()
+/datum/species/shapeshifter/xenochimera/add_inherent_spells(var/mob/living/carbon/human/H)
+ var/master_type = /obj/screen/movable/spell_master/chimera
+ var/obj/screen/movable/spell_master/chimera/new_spell_master = new master_type
+
+ if(!H.spell_masters)
+ H.spell_masters = list()
+
+ if(H.client)
+ H.client.screen += new_spell_master
+ new_spell_master.spell_holder = H
+ H.spell_masters.Add(new_spell_master)
+
+ for(var/spell_to_add in inherent_spells)
+ var/spell/S = new spell_to_add(H)
+ H.add_spell(S, "cult", master_type)
+
/datum/species/shapeshifter/xenochimera/proc/add_feral_spells(var/mob/living/carbon/human/H)
- if(!has_feral_spells && LAZYLEN(feral_spells) > 0)
- has_feral_spells = TRUE
- for(var/spell_to_add in feral_spells)
- var/spell/S = new spell_to_add(H)
- H.add_spell(S)
+ if(!has_feral_spells)
+ var/check = FALSE
+ var/master_type = /obj/screen/movable/spell_master/chimera
+ for(var/spell/S as anything in feral_spells)
+ var/spell/spell_to_add = new S(H)
+ check = H.add_spell(spell_to_add, "cult", master_type)
+ removable_spells += spell_to_add
+ if(check)
+ has_feral_spells = TRUE
+ else
+ return
else
return
/datum/species/shapeshifter/xenochimera/proc/remove_feral_spells(var/mob/living/carbon/human/H)
- H.spellremove() //This removes ALL spells
+ for(var/spell/S as anything in removable_spells)
+ S.remove_self(H)
+ removable_spells.Cut()
has_feral_spells = FALSE
- addtimer(CALLBACK(src, .proc/add_inherent_spells,H), 1 SECOND, TIMER_UNIQUE) //This doesn't work well without a delay, crappy workaround. Resets all cooldowns, too.
+
+/datum/species/shapeshifter/xenochimera/handle_post_spawn(mob/living/carbon/human/H)
+ ..()
+ for(var/spell/S as anything in feral_spells)
+ S = new S(H)
/datum/species/shapeshifter/xenochimera/proc/handle_feralness(var/mob/living/carbon/human/H)
@@ -452,7 +486,7 @@
/mob/living/carbon/human/proc/resp_biomorph(mob/living/carbon/human/target in view(1))
set name = "Respiratory Biomorph"
set desc = "Changes the gases we need to breathe."
- set category = "Abilities"
+ set category = "Chimera"
var/list/gas_choices = list(
"oxygen" = /datum/gas/oxygen,
@@ -505,7 +539,7 @@
/mob/living/carbon/human/proc/biothermic_adapt(mob/living/carbon/human/target in view(1))
set name = "Biothermic Adaptation"
set desc = "Changes our core body temperature."
- set category = "Abilities"
+ set category = "Chimera"
var/list/temperature_options = list(
"warm-blooded",
@@ -599,7 +633,7 @@
/mob/living/carbon/human/proc/atmos_biomorph(mob/living/carbon/human/target in view(1))
set name = "Atmospheric Biomorph"
set desc = "Changes our sensitivity to atmospheric pressure."
- set category = "Abilities"
+ set category = "Chimera"
var/list/pressure_options = list(
@@ -649,7 +683,7 @@
/mob/living/carbon/human/proc/vocal_biomorph()
set name = "Vocalization Biomorph"
set desc = "Changes our speech pattern."
- set category = "Abilities"
+ set category = "Chimera"
var/vocal_biomorph = input(src, "How should we adjust our speech?") as null|anything in list("common", "unathi", "tajaran")
if(!vocal_biomorph)
diff --git a/code/modules/mob/living/carbon/human/unarmed_attack.dm b/code/modules/mob/living/carbon/human/unarmed_attack.dm
index de98dab237b..ee47dc6abd4 100644
--- a/code/modules/mob/living/carbon/human/unarmed_attack.dm
+++ b/code/modules/mob/living/carbon/human/unarmed_attack.dm
@@ -10,6 +10,7 @@ var/global/list/sparring_attack_cache = list()
var/shredding = 0 // Calls the old attack_alien() behavior on objects/mobs when on harm intent.
var/sharp = 0
var/edge = 0
+ var/infected_wound_probability = 10
var/damage_type = BRUTE
var/sparring_variant_type = /datum/unarmed_attack/light_strike
@@ -89,6 +90,30 @@ var/global/list/sparring_attack_cache = list()
target.visible_message("[target] has been weakened!")
target.apply_effect(3, WEAKEN, armour)
+ if(user.species.infect_wounds) //Creates a pre-damaged, pre-infected wound. As nasty as this code.
+ if(prob(infected_wound_probability))
+ var/obj/item/organ/external/affecting = target.get_organ(zone)
+ var/attack_message
+ var/datum/wound/W
+ if(edge)
+ W = new /datum/wound/cut/small(5)
+ W.force_infect()
+ attack_message = "leaves behind infested residue in [target]!"
+ else
+ W = new /datum/wound/bruise(5)
+ W.force_infect()
+ attack_message = "scratches and pummels, their infested fluids mixing with [target]!"
+ if(LAZYLEN(affecting.wounds))
+ for(var/datum/wound/other in affecting.wounds)
+ if(other.can_merge(W))
+ other.merge_wound(W)
+ W = null
+ break
+ if(W)
+ affecting.wounds += W
+
+ target.visible_message("[user] [attack_message]")
+
/datum/unarmed_attack/proc/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/obj/item/organ/external/affecting = target.get_organ(zone)
user.visible_message("[user] [pick(attack_verb)] [target] in the [affecting.name]!")
diff --git a/code/modules/organs/wound.dm b/code/modules/organs/wound.dm
index dd7f5dcf890..cc91debbfff 100644
--- a/code/modules/organs/wound.dm
+++ b/code/modules/organs/wound.dm
@@ -19,11 +19,11 @@
var/min_damage = 0
// is the wound bandaged?
- var/bandaged = 0
+ var/bandaged = FALSE
// Similar to bandaged, but works differently
- var/clamped = 0
+ var/clamped = FALSE
// is the wound salved?
- var/salved = 0
+ var/salved = FALSE
// is the wound disinfected?
var/disinfected = 0
var/created = 0
@@ -37,7 +37,7 @@
// stages such as "cut", "deep cut", etc.
var/list/stages
// internal wounds can only be fixed through surgery
- var/internal = 0
+ var/internal = FALSE
// maximum stage at which bleeding should still happen. Beyond this stage bleeding is prevented.
var/max_bleeding_stage = 0
// one of CUT, PIERCE, BRUISE, BURN
@@ -46,7 +46,8 @@
// the maximum amount of damage that this wound can have and still autoheal
var/autoheal_cutoff = 10
-
+ // whether this wound starts infected regardless of damage level
+ var/forced_infected = FALSE
// helper lists
@@ -119,19 +120,29 @@
src.germ_level = max(src.germ_level, other.germ_level)
src.created = max(src.created, other.created) //take the newer created time
+ //forces an infection, and bleeding regardless of damage or stage
+ proc/force_infect()
+ bleed_threshold = 4 //Will always start bleeding, making the infection worse if untreated
+ forced_infected = TRUE
+ germ_level = INFECTION_LEVEL_ONE + 1
// checks if wound is considered open for external infections
// untreated cuts (and bleeding bruises) and burns are possibly infectable, chance higher if wound is bigger
proc/infection_check()
- if (damage < 10) //small cuts, tiny bruises, and moderate burns shouldn't be infectable.
- return 0
- if (is_treated() && damage < 25) //anything less than a flesh wound (or equivalent) isn't infectable if treated properly
- return 0
if (disinfected)
- germ_level = 0 //reset this, just in case
- return 0
-
+ if(germ_level > INFECTION_LEVEL_ONE)
+ germ_level = 0 //reset this, just in case
+ forced_infected = FALSE
+ return FALSE
+ if (damage < 10 && !forced_infected) //small cuts, tiny bruises, and moderate burns shouldn't be infectable.
+ return FALSE
+ if (is_treated() && damage < 25) //anything less than a flesh wound (or equivalent) isn't infectable if treated properly
+ return FALSE
if (damage_type == BRUISE && !bleeding()) //bruises only infectable if bleeding
- return 0
+ return FALSE
+
+
+ if(forced_infected) //This wound is forced to be infected, circumventing damage requirements, check after making sure it's not bleeding and isn't disinfected
+ return TRUE
var/dam_coef = round(damage/10)
switch (damage_type)
@@ -142,7 +153,7 @@
if (CUT)
return prob(dam_coef*20)
- return 0
+ return FALSE
proc/bandage()
bandaged = 1
@@ -295,7 +306,7 @@
max_bleeding_stage = 3
stages = list("big gaping wound" = 60, "healing gaping wound" = 40, "large blood soaked clot" = 25, "large angry scar" = 10, "large straight scar" = 0)
-datum/wound/cut/massive
+/datum/wound/cut/massive
max_bleeding_stage = 3
stages = list("massive wound" = 70, "massive healing wound" = 50, "massive blood soaked clot" = 25, "massive angry scar" = 10, "massive jagged scar" = 0)
@@ -365,7 +376,7 @@ datum/wound/puncture/massive
/** INTERNAL BLEEDING **/
/datum/wound/internal_bleeding
- internal = 1
+ internal = TRUE
stages = list("severed artery" = 30, "cut artery" = 20, "damaged artery" = 10, "bruised artery" = 5)
autoheal_cutoff = 5
max_bleeding_stage = 4 //all stages bleed. It's called internal bleeding after all.
@@ -399,4 +410,4 @@ datum/wound/puncture/massive
..(damage_amt)
/datum/wound/lost_limb/can_merge(var/datum/wound/other)
- return 0 //cannot be merged
+ return FALSE //cannot be merged
diff --git a/code/modules/spells/spell_code.dm b/code/modules/spells/spell_code.dm
index 31397c6cd0d..4ab16b6df24 100644
--- a/code/modules/spells/spell_code.dm
+++ b/code/modules/spells/spell_code.dm
@@ -340,3 +340,6 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
if(!user || (!(spell_flags & (STATALLOWED|GHOSTCAST)) && user.stat != originalstat) || !(user.loc == Location))
return 0
return 1
+
+/spell/proc/remove_self(mob/user = usr)
+ user.remove_spell(src)
diff --git a/code/modules/spells/spells.dm b/code/modules/spells/spells.dm
index f98eba16786..850e90ca0e4 100644
--- a/code/modules/spells/spells.dm
+++ b/code/modules/spells/spells.dm
@@ -36,7 +36,6 @@
/mob/proc/add_spell(var/spell/spell_to_add, var/spell_base = "wiz_spell_ready", var/master_type = /obj/screen/movable/spell_master)
if(!spell_masters)
spell_masters = list()
-
if(spell_masters.len)
for(var/obj/screen/movable/spell_master/spell_master in spell_masters)
if(spell_master.type == master_type)
diff --git a/code/modules/spells/targeted/chimera_spells.dm b/code/modules/spells/targeted/chimera_spells.dm
index ff4cbf0e1ec..79b34831105 100644
--- a/code/modules/spells/targeted/chimera_spells.dm
+++ b/code/modules/spells/targeted/chimera_spells.dm
@@ -15,19 +15,24 @@
duration = 0
hud_state = "wiz_jaunt"
+ override_base = "cult"
var/nutrition_cost_minimum = 50
var/nutrition_cost_proportional = 20 //percentage of nutriment it should cost if it's higher than the minimum
/spell/targeted/chimera/cast(list/targets, mob/user)
if(ishuman(user))
var/mob/living/carbon/human/H = user
- var/nut = H.nutrition / nutrition_cost_proportional
+ var/nut = (H.nutrition * nutrition_cost_proportional) / 100
var/final_cost
if(nut > nutrition_cost_minimum)
final_cost = nut
else
final_cost = nutrition_cost_minimum
- H.nutrition -= final_cost
+
+ if((H.nutrition - final_cost) >= 0)
+ H.nutrition -= final_cost
+ else
+ H.nutrition = 0 //We're already super starved, and feral, so cast it for free, you're likely using it to get food at this point.
else
return
@@ -45,7 +50,7 @@
invocation_type = SpI_NONE
charge_max = 35 SECONDS
duration = 30 SECONDS
- nutrition_cost_minimum = 100
+ nutrition_cost_minimum = 15 //The hungrier you get the less it will cost
nutrition_cost_proportional = 10
var/active = FALSE
@@ -71,7 +76,7 @@
///////////////
//Voice Mimic//
///////////////
-
+//It's a toggle, but doesn't cost nutriment to be toggled off
/spell/targeted/chimera/voice_mimic
name = "Voice Mimicry"
desc = "We shape our throat and tongue to imitate a person, or a sound. This ability is a toggle."
@@ -80,10 +85,10 @@
hud_state = "ling_mimic_voice"
invocation = "none"
invocation_type = SpI_NONE
- charge_max = 10 SECONDS
+ charge_max = 5 SECONDS
duration = 0
- nutrition_cost_minimum = 100
- nutrition_cost_proportional = 15
+ nutrition_cost_minimum = 25
+ nutrition_cost_proportional = 5
var/active = FALSE
/spell/targeted/chimera/voice_mimic/cast(list/targets, mob/user = usr)
@@ -98,7 +103,7 @@
to_chat(user, "We shift and morph our tongues, ready to reverberate as: [mimic_voice].")
H.SetSpecialVoice(mimic_voice)
active = TRUE
- ..()
+ ..() //Processes nutriment cost
else
to_chat(user, "We return our voice to our normal identity.")
H.UnsetSpecialVoice()
@@ -107,6 +112,211 @@
return
+////////////////
+//Regeneration//
+////////////////
+//Huge cooldown, huge cost, but will actually heal most of your issues.
+
+/spell/targeted/chimera/regenerate
+ name = "Regeneration"
+ desc = "We shed our skin, purging it of damage, regrowing limbs."
+
+ spell_flags = INCLUDEUSER
+ hud_state = "ling_fleshmend"
+ invocation = "none"
+ invocation_type = SpI_NONE
+ charge_max = 10 MINUTES
+ duration = 0
+ nutrition_cost_minimum = 500
+ nutrition_cost_proportional = 75
+ var/healing_amount = 30
+ var/delay = 2 MINUTES
+
+
+/spell/targeted/chimera/regenerate/cast_check(skipcharge = 0,mob/user = usr)
+ if(..())
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ if((nutrition_cost_minimum > H.nutrition) || nutrition_cost_minimum > ((H.nutrition * nutrition_cost_proportional) / 100) )
+ to_chat(H,"We don't have enough nutriment. This ability is costly...")
+ return FALSE
+ else return TRUE
+
+/spell/targeted/chimera/regenerate/cast(list/targets, mob/user = usr)
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ if(do_after(H, delay, null, FALSE, TRUE, INCAPACITATION_DISABLED))
+ H.restore_blood()
+ H.species.create_organs(H)
+ H.restore_all_organs()
+ H.adjustBruteLoss(-healing_amount)
+ H.adjustFireLoss(-healing_amount)
+ H.adjustOxyLoss(-healing_amount)
+ H.adjustCloneLoss(-healing_amount)
+ H.adjustBrainLoss(-healing_amount)
+ H.blinded = 0
+ H.SetBlinded(0)
+ H.eye_blurry = 0
+ H.ear_deaf = 0
+ H.ear_damage = 0
+
+ H.regenerate_icons()
+
+ playsound(H, 'sound/effects/blobattack.ogg', 30, 1)
+ var/T = get_turf(src)
+ new /obj/effect/gibspawner/human(T, H.dna,H.dna.blood_color,H.dna.blood_color)
+ H.visible_message("With a sickening squish, [src] reforms their whole body, casting their old parts on the floor!",
+ "We reform our body. We are whole once more.",
+ "You hear organic matter ripping and tearing!")
+ ..()
+ else
+ to_chat(user,"We were interrupted!")
+ charge_counter = 9.8 MINUTES
+
+
+////////////////
+//Revive spell//
+////////////////
+//Will incapacitate you for 10 minutes, and then you can revive.
+/spell/targeted/chimera/hatch
+ name = "Hatch Stasis"
+ desc = "We attempt to grow an entirely new body from scratch, or death."
+
+ spell_flags = INCLUDEUSER | GHOSTCAST
+ hud_state = "ling_regenerative_stasis"
+ invocation = "none"
+ invocation_type = SpI_NONE
+ charge_max = 60 MINUTES
+ duration = 0 SECONDS
+ nutrition_cost_minimum = 1
+ nutrition_cost_proportional = 1
+
+
+/spell/targeted/chimera/hatch/cast_check(skipcharge, mob/user = usr)
+ if(..())
+ if(!ishuman(user))
+ to_chat(user,"Non-humans can't use this!")
+ return FALSE
+
+ var/confirmation = alert("You will begin a lengthy process of around ten minutes you cannot cancel- Is this what you want?","Hatching Prompt","Yes", "No")
+ if(confirmation != "Yes")
+ to_chat(user, " Hatching cancelled. ")
+ return FALSE
+ else return TRUE
+
+/spell/targeted/chimera/hatch/cast(list/targets, mob/user = usr)
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ if(H.stat == DEAD)
+ H.visible_message(" [H] lays eerily still. Something about them seems off, even when dead.","We begin to gather up whatever is left to begin regrowth.")
+ else
+ H.visible_message(" [H] suddenly collapses, seizing up and going eerily still. ", "We begin the regrowth process to start anew.")
+ H.SetParalysis(8000) //admin style self-stun
+
+ //These are only messages to give the player and everyone around them an idea of which stage they're at
+ //visible_message doesn't seem to relay selfmessages if you're paralysed, so we use to_chat
+ addtimer(CALLBACK(H, /atom/.proc/visible_message," [H]'s skin begins to ripple and move, as if something was crawling underneath."), 4 MINUTES)
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat,H,"We begin to recycle the dead tissue."),4 MINUTES)
+
+ addtimer(CALLBACK(H, /atom/.proc/visible_message," [H]'s body begins to lose its shape, skin sloughing off and melting, losing form and composure.","There is little left. We will soon be ready."), 8 SECONDS)
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat,H,"There is little left. We will soon be ready."), 8 MINUTES)
+
+ addtimer(CALLBACK(src, .proc/add_pop,H,), 10 MINUTES)
+
+/spell/targeted/chimera/hatch/proc/add_pop(mob/user = usr)
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ H.visible_message(" [H] looks ready to burst!")
+ to_chat(H,"We are ready.")
+ var/spell/targeted/chimera/hatch_pop/S = new /spell/targeted/chimera/hatch_pop(H)
+ var/master_type = /obj/screen/movable/spell_master/chimera
+ H.add_spell(S, "cult", master_type)
+
+
+///////////////////////
+//Actual Revive Spell//
+///////////////////////
+//Not to be used normally. Given by the 'hatch' spell
+/spell/targeted/chimera/hatch_pop
+ name = "Emerge"
+ desc = "We emerge in our new form."
+
+ spell_flags = INCLUDEUSER | GHOSTCAST
+ hud_state = "ling_revive"
+ invocation = "none"
+ invocation_type = SpI_NONE
+ charge_max = 10 SECONDS //It gets removed after_cast anyway
+ duration = 0
+ nutrition_cost_minimum = 1
+ nutrition_cost_proportional = 1
+
+/spell/targeted/chimera/hatch_pop/cast(list/targets, mob/user = usr)
+ var/mob/living/carbon/human/H = user
+
+ var/braindamage = (H.brainloss * 0.6) //Can only heal half brain damage.
+
+ H.revive()
+ H.mutations.Remove(HUSK)
+ H.nutrition = 50 //Hungy, also guarantees ferality without any other tweaking
+ H.setBrainLoss(braindamage)
+
+ //Drop everything
+ for(var/obj/item/W in H)
+ H.drop_from_inventory(W)
+ H.visible_message("[H] emerges from a cloud of viscera!")
+ H.SetParalysis(0)
+ //Unfreeze some things
+ H.does_not_breathe = FALSE
+ H.update_canmove()
+ H.weakened = 2
+ //Visual effects
+ var/T = get_turf(H)
+ new /obj/effect/gibspawner/human(T, H.dna,H.dna.blood_color,H.dna.blood_color)
+ playsound(T, 'sound/effects/splat.ogg')
+
+/spell/targeted/chimera/hatch_pop/after_cast(list/targets, mob/user = usr)
+ var/mob/living/carbon/human/H = user
+ H.remove_spell(src)
+ qdel(src)
+
+
+////////////////////
+//Timed No Breathe//
+////////////////////
+//Same principle as thermal sight. Could be status effects?
+/spell/targeted/chimera/no_breathe
+ name = "Stop Respiration"
+ desc = "We change our form to no longer need to breathe at all. We cannot sustain this for long."
+
+ spell_flags = INCLUDEUSER
+ hud_state = "ling_toggle_breath"
+ invocation = "none"
+ invocation_type = SpI_NONE
+ charge_max = 125 SECONDS //5 seconds inbetween uses
+ duration = 120 SECONDS
+ nutrition_cost_minimum = 100
+ nutrition_cost_proportional = 20 //Costly.
+ var/active = FALSE
+
+
+/spell/targeted/chimera/no_breathe/cast(list/targets, mob/user = usr)
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ toggle_breath(user)
+ addtimer(CALLBACK(src, .proc/toggle_breath,H), duration, TIMER_UNIQUE)
+ ..()
+
+/spell/targeted/chimera/no_breathe/proc/toggle_breath(mob/living/carbon/human/H)
+ if(!active)
+ to_chat(H, "We preserve the air we have, no longer needing to breathe.")
+ H.does_not_breathe = TRUE
+ active = TRUE
+ else
+ to_chat(H, "Our reserves are drained.")
+ H.does_not_breathe = FALSE
+ active = FALSE
+
+
///////////////
//EMP Shriek //
///////////////
@@ -125,7 +335,10 @@
var/emp_med = 6
var/emp_light = 9
var/emp_long = 12
- charge_max = 5 MINUTES
+ smoke_spread = 1
+ smoke_amt = 1
+ override_base = "cult"
+ charge_max = 5 MINUTES //Let's not be able to spam this
/spell/aoe_turf/dissonant_shriek/before_cast(list/targets, mob/user = usr)
@@ -147,17 +360,15 @@
return
/spell/aoe_turf/dissonant_shriek/cast(list/targets, mob/user = usr)
-
for(var/mob/living/T in targets)
if(iscarbon(T))
if(T.mind)
- if(T.get_ear_protection() >= 2)
+ if(T.get_ear_protection() >= 2 || T == user)
continue
to_chat(T, "You hear an extremely loud screeching sound! It slightly \
[pick("confuses","confounds","perturbs","befuddles","dazes","unsettles","disorients")] you.")
- if(T != user)
- T.Confuse(10)
- SEND_SOUND(T, sound('sound/effects/screech.ogg'))
+ T.Confuse(10)
+ playsound(get_turf(user),'sound/effects/screech.ogg', 75, TRUE)
empulse(get_turf(user), emp_heavy, emp_med, emp_light, emp_long)