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)