From d6a9459ee6d026d34fef69b504412003bacf83e8 Mon Sep 17 00:00:00 2001
From: LostInEtc <37387759+LostInEtc@users.noreply.github.com>
Date: Tue, 26 Jun 2018 11:22:46 -0500
Subject: [PATCH] Adds-Garymut
Mutation and makes people Gary. Gary? Gaaaaary?
Also changes their name on injection, and changes it back on removal.
---
dna_injector.dm | 473 ++++++++++++++++++++++++++++++++
genetics.dm | 101 +++++++
mutations.dm | 698 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 1272 insertions(+)
create mode 100644 dna_injector.dm
create mode 100644 genetics.dm
create mode 100644 mutations.dm
diff --git a/dna_injector.dm b/dna_injector.dm
new file mode 100644
index 0000000..237fc4f
--- /dev/null
+++ b/dna_injector.dm
@@ -0,0 +1,473 @@
+/obj/item/weapon/dnainjector
+ name = "\improper DNA injector"
+ desc = "This injects the person with DNA."
+ icon = 'icons/obj/items.dmi'
+ icon_state = "dnainjector"
+ throw_speed = 3
+ throw_range = 5
+ w_class = 1
+ origin_tech = "biotech=1"
+
+ var/damage_coeff = 1
+ var/list/fields
+ var/list/add_mutations = list()
+ var/list/remove_mutations = list()
+ var/used = 0
+
+/obj/item/weapon/dnainjector/attack_paw(mob/user)
+ return attack_hand(user)
+
+
+/obj/item/weapon/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
+ if(M.has_dna() && !(M.disabilities & 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)
+ HM.force_lose(M)
+ for(var/datum/mutation/human/HM in add_mutations)
+ if(HM.name == RACEMUT)
+ message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] (MONKEY)")
+ log_msg += " (MONKEY)"
+ HM.force_give(M)
+ if(fields)
+ if(fields["name"] && fields["UE"] && fields["blood_type"])
+ M.real_name = fields["name"]
+ M.dna.unique_enzymes = fields["UE"]
+ M.name = M.real_name
+ M.dna.blood_type = fields["blood_type"]
+ if(fields["UI"]) //UI+UE
+ M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
+ M.updateappearance(mutations_overlay_update=1)
+ log_attack(log_msg)
+ else
+ user << "It appears that [M] does not have compatible DNA."
+ return
+
+/obj/item/weapon/dnainjector/attack(mob/target, mob/user)
+ if(!user.IsAdvancedToolUser())
+ user << "You don't have the dexterity to do this!"
+ return
+ if(used)
+ user << "This injector is used up!"
+ return
+ if(ishuman(target))
+ var/mob/living/carbon/human/humantarget = target
+ if (!humantarget.can_inject(user, 1))
+ return
+ add_logs(user, target, "attempted to inject", src)
+
+ if(target != user)
+ target.visible_message("[user] is trying to inject [target] with [src]!", "[user] is trying to inject [target] with [src]!")
+ if(!do_mob(user, target)) return
+ target.visible_message("[user] injects [target] with the syringe with [src]!", \
+ "[user] injects [target] with the syringe with [src]!")
+
+ else
+ user << "You inject yourself with [src]."
+
+ add_logs(user, target, "injected", src)
+
+ inject(target, user) //Now we actually do the heavy lifting.
+ used = 1
+ icon_state = "dnainjector0"
+ desc += " This one is used up."
+
+
+/obj/item/weapon/dnainjector/antihulk
+ name = "\improper DNA injector (Anti-Hulk)"
+ desc = "Cures green skin."
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[HULK])
+
+/obj/item/weapon/dnainjector/hulkmut
+ name = "\improper DNA injector (Hulk)"
+ desc = "This will make you big and strong, but give you a bad skin condition."
+ New()
+ ..()
+ add_mutations.Add(mutations_list[HULK])
+/obj/item/weapon/dnainjector/xraymut
+ name = "\improper DNA injector (Xray)"
+ desc = "Finally you can see what the Captain does."
+ New()
+ ..()
+ add_mutations.Add(mutations_list[XRAY])
+
+/obj/item/weapon/dnainjector/antixray
+ name = "\improper DNA injector (Anti-Xray)"
+ desc = "It will make you see harder."
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[XRAY])
+
+/////////////////////////////////////
+/obj/item/weapon/dnainjector/antiglasses
+ name = "\improper DNA injector (Anti-Glasses)"
+ desc = "Toss away those glasses!"
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[BADSIGHT])
+
+/obj/item/weapon/dnainjector/glassesmut
+ name = "\improper DNA injector (Glasses)"
+ desc = "Will make you need dorkish glasses."
+ New()
+ ..()
+ add_mutations.Add(mutations_list[BADSIGHT])
+
+/obj/item/weapon/dnainjector/epimut
+ name = "\improper DNA injector (Epi.)"
+ desc = "Shake shake shake the room!"
+ New()
+ ..()
+ add_mutations.Add(mutations_list[EPILEPSY])
+
+/obj/item/weapon/dnainjector/antiepi
+ name = "\improper DNA injector (Anti-Epi.)"
+ desc = "Will fix you up from shaking the room."
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[EPILEPSY])
+////////////////////////////////////
+/obj/item/weapon/dnainjector/anticough
+ name = "\improper DNA injector (Anti-Cough)"
+ desc = "Will stop that aweful noise."
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[COUGH])
+
+/obj/item/weapon/dnainjector/coughmut
+ name = "\improper DNA injector (Cough)"
+ desc = "Will bring forth a sound of horror from your throat."
+ New()
+ ..()
+ add_mutations.Add(mutations_list[COUGH])
+
+/obj/item/weapon/dnainjector/antidwarf
+ name = "\improper DNA injector (Anti-Dwarfism)"
+ desc = "Helps you grow big and strong."
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[DWARFISM])
+
+/obj/item/weapon/dnainjector/dwarf
+ name = "\improper DNA injector (Dwarfism)"
+ desc = "Its a small world after all."
+ New()
+ ..()
+ add_mutations.Add(mutations_list[DWARFISM])
+
+/obj/item/weapon/dnainjector/clumsymut
+ name = "\improper DNA injector (Clumsy)"
+ desc = "Makes clown minions."
+ New()
+ ..()
+ add_mutations.Add(mutations_list[CLOWNMUT])
+
+/obj/item/weapon/dnainjector/anticlumsy
+ name = "\improper DNA injector (Anti-Clumy)"
+ desc = "Apply this for Security Clown."
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[CLOWNMUT])
+
+/obj/item/weapon/dnainjector/antitour
+ name = "\improper DNA injector (Anti-Tour.)"
+ desc = "Will cure tourrets."
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[TOURETTES])
+
+/obj/item/weapon/dnainjector/tourmut
+ name = "\improper DNA injector (Tour.)"
+ desc = "Gives you a nasty case off tourrets."
+ New()
+ ..()
+ add_mutations.Add(mutations_list[TOURETTES])
+
+/obj/item/weapon/dnainjector/stuttmut
+ name = "\improper DNA injector (Stutt.)"
+ desc = "Makes you s-s-stuttterrr"
+ New()
+ ..()
+ add_mutations.Add(mutations_list[NERVOUS])
+
+/obj/item/weapon/dnainjector/antistutt
+ name = "\improper DNA injector (Anti-Stutt.)"
+ desc = "Fixes that speaking impairment."
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[NERVOUS])
+
+/obj/item/weapon/dnainjector/antifire
+ name = "\improper DNA injector (Anti-Fire)"
+ desc = "Cures fire."
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[COLDRES])
+
+/obj/item/weapon/dnainjector/firemut
+ name = "\improper DNA injector (Fire)"
+ desc = "Gives you fire."
+ New()
+ ..()
+ add_mutations.Add(mutations_list[COLDRES])
+
+/obj/item/weapon/dnainjector/blindmut
+ name = "\improper DNA injector (Blind)"
+ desc = "Makes you not see anything."
+ New()
+ ..()
+ add_mutations.Add(mutations_list[BLINDMUT])
+
+/obj/item/weapon/dnainjector/antiblind
+ name = "\improper DNA injector (Anti-Blind)"
+ desc = "ITS A MIRACLE!!!"
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[BLINDMUT])
+
+/obj/item/weapon/dnainjector/antitele
+ name = "\improper DNA injector (Anti-Tele.)"
+ desc = "Will make you not able to control your mind."
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[TK])
+
+/obj/item/weapon/dnainjector/telemut
+ name = "\improper DNA injector (Tele.)"
+ desc = "Super brain man!"
+ New()
+ ..()
+ add_mutations.Add(mutations_list[TK])
+
+/obj/item/weapon/dnainjector/telemut/darkbundle
+ name = "\improper DNA injector"
+ desc = "Good. Let the hate flow through you."
+
+/obj/item/weapon/dnainjector/deafmut
+ name = "\improper DNA injector (Deaf)"
+ desc = "Sorry, what did you say?"
+ New()
+ ..()
+ add_mutations.Add(mutations_list[DEAFMUT])
+
+/obj/item/weapon/dnainjector/antideaf
+ name = "\improper DNA injector (Anti-Deaf)"
+ desc = "Will make you hear once more."
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[DEAFMUT])
+
+/obj/item/weapon/dnainjector/h2m
+ name = "\improper DNA injector (Human > Monkey)"
+ desc = "Will make you a flea bag."
+ New()
+ ..()
+ add_mutations.Add(mutations_list[RACEMUT])
+
+/obj/item/weapon/dnainjector/m2h
+ name = "\improper DNA injector (Monkey > Human)"
+ desc = "Will make you...less hairy."
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[RACEMUT])
+
+/obj/item/weapon/dnainjector/antistealth
+ name = "\improper DNA injector (Anti-Cloak Of Darkness)"
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[STEALTH])
+
+/obj/item/weapon/dnainjector/stealthmut
+ name = "\improper DNA injector (Cloak of Darkness)"
+ desc = "Enables the subject to bend low levels of light around themselves, creating a cloaking effect."
+ New()
+ ..()
+ add_mutations.Add(mutations_list[STEALTH])
+
+/obj/item/weapon/dnainjector/antichameleon
+ name = "\improper DNA injector (Anti-Chameleon)"
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[CHAMELEON])
+
+/obj/item/weapon/dnainjector/chameleonmut
+ name = "\improper DNA injector (Chameleon)"
+ New()
+ ..()
+ add_mutations.Add(mutations_list[CHAMELEON])
+
+/obj/item/weapon/dnainjector/antiwacky
+ name = "\improper DNA injector (Anti-Wacky)"
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[WACKY])
+
+/obj/item/weapon/dnainjector/wackymut
+ name = "\improper DNA injector (Wacky)"
+ New()
+ ..()
+ add_mutations.Add(mutations_list[WACKY])
+
+/obj/item/weapon/dnainjector/antimute
+ name = "\improper DNA injector (Anti-Mute)"
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[MUT_MUTE])
+
+/obj/item/weapon/dnainjector/mutemut
+ name = "\improper DNA injector (Mute)"
+ New()
+ ..()
+ add_mutations.Add(mutations_list[MUT_MUTE])
+
+/obj/item/weapon/dnainjector/antismile
+ name = "\improper DNA injector (Anti-Smile)"
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[SMILE])
+
+/obj/item/weapon/dnainjector/smilemut
+ name = "\improper DNA injector (Smile)"
+ New()
+ ..()
+ add_mutations.Add(mutations_list[SMILE])
+
+/obj/item/weapon/dnainjector/unintelligablemut
+ name = "\improper DNA injector (Unintelligable)"
+ New()
+ ..()
+ add_mutations.Add(mutations_list[UNINTELLIGABLE])
+
+/obj/item/weapon/dnainjector/antiunintelligable
+ name = "\improper DNA injector (Anti-Unintelligable)"
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[UNINTELLIGABLE])
+
+/obj/item/weapon/dnainjector/swedishmut
+ name = "\improper DNA injector (Swedish)"
+ New()
+ ..()
+ add_mutations.Add(mutations_list[SWEDISH])
+
+/obj/item/weapon/dnainjector/antiswedish
+ name = "\improper DNA injector (Anti-Swedish)"
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[SWEDISH])
+
+/obj/item/weapon/dnainjector/chavmut
+ name = "\improper DNA injector (Chav)"
+ New()
+ ..()
+ add_mutations.Add(mutations_list[CHAV])
+
+/obj/item/weapon/dnainjector/antichav
+ name = "\improper DNA injector (Anti-Chav)"
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[CHAV])
+
+/obj/item/weapon/dnainjector/elvismut
+ name = "\improper DNA injector (Elvis)"
+ New()
+ ..()
+ add_mutations.Add(mutations_list[ELVIS])
+
+/obj/item/weapon/dnainjector/antielvis
+ name = "\improper DNA injector (Anti-Elvis)"
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[ELVIS])
+
+/obj/item/weapon/dnainjector/lasereyesmut
+ name = "\improper DNA injector (Laser Eyes)"
+ New()
+ ..()
+ add_mutations.Add(mutations_list[LASEREYES])
+
+/obj/item/weapon/dnainjector/antilasereyes
+ name = "\improper DNA injector (Anti-Laser Eyes)"
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[LASEREYES])
+
+/obj/item/weapon/dnainjector/garymut
+ name = "\improper DNA injector (Gary)"
+ New()
+ ..()
+ add_mutations.Add(mutations_list[GARY])
+
+/obj/item/weapon/dnainjector/antigary
+ name = "\improper DNA injector (Anti-Gary)"
+ New()
+ ..()
+ remove_mutations.Add(mutations_list[GARY])
+
+/obj/item/weapon/dnainjector/timed
+ var/duration = 600
+
+/obj/item/weapon/dnainjector/timed/inject(mob/living/carbon/M, mob/user)
+ if(M.has_dna() && !(M.disabilities & NOCLONE))
+ if(M.stat == DEAD) //prevents dead people from having their DNA changed
+ user << "You can't modify [M]'s DNA while \he's dead."
+ return
+ M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
+ var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
+ var/endtime = world.time+duration
+ for(var/datum/mutation/human/HM in remove_mutations)
+ if(HM.name == RACEMUT)
+ if(ishuman(M))
+ continue
+ M = HM.force_lose(M)
+ else
+ HM.force_lose(M)
+ for(var/datum/mutation/human/HM in add_mutations)
+ if((HM in M.dna.mutations) && !(M.dna.temporary_mutations[HM.name]))
+ continue //Skip permanent mutations we already have.
+ if(HM.name == RACEMUT && ishuman(M))
+ message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] (MONKEY)")
+ log_msg += " (MONKEY)"
+ M = HM.force_give(M)
+ else
+ HM.force_give(M)
+ M.dna.temporary_mutations[HM.name] = endtime
+ if(fields)
+ if(fields["name"] && fields["UE"] && fields["blood_type"])
+ if(!M.dna.previous["name"])
+ M.dna.previous["name"] = M.real_name
+ if(!M.dna.previous["UE"])
+ M.dna.previous["UE"] = M.dna.unique_enzymes
+ if(!M.dna.previous["blood_type"])
+ M.dna.previous["blood_type"] = M.dna.blood_type
+ M.real_name = fields["name"]
+ M.dna.unique_enzymes = fields["UE"]
+ M.name = M.real_name
+ M.dna.blood_type = fields["blood_type"]
+ M.dna.temporary_mutations[UE_CHANGED] = endtime
+ if(fields["UI"]) //UI+UE
+ if(!M.dna.previous["UI"])
+ M.dna.previous["UI"] = M.dna.uni_identity
+ M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
+ M.updateappearance(mutations_overlay_update=1)
+ M.dna.temporary_mutations[UI_CHANGED] = endtime
+ log_attack(log_msg)
+ else
+ user << "It appears that [M] does not have compatible DNA."
+ return
+
+/obj/item/weapon/dnainjector/timed/hulk
+ name = "\improper DNA injector (Hulk)"
+ desc = "This will make you big and strong, but give you a bad skin condition."
+ New()
+ ..()
+ add_mutations.Add(mutations_list[HULK])
+
+/obj/item/weapon/dnainjector/timed/h2m
+ name = "\improper DNA injector (Human > Monkey)"
+ desc = "Will make you a flea bag."
+ New()
+ ..()
+ add_mutations.Add(mutations_list[RACEMUT])
diff --git a/genetics.dm b/genetics.dm
new file mode 100644
index 0000000..2168d91
--- /dev/null
+++ b/genetics.dm
@@ -0,0 +1,101 @@
+
+//Defines copying names of mutations in all cases, make sure to change this if you change mutation's name
+#define HULK "Hulk"
+#define XRAY "X Ray Vision"
+#define COLDRES "Cold Resistance"
+#define TK "Telekinesis"
+#define NERVOUS "Nervousness"
+#define EPILEPSY "Epilepsy"
+#define MUTATE "Unstable DNA"
+#define COUGH "Cough"
+#define DWARFISM "Dwarfism"
+#define CLOWNMUT "Clumsiness"
+#define TOURETTES "Tourettes Syndrome"
+#define DEAFMUT "Deafness"
+#define BLINDMUT "Blindness"
+#define RACEMUT "Monkified"
+#define BADSIGHT "Near Sightness"
+#define LASEREYES "Laser Eyes"
+#define STEALTH "Cloak Of Darkness"
+#define CHAMELEON "Chameleon"
+#define WACKY "Wacky"
+#define MUT_MUTE "Mute"
+#define SMILE "Smile"
+#define UNINTELLIGABLE "Unintelligable"
+#define SWEDISH "Swedish"
+#define CHAV "Chav"
+#define ELVIS "Elvis"
+#define GARY "Gary"
+
+#define UI_CHANGED "ui changed"
+#define UE_CHANGED "ue changed"
+
+#define CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY 204
+
+// String identifiers for associative list lookup
+
+//Types of usual mutations
+#define POSITIVE 1
+#define NEGATIVE 2
+#define MINOR_NEGATIVE 3
+
+//Mutations that cant be taken from genetics and are not in SE
+#define NON_SCANNABLE -1
+
+ // Extra powers:
+#define LASER 9 // harm intent - click anywhere to shoot lasers from eyes
+#define HEAL 10 // healing people with hands
+#define SHADOW 11 // shadow teleportation (create in/out portals anywhere) (25%)
+#define SCREAM 12 // supersonic screaming (25%)
+#define EXPLOSIVE 13 // exploding on-demand (15%)
+#define REGENERATION 14 // superhuman regeneration (30%)
+#define REPROCESSOR 15 // eat anything (50%)
+#define SHAPESHIFTING 16 // take on the appearance of anything (40%)
+#define PHASING 17 // ability to phase through walls (40%)
+#define SHIELD 18 // shielding from all projectile attacks (30%)
+#define SHOCKWAVE 19 // attack a nearby tile and cause a massive shockwave, knocking most people on their asses (25%)
+#define ELECTRICITY 20 // ability to shoot electric attacks (15%)
+
+//DNA - Because fuck you and your magic numbers being all over the codebase.
+#define DNA_BLOCK_SIZE 3
+
+#define DNA_UNI_IDENTITY_BLOCKS 7
+#define DNA_HAIR_COLOR_BLOCK 1
+#define DNA_FACIAL_HAIR_COLOR_BLOCK 2
+#define DNA_SKIN_TONE_BLOCK 3
+#define DNA_EYE_COLOR_BLOCK 4
+#define DNA_GENDER_BLOCK 5
+#define DNA_FACIAL_HAIR_STYLE_BLOCK 6
+#define DNA_HAIR_STYLE_BLOCK 7
+
+#define DNA_STRUC_ENZYMES_BLOCKS 20
+#define DNA_UNIQUE_ENZYMES_LEN 32
+
+//Transformation proc stuff
+#define TR_KEEPITEMS 1
+#define TR_KEEPVIRUS 2
+#define TR_KEEPDAMAGE 4
+#define TR_HASHNAME 8 // hashing names (e.g. monkey(e34f)) (only in monkeyize)
+#define TR_KEEPIMPLANTS 16
+#define TR_KEEPSE 32 // changelings shouldn't edit the DNA's SE when turning into a monkey
+#define TR_DEFAULTMSG 64
+#define TR_KEEPSRC 128
+#define TR_KEEPORGANS 256
+
+//Organ stuff, It's here because "Genetics" is the most relevant file for organs
+#define ORGAN_ORGANIC 1
+#define ORGAN_ROBOTIC 2
+
+//Nutrition levels for humans. No idea where else to put it
+#define NUTRITION_LEVEL_FAT 600
+#define NUTRITION_LEVEL_FULL 550
+#define NUTRITION_LEVEL_WELL_FED 450
+#define NUTRITION_LEVEL_FED 350
+#define NUTRITION_LEVEL_HUNGRY 250
+#define NUTRITION_LEVEL_STARVING 150
+
+#define THIRST_LEVEL_FULL 400
+#define THIRST_LEVEL_LIGHT 300
+#define THIRST_LEVEL_MIDDLE 200
+#define THIRST_LEVEL_HARD 100
+#define THIRST_LEVEL_DEADLY 75
\ No newline at end of file
diff --git a/mutations.dm b/mutations.dm
new file mode 100644
index 0000000..5a5f7e1
--- /dev/null
+++ b/mutations.dm
@@ -0,0 +1,698 @@
+/var/global/list/mutations_list = list()
+
+/datum/mutation/
+
+ var/name
+
+/datum/mutation/New()
+ mutations_list[name] = src
+
+/datum/mutation/human
+
+ var/backupname
+ var/dna_block
+ var/quality
+ var/get_chance = 100
+ var/lowest_value = 256 * 8
+ var/text_gain_indication = ""
+ var/text_lose_indication = ""
+ var/list/visual_indicators = list()
+ var/layer_used = MUTATIONS_LAYER //which mutation layer to use
+ var/list/species_allowed = list() //to restrict mutation to only certain species
+ var/health_req //minimum health required to acquire the mutation
+ var/time_coeff = 1 //coefficient for timed mutations
+
+/datum/mutation/human/proc/force_give(mob/living/carbon/human/owner)
+ set_block(owner)
+ . = on_acquiring(owner)
+
+/datum/mutation/human/proc/force_lose(mob/living/carbon/human/owner)
+ set_block(owner, 0)
+ . = on_losing(owner)
+
+/datum/mutation/human/proc/set_se(se_string, on = 1)
+ if(!se_string || lentext(se_string) < DNA_STRUC_ENZYMES_BLOCKS * DNA_BLOCK_SIZE) return
+ var/before = copytext(se_string, 1, ((dna_block - 1) * DNA_BLOCK_SIZE) + 1)
+ var/injection = num2hex(on ? rand(lowest_value, (256 * 16) - 1) : rand(0, lowest_value - 1), DNA_BLOCK_SIZE)
+ var/after = copytext(se_string, (dna_block * DNA_BLOCK_SIZE) + 1, 0)
+ return before + injection + after
+
+/datum/mutation/human/proc/set_block(mob/living/carbon/owner, on = 1)
+ if(owner && owner.has_dna())
+ owner.dna.struc_enzymes = set_se(owner.dna.struc_enzymes, on)
+
+/datum/mutation/human/proc/check_block_string(se_string)
+ if(!se_string || lentext(se_string) < DNA_STRUC_ENZYMES_BLOCKS * DNA_BLOCK_SIZE) return 0
+ if(hex2num(getblock(se_string, dna_block)) >= lowest_value)
+ return 1
+
+/datum/mutation/human/proc/check_block(mob/living/carbon/human/owner)
+ if(check_block_string(owner.dna.struc_enzymes))
+ if(prob(get_chance))
+ . = on_acquiring(owner)
+ else
+ . = on_losing(owner)
+
+/datum/mutation/human/proc/on_acquiring(mob/living/carbon/human/owner)
+ if(!owner || !istype(owner) || owner.stat == DEAD || (src in owner.dna.mutations))
+ return 1
+ if(species_allowed.len && !species_allowed.Find(owner.dna.species.id))
+ return 1
+ if(health_req && owner.health < health_req)
+ return 1
+ owner.dna.mutations.Add(src)
+ if(text_gain_indication)
+ owner << text_gain_indication
+ if(visual_indicators.len)
+ var/list/mut_overlay = list(get_visual_indicator(owner))
+ if(owner.overlays_standing[layer_used])
+ mut_overlay = owner.overlays_standing[layer_used]
+ mut_overlay |= get_visual_indicator(owner)
+ owner.remove_overlay(layer_used)
+ owner.overlays_standing[layer_used] = mut_overlay
+ owner.apply_overlay(layer_used)
+
+/datum/mutation/human/proc/get_visual_indicator(mob/living/carbon/human/owner)
+ return
+
+/datum/mutation/human/proc/on_attack_hand(mob/living/carbon/human/owner, atom/target)
+ return
+
+/datum/mutation/human/proc/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
+ return
+
+/datum/mutation/human/proc/on_move(mob/living/carbon/human/owner, new_loc)
+ return
+
+/datum/mutation/human/proc/on_life(mob/living/carbon/human/owner)
+ return
+
+/datum/mutation/human/proc/on_losing(mob/living/carbon/human/owner)
+ if(owner && istype(owner) && (owner.dna.mutations.Remove(src)))
+ if(text_lose_indication && owner.stat != DEAD)
+ owner << text_lose_indication
+ if(visual_indicators.len)
+ var/list/mut_overlay = list()
+ if(owner.overlays_standing[layer_used])
+ mut_overlay = owner.overlays_standing[layer_used]
+ owner.remove_overlay(layer_used)
+ mut_overlay.Remove(get_visual_indicator(owner))
+ owner.overlays_standing[layer_used] = mut_overlay
+ owner.apply_overlay(layer_used)
+ return 0
+ return 1
+
+/datum/mutation/human/proc/say_mod(message)
+ if(message)
+ return message
+
+/datum/mutation/human/proc/get_spans()
+ return list()
+
+/datum/mutation/human/hulk
+
+ name = "Hulk"
+ quality = POSITIVE
+ get_chance = 15
+ lowest_value = 256 * 12
+ text_gain_indication = "Your muscles hurt!"
+ species_allowed = list("human") //no skeleton/lizard hulk
+ health_req = 25
+
+/datum/mutation/human/hulk/New()
+ ..()
+ visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="hulk_f_s", "layer"=-MUTATIONS_LAYER)
+ visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="hulk_m_s", "layer"=-MUTATIONS_LAYER)
+
+/datum/mutation/human/hulk/on_acquiring(mob/living/carbon/human/owner)
+ if(..())
+ return
+ var/status = CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH
+ owner.status_flags &= ~status
+
+/datum/mutation/human/hulk/on_attack_hand(mob/living/carbon/human/owner, atom/target)
+ return target.attack_hulk(owner)
+
+/datum/mutation/human/hulk/get_visual_indicator(mob/living/carbon/human/owner)
+ var/g = (owner.gender == FEMALE) ? 1 : 2
+ return visual_indicators[g]
+
+/datum/mutation/human/hulk/on_life(mob/living/carbon/human/owner)
+ if(owner.health < 0)
+ on_losing(owner)
+ owner << "You suddenly feel very weak."
+
+/datum/mutation/human/hulk/on_losing(mob/living/carbon/human/owner)
+ if(..())
+ return
+ owner.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH
+
+/datum/mutation/human/hulk/say_mod(message)
+ if(message)
+ message = "[uppertext(replacetext(message, ".", "!"))]!!"
+ return message
+
+/datum/mutation/human/telekinesis
+
+ name = "Telekinesis"
+ quality = POSITIVE
+ get_chance = 20
+ lowest_value = 256 * 12
+ text_gain_indication = "You feel smarter!"
+
+/datum/mutation/human/telekinesis/New()
+ ..()
+ visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="telekinesishead_s", "layer"=-MUTATIONS_LAYER)
+
+/datum/mutation/human/telekinesis/get_visual_indicator(mob/living/carbon/human/owner)
+ return visual_indicators[1]
+
+/datum/mutation/human/telekinesis/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
+ target.attack_tk(owner)
+
+/datum/mutation/human/cold_resistance
+
+ name = "Cold Resistance"
+ quality = POSITIVE
+ get_chance = 25
+ lowest_value = 256 * 12
+ text_gain_indication = "Your body feels warm!"
+ time_coeff = 5
+
+/datum/mutation/human/cold_resistance/New()
+ ..()
+ visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="fire_s", "layer"=-MUTATIONS_LAYER)
+
+/datum/mutation/human/cold_resistance/get_visual_indicator(mob/living/carbon/human/owner)
+ return visual_indicators[1]
+
+/datum/mutation/human/cold_resistance/on_life(mob/living/carbon/human/owner)
+ if(owner.getFireLoss())
+ if(prob(1))
+ owner.heal_organ_damage(0,1) //Is this really needed?
+
+/datum/mutation/human/x_ray
+
+ name = "X Ray Vision"
+ quality = POSITIVE
+ get_chance = 25
+ lowest_value = 256 * 12
+ text_gain_indication = "The walls suddenly disappear!"
+ time_coeff = 2
+
+/datum/mutation/human/x_ray/on_acquiring(mob/living/carbon/human/owner)
+ if(..())
+ return
+ on_life(owner)
+
+/datum/mutation/human/x_ray/on_life(mob/living/carbon/human/owner)
+ owner.sight |= SEE_MOBS|SEE_OBJS|SEE_TURFS
+ owner.see_in_dark = 8
+
+/datum/mutation/human/x_ray/on_losing(mob/living/carbon/human/owner)
+ if(..())
+ return
+ if((SEE_MOBS & owner.permanent_sight_flags) && (SEE_OBJS & owner.permanent_sight_flags) && (SEE_TURFS & owner.permanent_sight_flags)) //Xray flag combo
+ return
+ owner.see_in_dark = initial(owner.see_in_dark)
+ owner.sight = initial(owner.sight)
+
+/datum/mutation/human/nearsight
+
+ name = "Near Sightness"
+ quality = MINOR_NEGATIVE
+ text_gain_indication = "You can't see very well."
+
+/datum/mutation/human/nearsight/on_acquiring(mob/living/carbon/human/owner)
+ if(..())
+ return
+ owner.disabilities |= NEARSIGHT
+
+/datum/mutation/human/nearsight/on_losing(mob/living/carbon/human/owner)
+ if(..())
+ return
+ owner.disabilities &= ~NEARSIGHT
+
+/datum/mutation/human/epilepsy
+
+ name = "Epilepsy"
+ quality = NEGATIVE
+ text_gain_indication = "You get a headache."
+
+/datum/mutation/human/epilepsy/on_life(mob/living/carbon/human/owner)
+ if((prob(1) && owner.paralysis < 1))
+ owner.visible_message("[owner] starts having a seizure!", "You have a seizure!")
+ owner.Paralyse(10)
+ owner.Jitter(1000)
+ spawn(90)
+ owner.jitteriness = 10
+
+/datum/mutation/human/bad_dna
+
+ name = "Unstable DNA"
+ quality = NEGATIVE
+ text_gain_indication = "You feel strange."
+
+/datum/mutation/human/bad_dna/on_acquiring(mob/living/carbon/human/owner)
+ owner << text_gain_indication
+ var/mob/new_mob
+ if(prob(95))
+ if(prob(50))
+ new_mob = randmutb(owner)
+ else
+ new_mob = randmuti(owner)
+ else
+ new_mob = randmutg(owner)
+ if(new_mob && ismob(new_mob))
+ owner = new_mob
+ . = owner
+ on_losing(owner)
+
+/datum/mutation/human/cough
+
+ name = "Cough"
+ quality = MINOR_NEGATIVE
+ text_gain_indication = "You start coughing."
+
+/datum/mutation/human/cough/on_life(mob/living/carbon/human/owner)
+ if((prob(5) && owner.paralysis <= 1))
+ owner.drop_item()
+ owner.emote("cough")
+
+/datum/mutation/human/dwarfism
+
+ name = "Dwarfism"
+ quality = POSITIVE
+ get_chance = 15
+ lowest_value = 256 * 12
+ text_gain_indication = "Everything around you seems to grow.."
+ text_lose_indication = "Everything around you seems to shrink.."
+
+/datum/mutation/human/dwarfism/on_acquiring(mob/living/carbon/human/owner)
+ if(..()) return
+ owner.resize = 0.8
+ owner.pass_flags |= PASSTABLE
+ owner.visible_message("[owner] suddenly shrinks!")
+
+/datum/mutation/human/dwarfism/on_losing(mob/living/carbon/human/owner)
+ if(..()) return
+ owner.resize = 1.25
+ owner.pass_flags &= ~PASSTABLE
+ owner.visible_message("[owner] suddenly grows!")
+
+/datum/mutation/human/clumsy
+
+ name = "Clumsiness"
+ quality = MINOR_NEGATIVE
+ text_gain_indication = "You feel lightheaded."
+
+/datum/mutation/human/clumsy/on_acquiring(mob/living/carbon/human/owner)
+ if(..()) return
+ owner.disabilities |= CLUMSY
+
+/datum/mutation/human/clumsy/on_losing(mob/living/carbon/human/owner)
+ if(..())
+ return
+ owner.disabilities &= ~CLUMSY
+
+/datum/mutation/human/tourettes
+
+ name = "Tourettes Syndrome"
+ quality = NEGATIVE
+ text_gain_indication = "You twitch."
+
+/datum/mutation/human/tourettes/on_life(mob/living/carbon/human/owner)
+ if((prob(10) && owner.paralysis <= 1))
+ owner.Stun(10)
+ switch(rand(1, 3))
+ if(1)
+ owner.emote("twitch")
+ if(2 to 3)
+ owner.say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]")
+ var/x_offset_old = owner.pixel_x
+ var/y_offset_old = owner.pixel_y
+ var/x_offset = owner.pixel_x + rand(-2,2)
+ var/y_offset = owner.pixel_y + rand(-1,1)
+ animate(owner, pixel_x = x_offset, pixel_y = y_offset, time = 1)
+ animate(owner, pixel_x = x_offset_old, pixel_y = y_offset_old, time = 1)
+
+/datum/mutation/human/nervousness
+
+ name = "Nervousness"
+ quality = MINOR_NEGATIVE
+ text_gain_indication = "You feel nervous."
+
+/datum/mutation/human/nervousness/on_life(mob/living/carbon/human/owner)
+ if(prob(10))
+ owner.stuttering = max(10, owner.stuttering)
+
+/datum/mutation/human/deaf
+
+ name = "Deafness"
+ quality = NEGATIVE
+ text_gain_indication = "You can't seem to hear anything."
+
+/datum/mutation/human/deaf/on_acquiring(mob/living/carbon/human/owner)
+ if(..()) return
+ owner.disabilities |= DEAF
+
+/datum/mutation/human/deaf/on_losing(mob/living/carbon/human/owner)
+ if(..())
+ return
+ owner.disabilities &= ~DEAF
+
+/datum/mutation/human/blind
+
+ name = "Blindness"
+ quality = NEGATIVE
+ text_gain_indication = "You can't seem to see anything."
+
+/datum/mutation/human/blind/on_acquiring(mob/living/carbon/human/owner)
+ if(..()) return
+ owner.disabilities |= BLIND
+
+/datum/mutation/human/blind/on_losing(mob/living/carbon/human/owner)
+ if(..())
+ return
+ owner.disabilities &= ~BLIND
+
+/datum/mutation/human/race
+
+ name = "Monkified"
+ quality = NEGATIVE
+ time_coeff = 2
+
+/datum/mutation/human/race/on_acquiring(mob/living/carbon/human/owner)
+ if(..())
+ return
+ . = owner.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
+
+/datum/mutation/human/race/on_losing(mob/living/carbon/monkey/owner)
+ if(owner && istype(owner) && owner.stat != DEAD && (owner.dna.mutations.Remove(src)))
+ . = owner.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
+
+
+/datum/mutation/human/stealth
+ name = "Cloak Of Darkness"
+ quality = POSITIVE
+ get_chance = 25
+ lowest_value = 256 * 12
+ text_gain_indication = "You begin to fade into the shadows."
+ text_lose_indication = "You become fully visible."
+ time_coeff = 5
+
+
+/datum/mutation/human/stealth/on_life(mob/living/carbon/human/owner)
+ var/turf/simulated/T = get_turf(owner)
+ if(!istype(T))
+ return
+ if(T.lighting_lumcount <= 2)
+ owner.alpha -= 25
+ else
+ if(!owner.dna.check_mutation(CHAMELEON))
+ owner.alpha = round(255 * 0.80)
+
+/datum/mutation/human/stealth/on_losing(mob/living/carbon/human/owner)
+ if(..())
+ return
+ owner.alpha = 255
+
+/datum/mutation/human/chameleon
+ name = "Chameleon"
+ quality = POSITIVE
+ get_chance = 20
+ lowest_value = 256 * 12
+ text_gain_indication = "You feel one with your surroundings."
+ text_lose_indication = "You feel oddly exposed."
+ time_coeff = 5
+
+/datum/mutation/human/chameleon/on_acquiring(mob/living/carbon/human/owner)
+ if(..())
+ return
+ owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
+
+/datum/mutation/human/chameleon/on_life(mob/living/carbon/human/owner)
+ owner.alpha = max(0, owner.alpha - 25)
+
+/datum/mutation/human/chameleon/on_move(mob/living/carbon/human/owner)
+ owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
+
+/datum/mutation/human/chameleon/on_losing(mob/living/carbon/human/owner)
+ if(..())
+ return
+ owner.alpha = 255
+
+/datum/mutation/human/wacky
+ name = "Wacky"
+ quality = MINOR_NEGATIVE
+ text_gain_indication = "You feel an off sensation in your voicebox."
+ text_lose_indication = "The off sensation passes."
+
+/datum/mutation/human/wacky/get_spans()
+ return list(SPAN_SANS)
+
+/datum/mutation/human/mute
+ name = "Mute"
+ quality = NEGATIVE
+ text_gain_indication = "You feel unable to express yourself at all."
+ text_lose_indication = "You feel able to speak freely again."
+
+/datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner)
+ if(..())
+ return
+ owner.disabilities |= MUTE
+
+/datum/mutation/human/mute/on_losing(mob/living/carbon/human/owner)
+ if(..())
+ return
+ owner.disabilities &= ~MUTE
+
+/datum/mutation/human/gary
+ name = "Gary"
+ quality = MINOR_NEGATIVE
+ text_gain_indication = "Gary?"
+ text_lose_indication = "You feel significantly less Gary than before.."
+
+/datum/mutation/human/gary/say_mod(message)
+ if(message)
+ message = " [message] "
+ //Babies first line of code.
+ message = replacetext(message, message,pick("Gaaaary...","Gary!","...Gary?"))
+ return trim(message)
+
+/datum/mutation/human/gary/on_acquiring(mob/living/carbon/human/owner)
+ backupname = owner.real_name
+ if(..())
+ return
+ owner.real_name = "Gary"
+
+/datum/mutation/human/gary/on_losing(mob/living/carbon/human/owner)
+ if(..())
+ return
+ owner.real_name = backupname
+
+/datum/mutation/human/smile
+ name = "Smile"
+ quality = MINOR_NEGATIVE
+ dna_block = NON_SCANNABLE
+ text_gain_indication = "You feel so happy. Nothing can be wrong with anything. :)"
+ text_lose_indication = "Everything is terrible again. :("
+
+/datum/mutation/human/smile/say_mod(message)
+ if(message)
+ message = " [message] "
+ //Time for a friendly game of SS13
+ message = replacetext(message," stupid "," smart ")
+ message = replacetext(message," retard "," genius ")
+ message = replacetext(message," unrobust "," robust ")
+ message = replacetext(message," dumb "," smart ")
+ message = replacetext(message," awful "," great ")
+ message = replacetext(message," gay ",pick(" nice "," ok "," alright "))
+ message = replacetext(message," horrible "," fun ")
+ message = replacetext(message," terrible "," terribly fun ")
+ message = replacetext(message," terrifying "," wonderful ")
+ message = replacetext(message," gross "," cool ")
+ message = replacetext(message," disgusting "," amazing ")
+ message = replacetext(message," loser "," winner ")
+ message = replacetext(message," useless "," useful ")
+ message = replacetext(message," oh god "," cheese and crackers ")
+ message = replacetext(message," jesus "," gee wiz ")
+ message = replacetext(message," weak "," strong ")
+ message = replacetext(message," kill "," hug ")
+ message = replacetext(message," murder "," tease ")
+ message = replacetext(message," ugly "," beautiful ")
+ message = replacetext(message," douchbag "," nice guy ")
+ message = replacetext(message," whore "," lady ")
+ message = replacetext(message," nerd "," smart guy ")
+ message = replacetext(message," moron "," fun person ")
+ message = replacetext(message," IT'S LOOSE "," EVERYTHING IS FINE ")
+ message = replacetext(message," sex "," hug fight ")
+ message = replacetext(message," idiot "," genius ")
+ message = replacetext(message," fat "," thin ")
+ message = replacetext(message," beer "," water with ice ")
+ message = replacetext(message," drink "," water ")
+ message = replacetext(message," feminist "," empowered woman ")
+ message = replacetext(message," i hate you "," you're mean ")
+ message = replacetext(message," nigger "," african american ")
+ message = replacetext(message," jew "," jewish ")
+ message = replacetext(message," shit "," shiz ")
+ message = replacetext(message," crap "," poo ")
+ message = replacetext(message," slut "," tease ")
+ message = replacetext(message," ass "," butt ")
+ message = replacetext(message," damn "," dang ")
+ message = replacetext(message," fuck "," ")
+ message = replacetext(message," penis "," privates ")
+ message = replacetext(message," cunt "," privates ")
+ message = replacetext(message," dick "," jerk ")
+ message = replacetext(message," vagina "," privates ")
+ return trim(message)
+
+/datum/mutation/human/unintelligable
+ name = "Unintelligable"
+ quality = NEGATIVE
+ text_gain_indication = "You can't seem to form any coherent thoughts!"
+ text_lose_indication = "Your mind feels more clear."
+
+/datum/mutation/human/unintelligable/say_mod(message)
+ if(message)
+ var/prefix=copytext(message,1,2)
+ if(prefix == ";")
+ message = copytext(message,2)
+ else if(prefix in list(":","#"))
+ prefix += copytext(message,2,3)
+ message = copytext(message,3)
+ else
+ prefix=""
+
+ var/list/words = text2list(message," ")
+ var/list/rearranged = list()
+ for(var/i=1;i<=words.len;i++)
+ var/cword = pick(words)
+ words.Remove(cword)
+ var/suffix = copytext(cword,length(cword)-1,length(cword))
+ while(length(cword)>0 && suffix in list(".",",",";","!",":","?"))
+ cword = copytext(cword,1 ,length(cword)-1)
+ suffix = copytext(cword,length(cword)-1,length(cword) )
+ if(length(cword))
+ rearranged += cword
+ message = "[prefix][uppertext(list2text(rearranged," "))]!!"
+ return message
+
+/datum/mutation/human/swedish
+ name = "Swedish"
+ quality = MINOR_NEGATIVE
+ dna_block = NON_SCANNABLE
+ text_gain_indication = "You feel Swedish, however that works."
+ text_lose_indication = "The feeling of Swedishness passes."
+
+/datum/mutation/human/swedish/say_mod(message)
+ if(message)
+ message = replacetext(message,"w","v")
+ if(prob(30))
+ message += " Bork[pick("",", bork",", bork, bork")]!"
+ return message
+
+/datum/mutation/human/chav
+ name = "Chav"
+ quality = MINOR_NEGATIVE
+ dna_block = NON_SCANNABLE
+ text_gain_indication = "Ye feel like a reet prat like, innit?"
+ text_lose_indication = "You no longer feel like being rude and sassy."
+
+/datum/mutation/human/chav/say_mod(message)
+ if(message)
+ message = " [message] "
+ message = replacetext(message," looking at "," gawpin' at ")
+ message = replacetext(message," great "," bangin' ")
+ message = replacetext(message," man "," mate ")
+ message = replacetext(message," friend ",pick(" mate "," bruv "," bledrin "))
+ message = replacetext(message," what "," wot ")
+ message = replacetext(message," drink "," wet ")
+ message = replacetext(message," get "," giz ")
+ message = replacetext(message," what "," wot ")
+ message = replacetext(message," no thanks "," wuddent fukken do one ")
+ message = replacetext(message," i don't know "," wot mate ")
+ message = replacetext(message," no "," naw ")
+ message = replacetext(message," robust "," chin ")
+ message = replacetext(message," hi "," how what how ")
+ message = replacetext(message," hello "," sup bruv ")
+ message = replacetext(message," kill "," bang ")
+ message = replacetext(message," murder "," bang ")
+ message = replacetext(message," windows "," windies ")
+ message = replacetext(message," window "," windy ")
+ message = replacetext(message," break "," do ")
+ message = replacetext(message," your "," yer ")
+ message = replacetext(message," security "," coppers ")
+ return trim(message)
+
+/datum/mutation/human/elvis
+ name = "Elvis"
+ quality = MINOR_NEGATIVE
+ dna_block = NON_SCANNABLE
+ text_gain_indication = "You feel pretty good, honeydoll."
+ text_lose_indication = "You feel a little less conversation would be great."
+
+/datum/mutation/human/elvis/on_life(mob/living/carbon/human/owner)
+ switch(pick(1,2))
+ if(1)
+ if(prob(15))
+ var/list/dancetypes = list("swinging", "fancy", "stylish", "20'th century", "jivin'", "rock and roller", "cool", "salacious", "bashing", "smashing")
+ var/dancemoves = pick(dancetypes)
+ owner.visible_message("[owner] busts out some [dancemoves] moves!")
+ if(2)
+ if(prob(15))
+ owner.visible_message("[owner] [pick("jiggles their hips", "rotates their hips", "gyrates their hips", "taps their foot", "dances to an imaginary song", "jiggles their legs", "snaps their fingers")]!")
+
+/datum/mutation/human/elvis/say_mod(message)
+ if(message)
+ message = " [message] "
+ message = replacetext(message," i'm not "," I aint ")
+ message = replacetext(message," girl ",pick(" honey "," baby "," baby doll "))
+ message = replacetext(message," man ",pick(" son "," buddy "," brother"," pal "," friendo "))
+ message = replacetext(message," out of "," outta ")
+ message = replacetext(message," thank you "," thank you, thank you very much ")
+ message = replacetext(message," what are you "," whatcha ")
+ message = replacetext(message," yes ",pick(" sure", "yea "))
+ message = replacetext(message," faggot "," square ")
+ message = replacetext(message," muh valids "," getting my kicks ")
+ return trim(message)
+
+/datum/mutation/human/laser_eyes
+ name = "Laser Eyes"
+ quality = POSITIVE
+ dna_block = NON_SCANNABLE
+ text_gain_indication = "You feel pressure building up behind your eyes."
+ layer_used = FRONT_MUTATIONS_LAYER
+
+/datum/mutation/human/laser_eyes/New()
+ ..()
+ visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="lasereyes_s", "layer"=-FRONT_MUTATIONS_LAYER)
+
+/datum/mutation/human/laser_eyes/get_visual_indicator(mob/living/carbon/human/owner)
+ return visual_indicators[1]
+
+/datum/mutation/human/laser_eyes/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
+ if(owner.a_intent == "harm")
+ owner.LaserEyes(target)
+
+
+/mob/living/carbon/proc/update_mutations_overlay()
+ return
+
+/mob/living/carbon/human/update_mutations_overlay()
+ for(var/datum/mutation/human/CM in dna.mutations)
+ if(CM.species_allowed.len && !CM.species_allowed.Find(dna.species.id))
+ CM.force_lose(src) //shouldn't have that mutation at all
+ continue
+ if(CM.visual_indicators.len)
+ var/list/mut_overlay = list()
+ if(overlays_standing[CM.layer_used])
+ mut_overlay = overlays_standing[CM.layer_used]
+ var/image/V = CM.get_visual_indicator(src)
+ if(!mut_overlay.Find(V)) //either we lack the visual indicator or we have the wrong one
+ remove_overlay(CM.layer_used)
+ for(var/image/I in CM.visual_indicators)
+ mut_overlay.Remove(I)
+ mut_overlay |= V
+ overlays_standing[CM.layer_used] = mut_overlay
+ apply_overlay(CM.layer_used)