diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm
index 87552e5841..de3b90eb1c 100644
--- a/code/__DEFINES/DNA.dm
+++ b/code/__DEFINES/DNA.dm
@@ -94,36 +94,22 @@
#define FACEHAIR 3
#define EYECOLOR 4
#define LIPS 5
-#define RESISTHOT 6
-#define RESISTCOLD 7
-#define RESISTPRESSURE 8
-#define RADIMMUNE 9
-#define NOBREATH 10
-#define NOGUNS 11
-#define NOBLOOD 12
-#define NOFIRE 13
-#define VIRUSIMMUNE 14
-#define PIERCEIMMUNE 15
-#define NOTRANSSTING 16
-#define MUTCOLORS_PARTSONLY 17 //Used if we want the mutant colour to be only used by mutant bodyparts. Don't combine this with MUTCOLORS, or it will be useless.
-#define NODISMEMBER 18
-#define NOHUNGER 19
-#define NOCRITDAMAGE 20
-#define NOZOMBIE 21
-#define EASYDISMEMBER 22
-#define EASYLIMBATTACHMENT 23
-#define TOXINLOVER 24
-#define DIGITIGRADE 25 //Uses weird leg sprites. Optional for Lizards, required for ashwalkers. Don't give it to other races unless you make sprites for this (see human_parts_greyscale.dmi)
-#define NO_UNDERWEAR 26
-#define NOLIVER 27
-#define NOSTOMACH 28
-#define NO_DNA_COPY 29
-#define DRINKSBLOOD 30
-#define SPECIES_ORGANIC 31
-#define SPECIES_INORGANIC 32
-#define SPECIES_UNDEAD 33
-#define SPECIES_ROBOTIC 34
-#define NOEYES 35
+#define NOBLOOD 6
+#define NOTRANSSTING 7
+#define MUTCOLORS_PARTSONLY 8 //Used if we want the mutant colour to be only used by mutant bodyparts. Don't combine this with MUTCOLORS, or it will be useless.
+#define NOCRITDAMAGE 9
+#define NOZOMBIE 10
+#define DIGITIGRADE 11 //Uses weird leg sprites. Optional for Lizards, required for ashwalkers. Don't give it to other races unless you make sprites for this (see human_parts_greyscale.dmi)
+#define NO_UNDERWEAR 12
+#define NOLIVER 13
+#define NOSTOMACH 14
+#define NO_DNA_COPY 15
+#define DRINKSBLOOD 16
+#define SPECIES_ORGANIC 17
+#define SPECIES_INORGANIC 18
+#define SPECIES_UNDEAD 19
+#define SPECIES_ROBOTIC 20
+#define NOEYES 21
#define ORGAN_SLOT_BRAIN "brain"
#define ORGAN_SLOT_APPENDIX "appendix"
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 1334790ff1..6bc504d48a 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -21,6 +21,21 @@
#define TRAIT_SLEEPIMMUNE "sleep_immunity"
#define TRAIT_PUSHIMMUNE "push_immunity"
#define TRAIT_SHOCKIMMUNE "shock_immunity"
+#define TRAIT_RESISTHEAT "resist_heat"
+#define TRAIT_RESISTCOLD "resist_cold"
+#define TRAIT_RESISTHIGHPRESSURE "resist_high_pressure"
+#define TRAIT_RESISTLOWPRESSURE "resist_low_pressure"
+#define TRAIT_RADIMMUNE "rad_immunity"
+#define TRAIT_VIRUSIMMUNE "virus_immunity"
+#define TRAIT_PIERCEIMMUNE "pierce_immunity"
+#define TRAIT_NODISMEMBER "dismember_immunity"
+#define TRAIT_NOFIRE "nonflammable"
+#define TRAIT_NOGUNS "no_guns"
+#define TRAIT_NOHUNGER "no_hunger"
+#define TRAIT_EASYDISMEMBER "easy_dismember"
+#define TRAIT_LIMBATTACHMENT "limb_attach"
+#define TRAIT_TOXINLOVER "toxinlover"
+#define TRAIT_NOBREATH "no_breath"
#define TRAIT_ANTIMAGIC "anti_magic"
#define TRAIT_HOLY "holy"
@@ -56,4 +71,4 @@
#define TRAIT_HULK "hulk"
#define STASIS_MUTE "stasis"
#define GENETICS_SPELL "genetics_spell"
-#define EYES_COVERED "eyes_covered"
+#define EYES_COVERED "eyes_covered"
\ No newline at end of file
diff --git a/code/datums/components/caltrop.dm b/code/datums/components/caltrop.dm
index 8fc7a070af..9193651ee2 100644
--- a/code/datums/components/caltrop.dm
+++ b/code/datums/components/caltrop.dm
@@ -24,7 +24,7 @@
if(ishuman(AM))
var/mob/living/carbon/human/H = AM
- if(PIERCEIMMUNE in H.dna.species.species_traits)
+ if(H.has_trait(TRAIT_PIERCEIMMUNE))
return
if((flags & CALTROP_IGNORE_WALKERS) && H.m_intent == MOVE_INTENT_WALK)
diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm
index ffc20cc9cb..9f4fa1fe63 100644
--- a/code/datums/diseases/_MobProcs.dm
+++ b/code/datums/diseases/_MobProcs.dm
@@ -133,14 +133,10 @@
/mob/living/carbon/AirborneContractDisease(datum/disease/D)
if(internal)
return
- ..()
-
-/mob/living/carbon/human/AirborneContractDisease(datum/disease/D)
- if(dna && (NOBREATH in dna.species.species_traits))
+ if(has_trait(TRAIT_NOBREATH))
return
..()
-
//Proc to use when you 100% want to infect someone, as long as they aren't immune
/mob/proc/ForceContractDisease(datum/disease/D)
if(!CanContractDisease(D))
@@ -151,7 +147,7 @@
/mob/living/carbon/human/CanContractDisease(datum/disease/D)
if(dna)
- if((VIRUSIMMUNE in dna.species.species_traits) && !D.bypasses_immunity)
+ if(has_trait(TRAIT_VIRUSIMMUNE) && !D.bypasses_immunity)
return FALSE
var/can_infect = FALSE
diff --git a/code/datums/mutations/cold_resistance.dm b/code/datums/mutations/cold_resistance.dm
index 6281514e71..b221ac95ca 100644
--- a/code/datums/mutations/cold_resistance.dm
+++ b/code/datums/mutations/cold_resistance.dm
@@ -14,6 +14,18 @@
/datum/mutation/human/cold_resistance/get_visual_indicator(mob/living/carbon/human/owner)
return visual_indicators[1]
+/datum/mutation/human/cold_resistance/on_acquiring(mob/living/carbon/human/owner)
+ if(..())
+ return
+ owner.add_trait(TRAIT_RESISTCOLD, "cold_resistance")
+ owner.add_trait(TRAIT_RESISTLOWPRESSURE, "cold_resistance")
+
+/datum/mutation/human/cold_resistance/on_losing(mob/living/carbon/human/owner)
+ if(..())
+ return
+ owner.remove_trait(TRAIT_RESISTCOLD, "cold_resistance")
+ owner.remove_trait(TRAIT_RESISTLOWPRESSURE, "cold_resistance")
+
/datum/mutation/human/cold_resistance/on_life(mob/living/carbon/human/owner)
if(owner.getFireLoss())
if(prob(1))
diff --git a/code/datums/weather/weather_types/radiation_storm.dm b/code/datums/weather/weather_types/radiation_storm.dm
index 9c9bde19fc..0906a7e053 100644
--- a/code/datums/weather/weather_types/radiation_storm.dm
+++ b/code/datums/weather/weather_types/radiation_storm.dm
@@ -33,16 +33,15 @@
if(prob(40))
if(ishuman(L))
var/mob/living/carbon/human/H = L
- if(H.dna && H.dna.species)
- if(!(RADIMMUNE in H.dna.species.species_traits))
- if(prob(max(0,100-resist)))
- H.randmuti()
- if(prob(50))
- if(prob(90))
- H.randmutb()
- else
- H.randmutg()
- H.domutcheck()
+ if(H.dna && !H.has_trait(TRAIT_RADIMMUNE))
+ if(prob(max(0,100-resist)))
+ H.randmuti()
+ if(prob(50))
+ if(prob(90))
+ H.randmutb()
+ else
+ H.randmutg()
+ H.domutcheck()
L.rad_act(20)
/datum/weather/rad_storm/end()
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 5d87f65537..b46706ce9f 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -440,7 +440,7 @@
// brain function, they also have no limbs or internal organs.
- if(!NODISMEMBER in H.dna.species.species_traits)
+ if(!H.has_trait(TRAIT_NODISMEMBER))
var/static/list/zones = list("r_arm", "l_arm", "r_leg", "l_leg")
for(var/zone in zones)
var/obj/item/bodypart/BP = H.get_bodypart(zone)
diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm
index de0089d5c6..3b6113e67b 100644
--- a/code/game/machinery/computer/dna_console.dm
+++ b/code/game/machinery/computer/dna_console.dm
@@ -81,7 +81,7 @@
if(connected && connected.is_operational())
if(connected.occupant) //set occupant_status message
viable_occupant = connected.occupant
- if(viable_occupant.has_dna() && (!(RADIMMUNE in viable_occupant.dna.species.species_traits)) && (!(viable_occupant.has_trait(TRAIT_NOCLONE)) || (connected.scan_level == 3))) //occupant is viable for dna modification
+ if(viable_occupant.has_dna() && !viable_occupant.has_trait(TRAIT_RADIMMUNE) && !viable_occupant.has_trait(TRAIT_NOCLONE) || (connected.scan_level == 3)) //occupant is viable for dna modification
occupant_status += "[viable_occupant.name] => "
switch(viable_occupant.stat)
if(CONSCIOUS)
@@ -528,7 +528,7 @@
var/mob/living/carbon/viable_occupant = null
if(connected)
viable_occupant = connected.occupant
- if(!istype(viable_occupant) || !viable_occupant.dna || (RADIMMUNE in viable_occupant.dna.species.species_traits) || (viable_occupant.has_trait(TRAIT_NOCLONE)))
+ if(!istype(viable_occupant) || !viable_occupant.dna || viable_occupant.has_trait(TRAIT_RADIMMUNE) || viable_occupant.has_trait(TRAIT_NOCLONE))
viable_occupant = null
return viable_occupant
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 4267f69657..b21d95e7ab 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -250,7 +250,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
can_handle_hot = TRUE
else if(C.gloves && (C.gloves.max_heat_protection_temperature > 360))
can_handle_hot = TRUE
- else if(RESISTHOT in C.dna.species.species_traits)
+ else if(C.has_trait(TRAIT_RESISTHEAT))
can_handle_hot = TRUE
if(can_handle_hot)
diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm
index eb1ccd15f4..2e65a6c108 100644
--- a/code/game/objects/items/devices/laserpointer.dm
+++ b/code/game/objects/items/devices/laserpointer.dm
@@ -67,9 +67,12 @@
if (!user.IsAdvancedToolUser())
to_chat(user, "You don't have the dexterity to do this!")
return
+ if(user.has_trait(TRAIT_NOGUNS))
+ to_chat(user, "Your fingers can't press the button!")
+ return
if(ishuman(user))
var/mob/living/carbon/human/H = user
- if(H.dna.check_mutation(HULK) || (NOGUNS in H.dna.species.species_traits))
+ if(H.dna.check_mutation(HULK))
to_chat(user, "Your fingers can't press the button!")
return
diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm
index c908b619c4..0e8c82d963 100644
--- a/code/game/objects/items/dna_injector.dm
+++ b/code/game/objects/items/dna_injector.dm
@@ -31,7 +31,7 @@
/obj/item/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
prepare()
- if(M.has_dna() && !(RADIMMUNE in M.dna.species.species_traits) && !(M.has_trait(TRAIT_NOCLONE)))
+ if(M.has_dna() && !M.has_trait(TRAIT_RADIMMUNE) && !M.has_trait(TRAIT_NOCLONE))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/datum/mutation/human/HM in remove_mutations)
diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm
index ae73824899..fba0c1b1a2 100644
--- a/code/game/objects/items/stacks/sheets/glass.dm
+++ b/code/game/objects/items/stacks/sheets/glass.dm
@@ -274,13 +274,14 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
var/hit_hand = ((user.active_hand_index % 2 == 0) ? "r_" : "l_") + "arm"
if(ishuman(user))
var/mob/living/carbon/human/H = user
- if(!H.gloves && !(PIERCEIMMUNE in H.dna.species.species_traits)) // golems, etc
+ if(!H.gloves && !H.has_trait(TRAIT_PIERCEIMMUNE)) // golems, etc
to_chat(H, "[src] cuts into your hand!")
H.apply_damage(force*0.5, BRUTE, hit_hand)
else if(ismonkey(user))
var/mob/living/carbon/monkey/M = user
- to_chat(M, "[src] cuts into your hand!")
- M.apply_damage(force*0.5, BRUTE, hit_hand)
+ if(!M.has_trait(TRAIT_PIERCEIMMUNE))
+ to_chat(M, "[src] cuts into your hand!")
+ M.apply_damage(force*0.5, BRUTE, hit_hand)
/obj/item/shard/attackby(obj/item/I, mob/user, params)
diff --git a/code/modules/antagonists/highlander/highlander.dm b/code/modules/antagonists/highlander/highlander.dm
index 185bedba8f..aeca9c18bd 100644
--- a/code/modules/antagonists/highlander/highlander.dm
+++ b/code/modules/antagonists/highlander/highlander.dm
@@ -5,16 +5,12 @@
show_name_in_check_antagonists = TRUE
/datum/antagonist/highlander/apply_innate_effects(mob/living/mob_override)
- var/mob/living/carbon/human/H = owner.current || mob_override
- if(!istype(H))
- return
- H.dna.species.species_traits |= NOGUNS //nice try jackass
+ var/mob/living/L = owner.current || mob_override
+ L.add_trait(TRAIT_NOGUNS, "highlander")
/datum/antagonist/highlander/remove_innate_effects(mob/living/mob_override)
- var/mob/living/carbon/human/H = owner.current || mob_override
- if(!istype(H))
- return
- H.dna.species.species_traits &= ~NOGUNS
+ var/mob/living/L = owner.current || mob_override
+ L.remove_trait(TRAIT_NOGUNS, "highlander")
/datum/antagonist/highlander/on_removal()
owner.objectives -= objectives
@@ -76,7 +72,7 @@
sword.admin_spawned = TRUE //To prevent announcing
sword.pickup(H) //For the stun shielding
H.put_in_hands(sword)
-
+
var/obj/item/bloodcrawl/antiwelder = new(H)
antiwelder.name = "compulsion of honor"
diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm
index fb37c878a3..5e06851e58 100644
--- a/code/modules/assembly/mousetrap.dm
+++ b/code/modules/assembly/mousetrap.dm
@@ -1,142 +1,142 @@
-/obj/item/device/assembly/mousetrap
- name = "mousetrap"
- desc = "A handy little spring-loaded trap for catching pesty rodents."
- icon_state = "mousetrap"
- materials = list(MAT_METAL=100)
- attachable = 1
- var/armed = 0
-
-
-/obj/item/device/assembly/mousetrap/examine(mob/user)
- ..()
- if(armed)
- to_chat(user, "The mousetrap is armed!")
- else
- to_chat(user, "The mousetrap is not armed.")
-
-/obj/item/device/assembly/mousetrap/activate()
- if(..())
- armed = !armed
- if(!armed)
- if(ishuman(usr))
- var/mob/living/carbon/human/user = usr
- if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50))
- to_chat(user, "Your hand slips, setting off the trigger!")
- pulse(0)
- update_icon()
- if(usr)
- playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
-
-/obj/item/device/assembly/mousetrap/describe()
- return "The pressure switch is [armed?"primed":"safe"]."
-
-/obj/item/device/assembly/mousetrap/update_icon()
- if(armed)
- icon_state = "mousetraparmed"
- else
- icon_state = "mousetrap"
- if(holder)
- holder.update_icon()
-
-/obj/item/device/assembly/mousetrap/proc/triggered(mob/target, type = "feet")
- if(!armed)
- return
- var/obj/item/bodypart/affecting = null
- if(ishuman(target))
- var/mob/living/carbon/human/H = target
- if(PIERCEIMMUNE in H.dna.species.species_traits)
- playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
- armed = 0
- update_icon()
- pulse(0)
- return 0
- switch(type)
- if("feet")
- if(!H.shoes)
- affecting = H.get_bodypart(pick("l_leg", "r_leg"))
- H.Knockdown(60)
- if("l_hand", "r_hand")
- if(!H.gloves)
- affecting = H.get_bodypart(type)
- H.Stun(60)
- if(affecting)
- if(affecting.receive_damage(1, 0))
- H.update_damage_overlays()
- else if(ismouse(target))
- var/mob/living/simple_animal/mouse/M = target
- visible_message("SPLAT!")
- M.splat()
- playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
- armed = 0
- update_icon()
- pulse(0)
-
-
-/obj/item/device/assembly/mousetrap/attack_self(mob/living/carbon/human/user)
- if(!armed)
- to_chat(user, "You arm [src].")
- else
- if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50))
- var/which_hand = "l_hand"
- if(!(user.active_hand_index % 2))
- which_hand = "r_hand"
- triggered(user, which_hand)
- user.visible_message("[user] accidentally sets off [src], breaking their fingers.", \
- "You accidentally trigger [src]!")
- return
- to_chat(user, "You disarm [src].")
- armed = !armed
- update_icon()
- playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
-
-
-/obj/item/device/assembly/mousetrap/attack_hand(mob/living/carbon/human/user)
- if(armed)
- if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50))
- var/which_hand = "l_hand"
- if(!(user.active_hand_index % 2))
- which_hand = "r_hand"
- triggered(user, which_hand)
- user.visible_message("[user] accidentally sets off [src], breaking their fingers.", \
- "You accidentally trigger [src]!")
- return
- ..()
-
-
-/obj/item/device/assembly/mousetrap/Crossed(atom/movable/AM as mob|obj)
- if(armed)
- if(ismob(AM))
- var/mob/MM = AM
- if(!(MM.movement_type & FLYING))
- if(ishuman(AM))
- var/mob/living/carbon/H = AM
- if(H.m_intent == MOVE_INTENT_RUN)
- triggered(H)
- H.visible_message("[H] accidentally steps on [src].", \
- "You accidentally step on [src]")
- else if(ismouse(MM))
- triggered(MM)
- else if(AM.density) // For mousetrap grenades, set off by anything heavy
- triggered(AM)
- ..()
-
-
-/obj/item/device/assembly/mousetrap/on_found(mob/finder)
- if(armed)
- finder.visible_message("[finder] accidentally sets off [src], breaking their fingers.", \
- "You accidentally trigger [src]!")
- triggered(finder, (finder.active_hand_index % 2 == 0) ? "r_hand" : "l_hand")
- return 1 //end the search!
- return 0
-
-
-/obj/item/device/assembly/mousetrap/hitby(A as mob|obj)
- if(!armed)
- return ..()
- visible_message("[src] is triggered by [A].")
- triggered(null)
-
-
-/obj/item/device/assembly/mousetrap/armed
- icon_state = "mousetraparmed"
- armed = 1
+/obj/item/device/assembly/mousetrap
+ name = "mousetrap"
+ desc = "A handy little spring-loaded trap for catching pesty rodents."
+ icon_state = "mousetrap"
+ materials = list(MAT_METAL=100)
+ attachable = 1
+ var/armed = 0
+
+
+/obj/item/device/assembly/mousetrap/examine(mob/user)
+ ..()
+ if(armed)
+ to_chat(user, "The mousetrap is armed!")
+ else
+ to_chat(user, "The mousetrap is not armed.")
+
+/obj/item/device/assembly/mousetrap/activate()
+ if(..())
+ armed = !armed
+ if(!armed)
+ if(ishuman(usr))
+ var/mob/living/carbon/human/user = usr
+ if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50))
+ to_chat(user, "Your hand slips, setting off the trigger!")
+ pulse(0)
+ update_icon()
+ if(usr)
+ playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
+
+/obj/item/device/assembly/mousetrap/describe()
+ return "The pressure switch is [armed?"primed":"safe"]."
+
+/obj/item/device/assembly/mousetrap/update_icon()
+ if(armed)
+ icon_state = "mousetraparmed"
+ else
+ icon_state = "mousetrap"
+ if(holder)
+ holder.update_icon()
+
+/obj/item/device/assembly/mousetrap/proc/triggered(mob/target, type = "feet")
+ if(!armed)
+ return
+ var/obj/item/bodypart/affecting = null
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ if(H.has_trait(TRAIT_PIERCEIMMUNE))
+ playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
+ armed = 0
+ update_icon()
+ pulse(0)
+ return 0
+ switch(type)
+ if("feet")
+ if(!H.shoes)
+ affecting = H.get_bodypart(pick("l_leg", "r_leg"))
+ H.Knockdown(60)
+ if("l_hand", "r_hand")
+ if(!H.gloves)
+ affecting = H.get_bodypart(type)
+ H.Stun(60)
+ if(affecting)
+ if(affecting.receive_damage(1, 0))
+ H.update_damage_overlays()
+ else if(ismouse(target))
+ var/mob/living/simple_animal/mouse/M = target
+ visible_message("SPLAT!")
+ M.splat()
+ playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
+ armed = 0
+ update_icon()
+ pulse(0)
+
+
+/obj/item/device/assembly/mousetrap/attack_self(mob/living/carbon/human/user)
+ if(!armed)
+ to_chat(user, "You arm [src].")
+ else
+ if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50))
+ var/which_hand = "l_hand"
+ if(!(user.active_hand_index % 2))
+ which_hand = "r_hand"
+ triggered(user, which_hand)
+ user.visible_message("[user] accidentally sets off [src], breaking their fingers.", \
+ "You accidentally trigger [src]!")
+ return
+ to_chat(user, "You disarm [src].")
+ armed = !armed
+ update_icon()
+ playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
+
+
+/obj/item/device/assembly/mousetrap/attack_hand(mob/living/carbon/human/user)
+ if(armed)
+ if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50))
+ var/which_hand = "l_hand"
+ if(!(user.active_hand_index % 2))
+ which_hand = "r_hand"
+ triggered(user, which_hand)
+ user.visible_message("[user] accidentally sets off [src], breaking their fingers.", \
+ "You accidentally trigger [src]!")
+ return
+ ..()
+
+
+/obj/item/device/assembly/mousetrap/Crossed(atom/movable/AM as mob|obj)
+ if(armed)
+ if(ismob(AM))
+ var/mob/MM = AM
+ if(!(MM.movement_type & FLYING))
+ if(ishuman(AM))
+ var/mob/living/carbon/H = AM
+ if(H.m_intent == MOVE_INTENT_RUN)
+ triggered(H)
+ H.visible_message("[H] accidentally steps on [src].", \
+ "You accidentally step on [src]")
+ else if(ismouse(MM))
+ triggered(MM)
+ else if(AM.density) // For mousetrap grenades, set off by anything heavy
+ triggered(AM)
+ ..()
+
+
+/obj/item/device/assembly/mousetrap/on_found(mob/finder)
+ if(armed)
+ finder.visible_message("[finder] accidentally sets off [src], breaking their fingers.", \
+ "You accidentally trigger [src]!")
+ triggered(finder, (finder.active_hand_index % 2 == 0) ? "r_hand" : "l_hand")
+ return 1 //end the search!
+ return 0
+
+
+/obj/item/device/assembly/mousetrap/hitby(A as mob|obj)
+ if(!armed)
+ return ..()
+ visible_message("[src] is triggered by [A].")
+ triggered(null)
+
+
+/obj/item/device/assembly/mousetrap/armed
+ icon_state = "mousetraparmed"
+ armed = 1
diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm
index c8b8db0681..932a578d67 100644
--- a/code/modules/events/disease_outbreak.dm
+++ b/code/modules/events/disease_outbreak.dm
@@ -39,7 +39,7 @@
continue
if(H.stat == DEAD)
continue
- if(VIRUSIMMUNE in H.dna.species.species_traits) //Don't pick someone who's virus immune, only for it to not do anything.
+ if(H.has_trait(TRAIT_VIRUSIMMUNE)) //Don't pick someone who's virus immune, only for it to not do anything.
continue
var/foundAlready = FALSE // don't infect someone that already has a disease
for(var/thing in H.viruses)
diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm
index 9ec936c1f2..bb1a0d2f23 100644
--- a/code/modules/hydroponics/grown/nettle.dm
+++ b/code/modules/hydroponics/grown/nettle.dm
@@ -56,11 +56,8 @@
var/mob/living/carbon/C = user
if(C.gloves)
return FALSE
- if(ishuman(C))
- var/mob/living/carbon/human/H = C
- if(H.dna && H.dna.species)
- if(PIERCEIMMUNE in H.dna.species.species_traits)
- return FALSE
+ if(C.has_trait(TRAIT_PIERCEIMMUNE))
+ return FALSE
var/hit_zone = (C.held_index_to_dir(C.active_hand_index) == "l" ? "l_":"r_") + "arm"
var/obj/item/bodypart/affecting = C.get_bodypart(hit_zone)
if(affecting)
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index dd8c84c969..a30fd1492e 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -31,7 +31,7 @@
if(bodytemperature >= TCRYO && !(has_trait(TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
- if(blood_volume < BLOOD_VOLUME_NORMAL && !(NOHUNGER in dna.species.species_traits))
+ if(blood_volume < BLOOD_VOLUME_NORMAL && !has_trait(TRAIT_NOHUNGER))
var/nutrition_ratio = 0
switch(nutrition)
if(0 to NUTRITION_LEVEL_STARVING)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 8444779a79..b530ab0cc0 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -440,7 +440,7 @@
return ..()
/mob/living/carbon/proc/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, toxic = FALSE)
- if(dna && dna.species && NOHUNGER in dna.species.species_traits)
+ if(has_trait(TRAIT_NOHUNGER))
return 1
if(nutrition < 100 && !blood)
diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm
index 27c64625a8..662a42eea4 100644
--- a/code/modules/mob/living/carbon/carbon_movement.dm
+++ b/code/modules/mob/living/carbon/carbon_movement.dm
@@ -50,7 +50,7 @@
/mob/living/carbon/Move(NewLoc, direct)
. = ..()
if(. && mob_has_gravity()) //floating is easy
- if(dna && dna.species && (NOHUNGER in dna.species.species_traits))
+ if(has_trait(TRAIT_NOHUNGER))
nutrition = NUTRITION_LEVEL_FED - 1 //just less than feeling vigorous
else if(nutrition && stat != DEAD)
nutrition -= HUNGER_FACTOR/10
diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm
index a626266f01..b437b6a4f2 100644
--- a/code/modules/mob/living/carbon/damage_procs.dm
+++ b/code/modules/mob/living/carbon/damage_procs.dm
@@ -80,7 +80,7 @@
/mob/living/carbon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE)
- if(!forced && has_dna() && TOXINLOVER in dna.species.species_traits) //damage becomes healing and healing becomes damage
+ if(!forced && has_trait(TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage
amount = -amount
if(amount > 0)
blood_volume -= 5*amount
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 64ffc91ae7..6b5d533f11 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -482,7 +482,7 @@
. = 1 // Default to returning true.
if(user && !target_zone)
target_zone = user.zone_selected
- if(dna && (PIERCEIMMUNE in dna.species.species_traits))
+ if(has_trait(TRAIT_PIERCEIMMUNE))
. = 0
// If targeting the head, see if the head item is thin enough.
// If targeting anything else, see if the wear suit is thin enough.
@@ -643,7 +643,7 @@
to_chat(src, "You fail to perform CPR on [C]!")
return 0
- var/they_breathe = (!(NOBREATH in C.dna.species.species_traits))
+ var/they_breathe = !C.has_trait(TRAIT_NOBREATH)
var/they_lung = C.getorganslot(ORGAN_SLOT_LUNGS)
if(C.health > HEALTH_THRESHOLD_CRIT)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index b524e7efc4..c7d2541b08 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -136,7 +136,7 @@
else if(I)
if(I.throw_speed >= EMBED_THROWSPEED_THRESHOLD)
if(can_embed(I))
- if(prob(I.embedding.embed_chance) && !(dna && (PIERCEIMMUNE in dna.species.species_traits)))
+ if(prob(I.embedding.embed_chance) && !has_trait(TRAIT_PIERCEIMMUNE))
throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
var/obj/item/bodypart/L = pick(bodyparts)
L.embedded_objects |= I
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index c5e4581253..f3f0fe0215 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -138,7 +138,7 @@
if(src.dna.check_mutation(HULK))
to_chat(src, "Your meaty finger is much too large for the trigger guard!")
return FALSE
- if(NOGUNS in src.dna.species.species_traits)
+ if(has_trait(TRAIT_NOGUNS))
to_chat(src, "Your fingers don't fit in the trigger guard!")
return FALSE
if(mind)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 55e0325632..d47d68bf8b 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -228,11 +228,7 @@
return thermal_protection_flags
/mob/living/carbon/human/proc/get_cold_protection(temperature)
-
- if(dna.check_mutation(COLDRES))
- return TRUE //Fully protected from the cold.
-
- if(RESISTCOLD in dna.species.species_traits)
+ if(has_trait(TRAIT_RESISTCOLD))
return TRUE
//CITADEL EDIT Mandatory for vore code.
@@ -285,16 +281,14 @@
/mob/living/carbon/human/has_smoke_protection()
if(wear_mask)
if(wear_mask.flags_1 & BLOCK_GAS_SMOKE_EFFECT_1)
- . = 1
+ return TRUE
if(glasses)
if(glasses.flags_1 & BLOCK_GAS_SMOKE_EFFECT_1)
- . = 1
+ return TRUE
if(head)
if(head.flags_1 & BLOCK_GAS_SMOKE_EFFECT_1)
- . = 1
- if(NOBREATH in dna.species.species_traits)
- . = 1
- return .
+ return TRUE
+ return ..()
/mob/living/carbon/human/proc/handle_embedded_objects()
@@ -321,7 +315,7 @@
if(!can_heartattack())
return
- var/we_breath = (!(NOBREATH in dna.species.species_traits))
+ var/we_breath = !has_trait(TRAIT_NOBREATH, SPECIES_TRAIT)
if(!undergoing_cardiac_arrest())
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index c601f1445c..56ba4dff81 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -48,14 +48,12 @@
return real_name
/mob/living/carbon/human/IsVocal()
- CHECK_DNA_AND_SPECIES(src)
-
// how do species that don't breathe talk? magic, that's what.
- if(!(NOBREATH in dna.species.species_traits) && !getorganslot(ORGAN_SLOT_LUNGS))
- return 0
+ if(!has_trait(TRAIT_NOBREATH, SPECIES_TRAIT) && !getorganslot(ORGAN_SLOT_LUNGS))
+ return FALSE
if(mind)
return !mind.miming
- return 1
+ return TRUE
/mob/living/carbon/human/proc/SetSpecialVoice(new_voice)
if(new_voice)
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 3978811236..0c5f68d9ba 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -53,8 +53,10 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/damage_overlay_type = "human" //what kind of damage overlays (if any) appear on our species when wounded?
var/fixed_mut_color = "" //to use MUTCOLOR with a fixed color that's independent of dna.feature["mcolor"]
- // species flags. these can be found in flags.dm
+ // species-only traits. Can be found in DNA.dm
var/list/species_traits = list()
+ // generic traits tied to having the species
+ var/list/inherent_traits = list()
var/attack_verb = "punch" // punch-specific attack verb
var/sound/attack_sound = 'sound/weapons/punch1.ogg'
@@ -151,8 +153,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/should_have_brain = TRUE
var/should_have_heart = !(NOBLOOD in species_traits)
- var/should_have_lungs = !(NOBREATH in species_traits)
- var/should_have_appendix = !(NOHUNGER in species_traits)
+ var/should_have_lungs = !(TRAIT_NOBREATH in inherent_traits)
+ var/should_have_appendix = !(TRAIT_NOHUNGER in inherent_traits)
var/should_have_eyes = TRUE
var/should_have_ears = TRUE
var/should_have_tongue = TRUE
@@ -287,7 +289,10 @@ GLOBAL_LIST_EMPTY(roundstart_races)
else //Entries in the list should only ever be items or null, so if it's not an item, we can assume it's an empty hand
C.put_in_hands(new mutanthands())
- if(VIRUSIMMUNE in species_traits)
+ for(var/X in inherent_traits)
+ C.add_trait(X, SPECIES_TRAIT)
+
+ if(TRAIT_VIRUSIMMUNE in inherent_traits)
for(var/datum/disease/A in C.viruses)
A.cure(FALSE)
@@ -304,6 +309,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
C.dna.blood_type = random_blood_type()
if(DIGITIGRADE in species_traits)
C.Digitigrade_Leg_Swap(TRUE)
+ for(var/X in inherent_traits)
+ C.remove_trait(X, SPECIES_TRAIT)
/datum/species/proc/handle_hair(mob/living/carbon/human/H, forced_colour)
H.remove_overlay(HAIR_LAYER)
@@ -855,7 +862,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
//END EDIT
/datum/species/proc/spec_life(mob/living/carbon/human/H)
- if(NOBREATH in species_traits)
+ if(H.has_trait(TRAIT_NOBREATH))
H.setOxyLoss(0)
H.losebreath = 0
@@ -1111,8 +1118,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
H.update_inv_wear_suit()
// nutrition decrease and satiety
- if (H.nutrition > 0 && H.stat != DEAD && \
- H.dna && H.dna.species && (!(NOHUNGER in H.dna.species.species_traits)))
+ if (H.nutrition > 0 && H.stat != DEAD && !H.has_trait(TRAIT_NOHUNGER))
// THEY HUNGER
var/hunger_rate = HUNGER_FACTOR
if(H.satiety > 0)
@@ -1136,7 +1142,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(H.nutrition > NUTRITION_LEVEL_FAT)
H.metabolism_efficiency = 1
else if(H.nutrition > NUTRITION_LEVEL_FED && H.satiety > 80)
- if(H.metabolism_efficiency != 1.25 && (H.dna && H.dna.species && !(NOHUNGER in H.dna.species.species_traits)))
+ if(H.metabolism_efficiency != 1.25 && !H.has_trait(TRAIT_NOHUNGER))
to_chat(H, "You feel vigorous.")
H.metabolism_efficiency = 1.25
else if(H.nutrition < NUTRITION_LEVEL_STARVING + 50)
@@ -1165,7 +1171,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
. = FALSE
var/radiation = H.radiation
- if(RADIMMUNE in species_traits)
+ if(H.has_trait(TRAIT_RADIMMUNE))
radiation = 0
return TRUE
@@ -1285,7 +1291,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
add_logs(user, target, "shaked")
return 1
else
- var/we_breathe = (!(NOBREATH in user.dna.species.species_traits))
+ var/we_breathe = !user.has_trait(TRAIT_NOBREATH)
var/we_lung = user.getorganslot(ORGAN_SLOT_LUNGS)
if(we_breathe && we_lung)
@@ -1483,7 +1489,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
//dismemberment
var/probability = I.get_dismemberment_chance(affecting)
- if(prob(probability) || ((EASYDISMEMBER in species_traits) && prob(2*probability)))
+ if(prob(probability) || (H.has_trait(TRAIT_EASYDISMEMBER) && prob(2*probability)))
if(affecting.dismember(I.damtype))
I.add_mob_blood(H)
playsound(get_turf(H), I.get_dismember_sound(), 80, 1)
@@ -1612,7 +1618,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/////////////
/datum/species/proc/breathe(mob/living/carbon/human/H)
- if(NOBREATH in species_traits)
+ if(H.has_trait(TRAIT_NOBREATH))
return TRUE
/datum/species/proc/handle_environment(datum/gas_mixture/environment, mob/living/carbon/human/H)
@@ -1644,7 +1650,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + min(thermal_protection * (loc_temp - H.bodytemperature) / BODYTEMP_HEAT_DIVISOR, BODYTEMP_HEATING_MAX))
// +/- 50 degrees from 310K is the 'safe' zone, where no damage is dealt.
- if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !(RESISTHOT in species_traits))
+ if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !H.has_trait(TRAIT_RESISTHEAT))
//Body temperature is too hot.
var/burn_damage
switch(H.bodytemperature)
@@ -1683,7 +1689,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/adjusted_pressure = H.calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob.
switch(adjusted_pressure)
if(HAZARD_HIGH_PRESSURE to INFINITY)
- if(!(RESISTPRESSURE in species_traits))
+ if(!H.has_trait(TRAIT_RESISTHIGHPRESSURE))
H.adjustBruteLoss(min(((adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 ) * PRESSURE_DAMAGE_COEFFICIENT, MAX_HIGH_PRESSURE_DAMAGE) * H.physiology.pressure_mod)
H.throw_alert("pressure", /obj/screen/alert/highpressure, 2)
else
@@ -1695,7 +1701,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE)
H.throw_alert("pressure", /obj/screen/alert/lowpressure, 1)
else
- if(H.dna.check_mutation(COLDRES) || (RESISTPRESSURE in species_traits))
+ if(H.has_trait(TRAIT_RESISTLOWPRESSURE))
H.clear_alert("pressure")
else
H.adjustBruteLoss(LOW_PRESSURE_DAMAGE * H.physiology.pressure_mod)
@@ -1706,7 +1712,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
//////////
/datum/species/proc/handle_fire(mob/living/carbon/human/H, no_protection = FALSE)
- if(NOFIRE in species_traits)
+ if(H.has_trait(TRAIT_NOFIRE))
return
if(H.on_fire)
//the fire tries to damage the exposed clothes and items
@@ -1773,7 +1779,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
H.adjust_bodytemperature(BODYTEMP_HEATING_MAX + (H.fire_stacks * 12))
/datum/species/proc/CanIgniteMob(mob/living/carbon/human/H)
- if(NOFIRE in species_traits)
+ if(H.has_trait(TRAIT_NOFIRE))
return FALSE
return TRUE
diff --git a/code/modules/mob/living/carbon/human/species_types/abductors.dm b/code/modules/mob/living/carbon/human/species_types/abductors.dm
index 447245cad0..54549b15b9 100644
--- a/code/modules/mob/living/carbon/human/species_types/abductors.dm
+++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm
@@ -3,7 +3,8 @@
id = "abductor"
say_mod = "gibbers"
sexes = FALSE
- species_traits = list(SPECIES_ORGANIC,NOBLOOD,NOBREATH,VIRUSIMMUNE,NOGUNS,NOHUNGER,NOEYES)
+ species_traits = list(SPECIES_ORGANIC,NOBLOOD,NOEYES)
+ inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NOGUNS,TRAIT_NOHUNGER,TRAIT_NOBREATH)
mutanttongue = /obj/item/organ/tongue/abductor
var/scientist = FALSE // vars to not pollute spieces list with castes
diff --git a/code/modules/mob/living/carbon/human/species_types/android.dm b/code/modules/mob/living/carbon/human/species_types/android.dm
index 4badfa8405..0178a99dad 100644
--- a/code/modules/mob/living/carbon/human/species_types/android.dm
+++ b/code/modules/mob/living/carbon/human/species_types/android.dm
@@ -2,7 +2,8 @@
name = "Android"
id = "android"
say_mod = "states"
- species_traits = list(SPECIES_ROBOTIC,NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOBLOOD,PIERCEIMMUNE,NOHUNGER,EASYLIMBATTACHMENT)
+ species_traits = list(SPECIES_ROBOTIC,NOBLOOD)
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_LIMBATTACHMENT)
meat = null
damage_overlay_type = "synth"
mutanttongue = /obj/item/organ/tongue/robot
diff --git a/code/modules/mob/living/carbon/human/species_types/corporate.dm b/code/modules/mob/living/carbon/human/species_types/corporate.dm
index bc1fcc9b1e..7c4143ec6a 100644
--- a/code/modules/mob/living/carbon/human/species_types/corporate.dm
+++ b/code/modules/mob/living/carbon/human/species_types/corporate.dm
@@ -1,19 +1,20 @@
-/datum/species/corporate
- name = "Corporate Agent"
- id = "agent"
- hair_alpha = 0
- say_mod = "declares"
- speedmod = -2//Fast
- brutemod = 0.7//Tough against firearms
- burnmod = 0.65//Tough against lasers
- coldmod = 0
- heatmod = 0.5//it's a little tough to burn them to death not as hard though.
- punchdamagelow = 20
- punchdamagehigh = 30//they are inhumanly strong
- punchstunthreshold = 25
- attack_verb = "smash"
- attack_sound = 'sound/weapons/resonator_blast.ogg'
- blacklisted = 1
- use_skintones = 0
- species_traits = list(SPECIES_ORGANIC,RADIMMUNE,VIRUSIMMUNE,NOBLOOD,PIERCEIMMUNE,EYECOLOR,NODISMEMBER,NOHUNGER)
- sexes = 0
\ No newline at end of file
+/datum/species/corporate
+ name = "Corporate Agent"
+ id = "agent"
+ hair_alpha = 0
+ say_mod = "declares"
+ speedmod = -2//Fast
+ brutemod = 0.7//Tough against firearms
+ burnmod = 0.65//Tough against lasers
+ coldmod = 0
+ heatmod = 0.5//it's a little tough to burn them to death not as hard though.
+ punchdamagelow = 20
+ punchdamagehigh = 30//they are inhumanly strong
+ punchstunthreshold = 25
+ attack_verb = "smash"
+ attack_sound = 'sound/weapons/resonator_blast.ogg'
+ blacklisted = 1
+ use_skintones = 0
+ species_traits = list(SPECIES_ORGANIC,NOBLOOD,EYECOLOR)
+ inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER)
+ sexes = 0
diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
index 78cf1a3b7a..3a0e5a8415 100644
--- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm
+++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
@@ -2,7 +2,8 @@
name = "dullahan"
id = "dullahan"
default_color = "FFFFFF"
- species_traits = list(SPECIES_ORGANIC,EYECOLOR,HAIR,FACEHAIR,LIPS,NOBREATH,NOHUNGER)
+ species_traits = list(SPECIES_ORGANIC,EYECOLOR,HAIR,FACEHAIR,LIPS)
+ inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH)
mutant_bodyparts = list("tail_human", "ears", "wings")
default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "None")
use_skintones = TRUE
diff --git a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
index 1630b7a194..fba69e4e8b 100644
--- a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
@@ -247,7 +247,8 @@
name = "Slimeperson"
id = "slimeperson"
default_color = "00FFFF"
- species_traits = list(SPECIES_ORGANIC,MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD,TOXINLOVER)
+ species_traits = list(SPECIES_ORGANIC,MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
+ inherent_traits = list(TRAIT_TOXINLOVER)
mutant_bodyparts = list("mam_tail", "mam_ears", "taur")
default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None")
say_mod = "says"
diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm
index 3619e04584..d274261a2b 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -2,7 +2,8 @@
// Animated beings of stone. They have increased defenses, and do not need to breathe. They're also slow as fuuuck.
name = "Golem"
id = "iron golem"
- species_traits = list(SPECIES_INORGANIC,NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR)
+ species_traits = list(SPECIES_INORGANIC,NOBLOOD,MUTCOLORS,NO_UNDERWEAR)
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
mutant_organs = list(/obj/item/organ/adamantine_resonator)
speedmod = 2
armor = 55
@@ -84,7 +85,7 @@
fixed_mut_color = "a3d"
meat = /obj/item/stack/ore/plasma
//Can burn and takes damage from heat
- species_traits = list(SPECIES_INORGANIC,NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR)
+ inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
info_text = "As a Plasma Golem, you burn easily. Be careful, if you get hot enough while burning, you'll blow up!"
heatmod = 0 //fine until they blow up
prefix = "Plasma"
@@ -258,7 +259,7 @@
fixed_mut_color = "49311c"
meat = /obj/item/stack/sheet/mineral/wood
//Can burn and take damage from heat
- species_traits = list(SPECIES_ORGANIC,NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR)
+ inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
armor = 30
burnmod = 1.25
heatmod = 1.5
@@ -565,7 +566,7 @@
limbs_id = "cultgolem"
sexes = FALSE
info_text = "As a Runic Golem, you possess eldritch powers granted by the Elder God Nar'Sie."
- species_traits = list(SPECIES_INORGANIC,NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR,NOEYES) //no mutcolors
+ species_traits = list(SPECIES_INORGANIC,NOBLOOD,NO_UNDERWEAR,NOEYES) //no mutcolors
prefix = "Runic"
var/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/golem/phase_shift
@@ -619,7 +620,7 @@
limbs_id = "clockgolem"
info_text = "As a clockwork golem, you are faster than \
other types of golem (being a machine), and are immune to electric shocks."
- species_traits = list(SPECIES_INORGANIC,NO_UNDERWEAR, NOTRANSSTING, NOBREATH, NOZOMBIE, RADIMMUNE, NOBLOOD, RESISTCOLD, RESISTPRESSURE, PIERCEIMMUNE, NOEYES)
+ species_traits = list(SPECIES_ROBOTIC,NOBLOOD,NO_UNDERWEAR,NOEYES)
armor = 20 //Reinforced, but much less so to allow for fast movement
attack_verb = "smash"
attack_sound = 'sound/magic/clockwork/anima_fragment_attack.ogg'
@@ -671,7 +672,8 @@
limbs_id = "clothgolem"
sexes = FALSE
info_text = "As a Cloth Golem, you are able to reform yourself after death, provided your remains aren't burned or destroyed. You are, of course, very flammable."
- species_traits = list(SPECIES_UNDEAD,NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR) //no mutcolors, and can burn
+ species_traits = list(SPECIES_UNDEAD,NOBLOOD,NO_UNDERWEAR) //no mutcolors, and can burn
+ inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOGUNS)
armor = 15 //feels no pain, but not too resistant
burnmod = 2 // don't get burned
speedmod = 1 // not as heavy as stone
diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
index f32588d6b3..2297fffa97 100644
--- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
@@ -4,7 +4,8 @@
id = "jelly"
default_color = "00FF90"
say_mod = "chirps"
- species_traits = list(SPECIES_ORGANIC,MUTCOLORS,EYECOLOR,NOBLOOD,VIRUSIMMUNE,HAIR,FACEHAIR,TOXINLOVER) //CIT CHANGE - adds HAIR and FACEHAIR to species traits
+ species_traits = list(SPECIES_ORGANIC,MUTCOLORS,EYECOLOR,,HAIR,FACEHAIR,NOBLOOD)
+ inherent_traits = list(TRAIT_TOXINLOVER)
mutant_bodyparts = list("mam_tail", "mam_ears", "taur") //CIT CHANGE
default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None") //CIT CHANGE
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime
@@ -118,6 +119,7 @@
name = "Slimeperson"
id = "slime"
default_color = "00FFFF"
+ species_traits = list(SPECIES_ORGANIC,MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
say_mod = "says"
hair_color = "mutcolor"
hair_alpha = 150
diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
index 0d006196aa..15c8f70dc8 100644
--- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
@@ -54,4 +54,5 @@
name = "Ash Walker"
id = "ashlizard"
limbs_id = "lizard"
- species_traits = list(MUTCOLORS,EYECOLOR,LIPS,NOBREATH,NOGUNS,DIGITIGRADE)
+ species_traits = list(MUTCOLORS,EYECOLOR,LIPS,DIGITIGRADE)
+ inherent_traits = list(TRAIT_NOGUNS,TRAIT_NOBREATH)
diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
index a5c6720db5..5209fe8310 100644
--- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
@@ -4,7 +4,8 @@
say_mod = "rattles"
sexes = 0
meat = /obj/item/stack/sheet/mineral/plasma
- species_traits = list(SPECIES_INORGANIC,NOBLOOD,RESISTCOLD,RADIMMUNE,NOTRANSSTING,NOHUNGER)
+ species_traits = list(SPECIES_INORGANIC,NOBLOOD,NOTRANSSTING)
+ inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOHUNGER)
mutantlungs = /obj/item/organ/lungs/plasmaman
mutanttongue = /obj/item/organ/tongue/bone/plasmaman
mutantliver = /obj/item/organ/liver/plasmaman
diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
index 9357855191..17e7649cb6 100644
--- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
@@ -9,7 +9,8 @@
blacklisted = 1
ignored_by = list(/mob/living/simple_animal/hostile/faithless)
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/shadow
- species_traits = list(SPECIES_ORGANIC,NOBREATH,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,NOEYES)
+ species_traits = list(SPECIES_ORGANIC,NOBLOOD,NOEYES)
+ inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_NOBREATH)
dangerous_existence = 1
mutanteyes = /obj/item/organ/eyes/night_vision
@@ -37,7 +38,8 @@
burnmod = 1.5
blacklisted = TRUE
no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform, slot_s_store)
- species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR,NOHUNGER,NO_DNA_COPY,NOTRANSSTING,NOEYES)
+ species_traits = list(NOBLOOD,NO_UNDERWEAR,NO_DNA_COPY,NOTRANSSTING,NOEYES)
+ inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER)
mutanteyes = /obj/item/organ/eyes/night_vision/nightmare
mutant_organs = list(/obj/item/organ/heart/nightmare)
mutant_brain = /obj/item/organ/brain/nightmare
diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
index d47f3d71d5..c6a7e7a127 100644
--- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm
+++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
@@ -6,7 +6,8 @@
blacklisted = 1
sexes = 0
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
- species_traits = list(SPECIES_UNDEAD,NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYDISMEMBER,EASYLIMBATTACHMENT)
+ species_traits = list(SPECIES_UNDEAD,NOBLOOD)
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT)
mutanttongue = /obj/item/organ/tongue/bone
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
disliked_food = NONE
diff --git a/code/modules/mob/living/carbon/human/species_types/synths.dm b/code/modules/mob/living/carbon/human/species_types/synths.dm
index 856a472a73..786872544e 100644
--- a/code/modules/mob/living/carbon/human/species_types/synths.dm
+++ b/code/modules/mob/living/carbon/human/species_types/synths.dm
@@ -3,13 +3,15 @@
id = "synth"
say_mod = "beep boops" //inherited from a user's real species
sexes = 0
- species_traits = list(SPECIES_ROBOTIC,NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER) //all of these + whatever we inherit from the real species
+ species_traits = list(SPECIES_ROBOTIC,NOTRANSSTING) //all of these + whatever we inherit from the real species
+ inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER,TRAIT_NOBREATH)
dangerous_existence = 1
blacklisted = 1
meat = null
damage_overlay_type = "synth"
limbs_id = "synth"
- var/list/initial_species_traits = list(SPECIES_ROBOTIC,NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER,NO_DNA_COPY) //for getting these values back for assume_disguise()
+ var/list/initial_species_traits = list(SPECIES_ROBOTIC,NOTRANSSTING) //for getting these values back for assume_disguise()
+ var/list/initial_inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER,TRAIT_NOBREATH)
var/disguise_fail_health = 75 //When their health gets to this level their synthflesh partially falls off
var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged
@@ -41,7 +43,9 @@
say_mod = S.say_mod
sexes = S.sexes
species_traits = initial_species_traits.Copy()
+ inherent_traits = initial_inherent_traits.Copy()
species_traits |= S.species_traits
+ inherent_traits |= S.inherent_traits
species_traits -= list(SPECIES_ORGANIC, SPECIES_INORGANIC, SPECIES_UNDEAD)
attack_verb = S.attack_verb
attack_sound = S.attack_sound
@@ -61,6 +65,7 @@
name = initial(name)
say_mod = initial(say_mod)
species_traits = initial_species_traits.Copy()
+ inherent_traits = initial_inherent_traits.Copy()
attack_verb = initial(attack_verb)
attack_sound = initial(attack_sound)
miss_sound = initial(miss_sound)
diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm
index 5186811331..2267be85f2 100644
--- a/code/modules/mob/living/carbon/human/species_types/vampire.dm
+++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm
@@ -2,7 +2,8 @@
name = "vampire"
id = "vampire"
default_color = "FFFFFF"
- species_traits = list(SPECIES_UNDEAD,EYECOLOR,HAIR,FACEHAIR,LIPS,NOHUNGER,NOBREATH,DRINKSBLOOD)
+ species_traits = list(SPECIES_UNDEAD,EYECOLOR,HAIR,FACEHAIR,LIPS,DRINKSBLOOD)
+ inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH)
mutant_bodyparts = list("tail_human", "ears", "wings")
default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "None")
exotic_bloodtype = "U"
diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm
index 14502aa931..7fcc470661 100644
--- a/code/modules/mob/living/carbon/human/species_types/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm
@@ -8,7 +8,8 @@
sexes = 0
blacklisted = 1
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
- species_traits = list(SPECIES_UNDEAD,NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT,NOTRANSSTING)
+ species_traits = list(SPECIES_UNDEAD,NOBLOOD,NOZOMBIE,NOTRANSSTING)
+ inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH)
mutanttongue = /obj/item/organ/tongue/zombie
var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
disliked_food = NONE
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 8cbbc2b90f..5e5c77ee33 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -102,7 +102,9 @@
air_update_turf()
/mob/living/carbon/proc/has_smoke_protection()
- return 0
+ if(has_trait(TRAIT_NOBREATH))
+ return TRUE
+ return FALSE
//Third link in a breath chain, calls handle_breath_temperature()
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index 1c12b48919..71aea41e51 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -340,12 +340,9 @@
/mob/living/simple_animal/hostile/construct/harvester/AttackingTarget()
if(iscarbon(target))
- if(ishuman(target))
- var/mob/living/carbon/human/H = target
- if(H.dna && H.dna.species)
- if(NODISMEMBER in H.dna.species.species_traits)
- return ..() //ATTACK!
var/mob/living/carbon/C = target
+ if(C.has_trait(TRAIT_NODISMEMBER))
+ return ..() //ATTACK!
var/list/parts = list()
var/undismembermerable_limbs = 0
for(var/X in C.bodyparts)
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index 531c3b4257..2eed6c33d5 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -100,16 +100,14 @@
/datum/reagent/toxin/lexorin/on_mob_life(mob/living/M)
. = TRUE
- var/mob/living/carbon/C
- if(iscarbon(M))
- C = M
- CHECK_DNA_AND_SPECIES(C)
- if(NOBREATH in C.dna.species.species_traits)
- . = FALSE
+
+ if(M.has_trait(TRAIT_NOBREATH))
+ . = FALSE
if(.)
M.adjustOxyLoss(5, 0)
- if(C)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
C.losebreath += 2
if(prob(20))
M.emote("gasp")
diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm
index ae78123a26..a43e435977 100644
--- a/code/modules/station_goals/dna_vault.dm
+++ b/code/modules/station_goals/dna_vault.dm
@@ -256,24 +256,25 @@
var/obj/item/organ/lungs/L = H.internal_organs_slot[ORGAN_SLOT_LUNGS]
L.tox_breath_dam_min = 0
L.tox_breath_dam_max = 0
- S.species_traits |= VIRUSIMMUNE
+ H.add_trait(TRAIT_VIRUSIMMUNE, "dna_vault")
if(VAULT_NOBREATH)
to_chat(H, "Your lungs feel great.")
- S.species_traits |= NOBREATH
+ H.add_trait(TRAIT_NOBREATH, "dna_vault")
if(VAULT_FIREPROOF)
to_chat(H, "You feel fireproof.")
S.burnmod = 0.5
- S.heatmod = 0
+ H.add_trait(TRAIT_RESISTHEAT, "dna_vault")
+ H.add_trait(TRAIT_NOFIRE, "dna_vault")
if(VAULT_STUNTIME)
to_chat(H, "Nothing can keep you down for long.")
S.stunmod = 0.5
if(VAULT_ARMOUR)
to_chat(H, "You feel tough.")
S.armor = 30
-
+ H.add_trait(TRAIT_PIERCEIMMUNE, "dna_vault")
if(VAULT_SPEED)
to_chat(H, "Your legs feel faster.")
- S.speedmod = -1
+ H.add_trait(TRAIT_GOTTAGOFAST, "dna_vault")
if(VAULT_QUICK)
to_chat(H, "Your arms move as fast as lightning.")
H.next_move_modifier = 0.5
diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm
index c178d7f72f..133c22510e 100644
--- a/code/modules/surgery/bodyparts/bodyparts.dm
+++ b/code/modules/surgery/bodyparts/bodyparts.dm
@@ -62,7 +62,7 @@
/obj/item/bodypart/attack(mob/living/carbon/C, mob/user)
if(ishuman(C))
var/mob/living/carbon/human/H = C
- if(EASYLIMBATTACHMENT in H.dna.species.species_traits)
+ if(C.has_trait(TRAIT_LIMBATTACHMENT))
if(!H.get_bodypart(body_zone) && !animal_origin)
if(H == user)
H.visible_message("[H] jams [src] into [H.p_their()] empty socket!",\
diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm
index 10f2d182fe..7af437ae86 100644
--- a/code/modules/surgery/bodyparts/dismemberment.dm
+++ b/code/modules/surgery/bodyparts/dismemberment.dm
@@ -6,16 +6,14 @@
//Dismember a limb
/obj/item/bodypart/proc/dismember(dam_type = BRUTE)
if(!owner)
- return 0
+ return FALSE
var/mob/living/carbon/C = owner
if(!dismemberable)
- return 0
+ return FALSE
if(C.status_flags & GODMODE)
- return 0
- if(ishuman(C))
- var/mob/living/carbon/human/H = C
- if(NODISMEMBER in H.dna.species.species_traits) // species don't allow dismemberment
- return 0
+ return FALSE
+ if(C.has_trait(TRAIT_NODISMEMBER))
+ return FALSE
var/obj/item/bodypart/affecting = C.get_bodypart("chest")
affecting.receive_damage(CLAMP(brute_dam/2, 15, 50), CLAMP(burn_dam/2, 0, 50)) //Damage the chest based on limb's existing damage
@@ -46,14 +44,12 @@
/obj/item/bodypart/chest/dismember()
if(!owner)
- return 0
+ return FALSE
var/mob/living/carbon/C = owner
if(!dismemberable)
- return 0
- if(ishuman(C))
- var/mob/living/carbon/human/H = C
- if(NODISMEMBER in H.dna.species.species_traits) // species don't allow dismemberment
- return 0
+ return FALSE
+ if(C.has_trait(TRAIT_NODISMEMBER))
+ return FALSE
var/organ_spilled = 0
var/turf/T = get_turf(C)
diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm
index f492d99b8e..1aff20b81a 100644
--- a/code/modules/surgery/organs/lungs.dm
+++ b/code/modules/surgery/organs/lungs.dm
@@ -313,11 +313,7 @@
/obj/item/organ/lungs/proc/handle_breath_temperature(datum/gas_mixture/breath, mob/living/carbon/human/H) // called by human/life, handles temperatures
var/breath_temperature = breath.temperature
- var/species_traits = list()
- if(H && H.dna && H.dna.species && H.dna.species.species_traits)
- species_traits = H.dna.species.species_traits
-
- if(!(GLOB.mutations_list[COLDRES] in H.dna.mutations) && !(RESISTCOLD in species_traits)) // COLD DAMAGE
+ if(!H.has_trait(TRAIT_RESISTCOLD)) // COLD DAMAGE
var/cold_modifier = H.dna.species.coldmod
if(breath_temperature < cold_level_3_threshold)
H.apply_damage_type(cold_level_3_damage*cold_modifier, cold_damage_type)
@@ -329,7 +325,7 @@
if(prob(20))
to_chat(H, "You feel [cold_message] in your [name]!")
- if(!(RESISTHOT in species_traits)) // HEAT DAMAGE
+ if(!H.has_trait(TRAIT_RESISTHEAT)) // HEAT DAMAGE
var/heat_modifier = H.dna.species.heatmod
if(breath_temperature > heat_level_1_threshold && breath_temperature < heat_level_2_threshold)
H.apply_damage_type(heat_level_1_damage*heat_modifier, heat_damage_type)
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index fcaf89c61c..fe613af015 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -110,7 +110,7 @@
var/breathes = TRUE
var/blooded = TRUE
if(dna && dna.species)
- if(NOBREATH in dna.species.species_traits)
+ if(has_trait(TRAIT_NOBREATH, SPECIES_TRAIT))
breathes = FALSE
if(NOBLOOD in dna.species.species_traits)
blooded = FALSE