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)