diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 3f9416ab9632..eae05dcc5d18 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -18,6 +18,7 @@ #define TRAIT_XENO_HOST "xeno_host" //Tracks whether we're gonna be a baby alien's mummy. #define TRAIT_STUNIMMUNE "stun_immunity" #define TRAIT_PUSHIMMUNE "push_immunity" +#define TRAIT_SHOCKIMMUNE "shock_immunity" // common trait sources #define TRAIT_GENERIC "generic" diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index c3970baee068..d2ded9f907e7 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -73,6 +73,9 @@ // Randomly pick a symptom to activate. /datum/disease/advance/stage_act() ..() + if(carrier) + return + if(symptoms && symptoms.len) if(!processing) diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index 11bf6e5b8f67..c03f63234307 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -113,10 +113,10 @@ /obj/effect/spawner/lootdrop/organ_spawner name = "organ spawner" loot = list( - /obj/item/organ/heart/gland/bloody = 7, - /obj/item/organ/heart/gland/bodysnatch = 4, + /obj/item/organ/heart/gland/electric = 3, + /obj/item/organ/heart/gland/trauma = 4, /obj/item/organ/heart/gland/egg = 7, - /obj/item/organ/heart/gland/emp = 3, + /obj/item/organ/heart/gland/chem = 5, /obj/item/organ/heart/gland/mindshock = 5, /obj/item/organ/heart/gland/plasma = 7, /obj/item/organ/heart/gland/pop = 5, diff --git a/code/modules/antagonists/abductor/equipment/abduction_surgery.dm b/code/modules/antagonists/abductor/equipment/abduction_surgery.dm index 5b5bafdd2178..ffce85e43597 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_surgery.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_surgery.dm @@ -53,3 +53,48 @@ var/obj/item/organ/heart/gland/gland = tool gland.Insert(target, 2) return 1 + +/datum/surgery/pacify + name = "violence neutralization" + steps = list(/datum/surgery_step/incise, + /datum/surgery_step/retract_skin, + /datum/surgery_step/saw, + /datum/surgery_step/clamp_bleeders, + /datum/surgery_step/pacify, + /datum/surgery_step/close) + + species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) + possible_locs = list("head") + requires_bodypart_type = 0 + +/datum/surgery/pacify/can_start(mob/user, mob/living/carbon/target) + if(!ishuman(user)) + return FALSE + var/mob/living/carbon/human/H = user + . = FALSE + if(!(H.dna.species.id == "abductor")) + . = TRUE + for(var/obj/item/implant/abductor/A in H.implants) + . = TRUE + var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN) + if(!B) + to_chat(user, "It's hard to do surgery on someone's brain when they don't have one.") + return FALSE + +/datum/surgery_step/pacify + name = "rewire brain" + implements = list(/obj/item/hemostat = 100, /obj/item/screwdriver = 35, /obj/item/pen = 15) + time = 40 + +/datum/surgery_step/pacify/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user] begins to reshape [target]'s brain.", "You begin to reshape [target]'s brain...") + +/datum/surgery_step/pacify/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user] successfully reshapes [target]'s brain!", "You succeed in reshaping [target]'s brain.") + target.gain_trauma(/datum/brain_trauma/severe/pacifism) + return TRUE + +/datum/surgery_step/pacify/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user] successfully reshapes [target]'s brain!", "You screwed up, and rewired [target]'s brain the wrong way around...") + target.gain_trauma_type(BRAIN_TRAUMA_SEVERE) + return FALSE \ No newline at end of file diff --git a/code/modules/antagonists/abductor/equipment/gland.dm b/code/modules/antagonists/abductor/equipment/gland.dm index 7e4941583453..6eba723756ec 100644 --- a/code/modules/antagonists/abductor/equipment/gland.dm +++ b/code/modules/antagonists/abductor/equipment/gland.dm @@ -8,7 +8,7 @@ var/cooldown_low = 300 var/cooldown_high = 300 var/next_activation = 0 - var/uses // -1 For inifinite + var/uses // -1 For infinite var/human_only = 0 var/active = 0 @@ -104,9 +104,9 @@ /obj/item/organ/heart/gland/heals/activate() to_chat(owner, "You feel curiously revitalized.") - owner.adjustBruteLoss(-20) + owner.adjustToxLoss(-20, FALSE, TRUE) + owner.heal_bodypart_damage(20, 20, TRUE) owner.adjustOxyLoss(-20) - owner.adjustFireLoss(-20) /obj/item/organ/heart/gland/slime cooldown_low = 600 @@ -116,18 +116,22 @@ mind_control_uses = 1 mind_control_duration = 2400 +/obj/item/organ/heart/gland/slime/Insert(mob/living/carbon/M, special = 0) + ..() + owner.faction |= "slime" + owner.grant_language(/datum/language/slime) + /obj/item/organ/heart/gland/slime/activate() to_chat(owner, "You feel nauseous!") owner.vomit(20) - var/mob/living/simple_animal/slime/Slime - Slime = new(get_turf(owner), "grey") + var/mob/living/simple_animal/slime/Slime = new(get_turf(owner), "grey") Slime.Friends = list(owner) Slime.Leader = owner /obj/item/organ/heart/gland/mindshock - cooldown_low = 300 - cooldown_high = 300 + cooldown_low = 400 + cooldown_high = 700 uses = -1 icon_state = "mindshock" mind_control_uses = 1 @@ -140,21 +144,30 @@ for(var/mob/living/carbon/H in orange(4,T)) if(H == owner) continue - to_chat(H, "You hear a buzz in your head.") - H.confused += 20 + switch(pick(1,3)) + if(1) + to_chat(H, "You hear a loud buzz in your head, silencing your thoughts!") + H.Stun(50) + if(2) + to_chat(H, "You hear an annoying buzz in your head.") + H.confused += 15 + H.adjustBrainLoss(10, 160) + if(3) + H.hallucination += 80 /obj/item/organ/heart/gland/pop cooldown_low = 900 cooldown_high = 1800 uses = -1 - human_only = 1 + human_only = TRUE icon_state = "species" mind_control_uses = 5 mind_control_duration = 300 /obj/item/organ/heart/gland/pop/activate() to_chat(owner, "You feel unlike yourself.") - var/species = pick(list(/datum/species/lizard, /datum/species/jelly/slime, /datum/species/pod, /datum/species/fly, /datum/species/jelly)) + randomize_human(owner) + var/species = pick(list(/datum/species/human, /datum/species/lizard, /datum/species/moth, /datum/species/fly)) owner.set_species(species) /obj/item/organ/heart/gland/ventcrawling @@ -169,7 +182,6 @@ to_chat(owner, "You feel very stretchy.") owner.ventcrawler = VENTCRAWLER_ALWAYS - /obj/item/organ/heart/gland/viral cooldown_low = 1800 cooldown_high = 2400 @@ -180,30 +192,55 @@ /obj/item/organ/heart/gland/viral/activate() to_chat(owner, "You feel sick.") - var/virus_type = pick(/datum/disease/beesease, /datum/disease/brainrot, /datum/disease/magnitis) - var/datum/disease/D = new virus_type() - D.carrier = TRUE - owner.viruses += D - D.affected_mob = owner + var/datum/disease/advance/A = random_virus(pick(2,6),6) + A.carrier = TRUE + owner.viruses += A + A.affected_mob = owner owner.med_hud_set_status() +/obj/item/organ/heart/gland/viral/proc/random_virus(max_symptoms, max_level) + if(max_symptoms > SYMPTOM_LIMIT) + max_symptoms = SYMPTOM_LIMIT + var/datum/disease/advance/A = new(FALSE, null) + A.symptoms = list() + var/list/datum/symptom/possible_symptoms = list() + for(var/symptom in subtypesof(/datum/symptom)) + var/datum/symptom/S = symptom + if(initial(S.level) > max_level) + continue + if(initial(S.level) <= 0) //unobtainable symptoms + continue + possible_symptoms += S + for(var/i in 1 to max_symptoms) + var/datum/symptom/chosen_symptom = pick_n_take(possible_symptoms) + if(chosen_symptom) + var/datum/symptom/S = new chosen_symptom + A.symptoms += S + A.Refresh() //just in case someone already made and named the same disease + return A -/obj/item/organ/heart/gland/emp //TODO : Replace with something more interesting - cooldown_low = 900 - cooldown_high = 1600 - uses = 10 +/obj/item/organ/heart/gland/trauma //TODO : Replace with something more interesting + cooldown_low = 800 + cooldown_high = 1200 + uses = 5 icon_state = "emp" - mind_control_uses = 1 + mind_control_uses = 3 mind_control_duration = 1800 -/obj/item/organ/heart/gland/emp/activate() +/obj/item/organ/heart/gland/trauma/activate() to_chat(owner, "You feel a spike of pain in your head.") - empulse(get_turf(owner), 2, 5, 1) + if(prob(33)) + owner.gain_trauma_type(BRAIN_TRAUMA_SPECIAL, TRUE) + else + if(prob(20)) + owner.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRUE) + else + owner.gain_trauma_type(BRAIN_TRAUMA_MILD, TRUE) /obj/item/organ/heart/gland/spiderman cooldown_low = 450 cooldown_high = 900 - uses = 10 + uses = -1 icon_state = "spider" mind_control_uses = 2 mind_control_duration = 2400 @@ -211,7 +248,8 @@ /obj/item/organ/heart/gland/spiderman/activate() to_chat(owner, "You feel something crawling in your skin.") owner.faction |= "spiders" - new /obj/structure/spider/spiderling(owner.loc) + var/obj/structure/spider/spiderling/S = new(owner.drop_location()) + S.directive = "Protect your nest inside [owner.real_name]." /obj/item/organ/heart/gland/egg cooldown_low = 300 @@ -225,71 +263,60 @@ /obj/item/organ/heart/gland/egg/activate() to_chat(owner, "You lay an egg!") - var/obj/item/reagent_containers/food/snacks/egg/egg = new(owner.loc) + var/obj/item/reagent_containers/food/snacks/egg/egg = new(owner.drop_location()) egg.reagents.add_reagent("sacid",20) egg.desc += " It smells bad." -/obj/item/organ/heart/gland/bloody - cooldown_low = 200 - cooldown_high = 400 +/obj/item/organ/heart/gland/electric + cooldown_low = 800 + cooldown_high = 1200 uses = -1 - mind_control_uses = 1 - mind_control_duration = 450 + mind_control_uses = 2 + mind_control_duration = 900 -/obj/item/organ/heart/gland/bloody/activate() - owner.blood_volume -= 20 - owner.visible_message("[owner]'s skin erupts with blood!",\ - "Blood pours from your skin!") +/obj/item/organ/heart/gland/electric/Insert(mob/living/carbon/M, special = 0) + ..() + owner.add_trait(TRAIT_SHOCKIMMUNE, "abductor_gland") - for(var/turf/T in oview(3,owner)) //Make this respect walls and such - owner.add_splatter_floor(T) - for(var/mob/living/carbon/human/H in oview(3,owner)) //Blood decals for simple animals would be neat. aka Carp with blood on it. - H.add_mob_blood(owner) +/obj/item/organ/heart/gland/electric/Remove(mob/living/carbon/M, special = 0) + owner.remove_trait(TRAIT_SHOCKIMMUNE, "abductor_gland") + ..() +/obj/item/organ/heart/gland/electric/activate() + owner.visible_message("[owner]'s skin starts emitting electric arcs!",\ + "You feel electric energy building up inside you!") + playsound(get_turf(owner), "sparks", 100, 1, -1) + addtimer(CALLBACK(src, .proc/zap), rand(30, 100)) -/obj/item/organ/heart/gland/bodysnatch - cooldown_low = 600 - cooldown_high = 600 - human_only = 1 - uses = 1 - mind_control_uses = 1 - mind_control_duration = 600 +/obj/item/organ/heart/gland/electric/proc/zap() + tesla_zap(owner, 4, 8000, FALSE, TRUE) + playsound(get_turf(owner), 'sound/magic/lightningshock.ogg', 50, 1) -/obj/item/organ/heart/gland/bodysnatch/activate() - to_chat(owner, "You feel something moving around inside you...") - //spawn cocoon with clone greytide snpc inside - if(ishuman(owner)) - var/obj/structure/spider/cocoon/abductor/C = new (get_turf(owner)) - C.Copy(owner) - C.Start() - owner.adjustBruteLoss(40) - owner.add_splatter_floor() +/obj/item/organ/heart/gland/chem + cooldown_low = 50 + cooldown_high = 50 + uses = -1 + mind_control_uses = 3 + mind_control_duration = 1200 + var/list/possible_reagents = list() -/obj/structure/spider/cocoon/abductor - name = "slimy cocoon" - desc = "Something is moving inside." - icon = 'icons/effects/effects.dmi' - icon_state = "cocoon_large3" - color = rgb(10,120,10) - density = TRUE - var/hatch_time = 0 - -/obj/structure/spider/cocoon/abductor/proc/Copy(mob/living/carbon/human/H) - var/mob/living/carbon/human/interactive/greytide/clone = new(src) - clone.hardset_dna(H.dna.uni_identity,H.dna.struc_enzymes,H.real_name, H.dna.blood_type, H.dna.species, H.dna.features) - -/obj/structure/spider/cocoon/abductor/proc/Start() - hatch_time = world.time + 600 - START_PROCESSING(SSobj, src) - -/obj/structure/spider/cocoon/abductor/process() - if(world.time > hatch_time) - STOP_PROCESSING(SSobj, src) - for(var/mob/M in contents) - src.visible_message("[src] hatches!") - M.forceMove(drop_location()) - qdel(src) +/obj/item/organ/heart/gland/chem/Initialize() + ..() + for(var/X in subtypesof(/datum/reagent/drug)) + var/datum/reagent/R = X + possible_reagents += initial(R.id) + for(var/X in subtypesof(/datum/reagent/medicine)) + var/datum/reagent/R = X + possible_reagents += initial(R.id) + for(var/X in typesof(/datum/reagent/toxin)) + var/datum/reagent/R = X + possible_reagents += initial(R.id) +/obj/item/organ/heart/gland/chem/activate() + var/chem_to_add = pick(possible_reagents) + owner.reagents.add_reagent(chem_to_add, 2) + owner.adjustToxLoss(-2, TRUE, TRUE) + ..() /obj/item/organ/heart/gland/plasma cooldown_low = 1200 diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index f91b254ad4d6..2650d4aa5904 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -213,6 +213,8 @@ /mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE) if(tesla_shock && (flags_2 & TESLA_IGNORE_2)) return FALSE + if(has_trait(TRAIT_SHOCKIMMUNE)) + return FALSE shock_damage *= siemens_coeff if(dna && dna.species) shock_damage *= dna.species.siemens_coeff diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 2304502c40a7..6450c13bb76d 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -303,6 +303,8 @@ /mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE) if(tesla_shock && (flags_2 & TESLA_IGNORE_2)) return FALSE + if(has_trait(TRAIT_SHOCKIMMUNE)) + return FALSE if(shock_damage > 0) if(!illusion) adjustFireLoss(shock_damage)