diff --git a/1Item_list.dmm b/1Item_list.dmm index 4472ccccec..2b851a365f 100644 --- a/1Item_list.dmm +++ b/1Item_list.dmm @@ -4090,7 +4090,7 @@ }, /area/survivalpod) "bkv" = ( -/obj/item/dnainjector/antistutt, +/obj/item/dnainjector/set_trait/anxiety/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -6171,7 +6171,7 @@ }, /area/survivalpod) "bQK" = ( -/obj/item/dnainjector/hallucination, +/obj/item/dnainjector/set_trait/flashproof, /turf/simulated/fitness{ icon_state = "vault" }, @@ -7219,7 +7219,7 @@ }, /area/survivalpod) "cgu" = ( -/obj/item/dnainjector/noprints, +/obj/item/dnainjector/set_trait/noprints, /turf/simulated/fitness{ icon_state = "vault" }, @@ -7591,7 +7591,7 @@ }, /area/survivalpod) "clx" = ( -/obj/item/dnainjector/tourmut, +/obj/item/dnainjector/set_trait/tourettes, /turf/simulated/fitness{ icon_state = "vault" }, @@ -14005,7 +14005,7 @@ }, /area/survivalpod) "eeW" = ( -/obj/item/dnainjector/anticough, +/obj/item/dnainjector/set_trait/cough/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -14075,7 +14075,7 @@ }, /area/survivalpod) "egn" = ( -/obj/item/dnainjector/glassesmut, +/obj/item/dnainjector/set_trait/nearsighted, /turf/simulated/fitness{ icon_state = "vault" }, @@ -17728,7 +17728,7 @@ }, /area/survivalpod) "fko" = ( -/obj/item/dnainjector/antifire, +/obj/item/dnainjector/set_trait/heatadapt/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -18258,7 +18258,7 @@ }, /area/survivalpod) "ftt" = ( -/obj/item/dnainjector/antiepi, +/obj/item/dnainjector/set_trait/epilepsy/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -19736,7 +19736,7 @@ }, /area/survivalpod) "fPz" = ( -/obj/item/dnainjector/antimorph, +/obj/item/dnainjector/set_trait/morph/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -20192,7 +20192,7 @@ }, /area/survivalpod) "fVT" = ( -/obj/item/dnainjector/antiregenerate, +/obj/item/dnainjector/set_trait/regenerate/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -21832,7 +21832,7 @@ }, /area/survivalpod) "gvF" = ( -/obj/item/dnainjector/clumsymut, +/obj/item/dnainjector/set_trait/clumsy, /turf/simulated/fitness{ icon_state = "vault" }, @@ -24337,7 +24337,7 @@ /turf/simulated/floor/atoll, /area/survivalpod) "hgB" = ( -/obj/item/dnainjector/m2h, +/obj/item/dnainjector/set_trait/remotetalk, /turf/simulated/fitness{ icon_state = "vault" }, @@ -27135,7 +27135,7 @@ }, /area/survivalpod) "hWt" = ( -/obj/item/dnainjector/antitour, +/obj/item/dnainjector/set_trait/tourettes/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -29050,7 +29050,7 @@ }, /area/survivalpod) "iyg" = ( -/obj/item/dnainjector/antiglasses, +/obj/item/dnainjector/set_trait/nearsighted/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -29426,7 +29426,7 @@ }, /area/survivalpod) "iDS" = ( -/obj/item/dnainjector/antinoprints, +/obj/item/dnainjector/set_trait/noprints/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -32750,7 +32750,7 @@ }, /area/survivalpod) "jDH" = ( -/obj/item/dnainjector/insulation, +/obj/item/dnainjector/set_trait/coldadapt, /turf/simulated/fitness{ icon_state = "vault" }, @@ -33329,7 +33329,7 @@ }, /area/survivalpod) "jKU" = ( -/obj/item/dnainjector/xraymut, +/obj/item/dnainjector/set_trait/xray, /turf/simulated/fitness{ icon_state = "vault" }, @@ -36242,7 +36242,7 @@ }, /area/survivalpod) "kDt" = ( -/obj/item/dnainjector, +/obj/item/dnainjector/random, /turf/simulated/fitness{ icon_state = "vault" }, @@ -36290,7 +36290,7 @@ }, /area/survivalpod) "kDX" = ( -/obj/item/dnainjector/coughmut, +/obj/item/dnainjector/set_trait/cough, /turf/simulated/fitness{ icon_state = "vault" }, @@ -39829,7 +39829,7 @@ }, /area/survivalpod) "lGo" = ( -/obj/item/dnainjector/deafmut, +/obj/item/dnainjector/set_trait/deaf, /turf/simulated/fitness{ icon_state = "vault" }, @@ -43259,7 +43259,7 @@ }, /area/survivalpod) "mGj" = ( -/obj/item/dnainjector/morph, +/obj/item/dnainjector/set_trait/morph, /turf/simulated/fitness{ icon_state = "vault" }, @@ -43831,7 +43831,7 @@ }, /area/survivalpod) "mPi" = ( -/obj/item/dnainjector/telemut, +/obj/item/dnainjector/set_trait/tk, /turf/simulated/fitness{ icon_state = "vault" }, @@ -43909,7 +43909,7 @@ }, /area/survivalpod) "mQw" = ( -/obj/item/dnainjector/antirunfast, +/obj/item/dnainjector/set_trait/haste/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -45962,7 +45962,7 @@ }, /area/survivalpod) "ntI" = ( -/obj/item/dnainjector/antiinsulation, +/obj/item/dnainjector/set_trait/coldadapt/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -46022,7 +46022,7 @@ }, /area/survivalpod) "nuY" = ( -/obj/item/dnainjector/antihallucination, +/obj/item/dnainjector/set_trait/flashproof/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -47375,7 +47375,7 @@ }, /area/survivalpod) "nMU" = ( -/obj/item/dnainjector/antitele, +/obj/item/dnainjector/set_trait/tk/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -47947,7 +47947,7 @@ }, /area/survivalpod) "nVr" = ( -/obj/item/dnainjector/blindmut, +/obj/item/dnainjector/set_trait/blind, /turf/simulated/fitness{ icon_state = "vault" }, @@ -50472,7 +50472,7 @@ }, /area/survivalpod) "oHT" = ( -/obj/item/dnainjector/nobreath, +/obj/item/dnainjector/set_trait/nobreathe, /turf/simulated/fitness{ icon_state = "vault" }, @@ -53739,7 +53739,7 @@ }, /area/survivalpod) "pIH" = ( -/obj/item/dnainjector/regenerate, +/obj/item/dnainjector/set_trait/regenerate, /turf/simulated/fitness{ icon_state = "vault" }, @@ -57638,7 +57638,7 @@ }, /area/survivalpod) "qSE" = ( -/obj/item/disk/data/monkey, +/obj/item/disk/body_record, /turf/simulated/fitness{ icon_state = "vault" }, @@ -60390,7 +60390,7 @@ }, /area/survivalpod) "rJl" = ( -/obj/item/dnainjector/anticlumsy, +/obj/item/dnainjector/set_trait/clumsy/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -61384,7 +61384,7 @@ }, /area/survivalpod) "rYL" = ( -/obj/item/dnainjector/h2m, +/obj/item/dnainjector/set_trait/remotetalk/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -64464,7 +64464,7 @@ }, /area/survivalpod) "sVd" = ( -/obj/item/dnainjector/antideaf, +/obj/item/dnainjector/set_trait/deaf/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -65456,7 +65456,7 @@ }, /area/survivalpod) "tiU" = ( -/obj/item/dnainjector/runfast, +/obj/item/dnainjector/set_trait/haste, /turf/simulated/fitness{ icon_state = "vault" }, @@ -66176,7 +66176,7 @@ }, /area/survivalpod) "ttB" = ( -/obj/item/dnainjector/stuttmut, +/obj/item/dnainjector/set_trait/anxiety, /turf/simulated/fitness{ icon_state = "vault" }, @@ -68527,7 +68527,7 @@ }, /area/survivalpod) "ueC" = ( -/obj/item/dnainjector/antinobreath, +/obj/item/dnainjector/set_trait/nobreathe/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -69577,7 +69577,7 @@ }, /area/survivalpod) "uvF" = ( -/obj/item/dnainjector/firemut, +/obj/item/dnainjector/set_trait/heatadapt, /turf/simulated/fitness{ icon_state = "vault" }, @@ -70686,7 +70686,7 @@ }, /area/survivalpod) "uLL" = ( -/obj/item/dnainjector/remoteview, +/obj/item/dnainjector/set_trait/remoteview, /turf/simulated/fitness{ icon_state = "vault" }, @@ -70722,7 +70722,7 @@ }, /area/survivalpod) "uMw" = ( -/obj/item/dnainjector/epimut, +/obj/item/dnainjector/set_trait/epilepsy, /turf/simulated/fitness{ icon_state = "vault" }, @@ -71106,7 +71106,7 @@ }, /area/survivalpod) "uSj" = ( -/obj/item/dnainjector/antixray, +/obj/item/dnainjector/set_trait/xray/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -73588,7 +73588,7 @@ }, /area/survivalpod) "vDD" = ( -/obj/item/disk/data, +/obj/item/disk/body_record, /turf/simulated/fitness{ icon_state = "vault" }, @@ -74066,7 +74066,7 @@ }, /area/survivalpod) "vKJ" = ( -/obj/item/dnainjector/antihulk, +/obj/item/dnainjector/set_trait/hulk/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -75611,7 +75611,7 @@ }, /area/survivalpod) "wgu" = ( -/obj/item/dnainjector/antiblind, +/obj/item/dnainjector/set_trait/blind/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -76305,7 +76305,7 @@ }, /area/survivalpod) "wqM" = ( -/obj/item/disk/data/demo, +/obj/item/disk/body_record, /turf/simulated/fitness{ icon_state = "vault" }, @@ -77105,7 +77105,7 @@ }, /area/survivalpod) "wCK" = ( -/obj/item/dnainjector/hulkmut, +/obj/item/dnainjector/set_trait/hulk, /turf/simulated/fitness{ icon_state = "vault" }, @@ -79888,7 +79888,7 @@ }, /area/survivalpod) "xsA" = ( -/obj/item/dnainjector/midgit, +/obj/item/dnainjector/set_trait/table_passer, /turf/simulated/fitness{ icon_state = "vault" }, @@ -80656,7 +80656,7 @@ }, /area/survivalpod) "xDX" = ( -/obj/item/dnainjector/antimidgit, +/obj/item/dnainjector/set_trait/table_passer/disable, /turf/simulated/fitness{ icon_state = "vault" }, @@ -81192,7 +81192,7 @@ }, /area/survivalpod) "xKQ" = ( -/obj/item/dnainjector/antiremoteview, +/obj/item/dnainjector/set_trait/remotetalk/disable, /turf/simulated/fitness{ icon_state = "vault" }, diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm index c3e3097fb6..124463c9d8 100644 --- a/code/ZAS/Phoron.dm +++ b/code/ZAS/Phoron.dm @@ -136,6 +136,7 @@ var/image/contamination_overlay = image('icons/effects/contamination.dmi') randmutb(src) to_chat(src, span_danger("High levels of toxins cause you to spontaneously mutate!")) domutcheck(src,null) + UpdateAppearance() /mob/living/carbon/human/proc/burn_eyes() var/obj/item/organ/internal/eyes/E = internal_organs_by_name[O_EYES] diff --git a/code/__defines/ballistics_ch.dm b/code/__defines/ballistics_ch.dm index ad893f2e64..2bc387b074 100644 --- a/code/__defines/ballistics_ch.dm +++ b/code/__defines/ballistics_ch.dm @@ -38,7 +38,3 @@ GLOBAL_VAR_INIT(ENERGY_DAMAGE_ORGAN_FACTOR,0.035) #define ENERGY_DAMAGE_COEFFICIENT 0.05 #define ENERGY_DAMAGE_FLESH_FALLOFF_POINT 10 #define ENERGY_DAMAGE_ORGAN_FALLOFF_POINT 7 - -#ifndef GAUSSIAN_RANDOM -#define GAUSSIAN_RANDOM(vars...) ((-2*log(rand()))**0.5 * cos(6.28318530718*rand())) -#endif diff --git a/code/__defines/damage_organs.dm b/code/__defines/damage_organs.dm index 6bfcd15792..d9eef97bd7 100644 --- a/code/__defines/damage_organs.dm +++ b/code/__defines/damage_organs.dm @@ -45,6 +45,7 @@ #define DROPLIMB_EDGE 0 #define DROPLIMB_BLUNT 1 #define DROPLIMB_BURN 2 +#define DROPLIMB_ACID 3 // Damage above this value must be repaired with surgery. #define ROBOLIMB_REPAIR_CAP 60 //CHOMPedit, bumping it up to 60 to keep consistency with our global cap of 60 diff --git a/code/__defines/dna.dm b/code/__defines/dna.dm index bcf5f15e3c..6140bf37bf 100644 --- a/code/__defines/dna.dm +++ b/code/__defines/dna.dm @@ -13,6 +13,7 @@ #define NOCLONE 8 #define LASER 9 // Harm intent - click anywhere to shoot lasers from eyes. #define HEAL 10 // Healing people with hands. +#define FLASHPROOF 11 // Flashproof eyes. #define SKELETON 29 #define PLANT 30 @@ -36,14 +37,22 @@ #define COUGHING 0x4 #define TOURETTES 0x8 #define NERVOUS 0x10 - +/* +#define DEPRESSION 0x20 // Roleplay drugs +#define SCHIZOPHRENIA 0x40 // Roleplay drugs +*/ +#define WINGDINGS 0x80 // Better handling as disability +#define DETERIORATE 0x100 // Body melts slowly, medical loves you! +#define GIBBING 0x200 // Landmine for genetics to find +#define CENSORED 0x400 // Cannot swear // sdisabilities #define BLIND 0x1 #define MUTE 0x2 #define DEAF 0x4 +/* Traitgenes (Blocks have finally been retired, huzzah! // The way blocks are handled badly needs a rewrite, this is horrible. -// Too much of a project to handle at the moment, TODO for later. +// Too much of a project to handle at the moment, TODO for later.) var/BLINDBLOCK = 0 var/DEAFBLOCK = 0 var/HULKBLOCK = 0 @@ -74,6 +83,7 @@ var/HALLUCINATIONBLOCK = 0 var/NOPRINTSBLOCK = 0 var/SHOCKIMMUNITYBLOCK = 0 var/SMALLSIZEBLOCK = 0 +*/ // Define block bounds (off-low,off-high,on-low,on-high) // Used in setupgame.dm @@ -147,7 +157,9 @@ var/SMALLSIZEBLOCK = 0 #define DNA_UI_WING3_B 57 // VOREStation snippet end. #define DNA_UI_LENGTH 57 // VOREStation Edit - Needs to match the highest number above. -#define DNA_SE_LENGTH 49 // VOREStation Edit (original was UI+11) +#define DNA_SE_LENGTH 90 // Traitgenes (Expanded from 49 to 84, there have been a considerable expansion of genes. +// This leaves room for future expansion. This can be arbitrarily raised without worry if genes start to get crowded. +// Should have more than 10 empty genes after setup. - Willbird) //DNA modifiers // Buffer datatype flags. @@ -160,4 +172,4 @@ var/SMALLSIZEBLOCK = 0 // Gene flags #define GENE_ALWAYS_ACTIVATE 1 -#define MUTCHK_HIDEMSG 2 +#define MUTCHK_HIDEMSG 2 // Traitgenes (Hide gene activation/deactivation messages, mostly for resleeving so you don't get spammed) diff --git a/code/__defines/gamemode.dm b/code/__defines/gamemode.dm index 6175e0aa3e..8a3c8102e5 100644 --- a/code/__defines/gamemode.dm +++ b/code/__defines/gamemode.dm @@ -55,7 +55,7 @@ var/list/be_special_flags = list( "Wizard" = BE_WIZARD, "Malf AI" = BE_MALF, "Revolutionary" = BE_REV, - "Genaprawn" = BE_ALIEN, //CHOMPedit + "Genaprawn" = BE_ALIEN, "Positronic Brain" = BE_AI, "Cultist" = BE_CULTIST, "Renegade" = BE_RENEGADE, diff --git a/code/__defines/is_helpers.dm b/code/__defines/is_helpers.dm index f28dbd35ac..bad9873191 100644 --- a/code/__defines/is_helpers.dm +++ b/code/__defines/is_helpers.dm @@ -44,6 +44,7 @@ #define isslime(A) istype(A, /mob/living/simple_mob/slime) #define isxeno(A) istype(A, /mob/living/simple_mob/animal/space/alien) #define issimplekin(A) istype(A, /mob/living/simple_mob/shadekin) +#define isprotblob(A) istype(A, /mob/living/simple_mob/protean_blob) #define ismetroid(A) istype(A, /mob/living/simple_mob/metroid) //CHOMP Addition #define iscarbon(A) istype(A, /mob/living/carbon) diff --git a/code/__defines/life.dm b/code/__defines/life.dm index 50c15aaa6b..dec65d9e78 100644 --- a/code/__defines/life.dm +++ b/code/__defines/life.dm @@ -19,4 +19,4 @@ #define TECHNOMANCER_INSTABILITY_MIN_GLOW 10 // When above this number, the entity starts glowing, affecting others. -#define RADIATION_SPEED_COEFFICIENT 0.1 //CHOMPAdd, global here +#define RADIATION_SPEED_COEFFICIENT 0.1 diff --git a/code/__defines/math_ch.dm b/code/__defines/math_ch.dm index b536c5ea68..9ff3059cd6 100644 --- a/code/__defines/math_ch.dm +++ b/code/__defines/math_ch.dm @@ -4,3 +4,5 @@ return 1 else return 0 + +#define GAUSSIAN_RANDOM(vars...) ((-2*log(rand()))**0.5 * cos(6.28318530718*rand())) diff --git a/code/__defines/span_vr.dm b/code/__defines/span.dm similarity index 96% rename from code/__defines/span_vr.dm rename to code/__defines/span.dm index 727f04ad5c..fe949e69b0 100644 --- a/code/__defines/span_vr.dm +++ b/code/__defines/span.dm @@ -239,7 +239,11 @@ // Links! #define span_linkify(str) ("" + str + "") -// Just used downstream #define span_wingdings(str) ("" + str + "") #define span_maptext(str) ("" + str + "") + +#define span_major_announcement_text(str) ("" + str + "") +#define span_major_announcement_title(str) ("" + str + "") +#define span_ooc_announcement_text(str) ("" + str + "") +#define span_subheader_announcement_text(str) ("" + str + "") diff --git a/modular_chomp/code/_HELPERS/announcements.dm b/code/_helpers/announcements.dm similarity index 97% rename from modular_chomp/code/_HELPERS/announcements.dm rename to code/_helpers/announcements.dm index aaafa4732d..5ab52144ff 100644 --- a/modular_chomp/code/_HELPERS/announcements.dm +++ b/code/_helpers/announcements.dm @@ -25,7 +25,7 @@ title = "", players, play_sound = TRUE, - sound_override = 'modular_chomp/sound/misc/bloop.ogg', + sound_override = 'sound/misc/bloop.ogg', sender_override = "Server Admin Announcement", encode_title = TRUE, encode_text = FALSE, diff --git a/code/_helpers/global_lists_vr.dm b/code/_helpers/global_lists_vr.dm index 3cd61d8e7a..7ccf05086c 100644 --- a/code/_helpers/global_lists_vr.dm +++ b/code/_helpers/global_lists_vr.dm @@ -578,6 +578,9 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN, traits_costs[path] = cost all_traits[path] = instance + // Traitgenes Initilize trait genes + setupgenetics(all_traits) + // Shakey shakey shake sortTim(all_traits, GLOBAL_PROC_REF(cmp_trait_datums_name), associative = TRUE) @@ -585,19 +588,20 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN, for(var/traitpath in all_traits) var/datum/trait/T = all_traits[traitpath] var/category = T.category - switch(category) - if(-INFINITY to -0.1) - negative_traits[traitpath] = T - if(!(T.custom_only)) - everyone_traits_negative[traitpath] = T - if(0) - neutral_traits[traitpath] = T - if(!(T.custom_only)) - everyone_traits_neutral[traitpath] = T - if(0.1 to INFINITY) - positive_traits[traitpath] = T - if(!(T.custom_only)) - everyone_traits_positive[traitpath] = T + if(!T.hidden) // Traitgenes forbid hidden traits from showing, done to hide genetics only traits + switch(category) + if(-INFINITY to -0.1) + negative_traits[traitpath] = T + if(!(T.custom_only)) + everyone_traits_negative[traitpath] = T + if(0) + neutral_traits[traitpath] = T + if(!(T.custom_only)) + everyone_traits_neutral[traitpath] = T + if(0.1 to INFINITY) + positive_traits[traitpath] = T + if(!(T.custom_only)) + everyone_traits_positive[traitpath] = T // Weaver recipe stuff diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 0d66026fbf..89d6132361 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -328,7 +328,7 @@ setClickCooldown(4) var/turf/T = get_turf(src) - var/obj/item/projectile/beam/LE = new (T) + var/obj/item/projectile/beam/laser_vision/LE = new (T) LE.icon = 'icons/effects/genetics.dmi' LE.icon_state = "eyelasers" playsound(src, 'sound/weapons/taser2.ogg', 75, 1) diff --git a/code/controllers/subsystems/atoms.dm b/code/controllers/subsystems/atoms.dm index 211ef0517d..e74800a6f8 100644 --- a/code/controllers/subsystems/atoms.dm +++ b/code/controllers/subsystems/atoms.dm @@ -9,7 +9,6 @@ SUBSYSTEM_DEF(atoms) flags = SS_NO_FIRE var/static/initialized = INITIALIZATION_INSSATOMS - // var/list/created_atoms // This is never used, so don't bother. ~Leshana var/static/old_initialized var/list/late_loaders @@ -18,7 +17,6 @@ SUBSYSTEM_DEF(atoms) var/list/BadInitializeCalls = list() /datum/controller/subsystem/atoms/Initialize() - setupgenetics() //to set the mutations' place in structural enzymes, so initializers know where to put mutations. initialized = INITIALIZATION_INNEW_MAPLOAD to_world_log("Initializing objects") admin_notice(span_danger("Initializing objects"), R_DEBUG) @@ -62,11 +60,6 @@ SUBSYSTEM_DEF(atoms) testing("Late initialized [late_loaders.len] atoms") late_loaders.Cut() - // Nothing ever checks return value of this proc, so don't bother. If this ever changes fix code in /atom/New() ~Leshana - // if(atoms) - // . = created_atoms + atoms - // created_atoms = null - /datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments) var/the_type = A.type if(QDELING(A)) diff --git a/code/datums/diseases/advance/symptoms/telepathy.dm b/code/datums/diseases/advance/symptoms/telepathy.dm index 10a42cc6ad..c87e3178be 100644 --- a/code/datums/diseases/advance/symptoms/telepathy.dm +++ b/code/datums/diseases/advance/symptoms/telepathy.dm @@ -27,13 +27,19 @@ Bonus /datum/symptom/telepathy/Start(datum/disease/advance/A) if(iscarbon(A)) var/mob/living/carbon/human/H = A.affected_mob - H.dna.SetSEState(REMOTETALKBLOCK, 1) + // Traitgenes Locate the gene from trait + var/datum/gene/trait/G = get_gene_from_trait(/datum/trait/positive/superpower_remotetalk) + H.dna.SetSEState(G.block, 1) domutcheck(H, null, TRUE) + H.UpdateAppearance() to_chat(H, span_notice("Your mind expands...")) /datum/symptom/telepathy/End(datum/disease/advance/A) if(iscarbon(A)) var/mob/living/carbon/human/H = A.affected_mob - H.dna.SetSEState(REMOTETALKBLOCK, 0) + // Traitgenes Locate the gene from trait + var/datum/gene/trait/G = get_gene_from_trait(/datum/trait/positive/superpower_remotetalk) + H.dna.SetSEState(G.block, 0) domutcheck(H, null, TRUE) + H.UpdateAppearance() to_chat(H, span_notice("Everything feels... Normal.")) diff --git a/code/game/antagonist/alien/xenomorph.dm b/code/game/antagonist/alien/xenomorph.dm index 585caeec72..cac15e03c5 100644 --- a/code/game/antagonist/alien/xenomorph.dm +++ b/code/game/antagonist/alien/xenomorph.dm @@ -3,8 +3,8 @@ var/datum/antagonist/xenos/xenomorphs /datum/antagonist/xenos id = MODE_XENOMORPH role_type = BE_ALIEN - role_text = "Genaprawn" //CHOMPedit - role_text_plural = "Genaprawns" //CHOMPedit + role_text = "Genaprawn" + role_text_plural = "Genaprawns" mob_path = /mob/living/carbon/alien/larva bantype = "Xenomorph" flags = ANTAG_OVERRIDE_MOB | ANTAG_RANDSPAWN | ANTAG_OVERRIDE_JOB | ANTAG_VOTABLE diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index c323736b17..3aefc12c66 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -1,20 +1,10 @@ -/** -* DNA 2: The Spaghetti Strikes Back -* -* @author N3X15 -*/ - // What each index means: #define DNA_OFF_LOWERBOUND 1 #define DNA_OFF_UPPERBOUND 2 #define DNA_ON_LOWERBOUND 3 #define DNA_ON_UPPERBOUND 4 -// For later: -//# define DNA_SE_LENGTH 50 // Was STRUCDNASIZE, size 27. 15 new blocks added = 42, plus room to grow. - - -// Defines which values mean "on" or "off". +// Defines which values mean "on" or "off". // This is to make some of the more OP superpowers a larger PITA to activate, // and to tell our new DNA datum which values to set in order to turn something // on or off. @@ -23,7 +13,19 @@ var/global/list/dna_activity_bounds[DNA_SE_LENGTH] // Used to determine what each block means (admin hax and species stuff on /vg/, mostly) var/global/list/assigned_blocks[DNA_SE_LENGTH] -var/global/list/datum/dna/gene/dna_genes[0] +// Traitgenes Genes accessible by global VV, and lists for good and bad mutations for quick randomized selection of traitgenes. Removed dna from gene's path +GLOBAL_LIST_EMPTY_TYPED(dna_genes, /datum/gene) +GLOBAL_LIST_EMPTY(trait_to_dna_genes) // Reverse lookup genes, use get_gene_from_trait(var/trait_path) to read this +GLOBAL_LIST_EMPTY_TYPED(dna_genes_good, /datum/gene/trait) +GLOBAL_LIST_EMPTY_TYPED(dna_genes_neutral, /datum/gene/trait) +GLOBAL_LIST_EMPTY_TYPED(dna_genes_bad, /datum/gene/trait) + +/proc/get_gene_from_trait(var/trait_path) // ALWAYS USE THIS + RETURN_TYPE(/datum/gene/trait) + var/G = GLOB.trait_to_dna_genes[trait_path] + if(!G) // This SHOULD NOT HAPPEN, be sure any viruses or injectors that give trait paths are actually traitgenes. + stack_trace("[trait_path] was used as a traitgene, without being flagged as one.") + return G /datum/dna // READ-ONLY, GETS OVERWRITTEN @@ -70,7 +72,6 @@ var/global/list/datum/dna/gene/dna_genes[0] var/list/custom_heat = list() var/list/custom_cold = list() var/digitigrade = 0 //0, Not FALSE, for future use as indicator for digitigrade types - // VOREStation // New stuff var/species = SPECIES_HUMAN @@ -88,10 +89,10 @@ var/global/list/datum/dna/gene/dna_genes[0] new_dna.real_name=real_name new_dna.species=species new_dna.body_markings=body_markings.Copy() - new_dna.base_species=base_species //VOREStation Edit - new_dna.custom_species=custom_species //VOREStaton Edit - new_dna.species_traits=species_traits.Copy() //VOREStation Edit - new_dna.blood_color=blood_color //VOREStation Edit + new_dna.base_species=base_species + new_dna.custom_species=custom_species + new_dna.species_traits=species_traits.Copy() + new_dna.blood_color=blood_color new_dna.blood_reagents=blood_reagents new_dna.scale_appearance = scale_appearance new_dna.offset_override = offset_override @@ -105,13 +106,13 @@ var/global/list/datum/dna/gene/dna_genes[0] new_dna.r_grad = r_grad new_dna.g_grad = g_grad new_dna.b_grad = b_grad - new_dna.custom_say=custom_say //VOREStaton Edit - new_dna.custom_ask=custom_ask //VOREStaton Edit - new_dna.custom_whisper=custom_whisper //VOREStaton Edit - new_dna.custom_exclaim=custom_exclaim //VOREStaton Edit - new_dna.custom_heat=custom_heat //VOREStation Edit - new_dna.custom_cold=custom_cold //VOREStation Edit - new_dna.digitigrade=src.digitigrade //VOREStation Edit + new_dna.custom_say=custom_say + new_dna.custom_ask=custom_ask + new_dna.custom_whisper=custom_whisper + new_dna.custom_exclaim=custom_exclaim + new_dna.custom_heat=custom_heat + new_dna.custom_cold=custom_cold + new_dna.digitigrade=src.digitigrade var/list/body_markings_genetic = (body_markings - body_marking_nopersist_list) new_dna.body_markings=body_markings_genetic.Copy() for(var/b=1;b<=DNA_SE_LENGTH;b++) @@ -259,7 +260,6 @@ var/global/list/datum/dna/gene/dna_genes[0] SetUIValueRange(offset, red, 255, 1) SetUIValueRange(offset + 1, green, 255, 1) SetUIValueRange(offset + 2, blue, 255, 1) - // VORE Station Edit End SetUIValueRange(DNA_UI_HAIR_R, character.r_hair, 255, 1) SetUIValueRange(DNA_UI_HAIR_G, character.g_hair, 255, 1) @@ -312,7 +312,7 @@ var/global/list/datum/dna/gene/dna_genes[0] if (block<=0) return ASSERT(maxvalue<=4095) var/range = (4095 / maxvalue) - if(value!=null) //CHOMPEdit DO NOT PORT VIRGO'S FIX FOR RESLEEVING. IT IS BAD. Also fuck travis + if(value!=null) SetUIValue(block,round(value * range),defer) // Getter version of above. @@ -429,6 +429,19 @@ var/global/list/datum/dna/gene/dna_genes[0] /datum/dna/proc/GetSEBlock(var/block) return EncodeDNABlock(GetSEValue(block)) +// Get activation intensity, returns 0 to 1, you MUST check if the gene is active first! This is used for future expansion where genetraits can have multiple levels of activation/intensity +/datum/dna/proc/GetSEActivationIntensity(var/block) + if (block<=0) return 0 + var/list/BOUNDS=GetDNABounds(block) + var/value=GetSEValue(block) + var/val = (value - BOUNDS[DNA_ON_LOWERBOUND]) / (BOUNDS[DNA_ON_UPPERBOUND] - BOUNDS[DNA_ON_LOWERBOUND]) + return val + +// Gets the activation intensity index. ex: if a genetrait has 5 levels of activations, the gene will have 5 possible levels of activation. this is a future TODO. +/datum/dna/proc/GetSEActivationLevel(var/block,var/number_of_levels) + var/raw_val = GetSEActivationIntensity(block) + return round(raw_val * number_of_levels) // TODO - If this should be round/floor/ceil + // Do not use this unless you absolutely have to. // Set a block from a hex string. This is inefficient. If you can, use SetUIValue(). // Used in DNA modifiers. diff --git a/code/game/dna/dna2_domutcheck.dm b/code/game/dna/dna2_domutcheck.dm index 2b3f820532..85c6f812fc 100644 --- a/code/game/dna/dna2_domutcheck.dm +++ b/code/game/dna/dna2_domutcheck.dm @@ -3,8 +3,27 @@ // M: Mob to mess with // connected: Machine we're in, type unchecked so I doubt it's used beyond monkeying // flags: See below, bitfield. + /proc/domutcheck(var/mob/living/M, var/connected=null, var/flags=0) - for(var/datum/dna/gene/gene in dna_genes) + // Traitgenes NO_SCAN and Synthetics cannot be mutated + if(M.isSynthetic()) + return + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(!H.species || H.species.flags & NO_SCAN) + return + // Traitgenes Sort genes into currently active, and deactivated... Genes that are active and may deactivate should do so before attempting to activate genes(to avoid conflicts blocking them!) + var/list/enabled_genes = list() + var/list/disabled_genes = list() + for(var/datum/gene/gene in GLOB.dna_genes) // Traitgenes Genes accessible by global VV, removed dna from path + if(!M || !M.dna) + return + if(gene.block) + if(gene.name in M.active_genes || gene.flags & GENE_ALWAYS_ACTIVATE) + enabled_genes.Add(gene) + else + disabled_genes.Add(gene) + for(var/datum/gene/gene in enabled_genes + disabled_genes) // Traitgenes Removed /dna/ from path if(!M || !M.dna) return if(!gene.block) @@ -21,22 +40,31 @@ gene_active = M.dna.GetSEState(gene.block) // Prior state - var/gene_prior_status = (gene.type in M.active_genes) + var/gene_prior_status = (gene.name in M.active_genes) // Traitgenes Use name instead, cannot use type with dynamically setup traitgenes var/changed = gene_active != gene_prior_status || (gene.flags & GENE_ALWAYS_ACTIVATE) // If gene state has changed: - if(changed) + if(changed || flags & MUTCHK_FORCED) // Traitgenes MUTCHK_FORCED always applies or removes genes // Gene active (or ALWAYS ACTIVATE) if(gene_active || (gene.flags & GENE_ALWAYS_ACTIVATE)) - testing("[gene.name] activated!") + // Traitgenes Handle trait conflicts, do not activate if so! Has to be done here so that SE activation without trait activation is possible. + if(istype(gene,/datum/gene/trait)) + var/datum/gene/trait/TG = gene + if(!ishuman(M)) + continue // Trait genes are human only + var/mob/living/carbon/human/H = M + if(TG.has_conflict(H.species.traits)) + continue // The SE is on, but the gene is denied... + //testing("[gene.name] activated!") gene.activate(M,connected,flags) if(M) - M.active_genes |= gene.type + M.active_genes |= gene.name // Traitgenes Use name instead, cannot use type with dynamically setup traitgenes M.update_icon = 1 // If Gene is NOT active: else - testing("[gene.name] deactivated!") + //testing("[gene.name] deactivated!") gene.deactivate(M,connected,flags) if(M) - M.active_genes -= gene.type + M.active_genes -= gene.name // Traitgenes Use name instead, cannot use type with dynamically setup traitgenes M.update_icon = 1 + M.update_mutations() diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 8250613537..86aa5edc64 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -23,42 +23,51 @@ // Give Random Bad Mutation to M /proc/randmutb(var/mob/living/M) if(!M || !(M.dna)) return + // Traitgenes NO_SCAN and Synthetics cannot be mutated + if(M.isSynthetic()) + return + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(!H.species || H.species.flags & NO_SCAN) + return M.dna.check_integrity() - //var/block = pick(GLASSESBLOCK,COUGHBLOCK,FAKEBLOCK,NERVOUSBLOCK,CLUMSYBLOCK,TWITCHBLOCK,HEADACHEBLOCK,BLINDBLOCK,DEAFBLOCK,HALLUCINATIONBLOCK) // Most of these are disabled anyway. - var/block = pick(FAKEBLOCK,CLUMSYBLOCK,BLINDBLOCK,DEAFBLOCK) - M.dna.SetSEState(block, 1) + // Traitgenes Pick from bad traitgenes + var/datum/gene/trait/T = pick(GLOB.dna_genes_bad + (prob(10) ? GLOB.dna_genes_neutral : list()) ) // Chance for neutrals as well + M.dna.SetSEState(T.block, TRUE) // Give Random Good Mutation to M /proc/randmutg(var/mob/living/M) if(!M || !(M.dna)) return + // Traitgenes NO_SCAN and Synthetics cannot be mutated + if(M.isSynthetic()) + return + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(!H.species || H.species.flags & NO_SCAN) + return M.dna.check_integrity() - //var/block = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,NOBREATHBLOCK,REMOTEVIEWBLOCK,REGENERATEBLOCK,INCREASERUNBLOCK,REMOTETALKBLOCK,MORPHBLOCK,BLENDBLOCK,NOPRINTSBLOCK,SHOCKIMMUNITYBLOCK,SMALLSIZEBLOCK) // Much like above, most of these blocks are disabled in code. - var/block = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,REGENERATEBLOCK,REMOTETALKBLOCK) - M.dna.SetSEState(block, 1) - -// Random Appearance Mutation -/proc/randmuti(var/mob/living/M) - if(!M || !(M.dna)) return - M.dna.check_integrity() - M.dna.SetUIValue(rand(1,DNA_UI_LENGTH),rand(1,4095)) + // Traitgenes Pick from good traitgenes + var/datum/gene/trait/T = pick(GLOB.dna_genes_good + (prob(10) ? GLOB.dna_genes_neutral : list()) ) // Chance for neutrals as well + M.dna.SetSEState(T.block, TRUE) // Scramble UI or SE. /proc/scramble(var/UI, var/mob/M, var/prob) if(!M || !(M.dna)) return + // Traitgenes edit begin - NO_SCAN and Synthetics cannot be mutated + if(M.isSynthetic()) + return + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(!H.species || H.species.flags & NO_SCAN) + return + // Traitgenes edit end M.dna.check_integrity() - if(UI) - for(var/i = 1, i <= DNA_UI_LENGTH-1, i++) - if(prob(prob)) - M.dna.SetUIValue(i,rand(1,4095),1) - M.dna.UpdateUI() - M.UpdateAppearance() - - else - for(var/i = 1, i <= DNA_SE_LENGTH-1, i++) - if(prob(prob)) - M.dna.SetSEValue(i,rand(1,4095),1) - M.dna.UpdateSE() - domutcheck(M, null) + for(var/i = 1, i <= DNA_SE_LENGTH-1, i++) + if(prob(prob)) + M.dna.SetSEValue(i,rand(1,4095),1) + M.dna.UpdateSE() + domutcheck(M, null) + M.UpdateAppearance() return // I haven't yet figured out what the fuck this is supposed to do. @@ -122,8 +131,7 @@ return output -// /proc/updateappearance has changed behavior, so it's been removed -// Use mob.UpdateAppearance() instead. +// Use mob.UpdateAppearance() // Simpler. Don't specify UI in order for the mob to use its own. /mob/proc/UpdateAppearance(var/list/UI=null) @@ -175,8 +183,6 @@ if((0 < beard) && (beard <= facial_hair_styles_list.len)) H.f_style = facial_hair_styles_list[beard] - // VORE StationEdit Start - // Ears var/ears = dna.GetUIValueRange(DNA_UI_EAR_STYLE, ear_styles_list.len + 1) - 1 if(ears < 1) @@ -257,6 +263,7 @@ H.custom_ask = dna.custom_ask H.custom_whisper = dna.custom_whisper H.custom_exclaim = dna.custom_exclaim + H.species.blood_color = dna.blood_color H.fuzzy = dna.scale_appearance H.offset_override = dna.offset_override H.synth_markings = dna.synth_markings @@ -281,9 +288,9 @@ H.species.species_sounds_female = dna.species_sounds_female // CHOMPEnable ENd - H.force_update_organs() + H.force_update_organs() //VOREStation Add - Gotta do this too H.force_update_limbs() - //H.update_body(0) //Done in force_update_limbs already + //H.update_body(0) //VOREStation Edit - Done in force_update_limbs already H.update_eyes() H.update_hair() diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index e2b9e5dcb8..99b8d854ce 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -1,6 +1,5 @@ #define DNA_BLOCK_SIZE 3 -#define PAGE_UI "ui" #define PAGE_SE "se" #define PAGE_BUFFER "buffer" #define PAGE_REJUVENATORS "rejuvenators" @@ -69,7 +68,7 @@ interact_offline = 1 circuit = /obj/item/circuitboard/clonescanner var/locked = 0 - var/mob/living/carbon/occupant = null + var/datum/weakref/occupant = null var/obj/item/reagent_containers/glass/beaker = null var/opened = 0 var/damage_coeff @@ -81,6 +80,10 @@ default_apply_parts() RefreshParts() +/obj/machinery/dna_scannernew/Destroy() + eject_occupant() + . = ..() + /obj/machinery/dna_scannernew/RefreshParts() scan_level = 0 damage_coeff = 0 @@ -112,16 +115,24 @@ return /obj/machinery/dna_scannernew/proc/eject_occupant() - src.go_out() + var/mob/living/carbon/WC = occupant?.resolve() + go_out() for(var/obj/O in src) if((!istype(O,/obj/item/reagent_containers)) && (!istype(O,/obj/item/circuitboard/clonescanner)) && (!istype(O,/obj/item/stock_parts)) && (!istype(O,/obj/item/stack/cable_coil))) - O.loc = get_turf(src)//Ejects items that manage to get in there (exluding the components) - if(!occupant) + O.forceMove(get_turf(src)) //Ejects items that manage to get in there (exluding the components) + if(!WC) for(var/mob/M in src)//Failsafe so you can get mobs out - M.loc = get_turf(src) + M.forceMove(get_turf(src)) /obj/machinery/dna_scannernew/MouseDrop_T(var/mob/target, var/mob/user) //Allows borgs to clone people without external assistance - if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user)|| !ishuman(target)) + var/mob/living/carbon/WC = occupant?.resolve() + if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user)|| !ishuman(target) || WC) + return + // Traitgenes Do not allow buckled or ridden mobs + if(target.buckled) + return + if(target.has_buckled_mobs()) + to_chat(user, span_warning("\The [target] has other entities attached to it. Remove them first.")) return put_in(target) @@ -130,27 +141,37 @@ set category = "Object" set name = "Enter DNA Scanner" + if(usr.stat != 0) return if(!ishuman(usr) && !issmall(usr)) //Make sure they're a mob that has dna to_chat(usr, span_notice("Try as you might, you can not climb up into the scanner.")) return - if(src.occupant) + if(occupant) to_chat(usr, span_warning("The scanner is already occupied!")) return if(usr.abiotic()) to_chat(usr, span_warning("The subject cannot have abiotic items on.")) return + var/mob/living/carbon/WC = occupant?.resolve() + if(WC) + to_chat(usr, span_warning("There is already something inside.")) + return usr.stop_pulling() usr.client.perspective = EYE_PERSPECTIVE usr.client.eye = src - usr.loc = src - src.occupant = usr - src.icon_state = "scanner_1" - src.add_fingerprint(usr) + usr.forceMove(src) + occupant = WEAKREF(usr) + icon_state = "scanner_1" + add_fingerprint(usr) SStgui.update_uis(src) /obj/machinery/dna_scannernew/attackby(var/obj/item/item as obj, var/mob/user as mob) + // Traitgenes Deconstructable dna scanner + if(default_deconstruction_screwdriver(user, item)) + return + if(default_deconstruction_crowbar(user, item)) + return if(istype(item, /obj/item/reagent_containers/glass)) if(beaker) to_chat(user, span_warning("A beaker is already loaded into the machine.")) @@ -158,19 +179,19 @@ beaker = item user.drop_item() - item.loc = src + item.forceMove(src) user.visible_message("\The [user] adds \a [item] to \the [src]!", "You add \a [item] to \the [src]!") SStgui.update_uis(src) return else if(istype(item, /obj/item/organ/internal/brain)) - if(src.occupant) + if(occupant) to_chat(user, span_warning("The scanner is already occupied!")) return var/obj/item/organ/internal/brain/brain = item if(brain.clone_source) user.drop_item() - brain.loc = src + brain.forceMove(src) put_in(brain.brainmob) src.add_fingerprint(user) user.visible_message("\The [user] adds \a [item] to \the [src]!", "You add \a [item] to \the [src]!") @@ -184,7 +205,7 @@ var/obj/item/grab/G = item if(!ismob(G.affecting)) return - if(src.occupant) + if(occupant) to_chat(user, span_warning("The scanner is already occupied!")) return if(G.affecting.abiotic()) @@ -195,13 +216,32 @@ qdel(G) return +// Traitgenes Deconstructable dna scanner +/obj/machinery/dna_scannernew/dismantle() + // release contents + if(beaker) + beaker.forceMove(get_turf(src)) + beaker = null + if(occupant) + var/mob/living/carbon/WC = occupant.resolve() + WC.forceMove(get_turf(src)) + occupant = null + // Disconnect from our terminal + for(var/dirfind in cardinal) + var/obj/machinery/computer/scan_consolenew/console = locate(/obj/machinery/computer/scan_consolenew, get_step(src, dirfind)) + if(console && console.connected == src) + console.connected = null + SStgui.close_uis(console) + break + . = ..() + /obj/machinery/dna_scannernew/proc/put_in(var/mob/M) if(M.client) M.client.perspective = EYE_PERSPECTIVE M.client.eye = src - M.loc = src - src.occupant = M - src.icon_state = "scanner_1" + M.forceMove(src) + occupant = WEAKREF(M) + icon_state = "scanner_1" // search for ghosts, if the corpse is empty and the scanner is connected to a cloner if(locate(/obj/machinery/computer/cloning, get_step(src, NORTH)) \ @@ -217,49 +257,45 @@ SStgui.update_uis(src) /obj/machinery/dna_scannernew/proc/go_out() - if((!( src.occupant ) || src.locked)) + if((!(occupant) || locked)) return - if(src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - if(istype(occupant,/mob/living/carbon/brain)) + var/mob/living/carbon/WC = occupant.resolve() + if(WC.client) + WC.client.eye = WC.client.mob + WC.client.perspective = MOB_PERSPECTIVE + if(istype(WC,/mob/living/carbon/brain)) for(var/obj/O in src) if(istype(O,/obj/item/organ/internal/brain)) - O.loc = get_turf(src) - src.occupant.loc = O + O.forceMove(get_turf(src)) + WC.forceMove(O) break else - src.occupant.loc = src.loc - src.occupant = null - src.icon_state = "scanner_0" + WC.forceMove(loc) + occupant = null + icon_state = "scanner_0" SStgui.update_uis(src) /obj/machinery/dna_scannernew/ex_act(severity) + var/our_tile = loc //This is done here as if you try to feed loc in the A.forcemove, it will runtime as src id qdel'd before they can be moved. switch(severity) if(1.0) for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc + A.forceMove(our_tile) ex_act(severity) - //Foreach goto(35) - //SN src = null qdel(src) return if(2.0) if(prob(50)) for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc + A.forceMove(our_tile) ex_act(severity) - //Foreach goto(108) - //SN src = null qdel(src) return if(3.0) if(prob(25)) for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc + A.forceMove(our_tile) ex_act(severity) - //Foreach goto(181) - //SN src = null qdel(src) return else @@ -280,25 +316,31 @@ var/selected_ui_target_hex = 1 var/radiation_duration = 2.0 var/radiation_intensity = 1.0 - var/list/datum/dna2/record/buffers[3] + var/list/datum/transhuman/body_record/buffers[3] // Traitgenes Use bodyrecords var/irradiating = 0 var/injector_ready = 0 //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete var/obj/machinery/dna_scannernew/connected = null - var/obj/item/disk/data/disk = null - var/selected_menu_key = PAGE_UI + // Traitgenes body record disks are used instead of a unique disk + var/obj/item/disk/body_record/disk = null + var/selected_menu_key = PAGE_SE anchored = TRUE use_power = USE_POWER_IDLE idle_power_usage = 10 active_power_usage = 400 /obj/machinery/computer/scan_consolenew/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/disk/data)) //INSERT SOME diskS - if(!src.disk) - user.drop_item() - I.loc = src - src.disk = I - to_chat(user, "You insert [I].") - SStgui.update_uis(src) // update all UIs attached to src + // Traitgenes body record disks are used instead of a unique disk + if(istype(I, /obj/item/disk/body_record)) //INSERT SOME diskS + if(connected) + if(!disk) + user.drop_item() + I.forceMove(src) + disk = I + to_chat(user, "You insert [I].") + SStgui.update_uis(src) // update all UIs attached to src + return + else + to_chat(user, "\The [src] will not accept a disk without a DNA modifier connected.") return else ..() @@ -308,12 +350,10 @@ switch(severity) if(1.0) - //SN src = null qdel(src) return if(2.0) if(prob(50)) - //SN src = null qdel(src) return else @@ -322,9 +362,16 @@ /obj/machinery/computer/scan_consolenew/Initialize() . = ..() for(var/i=0;i<3;i++) - buffers[i+1]=new /datum/dna2/record - for(dir in list(NORTH,EAST,SOUTH,WEST)) - connected = locate(/obj/machinery/dna_scannernew, get_step(src, dir)) + // Traitgenes Use bodyrecords + var/datum/transhuman/body_record/R = new /datum/transhuman/body_record() + R.mydna = new + R.mydna.dna = new + R.mydna.dna.ResetUI() + R.mydna.dna.ResetSE() + buffers[i+1]=R + // Traitgenes don't alter direction of computer as this scans for neighbour + for(var/dirfind in cardinal) + connected = locate(/obj/machinery/dna_scannernew, get_step(src, dirfind)) if(connected) break VARSET_IN(src, injector_ready, TRUE, 25 SECONDS) @@ -335,7 +382,7 @@ arr += "[i]:[EncodeDNABlock(buffer[i])]" return arr -/obj/machinery/computer/scan_consolenew/proc/setInjectorBlock(var/obj/item/dnainjector/I, var/blk, var/datum/dna2/record/buffer) +/obj/machinery/computer/scan_consolenew/proc/setInjectorBlock(var/obj/item/dnainjector/I, var/blk, var/datum/transhuman/body_record/buffer) // Traitgenes Stores the entire body record var/pos = findtext(blk,":") if(!pos) return 0 var/id = text2num(copytext(blk,1,pos)) @@ -344,15 +391,6 @@ I.buf = buffer return 1 -/* -/obj/machinery/computer/scan_consolenew/process() //not really used right now - if(stat & (NOPOWER|BROKEN)) - return - if(!( src.status )) //remove this - return - return -*/ - /obj/machinery/computer/scan_consolenew/attack_ai(user as mob) src.add_hiddenprint(user) tgui_interact(user) @@ -362,7 +400,8 @@ tgui_interact(user) /obj/machinery/computer/scan_consolenew/tgui_interact(mob/user, datum/tgui/ui) - if(!connected || user == connected.occupant || user.stat) + var/mob/living/carbon/WC = connected?.occupant?.resolve() + if(!connected || user == WC || user.stat) return ui = SStgui.try_update_ui(user, src, ui) if(!ui) @@ -381,19 +420,24 @@ data["hasDisk"] = disk ? 1 : 0 var/diskData[0] - if(!disk || !disk.buf) + if(!disk || !disk.stored || !disk.stored.mydna) // Traitgenesbody record disks are used instead of a unique disk diskData["data"] = null diskData["owner"] = null diskData["label"] = null diskData["type"] = null diskData["ue"] = null else - diskData = disk.buf.GetData() + diskData = disk.stored.mydna.GetData() // Traitgenes body record disks are used instead of a unique disk data["disk"] = diskData - var/list/new_buffers = list() - for(var/datum/dna2/record/buf in src.buffers) - new_buffers += list(buf.GetData()) + // Traitgenes Fixed buffer menu + var/list/new_buffers[src.buffers.len] + for(var/i=1;i<=src.buffers.len;i++) + var/datum/transhuman/body_record/R = buffers[i] + if(R && R.mydna) + new_buffers[i]=R.mydna.GetData() + else + new_buffers[i]=list("data" = list(), "owner" = null, "label" = null, "type" = DNA2_BUF_SE, "ue" = 0) data["buffers"]=new_buffers data["radiationIntensity"] = radiation_intensity @@ -409,7 +453,8 @@ data["selectedUITargetHex"] = selected_ui_target_hex var/occupantData[0] - if(!src.connected.occupant || !src.connected.occupant.dna) + var/mob/living/carbon/WC = connected?.occupant?.resolve() + if(!WC || !WC.dna) occupantData["name"] = null occupantData["stat"] = null occupantData["isViableSubject"] = null @@ -421,18 +466,26 @@ occupantData["structuralEnzymes"] = null occupantData["radiationLevel"] = null else - occupantData["name"] = connected.occupant.real_name - occupantData["stat"] = connected.occupant.stat + occupantData["name"] = WC.real_name + occupantData["stat"] = WC.stat occupantData["isViableSubject"] = 1 - if(NOCLONE in connected.occupant.mutations || !src.connected.occupant.dna) + // Traitgenes NO_SCAN and Synthetics cannot be mutated + var/allowed = TRUE + if(WC.isSynthetic()) + allowed = FALSE + if(ishuman(WC)) + var/mob/living/carbon/human/H = WC + if(!H.species || (H.species.flags & NO_SCAN)) + allowed = FALSE + if(!allowed || (NOCLONE in WC.mutations) || !WC.dna) occupantData["isViableSubject"] = 0 - occupantData["health"] = connected.occupant.health - occupantData["maxHealth"] = connected.occupant.maxHealth + occupantData["health"] = WC.health + occupantData["maxHealth"] = WC.maxHealth occupantData["minHealth"] = CONFIG_GET(number/health_threshold_dead) - occupantData["uniqueEnzymes"] = connected.occupant.dna.unique_enzymes - occupantData["uniqueIdentity"] = connected.occupant.dna.uni_identity - occupantData["structuralEnzymes"] = connected.occupant.dna.struc_enzymes - occupantData["radiationLevel"] = connected.occupant.radiation + occupantData["uniqueEnzymes"] = WC.dna.unique_enzymes + occupantData["uniqueIdentity"] = WC.dna.uni_identity + occupantData["structuralEnzymes"] = WC.dna.struc_enzymes + occupantData["radiationLevel"] = WC.radiation data["occupant"] = occupantData; data["isBeakerLoaded"] = connected.beaker ? 1 : 0 @@ -454,7 +507,7 @@ return TRUE if(!istype(ui.user.loc, /turf)) return TRUE - if(!src || !src.connected) + if(!src || !connected) return TRUE if(irradiating) // Make sure that it isn't already irradiating someone... return TRUE @@ -464,107 +517,60 @@ if(tgui_act_modal(action, params)) return TRUE - . = TRUE switch(action) if("selectMenuKey") + playsound(src, 'sound/machines/button.ogg', 30, 1, 0) var/key = params["key"] - if(!(key in list(PAGE_UI, PAGE_SE, PAGE_BUFFER, PAGE_REJUVENATORS))) - return + if(!(key in list(/*PAGE_UI,*/ PAGE_SE, PAGE_BUFFER, PAGE_REJUVENATORS))) // Traitgenes Body design console is used to edit UIs now + return TRUE selected_menu_key = key + return TRUE if("toggleLock") + playsound(src, 'sound/machines/button.ogg', 30, 1, 0) if(connected && connected.occupant) connected.locked = !(connected.locked) + return TRUE if("pulseRadiation") + playsound(src, 'sound/machines/button.ogg', 30, 1, 0) irradiating = radiation_duration var/lock_state = connected.locked connected.locked = TRUE //lock it - - SStgui.update_uis(src) // update all UIs attached to src - sleep(10 * radiation_duration) // sleep for radiation_duration seconds - - irradiating = 0 - connected.locked = lock_state - - if(!connected.occupant) - return - - if(prob(95)) - if(prob(75)) - randmutb(connected.occupant) - else - randmuti(connected.occupant) - else - if(prob(95)) - randmutg(connected.occupant) - else - randmuti(connected.occupant) - - connected.occupant.apply_effect(((radiation_intensity*3)+radiation_duration*3), IRRADIATE, check_protection = 0) + addtimer(CALLBACK(src, PROC_REF(do_pulse), lock_state), radiation_duration SECONDS, TIMER_DELETE_ME) + return TRUE if("radiationDuration") radiation_duration = clamp(text2num(params["value"]), 1, 20) + return TRUE if("radiationIntensity") radiation_intensity = clamp(text2num(params["value"]), 1, 10) - //////////////////////////////////////////////////////// - if("changeUITarget") - selected_ui_target = clamp(text2num(params["value"]), 1, 15) - selected_ui_target_hex = num2text(selected_ui_target, 1, 16) - if("selectUIBlock") // This chunk of code updates selected block / sub-block based on click - var/select_block = text2num(params["block"]) - var/select_subblock = text2num(params["subblock"]) - if(!select_block || !select_subblock) - return - - selected_ui_block = clamp(select_block, 1, DNA_UI_LENGTH) - selected_ui_subblock = clamp(select_subblock, 1, DNA_BLOCK_SIZE) - if("pulseUIRadiation") - var/block = connected.occupant.dna.GetUISubBlock(selected_ui_block,selected_ui_subblock) - - irradiating = radiation_duration - var/lock_state = connected.locked - connected.locked = TRUE //lock it - - SStgui.update_uis(src) // update all UIs attached to src - sleep(10 * radiation_duration) // sleep for radiation_duration seconds - - irradiating = 0 - connected.locked = lock_state - - if(!connected.occupant) - return - - if(prob((80 + (radiation_duration / 2)))) - block = miniscrambletarget(num2text(selected_ui_target), radiation_intensity, radiation_duration) - connected.occupant.dna.SetUISubBlock(selected_ui_block,selected_ui_subblock,block) - connected.occupant.UpdateAppearance() - connected.occupant.apply_effect((radiation_intensity+radiation_duration), IRRADIATE, check_protection = 0) - else - if(prob(20 + radiation_intensity)) - randmutb(connected.occupant) - domutcheck(connected.occupant,connected) - else - randmuti(connected.occupant) - connected.occupant.UpdateAppearance() - connected.occupant.apply_effect(((radiation_intensity*2)+radiation_duration), IRRADIATE, check_protection = 0) - //////////////////////////////////////////////////////// + return TRUE if("injectRejuvenators") + playsound(src, 'sound/machines/button.ogg', 30, 1, 0) if(!connected.occupant || !connected.beaker) - return + return TRUE + var/mob/living/carbon/WC = connected?.occupant?.resolve() var/inject_amount = clamp(round(text2num(params["amount"]), 5), 0, 50) // round to nearest 5 and clamp to 0-50 if(!inject_amount) - return - connected.beaker.reagents.trans_to_mob(connected.occupant, inject_amount, CHEM_BLOOD) + return TRUE + connected.beaker.reagents.trans_to_mob(WC, inject_amount, CHEM_BLOOD) + return TRUE //////////////////////////////////////////////////////// if("selectSEBlock") // This chunk of code updates selected block / sub-block based on click (se stands for strutural enzymes) + playsound(src, "keyboard", 40) var/select_block = text2num(params["block"]) var/select_subblock = text2num(params["subblock"]) if(!select_block || !select_subblock) - return + return TRUE selected_se_block = clamp(select_block, 1, DNA_SE_LENGTH) selected_se_subblock = clamp(select_subblock, 1, DNA_BLOCK_SIZE) + return TRUE if("pulseSERadiation") - var/block = connected.occupant.dna.GetSESubBlock(selected_se_block,selected_se_subblock) + if(!connected?.occupant) + return TRUE + var/mob/living/carbon/WC = connected?.occupant?.resolve() + playsound(src, "keyboard", 40) + var/block = WC.dna.GetSESubBlock(selected_se_block,selected_se_subblock) //var/original_block=block //testing("Irradiating SE block [selected_se_block]:[selected_se_subblock] ([block])...") @@ -572,156 +578,124 @@ var/lock_state = connected.locked connected.locked = TRUE //lock it - SStgui.update_uis(src) // update all UIs attached to src - sleep(10 * radiation_duration) // sleep for radiation_duration seconds + //We call the do_irradiate proc here after radation_duration SECONDS + addtimer(CALLBACK(src, PROC_REF(do_irradiate), lock_state, block), radiation_duration SECONDS, TIMER_DELETE_ME) + return TRUE - irradiating = 0 - connected.locked = lock_state - - if(connected.occupant) - if(prob((80 + (radiation_duration / 2)))) - // FIXME: Find out what these corresponded to and change them to the WHATEVERBLOCK they need to be. - //if((selected_se_block != 2 || selected_se_block != 12 || selected_se_block != 8 || selected_se_block || 10) && prob (20)) - var/real_SE_block=selected_se_block - block = miniscramble(block, radiation_intensity, radiation_duration) - if(prob(20)) - if(selected_se_block > 1 && selected_se_block < DNA_SE_LENGTH/2) - real_SE_block++ - else if(selected_se_block > DNA_SE_LENGTH/2 && selected_se_block < DNA_SE_LENGTH) - real_SE_block-- - - //testing("Irradiated SE block [real_SE_block]:[selected_se_subblock] ([original_block] now [block]) [(real_SE_block!=selected_se_block) ? "(SHIFTED)":""]!") - connected.occupant.dna.SetSESubBlock(real_SE_block,selected_se_subblock,block) - connected.occupant.apply_effect((radiation_intensity+radiation_duration), IRRADIATE, check_protection = 0) - domutcheck(connected.occupant,connected) - else - connected.occupant.apply_effect(((radiation_intensity*2)+radiation_duration), IRRADIATE, check_protection = 0) - if (prob(80-radiation_duration)) - //testing("Random bad mut!") - randmutb(connected.occupant) - domutcheck(connected.occupant,connected) - else - randmuti(connected.occupant) - //testing("Random identity mut!") - connected.occupant.UpdateAppearance() if("ejectBeaker") + playsound(src, 'sound/machines/button.ogg', 30, 1, 0) if(connected.beaker) var/obj/item/reagent_containers/glass/B = connected.beaker - B.loc = connected.loc + B.forceMove(connected.loc) connected.beaker = null + return TRUE if("ejectOccupant") + playsound(src, 'sound/machines/button.ogg', 30, 1, 0) connected.eject_occupant() + // Eject disk too, because we can't get to the UI otherwise + if(!disk) + return TRUE + disk.forceMove(get_turf(src)) + disk = null // Transfer Buffer Management if("bufferOption") var/bufferOption = params["option"] var/bufferId = text2num(params["id"]) if(bufferId < 1 || bufferId > 3) // Not a valid buffer id - return + return TRUE - var/datum/dna2/record/buffer = buffers[bufferId] + var/datum/transhuman/body_record/buffer = buffers[bufferId] // Traitgenes Use bodyrecords switch(bufferOption) - if("saveUI") - if(connected.occupant && connected.occupant.dna) - var/datum/dna2/record/databuf=new - databuf.types = DNA2_BUF_UI // DNA2_BUF_UE - databuf.dna = connected.occupant.dna.Clone() - if(ishuman(connected.occupant)) - var/mob/living/carbon/human/H = connected.occupant - databuf.dna.real_name = H.dna.real_name - databuf.gender = H.gender - databuf.body_descriptors = H.descriptors - databuf.name = "Unique Identifier" - buffers[bufferId] = databuf - if("saveUIAndUE") - if(connected.occupant && connected.occupant.dna) - var/datum/dna2/record/databuf=new - databuf.types = DNA2_BUF_UI|DNA2_BUF_UE - databuf.dna = connected.occupant.dna.Clone() - if(ishuman(connected.occupant)) - var/mob/living/carbon/human/H = connected.occupant - databuf.dna.real_name = H.dna.real_name - databuf.gender = H.gender - databuf.body_descriptors = H.descriptors - databuf.name = "Unique Identifier + Unique Enzymes" - buffers[bufferId] = databuf - if("saveSE") - if(connected.occupant && connected.occupant.dna) - var/datum/dna2/record/databuf=new - databuf.types = DNA2_BUF_SE - databuf.dna = connected.occupant.dna.Clone() - if(ishuman(connected.occupant)) - var/mob/living/carbon/human/H = connected.occupant - databuf.dna.real_name = H.dna.real_name - databuf.gender = H.gender - databuf.body_descriptors = H.descriptors - databuf.name = "Structural Enzymes" + // Traitgenes Moved SE and UI saves to storing the entire body record + if("saveDNA") + playsound(src, "keyboard", 40) // into console + var/mob/living/carbon/WC = connected?.occupant?.resolve() + if(WC && WC.dna) + // Traitgenes Properly clone records + var/datum/transhuman/body_record/databuf = new /datum/transhuman/body_record() + databuf.init_from_mob(WC) + databuf.mydna.types = DNA2_BUF_SE // structurals only + if(ishuman(WC)) + var/mob/living/carbon/human/H = WC + databuf.mydna.dna.real_name = H.dna.real_name + databuf.mydna.gender = H.gender + databuf.mydna.body_descriptors = H.descriptors buffers[bufferId] = databuf + return TRUE if("clear") - buffers[bufferId] = new /datum/dna2/record() + playsound(src, "keyboard", 40) + // Traitgenes Storing the entire body record + var/datum/transhuman/body_record/R = new /datum/transhuman/body_record() + R.mydna = new + R.mydna.dna = new + R.mydna.dna.ResetUI() + R.mydna.dna.ResetSE() + buffers[bufferId] = R + return TRUE if("changeLabel") - tgui_modal_input(src, "changeBufferLabel", "Please enter the new buffer label:", null, list("id" = bufferId), buffer.name, TGUI_MODAL_INPUT_MAX_LENGTH_NAME) + playsound(src, "keyboard", 40) + tgui_modal_input(src, "changeBufferLabel", "Please enter the new buffer label:", null, list("id" = bufferId), buffer.mydna.name, TGUI_MODAL_INPUT_MAX_LENGTH_NAME) + return TRUE if("transfer") - if(!connected.occupant || (NOCLONE in connected.occupant.mutations) || !connected.occupant.dna) - return - + var/mob/living/carbon/WC = connected?.occupant?.resolve() + if(!WC || (NOCLONE in WC.mutations) || !WC.dna) + return TRUE irradiating = 2 var/lock_state = connected.locked connected.locked = 1//lock it - - SStgui.update_uis(src) // update all UIs attached to src - sleep(2 SECONDS) // sleep for 2 seconds - - irradiating = 0 - connected.locked = lock_state - - var/datum/dna2/record/buf = buffers[bufferId] - - if((buf.types & DNA2_BUF_UI)) - if((buf.types & DNA2_BUF_UE)) - connected.occupant.real_name = buf.dna.real_name - connected.occupant.name = buf.dna.real_name - if(ishuman(connected.occupant)) - var/mob/living/carbon/human/H = connected.occupant - H.gender = buf.gender - H.descriptors = buf.body_descriptors - connected.occupant.UpdateAppearance(buf.dna.UI.Copy()) - else if(buf.types & DNA2_BUF_SE) - connected.occupant.dna.SE = buf.dna.SE - connected.occupant.dna.UpdateSE() - if(ishuman(connected.occupant)) - var/mob/living/carbon/human/H = connected.occupant - H.gender = buf.gender - H.descriptors = buf.body_descriptors - domutcheck(connected.occupant,connected) - connected.occupant.apply_effect(rand(20,50), IRRADIATE, check_protection = 0) + addtimer(CALLBACK(src, PROC_REF(do_transfer), lock_state, bufferId), 2 SECONDS, TIMER_DELETE_ME) + return TRUE if("createInjector") if(!injector_ready) - return + return TRUE if(text2num(params["block"]) > 0) - var/list/choices = all_dna_blocks((buffer.types & DNA2_BUF_SE) ? buffer.dna.SE : buffer.dna.UI) + var/list/choices = all_dna_blocks(buffer.mydna.dna.SE) // Traitgenes Storing the entire body record, and no more using UIs tgui_modal_choice(src, "createInjectorBlock", "Please select the block to create an injector from:", null, list("id" = bufferId), null, choices) else create_injector(bufferId, TRUE) + return TRUE + // Traitgenes Storing the entire body record if("loadDisk") - if(isnull(disk) || disk.read_only) + playsound(src, "keyboard", 40) + if(isnull(disk) || !disk.stored) return - buffers[bufferId] = disk.buf.copy() + // Traitgenes Properly clone records + var/datum/transhuman/body_record/databuf = new /datum/transhuman/body_record() + databuf.init_from_br(disk.stored) + databuf.mydna.types = DNA2_BUF_SE // structurals only + buffers[bufferId] = databuf if("saveDisk") - if(isnull(disk) || disk.read_only) - return - var/datum/dna2/record/buf = buffers[bufferId] - disk.buf = buf.copy() - disk.name = "data disk - '[buf.dna.real_name]'" + playsound(src, "keyboard", 40) + if(isnull(disk)) // Traitgenes Removed readonly + return TRUE + var/datum/transhuman/body_record/buf = buffers[bufferId] + // Traitgenes Properly clone records + disk.stored = new /datum/transhuman/body_record() + disk.stored.init_from_br(buf) + disk.stored.mydna.types = DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE // DNA disks need to maintain their data + disk.name = "Body Design Disk ('[buf.mydna.name]')" + return TRUE + if("sleeveDisk") + playsound(src, "keyboard", 40) + var/datum/transhuman/body_record/buf = buffers[bufferId] + // Send printable record to first sleevepod in area + print_sleeve(usr, buf) + return TRUE if("wipeDisk") - if(isnull(disk) || disk.read_only) - return - disk.buf = null + playsound(src, "keyboard", 40) + // Traitgenes Storing the entire body record + if(isnull(disk)) + return TRUE + disk.stored = null + return TRUE if("ejectDisk") + playsound(src, 'sound/machines/button.ogg', 30, 1, 0) if(!disk) - return + return TRUE disk.forceMove(get_turf(src)) disk = null + return TRUE /** * Creates a blank injector with the name of the buffer at the given buffer_id @@ -739,12 +713,13 @@ addtimer(CALLBACK(src, PROC_REF(injector_cooldown_finish)), 30 SECONDS) // Create it - var/datum/dna2/record/buf = buffers[buffer_id] + var/datum/transhuman/body_record/buf = buffers[buffer_id] // Traitgenes Use bodyrecords var/obj/item/dnainjector/I = new() + buf.mydna.types = DNA2_BUF_SE // Traitgenes SE only, use the designer for UI and UEs, super broken in this codebase due to years of no one respecting genetics... I.forceMove(loc) - I.name += " ([buf.name])" + I.name += " ([buf.mydna.name])" if(copy_buffer) - I.buf = buf.copy() + I.buf = buf.mydna.copy() return I /** @@ -772,24 +747,164 @@ var/buffer_id = text2num(arguments["id"]) if(buffer_id < 1 || buffer_id > length(buffers)) return - var/datum/dna2/record/buf = buffers[buffer_id] + var/datum/transhuman/body_record/buf = buffers[buffer_id] // Traitgenes Use bodyrecords var/obj/item/dnainjector/I = create_injector(buffer_id) - setInjectorBlock(I, answer, buf.copy()) + setInjectorBlock(I, answer, buf.mydna.copy()) // Traitgenes Use bodyrecords + I.name += " - Block [answer]" // Traitgenes By default show the block of a block injector if("changeBufferLabel") var/buffer_id = text2num(arguments["id"]) if(buffer_id < 1 || buffer_id > length(buffers)) return - var/datum/dna2/record/buf = buffers[buffer_id] - buf.name = answer + var/datum/transhuman/body_record/buf = buffers[buffer_id] // Traitgenes Use bodyrecords + buf.mydna.name = answer // Traitgenes Use bodyrecords buffers[buffer_id] = buf else return FALSE else return FALSE + +/** + * Triggers sleeve growing in a clonepod within the area + * + * Arguments: + * * active_br - Body record to print + */ +/obj/machinery/computer/scan_consolenew/proc/print_sleeve(var/mob/user, var/datum/transhuman/body_record/active_br) + //deleted record + if(!istype(active_br)) + to_chat(user, span_danger( "Error: Data corruption.")) + return + //Trying to make an fbp + if(active_br.synthetic ) + to_chat(user, span_danger( "Error: Cannot grow synthetic.")) + return + //No pods + var/obj/machinery/clonepod/transhuman/pod = locate() in get_area(src) + if(!pod) + to_chat(user, span_danger( "Error: No growpods detected.")) + return + //Already doing someone. + if(pod.occupant) + to_chat(user, span_danger( "Error: Growpod is currently occupied.")) + return + //Not enough materials. + if(pod.get_biomass() < CLONE_BIOMASS) + to_chat(user, span_danger( "Error: Not enough biomass.")) + return + //Gross pod (broke mid-cloning or something). + if(pod.mess) + to_chat(user, span_danger( "Error: Growpod malfunction.")) + return + //Disabled in config. + if(!CONFIG_GET(flag/revival_cloning)) + to_chat(user, span_danger( "Error: Unable to initiate growing cycle.")) + return + //Invalid genes! + if(active_br.mydna.name == "Empty" || active_br.mydna.id == null) + to_chat(user, span_danger( "Error: Data corruption.")) + return + //Do the cloning! + if(!pod.growclone(active_br)) + to_chat(user, span_danger( "Initiating growing cycle... Error: Post-initialisation failed. Growing cycle aborted.")) + return + to_chat(user, span_notice( "Initiating growing cycle...")) + +/obj/machinery/computer/scan_consolenew/proc/do_irradiate(var/lock_state, var/block) + var/mob/living/carbon/WC = connected?.occupant?.resolve() + irradiating = 0 + connected.locked = lock_state + if(!WC) + return + + if(prob((80 + (radiation_duration / 2)))) + // FIXME: Find out what these corresponded to and change them to the WHATEVERBLOCK they need to be. + //if((selected_se_block != 2 || selected_se_block != 12 || selected_se_block != 8 || selected_se_block || 10) && prob (20)) + var/real_SE_block=selected_se_block + block = miniscramble(block, radiation_intensity, radiation_duration) + if(prob(20)) + if(selected_se_block > 1 && selected_se_block < DNA_SE_LENGTH/2) + real_SE_block++ + else if(selected_se_block > DNA_SE_LENGTH/2 && selected_se_block < DNA_SE_LENGTH) + real_SE_block-- + + //testing("Irradiated SE block [real_SE_block]:[selected_se_subblock] ([original_block] now [block]) [(real_SE_block!=selected_se_block) ? "(SHIFTED)":""]!") + WC.dna.SetSESubBlock(real_SE_block,selected_se_subblock,block) + WC.apply_effect((radiation_intensity+radiation_duration), IRRADIATE, check_protection = 0) + else + WC.apply_effect(((radiation_intensity*2)+radiation_duration), IRRADIATE, check_protection = 0) + if (prob(80-radiation_duration)) + //testing("Random bad mut!") + randmutb(WC) + domutcheck(WC,null,MUTCHK_FORCED) + WC.UpdateAppearance() + // Traitgenes Do gene updates here, and more comprehensively + if(ishuman(WC)) + var/mob/living/carbon/human/H = WC + H.sync_dna_traits(FALSE,TRUE) + H.sync_organ_dna() + WC.regenerate_icons() + +/obj/machinery/computer/scan_consolenew/proc/do_pulse(var/lock_state) + var/mob/living/carbon/WC = connected?.occupant?.resolve() + irradiating = 0 + connected.locked = lock_state + + if(!WC) + return + // Traitgenes Make the fullbody irritation more risky + if(prob((radiation_intensity*2) + (radiation_duration*2))) + if(prob(95)) + if(prob(75)) + randmutb(WC) + else + if(prob(95)) + randmutg(WC) + domutcheck(WC,null,MUTCHK_FORCED) + WC.UpdateAppearance() + // Traitgenes Do gene updates here, and more comprehensively + if(ishuman(WC)) + var/mob/living/carbon/human/H = WC + H.sync_dna_traits(FALSE,FALSE) + H.sync_organ_dna() + WC.regenerate_icons() + + WC.apply_effect(((radiation_intensity*3)+radiation_duration*3), IRRADIATE, check_protection = 0) + + +/obj/machinery/computer/scan_consolenew/proc/do_transfer(var/lock_state, var/bufferId) + irradiating = 0 + connected.locked = lock_state + + playsound(src, "keyboard", 40) + + var/mob/living/carbon/WC = connected?.occupant?.resolve() + if(!WC) + return TRUE + var/datum/transhuman/body_record/buf = buffers[bufferId] // Traitgenes- Use bodyrecords + if(buf.mydna.types & DNA2_BUF_SE) + // Apply SEs only to the current occupant! + WC.dna.SE = buf.mydna.dna.SE.Copy() + WC.dna.UpdateSE() + domutcheck(WC,connected, MUTCHK_FORCED | MUTCHK_HIDEMSG) // TOO MANY MUTATIONS FOR MESSAGES + WC.UpdateAppearance() + to_chat(WC, span_warning("Your body stings as it wildly changes!")) + + // apply genes + if(ishuman(WC)) + var/mob/living/carbon/human/H = WC + H.sync_organ_dna() + + //Apply genetic modifiers + WC.dna.genetic_modifiers.Cut() // clear em! + for(var/modifier_type in buf.genetic_modifiers) + WC.add_modifier(modifier_type) + WC.apply_effect(rand(20,50), IRRADIATE, check_protection = 0) + + + #undef DNA_BLOCK_SIZE -#undef PAGE_UI #undef PAGE_SE #undef PAGE_BUFFER #undef PAGE_REJUVENATORS diff --git a/code/game/dna/genes/gene.dm b/code/game/dna/genes/gene.dm index 5bf3145b33..d7d6608a5a 100644 --- a/code/game/dna/genes/gene.dm +++ b/code/game/dna/genes/gene.dm @@ -1,15 +1,4 @@ -/** -* Gene Datum -* -* domutcheck was getting pretty hairy. This is the solution. -* -* All genes are stored in a global variable to cut down on memory -* usage. -* -* @author N3X15 -*/ - -/datum/dna/gene +/datum/gene // Traitgenes Removed /dna/ from path... WHY WAS THIS A SUBTYPE OF DNA!? It's taking a huge struct and making 50 of them at startup, growing with every new var and list stuffed in /datum/dna - Willbird // Display name var/name="BASE GENE" @@ -23,100 +12,152 @@ // Any of a number of GENE_ flags. var/flags=0 + /** * Is the gene active in this mob's DNA? */ -/datum/dna/gene/proc/is_active(var/mob/M) - return (M.active_genes && (type in M.active_genes)) +/datum/gene/proc/is_active(var/mob/M) // Traitgenes edit - Removed /dna/ from path + return (M.active_genes && (name in M.active_genes)) // Traitgenes edit - Use name instead, cannot use type with dynamically setup traitgenes. It is always unique due to the block number being appended to it. // Return 1 if we can activate. // HANDLE MUTCHK_FORCED HERE! -/datum/dna/gene/proc/can_activate(var/mob/M, var/flags) +/datum/gene/proc/can_activate(var/mob/M, var/mut_flags) // Traitgenes edit - Removed /dna/ from path. mut_flags instead of flags for clarity return 0 // Called when the gene activates. Do your magic here. -/datum/dna/gene/proc/activate(var/mob/M, var/connected, var/flags) +/datum/gene/proc/activate(var/mob/M, var/connected, var/mut_flags) // Traitgenes edit - Removed /dna/ from path. mut_flags instead of flags for clarity return /** * Called when the gene deactivates. Undo your magic here. * Only called when the block is deactivated. */ -/datum/dna/gene/proc/deactivate(var/mob/M, var/connected, var/flags) +/datum/gene/proc/deactivate(var/mob/M, var/connected, var/mut_flags) // Traitgenes edit - Removed /dna/ from path. mut_flags instead of flags for clarity return -// This section inspired by goone's bioEffects. - -/** -* Called in each life() tick. -*/ -/datum/dna/gene/proc/OnMobLife(var/mob/M) - return - -/** -* Called when the mob dies -*/ -/datum/dna/gene/proc/OnMobDeath(var/mob/M) - return - -/** -* Called when the mob says shit -*/ -/datum/dna/gene/proc/OnSay(var/mob/M, var/message) - return message - -/** -* Called after the mob runs update_icons. -* -* @params M The subject. -* @params g Gender (m or f) -* @params fat Fat? (0 or 1) -*/ -/datum/dna/gene/proc/OnDrawUnderlays(var/mob/M, var/g, var/fat) - return 0 - - +// Traitgenes edit - Genes are linked to traits now. Because no one bothered to maintain genes, and instead jumped through two different trait systems to avoid them. So here we are. - Willbird ///////////////////// -// BASIC GENES +// TRAIT GENES // -// These just chuck in a mutation and display a message. -// -// Gene is activated: -// 1. If mutation already exists in mob -// 2. If the probability roll succeeds -// 3. Activation is forced (done in domutcheck) +// Activate traits with a message when enabled +// IMPORTANT - in 99% of situations you should NOT need to edit gene code when adding a new traitgene. Genes only handle the on/off state of traits, traits control the changes and behaviors! +// Just keep pretending genecode doesn't exist and you should be fine. Traitgenes were made with that in mind, and are not intended to be something you need to edit every time you add a traitgene. +// Traitgenes only require that your trait has both an apply() and unapply() if it does anything like adding verbs. Otherwise, you don't even need to add trait exceptions. traitgenes handle it automatically. +// You probably shouldn't mark traits as traitgenes if they are custom species only, species locked, or species banned traits however... - Willbird ///////////////////// -/datum/dna/gene/basic - name="BASIC GENE" +/datum/gene/trait + desc="Gene linked to a trait." + var/datum/trait/linked_trait = null // Internal use, do not assign. + var/list/conflict_traits = list() // Cache known traits that don't work with this one, instead of doing it all at once, or EVERY time we do a mutation check - // Mutation to give - var/mutation=0 +/datum/gene/trait/Destroy() + // unlink circular reference + if(linked_trait) + linked_trait.linked_gene = null + linked_trait = null + . = ..() - // Activation probability - var/activation_prob=45 +// Use these when displaying info to players +/datum/gene/trait/proc/get_name() + if(linked_trait) + return linked_trait.name + return name - // Possible activation messages - var/list/activation_messages=list() +/datum/gene/trait/proc/get_desc() + if(linked_trait) + return linked_trait.desc + return desc - // Possible deactivation messages - var/list/deactivation_messages=list() +/datum/gene/trait/can_activate(var/mob/M,var/mut_flags) + return TRUE // We don't do probability checks for trait genes, due to the spiderweb of logic they are with conflicting genes. Check has_conflicts() for how conflicting traits are handled. -/datum/dna/gene/basic/can_activate(var/mob/M,var/flags) - if(flags & MUTCHK_FORCED) - return 1 - // Probability check - return probinj(activation_prob,(flags&MUTCHK_FORCED)) +/** + * Behold the CONFLICT-O-TRON. Checks for trait conflicts the same way code\modules\client\preference_setup\vore\07_traits.dm does, + * and then caches the results. Cause traits can't change conflicts mid-round. Unless that changes someday, god help us all if so. + * You do not need to add any unique exceptions here, check trait code instead if you want to handle conflicts and forced exceptions. + * They already handle it. This just uses the same system. - Willbird + * + * quick_scan = FALSE, will do a deep conflict check. Checking every trait in the list, and not just failing out at the first one that conflicts. + * + * Recommended way to write has_conflict calls: + * ``` + * has_conflict(traits_to_check = list(trait_path)) + * ``` + */ +/datum/gene/trait/proc/has_conflict(var/list/traits_to_check, var/quick_scan = TRUE) + var/has_conflict = FALSE + var/path = linked_trait.type + for(var/P in traits_to_check) + // don't get triggered by self + if(P == path) + continue -/datum/dna/gene/basic/activate(var/mob/M) - M.mutations.Add(mutation) - if(activation_messages.len) - var/msg = pick(activation_messages) - to_chat(M, span_notice("[msg]")) + // check if cached first... + if(!isnull(conflict_traits[P])) + if(quick_scan && conflict_traits[P]) + return TRUE + continue -/datum/dna/gene/basic/deactivate(var/mob/M) - M.mutations.Remove(mutation) - if(deactivation_messages.len) - var/msg = pick(deactivation_messages) - to_chat(M, span_warning("[msg]")) + // check trait if not. CONFLICT-O-TRON ENGAGE + conflict_traits[P] = FALSE + + var/datum/trait/instance_test = all_traits[P] + if(path in instance_test.excludes) + conflict_traits[P] = TRUE + has_conflict = TRUE + // depending on scan mode we want to scan all, or only the first failure + if(quick_scan) + return TRUE + continue + for(var/V in linked_trait.var_changes) + if(V == "flags") + continue + if(V in instance_test.var_changes) + conflict_traits[P] = TRUE + has_conflict = TRUE + // depending on scan mode we want to scan all, or only the first failure + if(quick_scan) + return TRUE + continue + for(var/V in linked_trait.var_changes_pref) + if(V in instance_test.var_changes_pref) + conflict_traits[P] = TRUE + has_conflict = TRUE + // depending on scan mode we want to scan all, or only the first failure + if(quick_scan) + return TRUE + continue + return has_conflict + +/datum/gene/trait/activate(var/mob/M, var/connected, var/mut_flags) + if(linked_trait && ishuman(M)) + var/mob/living/carbon/human/H = M + if(H.species) // Lets avoid runtime assertions + // Add trait + if(linked_trait.type in H.species.traits) + return + linked_trait.apply( H.species, H, H.species.traits[linked_trait.type]) + H.species.traits.Add(linked_trait.type) + if(!(linked_trait.type in H.dna.species_traits)) // Set species traits too + H.dna.species_traits.Add(linked_trait.type) + // message player with change + if(!(mut_flags & MUTCHK_HIDEMSG)) + linked_trait.send_message( H, TRUE) + +/datum/gene/trait/deactivate(var/mob/M, var/connected, var/mut_flags) + if(linked_trait && ishuman(M)) + var/mob/living/carbon/human/H = M + if(H.species) // Lets avoid runtime assertions + // Remove trait + if(!(linked_trait.type in H.species.traits)) + return + linked_trait.unapply( H.species, H, H.species.traits[linked_trait.type]) + linked_trait.remove(H.species) // Does nothing, but may as well call it because it exists and has a place now + H.species.traits.Remove(linked_trait.type) + if(linked_trait.type in H.dna.species_traits) // Clear species traits too + H.dna.species_traits.Remove(linked_trait.type) + // message player with change + if(!(mut_flags & MUTCHK_HIDEMSG)) + linked_trait.send_message( H, FALSE) diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm index 69a7fe6fe9..ee60199480 100644 --- a/code/game/gamemodes/changeling/powers/transform.dm +++ b/code/game/gamemodes/changeling/powers/transform.dm @@ -35,7 +35,7 @@ if(ishuman(src)) var/mob/living/carbon/human/H = src var/newSpecies = chosen_dna.speciesName - H.set_species(newSpecies,1) + H.set_species(newSpecies) qdel_swap(src.dna, chosen_dna.dna.Clone()) src.dna.b_type = "AB+" //This is needed to avoid blood rejection bugs. The fact that the blood type might not match up w/ records could be a *FEATURE* too. @@ -47,6 +47,7 @@ src.real_name = chosen_dna.name src.UpdateAppearance() domutcheck(src, null) + UpdateAppearance() changeling_update_languages(changeling.absorbed_languages) if(chosen_dna.genMods) var/mob/living/carbon/human/self = src diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 2bf8f17592..e24ed45867 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -159,6 +159,7 @@ var/hadevent = 0 else randmutg(H) domutcheck(H,null,MUTCHK_FORCED) + H.UpdateAppearance() sleep(100) command_announcement.Announce("High levels of radiation detected near \the [station_name()]. Please report to the Med-bay if you feel strange.", "Anomaly Alert", new_sound = 'sound/AI/radiation.ogg') diff --git a/code/game/gamemodes/setupgame.dm b/code/game/gamemodes/setupgame.dm index 1ad2b543d3..db935e35a4 100644 --- a/code/game/gamemodes/setupgame.dm +++ b/code/game/gamemodes/setupgame.dm @@ -2,82 +2,63 @@ // (mostly) DNA2 SETUP ///////////////////////// -// Randomize block, assign a reference name, and optionally define difficulty (by making activation zone smaller or bigger) -// The name is used on /vg/ for species with predefined genetic traits, -// and for the DNA panel in the player panel. -/proc/getAssignedBlock(var/name,var/list/blocksLeft, var/activity_bounds=DNA_DEFAULT_BOUNDS) - if(blocksLeft.len==0) - warning("[name]: No more blocks left to assign!") - return 0 - var/assigned = pick(blocksLeft) - blocksLeft.Remove(assigned) - assigned_blocks[assigned]=name - dna_activity_bounds[assigned]=activity_bounds - //testing("[name] assigned to block #[assigned].") - return assigned - -/proc/setupgenetics() - - if (prob(50)) - // Currently unused. Will revisit. - N3X - BLOCKADD = rand(-300,300) - if (prob(75)) - DIFFMUT = rand(0,20) - - var/list/numsToAssign=new() - for(var/i=1;i") + else + dat += "There is no known treatment.
" OX = M.getOxyLoss() > 50 ? "[span_cyan(span_bold("Severe oxygen deprivation detected"))]" : "Subject bloodstream oxygen level normal" TX = M.getToxLoss() > 50 ? "[span_green(span_bold("Dangerous amount of toxins detected"))]" : "Subject bloodstream toxin level minimal" diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index 8a0a4493f8..9f79c86d76 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -5,21 +5,22 @@ icon_state = "dnainjector" var/block=0 var/datum/dna2/record/buf=null - var/s_time = 10.0 throw_speed = 1 throw_range = 5 w_class = ITEMSIZE_TINY slot_flags = SLOT_EARS var/uses = 1 var/nofail - var/is_bullet = 0 - var/inuse = 0 // USE ONLY IN PREMADE SYRINGES. WILL NOT WORK OTHERWISE. var/datatype=0 var/value=0 -/obj/item/dnainjector/New() + // Traitgenes edit begin - Removed subtype, replaced with flag. Allows for safe injectors. Mostly for admin usage. + var/has_radiation = TRUE + // Traitgenes edit end + +/obj/item/dnainjector/Initialize() // Traitgenes edit - Moved to init if(datatype && block) buf=new buf.dna=new @@ -28,6 +29,7 @@ //testing("[name]: DNA2 SE blocks prior to SetValue: [english_list(buf.dna.SE)]") SetValue(src.value) //testing("[name]: DNA2 SE blocks after SetValue: [english_list(buf.dna.SE)]") + . = ..() // Traitgenes edit - Moved to init /obj/item/dnainjector/proc/GetRealBlock(var/selblock) if(selblock==0) @@ -64,38 +66,54 @@ return buf.dna.SetUIValue(real_block,val) /obj/item/dnainjector/proc/inject(mob/M as mob, mob/user as mob) - if(isliving(M)) + if(isliving(M) && has_radiation) var/mob/living/L = M L.apply_effect(rand(5,20), IRRADIATE, check_protection = 0) L.apply_damage(max(2,L.getCloneLoss()), CLONE) - if (!(NOCLONE in M.mutations)) // prevents drained people from having their DNA changed - if (buf.types & DNA2_BUF_UI) - if (!block) //isolated block? - M.UpdateAppearance(buf.dna.UI.Copy()) - if (buf.types & DNA2_BUF_UE) //unique enzymes? yes - M.real_name = buf.dna.real_name - M.name = buf.dna.real_name + // Traitgenes edit begin - NO_SCAN and Synthetics cannot be mutated + var/allow = TRUE + if(M.isSynthetic()) + allow = FALSE + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(!H.species || H.species.flags & NO_SCAN) + allow = FALSE + // Traitgenes edit end + if (!(NOCLONE in M.mutations) && allow) // prevents drained people from having their DNA changed, Traitgenes edit - NO_SCAN and Synthetics cannot be mutated + if(buf) + if (buf.types & DNA2_BUF_UI) + if (!block) //isolated block? + M.UpdateAppearance(buf.dna.UI.Copy()) + if (buf.types & DNA2_BUF_UE) //unique enzymes? yes + M.real_name = buf.dna.real_name + M.name = buf.dna.real_name + uses-- + else + M.dna.SetUIValue(block,src.GetValue()) + M.UpdateAppearance() + uses-- + if (buf.types & DNA2_BUF_SE) + if (!block) //isolated block? + M.dna.SE = buf.dna.SE.Copy() + M.dna.UpdateSE() + else + M.dna.SetSEValue(block,src.GetValue()) uses-- - else - M.dna.SetUIValue(block,src.GetValue()) - M.UpdateAppearance() - uses-- - if (buf.types & DNA2_BUF_SE) - if (!block) //isolated block? - M.dna.SE = buf.dna.SE.Copy() - M.dna.UpdateSE() - else - M.dna.SetSEValue(block,src.GetValue()) - domutcheck(M, null, block!=null) - uses-- - if(prob(5)) - trigger_side_effect(M) + // Traitgenes edit - Moved gene checks to after side effects + if(prob(5)) + trigger_side_effect(M) + // Traitgenes edit begin - Do gene updates here, and more comprehensively + if(ishuman(M)) + var/mob/living/carbon/human/H = M + H.sync_dna_traits(FALSE,FALSE) + H.sync_organ_dna() + M.regenerate_icons() + // Traitgenes edit end - spawn(0)//this prevents the collapse of space-time continuum - if (user) - user.drop_from_inventory(src) - qdel(src) + if (user) + user.drop_from_inventory(src) + INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), src) return uses /obj/item/dnainjector/attack(mob/M as mob, mob/user as mob) @@ -103,18 +121,19 @@ return if (!user.IsAdvancedToolUser()) return - if(inuse) - return 0 + if (in_use) + return user.visible_message(span_danger("\The [user] is trying to inject \the [M] with \the [src]!")) - inuse = 1 - s_time = world.time - spawn(50) - inuse = 0 + in_use = TRUE + + //addtimer(VARSET_CALLBACK(src, in_use , FALSE), 5 SECONDS, TIMER_DELETE_ME) //Leaving this for reference of how to do the timer here if do_after wasn't present. if(!do_after(user,50)) + in_use = FALSE return + user.setClickCooldown(DEFAULT_QUICK_COOLDOWN) user.do_attack_animation(M) @@ -125,454 +144,209 @@ to_chat(user, span_warning("Apparently it didn't work...")) return - // Used by admin log. - var/injected_with_monkey = "" - if((buf.types & DNA2_BUF_SE) && (block ? (GetState() && block == MONKEYBLOCK) : GetState(MONKEYBLOCK))) - injected_with_monkey = span_danger("(MONKEY)") - - add_attack_logs(user,M,"[injected_with_monkey] used the [name] on") - - // Apply the DNA shit. inject(M, user) return -/obj/item/dnainjector/hulkmut - name = "\improper DNA injector (Hulk)" - desc = "This will make you big and strong, but give you a bad skin condition." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/hulkmut/New() - block = HULKBLOCK - ..() - -/obj/item/dnainjector/antihulk - name = "\improper DNA injector (Anti-Hulk)" - desc = "Cures green skin." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antihulk/New() - block = HULKBLOCK - ..() - -/obj/item/dnainjector/xraymut - name = "\improper DNA injector (Xray)" - desc = "Finally you can see what the " + JOB_SITE_MANAGER + " does." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/xraymut/New() - block = XRAYBLOCK - ..() - -/obj/item/dnainjector/antixray - name = "\improper DNA injector (Anti-Xray)" - desc = "It will make you see harder." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antixray/New() - block = XRAYBLOCK - ..() - -/obj/item/dnainjector/firemut - name = "\improper DNA injector (Fire)" - desc = "Gives you fire." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/firemut/New() - block = FIREBLOCK - ..() - -/obj/item/dnainjector/antifire - name = "\improper DNA injector (Anti-Fire)" - desc = "Cures fire." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antifire/New() - block = FIREBLOCK - ..() - -/obj/item/dnainjector/telemut - name = "\improper DNA injector (Tele.)" - desc = "Super brain man!" - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/telemut/New() - block = TELEBLOCK - ..() - -/obj/item/dnainjector/antitele - name = "\improper DNA injector (Anti-Tele.)" - desc = "Will make you not able to control your mind." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antitele/New() - block = TELEBLOCK - ..() - -/obj/item/dnainjector/nobreath - name = "\improper DNA injector (No Breath)" - desc = "Hold your breath and count to infinity." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/nobreath/New() - block = NOBREATHBLOCK - ..() - -/obj/item/dnainjector/antinobreath - name = "\improper DNA injector (Anti-No Breath)" - desc = "Hold your breath and count to 100." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antinobreath/New() - block = NOBREATHBLOCK - ..() - -/obj/item/dnainjector/remoteview - name = "\improper DNA injector (Remote View)" - desc = "Stare into the distance for a reason." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/remoteview/New() - block = REMOTEVIEWBLOCK - ..() - -/obj/item/dnainjector/antiremoteview - name = "\improper DNA injector (Anti-Remote View)" - desc = "Cures green skin." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antiremoteview/New() - block = REMOTEVIEWBLOCK - ..() - -/obj/item/dnainjector/regenerate - name = "\improper DNA injector (Regeneration)" - desc = "Healthy but hungry." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/regenerate/New() - block = REGENERATEBLOCK - ..() - -/obj/item/dnainjector/antiregenerate - name = "\improper DNA injector (Anti-Regeneration)" - desc = "Sickly but sated." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antiregenerate/New() - block = REGENERATEBLOCK - ..() - -/obj/item/dnainjector/runfast - name = "\improper DNA injector (Increase Run)" - desc = "Running Man." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/runfast/New() - block = INCREASERUNBLOCK - ..() - -/obj/item/dnainjector/antirunfast - name = "\improper DNA injector (Anti-Increase Run)" - desc = "Walking Man." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antirunfast/New() - block = INCREASERUNBLOCK - ..() - -/obj/item/dnainjector/morph - name = "\improper DNA injector (Morph)" - desc = "A total makeover." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/morph/New() - block = MORPHBLOCK - ..() - -/obj/item/dnainjector/antimorph - name = "\improper DNA injector (Anti-Morph)" - desc = "Cures identity crisis." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antimorph/New() - block = MORPHBLOCK - ..() - -/obj/item/dnainjector/noprints - name = "\improper DNA injector (No Prints)" - desc = "Better than a pair of budget insulated gloves." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/noprints/New() - block = NOPRINTSBLOCK - ..() - -/obj/item/dnainjector/antinoprints - name = "\improper DNA injector (Anti-No Prints)" - desc = "Not quite as good as a pair of budget insulated gloves." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antinoprints/New() - block = NOPRINTSBLOCK - ..() - -/obj/item/dnainjector/insulation - name = "\improper DNA injector (Shock Immunity)" - desc = "Better than a pair of real insulated gloves." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/insulation/New() - block = SHOCKIMMUNITYBLOCK - ..() - -/obj/item/dnainjector/antiinsulation - name = "\improper DNA injector (Anti-Shock Immunity)" - desc = "Not quite as good as a pair of real insulated gloves." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antiinsulation/New() - block = SHOCKIMMUNITYBLOCK - ..() - -/obj/item/dnainjector/midgit - name = "\improper DNA injector (Small Size)" - desc = "Makes you shrink." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/midgit/New() - block = SMALLSIZEBLOCK - ..() - -/obj/item/dnainjector/antimidgit - name = "\improper DNA injector (Anti-Small Size)" - desc = "Makes you grow. But not too much." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antimidgit/New() - block = SMALLSIZEBLOCK - ..() - -///////////////////////////////////// -/obj/item/dnainjector/antiglasses - name = "\improper DNA injector (Anti-Glasses)" - desc = "Toss away those glasses!" - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antiglasses/New() - block = GLASSESBLOCK - ..() - -/obj/item/dnainjector/glassesmut - name = "\improper DNA injector (Glasses)" - desc = "Will make you need dorkish glasses." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/glassesmut/New() - block = GLASSESBLOCK - ..() - -/obj/item/dnainjector/epimut - name = "\improper DNA injector (Epi.)" - desc = "Shake shake shake the room!" - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/epimut/New() - block = HEADACHEBLOCK - ..() - -/obj/item/dnainjector/antiepi - name = "\improper DNA injector (Anti-Epi.)" - desc = "Will fix you up from shaking the room." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antiepi/New() - block = HEADACHEBLOCK - ..() - -/obj/item/dnainjector/anticough - name = "\improper DNA injector (Anti-Cough)" - desc = "Will stop that awful noise." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/anticough/New() - block = COUGHBLOCK - ..() - -/obj/item/dnainjector/coughmut - name = "\improper DNA injector (Cough)" - desc = "Will bring forth a sound of horror from your throat." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/coughmut/New() - block = COUGHBLOCK - ..() - -/obj/item/dnainjector/clumsymut - name = "\improper DNA injector (Clumsy)" - desc = "Makes clumsy minions." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/clumsymut/New() - block = CLUMSYBLOCK - ..() - -/obj/item/dnainjector/anticlumsy - name = "\improper DNA injector (Anti-Clumy)" - desc = "Cleans up confusion." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/anticlumsy/New() - block = CLUMSYBLOCK - ..() - -/obj/item/dnainjector/antitour - name = "\improper DNA injector (Anti-Tour.)" - desc = "Will cure tourrets." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antitour/New() - block = TWITCHBLOCK - ..() - -/obj/item/dnainjector/tourmut - name = "\improper DNA injector (Tour.)" - desc = "Gives you a nasty case off tourrets." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/tourmut/New() - block = TWITCHBLOCK - ..() - -/obj/item/dnainjector/stuttmut - name = "\improper DNA injector (Stutt.)" - desc = "Makes you s-s-stuttterrr" - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/stuttmut/New() - block = NERVOUSBLOCK - ..() - -/obj/item/dnainjector/antistutt - name = "\improper DNA injector (Anti-Stutt.)" - desc = "Fixes that speaking impairment." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antistutt/New() - block = NERVOUSBLOCK - ..() - -/obj/item/dnainjector/blindmut - name = "\improper DNA injector (Blind)" - desc = "Makes you not see anything." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/blindmut/New() - block = BLINDBLOCK - ..() - -/obj/item/dnainjector/antiblind - name = "\improper DNA injector (Anti-Blind)" - desc = "ITS A MIRACLE!!!" - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antiblind/New() - block = BLINDBLOCK - ..() - -/obj/item/dnainjector/deafmut - name = "\improper DNA injector (Deaf)" - desc = "Sorry, what did you say?" - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/deafmut/New() - block = DEAFBLOCK - ..() - -/obj/item/dnainjector/antideaf - name = "\improper DNA injector (Anti-Deaf)" - desc = "Will make you hear once more." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antideaf/New() - block = DEAFBLOCK - ..() - -/obj/item/dnainjector/hallucination - name = "\improper DNA injector (Halluctination)" - desc = "What you see isn't always what you get." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/hallucination/New() - block = HALLUCINATIONBLOCK - ..() - -/obj/item/dnainjector/antihallucination - name = "\improper DNA injector (Anti-Hallucination)" - desc = "What you see is what you get." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/antihallucination/New() - block = HALLUCINATIONBLOCK - ..() - -/obj/item/dnainjector/h2m - name = "\improper DNA injector (Human > Monkey)" - desc = "Will make you a flea bag." - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/h2m/New() - block = MONKEYBLOCK - ..() - -/obj/item/dnainjector/m2h - name = "\improper DNA injector (Monkey > Human)" - desc = "Will make you...less hairy." - datatype = DNA2_BUF_SE - value = 0x001 - -/obj/item/dnainjector/m2h/New() - block = MONKEYBLOCK - ..() + +// Traitgenes Injectors are randomized now due to no hardcoded genes. Split into good or bad, and then versions that specify what they do on the label. +// Otherwise scroll down further for how to make unique injectors +/obj/item/dnainjector/proc/pick_block(var/datum/gene/trait/G, var/labeled, var/allow_disable, var/force_disable = FALSE) + if(G) + block = G.block + datatype = DNA2_BUF_SE + if(!force_disable) + value = 0xFFF + else + value = 0x000 + if(allow_disable) + value = pick(0x000,0xFFF) + if(labeled) + name = initial(name) + " - [value == 0x000 ? "Removes" : ""] [G.get_name()]" + +/obj/item/dnainjector/random + name = "\improper DNA injector" + desc = "This injects the person with DNA." + +// Purely rando +/obj/item/dnainjector/random/Initialize() + pick_block( pick(GLOB.dna_genes_good + GLOB.dna_genes_neutral + GLOB.dna_genes_bad), FALSE, TRUE) + . = ..() + +/obj/item/dnainjector/random_labeled/Initialize() + pick_block( pick(GLOB.dna_genes_good + GLOB.dna_genes_neutral + GLOB.dna_genes_bad), TRUE, TRUE) + . = ..() + +// Good/bad but also neutral genes mixed in, less OP selection of genes +/obj/item/dnainjector/random_good/Initialize() + pick_block( pick(GLOB.dna_genes_good + GLOB.dna_genes_neutral ), FALSE, TRUE) + . = ..() + +/obj/item/dnainjector/random_good_labeled/Initialize() + pick_block( pick(GLOB.dna_genes_good + GLOB.dna_genes_neutral ), TRUE, TRUE) + . = ..() + +/obj/item/dnainjector/random_bad/Initialize() + pick_block( pick(GLOB.dna_genes_bad + GLOB.dna_genes_neutral ), FALSE, TRUE) + . = ..() + +/obj/item/dnainjector/random_bad_labeled/Initialize() + pick_block( pick(GLOB.dna_genes_bad + GLOB.dna_genes_neutral ), TRUE, TRUE) + . = ..() + +// Purely good/bad genes, intended to be usually good rewards or punishments +/obj/item/dnainjector/random_verygood/Initialize() + pick_block( pick(GLOB.dna_genes_good), FALSE, FALSE) + . = ..() + +/obj/item/dnainjector/random_verygood_labeled/Initialize() + pick_block( pick(GLOB.dna_genes_good), TRUE, FALSE) + . = ..() + +/obj/item/dnainjector/random_verybad/Initialize() + pick_block( pick(GLOB.dna_genes_bad), FALSE, FALSE) + . = ..() + +/obj/item/dnainjector/random_verybad_labeled/Initialize() + pick_block( pick(GLOB.dna_genes_bad), TRUE, FALSE) + . = ..() + +// Random neutral traits +/obj/item/dnainjector/random_neutral/Initialize() + pick_block( pick(GLOB.dna_genes_neutral ), FALSE, TRUE) + . = ..() + +/obj/item/dnainjector/random_neutral_labeled/Initialize() + pick_block( pick(GLOB.dna_genes_neutral ), TRUE, TRUE) + . = ..() + +// If you want a unique injector, use a subtype of these +/obj/item/dnainjector/set_trait + var/trait_path + var/disabling = FALSE + +/obj/item/dnainjector/set_trait/Initialize() + var/G = get_gene_from_trait(trait_path) + if(trait_path && G) + pick_block( G, TRUE, FALSE, disabling) + else + qdel(src) + return + . = ..() + + disabling = TRUE + +// Injectors for all original genes and some new ones +/obj/item/dnainjector/set_trait/anxiety // stutter + trait_path = /datum/trait/negative/disability_anxiety +/obj/item/dnainjector/set_trait/anxiety/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/noprints // noprints + trait_path = /datum/trait/positive/superpower_noprints +/obj/item/dnainjector/set_trait/noprints/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/tourettes // tour + trait_path = /datum/trait/negative/disability_tourettes +/obj/item/dnainjector/set_trait/tourettes/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/cough // cough + trait_path = /datum/trait/negative/disability_cough +/obj/item/dnainjector/set_trait/cough/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/nearsighted // glasses + trait_path = /datum/trait/negative/disability_nearsighted +/obj/item/dnainjector/set_trait/nearsighted/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/heatadapt // fire + trait_path = /datum/trait/neutral/hotadapt +/obj/item/dnainjector/set_trait/heatadapt/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/epilepsy // epi + trait_path = /datum/trait/negative/disability_epilepsy +/obj/item/dnainjector/set_trait/epilepsy/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/morph // morph + trait_path = /datum/trait/positive/superpower_morph +/obj/item/dnainjector/set_trait/morph/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/regenerate // regenerate + trait_path = /datum/trait/positive/superpower_regenerate +/obj/item/dnainjector/set_trait/regenerate/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/clumsy // clumsy + trait_path = /datum/trait/negative/disability_clumsy +/obj/item/dnainjector/set_trait/clumsy/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/coldadapt // insulated + trait_path = /datum/trait/neutral/coldadapt +/obj/item/dnainjector/set_trait/coldadapt/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/xray // xraymut + trait_path = /datum/trait/positive/superpower_xray +/obj/item/dnainjector/set_trait/xray/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/deaf // deafmut + trait_path = /datum/trait/negative/disability_deaf +/obj/item/dnainjector/set_trait/deaf/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/tk // telemut + trait_path = /datum/trait/positive/superpower_tk +/obj/item/dnainjector/set_trait/tk/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/haste // runfast + trait_path = /datum/trait/positive/speed_fast +/obj/item/dnainjector/set_trait/haste/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/blind // blindmut + trait_path = /datum/trait/negative/blindness +/obj/item/dnainjector/set_trait/blind/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/nobreathe // nobreath + trait_path = /datum/trait/positive/superpower_nobreathe +/obj/item/dnainjector/set_trait/nobreathe/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/remoteview // remoteview + trait_path = /datum/trait/positive/superpower_remoteview +/obj/item/dnainjector/set_trait/remoteview/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/flashproof // flashproof + trait_path = /datum/trait/positive/superpower_flashproof +/obj/item/dnainjector/set_trait/flashproof/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/hulk // hulk + trait_path = /datum/trait/positive/superpower_hulk +/obj/item/dnainjector/set_trait/hulk/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/table_passer // midgit + trait_path = /datum/trait/positive/table_passer +/obj/item/dnainjector/set_trait/table_passer/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/remotetalk // remotetalk + trait_path = /datum/trait/positive/superpower_remotetalk +/obj/item/dnainjector/set_trait/remotetalk/disable + disabling = TRUE + +/obj/item/dnainjector/set_trait/nonconduct // shock + trait_path = /datum/trait/positive/nonconductive_plus +/obj/item/dnainjector/set_trait/nonconduct/disable + disabling = TRUE diff --git a/code/game/objects/items/weapons/gift_wrappaper_ch.dm b/code/game/objects/items/weapons/gift_wrappaper_ch.dm index b9c78d9aaa..a3d2373e02 100644 --- a/code/game/objects/items/weapons/gift_wrappaper_ch.dm +++ b/code/game/objects/items/weapons/gift_wrappaper_ch.dm @@ -98,12 +98,12 @@ /obj/item/grenade/spawnergrenade/casino/zorgoia, /obj/item/grenade/spawnergrenade/casino/gygax, /obj/item/lego, - /obj/item/dnainjector/nobreath, - /obj/item/dnainjector/regenerate, - /obj/item/dnainjector/remoteview, - /obj/item/dnainjector/runfast, - /obj/item/dnainjector/telemut, - /obj/item/dnainjector/xraymut, + /obj/item/dnainjector/set_trait/nobreathe, + /obj/item/dnainjector/set_trait/regenerate, + /obj/item/dnainjector/set_trait/remoteview, + /obj/item/dnainjector/set_trait/haste, + /obj/item/dnainjector/set_trait/tk, + /obj/item/dnainjector/set_trait/xray, /obj/item/instrument/accordion, /obj/item/instrument/banjo, /obj/item/instrument/bikehorn, @@ -164,7 +164,7 @@ var/gift_type_chaos = pick( /obj/item/grenade/spawnergrenade/casino/gygax/gorilla, - /obj/item/dnainjector/hulkmut, + /obj/item/dnainjector/set_trait/hulk, /obj/item/grenade/spawnergrenade/casino/infinitycake, /obj/item/grenade/spawnergrenade/casino/universal_technomancer, /obj/item/spellbook, @@ -186,4 +186,4 @@ I.add_fingerprint(M) qdel(src) - return \ No newline at end of file + return diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index ea5acddb63..e66059ae9c 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -150,9 +150,11 @@ name = "box of DNA injectors" desc = "This box contains injectors it seems." icon_state = "dna" + // Traitgenes New injector loot starts_with = list( - /obj/item/dnainjector/h2m = 3, - /obj/item/dnainjector/m2h = 3 + /obj/item/dnainjector/random_good_labeled = 2, + /obj/item/dnainjector/random_neutral_labeled = 2, + /obj/item/dnainjector/random_labeled = 2 ) /obj/item/storage/box/flashbangs @@ -225,8 +227,8 @@ /obj/item/storage/box/flare name = "box of flares" - desc = "A box containing 14 flares." // CHOMPedit: More flares. - starts_with = list(/obj/item/flashlight/flare = 14) // CHOMPedit: More flares. + desc = "A box containing 14 flares." + starts_with = list(/obj/item/flashlight/flare = 14) /obj/item/storage/box/trackimp name = "boxed tracking implant kit" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index 37c2986ac4..1b113c34b0 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -157,3 +157,46 @@ broken = 1 locked = 0 ..() + +/obj/structure/closet/secure_closet/mind + name = "mind secured locker" + var/datum/mind/owner + var/self_del = 1 + anchored = 0 + +/obj/structure/closet/secure_closet/mind/New(var/datum/mind/mind_target, var/del_self = 1) + .=..() + self_del = del_self + if(mind_target) + owner = mind_target + name = "Owned by [owner.name]" + if(owner.current) + var/icon/I = get_flat_icon(owner.current, dir=SOUTH, no_anim=TRUE) + var/image/IM = image(I, pixel_x = (32 - I.Width())) + //icon2base64(get_flat_icon(owner.current,dir=SOUTH,no_anim=TRUE)) + /* + I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE) + I.plane = MOB_PLANE + I.layer = MOB_LAYER + */ + add_overlay(IM) + qdel(I) + +/obj/structure/closet/secure_closet/mind/allowed(mob/user) + if(user.mind == owner) + return TRUE + else + return FALSE + +/obj/structure/closet/secure_closet/mind/open() + .=..() + if(self_del) + qdel(src) + +/obj/structure/closet/secure_closet/mind/LateInitialize() + if(ispath(closet_appearance)) + closet_appearance = GLOB.closet_appearances[closet_appearance] + if(istype(closet_appearance)) + icon = closet_appearance.icon + color = null + update_icon() diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 14cec7d5d3..7e727d5a72 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -141,15 +141,33 @@ var/global/floorIsLava = 0 body += "

" body += "DNA Blocks:
" var/bname - for(var/block=1;block<=DNA_SE_LENGTH;block++) + var/list/output_list = list() + // Traitgenes more reliable way to check gene states + for(var/setup_block=1;setup_block<=DNA_SE_LENGTH;setup_block++) + output_list["[setup_block]"] = null + for(var/datum/gene/gene in GLOB.dna_genes) // Traitgenes Genes accessible by global VV. Removed /dna/ from path + output_list["[gene.block]"] = gene + for(var/block=1;block<=DNA_SE_LENGTH;block++) // Traitgenes more reliable way to check gene states + var/datum/gene/gene = output_list["[block]"] // Traitgenes Removed /dna/ from path if(((block-1)%5)==0) body += "" - bname = assigned_blocks[block] + // Traitgenes more reliable way to check gene states + if(gene) + bname = gene.name + else + bname = "" body += "" @@ -627,7 +645,7 @@ var/global/floorIsLava = 0 if(!check_rights(R_SERVER,0)) message = sanitize(message, 500, extra = 0) message = replacetext(message, "\n", "
") // required since we're putting it in a

tag - send_ooc_announcement(message, "From [usr.client.holder.fakekey ? "Administrator" : usr.key]") // CHOMPEdit + send_ooc_announcement(message, "From [usr.client.holder.fakekey ? "Administrator" : usr.key]") log_admin("Announce: [key_name(usr)] : [message]") feedback_add_details("admin_verb","A") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -903,12 +921,6 @@ var/datum/announcement/minor/admin_min_announcer = new set desc="Whether persistent data will be saved from now on." set name="Toggle Persistent Data" CONFIG_SET(flag/persistence_disabled, !CONFIG_GET(flag/persistence_disabled)) - /* CHOMP Edit: the entire world doesn't need to know. - if(!CONFIG_GET(flag/persistence_disabled)) - to_world(span_world("Persistence is now enabled.")) - else - to_world(span_world("Persistence is no longer enabled.")) - */ message_admins(span_blue("[key_name_admin(usr)] toggled persistence to [CONFIG_GET(flag/persistence_disabled) ? "Off" : "On"]."), 1) log_admin("[key_name(usr)] toggled persistence to [CONFIG_GET(flag/persistence_disabled) ? "Off" : "On"].") world.update_status() diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 2a94edde18..77b933d70d 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -617,7 +617,7 @@ if(istype(M, /mob/living/carbon)) M.dna.SetSEState(block,!M.dna.GetSEState(block)) domutcheck(M,null,MUTCHK_FORCED) - M.update_mutations() + M.UpdateAppearance() var/state="[M.dna.GetSEState(block)?"on":"off"]" var/blockname=assigned_blocks[block] message_admins("[key_name_admin(src)] has toggled [M.key]'s [blockname] block [state]!") diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 615c7677fd..2dc8c6578e 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -9,8 +9,8 @@ return for(var/obj/item/W in M) - if(istype(W, /obj/item/implant/backup) || istype(W, /obj/item/nif)) //VOREStation Edit - There's basically no reason to remove either of these - continue //VOREStation Edit + if(istype(W, /obj/item/implant/backup) || istype(W, /obj/item/nif)) //There's basically no reason to remove either of these + continue M.drop_from_inventory(W) log_admin("[key_name(usr)] made [key_name(M)] drop everything!") @@ -432,8 +432,8 @@ Traitors and the like can also be revived with the previous role mostly intact. return if(samejob == "Yes") charjob = record_found.fields["real_rank"] - else if(samejob == JOB_ALT_VISITOR) //VOREStation Edit - Visitor not Assistant - charjob = JOB_ALT_VISITOR //VOREStation Edit - Visitor not Assistant + else if(samejob == JOB_ALT_VISITOR) + charjob = JOB_ALT_VISITOR else records = tgui_alert(src,"No data core entry detected. Would you like add them to the manifest, and sec/med/HR records?","Records",list("No", "Yes", "Cancel")) if(!records || records == "Cancel") @@ -465,10 +465,8 @@ Traitors and the like can also be revived with the previous role mostly intact. //For logging later var/admin = key_name_admin(src) var/player_key = picked_client.key - //VOREStation Add - Needed for persistence var/picked_ckey = picked_client.ckey var/picked_slot = picked_client.prefs.default_slot - //VOREStation Add End var/mob/living/carbon/human/new_character var/spawnloc @@ -517,7 +515,9 @@ Traitors and the like can also be revived with the previous role mostly intact. picked_client.prefs.copy_to(new_character) if(new_character.dna) new_character.dna.ResetUIFrom(new_character) + new_character.sync_dna_traits(TRUE) // Traitgenes Sync traits to genetics if needed new_character.sync_organ_dna() + new_character.initialize_vessel() if(inhabit) new_character.key = player_key //Were they any particular special role? If so, copy. @@ -527,11 +527,9 @@ Traitors and the like can also be revived with the previous role mostly intact. antag_data.add_antagonist(new_character.mind) antag_data.place_mob(new_character) - //VOREStation Add - Required for persistence if(new_character.mind) new_character.mind.loaded_from_ckey = picked_ckey new_character.mind.loaded_from_slot = picked_slot - //VOREStation Add End for(var/lang in picked_client.prefs.alternate_languages) var/datum/language/chosen_language = GLOB.all_languages[lang] @@ -555,7 +553,7 @@ Traitors and the like can also be revived with the previous role mostly intact. //A redraw for good measure new_character.regenerate_icons() - new_character.update_transform() //VOREStation Edit + new_character.update_transform() //If we're announcing their arrival if(announce) @@ -700,7 +698,7 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Fun.Do Not" set name = "Explosion" - if(!check_rights(R_DEBUG|R_FUN)) return //VOREStation Edit + if(!check_rights(R_DEBUG|R_FUN)) return var/devastation = tgui_input_number(usr, "Range of total devastation. -1 to none", text("Input"), min_value=-1) if(devastation == null) return @@ -728,7 +726,7 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Fun.Do Not" set name = "EM Pulse" - if(!check_rights(R_DEBUG|R_FUN)) return //VOREStation Edit + if(!check_rights(R_DEBUG|R_FUN)) return var/heavy = tgui_input_number(usr, "Range of heavy pulse.", text("Input")) if(heavy == null) return @@ -754,7 +752,7 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Fun.Do Not" set name = "Gib" - if(!check_rights(R_ADMIN|R_FUN)) return //VOREStation Edit + if(!check_rights(R_ADMIN|R_FUN)) return var/confirm = tgui_alert(src, "You sure?", "Confirm", list("Yes", "No")) if(confirm != "Yes") return @@ -855,7 +853,7 @@ Traitors and the like can also be revived with the previous role mostly intact. /client/proc/cmd_admin_check_contents(mob/living/M as mob in mob_list) set category = "Admin.Investigate" set name = "Check Contents" - set popup_menu = FALSE //VOREStation Edit - Declutter. + set popup_menu = FALSE if(!holder) return @@ -912,7 +910,7 @@ Traitors and the like can also be revived with the previous role mostly intact. mob.set_viewsize(view) log_admin("[key_name(usr)] changed their view range to [view].") - message_admins("[key_name_admin(usr)] changed their view range to [view].", 1) //CHOMPEdit - Uncommented this. + message_admins("[key_name_admin(usr)] changed their view range to [view].", 1) feedback_add_details("admin_verb","CVRA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -923,7 +921,7 @@ Traitors and the like can also be revived with the previous role mostly intact. if ((!( ticker ) || !emergency_shuttle.location())) return - if(!check_rights(R_ADMIN)) return //VOREStation Edit + if(!check_rights(R_ADMIN)) return var/confirm = tgui_alert(src, "You sure?", "Confirm", list("Yes", "No")) if(confirm != "Yes") return @@ -952,7 +950,7 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Admin.Events" set name = "Cancel Shuttle" - if(!check_rights(R_ADMIN|R_FUN)) return // CHOMPstation edit: Lets anyone cancel the shuttle. + if(!check_rights(R_ADMIN|R_FUN)) return if(tgui_alert(src, "You sure?", "Confirm", list("Yes", "No")) != "Yes") return @@ -973,7 +971,7 @@ Traitors and the like can also be revived with the previous role mostly intact. if (!ticker) return - if(!check_rights(R_ADMIN)) return //VOREStation Edit + if(!check_rights(R_ADMIN)) return emergency_shuttle.deny_shuttle = !emergency_shuttle.deny_shuttle @@ -1029,7 +1027,7 @@ Traitors and the like can also be revived with the previous role mostly intact. set name = "Toggle random events on/off" set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off" - if(!check_rights(R_SERVER)) return //VOREStation Edit + if(!check_rights(R_SERVER)) return if(!CONFIG_GET(flag/allow_random_events)) CONFIG_SET(flag/allow_random_events, TRUE) diff --git a/code/modules/casino/casino_prize_vendor.dm b/code/modules/casino/casino_prize_vendor.dm index 21bb2de1af..fa5a489ed1 100644 --- a/code/modules/casino/casino_prize_vendor.dm +++ b/code/modules/casino/casino_prize_vendor.dm @@ -221,12 +221,12 @@ CASINO_PRIZE("Implant: Restraining bolt", /obj/item/implantcase/restrainingbolt, 1, 1000, "implants"), CASINO_PRIZE("Implant: Surge", /obj/item/implantcase/surge, 1, 500, "implants"), CASINO_PRIZE("Implant: Wrist sword", /obj/item/implantcase/sword, 1, 1000, "implants"), - CASINO_PRIZE("Genemod: No breath", /obj/item/dnainjector/nobreath, 1, 1000, "implants"), - CASINO_PRIZE("Genemod: Regenerate", /obj/item/dnainjector/regenerate, 1, 1000, "implants"), - CASINO_PRIZE("Genemod: Remote view", /obj/item/dnainjector/remoteview, 1, 1000, "implants"), - CASINO_PRIZE("Genemod: Sprinter", /obj/item/dnainjector/runfast, 1, 1000, "implants"), - CASINO_PRIZE("Genemod: Telekinesis", /obj/item/dnainjector/telemut, 1, 1000, "implants"), - CASINO_PRIZE("Genemod: X-ray", /obj/item/dnainjector/xraymut, 1, 1000, "implants"), + CASINO_PRIZE("Genemod: No breath", /obj/item/dnainjector/set_trait/nobreathe, 1, 1000, "implants"), + CASINO_PRIZE("Genemod: Regenerate", /obj/item/dnainjector/set_trait/regenerate, 1, 1000, "implants"), + CASINO_PRIZE("Genemod: Remote view", /obj/item/dnainjector/set_trait/remoteview, 1, 1000, "implants"), + CASINO_PRIZE("Genemod: Sprinter", /obj/item/dnainjector/set_trait/haste, 1, 1000, "implants"), + CASINO_PRIZE("Genemod: Telekinesis", /obj/item/dnainjector/set_trait/tk, 1, 1000, "implants"), + CASINO_PRIZE("Genemod: X-ray", /obj/item/dnainjector/set_trait/xray, 1, 1000, "implants"), ) item_list["Event"] = list( diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index deb4c31150..af656eef26 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -56,9 +56,11 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O var/datum/sprite_accessory/instance = style_list[path] if(!istype(instance)) continue + if(instance.name == DEVELOPER_WARNING_NAME) + continue if(instance.ckeys_allowed && (!client || !(client.ckey in instance.ckeys_allowed))) continue - if(instance.species_allowed && (!species || !(species in instance.species_allowed)) && (!client || !check_rights(R_ADMIN | R_EVENT | R_FUN, 0, client)) && (!custom_base || !(custom_base in instance.species_allowed))) //VOREStation Edit: Custom Species + if(instance.species_allowed && (!species || !(species in instance.species_allowed)) && (!client || !check_rights(R_ADMIN | R_EVENT | R_FUN, 0, client)) && (!custom_base || !(custom_base in instance.species_allowed))) continue .[instance.name] = instance @@ -83,7 +85,6 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.f_style = save_data["facial_style_name"] pref.grad_style = save_data["grad_style_name"] pref.b_type = save_data["b_type"] - pref.disabilities = save_data["disabilities"] pref.organ_data = check_list_copy(save_data["organ_data"]) pref.rlimb_data = check_list_copy(save_data["rlimb_data"]) pref.body_markings = check_list_copy(save_data["body_markings"]) @@ -95,13 +96,6 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.synth_markings = save_data["synth_markings"] pref.bgstate = save_data["bgstate"] pref.body_descriptors = check_list_copy(save_data["body_descriptors"]) - //YWadd start - pref.wingdings = save_data["Wingdings"] - pref.colorblind_mono = save_data["colorblind_mono"] - pref.colorblind_vulp = save_data["colorblind_vulp"] - pref.colorblind_taj = save_data["colorblind_taj"] - pref.haemophilia = save_data["haemophilia"] - //YWadd end pref.ear_style = save_data["ear_style"] pref.ear_secondary_style = save_data["ear_secondary_style"] pref.ear_secondary_colors = save_data["ear_secondary_colors"] @@ -116,7 +110,6 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O save_data["facial_style_name"] = pref.f_style save_data["grad_style_name"] = pref.grad_style save_data["b_type"] = pref.b_type - save_data["disabilities"] = pref.disabilities save_data["organ_data"] = check_list_copy(pref.organ_data) save_data["rlimb_data"] = check_list_copy(pref.rlimb_data) var/list/body_markings = check_list_copy(pref.body_markings) @@ -129,13 +122,6 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O save_data["synth_markings"] = pref.synth_markings save_data["bgstate"] = pref.bgstate save_data["body_descriptors"] = check_list_copy(pref.body_descriptors) - //YWadd start - save_data["Wingdings"] = pref.wingdings - save_data["colorblind_mono"] = pref.colorblind_mono - save_data["colorblind_vulp"] = pref.colorblind_vulp - save_data["colorblind_taj"] = pref.colorblind_taj - save_data["haemophilia"] = pref.haemophilia - //YWadd end save_data["ear_style"] = pref.ear_style save_data["ear_secondary_style"] = pref.ear_secondary_style save_data["ear_secondary_colors"] = pref.ear_secondary_colors @@ -153,12 +139,11 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.grad_style = sanitize_inlist(pref.grad_style, GLOB.hair_gradients, initial(pref.grad_style)) pref.b_type = sanitize_text(pref.b_type, initial(pref.b_type)) - pref.disabilities = sanitize_integer(pref.disabilities, 0, 65535, initial(pref.disabilities)) if(!pref.organ_data) pref.organ_data = list() if(!pref.rlimb_data) pref.rlimb_data = list() if(!pref.body_markings) pref.body_markings = list() else pref.body_markings &= body_marking_styles_list - for (var/M in pref.body_markings) //VOREStation Edit + for (var/M in pref.body_markings) if (!islist(pref.body_markings[M])) var/col = istext(pref.body_markings[M]) ? pref.body_markings[M] : "#000000" pref.body_markings[M] = pref.mass_edit_marking_list(M,color=col) @@ -214,24 +199,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O character.set_gender(pref.biological_gender) - if(pref.species == "Grey")//YWadd START - character.wingdings = pref.wingdings - - if(pref.colorblind_mono == 1) - character.add_modifier(/datum/modifier/trait/colorblind_monochrome) - - else if(pref.colorblind_vulp == 1) - character.add_modifier(/datum/modifier/trait/colorblind_vulp) - - else if(pref.colorblind_taj == 1) - character.add_modifier(/datum/modifier/trait/colorblind_taj) - - if(pref.haemophilia == 1) - character.add_modifier(/datum/modifier/trait/haemophilia) - //YWadd END - // Destroy/cyborgize organs and limbs. - //VOREStation Edit character.synthetic = pref.species == "Protean" ? all_robolimbs["protean"] : null //Clear the existing var. (unless protean, then switch it to the normal protean limb) var/list/organs_to_edit = list() for (var/name in list(BP_TORSO, BP_HEAD, BP_GROIN, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT)) @@ -242,7 +210,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O organs_to_edit += name else organs_to_edit.Insert(x+(O.robotic == ORGAN_NANOFORM ? 1 : 0), name) - for(var/name in organs_to_edit) //VOREStation edit end + for(var/name in organs_to_edit) var/status = pref.organ_data[name] var/obj/item/organ/external/O = character.organs_by_name[name] if(O) @@ -279,7 +247,6 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O for(var/M in pref.body_markings) priority += 1 var/datum/sprite_accessory/marking/mark_datum = body_marking_styles_list[M] - //var/mark_color = "[pref.body_markings[M]]" //VOREStation Edit for(var/BP in mark_datum.body_parts) var/obj/item/organ/external/O = character.organs_by_name[BP] @@ -307,14 +274,12 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O var/datum/species/mob_species = GLOB.all_species[pref.species] . += "

 12345
[block-1]" if(bname) - var/bstate=M.dna.GetSEState(block) + var/bstate=(bname in M.active_genes) // Traitgenes more reliable way to check gene states + // Traitgenes show trait linked names on mouseover + var/tname = bname + if(istype(gene,/datum/gene/trait)) + var/datum/gene/trait/T = gene + tname = T.get_name() var/bcolor="[(bstate)?"#006600":"#ff0000"]" - body += "[bname][block]" + if(!bstate && M.dna.GetSEState(block)) // Gene isn't active, but the dna says it is... Was blocked by another gene! + bcolor="#d88d00" + body += "[bname][block]" // Traitgenes edit - show trait linked names on mouseover else body += "[block]" body+="
Body " - . += "(®)" + . += "(®)" . += "
" . += "Species: [pref.species]
" . += "Blood Type: [pref.b_type]
" if(has_flag(mob_species, HAS_SKIN_TONE)) . += "Skin Tone: [-pref.s_tone + 35]/220
" - . += "Disabilities
Adjust
" // YWadd - //YWcommented moved onto disabilities. += "Needs Glasses: [pref.disabilities & NEARSIGHTED ? "Yes" : "No"]
" . += "Limbs: Adjust Reset
" . += "Internal Organs: Adjust
" //display limbs below @@ -565,9 +530,6 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.alternate_languages.Cut() // Reset their alternate languages. Todo: attempt to just fix it instead? return TOPIC_HANDLED - else if(href_list["disabilities_yw"]) - Disabilities_YW(user) //ChompEDIT - usr removal - else if(href_list["set_species"]) user << browse(null, "window=species") if(!pref.species_preview || !(pref.species_preview in GLOB.all_species)) @@ -580,7 +542,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O else return TOPIC_NOACTION - if(((!(setting_species.spawn_flags & SPECIES_CAN_JOIN)) || (!is_alien_whitelisted(preference_mob(),setting_species))) && !check_rights(R_ADMIN|R_EVENT, 0) && !(setting_species.spawn_flags & SPECIES_WHITELIST_SELECTABLE)) //VOREStation Edit: selectability + if(((!(setting_species.spawn_flags & SPECIES_CAN_JOIN)) || (!is_alien_whitelisted(preference_mob(),setting_species))) && !check_rights(R_ADMIN|R_EVENT, 0) && !(setting_species.spawn_flags & SPECIES_WHITELIST_SELECTABLE)) return TOPIC_NOACTION var/prev_species = pref.species @@ -588,7 +550,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O if(prev_species != pref.species) if(!(pref.biological_gender in mob_species.genders)) pref.set_biological_gender(mob_species.genders[1]) - pref.custom_species = null //VOREStation Edit - This is cleared on species changes + pref.custom_species = null //grab one of the valid hair styles for the newly chosen species var/list/valid_hairstyles = pref.get_valid_hairstyles(user) @@ -621,7 +583,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O var/min_age = get_min_age() var/max_age = get_max_age() pref.update_preference_by_type(/datum/preference/numeric/human/age, max(min(pref.read_preference(/datum/preference/numeric/human/age), max_age), min_age)) - pref.blood_color = setting_species.blood_color // VOREstation edit + pref.blood_color = setting_species.blood_color return TOPIC_REFRESH_UPDATE_PREVIEW @@ -756,15 +718,6 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O else if(href_list["marking_style"]) var/list/usable_markings = pref.body_markings.Copy() ^ body_marking_styles_list.Copy() - /* VOREStation Removal - No markings whitelist, let people mix/match - for(var/M in usable_markings) - var/datum/sprite_accessory/S = usable_markings[M] - var/datum/species/spec = GLOB.all_species[pref.species] - if(!S.species_allowed.len) - continue - else if(!(pref.species in S.species_allowed) && !(pref.custom_base in S.species_allowed) && !(spec.base_species in S.species_allowed)) - usable_markings -= M - */ //VOREStation Removal End var/new_marking = tgui_input_list(user, "Choose a body marking:", "Character Preference", usable_markings) if(new_marking && CanUseTopic(user)) pref.body_markings[new_marking] = pref.mass_edit_marking_list(new_marking) //New markings start black @@ -962,10 +915,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O continue if(tmp_species in M.species_cannot_use) continue - //VOREStation Add - Cyberlimb whitelisting. if(M.whitelisted_to && !(user.ckey in M.whitelisted_to)) continue - //VOREStation Add End usable_manufacturers[company] = M if(!usable_manufacturers.len) return @@ -1062,11 +1013,6 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O return TOPIC_REFRESH - else if(href_list["disabilities"]) - var/disability_flag = text2num(href_list["disabilities"]) - pref.disabilities ^= disability_flag - Disabilities_YW(user) //YW Edit //ChompEDIT - usr removal - else if(href_list["toggle_preview_value"]) pref.equip_preview_mob ^= text2num(href_list["toggle_preview_value"]) return TOPIC_REFRESH_UPDATE_PREVIEW @@ -1093,38 +1039,6 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.bgstate = next_in_list(pref.bgstate, pref.bgstate_options) return TOPIC_REFRESH_UPDATE_PREVIEW - //YW Add Start - - else if(href_list["wingdings"]) - pref.wingdings = !pref.wingdings - Disabilities_YW(user) //ChompEDIT - usr removal - - else if(href_list["colorblind_mono"]) - pref.colorblind_mono = !pref.colorblind_mono - Disabilities_YW(user) //ChompEDIT - usr removal - - else if(href_list["colorblind_vulp"]) - pref.colorblind_vulp = !pref.colorblind_vulp - Disabilities_YW(user) //ChompEDIT - usr removal - - else if(href_list["colorblind_taj"]) - pref.colorblind_taj = !pref.colorblind_taj - Disabilities_YW(user) //ChompEDIT - usr removal - - else if(href_list["haemophilia"]) - pref.haemophilia = !pref.haemophilia - Disabilities_YW(user) //ChompEDIT - usr removal - - else if(href_list["reset_disabilities"]) - pref.wingdings = 0 - pref.colorblind_mono = 0 - pref.colorblind_taj = 0 - pref.colorblind_vulp = 0 - pref.haemophilia = 0 - Disabilities_YW(user) //ChompEDIT - usr removal - - //YW Add End - else if(href_list["ear_style"]) var/new_ear_style = tgui_input_list(user, "Select an ear style for this character:", "Character Preference", pref.get_available_styles(global.ear_styles_list), pref.ear_style) if(new_ear_style) @@ -1260,12 +1174,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O dat += "

[current_species.name] \[change\]


" dat += "" dat += "" - //vorestation edit begin if(current_species.wikilink) dat += "" else dat += "" - //vorestation edit end dat += "
[current_species.blurb]

See the wiki for more details.
[current_species.blurb]" if("preview" in cached_icon_states(current_species.icobase)) user << browse_rsc(icon(current_species.icobase,"preview"), "species_preview_[current_species.name].png") @@ -1322,7 +1234,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O dat += "You cannot play as this species.
If you wish to be whitelisted, you can make an application post on the forums.

" else if(restricted == 2) dat += "You cannot play as this species.
This species is not available for play as a station race..

" - if(!restricted || check_rights(R_ADMIN|R_EVENT, 0) || current_species.spawn_flags & SPECIES_WHITELIST_SELECTABLE) //VOREStation Edit: selectability + if(!restricted || check_rights(R_ADMIN|R_EVENT, 0) || current_species.spawn_flags & SPECIES_WHITELIST_SELECTABLE) dat += "\[select\]" dat += "" diff --git a/code/modules/client/preference_setup/loadout/loadout_fluffitems.dm b/code/modules/client/preference_setup/loadout/loadout_fluffitems.dm index 5b260dcce6..beb77eeb02 100644 --- a/code/modules/client/preference_setup/loadout/loadout_fluffitems.dm +++ b/code/modules/client/preference_setup/loadout/loadout_fluffitems.dm @@ -284,7 +284,7 @@ character_name = list("Cappy Fuzzlyfeathers") /datum/gear/fluff/james_disk - path = /obj/item/disk/data + path = /obj/item/disk/body_record display_name = "James' Disk" ckeywhitelist = list("cockatricexl") character_name = list("James Holder") diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 555e4dbb8c..5051e43913 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -26,7 +26,7 @@ var/list/preferences_datums = list() var/headset = 1 //headset type var/backbag = 2 //backpack type var/pdachoice = 1 //PDA type - //var/shoe_hater = FALSE //RS ADD - if true, will spawn with no shoes //CHOMPRemove, remove RS No shoes + //var/shoe_hater = FALSE //If true, will spawn with no shoes //CHOMPRemove, remove RS No shoes var/no_jacket = FALSE //if true, will not spawn with outfit's jacket/outer layer var/h_style = "Bald" //Hair type var/grad_style = "none" //Gradient style @@ -42,7 +42,7 @@ var/list/preferences_datums = list() var/gear_slot = 1 //The current gear save slot var/list/traits //Traits which modifier characters for better or worse (mostly worse). var/synth_color = 0 //Lets normally uncolorable synth parts be colorable. - var/synth_markings = 1 //Enable/disable markings on synth parts. //VOREStation Edit - 1 by default + var/synth_markings = 1 //Enable/disable markings on synth parts. var/digitigrade = 0 //Some faction information. @@ -104,7 +104,6 @@ var/list/preferences_datums = list() var/sec_record = "" var/gen_record = "" var/exploit_record = "" - var/disabilities = 0 var/economic_status = "Average" @@ -290,12 +289,13 @@ var/list/preferences_datums = list() return 1 if(href_list["save"]) - save_character() + if(save_character()) + to_chat(usr,span_notice("Character [player_setup?.preferences?.real_name] saved!")) save_preferences() else if(href_list["reload"]) load_preferences() load_character() - attempt_vr(client.prefs_vr,"load_vore","") //VOREStation Edit + attempt_vr(client.prefs_vr,"load_vore","") sanitize_preferences() else if(href_list["load"]) if(!IsGuestKey(usr.key)) @@ -343,7 +343,7 @@ var/list/preferences_datums = list() preference.apply_pref_to(character, read_preference(preference.type)) - // VOREStation Edit - Sync up all their organs and species one final time + // Sync up all their organs and species one final time character.force_update_organs() if(icon_updates) @@ -394,7 +394,7 @@ var/list/preferences_datums = list() load_preferences() load_character(slotnum) - attempt_vr(user.client?.prefs_vr,"load_vore","") //VOREStation Edit + attempt_vr(user.client?.prefs_vr,"load_vore","") sanitize_preferences() save_preferences() ShowChoices(user) diff --git a/code/modules/client/preferences_yw.dm b/code/modules/client/preferences_yw.dm deleted file mode 100644 index ad725621ef..0000000000 --- a/code/modules/client/preferences_yw.dm +++ /dev/null @@ -1,29 +0,0 @@ -/datum/preferences - var/wingdings = 1 - var/colorblind_mono = 0 - var/colorblind_vulp = 0 - var/colorblind_taj = 0 - var/haemophilia = 1 - -//proc for setting disabilities -/datum/category_item/player_setup_item/general/body/proc/Disabilities_YW(mob/user) - var/dat = "" - dat += "
" - - if(pref.species == "Grey") - dat += "Speak Wingdings: [pref.wingdings ? "Yes" : "No"]
" - dat += "Needs Glasses: [pref.disabilities & NEARSIGHTED ? "Yes" : "No"]
" - if(pref.colorblind_vulp == 0 && pref.colorblind_taj == 0) - dat += "Colorblind - Monochromacy): [pref.colorblind_mono ? "Yes" : "No"]
" - if(pref.colorblind_mono == 0 && pref.colorblind_taj == 0) - dat += "Colorblind - Green-Red): [pref.colorblind_vulp ? "Yes" : "No"]
" - if(pref.colorblind_mono == 0 && pref.colorblind_vulp == 0) - dat += "Colorblind - Blue-Red): [pref.colorblind_taj ? "Yes" : "No"]
" - dat += "Haemophilia: [pref.haemophilia ? "Yes" : "No"]
" - - dat += "Reset
" - - dat += "
" - var/datum/browser/popup = new(user, "disabil", "
Choose Disabilities
", 350, 380, src) - popup.set_content(dat) - popup.open() diff --git a/code/modules/emotes/emote_define.dm b/code/modules/emotes/emote_define.dm index 7bfeafbe02..29864e3fac 100644 --- a/code/modules/emotes/emote_define.dm +++ b/code/modules/emotes/emote_define.dm @@ -84,6 +84,8 @@ var/global/list/emotes_by_key /decl/emote/proc/do_emote(var/atom/user, var/extra_params) if(ismob(user) && check_restraints) var/mob/M = user + if(M.transforming) //Transforming acts as a stasis. + return if(M.restrained()) to_chat(user, span_warning("You are restrained and cannot do that.")) return diff --git a/code/modules/eventkit/generic_objects/generic_item.dm b/code/modules/eventkit/generic_objects/generic_item.dm index d1b89fb81a..943de2bc40 100644 --- a/code/modules/eventkit/generic_objects/generic_item.dm +++ b/code/modules/eventkit/generic_objects/generic_item.dm @@ -50,11 +50,11 @@ var/flash_time = 10 if(ishuman(O)) var/mob/living/carbon/human/H = O - //VOREStation Edit Start if(H.nif && H.nif.flag_check(NIF_V_FLASHPROT,NIF_FLAGS_VISION)) H.nif.notify("High intensity light detected, and blocked!",TRUE) continue - //VOREStation Edit End + if(FLASHPROOF in H.mutations) + continue if(!H.eyecheck() <= 0) continue flash_time *= H.species.flash_mod diff --git a/code/modules/eventkit/generic_objects/generic_structure.dm b/code/modules/eventkit/generic_objects/generic_structure.dm index 36d3b4cb26..0878fef63a 100644 --- a/code/modules/eventkit/generic_objects/generic_structure.dm +++ b/code/modules/eventkit/generic_objects/generic_structure.dm @@ -55,11 +55,11 @@ var/flash_time = 10 if(ishuman(O)) var/mob/living/carbon/human/H = O - //VOREStation Edit Start if(H.nif && H.nif.flag_check(NIF_V_FLASHPROT,NIF_FLAGS_VISION)) H.nif.notify("High intensity light detected, and blocked!",TRUE) continue - //VOREStation Edit End + if(FLASHPROOF in H.mutations) + continue if(!H.eyecheck() <= 0) continue flash_time *= H.species.flash_mod diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index cb8f33f66b..587177ae42 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -60,6 +60,7 @@ else randmutg(H) // Applies good mutation domutcheck(H,null,MUTCHK_FORCED) + H.UpdateAppearance() /datum/event/radiation_storm/end() revoke_maint_all_access() diff --git a/code/modules/genetics/side_effects.dm b/code/modules/genetics/side_effects.dm index 6ee490cd56..286b96927c 100644 --- a/code/modules/genetics/side_effects.dm +++ b/code/modules/genetics/side_effects.dm @@ -1,81 +1,78 @@ /datum/genetics/side_effect - var/name // name of the side effect, to use as a header in the manual - var/symptom // description of the symptom of the side effect - var/treatment // description of the treatment of the side effect - var/effect // description of what happens when not treated - var/duration = 0 // delay between start() and finish() + var/name // name of the side effect, to use as a header in the manual + var/duration = 0 // delay between start() and finish() + var/antidote_reagent // What type of reagent we require to stop the specific side effect from happening + +/proc/trigger_side_effect(mob/living/carbon/human/H) + if(!ishuman(H)) return + var/tp = pick(subtypesof(/datum/genetics/side_effect)) + var/datum/genetics/side_effect/S = new tp + + S.start(H) + addtimer(CALLBACK(H, TYPE_PROC_REF(/mob/living/carbon/human, Weaken), 4), 2 SECONDS, TIMER_DELETE_ME) + addtimer(CALLBACK(S, TYPE_PROC_REF(/datum/genetics/side_effect, finish), WEAKREF(H)), S.duration, TIMER_DELETE_ME) + //above is doing: Call S.finish(H) in S.duration /datum/genetics/side_effect/proc/start(mob/living/carbon/human/H) + if(H && ishuman(H)) + H.genetic_side_effects += src // start the side effect, this should give some cue as to what's happening, // such as gasping. These cues need to be unique among side-effects. -/datum/genetics/side_effect/proc/finish(mob/living/carbon/human/H) +/datum/genetics/side_effect/proc/finish(var/datum/weakref/WR) + var/mob/living/carbon/human/H = WR.resolve() + if(!H || !ishuman(H)) return FALSE + H.genetic_side_effects -= src + if(antidote_reagent && (H.reagents.has_reagent(antidote_reagent)|| H.ingested.has_reagent(antidote_reagent) || H.touching.has_reagent(antidote_reagent))) + return TRUE + return FALSE // Finish the side-effect. This should first check whether the cure has been // applied, and if not, cause bad things to happen. /datum/genetics/side_effect/genetic_burn name = "Genetic Burn" - symptom = "Subject's skin turns unusualy red." - treatment = "Inject small dose of dexalin." - effect = "Subject's skin burns." duration = 30 SECONDS + antidote_reagent = REAGENT_ID_DEXALIN /datum/genetics/side_effect/genetic_burn/start(mob/living/carbon/human/H) + ..() H.custom_emote(VISIBLE_MESSAGE, "starts turning very red..") -/datum/genetics/side_effect/genetic_burn/finish(mob/living/carbon/human/H) - if(H.reagents.has_reagent(REAGENT_ID_DEXALIN)) - return +/datum/genetics/side_effect/genetic_burn/finish(datum/weakref/WR) + if(..()) return + var/mob/living/carbon/human/H = WR.resolve() for(var/organ_name in BP_ALL) var/obj/item/organ/external/E = H.get_organ(organ_name) E.take_damage(0, 5, 0) /datum/genetics/side_effect/bone_snap - name = "Bone Snap" - symptom = "Subject's limbs tremble notably." - treatment = "Inject small dose of bicaridine." - effect = "Subject's bone breaks." + name = "Genetic Bone Snap" duration = 60 SECONDS + antidote_reagent = REAGENT_ID_BICARIDINE /datum/genetics/side_effect/bone_snap/start(mob/living/carbon/human/H) + ..() H.custom_emote(VISIBLE_MESSAGE, "'s limbs start shivering uncontrollably.") -/datum/genetics/side_effect/bone_snap/finish(mob/living/carbon/human/H) - if(H.reagents.has_reagent(REAGENT_ID_BICARIDINE)) - return +/datum/genetics/side_effect/bone_snap/finish(datum/weakref/WR) + if(..()) return + var/mob/living/carbon/human/H = WR.resolve() var/organ_name = pick(BP_ALL) var/obj/item/organ/external/E = H.get_organ(organ_name) E.take_damage(20, 0, 0) E.fracture() /datum/genetics/side_effect/confuse - name = "Confuse" - symptom = "Subject starts drooling uncontrollably." - treatment = "Inject small dose of dylovene." - effect = "Subject becomes confused." + name = "Genetic Confusion" duration = 30 SECONDS + antidote_reagent = REAGENT_ID_ANTITOXIN /datum/genetics/side_effect/confuse/start(mob/living/carbon/human/H) + ..() var/datum/gender/T = gender_datums[H.get_visible_gender()] H.custom_emote(VISIBLE_MESSAGE, "has drool running down from [T.his] mouth.") -/datum/genetics/side_effect/confuse/finish(mob/living/carbon/human/H) - if(H.reagents.has_reagent(REAGENT_ID_ANTITOXIN)) - return +/datum/genetics/side_effect/confuse/finish(datum/weakref/WR) + if(..()) return + var/mob/living/carbon/human/H = WR.resolve() H.Confuse(100) - -/proc/trigger_side_effect(mob/living/carbon/human/H) - spawn - if(!istype(H)) return - var/tp = pick(subtypesof(/datum/genetics/side_effect)) - var/datum/genetics/side_effect/S = new tp - - S.start(H) - spawn(20) - if(!istype(H)) return - H.Weaken(rand(0, S.duration / 50)) - sleep(S.duration) - - if(!istype(H)) return - H.SetWeakened(0) - S.finish(H) diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm index db8690e66f..8713dc8a7a 100644 --- a/code/modules/mining/abandonedcrates.dm +++ b/code/modules/mining/abandonedcrates.dm @@ -112,7 +112,7 @@ if(92) new/obj/item/material/sword/katana(src) if(93) - new/obj/item/dnainjector/xraymut(src) // Probably the least OP + new/obj/item/dnainjector/set_trait/xray(src) // Probably the least OP if(94) // Why the hell not new/obj/item/storage/backpack/clown(src) new/obj/item/clothing/under/rank/clown(src) diff --git a/code/modules/mining/abandonedcrates_vr.dm b/code/modules/mining/abandonedcrates_vr.dm index fde862ed75..3e8946e643 100644 --- a/code/modules/mining/abandonedcrates_vr.dm +++ b/code/modules/mining/abandonedcrates_vr.dm @@ -59,7 +59,8 @@ list(/obj/item/storage/belt/utility/chief/full, 8) = 2, list(/obj/item/personal_shield_generator/belt/mining/loaded, 6) = 2, list(pick(subtypesof(/obj/item/melee/energy/sword) - /obj/item/melee/energy/sword/charge), 6) = 2, - list(pick(/obj/item/dnainjector/xraymut, /obj/item/dnainjector/nobreath, /obj/item/dnainjector/insulation), 6) = 2, + // Traitgenes New injector loot + list(pick(/obj/item/dnainjector/random_good,/obj/item/dnainjector/random_good_labeled,/obj/item/dnainjector/random_labeled,/obj/item/dnainjector/random), 6) = 2, list(/obj/item/gun/energy/netgun, 7) = 2, list(pick(prob(300);/obj/item/gun/energy/mouseray, prob(50);/obj/item/gun/energy/mouseray/corgi, @@ -103,7 +104,8 @@ list(/obj/item/card/emag, 11) = 1, list(/obj/item/melee/shock_maul, 11) = 3, list(/obj/item/clothing/suit/storage/vest/martian_miner/reinforced, 4) = 6, - list(/obj/item/storage/backpack/sport/hyd/catchemall, 11) = 1 + list(/obj/item/storage/backpack/sport/hyd/catchemall, 11) = 1, + list(/obj/item/prop/alien/junk, 12) = 1, )) var/path = choice[1] var/value = choice[2] diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 90abf96071..062110d577 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -590,6 +590,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp return ..() /mob/observer/dead/Destroy() + visualnet.addVisibility(src, src.client) visualnet = null if(ismob(following)) var/mob/M = following diff --git a/code/modules/mob/freelook/ai/eye.dm b/code/modules/mob/freelook/ai/eye.dm index ff44a1f690..dc8e3dde73 100644 --- a/code/modules/mob/freelook/ai/eye.dm +++ b/code/modules/mob/freelook/ai/eye.dm @@ -15,6 +15,9 @@ if(owner) var/mob/living/silicon/ai/ai = owner ai.all_eyes -= src + owner = null + visualnet.clear_references(src, src.client) + visualnet = null . = ..() /mob/observer/eye/aiEye/setLoc(var/T, var/cancel_tracking = 1) diff --git a/code/modules/mob/freelook/visualnet.dm b/code/modules/mob/freelook/visualnet.dm index d153701cdd..10f0a6c809 100644 --- a/code/modules/mob/freelook/visualnet.dm +++ b/code/modules/mob/freelook/visualnet.dm @@ -157,3 +157,18 @@ var/datum/chunk/chunk = cameranet.getCameraChunk(x, y, z) usr.client.debug_variables(chunk) */ + +/datum/visualnet/proc/clear_references(list/moved_eyes, client/C) + if(!islist(moved_eyes)) + moved_eyes = moved_eyes ? list(moved_eyes) : list() + + var/list/chunks_pre_seen = list() + + for(var/mob/observer/eye/eye as anything in moved_eyes) + if(C) + chunks_pre_seen |= eye.visibleChunks + + if(C) + for(var/datum/chunk/c as anything in chunks_pre_seen) + for(var/mob/observer/eye/eye as anything in moved_eyes) + c.remove(eye) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index edffa66229..1cc155e1e3 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -147,10 +147,11 @@ var/list/slot_equipment_priority = list( \ // If canremove or other conditions need to be checked then use unEquip instead. /mob/proc/drop_from_inventory(var/obj/item/W, var/atom/target) - if(W) - remove_from_mob(W, target) - return TRUE - return FALSE + if(!W) + return FALSE + if(isnull(target) && istype( src.loc,/obj/structure/disposalholder)) + return remove_from_mob(W, src.loc) + return remove_from_mob(W, target) //Drops the item in our left hand /mob/proc/drop_l_hand(var/atom/Target) diff --git a/code/modules/mob/language/outsider.dm b/code/modules/mob/language/outsider.dm index 7c3510b327..d6f85442d8 100644 --- a/code/modules/mob/language/outsider.dm +++ b/code/modules/mob/language/outsider.dm @@ -77,7 +77,7 @@ /datum/language/xenocommon name = "Xenolingua" //CHOMPedit colour = "alien" - desc = "The common tongue of both the xenomorphs and the Genaprawns." //CHOMPedit + desc = "The common tongue of both the xenomorphs and the Genaprawns." speech_verb = "hisses" ask_verb = "hisses" exclaim_verb = "hisses" diff --git a/code/modules/mob/living/carbon/alien/larva/progression.dm b/code/modules/mob/living/carbon/alien/larva/progression.dm index c2852f2fa6..fdfdb1cbf2 100644 --- a/code/modules/mob/living/carbon/alien/larva/progression.dm +++ b/code/modules/mob/living/carbon/alien/larva/progression.dm @@ -10,9 +10,9 @@ to_chat(src, span_notice("There are three to choose from:")) to_chat(src, span_bold("Hunters") + span_notice(" are strong and agile, able to hunt away from the hive and rapidly move through ventilation shafts. Hunters generate plasma slowly and have low reserves.")) to_chat(src, span_bold("Sentinels") + span_notice(" are tasked with protecting the hive and are deadly up close and at a range. They are not as physically imposing nor fast as the hunters.")) - to_chat(src, span_bold("Drones") + span_notice(" are the working class, offering the largest plasma storage and generation. They are the only caste which may evolve again, turning into the dreaded Genaprawn queen.")) //CHOMPedit + to_chat(src, span_bold("Drones") + span_notice(" are the working class, offering the largest plasma storage and generation. They are the only caste which may evolve again, turning into the dreaded Genaprawn queen.")) var/alien_caste = tgui_alert(src, "Please choose which alien caste you shall belong to.","Alien Choice",list("Hunter","Sentinel","Drone")) - return alien_caste ? "Genaprawn [alien_caste]" : null //CHOMPedit + return alien_caste ? "Genaprawn [alien_caste]" : null /mob/living/carbon/alien/larva/show_evolution_blurb() return diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm index f1157ab3a3..c392d01fa2 100644 --- a/code/modules/mob/living/carbon/brain/brain.dm +++ b/code/modules/mob/living/carbon/brain/brain.dm @@ -8,7 +8,7 @@ use_me = 0 //Can't use the me verb, it's a freaking immobile brain icon = 'icons/obj/surgery.dmi' icon_state = "brain1" - no_vore = TRUE //VOREStation Edit - PLEASE. lol. + no_vore = TRUE can_pain_emote = FALSE // CHOMPEdit: Sanity/safety low_priority = TRUE //CHOMPEdit diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index ce918a252a..9481cbe358 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -27,10 +27,12 @@ var/can_defib = 1 //Horrible damage (like beheadings) will prevent defibbing organics. var/active_regen = FALSE //Used for the regenerate proc in human_powers.dm var/active_regen_delay = 300 - var/last_breath_sound //CHOMPAdd, Feels weird doing this, but allows us to store the value across proc calls per-mob. + var/last_breath_sound //Allows us to store the value across proc calls per-mob. var/list/teleporters = list() //Used for lleill abilities var/rest_dir = 0 //To lay down in a specific direction + var/gutdeathpressure = 0 //For GIBBING trait + var/list/datum/genetics/side_effect/genetic_side_effects = list() //For any genetic side effects we currently have. /mob/living/carbon/human/Initialize(mapload, var/new_species = null) if(!dna) @@ -39,7 +41,7 @@ if(!species) if(new_species) - set_species(new_species,1) + set_species(new_species) else set_species() @@ -62,19 +64,17 @@ if(dna) dna.ready_dna(src) dna.real_name = real_name + sync_dna_traits(FALSE) // Traitgenes Sync traits to genetics if needed sync_organ_dna() + initialize_vessel() AddComponent(/datum/component/personal_crafting) /mob/living/carbon/human/Destroy() human_mob_list -= src - QDEL_NULL_LIST(organs) // CHOMPEdit - /* //REMOVE - this is done on mob/living/Destroy - for(var/organ in organs) - qdel(organ) - */ + QDEL_NULL_LIST(organs) if(nif) - QDEL_NULL(nif) //VOREStation Add + QDEL_NULL(nif) worn_clothing.Cut() @@ -195,7 +195,7 @@ if (!get_ear_protection() >= 2) ear_damage += 30 ear_deaf += 120 - deaf_loop.start() // CHOMPStation Add: Ear Ringing/Deafness + deaf_loop.start() // CHOMPEnable: Ear Ringing/Deafness if (prob(70) && !shielded) Paralyse(10) @@ -206,7 +206,7 @@ if (!get_ear_protection() >= 2) ear_damage += 15 ear_deaf += 60 - deaf_loop.start() // CHOMPStation Add: Ear Ringing/Deafness + deaf_loop.start() // CHOMPEnable: Ear Ringing/Deafness if (prob(50) && !shielded) Paralyse(10) @@ -742,7 +742,7 @@ src << browse(null, "window=flavor_changes") return if("general") - var/msg = strip_html_simple(tgui_input_text(usr,"Update the general description of your character. This will be shown regardless of clothing.","Flavor Text",html_decode(flavor_texts[href_list["flavor_change"]]), multiline = TRUE, prevent_enter = TRUE)) //VOREStation Edit: separating out OOC notes + var/msg = strip_html_simple(tgui_input_text(usr,"Update the general description of your character. This will be shown regardless of clothing.","Flavor Text",html_decode(flavor_texts[href_list["flavor_change"]]), multiline = TRUE, prevent_enter = TRUE)) //Separating out OOC notes if(msg) flavor_texts[href_list["flavor_change"]] = msg set_flavor() @@ -820,11 +820,9 @@ return 1 /mob/living/carbon/human/IsAdvancedToolUser(var/silent) - // VOREstation start if(feral) to_chat(src, span_warning("Your primitive mind can't grasp the concept of that thing.")) return 0 - // VOREstation end if(species.has_fine_manipulation) return 1 if(!silent) @@ -960,6 +958,8 @@ return var/list/creatures = list() for(var/mob/living/carbon/h in mob_list) + if(h == src) // Don't target self + continue creatures += h var/mob/target = tgui_input_list(src, "Who do you want to project your mind to?", "Project Mind", creatures) if (isnull(target)) @@ -994,9 +994,14 @@ var/list/mob/creatures = list() + var/turf/current = get_turf(src) // Needs to be on station or same z to perform telepathy for(var/mob/living/carbon/h in mob_list) var/turf/temp_turf = get_turf(h) - if((temp_turf.z != 1 && temp_turf.z != 5) || h.stat!=CONSCIOUS) //Not on mining or the station. Or dead + if(!istype(temp_turf,/turf/)) // Nullcheck fix + continue + if(h == src) // Traitgenes edit - Don't target self + continue + if(!((temp_turf.z in using_map.station_levels) || current.z == temp_turf.z) || h.stat!=CONSCIOUS) // Needs to be on station or same z to perform telepathy continue creatures += h @@ -1052,13 +1057,20 @@ H.brainmob.mind.transfer_to(src) qdel(H) - // Vorestation Addition - reapply markings/appearance from prefs for player mobs + // Traitgenes Disable all traits currently active, before prefs.copy_to() is applied, as it refreshes the traits list! + for(var/datum/gene/trait/gene in GLOB.dna_genes) + if(gene.name in active_genes) + gene.deactivate(src) + active_genes -= gene.name + + // Reapply markings/appearance from prefs for player mobs if(client) //just to be sure client.prefs.copy_to(src) if(dna) dna.ResetUIFrom(src) + sync_dna_traits(TRUE) // Traitgenes Sync traits to genetics if needed sync_organ_dna() - // end vorestation addition + initialize_vessel() losebreath = 0 @@ -1221,7 +1233,7 @@ else to_chat(usr, span_warning("You failed to check the pulse. Try again.")) -/mob/living/carbon/human/proc/set_species(var/new_species, var/default_colour, var/regen_icons = TRUE, var/mob/living/carbon/human/example = null) //VOREStation Edit - send an example +/mob/living/carbon/human/proc/set_species(var/new_species) if(!dna) if(!new_species) @@ -1238,7 +1250,7 @@ if(species) - if(species.name && species.name == new_species && species.name != "Custom Species") //VOREStation Edit + if(species.name && species.name == new_species && species.name != "Custom Species") return if(species.language) remove_language(species.language) @@ -1249,7 +1261,7 @@ // Clear out their species abilities. species.remove_inherent_verbs(src) holder_type = null - hunger_rate = initial(hunger_rate) //VOREStation Add + hunger_rate = initial(hunger_rate) species = GLOB.all_species[new_species] @@ -1262,13 +1274,8 @@ if(species.icon_scale_x != DEFAULT_ICON_SCALE_X || species.icon_scale_y != DEFAULT_ICON_SCALE_Y) update_transform() - if(example) //VOREStation Edit begin - if(!(example == src)) - r_skin = example.r_skin - g_skin = example.g_skin - b_skin = example.b_skin - else if(species.base_color) //VOREStation Edit end - //Apply colour. + if(species.base_color) + //Apply color. r_skin = hex2num(copytext(species.base_color,2,4)) g_skin = hex2num(copytext(species.base_color,4,6)) b_skin = hex2num(copytext(species.base_color,6,8)) @@ -1285,17 +1292,15 @@ //icon_state = lowertext(species.name) //Necessary? - //VOREStation Edit start: swap places of those two procs species.handle_post_spawn(src) species.create_organs(src) - //VOREStation Edit end: swap places of those two procs maxHealth = species.total_health - hunger_rate = species.hunger_factor //VOREStation Add + hunger_rate = species.hunger_factor - default_pixel_x = initial(pixel_x) + species.pixel_offset_x //CHOMPedit for giving datum/species ways to change 64x64 sprite offsets + default_pixel_x = initial(pixel_x) + species.pixel_offset_x //For giving datum/species ways to change 64x64 sprite offsets default_pixel_y = initial(pixel_y) + species.pixel_offset_y pixel_x = default_pixel_x pixel_y = default_pixel_y @@ -1310,6 +1315,24 @@ var/datum/mob_descriptor/descriptor = species.descriptors[desctype] descriptors[desctype] = descriptor.default_value + //This was the old location of initialize_vessel. A race condiiton happened here because of species code being JANK. This resulted in runtimes during unit test, but worked perfectly fine in game. + //Now, initialize_vessel has been moved to human/Initialize() + // addtimer(CALLBACK(src, PROC_REF(initialize_vessel)), 0, TIMER_DELETE_ME) //Doing ASYNC fails here. This used to be a spawn(0) + + // Rebuild the HUD. If they aren't logged in then login() should reinstantiate it for them. + update_hud() + + //A slew of bits that may be affected by our species change + regenerate_icons() + + if(species) + return 1 + else + return 0 + +/mob/living/carbon/human/proc/initialize_vessel() //This needs fixing. For some reason mob species is not immediately set in set_species. + SHOULD_NOT_OVERRIDE(TRUE) + regenerate_icons() make_blood() if(vessel.total_volume < species.blood_volume) vessel.maximum_volume = species.blood_volume @@ -1321,19 +1344,6 @@ species.update_attack_types() //Required for any trait that updates unarmed_types in setup. species.update_vore_belly_def_variant() - // Rebuild the HUD. If they aren't logged in then login() should reinstantiate it for them. - update_hud() - - //A slew of bits that may be affected by our species change - regenerate_icons() - - if(species) - //if(mind) //VOREStation Removal - //apply_traits() //VOREStation Removal - return 1 - else - return 0 - /mob/living/carbon/human/proc/bloody_doodle() set category = "IC.Game" set name = "Write in blood" @@ -1500,14 +1510,14 @@ if(C.body_parts_covered & FEET) footcoverage_check = TRUE break - if(lying) // CHOMPadd - Drops stuff from hands, but no sleep. + if(lying) playsound(src, 'sound/misc/slip.ogg', 25, 1, -1) drop_both_hands() return 0 if((species.flags & NO_SLIP && !footcoverage_check) || (shoes && (shoes.item_flags & NOSLIP))) //Footwear negates a species' natural traction. return 0 if(..(slipped_on,stun_duration)) - drop_both_hands() // CHOMPAdd - Drops stuff from both hands + drop_both_hands() return 1 /mob/living/carbon/human/proc/relocate() @@ -1563,7 +1573,11 @@ current_limb.relocate() /mob/living/carbon/human/drop_from_inventory(var/obj/item/W, var/atom/target = null) - return !(W in organs) && ..() + if(W in organs) + return FALSE + if(isnull(target) && istype( src.loc,/obj/structure/disposalholder)) + return remove_from_mob(W, src.loc) + return ..() /mob/living/carbon/human/reset_view(atom/A, update_hud = 1) ..() @@ -1573,8 +1587,8 @@ /mob/living/carbon/human/Check_Shoegrip() if(shoes && (shoes.item_flags & NOSLIP) && istype(shoes, /obj/item/clothing/shoes/magboots)) //magboots + dense_object = no floating return 1 - if(flying) //VOREStation Edit. Checks to see if they have wings and are flying. - return 1 //VOREStation Edit. + if(flying) // Checks to see if they have wings and are flying. + return 1 return 0 //Puts the item into our active hand if possible. returns 1 on success. @@ -1671,12 +1685,10 @@ /mob/living/carbon/human/can_feel_pain(var/obj/item/organ/check_organ) if(isSynthetic()) return 0 - //RS ADD START if(!digest_pain && (isbelly(src.loc) || istype(src.loc, /turf/simulated/floor/water/digestive_enzymes))) var/obj/belly/b = src.loc if(b.digest_mode == DM_DIGEST || b.digest_mode == DM_SELECT) return FALSE - //RS ADD END for(var/datum/modifier/M in modifiers) if(M.pain_immunity == TRUE) return 0 @@ -1722,8 +1734,8 @@ /mob/living/carbon/human/proc/get_display_species() //Shows species in tooltip - if(src.custom_species) //VOREStation Add - return custom_species //VOREStation Add + if(src.custom_species) + return custom_species //Beepboops get special text if obviously beepboop if(looksSynthetic()) if(gender == MALE) @@ -1828,7 +1840,7 @@ /mob/living/carbon/human/verb/lay_down_left() set name = "Rest-Left" - rest_dir = 1 // CHOMPEdit + rest_dir = 1 resting = !resting to_chat(src, span_notice("You are now [resting ? "resting" : "getting up"].")) update_canmove() @@ -1836,7 +1848,7 @@ /mob/living/carbon/human/verb/lay_down_right() set name = "Rest-Right" - rest_dir = 0 // CHOMPEdit + rest_dir = 0 resting = !resting to_chat(src, span_notice("You are now [resting ? "resting" : "getting up"].")) update_canmove() diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 2e15db1258..08f781288a 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -166,3 +166,6 @@ var/block_hud var/phobias //For holding a list of phobias + + var/loneliness_stage = 0 + var/next_loneliness_time = 0 diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index 003d3732fa..d32a56a81c 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -5,17 +5,6 @@ update_icons_body() //Body handles eyes update_eyes() //For floating eyes only -/* -/mob/living/carbon/var/list/internal_organs = list() -/mob/living/carbon/human/var/list/organs = list() -/mob/living/carbon/human/var/list/organs_by_name = list() // map organ names to organs -/mob/living/carbon/human/var/list/internal_organs_by_name = list() // so internal organs have less ickiness too - -/mob/living/carbon/human/proc/get_bodypart_name(var/zone) - var/obj/item/organ/external/E = get_organ(zone) - if(E) . = E.name -*/ - /mob/living/carbon/human/proc/recheck_bad_external_organs() var/damage_this_tick = getToxLoss() for(var/obj/item/organ/external/O in organs) @@ -47,7 +36,7 @@ if(!force_process && !bad_external_organs.len) return - number_wounds = 0 //VOREStation Add - You have to reduce this at some point... + number_wounds = 0 for(var/obj/item/organ/external/E in bad_external_organs) if(!E) continue @@ -62,7 +51,7 @@ //Moving around with fractured ribs won't do you any good if (prob(10) && !stat && can_feel_pain() && chem_effects[CE_PAINKILLER] < 50 && E.is_broken() && E.internal_organs.len) custom_pain("Pain jolts through your broken [E.encased ? E.encased : E.name], staggering you!", 50) - emote("pain") // CHOMPStation Add: You SHOULD make a noise here. + emote("pain") drop_item(loc) Stun(2) @@ -105,7 +94,7 @@ else if (E.is_dislocated()) stance_damage += 0.5 - if(E && (!E.is_usable() || E.is_broken() || E.is_dislocated())) //VOREStation Edit + if(E && (!E.is_usable() || E.is_broken() || E.is_dislocated())) limb_pain = E.organ_can_feel_pain() // Canes and crutches help you stand (if the latter is ever added) @@ -118,7 +107,7 @@ // standing is poor if(stance_damage >= 4 || (stance_damage >= 2 && prob(5))) - if(!(lying || resting) && !isbelly(loc)) //VOREStation Edit + if(!(lying || resting) && !isbelly(loc)) if(limb_pain) emote("scream") custom_emote(1, "collapses!") @@ -164,11 +153,11 @@ continue drop_from_inventory(r_hand) - if(!isbelly(loc)) //VOREStation Add + if(!isbelly(loc)) var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") custom_emote(VISIBLE_MESSAGE, "[(can_feel_pain()) ? "" : emote_scream ]drops what they were holding in their [E.name]!") if(can_feel_pain()) - emote("pain") // CHOMPStation Add: You SHOULD make a noise here. + emote("pain") else if(E.is_malfunctioning()) switch(E.body_part) @@ -181,7 +170,7 @@ continue drop_from_inventory(r_hand) - if(!isbelly(loc)) //VOREStation Add + if(!isbelly(loc)) custom_emote(VISIBLE_MESSAGE, "drops what they were holding, their [E.name] malfunctioning!") var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() @@ -198,6 +187,32 @@ var/obj/item/organ/O = pick(organs) O.trace_chemicals[A.name] = 100 +// Traitgenes Init genes based on the traits currently active +/mob/living/carbon/human/proc/sync_dna_traits(var/refresh_traits, var/hide_message = TRUE) + SHOULD_NOT_OVERRIDE(TRUE) //Don't. Even. /Think/. About. It. + if(!dna || !species) + return + // Traitgenes NO_SCAN and Synthetics cannot be mutated + if(isSynthetic()) + return + if(species.flags & NO_SCAN) + return + if(refresh_traits && species.traits) + for(var/TR in species.traits) + var/datum/trait/T = all_traits[TR] + if(!T) + continue + if(!T.linked_gene) + continue + var/datum/gene/trait/gene = T.linked_gene + dna.SetSEState(gene.block, TRUE, TRUE) + // testing("[gene.name] Setup activated!") + dna.UpdateSE() + var/flgs = MUTCHK_FORCED + if(hide_message) + flgs |= MUTCHK_HIDEMSG + domutcheck( src, null, flgs) + /mob/living/carbon/human/proc/sync_organ_dna() var/list/all_bits = internal_organs|organs for(var/obj/item/organ/O in all_bits) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 09335b16cb..d895b5d66c 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -4,15 +4,14 @@ #define HUMAN_MAX_OXYLOSS 1 //Defines how much oxyloss humans can get per tick. A tile with no air at all (such as space) applies this value, otherwise it's a percentage of it. #define HUMAN_CRIT_MAX_OXYLOSS ( 2.0 / 6) //The amount of damage you'll get when in critical condition. We want this to be a 5 minute deal = 300s. There are 50HP to get through, so (1/6)*last_tick_duration per second. Breaths however only happen every 4 ticks. last_tick_duration = ~2.0 on average -#define HEAT_DAMAGE_LEVEL_1 2 //VOREStation Edit //Amount of damage applied when your body temperature just passes the 360.15k safety point -#define HEAT_DAMAGE_LEVEL_2 4 //VOREStation Edit //Amount of damage applied when your body temperature passes the 400K point -#define HEAT_DAMAGE_LEVEL_3 8 //VOREStation Edit //Amount of damage applied when your body temperature passes the 1000K point +#define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point +#define HEAT_DAMAGE_LEVEL_2 4 //Amount of damage applied when your body temperature passes the 400K point +#define HEAT_DAMAGE_LEVEL_3 8 //Amount of damage applied when your body temperature passes the 1000K point #define COLD_DAMAGE_LEVEL_1 0.5 //Amount of damage applied when your body temperature just passes the 260.15k safety point #define COLD_DAMAGE_LEVEL_2 1.5 //Amount of damage applied when your body temperature passes the 200K point #define COLD_DAMAGE_LEVEL_3 3 //Amount of damage applied when your body temperature passes the 120K point -//# define RADIATION_SPEED_COEFFICIENT 0.1 //CHOMPRemove #define HUMAN_COMBUSTION_TEMP 524 //524k is the sustained combustion temperature of human fat /mob/living/carbon/human @@ -53,7 +52,7 @@ Sleeping(20) //No need to update all of these procs if the guy is dead. - fall() //VORESTATION EDIT. Prevents people from floating + fall() //Prevents people from floating if(stat != DEAD && !stasis) //Updates the number of stored chemicals for powers handle_changeling() @@ -61,8 +60,8 @@ //Organs and blood handle_organs() stabilize_body_temperature() //Body temperature adjusts itself (self-regulation) - weightgain() //VOREStation Addition - process_weaver_silk() //VOREStation Addition + weightgain() + process_weaver_silk() handle_shock() handle_pain() @@ -72,7 +71,7 @@ handle_medical_side_effects() handle_heartbeat() - handle_nif() //VOREStation Addition + handle_nif() if(phobias) handle_phobias() if(!client) @@ -182,7 +181,7 @@ return if (disabilities & EPILEPSY) - if ((prob(1) && paralysis < 1)) + if ((prob(1) && prob(1) && paralysis < 1)) to_chat(src, span_red("You have a seizure!")) for(var/mob/O in viewers(src, null)) if(O == src) @@ -193,23 +192,57 @@ if (disabilities & COUGHING) if ((prob(5) && paralysis <= 1)) drop_item() - spawn(0) - emote("cough") - return + emote("cough") + if(dna) + if(disabilities & DETERIORATE && prob(2) && prob(3)) // stacked percents for rarity + // random strange symptoms from organ/limb + custom_emote(VISIBLE_MESSAGE, "flinches slightly.") + switch(rand(1,4)) + if(1) + adjustToxLoss(rand(2,8)) + if(2) + adjustCloneLoss(rand(1,2)) + if(3) + add_chemical_effect(CE_PAINKILLER, rand(8,28)) + else + adjustOxyLoss(rand(13,26)) + // external organs need to fall off if damaged enough + var/obj/item/organ/O = pick(organs) + if(O && !(O.organ_tag == BP_GROIN || O.organ_tag == BP_TORSO) && istype(O,/obj/item/organ/external)) + var/obj/item/organ/external/E = O + if(O.damage >= O.min_broken_damage && O.robotic <= ORGAN_ASSISTED && prob(70)) + add_chemical_effect(CE_PAINKILLER, 120) // what limb? Extreme nerve damage. Can't feel a thing + shock + E.droplimb(TRUE, DROPLIMB_ACID) + if(disabilities & GIBBING) + gutdeathpressure += 0.01 + if(gutdeathpressure > 0 && prob(gutdeathpressure)) + emote(pick("whimper","belch","belch","belch","choke","shiver")) + Weaken(gutdeathpressure / 3) + if((gutdeathpressure/3) >= 1 && prob(gutdeathpressure/3)) + gutdeathpressure = 0 // to stop retriggering + spawn(1) + emote(pick("whimper","shiver")) + spawn(3) + emote(pick("whimper","belch","shiver")) + spawn(4) + emote(pick("whimper","shiver")) + spawn(6) + emote(pick("belch")) + gib() if (disabilities & TOURETTES) - if ((prob(10) && paralysis <= 1)) + if ((prob(1) && prob(2) && paralysis <= 1)) Stun(10) - spawn(0) - switch(rand(1, 3)) - if(1) - emote("twitch") - if(2 to 3) - say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]") - make_jittery(100) - return + make_jittery(100) + switch(rand(1, 3)) + if(1) + emote("twitch") + if(2 to 3) + say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]") if (disabilities & NERVOUS) - if (prob(10)) - stuttering = max(10, stuttering) + if (prob(5) && prob(7)) + stuttering = max(15, stuttering) + if(jitteriness < 50) + make_jittery(65) var/rn = rand(0, 200) if(getBrainLoss() >= 5) @@ -261,21 +294,25 @@ if((COLD_RESISTANCE in mutations) || (prob(1))) heal_organ_damage(0,1) - if(stat != DEAD) //CHOMPadd: Until I find where nutrion heal code is anyway - if((mRegen in mutations)) - heal_organ_damage(0.2,0.2) + if(stat != DEAD) + if((mRegen in mutations)) + var/heal = rand(0.2,1.3) + if(prob(50)) + for(var/obj/item/organ/external/O in bad_external_organs) + for(var/datum/wound/W in O.wounds) + if(W.bleeding()) + W.damage = max(W.damage - heal, 0) + if(W.damage <= 0) + O.wounds -= W + if(W.internal) + W.damage = max(W.damage - heal, 0) + if(W.damage <= 0) + O.wounds -= W + else + heal_organ_damage(heal,heal) - // DNA2 - Gene processing. - // The HULK stuff that was here is now in the hulk gene. - if(!isSynthetic()) - for(var/datum/dna/gene/gene in dna_genes) - if(!gene.block) - continue - if(gene.is_active(src)) - gene.OnMobLife(src) - - radiation = CLAMP(radiation,0,2500) //Max of 50Gy. If you reach that...You're going to wish you were dead. You probably will be dead. - accumulated_rads = CLAMP(accumulated_rads,0,2500) //Max of 50Gy as well. You should never get higher than this. You will be dead before you can reach this. + radiation = CLAMP(radiation,0,5000) //Max of 100Gy. If you reach that...You're going to wish you were dead. You probably will be dead. + accumulated_rads = CLAMP(accumulated_rads,0,5000) //Max of 100Gy as well. You should never get higher than this. You will be dead before you can reach this. var/obj/item/organ/internal/I = null //Used for further down below when an organ is picked. if(!radiation) if(species.appearance_flags & RADIATION_GLOWS) @@ -292,12 +329,12 @@ var/obj/item/organ/internal/diona/nutrients/rad_organ = locate() in internal_organs if(rad_organ && !rad_organ.is_broken()) var/rads = radiation/25 - radiation -= rads - adjust_nutrition(rads) - adjustBruteLoss(-(rads)) - adjustFireLoss(-(rads)) - adjustOxyLoss(-(rads)) - adjustToxLoss(-(rads)) + radiation -= (rads * species.rad_removal_mod) + adjust_nutrition(rads * species.rad_removal_mod) + adjustBruteLoss(-(rads * species.rad_removal_mod)) + adjustFireLoss(-(rads * species.rad_removal_mod)) + adjustOxyLoss(-(rads * species.rad_removal_mod)) + adjustToxLoss(-(rads * species.rad_removal_mod)) updatehealth() return @@ -305,25 +342,26 @@ if(core) return - //VOREStation Addition start: shadekin var/obj/item/organ/internal/brain/shadekin/s_brain = locate() in internal_organs if(s_brain) return - //VOREStation Addition end: shadekin if(reagents.has_reagent(REAGENT_ID_PRUSSIANBLUE)) //Prussian Blue temporarily stops radiation effects. return var/damage = 0 + if(!species.radiation_mod) //If we are rad immune, stop here and remove rads if we have any. + radiation -= 10 * RADIATION_SPEED_COEFFICIENT * species.rad_removal_mod + return - if (radiation < 50) //Less than 1.0 Gy. No side effects. - radiation -= 10 * RADIATION_SPEED_COEFFICIENT + if (radiation < species.rad_levels["safe"]) //Less than 1.0 Gy. No side effects. + radiation -= 10 * RADIATION_SPEED_COEFFICIENT * species.rad_removal_mod accumulated_rads += 10 * RADIATION_SPEED_COEFFICIENT //No escape from accumulated rads. - else if (radiation >= 50 && radiation < 100) //Equivalent of 1.0-2.0 Gy. Minimum stage you start seeing effects. + else if (radiation >= species.rad_levels["safe"] && radiation < species.rad_levels["danger_1"]) //Equivalent of 1.0-2.0 Gy. Minimum stage you start seeing effects. damage = 1 - radiation -= 10 * RADIATION_SPEED_COEFFICIENT + radiation -= 10 * RADIATION_SPEED_COEFFICIENT * species.rad_removal_mod accumulated_rads += 10 * RADIATION_SPEED_COEFFICIENT if(!isSynthetic()) if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT) && !weakened) @@ -338,9 +376,9 @@ if(prob(1) && prob(100 * RADIATION_SPEED_COEFFICIENT)) //Rare chance of vomiting. spawn vomit() - else if (radiation >= 100 && radiation < 300) //Equivalent of 2.0 to 6.0 Gy. Nobody should ever be above this without extreme negligence. + else if (radiation >= species.rad_levels["danger_1"] && radiation < species.rad_levels["danger_2"]) //Equivalent of 2.0 to 6.0 Gy. Nobody should ever be above this without extreme negligence. damage = 3 - radiation -= 30 * RADIATION_SPEED_COEFFICIENT + radiation -= 30 * RADIATION_SPEED_COEFFICIENT * species.rad_removal_mod accumulated_rads += 30 * RADIATION_SPEED_COEFFICIENT if(!isSynthetic()) if(prob(5)) @@ -354,9 +392,9 @@ to_chat(src, span_warning("You feel sick.")) AdjustWeakened(3) - else if (radiation >= 300 && radiation < 400) //Equivalent of 6.0 to 8.0 Gy. + else if (radiation >= species.rad_levels["danger_2"] && radiation < species.rad_levels["danger_3"]) //Equivalent of 6.0 to 8.0 Gy. damage = 5 - radiation -= 50 * RADIATION_SPEED_COEFFICIENT + radiation -= 50 * RADIATION_SPEED_COEFFICIENT * species.rad_removal_mod accumulated_rads += 50 * RADIATION_SPEED_COEFFICIENT if(!isSynthetic()) if(prob(15)) @@ -381,9 +419,9 @@ I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT) - else if (radiation >= 400 && radiation < 1500) //Equivalent of 8.0 to 30 Gy. + else if (radiation >= species.rad_levels["danger_3"] && radiation < species.rad_levels["danger_4"]) //Equivalent of 8.0 to 30 Gy. damage = 10 - radiation -= 100 * RADIATION_SPEED_COEFFICIENT + radiation -= 100 * RADIATION_SPEED_COEFFICIENT * species.rad_removal_mod accumulated_rads += 100 * RADIATION_SPEED_COEFFICIENT if(!isSynthetic()) if(prob(25)) @@ -407,8 +445,8 @@ to_chat(src, span_critical("Your entire body feels like it's on fire!")) adjustHalLoss(5) if(prob(10) && internal_organs.len) + // CHOMPedit begin - organ mutations if(prob(2)) - // CHOMPedit begin - organ mutations random_malignant_organ(TRUE,FALSE,prob(60)) // CHOMPedit end else @@ -416,9 +454,9 @@ if(istype(I)) I.add_autopsy_data("Radiation Induced Cancerous Growth", damage) I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT) - else if (radiation >= 1500) //Above 30Gy. You had to get absolutely blasted with rads for this. + else if (radiation >= species.rad_levels["danger_4"]) //Above 30Gy. You had to get absolutely blasted with rads for this. damage = 30 - radiation -= 300 * RADIATION_SPEED_COEFFICIENT + radiation -= 300 * RADIATION_SPEED_COEFFICIENT * species.rad_removal_mod accumulated_rads += 300 * RADIATION_SPEED_COEFFICIENT if(!isSynthetic()) @@ -442,16 +480,10 @@ if(get_active_hand() && prob(15)) //CNS is shutting down. to_chat(src, span_danger("Your hand won't respond properly, you drop what you're holding!")) drop_item() - if(internal_organs.len) - // CHOMPedit begin - organ mutations - if(prob(2)) - // random organ time! - random_malignant_organ(prob(40),FALSE,TRUE) - // CHOMPedit end - else - I = pick(internal_organs) //Internal organ damage...Not good. Not good at all. - if(istype(I)) I.add_autopsy_data("Radiation Induced Cancerous Growth", damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT) - I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT) + if(internal_organs.len) //TODO: Add malignant organs. - The person that wrote radcode. + I = pick(internal_organs) //Internal organ damage...Not good. Not good at all. + if(istype(I)) I.add_autopsy_data("Radiation Induced Cancerous Growth", damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT) + I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT) /* //Not-so-sparkledog code. TODO: Make a pref for 'special game interactions' that allows interactions that align with prefs to occur. if(radiation >= 250) //Special effect stuff that occurs at certain rad levels. @@ -561,7 +593,7 @@ if(status_flags & GODMODE) return - if(mNobreath in src.mutations) //CHOMPadd + if(mNobreath in mutations) return if(suiciding) @@ -897,7 +929,7 @@ pl_effects() break - if(istype(loc, /turf/space)) //VOREStation Edit - No FBPs overheating on space turfs inside mechs or people. + if(istype(loc, /turf/space)) //No FBPs overheating on space turfs inside mechs or people. //Don't bother if the temperature drop is less than 0.1 anyways. Hopefully BYOND is smart enough to turn this constant expression into a constant if(bodytemperature > (0.1 * HUMAN_HEAT_CAPACITY/(HUMAN_EXPOSED_SURFACE_AREA*STEFAN_BOLTZMANN_CONSTANT))**(1/4) + COSMIC_RADIATION_TEMPERATURE) //Thermal radiation into space @@ -998,7 +1030,7 @@ throw_alert("pressure", /obj/screen/alert/lowpressure, 1) else if( !(COLD_RESISTANCE in mutations)) - if(!isSynthetic() || !nif || !nif.flag_check(NIF_O_PRESSURESEAL,NIF_FLAGS_OTHER)) //VOREStation Edit - NIF pressure seals + if(!isSynthetic() || !nif || !nif.flag_check(NIF_O_PRESSURESEAL,NIF_FLAGS_OTHER)) var/pressure_damage = LOW_PRESSURE_DAMAGE if(stat==DEAD) pressure_damage = pressure_damage/2 @@ -1022,25 +1054,6 @@ return -/* -/mob/living/carbon/human/proc/adjust_body_temperature(current, loc_temp, boost) - var/temperature = current - var/difference = abs(current-loc_temp) //get difference - var/increments// = difference/10 //find how many increments apart they are - if(difference > 50) - increments = difference/5 - else - increments = difference/10 - var/change = increments*boost // Get the amount to change by (x per increment) - var/temp_change - if(current < loc_temp) - temperature = min(loc_temp, temperature+change) - else if(current > loc_temp) - temperature = max(loc_temp, temperature-change) - temp_change = (temperature - current) - return temp_change -*/ - /mob/living/carbon/human/proc/stabilize_body_temperature() // We produce heat naturally. if (species.passive_temp_gain) @@ -1050,7 +1063,7 @@ // FBPs will overheat when alive, prosthetic limbs are fine. if(stat != DEAD && robobody_count) - if(!nif || !nif.flag_check(NIF_O_HEATSINKS,NIF_FLAGS_OTHER)) //VOREStation Edit - NIF heatsinks prevent the base heat increase per tick if installed. + if(!nif || !nif.flag_check(NIF_O_HEATSINKS,NIF_FLAGS_OTHER)) bodytemperature += round(robobody_count*1.15) var/obj/item/organ/internal/robotic/heatsink/HS = internal_organs_by_name[O_HEATSINK] if(!HS || HS.is_broken()) // However, NIF Heatsinks will not compensate for a core FBP component (your heatsink) being lost. @@ -1183,8 +1196,8 @@ var/total_phoronloss = 0 for(var/obj/item/I in src) if(I.contaminated) - if(check_belly(I)) continue //VOREStation Edit - if(src.species && src.species.get_bodytype() != "Vox" && src.species.get_bodytype() != "Shadekin") //VOREStation Edit: shadekin + if(check_belly(I)) continue + if(src.species && src.species.get_bodytype() != "Vox" && src.species.get_bodytype() != "Shadekin") // This is hacky, I'm so sorry. if(I != l_hand && I != r_hand) //If the item isn't in your hands, you're probably wearing it. Full damage for you. total_phoronloss += vsc.plc.CONTAMINATION_LOSS @@ -1212,7 +1225,6 @@ take_overall_damage(1,1) else //heal in the dark heal_overall_damage(1,1) - //CHOMPEdit Begin if(species.photosynthesizing && nutrition < 1000) var/light_amount = 0 if(isturf(loc)) @@ -1222,37 +1234,32 @@ // nutrition decrease if(nutrition <= 0 && species.shrinks && size_multiplier > RESIZE_TINY) nutrition = 0.1 - //CHOMPEdit End if(nutrition > 0 && stat != DEAD) var/nutrition_reduction = species.hunger_factor for(var/datum/modifier/mod in modifiers) if(!isnull(mod.metabolism_percent)) nutrition_reduction *= mod.metabolism_percent - //CHOMPEdit Begin if(nutrition > 1000 && species.grows) //Removing the strict check against normal max/min size to support dorms/VR oversizing nutrition_reduction *= 5 resize(size_multiplier+0.01, animate = FALSE, uncapped = has_large_resize_bounds()) //Bringing this code in line with micro and macro shrooms if(nutrition < 50 && species.shrinks) nutrition_reduction *= 0.3 resize(size_multiplier-0.01, animate = FALSE, uncapped = has_large_resize_bounds()) //Bringing this code in line with micro and macro shrooms - //CHOMPEdit End adjust_nutrition(-nutrition_reduction) - if(noisy == TRUE && nutrition < 250 && prob(10)) //VOREStation edit for hunger noises. + if(noisy == TRUE && nutrition < 250 && prob(10)) var/sound/growlsound = sound(get_sfx("hunger_sounds")) var/growlmultiplier = 100 - (nutrition / 250 * 100) playsound(src, growlsound, vol = growlmultiplier, vary = 1, falloff = 0.1, ignore_walls = TRUE, preference = /datum/preference/toggle/digestion_noises) - // VOREStation Edit End - //CHOMPEdit Begin + // CHOMPEnable Start if(nutrition > 500 && noisy_full == TRUE) var/belch_prob = 5 //Maximum belch prob. if(nutrition < 4075) belch_prob = ((nutrition-500)/3575)*5 //Scale belch prob with fullness if not already at max. If editing make sure the multiplier matches the max prob above. if(prob(belch_prob)) src.emote("belch") - //CHOMPEdit End - + // CHOMPEnable End if((CE_DARKSIGHT in chem_effects) && chemical_darksight == 0) recalculate_vis() chemical_darksight = 1 @@ -1266,7 +1273,7 @@ updatehealth() - return //TODO: DEFERRED + return //DO NOT CALL handle_statuses() from this proc, it's called from living/Life() as long as this returns a true value. /mob/living/carbon/human/handle_regular_status_updates() @@ -1281,7 +1288,7 @@ if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP blinded = 1 silent = 0 - deaf_loop.stop() // CHOMPStation Add: Ear Ringing/Deafness - Not sure if we need this, but, safety. + deaf_loop.stop() // CHOMPEnable: Ear Ringing/Deafness - Not sure if we need this, but, safety. else //ALIVE. LIGHTS ARE ON updatehealth() //TODO @@ -1289,23 +1296,23 @@ death() blinded = 1 silent = 0 - deaf_loop.stop() // CHOMPStation Add: Ear Ringing/Deafness - Not sure if we need this, but, safety. + deaf_loop.stop() // CHOMPEnable: Ear Ringing/Deafness - Not sure if we need this, but, safety. return 1 //UNCONSCIOUS. NO-ONE IS HOME - if((getOxyLoss() > (species.total_health/2)) || (health <= (CONFIG_GET(number/health_threshold_crit) * species.crit_mod))) // CHOMPEdit + if((getOxyLoss() > (species.total_health/2)) || (health <= (CONFIG_GET(number/health_threshold_crit) * species.crit_mod))) Paralyse(3) if(hallucination) if(hallucination >= 20 && !(species.flags & (NO_POISON|IS_PLANT|NO_HALLUCINATION)) ) - //if(prob(3)) //ChompREMOVE fake_attacker - EXTREME image qdel usage. - //fake_attack(src) //ChompREMOVE fake_attacker - EXTREME image qdel usage. if(!handling_hal) spawn handle_hallucinations() //The not boring kind! + /* Stop spinning the view, it breaks too much. if(client && prob(5)) client.dir = pick(2,4,8) spawn(rand(20,50)) client.dir = 1 + */ hallucination = max(0, hallucination - 2) else @@ -1359,6 +1366,16 @@ adjustHalLoss(-3) if(sleeping) + if(prob(2)) + if(prob(50)) + adjustBruteLoss(-1) + else + adjustFireLoss(-1) + if(bad_external_organs.len && prob(45)) + var/obj/item/organ/badorgan = pick(bad_external_organs) + if(!badorgan.is_broken() && badorgan.is_bruised()) + badorgan.damage -= 1 + handle_dreams() if (mind) //Are they SSD? If so we'll keep them asleep but work off some of that sleep var in case of stoxin or similar. @@ -1430,7 +1447,7 @@ //Ears if(sdisabilities & DEAF) //disabled-deaf, doesn't get better on its own ear_deaf = max(ear_deaf, 1) - deaf_loop.start(skip_start_sound = TRUE) // CHOMPStation Add: Ear Ringing/Deafness + deaf_loop.start(skip_start_sound = TRUE) // CHOMPEnable: Ear Ringing/Deafness else if(ear_deaf) //deafness, heals slowly over time ear_deaf = max(ear_deaf-1, 0) else if(get_ear_protection() >= 2) //resting your ears with earmuffs heals ear damage faster @@ -1439,10 +1456,10 @@ else if(ear_damage < 25) //ear damage heals slowly under this threshold. otherwise you'll need earmuffs ear_damage = max(ear_damage-0.05, 0) - // CHOMPAdd: Handle Ear ringing, standalone safety check. + // CHOMPEnable Start: Handle Ear ringing, standalone safety check. if(ear_deaf <= 0) - deaf_loop.stop() // CHOMPStation Add: Ear Ringing/Deafness - // CHOMPAdd End + deaf_loop.stop() + // CHOMPEnable End //Resting if(resting) @@ -1617,14 +1634,12 @@ fat_alert = /obj/screen/alert/fat/synth hungry_alert = /obj/screen/alert/hungry/synth starving_alert = /obj/screen/alert/starving/synth - //VOREStation Add - Vampire hunger alert else if(get_species() == SPECIES_CUSTOM) var/datum/species/custom/C = species if(/datum/trait/neutral/bloodsucker in C.traits) fat_alert = /obj/screen/alert/fat/vampire hungry_alert = /obj/screen/alert/hungry/vampire starving_alert = /obj/screen/alert/starving/vampire - //VOREStation Add End switch(nutrition) if(450 to INFINITY) @@ -1654,7 +1669,7 @@ if(G.prescription) apply_nearsighted_overlay = FALSE - if(nif && nif.flag_check(NIF_V_CORRECTIVE, NIF_FLAGS_VISION)) // VOREStation Edit - NIF + if(nif && nif.flag_check(NIF_V_CORRECTIVE, NIF_FLAGS_VISION)) apply_nearsighted_overlay = FALSE set_fullscreen(apply_nearsighted_overlay, "nearsighted", /obj/screen/fullscreen/impaired, 1) @@ -1682,7 +1697,7 @@ var/obj/item/clothing/glasses/welding/O = glasses if(!O.up) found_welder = 1 - if(!found_welder && nif && nif.flag_check(NIF_V_UVFILTER,NIF_FLAGS_VISION)) found_welder = 1 //VOREStation Add - NIF + if(!found_welder && nif && nif.flag_check(NIF_V_UVFILTER,NIF_FLAGS_VISION)) found_welder = 1 if(istype(glasses, /obj/item/clothing/glasses/sunglasses/thinblindfold)) found_welder = 1 if(!found_welder && istype(head, /obj/item/clothing/head/welding)) @@ -1694,7 +1709,7 @@ if(O.helmet && O.helmet == head && (O.helmet.body_parts_covered & EYES)) if((O.offline && O.offline_vision_restriction == 1) || (!O.offline && O.vision_restriction == 1)) found_welder = 1 - if(absorbed) found_welder = 1 //VOREStation Code + if(absorbed) found_welder = 1 if(found_welder) client.screen |= global_hud.darkMask @@ -1858,12 +1873,10 @@ var/turf/T = loc if(T.get_lumcount() <= LIGHTING_SOFT_THRESHOLD) /* CHOMPEdit Start - //VOREStation Add Start if(text2num(time2text(world.timeofday, "MM")) == 4) if(text2num(time2text(world.timeofday, "DD")) == 1) playsound_local(src,pick(scawwySownds),50, 0) return - //VOREStation Add End */ // CHOMPedit End playsound_local(src,pick(scarySounds),50, 1, -1) @@ -1932,7 +1945,6 @@ /mob/living/carbon/human/handle_shock() ..() if(status_flags & GODMODE) return 0 //godmode - //CHOMPEdit - couple of fixes here. Fixes synths being stuck in permenant shock. if(traumatic_shock >= 80 && can_feel_pain()) shock_stage += 1 else @@ -1940,9 +1952,8 @@ shock_stage = max(shock_stage-1, 0) if(!can_feel_pain()) return - if(health < (CONFIG_GET(number/health_threshold_softcrit) * species.crit_mod)) //CHOMPEdit - fixes + if(health < (CONFIG_GET(number/health_threshold_softcrit) * species.crit_mod)) shock_stage = max(shock_stage, 61) - //CHOMPEdit end if(stat) return 0 @@ -1951,7 +1962,7 @@ custom_pain("[pick("It hurts so much", "You really need some painkillers", "Dear god, the pain")]!", 40) if(shock_stage >= 30) - if(shock_stage == 30 && !isbelly(loc)) //VOREStation Edit + if(shock_stage == 30 && !isbelly(loc)) custom_emote(VISIBLE_MESSAGE, "is having trouble keeping their eyes open.") eye_blurry = max(2, eye_blurry) if(traumatic_shock >= 80) @@ -1963,7 +1974,7 @@ to_chat(src, span_danger("[pick("The pain is excruciating", "Please, just end the pain", "Your whole body is going numb")]!")) if (shock_stage >= 60) - if(shock_stage == 60 && !isbelly(loc)) //VOREStation Edit + if(shock_stage == 60 && !isbelly(loc)) custom_emote(VISIBLE_MESSAGE, "'s body becomes limp.") if (prob(2)) if(traumatic_shock >= 80) @@ -1974,26 +1985,22 @@ if (prob(5)) if(traumatic_shock >= 80) to_chat(src, span_danger("[pick("The pain is excruciating", "Please, just end the pain", "Your whole body is going numb")]!")) - // CHOMPEdit: Pain - if(prob(20) && !isbelly(loc)) // Hopefully not spammy, only 20% of the time will we groan in pain + sanity for in-belly + if(prob(20) && !isbelly(loc)) emote("pain") - // CHOMPEdit End Weaken(20) if(shock_stage >= 120) if (prob(2)) if(traumatic_shock >= 80) to_chat(src, span_danger("[pick("You black out", "You feel like you could die any moment now", "You are about to lose consciousness")]!")) - // CHOMPEdit: Pain - if(prob(40) && !isbelly(loc)) // Hopefully not spammy, only 40% of the time will we groan in pain + sanity for in-belly + if(prob(40) && !isbelly(loc)) emote("pain") - // CHOMPEdit End Paralyse(5) if(shock_stage == 150) - if(!isbelly(loc)) //VOREStation Edit + if(!isbelly(loc)) custom_emote(VISIBLE_MESSAGE, "can no longer stand, collapsing!") - if(prob(60)) // Hopefully not spammy, only 60% of the time will we groan in pain + if(prob(60)) emote("pain") Weaken(20) @@ -2155,15 +2162,6 @@ holder2.icon_state = "huddead" else if(has_virus()) holder.icon_state = "hudill" -/* Start Chomp edit - else if(has_brain_worms()) - var/mob/living/simple_mob/animal/borer/B = has_brain_worms() - if(B.controlling) - holder.icon_state = "hudbrainworm" - else - holder.icon_state = "hudhealthy" - holder2.icon_state = "hudbrainworm" -End Chomp edit */ else holder.icon_state = "hudhealthy" if(has_virus()) @@ -2278,7 +2276,7 @@ End Chomp edit */ holder.icon_state = "hudblank" apply_hud(BACKUP_HUD, holder) - //VOREStation Antag Hud + //Vore Antag Hud if (BITTEST(hud_updateflag, VANTAG_HUD)) var/image/vantag = grab_hud(VANTAG_HUD) if(vantag_pref) @@ -2348,5 +2346,4 @@ End Chomp edit */ #undef COLD_DAMAGE_LEVEL_2 #undef COLD_DAMAGE_LEVEL_3 -//# undef RADIATION_SPEED_COEFFICIENT //CHOMPRemove #undef HUMAN_COMBUSTION_TEMP diff --git a/code/modules/mob/living/carbon/human/life_ch.dm b/code/modules/mob/living/carbon/human/life_ch.dm deleted file mode 100644 index 91fc297fd5..0000000000 --- a/code/modules/mob/living/carbon/human/life_ch.dm +++ /dev/null @@ -1,97 +0,0 @@ -/mob/living/carbon/human/handle_mutations_and_radiation() - if(inStasisNow()) - return - - if(getFireLoss()) - if((COLD_RESISTANCE in mutations) || (prob(1))) - heal_organ_damage(0,1) - - // DNA2 - Gene processing. - // The HULK stuff that was here is now in the hulk gene. - if(!isSynthetic()) - for(var/datum/dna/gene/gene in dna_genes) - if(!gene.block) - continue - if(gene.is_active(src)) - gene.OnMobLife(src) - - radiation = CLAMP(radiation,0,250) - - if(!radiation) - if(species.appearance_flags & RADIATION_GLOWS) - set_light(0) - else - if(species.appearance_flags & RADIATION_GLOWS) - set_light(max(1,min(5,radiation/15)), max(1,min(10,radiation/25)), species.get_flesh_colour(src)) - // END DOGSHIT SNOWFLAKE - - var/obj/item/organ/internal/diona/nutrients/rad_organ = locate() in internal_organs - if(rad_organ && !rad_organ.is_broken()) - var/rads = radiation/25 - radiation -= rads - adjust_nutrition(rads) - adjustBruteLoss(-(rads)) - adjustFireLoss(-(rads)) - adjustOxyLoss(-(rads)) - adjustToxLoss(-(rads)) - updatehealth() - return - - var/obj/item/organ/internal/brain/slime/core = locate() in internal_organs - if(core) - return - - //VOREStation Addition start: shadekin - var/obj/item/organ/internal/brain/shadekin/s_brain = locate() in internal_organs - if(s_brain) - return - //VOREStation Addition end: shadekin - - if(reagents.has_reagent("prussian_blue")) //Prussian Blue temporarily stops radiation effects. - return - - var/rad_mult = RADIATION_SPEED_COEFFICIENT * species.rad_removal_mod - var/damage = 0 - radiation -= 1 * rad_mult - if(radiation > species.rad_levels["safe"] && prob(25)) // Safe for a little over 2m at the recommended maximum safe dosage of 0.05Bq - damage = 1 - - if (radiation > species.rad_levels["danger_1"]) - damage = 1 - radiation -= 1 * rad_mult - if(!isSynthetic()) - if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT)) - radiation -= 5 * rad_mult - to_chat(src, span_warning("You feel weak.")) - Weaken(3) - if(!lying) - emote("collapse") - if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT) && species.get_bodytype() == SPECIES_HUMAN) //apes go bald - if((h_style != "Bald" || f_style != "Shaved" )) - to_chat(src, span_warning("Your hair falls out.")) - h_style = "Bald" - f_style = "Shaved" - update_hair() - - if (radiation > species.rad_levels["danger_2"]) - damage = 3 - radiation -= 1 * rad_mult - if(!isSynthetic()) - if(prob(5)) - take_overall_damage(0, 5 * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns") - if(prob(1)) - to_chat(src, span_warning("You feel strange!")) - adjustCloneLoss(5 * RADIATION_SPEED_COEFFICIENT) - emote("gasp") - - if (radiation > species.rad_levels["danger_3"]) - damage = 6 - radiation -= 4 * rad_mult - - if(damage) - damage *= species.radiation_mod - adjustToxLoss(damage * RADIATION_SPEED_COEFFICIENT) - updatehealth() - if(!isSynthetic() && organs.len) - var/obj/item/organ/external/O = pick(organs) - if(istype(O)) O.add_autopsy_data("Radiation Poisoning", damage) diff --git a/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm b/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm index 6e08101676..ae99925009 100644 --- a/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm +++ b/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm @@ -507,7 +507,7 @@ H.health = H.maxHealth -/datum/species/shadekin/produceCopy(var/list/traits, var/mob/living/carbon/human/H, var/custom_base, var/reset_dna = TRUE) +/datum/species/shadekin/produceCopy(var/list/traits, var/mob/living/carbon/human/H, var/custom_base, var/reset_dna = TRUE) // Traitgenes reset_dna flag required, or genes get reset on resleeve var/datum/species/shadekin/new_copy = ..() diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 387ab8c8aa..2bfab76ce4 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -18,9 +18,6 @@ var/fire_icon_state = "humanoid" // The icon_state used inside OnFire.dmi for when on fire. var/suit_storage_icon = 'icons/inventory/suit_store/mob.dmi' // Icons used for worn items in suit storage slot. - var/pixel_offset_x = 0 // CHOMPedit. Used for offsetting 64x64 and up icons. - var/pixel_offset_y = 0 // CHOMPedit. Used for offsetting 64x64 and up icons. - // Damage overlay and masks. var/damage_overlays = 'icons/mob/human_races/masks/dam_human.dmi' var/damage_mask = 'icons/mob/human_races/masks/dam_mask_human.dmi' @@ -254,6 +251,18 @@ var/gluttonous // Can eat some mobs. 1 for mice, 2 for monkeys, 3 for people. var/soft_landing = FALSE // Can fall down and land safely on small falls. + var/drippy = FALSE // If we drip or not. Primarily for goo beings. + var/photosynthesizing = FALSE // If we get nutrition from light or not. + var/shrinks = FALSE // If we shrink when we have no nutrition. Not added but here for downstream's sake. + var/grows = FALSE // Same as above but if we grow when >1000 nutrition. + var/crit_mod = 1 // Used for when we go unconscious. Used downstream. + var/list/env_traits = list() + var/pixel_offset_x = 0 // Used for offsetting 64x64 and up icons. + var/pixel_offset_y = 0 // Used for offsetting 64x64 and up icons. + var/rad_levels = list("safe" = 50, "danger_1" = 100, "danger_2" = 300, "danger_3" = 400, "danger_4" = 1500) //For handle_mutations_and_radiation + var/rad_removal_mod = 1 + + var/rarity_value = 1 // Relative rarity/collector value for this species. var/economic_modifier = 2 // How much money this species makes diff --git a/code/modules/mob/living/carbon/human/species/species_shapeshift.dm b/code/modules/mob/living/carbon/human/species/species_shapeshift.dm index 69ff16c26b..bf80064540 100644 --- a/code/modules/mob/living/carbon/human/species/species_shapeshift.dm +++ b/code/modules/mob/living/carbon/human/species/species_shapeshift.dm @@ -12,7 +12,6 @@ var/list/wrapped_species_by_ref = list() ) var/list/valid_transform_species = list() - var/monochromatic //var/default_form = SPECIES_HUMAN //VOREStation edit /datum/species/shapeshifter/get_valid_shapeshifter_forms(var/mob/living/carbon/human/H) @@ -64,13 +63,6 @@ var/list/wrapped_species_by_ref = list() /datum/species/shapeshifter/handle_post_spawn(var/mob/living/carbon/human/H) ..() wrapped_species_by_ref["\ref[H]"] = base_species //VOREStation edit - if(monochromatic) - H.r_hair = H.r_skin - H.g_hair = H.g_skin - H.b_hair = H.b_skin - H.r_facial = H.r_skin - H.g_facial = H.g_skin - H.b_facial = H.b_skin for(var/obj/item/organ/external/E in H.organs) E.sync_colour_to_human(H) @@ -193,14 +185,6 @@ var/list/wrapped_species_by_ref = list() g_synth = g_skin b_synth = b_skin - var/datum/species/shapeshifter/S = species - if(S.monochromatic) - r_hair = r_skin - g_hair = g_skin - b_hair = b_skin - r_facial = r_skin - g_facial = g_skin - b_facial = b_skin for(var/obj/item/organ/external/E in organs) E.sync_colour_to_human(src) diff --git a/code/modules/mob/living/carbon/human/species/species_shapeshift_vr.dm b/code/modules/mob/living/carbon/human/species/species_shapeshift_vr.dm index 9c55b9769e..ca1657bf85 100644 --- a/code/modules/mob/living/carbon/human/species/species_shapeshift_vr.dm +++ b/code/modules/mob/living/carbon/human/species/species_shapeshift_vr.dm @@ -280,7 +280,7 @@ else to_chat(character, span_notice("You need to be aggressively grabbing someone before you can copy their form.")) return - if (!istype(victim)) + if (!ishuman(victim)) to_chat(character, span_warning("You can only perform this on human mobs!")) return if (!victim.client) diff --git a/code/modules/mob/living/carbon/human/species/species_vr.dm b/code/modules/mob/living/carbon/human/species/species_vr.dm index ec8b745941..1433564c55 100644 --- a/code/modules/mob/living/carbon/human/species/species_vr.dm +++ b/code/modules/mob/living/carbon/human/species/species_vr.dm @@ -72,7 +72,7 @@ else ..() -/datum/species/proc/produceCopy(var/list/traits, var/mob/living/carbon/human/H, var/custom_base, var/reset_dna = TRUE) +/datum/species/proc/produceCopy(var/list/traits, var/mob/living/carbon/human/H, var/custom_base, var/reset_dna = TRUE) // Traitgenes reset_dna flag required, or genes get reset on resleeve ASSERT(src) ASSERT(istype(H)) var/datum/species/new_copy = new src.type() diff --git a/code/modules/mob/living/carbon/human/species/station/monkey.dm b/code/modules/mob/living/carbon/human/species/station/monkey.dm index bdcae75dc7..5819b10aca 100644 --- a/code/modules/mob/living/carbon/human/species/station/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/station/monkey.dm @@ -60,22 +60,45 @@ /datum/species/monkey/handle_npc(var/mob/living/carbon/human/H) if(H.stat != CONSCIOUS) return - if(prob(33) && H.canmove && isturf(H.loc) && !H.pulledby) //won't move if being pulled - step(H, pick(cardinal)) - if(prob(1)) - H.emote(pick("scratch","jump","roll","tail")) + // Traitgenes Monkeys perform emotes based on their traits + if(H.canmove && isturf(H.loc) && !H.pulledby) //won't move if being pulled + if(prob(33)) + step(H, pick(cardinal)) + if(prob(5)) + // Handle generic gene expression emotes + if(!H.species || !H.species.traits || H.species.traits.len == 0) + H.emote(pick("scratch","jump","roll","tail")) // fallbacks + else + var/datum/trait/T = all_traits[pick(H.species.traits)] + if(T) + var/geneexpression + if(T.primitive_expression_messages.len) + geneexpression = pick(T.primitive_expression_messages) + if(geneexpression) + H.custom_emote(VISIBLE_MESSAGE, "[geneexpression]") + else + H.emote(pick("scratch","jump","roll","tail")) + // More... intense, expressions... + if(prob(5) && H.mutations.len) + if((LASER in H.mutations)) + // zappy monkeys + var/list/targs = list() + for(var/atom/X in orange(7, H)) + targs.Add(X) + if(targs.len) + H.LaserEyes(pick(targs)) ..() /datum/species/monkey/get_random_name() return "[lowertext(name)] ([rand(100,999)])" -/datum/species/monkey/handle_post_spawn(var/mob/living/carbon/human/H)//CHOMPadd begin +/datum/species/monkey/handle_post_spawn(var/mob/living/carbon/human/H) if(!H.ckey) H.can_be_drop_prey = TRUE H.digest_leave_remains = 1 H.low_priority = TRUE - return ..()//CHOMPadd end + return ..() /datum/species/monkey/tajaran name = SPECIES_MONKEY_TAJ diff --git a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_rig.dm b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_rig.dm index 6f5b28bebf..762ece39cb 100644 --- a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_rig.dm +++ b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_rig.dm @@ -60,8 +60,12 @@ /obj/item/rig/protean/Destroy() if(myprotean) var/mob/living/carbon/human/P = myprotean - var/datum/species/protean/S = P?.species - S?.OurRig = null + if(!ishuman(P) && isprotblob(myprotean)) + var/mob/living/simple_mob/protean_blob/blob = myprotean + P = blob.humanform + if(ishuman(P)) + var/datum/species/protean/S = P?.species + S?.OurRig = null myprotean = null . = ..() diff --git a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm index 80efbaa726..465d38ed55 100755 --- a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm +++ b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm @@ -119,8 +119,6 @@ var/global/list/abilities = list() - var/monochromatic = FALSE //IGNORE ME - var/blob_appearance = "puddle1" var/blob_color_1 = "#363636" var/blob_color_2 = "#ba3636" diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm index 1fae0f21ca..aed506ebc6 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm @@ -32,6 +32,12 @@ var_changes = list("item_slowdown_mod" = 2.0) custom_only = FALSE banned_species = list(SPECIES_TESHARI) //These are already this weak. + //Traitgenes + is_genetrait = TRUE + hidden = FALSE + + activation_message="Everything feels so much heavier" + primitive_expression_messages=list("hunches forwards") /datum/trait/negative/endurance_low name = "Low Endurance" @@ -112,6 +118,13 @@ custom_only = FALSE varchange_type = TRAIT_VARCHANGE_LESS_BETTER + //Traitgenes + is_genetrait = TRUE + hidden = FALSE + + activation_message="You recieve a sudden shock of static." + primitive_expression_messages=list("shudders as their hair stands on end") + /datum/trait/negative/haemophilia name = "Haemophilia" // CHOMPEdit: Trait List Organization desc = "When you bleed, you bleed a LOT. Double the bloodloss rate." // CHOMPEdit: More Trait Feedback for players. @@ -140,6 +153,13 @@ excludes = list(/datum/trait/negative/lightweight_light) //CHOMPedit Added a lesser version of this trait custom_only = FALSE + //Traitgenes + is_genetrait = TRUE + hidden = FALSE + + activation_message="You feel off balance..." + primitive_expression_messages=list("staggers") + /datum/trait/negative/neural_hypersensitivity name = "Neural Hypersensitivity" desc = "Your nerves are particularly sensitive to physical changes, leading to experiencing twice the intensity of pain and pleasure alike. Makes all pain effects twice as strong, and occur at half as much damage." @@ -152,6 +172,13 @@ cost = -2 can_take = ORGANICS + //Traitgenes + is_genetrait = TRUE + hidden = FALSE + + activation_message="You feel like breathing is more difficult..." + primitive_expression_messages=list("gasps") + /datum/trait/negative/breathes/phoron name = "Phoron Breather" desc = "You breathe phoron instead of oxygen (which is poisonous to you), much like a Vox." @@ -162,6 +189,7 @@ desc = "You breathe nitrogen instead of oxygen (which is poisonous to you). Incidentally, phoron isn't poisonous to breathe to you." var_changes = list("breath_type" = GAS_N2, "poison_type" = GAS_O2, "ideal_air_type" = /datum/gas_mixture/belly_air/nitrogen_breather) + /datum/trait/negative/monolingual name = "Monolingual" desc = "You are not good at learning languages." @@ -179,7 +207,13 @@ custom_only = FALSE varchange_type = TRAIT_VARCHANGE_MORE_BETTER -/* // CHOMPedit: commented out because we disabled baymiss so this does nothing. + //Traitgenes + is_genetrait = TRUE + hidden = FALSE + + activation_message="The dark seems darker than usual." + primitive_expression_messages=list("looks towards the light") + /datum/trait/negative/bad_shooter name = "Bad Shot" desc = "You are terrible at aiming." @@ -187,7 +221,13 @@ var_changes = list("gun_accuracy_mod" = -35) custom_only = FALSE varchange_type = TRAIT_VARCHANGE_MORE_BETTER -*/ + + //Traitgenes + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your hands quiver" + primitive_expression_messages=list("hands quiver uncontrollably") /datum/trait/negative/bad_swimmer name = "Bad Swimmer" @@ -198,6 +238,466 @@ varchange_type = TRAIT_VARCHANGE_LESS_BETTER excludes = list(/datum/trait/positive/good_swimmer) +/datum/trait/negative/less_blood + name = "Low Blood Volume" + desc = "You have 33.3% less blood volume compared to most species, making you more prone to blood loss issues." + cost = -3 + var_changes = list("blood_volume" = 375) + excludes = list(/datum/trait/negative/less_blood_extreme) + can_take = ORGANICS + +/datum/trait/negative/less_blood_extreme + name = "Low Blood Volume, Extreme" + desc = "You have 60% less blood volume compared to most species, making you much more prone to blood loss issues." + cost = -5 + var_changes = list("blood_volume" = 224) + excludes = list(/datum/trait/negative/less_blood) + can_take = ORGANICS + +/datum/trait/negative/extreme_slowdown + name = "Slowdown, Extreme" + desc = "You move EXTREMELY slower than baseline" + cost = -8 + var_changes = list("slowdown" = 4.0) + + //Traitgenes + is_genetrait = TRUE + hidden = FALSE + + activation_message="You feel like moving is more difficult..." + primitive_expression_messages=list("moves sluggishly") + +/datum/trait/negative/low_blood_sugar + name = "Low Blood Sugar" + desc = "If you let your nutrition get too low, you will start to experience adverse affects including hallucinations, unconsciousness, and weakness" + cost = -1 + special_env = TRUE + + // Traitgenes Made into a gene trait + is_genetrait = TRUE + hidden = FALSE + + activation_message="You feel drowsy..." + primitive_expression_messages=list("looks drowsy") + +/datum/trait/negative/low_blood_sugar/handle_environment_special(var/mob/living/carbon/human/H) + if(H.nutrition > 200) //Sanity check because stupid bugs >:v + return + if((H.nutrition < 200) && prob(5)) + if(H.nutrition > 100) + to_chat(H,span_warning("You start to feel noticeably weak as your stomach rumbles, begging for more food. Maybe you should eat something to keep your blood sugar up")) + else if(H.nutrition > 50) + to_chat(H,span_warning("You begin to feel rather weak, and your stomach rumbles loudly. You feel lightheaded and it's getting harder to think. You really need to eat something.")) + else if(H.nutrition > 25) + to_chat(H,span_danger("You're feeling very weak and lightheaded, and your stomach continously rumbles at you. You really need to eat something!")) + else + to_chat(H,span_critical("You're feeling extremely weak and lightheaded. You feel as though you might pass out any moment and your stomach is screaming for food by now! You should really find something to eat!")) + if((H.nutrition < 100) && prob(10)) + H.Confuse(10) + if((H.nutrition < 50) && prob(25)) + H.hallucination = max(30,H.hallucination+8) + if((H.nutrition < 25) && prob(5)) + H.drowsyness = max(100,H.drowsyness+30) + + +/datum/trait/negative/blindness + name = "Permanently blind" + desc = "You are blind. For whatever reason, nothing is able to change this fact, not even surgery. WARNING: YOU WILL NOT BE ABLE TO SEE ANY POSTS USING THE ME VERB, ONLY SUBTLE AND DIALOGUE ARE VIEWABLE TO YOU, YOU HAVE BEEN WARNED." + cost = -12 + special_env = TRUE + custom_only = FALSE + + // Traitgenes Replaces /datum/trait/negative/disability_blind, made into a gene trait + is_genetrait = TRUE + hidden = TRUE //Making this so people can't pick it in character select. While a blind character makes senese, not being able to see posts is a massive issue that needs to be addressed some other time. + + sdisability=BLIND + activation_message="You can't seem to see anything." + primitive_expression_messages=list("stumbles aimlessly.") + +/datum/trait/negative/blindness/handle_environment_special(var/mob/living/carbon/human/H) + H.sdisabilities |= sdisability //no matter what you do, the blindess still comes for you // Traitgenes tweaked to be consistant with other gene traits by using var + +/datum/trait/negative/agoraphobia + name = "Agoraphobia" + desc = "You very much dislike being in crowded places. When in the company of more than two other people, you start to panic and experience adverse effects." + cost = -3 + var/warning_cap = 400 + var/hallucination_cap = 25 + var/escalation_speed = 0.8 + special_env = TRUE + excludes = list(/datum/trait/negative/lonely,/datum/trait/negative/lonely/major) + + //Traitgenes + is_genetrait = TRUE + hidden = FALSE + + activation_message="You feel like you need some space" + primitive_expression_messages=list("keeps their distance from others") + +/datum/trait/negative/agoraphobia/handle_environment_special(var/mob/living/carbon/human/H) + spawn(0) + var/list/in_range = list() + // If they're dead or unconcious they're a bit beyond this kind of thing. + if(H.stat) + return + // No point processing if we're already stressing the hell out. + if(H.hallucination >= hallucination_cap && H.loneliness_stage >= warning_cap) + return + in_range |= check_mob_company(H,H) //Checks our item slots and bellies for any people. + in_range |= belly_check(H,H.loc) //Recursive check if we're in anyones bellies, are they in anyone's belly, etc. + in_range |= holder_check(H,H.loc) //Recursive check if someone's holding us, is anyone holding them, etc. + + // Check for company. + for(var/mob/living/M in viewers(get_turf(H))) + in_range |= check_mob_company(H,M) + + for(var/obj/effect/overlay/aiholo/A in range(5, H)) + in_range |= A + + if(in_range.len > 2) + if(H.loneliness_stage < warning_cap) + H.loneliness_stage = min(warning_cap,H.loneliness_stage+escalation_speed) + handle_loneliness(H) + if(H.loneliness_stage >= warning_cap && H.hallucination < hallucination_cap) + H.hallucination = min(hallucination_cap,H.hallucination+2.5*escalation_speed) + else + H.loneliness_stage = max(H.loneliness_stage-4,0) + + +/datum/trait/negative/agoraphobia/proc/handle_loneliness(var/mob/living/carbon/human/H) + if(world.time < H.next_loneliness_time) + return //Moved this at the top so we dont waste time assigning vars we will never use + var/ms = handle_loneliness_message(H) + if(ms) + to_chat(H, ms) + H.next_loneliness_time = world.time+500 + H.fear = min((H.fear + 3), 102) + +/datum/trait/negative/agoraphobia/proc/handle_loneliness_message(var/mob/living/carbon/human/H) + var/Lonely = H.loneliness_stage + if(Lonely == escalation_speed) + return "You notice there's more people than you feel comfortable with around you..." + else if(Lonely >= 50 && Lonely < 250) + return "You start to feel anxious from the number of people around you." + else if(Lonely >= 250 && Lonely < warning_cap) + if(H.stuttering < hallucination_cap) + H.stuttering += 5 + return "[pick("You don't think you can last much longer with this much company!", "You should go find some space!")]" //if we add more here make it a list for readability + else if(Lonely >= warning_cap) + var/list/panicmessages = list( "Why am I still here? I have to leave and get some space!", + "Please, just let me be alone!", + "I need to be alone!") + return span_bolddanger("[pick(panicmessages)]") + return FALSE + +/datum/trait/negative/agoraphobia/proc/find_held_by(var/atom/item) + if(!item || !istype(item)) + return null + else if(istype(item,/mob/living)) + return item + else + return find_held_by(item.loc) + +/datum/trait/negative/agoraphobia/proc/holder_check(var/mob/living/carbon/human/H,var/obj/item/holder/H_holder) + var/list/in_range = list() + if(istype(H_holder)) + var/mob/living/held_by = find_held_by(H_holder) + if(held_by) + in_range |= check_mob_company(H,held_by,FALSE) + in_range |= holder_check(H,held_by) + return in_range + +/datum/trait/negative/agoraphobia/proc/belly_check(var/mob/living/carbon/human/H,var/obj/belly/B) + var/list/in_range = list() + if(istype(B)) + in_range |= check_mob_company(H,B.owner,FALSE) + if(isbelly(B.owner.loc)) + in_range |= belly_check(H,B.owner.loc) + return in_range + +/datum/trait/negative/agoraphobia/proc/check_mob_company(var/mob/living/carbon/human/H,var/mob/living/M,var/invis_matters = TRUE) + var/list/in_range = list() + if(!istype(M)) + return in_range + var/social_check = !istype(M, /mob/living/carbon) && !istype(M, /mob/living/silicon/robot) + var/ckey_check = !M.ckey + var/overall_checks = M == H || M.stat == DEAD || social_check || ckey_check + if(invis_matters && M.invisibility > H.see_invisible) + return in_range + if(!overall_checks) + in_range |= M + in_range |= check_contents(M,H) + return in_range + +/datum/trait/negative/agoraphobia/proc/check_contents(var/atom/item,var/mob/living/carbon/human/H,var/max_layer = 3,var/current_layer = 1) + var/list/in_range = list() + if(!item || !istype(item) || current_layer > max_layer) + return in_range + for(var/datum/content in item.contents) + if(istype(content,/obj/item/holder)) + var/obj/item/holder/contentholder = content + in_range |= check_mob_company(H,contentholder.held_mob) + else + in_range |= check_contents(content,H,max_layer,current_layer+1) + return in_range + +/datum/trait/negative/lonely + name = "Minor loneliness vulnerability" + desc = "You're very prone to loneliness! Being alone for extended periods of time causes adverse effects. Most mobs will cure this loneliness as long as they aren't hostile." + cost = -1 + var/warning_cap = 400 + var/only_people = FALSE + var/hallucination_cap = 25 + var/escalation_speed = 0.8 + special_env = TRUE + excludes = list(/datum/trait/negative/lonely/major,/datum/trait/negative/agoraphobia) + +/datum/trait/negative/lonely/major + name = "Major loneliness vulnerability" + desc = "You're extremely prone to loneliness! Being alone for extended periods of time causes adverse effects. Most mobs won't be enough to cure this loneliness, you need other social beings." + cost = -3 + warning_cap = 300 + hallucination_cap = 50 + escalation_speed = 1.3 + only_people = TRUE + special_env = TRUE + excludes = list(/datum/trait/negative/lonely,/datum/trait/negative/agoraphobia) + + //Traitgenes + is_genetrait = TRUE + hidden = FALSE + + activation_message="You feel like you are in desperate need of company..." + primitive_expression_messages=list("Looks up at you pleadingly") + +/datum/trait/negative/lonely/proc/sub_loneliness(var/mob/living/carbon/human/H,var/amount = 4) + H.loneliness_stage = max(H.loneliness_stage - 4, 0) + if(world.time >= H.next_loneliness_time && H.loneliness_stage > 0) + to_chat(H, span_infoplain("The nearby company calms you down...")) + H.next_loneliness_time = world.time+500 + +/datum/trait/negative/lonely/proc/check_mob_company(var/mob/living/carbon/human/H,var/mob/living/M) + if(!istype(M)) + return 0 + var/social_check = only_people && !istype(M, /mob/living/carbon) && !istype(M, /mob/living/silicon/robot) + var/self_invisible_check = M == H || M.invisibility > H.see_invisible + var/ckey_check = only_people && !M.ckey + var/overall_checks = M.stat == DEAD || social_check || ckey_check + if(self_invisible_check) + return 0 + if((M.faction == "neutral" || M.faction == H.faction) && !overall_checks) + sub_loneliness(H) + return 1 + else + if(M.vore_organs) + for(var/obj/belly/B in M.vore_organs) + for(var/mob/living/content in B.contents) + if(istype(content)) + check_mob_company(H,content) + return 0 + +/datum/trait/negative/lonely/proc/check_contents(var/atom/item,var/mob/living/carbon/human/H,var/max_layer = 3,var/current_layer = 1) + if(!item || !istype(item) || current_layer > max_layer) + return 0 + for(var/datum/content in item.contents) + if(istype(content,/obj/item/holder)) + var/obj/item/holder/contentholder = content + if(check_mob_company(H,contentholder.held_mob)) + return 1 + else + if(check_contents(content,H,max_layer,current_layer+1)) + return 1 + return 0 + +/datum/trait/negative/lonely/handle_environment_special(var/mob/living/carbon/human/H) + spawn(0) + // If they're dead or unconcious they're a bit beyond this kind of thing. + if(H.stat) + return + // No point processing if we're already stressing the hell out. + if(H.hallucination >= hallucination_cap && H.loneliness_stage >= warning_cap) + return + + // Outpost 21 addition begin - extended loneliness mechanics + if(H.mind && H.mind.changeling) // We are never alone~ + H.loneliness_stage = 0 + return + if(H.has_brain_worms()) // Brain friends! + sub_loneliness(H) + return + // Outpost 21 addition end + + // Vored? Not gonna get frightened. + if(isbelly(H.loc)) + sub_loneliness(H) + return + if(istype(H.loc, /obj/item/holder)) + sub_loneliness(H) + return + // Check for company. + if(check_contents(H,H)) //Check our item slots and storage for any micros. + sub_loneliness(H) + return + for(var/mob/living/M in viewers(get_turf(H))) + if(check_mob_company(H,M)) + return + //Check to see if there's anyone in our belly + if(H.vore_organs) + for(var/obj/belly/B in H.vore_organs) + for(var/mob/living/content in B.contents) + if(istype(content)) + if(check_mob_company(H,content)) + return + for(var/obj/item/holder/micro/M in range(1, H)) + sub_loneliness(H) + for(var/obj/effect/overlay/aiholo/A in range(5, H)) + sub_loneliness(H) + + for(var/obj/item/toy/plushie/teshari/P in range(5, H)) + sub_loneliness(H) + + // No company? Suffer :( + if(H.loneliness_stage < warning_cap) + H.loneliness_stage = min(warning_cap,H.loneliness_stage+escalation_speed) + handle_loneliness(H) + if(H.loneliness_stage >= warning_cap && H.hallucination < hallucination_cap) + H.hallucination = min(hallucination_cap,H.hallucination+2.5*escalation_speed) + +/datum/trait/negative/lonely/proc/handle_loneliness(var/mob/living/carbon/human/H) + var/ms = "" + if(H.loneliness_stage == escalation_speed) + ms = "[pick("Well.. No one is around you anymore...","Well.. You're alone now...","You suddenly feel alone...")]" // Outpost 21 edit - More variety + if(H.loneliness_stage >= 50) + ms = "[pick("You begin to feel alone...","You feel isolated...","You need company...","Where is everyone?...","You need to find someone...")]" // Outpost 21 edit - More variety + if(H.loneliness_stage >= 250) + ms = "[pick("You don't think you can last much longer without some visible company!", "You should go find someone to be with!","You need to find company!","Find someone to be with!")]" // Outpost 21 edit - More variety + if(H.stuttering < hallucination_cap) + H.stuttering += 5 + if(H.loneliness_stage >= warning_cap) + ms = span_danger(span_bold("[pick("Where are the others?", "Please, there has to be someone nearby!", "I don't want to be alone!","Please, anyone! I don't want to be alone!")]")) // Outpost 21 edit - More variety + if(world.time < H.next_loneliness_time) + return + if(ms != "") + to_chat(H, ms) + H.next_loneliness_time = world.time+500 + H.fear = min((H.fear + 3), 102) + + +/datum/trait/negative/endurance_glass // Glass Cannon + name = "Glass Endurance" + desc = "Your body is very fragile. Reduces your maximum hitpoints to 25. Beware sneezes. You require only 50 damage in total to die, compared to 200 normally. You will go into crit after losing 25 HP, compared to crit at 100 HP." + cost = -12 // Similar to Very Low Endurance, this straight up will require you NEVER getting in a fight. This is extremely crippling. I salute the madlad that takes this. + var_changes = list("total_health" = 25) + +/datum/trait/negative/endurance_glass/apply(var/datum/species/S,var/mob/living/carbon/human/H) + ..() + H.setMaxHealth(S.total_health) + +/datum/trait/negative/endurance_glass // Glass Cannon + name = "Glass Endurance" + desc = "Your body is very fragile. Reduces your maximum hitpoints to 25. Beware sneezes. You require only 50 damage in total to die, compared to 200 normally. You will go into crit after losing 25 HP, compared to crit at 100 HP." + cost = -12 // Similar to Very Low Endurance, this straight up will require you NEVER getting in a fight. This is extremely crippling. I salute the madlad that takes this. + var_changes = list("total_health" = 25) + +/datum/trait/negative/endurance_glass/apply(var/datum/species/S,var/mob/living/carbon/human/H) + ..() + H.setMaxHealth(S.total_health) + +/datum/trait/negative/reduced_biocompat_minor + name = "Reduced Biocompatibility, Minor" + desc = "For whatever reason, you're one of the unlucky few who don't get as much benefit from modern-day chemicals. Remember to note this down in your medical records! Chems are only 80% as effective on you!" + cost = -2 + var_changes = list("chem_strength_heal" = 0.8) + can_take = ORGANICS + +/datum/trait/negative/reduced_biocompat + name = "Reduced Biocompatibility" + desc = "For whatever reason, you're one of the unlucky few who don't get as much benefit from modern-day chemicals. Remember to note this down in your medical records! Chems are only 60% as effective on you!" + cost = -4 + var_changes = list("chem_strength_heal" = 0.6) + can_take = ORGANICS + +/datum/trait/negative/reduced_biocompat_extreme + name = "Reduced Biocompatibility, Major" + desc = "For whatever reason, you're one of the unlucky few who don't get as much benefit from modern-day chemicals. Remember to note this down in your medical records! Chems are only 30% as effective on you!" + cost = -8 + var_changes = list("chem_strength_heal" = 0.3) + can_take = ORGANICS + + //Traitgenes + is_genetrait = TRUE + hidden = FALSE + + activation_message="You feel no different" + primitive_expression_messages=list("blinks") + +// Rykkanote: Relocated these here as we're no longer a YW downstream. +/datum/trait/negative/light_sensitivity + name = "Photosensitivity" + desc = "You have trouble dealing with sudden flashes of light, taking some time for you to recover. The effects of flashes from cameras and security equipment leaves you stunned for some time. 50% increased stun duration from flashes." + cost = -1 + var_changes = list("flash_mod" = 1.5) + +/datum/trait/negative/light_sensitivity_plus + name = "Photosensitivity, Major" + desc = "You have trouble dealing with sudden flashes of light, taking quite a long time for you to be able to recover. The effects of flashes from cameras and security equipment leave you stunned for some time. 100% (2x) stun duration from flashes." + cost = -2 + var_changes = list("flash_mod" = 2.0) + + //Traitgenes + is_genetrait = TRUE + hidden = FALSE + + activation_message="Lights feel painful to look at..." + primitive_expression_messages=list("holds a hand up to their eyes") + +/datum/trait/negative/haemophilia_plus + name = "Haemophilia, Major" + desc = "Some say that when it rains, it pours. Unfortunately, this is also true for yourself if you get cut. You bleed much faster than average, at 3x the normal rate." + cost = -3 + can_take = ORGANICS + + activation_message="You feel " + primitive_expression_messages=list("bumps their toe, screaming in pain") + +/datum/trait/negative/haemophilia_plus/apply(var/datum/species/S,var/mob/living/carbon/human/H) + ..() + H.add_modifier(/datum/modifier/trait/haemophilia) + +/datum/trait/negative/haemophilia_plus/unapply(var/datum/species/S,var/mob/living/carbon/human/H) + ..() + H.remove_modifiers_of_type(/datum/modifier/trait/haemophilia) + +/datum/trait/negative/pain_intolerance_basic + name = "Pain Intolerance" + desc = "You are frail and sensitive to pain. You experience 25% more pain from all sources." + cost = -2 + var_changes = list("pain_mod" = 1.2) + +/datum/trait/negative/pain_intolerance_advanced + name = "Pain Intolerance, Major" + desc = "You are highly sensitive to all sources of pain, and experience 50% more pain." + cost = -3 + var_changes = list("pain_mod" = 1.5) //this makes you extremely vulnerable to most sources of pain, a stunbaton bop or shotgun beanbag will do around 90 agony, almost enough to drop you in one hit. + + //Traitgenes + is_genetrait = TRUE + hidden = FALSE + + activation_message="You feel as though the airflow around you is painful..." + primitive_expression_messages=list("bumps their toe, screaming in pain") + +/datum/trait/negative/sensitive_biochem + name = "Sensitive Biochemistry" + desc = "Your biochemistry is a little delicate, rendering you more susceptible to both deadly toxins and the more subtle ones. You'll probably want to list this in your medical records, and perhaps in your exploitable info as well. Toxin damages and knockout drugs are 25% stronger on you." + cost = -1 + var_changes = list("chem_strength_tox" = 1.25) + + //Traitgenes + is_genetrait = TRUE + hidden = FALSE + /datum/trait/negative/slipperydirt name = "Dirt Vulnerability" desc = "Even the tiniest particles of dirt give you uneasy footing, even through several layers of footwear." diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/negative_ch.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/negative_ch.dm index 2d0d5c4151..b772385527 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/negative_ch.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/negative_ch.dm @@ -1,79 +1,18 @@ -#ifndef GAUSSIAN_RANDOM -#define GAUSSIAN_RANDOM(vars...) ((-2*log(rand()))**0.5 * cos(6.28318530718*rand())) -#endif - /datum/trait/negative/hollow excludes = list(/datum/trait/positive/densebones) -/datum/trait/negative/less_blood - name = "Low Blood Volume" - desc = "You have 33.3% less blood volume compared to most species, making you more prone to blood loss issues." - cost = -3 - var_changes = list("blood_volume" = 375) - excludes = list(/datum/trait/negative/less_blood_extreme,/datum/trait/positive/more_blood,/datum/trait/positive/more_blood_extreme) - can_take = ORGANICS - -/datum/trait/negative/less_blood_extreme - name = "Low Blood Volume, Extreme" - desc = "You have 60% less blood volume compared to most species, making you much more prone to blood loss issues." - cost = -5 - var_changes = list("blood_volume" = 224) - excludes = list(/datum/trait/negative/less_blood,/datum/trait/positive/more_blood,/datum/trait/positive/more_blood_extreme) - can_take = ORGANICS - /datum/trait/negative/scrawny name = "Scrawny" desc = "You have a much harder time breaking free of grabs as well as creating and holding onto grabs on other people." cost = -2 var_changes = list("grab_resist_divisor_victims" = 0.5, "grab_resist_divisor_self" = 3, "grab_power_victims" = 1, "grab_power_self" = -1) -/datum/trait/negative/extreme_slowdown - name = "Slowdown, Extreme" - desc = "You move EXTREMELY slower than baseline" - cost = -8 - var_changes = list("slowdown" = 4.0) - /datum/trait/negative/deep_sleeper name = "Deep Sleeper" desc = "When you fall asleep, it takes you four times as long to wake up." cost = -1 var_changes = list("waking_speed" = 0.25) -/datum/trait/negative/low_blood_sugar - name = "Low Blood Sugar" - desc = "If you let your nutrition get too low, you will start to experience adverse affects including hallucinations, unconsciousness, and weakness" - cost = -1 - special_env = TRUE - -/datum/trait/negative/low_blood_sugar/handle_environment_special(var/mob/living/carbon/human/H) - if(H.nutrition > 200) //Sanity check because stupid bugs >:v - return - if((H.nutrition < 200) && prob(5)) - if(H.nutrition > 100) - to_chat(H,span_warning("You start to feel noticeably weak as your stomach rumbles, begging for more food. Maybe you should eat something to keep your blood sugar up")) - else if(H.nutrition > 50) - to_chat(H,span_warning("You begin to feel rather weak, and your stomach rumbles loudly. You feel lightheaded and it's getting harder to think. You really need to eat something.")) - else if(H.nutrition > 25) - to_chat(H,span_danger("You're feeling very weak and lightheaded, and your stomach continously rumbles at you. You really need to eat something!")) - else - to_chat(H,span_critical("You're feeling extremely weak and lightheaded. You feel as though you might pass out any moment and your stomach is screaming for food by now! You should really find something to eat!")) - if((H.nutrition < 100) && prob(10)) - H.Confuse(10) - if((H.nutrition < 50) && prob(25)) - H.hallucination = max(30,H.hallucination+8) - if((H.nutrition < 25) && prob(5)) - H.drowsyness = min(100,H.drowsyness+30) - -/datum/trait/negative/blindness - name = "Permanently blind" - desc = "You are blind. For whatever reason, nothing is able to change this fact, not even surgery. WARNING: YOU WILL NOT BE ABLE TO SEE ANY POSTS USING THE ME VERB, ONLY SUBTLE AND DIALOGUE ARE VIEWABLE TO YOU, YOU HAVE BEEN WARNED." - cost = -12 - special_env = TRUE - custom_only = FALSE - -/datum/trait/negative/blindness/handle_environment_special(var/mob/living/carbon/human/H) - H.sdisabilities |= BLIND //no matter what you do, the blindess still comes for you - /datum/trait/negative/schizophrenia name = "Episodic hallucinations." desc = "You have a condition which causes you to spontaneously have hallucinations! Luckily for you, in the modern space age, our doctors have solutions for you, just make sure you don't forget to take your pills." @@ -137,321 +76,3 @@ if(istype(reagent,/datum/reagent/tercozolam)) total_vol += reagent.volume return total_vol -/datum/trait/negative/agoraphobia - name = "Agoraphobia" - desc = "You very much dislike being in crowded places. When in the company of more than two other people, you start to panic and experience adverse effects." - cost = -3 - var/warning_cap = 400 - var/hallucination_cap = 25 - var/escalation_speed = 0.8 - special_env = TRUE - excludes = list(/datum/trait/negative/lonely,/datum/trait/negative/lonely/major) - -/datum/trait/negative/agoraphobia/handle_environment_special(var/mob/living/carbon/human/H) - spawn(0) - var/list/in_range = list() - // If they're dead or unconcious they're a bit beyond this kind of thing. - if(H.stat) - return - // No point processing if we're already stressing the hell out. - if(H.hallucination >= hallucination_cap && H.loneliness_stage >= warning_cap) - return - in_range |= check_mob_company(H,H) //Checks our item slots and bellies for any people. - in_range |= belly_check(H,H.loc) //Recursive check if we're in anyones bellies, are they in anyone's belly, etc. - in_range |= holder_check(H,H.loc) //Recursive check if someone's holding us, is anyone holding them, etc. - - // Check for company. - for(var/mob/living/M in viewers(get_turf(H))) - in_range |= check_mob_company(H,M) - - for(var/obj/effect/overlay/aiholo/A in range(5, H)) - in_range |= A - - if(in_range.len > 2) - if(H.loneliness_stage < warning_cap) - H.loneliness_stage = min(warning_cap,H.loneliness_stage+escalation_speed) - handle_loneliness(H) - if(H.loneliness_stage >= warning_cap && H.hallucination < hallucination_cap) - H.hallucination = min(hallucination_cap,H.hallucination+2.5*escalation_speed) - else - H.loneliness_stage = max(H.loneliness_stage-4,0) - - -/datum/trait/negative/agoraphobia/proc/handle_loneliness(var/mob/living/carbon/human/H) - if(world.time < H.next_loneliness_time) - return //Moved this at the top so we dont waste time assigning vars we will never use - var/ms = handle_loneliness_message(H) - if(ms) - to_chat(H, ms) - H.next_loneliness_time = world.time+500 - H.fear = min((H.fear + 3), 102) - -/datum/trait/negative/agoraphobia/proc/handle_loneliness_message(var/mob/living/carbon/human/H) - var/Lonely = H.loneliness_stage - if(Lonely == escalation_speed) - return "You notice there's more people than you feel comfortable with around you..." - else if(Lonely >= 50 && Lonely < 250) - return "You start to feel anxious from the number of people around you." - else if(Lonely >= 250 && Lonely < warning_cap) - if(H.stuttering < hallucination_cap) - H.stuttering += 5 - return "[pick("You don't think you can last much longer with this much company!", "You should go find some space!")]" //if we add more here make it a list for readability - else if(Lonely >= warning_cap) - var/list/panicmessages = list( "Why am I still here? I have to leave and get some space!", - "Please, just let me be alone!", - "I need to be alone!") - return span_bolddanger("[pick(panicmessages)]") - return FALSE - -/datum/trait/negative/agoraphobia/proc/find_held_by(var/atom/item) - if(!item || !istype(item)) - return null - else if(istype(item,/mob/living)) - return item - else - return find_held_by(item.loc) - -/datum/trait/negative/agoraphobia/proc/holder_check(var/mob/living/carbon/human/H,var/obj/item/holder/H_holder) - var/list/in_range = list() - if(istype(H_holder)) - var/mob/living/held_by = find_held_by(H_holder) - if(held_by) - in_range |= check_mob_company(H,held_by,FALSE) - in_range |= holder_check(H,held_by) - return in_range - -/datum/trait/negative/agoraphobia/proc/belly_check(var/mob/living/carbon/human/H,var/obj/belly/B) - var/list/in_range = list() - if(istype(B)) - in_range |= check_mob_company(H,B.owner,FALSE) - if(isbelly(B.owner.loc)) - in_range |= belly_check(H,B.owner.loc) - return in_range - -/datum/trait/negative/agoraphobia/proc/check_mob_company(var/mob/living/carbon/human/H,var/mob/living/M,var/invis_matters = TRUE) - var/list/in_range = list() - if(!istype(M)) - return in_range - var/social_check = !istype(M, /mob/living/carbon) && !istype(M, /mob/living/silicon/robot) - var/ckey_check = !M.ckey - var/overall_checks = M == H || M.stat == DEAD || social_check || ckey_check - if(invis_matters && M.invisibility > H.see_invisible) - return in_range - if(!overall_checks) - in_range |= M - if(M.vore_organs) - for(var/obj/belly/B in M.vore_organs) - for(var/mob/living/content in B.contents) - if(istype(content)) - in_range |= check_mob_company(H,content) - in_range |= check_contents(M,H) - return in_range - -/datum/trait/negative/agoraphobia/proc/check_contents(var/atom/item,var/mob/living/carbon/human/H,var/max_layer = 3,var/current_layer = 1) - var/list/in_range = list() - if(!item || !istype(item) || current_layer > max_layer) - return in_range - for(var/datum/content in item.contents) - if(istype(content,/obj/item/holder)) - var/obj/item/holder/contentholder = content - in_range |= check_mob_company(H,contentholder.held_mob) - else - in_range |= check_contents(content,H,max_layer,current_layer+1) - return in_range - -/datum/trait/negative/lonely - name = "Minor loneliness vulnerability" - desc = "You're very prone to loneliness! Being alone for extended periods of time causes adverse effects. Most mobs will cure this loneliness as long as they aren't hostile." - cost = -1 - var/warning_cap = 400 - var/only_people = FALSE - var/hallucination_cap = 25 - var/escalation_speed = 0.8 - special_env = TRUE - excludes = list(/datum/trait/negative/lonely/major,/datum/trait/negative/agoraphobia) - -/datum/trait/negative/lonely/major - name = "Major loneliness vulnerability" - desc = "You're extremely prone to loneliness! Being alone for extended periods of time causes adverse effects. Most mobs won't be enough to cure this loneliness, you need other social beings." - cost = -3 - warning_cap = 300 - hallucination_cap = 50 - escalation_speed = 1.3 - only_people = TRUE - special_env = TRUE - excludes = list(/datum/trait/negative/lonely,/datum/trait/negative/agoraphobia) - -/datum/trait/negative/lonely/proc/sub_loneliness(var/mob/living/carbon/human/H,var/amount = 4) - H.loneliness_stage = max(H.loneliness_stage - 4, 0) - if(world.time >= H.next_loneliness_time && H.loneliness_stage > 0) - to_chat(H, span_infoplain("The nearby company calms you down...")) - H.next_loneliness_time = world.time+500 - -/datum/trait/negative/lonely/proc/check_mob_company(var/mob/living/carbon/human/H,var/mob/living/M) - if(!istype(M)) - return 0 - var/social_check = only_people && !istype(M, /mob/living/carbon) && !istype(M, /mob/living/silicon/robot) - var/self_invisible_check = M == H || M.invisibility > H.see_invisible - var/ckey_check = only_people && !M.ckey - var/overall_checks = M.stat == DEAD || social_check || ckey_check - if(self_invisible_check) - return 0 - if((M.faction == "neutral" || M.faction == H.faction) && !overall_checks) - sub_loneliness(H) - return 1 - else - if(M.vore_organs) - for(var/obj/belly/B in M.vore_organs) - for(var/mob/living/content in B.contents) - if(istype(content)) - check_mob_company(H,content) - return 0 - -/datum/trait/negative/lonely/proc/check_contents(var/atom/item,var/mob/living/carbon/human/H,var/max_layer = 3,var/current_layer = 1) - if(!item || !istype(item) || current_layer > max_layer) - return 0 - for(var/datum/content in item.contents) - if(istype(content,/obj/item/holder)) - var/obj/item/holder/contentholder = content - if(check_mob_company(H,contentholder.held_mob)) - return 1 - else - if(check_contents(content,H,max_layer,current_layer+1)) - return 1 - return 0 - -/datum/trait/negative/lonely/handle_environment_special(var/mob/living/carbon/human/H) - spawn(0) - // If they're dead or unconcious they're a bit beyond this kind of thing. - if(H.stat) - return - // No point processing if we're already stressing the hell out. - if(H.hallucination >= hallucination_cap && H.loneliness_stage >= warning_cap) - return - // Vored? Not gonna get frightened. - if(isbelly(H.loc)) - sub_loneliness(H) - return - if(istype(H.loc, /obj/item/holder)) - sub_loneliness(H) - return - // Check for company. - if(check_contents(H,H)) //Check our item slots and storage for any micros. - sub_loneliness(H) - return - for(var/mob/living/M in viewers(get_turf(H))) - if(check_mob_company(H,M)) - return - //Check to see if there's anyone in our belly - if(H.vore_organs) - for(var/obj/belly/B in H.vore_organs) - for(var/mob/living/content in B.contents) - if(istype(content)) - if(check_mob_company(H,content)) - return - for(var/obj/item/holder/micro/M in range(1, H)) - sub_loneliness(H) - for(var/obj/effect/overlay/aiholo/A in range(5, H)) - sub_loneliness(H) - - // No company? Suffer :( - if(H.loneliness_stage < warning_cap) - H.loneliness_stage = min(warning_cap,H.loneliness_stage+escalation_speed) - handle_loneliness(H) - if(H.loneliness_stage >= warning_cap && H.hallucination < hallucination_cap) - H.hallucination = min(hallucination_cap,H.hallucination+2.5*escalation_speed) - -/datum/trait/negative/lonely/proc/handle_loneliness(var/mob/living/carbon/human/H) - var/ms = "" - if(H.loneliness_stage == escalation_speed) - ms = "Well.. No one is around you anymore..." - if(H.loneliness_stage >= 50) - ms = "You begin to feel alone..." - if(H.loneliness_stage >= 250) - ms = "[pick("You don't think you can last much longer without some visible company!", "You should go find someone!")]" - if(H.stuttering < hallucination_cap) - H.stuttering += 5 - if(H.loneliness_stage >= warning_cap) - ms = span_danger(span_bold("[pick("Where are the others?", "Please, there has to be someone nearby!", "I don't want to be alone!")]")) - if(world.time < H.next_loneliness_time) - return - if(ms != "") - to_chat(H, ms) - H.next_loneliness_time = world.time+500 - H.fear = min((H.fear + 3), 102) - -/datum/trait/negative/endurance_glass // Glass Cannon - name = "Glass Endurance" - desc = "Your body is very fragile. Reduces your maximum hitpoints to 25. Beware sneezes. You require only 50 damage in total to die, compared to 200 normally. You will go into crit after losing 25 HP, compared to crit at 100 HP." - cost = -12 // Similar to Very Low Endurance, this straight up will require you NEVER getting in a fight. This is extremely crippling. I salute the madlad that takes this. - var_changes = list("total_health" = 25) - -/datum/trait/negative/endurance_glass/apply(var/datum/species/S,var/mob/living/carbon/human/H) - ..() - H.setMaxHealth(S.total_health) - -/datum/trait/negative/reduced_biocompat_minor - name = "Reduced Biocompatibility, Minor" - desc = "For whatever reason, you're one of the unlucky few who don't get as much benefit from modern-day chemicals. Remember to note this down in your medical records! Chems are only 80% as effective on you!" - cost = -2 - var_changes = list("chem_strength_heal" = 0.8) - can_take = ORGANICS - -/datum/trait/negative/reduced_biocompat - name = "Reduced Biocompatibility" - desc = "For whatever reason, you're one of the unlucky few who don't get as much benefit from modern-day chemicals. Remember to note this down in your medical records! Chems are only 60% as effective on you!" - cost = -4 - var_changes = list("chem_strength_heal" = 0.6) - can_take = ORGANICS - -/datum/trait/negative/reduced_biocompat_extreme - name = "Reduced Biocompatibility, Major" - desc = "For whatever reason, you're one of the unlucky few who don't get as much benefit from modern-day chemicals. Remember to note this down in your medical records! Chems are only 30% as effective on you!" - cost = -8 - var_changes = list("chem_strength_heal" = 0.3) - can_take = ORGANICS - -// Rykkanote: Relocated these here as we're no longer a YW downstream. -/datum/trait/negative/light_sensitivity - name = "Photosensitivity" - desc = "You have trouble dealing with sudden flashes of light, taking some time for you to recover. The effects of flashes from cameras and security equipment leaves you stunned for some time. 50% increased stun duration from flashes." - cost = -1 - var_changes = list("flash_mod" = 1.5) - -/datum/trait/negative/light_sensitivity_plus - name = "Photosensitivity, Major" - desc = "You have trouble dealing with sudden flashes of light, taking quite a long time for you to be able to recover. The effects of flashes from cameras and security equipment leave you stunned for some time. 100% (2x) stun duration from flashes." - cost = -2 - var_changes = list("flash_mod" = 2.0) - - -/datum/trait/negative/haemophilia_plus - name = "Haemophilia, Major" - desc = "Some say that when it rains, it pours. Unfortunately, this is also true for yourself if you get cut. You bleed much faster than average, at 3x the normal rate." // CHOMPEdit: More Trait Feedback for players. - cost = -3 - can_take = ORGANICS - -/datum/trait/negative/haemophilia_plus/apply(var/datum/species/S,var/mob/living/carbon/human/H) - ..() - H.add_modifier(/datum/modifier/trait/haemophilia) - -/datum/trait/negative/pain_intolerance_basic - name = "Pain Intolerance" - desc = "You are frail and sensitive to pain. You experience 25% more pain from all sources." - cost = -2 - var_changes = list("pain_mod" = 1.2) // CHOMPEdit: Makes this exact opposite of Pain Tolerance Basic. - -/datum/trait/negative/pain_intolerance_advanced - name = "Pain Intolerance, Major" - desc = "You are highly sensitive to all sources of pain, and experience 50% more pain." - cost = -3 - var_changes = list("pain_mod" = 1.5) //this makes you extremely vulnerable to most sources of pain, a stunbaton bop or shotgun beanbag will do around 90 agony, almost enough to drop you in one hit. CHOMPEdit: This really should cost more if it's this bad. - - -/datum/trait/negative/sensitive_biochem - name = "Sensitive Biochemistry" - desc = "Your biochemistry is a little delicate, rendering you more susceptible to both deadly toxins and the more subtle ones. You'll probably want to list this in your medical records, and perhaps in your exploitable info as well. Toxin damages and knockout drugs are 25% stronger on you." - cost = -1 - var_changes = list("chem_strength_tox" = 1.25) - -#undef GAUSSIAN_RANDOM diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/negative_genes.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/negative_genes.dm new file mode 100644 index 0000000000..5b58c77fdb --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/negative_genes.dm @@ -0,0 +1,209 @@ +/datum/trait/negative + category = TRAIT_TYPE_NEGATIVE + +/* Was disabled in setupgame.dm, likely nonfunctional +/datum/trait/negative/disability_hallucinations + name = "Disability: Hallucinations" + desc = "..." + cost = -3 + custom_only = FALSE + + is_genetrait = TRUE + hidden = FALSE + + mutation = mHallucination + activation_message="Your mind says 'Hello'." +*/ + +/datum/trait/negative/disability_epilepsy + name = "Epilepsy" + desc = "You experience periodic seizures." + cost = -3 + custom_only = FALSE + + is_genetrait = TRUE + hidden = FALSE + + disability=EPILEPSY + activation_message="You get a headache." + primitive_expression_messages=list("shudders and twitches.") + +/datum/trait/negative/disability_cough + name = "Coughing Fits" + desc = "You can't stop yourself from coughing." + cost = -1 + custom_only = FALSE + + is_genetrait = TRUE + hidden = FALSE + + disability=COUGHING + activation_message="You start coughing." + +/datum/trait/negative/disability_clumsy + name = "Clumsy" + desc = "You often make silly mistakes, or drop things." + cost = -2 + custom_only = FALSE + + is_genetrait = TRUE + hidden = FALSE + + mutation=CLUMSY + activation_message="You feel lightheaded." + primitive_expression_messages=list("trips.") + +/datum/trait/negative/disability_tourettes + name = "Tourettes Syndrome" + desc = "You have periodic motor seizures, and cannot stop yourself from yelling profanity." + cost = -2 + custom_only = FALSE + + is_genetrait = TRUE + hidden = FALSE + + disability=TOURETTES + activation_message="You twitch." + primitive_expression_messages=list("twitches and chitters.") + +/datum/trait/negative/disability_anxiety + name = "Anxiety Disorder" + desc = "You have extreme anxiety, often stuttering words." + cost = -1 + custom_only = FALSE + + is_genetrait = TRUE + hidden = FALSE + + disability=NERVOUS + activation_message="You feel nervous." + primitive_expression_messages=list("anxiously chitters.") + +/* Replaced by /datum/trait/negative/blindness +/datum/trait/negative/disability_blind + name = "Blinded" + desc = "You are unable to see anything." + cost = -3 + custom_only = FALSE + + is_genetrait = TRUE + hidden = FALSE + + sdisability=BLIND + activation_message="You can't seem to see anything." + +/datum/trait/negative/disability_blind/handle_environment_special(var/mob/living/carbon/human/H) + H.sdisabilities |= sdisability // In space, no one can hear you scream +*/ + +/datum/trait/negative/disability_mute + name = "Mute" + desc = "You are unable to speak." + cost = -3 + custom_only = FALSE + + is_genetrait = TRUE + hidden = FALSE + + sdisability=MUTE + activation_message="Your throat feels strange..." + primitive_expression_messages=list("screams without a sound.") + +/datum/trait/negative/disability_mute/handle_environment_special(var/mob/living/carbon/human/H) + H.sdisabilities |= sdisability // In space, no one can hear you scream + +/datum/trait/negative/disability_deaf + name = "Deaf" + desc = "You are unable to hear anything." + cost = -3 + custom_only = FALSE + + is_genetrait = TRUE + hidden = FALSE + + sdisability=DEAF + activation_message="It's kinda quiet." + primitive_expression_messages=list("stares blanky.") + +/datum/trait/negative/disability_deaf/handle_environment_special(var/mob/living/carbon/human/H) + H.sdisabilities |= sdisability // In space, I can't hear shit + +/datum/trait/negative/disability_deaf/apply(var/datum/species/S,var/mob/living/carbon/human/H) + . = ..() + H.ear_deaf = 1 + /* //Not used here, used downstream. + if(H.stat != DEAD) + H.deaf_loop.start(skip_start_sound = TRUE) // Ear Ringing/Deafness + */ + +/datum/trait/negative/disability_deaf/unapply(datum/species/S, mob/living/carbon/human/H) + . = ..() + H.ear_deaf = 0 + /* //Not used here, used downstream. + H.deaf_loop.stop() + */ + +/datum/trait/negative/disability_nearsighted + name = "Nearsighted" + desc = "You have difficulty seeing things far away." + cost = -2 + custom_only = FALSE + + is_genetrait = TRUE + hidden = FALSE + + disability=NEARSIGHTED + activation_message="Your eyes feel weird..." + primitive_expression_messages=list("squints and stares.") + +/datum/trait/negative/disability_wingdings + name = "Incomprehensible" + desc = "You are unable to speak normally, everything you say comes out as insane gibberish." + cost = -2 + custom_only = FALSE + + is_genetrait = TRUE + hidden = FALSE + + disability=WINGDINGS + activation_message="You feel a little... Ga-hoo!" + primitive_expression_messages=list("zooks!","bloops!","boinks!") + +/datum/trait/negative/disability_deteriorating + name = "Rotting Genetics" + desc = "Your body is slowly failing due to a chronic genetic disorder, expect to lose limbs or have organs shutdown randomly." + cost = -4 + custom_only = FALSE + + is_genetrait = TRUE + hidden = FALSE + + disability=DETERIORATE + activation_message="You feel sore..." + primitive_expression_messages=list("shudders.","gasps.","chokes.") + +/datum/trait/negative/disability_gibbing + name = "Gibbingtons" + desc = "Your body is on the edge of exploding, anything could set it off! A rare genetic disorder, only discovered with the invention of resleeving technology!" + cost = -5 + custom_only = FALSE + + is_genetrait = TRUE + hidden = TRUE + + disability=GIBBING + activation_message="You feel bloated..." + primitive_expression_messages=list("shudders.","gasps.","chokes.") + +/datum/trait/negative/disability_censored + name = "Censored" + desc = "You are unable to speak profanity. To an excessive degree..." + cost = -1 + custom_only = FALSE + + is_genetrait = TRUE + hidden = FALSE + + disability=CENSORED + activation_message="You feel less rude..." + primitive_expression_messages=list("BEEPS!") diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm index d906f2b58c..c36644689d 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm @@ -7,7 +7,7 @@ cost = 0 var_changes = list("metabolic_rate" = 1.2, "hunger_factor" = 0.2, "metabolism" = 0.06) // +20% rate and 4x hunger (Teshari level) excludes = list(/datum/trait/neutral/metabolism_down, /datum/trait/neutral/metabolism_apex) - custom_only = FALSE // CHOMPEdit + custom_only = FALSE /datum/trait/neutral/metabolism_down name = "Metabolism, Slow" @@ -15,7 +15,7 @@ cost = 0 var_changes = list("metabolic_rate" = 0.8, "hunger_factor" = 0.04, "metabolism" = 0.0012) // -20% of default. excludes = list(/datum/trait/neutral/metabolism_up, /datum/trait/neutral/metabolism_apex) - custom_only = FALSE // CHOMPEdit + custom_only = FALSE /datum/trait/neutral/metabolism_apex name = "Metabolism, Apex" @@ -23,7 +23,7 @@ cost = 0 var_changes = list("metabolic_rate" = 1.4, "hunger_factor" = 0.4, "metabolism" = 0.012) // +40% rate and 8x hunger (Double Teshari) excludes = list(/datum/trait/neutral/metabolism_up, /datum/trait/neutral/metabolism_down) - custom_only = FALSE // CHOMPEdit + custom_only = FALSE /datum/trait/neutral/coldadapt name = "Temp. Adapted, Cold" @@ -34,6 +34,13 @@ excludes = list(/datum/trait/neutral/hotadapt) can_take = ORGANICS // CHOMP edit + // Traitgenes Replaces /datum/trait/positive/superpower_cold_resist, made into a genetrait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your body is filled with warmth." + primitive_expression_messages=list("pants, sweat dripping down their head.") + /datum/trait/neutral/hotadapt name = "Temp. Adapted, Heat" desc = "You are able to withstand much hotter temperatures than other species, and can even be comfortable in extremely hot environments. You are also more vulnerable to cold environments, and have a higher body temperature as a consequence of these adaptations." @@ -43,6 +50,14 @@ excludes = list(/datum/trait/neutral/coldadapt) can_take = ORGANICS // CHOMP edit + // Traitgenes Made into a genetrait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your body feels chilly." + primitive_expression_messages=list("shivers.") + + /datum/trait/neutral/autohiss_unathi name = "Autohiss (Unathi)" desc = "You roll your S's and x's" @@ -57,7 +72,6 @@ autohiss_exempt = list(LANGUAGE_UNATHI)) excludes = list(/datum/trait/neutral/autohiss_tajaran, /datum/trait/neutral/autohiss_vassilian, /datum/trait/neutral/autohiss_zaddat) // CHOMPEdit: exclude vassillian hiss custom_only = FALSE - //banned_species = list(SPECIES_TAJARAN, SPECIES_UNATHI, SPECIES_ZADDAT) //CHOMPRemove /datum/trait/neutral/autohiss_tajaran name = "Autohiss (Tajaran)" @@ -70,7 +84,6 @@ autohiss_exempt = list(LANGUAGE_SIIK,LANGUAGE_AKHANI,LANGUAGE_ALAI)) excludes = list(/datum/trait/neutral/autohiss_unathi, /datum/trait/neutral/autohiss_zaddat, /datum/trait/neutral/autohiss_vassilian) // CHOMPEdit: exclude vassillian hiss custom_only = FALSE - //banned_species = list(SPECIES_TAJARAN, SPECIES_UNATHI, SPECIES_ZADDAT) //CHOMPRemove /datum/trait/neutral/autohiss_zaddat name = "Autohiss (Zaddat)" @@ -88,9 +101,8 @@ "v" = list("vv", "vvv") ), autohiss_exempt = list(LANGUAGE_ZADDAT,LANGUAGE_VESPINAE)) - excludes = list(/datum/trait/neutral/autohiss_tajaran, /datum/trait/neutral/autohiss_unathi) + excludes = list(/datum/trait/neutral/autohiss_tajaran) custom_only = FALSE - //banned_species = list(SPECIES_TAJARAN, SPECIES_UNATHI, SPECIES_ZADDAT) // CHOMPRemove /datum/trait/neutral/bloodsucker name = "Bloodsucker, Obligate" @@ -231,7 +243,7 @@ add_verb(H, /mob/living/proc/toggle_stuffing_mode) /datum/trait/neutral/hard_vore - name = "Hard Vore" //CHOMPedit Renamed Brutal Predation to Hard Vore, because some people don't know what this actually does + name = "Hard Vore" desc = "Allows you to tear off limbs & tear out internal organs." cost = 0 custom_only = FALSE @@ -247,10 +259,25 @@ custom_only = FALSE var_changes = list("trashcan" = 1) + // Traitgenes made into a genetrait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your stomach feels strange." + primitive_expression_messages=list("eats something off the ground.") + /datum/trait/neutral/trashcan/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..() add_verb(H, /mob/living/proc/eat_trash) - add_verb(H, /mob/living/proc/toggle_trash_catching) //Ported from chompstation + add_verb(H, /mob/living/proc/toggle_trash_catching) + +// Traitgenes made into a genetrait +/datum/trait/neutral/trashcan/unapply(datum/species/S, mob/living/carbon/human/H, trait_prefs) + ..() + if(!(/mob/living/proc/eat_trash in S.inherent_verbs)) + remove_verb(H,/mob/living/proc/eat_trash) + if(!(/mob/living/proc/toggle_trash_catching in S.inherent_verbs)) + remove_verb(H,/mob/living/proc/toggle_trash_catching) /datum/trait/neutral/gem_eater name = "Expensive Taste" @@ -259,17 +286,30 @@ custom_only = FALSE var_changes = list("organic_food_coeff" = 0, "eat_minerals" = 1) + // Traitgenes made into a genetrait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your stomach feels strange." + primitive_expression_messages=list("picks up and eats something shiny off the ground.") + /datum/trait/neutral/gem_eater/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..() add_verb(H, /mob/living/proc/eat_minerals) +// Traitgenes made into a genetrait +/datum/trait/neutral/gem_eater/unapply(datum/species/S, mob/living/carbon/human/H, trait_prefs) + ..() + if(!(/mob/living/proc/eat_minerals in S.inherent_verbs)) + remove_verb(H,/mob/living/proc/eat_minerals) + /datum/trait/neutral/synth_chemfurnace name = "Biofuel Processor" desc = "You are able to gain energy through consuming and processing normal food, at the cost of significantly slower recharging via cyborg chargers. Energy-dense foods such as protein bars and survival food will yield the best results." cost = 0 custom_only = FALSE can_take = SYNTHETICS - var_changes = list("organic_food_coeff" = 0.75, "synthetic_food_coeff" = 1) //CHOMPEdit: Increase values + var_changes = list("organic_food_coeff" = 0.75, "synthetic_food_coeff" = 1) excludes = list(/datum/trait/neutral/biofuel_value_down) /datum/trait/neutral/synth_ethanolburner @@ -296,10 +336,23 @@ var_changes = list("has_glowing_eyes" = 1) has_preferences = list("has_glowing_eyes" = list(TRAIT_PREF_TYPE_BOOLEAN, "Glowing on spawn", TRAIT_VAREDIT_TARGET_SPECIES)) + // Traitgenes Made into a genetrait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your eyes feel brighter." + primitive_expression_messages=list("eyes twinkle.") + /datum/trait/neutral/glowing_eyes/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..() add_verb(H, /mob/living/carbon/human/proc/toggle_eye_glow) +// Traitgenes Made into a genetrait +/datum/trait/neutral/glowing_eyes/unapply(var/datum/species/S,var/mob/living/carbon/human/H) + ..() + if(!(/mob/living/carbon/human/proc/toggle_eye_glow in S.inherent_verbs)) + remove_verb(H,/mob/living/carbon/human/proc/toggle_eye_glow) + /datum/trait/neutral/glowing_body name = "Glowing Body" desc = "Your body glows about as much as a PDA light! Settable color and toggle in Abilities tab ingame." @@ -308,11 +361,26 @@ has_preferences = list("glow_toggle" = list(TRAIT_PREF_TYPE_BOOLEAN, "Glowing on spawn", TRAIT_VAREDIT_TARGET_MOB, FALSE), \ "glow_color" = list(TRAIT_PREF_TYPE_COLOR, "Glow color", TRAIT_VAREDIT_TARGET_MOB)) + // Traitgenes Made into a genetrait + is_genetrait = TRUE + hidden = FALSE + + activation_message="You feel enlightened." + primitive_expression_messages=list("shines and sparkles.") + /datum/trait/neutral/glowing_body/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..() add_verb(H, /mob/living/proc/glow_toggle) add_verb(H, /mob/living/proc/glow_color) +// Traitgenes Made into a genetrait +/datum/trait/neutral/glowing_body/unapply(var/datum/species/S,var/mob/living/carbon/human/H) + ..() + if(!(/mob/living/proc/glow_toggle in S.inherent_verbs)) + remove_verb(H,/mob/living/proc/glow_toggle) + if(!(/mob/living/proc/glow_color in S.inherent_verbs)) + remove_verb(H,/mob/living/proc/glow_color) + //Allergen traits! Not available to any species with a base allergens var. /datum/trait/neutral/allergy name = "Allergy: Gluten" @@ -321,10 +389,22 @@ custom_only = FALSE var/allergen = ALLERGEN_GRAINS + // Traitgenes Made ALL ALLERGYS into gene traits + is_genetrait = TRUE + hidden = FALSE + + activation_message="Something feels odd..." + /datum/trait/neutral/allergy/apply(var/datum/species/S,var/mob/living/carbon/human/H) S.allergens |= allergen ..() +// Traitgenes edit begin - Made ALL ALLERGYS into gene traits +/datum/trait/neutral/allergy/unapply(var/datum/species/S,var/mob/living/carbon/human/H) + S.allergens &= ~allergen + ..() +// Traitgenes edit end + /datum/trait/neutral/allergy/meat name = "Allergy: Meat" desc = "You're highly allergic to just about any form of meat. You're probably better off just sticking to vegetables. NB: By taking this trait, you acknowledge there is a significant risk your character may suffer a fatal reaction if exposed to this substance." @@ -486,6 +566,12 @@ custom_only = FALSE var_changes = list("spice_mod" = 3) // 300% as effective if spice_mod is set to 1. If it's not 1 in species.dm, update this! + // Traitgenes Made into a gene trait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your belly feels strange..." + /datum/trait/neutral/spice_intolerance_basic name = "Spice Intolerance, Heavy" desc = "Spicy (and chilly) peppers are twice as strong. (This does not affect pepperspray.)" @@ -521,6 +607,12 @@ custom_only = FALSE var_changes = list("spice_mod" = 0.25) // 25% as effective if spice_mod is set to 1. If it's not 1 in species.dm, update this! + // Traitgenes Made into a gene trait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your belly feels strange..." + // Alcohol Traits Start Here, from negative to positive. /datum/trait/neutral/alcohol_intolerance_advanced name = "Liver of Air" @@ -529,6 +621,12 @@ custom_only = FALSE var_changes = list("chem_strength_alcohol" = 0.33) + // Traitgenes Made into a gene trait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your belly feels strange..." + /datum/trait/neutral/alcohol_intolerance_basic name = "Liver of Lilies" desc = "You have a hard time with alcohol. Maybe you just never took to it, or maybe it doesn't agree with your system... either way, alcohol hits you twice as hard." @@ -571,38 +669,77 @@ cost = 0 custom_only = FALSE var_changes = list("chem_strength_alcohol" = 4) + + // Traitgenes Made into a gene trait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your belly feels strange..." // Alcohol Traits End Here. /datum/trait/neutral/colorblind/mono name = "Colorblindness (Monochromancy)" desc = "You simply can't see colors at all, period. You are 100% colorblind." cost = 0 - custom_only = FALSE //CHOMPedit: Some of this are named with species, and there is a descent number of reasons to have this. + custom_only = FALSE + + // Traitgenes Made into a gene trait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your eyes feel strange..." /datum/trait/neutral/colorblind/mono/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..() H.add_modifier(/datum/modifier/trait/colorblind_monochrome) +// Traitgenes Made into a gene trait +/datum/trait/neutral/colorblind/mono/unapply(var/datum/species/S,var/mob/living/carbon/human/H) + ..() + H.remove_a_modifier_of_type(/datum/modifier/trait/colorblind_monochrome) + /datum/trait/neutral/colorblind/para_vulp name = "Colorblindness (Para Vulp)" desc = "You have a severe issue with green colors and have difficulty recognizing them from red colors." cost = 0 - custom_only = FALSE //CHOMPedit: Some of this are named with species, and there is a descent number of reasons to have this. + custom_only = FALSE + + // Traitgenes Made into a gene trait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your eyes feel strange..." /datum/trait/neutral/colorblind/para_vulp/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..() H.add_modifier(/datum/modifier/trait/colorblind_vulp) +// Traitgenes Made into a gene trait +/datum/trait/neutral/colorblind/para_vulp/unapply(var/datum/species/S,var/mob/living/carbon/human/H) + ..() + H.remove_a_modifier_of_type(/datum/modifier/trait/colorblind_vulp) + /datum/trait/neutral/colorblind/para_taj name = "Colorblindness (Para Taj)" desc = "You have a minor issue with blue colors and have difficulty recognizing them from red colors." cost = 0 - custom_only = FALSE //CHOMPedit: Some of this are named with species, and there is a descent number of reasons to have this. + custom_only = FALSE + + // Traitgenes - Made into a gene trait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your eyes feel strange..." /datum/trait/neutral/colorblind/para_taj/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..() H.add_modifier(/datum/modifier/trait/colorblind_taj) +// Traitgenes Made into a gene trait +/datum/trait/neutral/colorblind/para_taj/unapply(var/datum/species/S,var/mob/living/carbon/human/H) + ..() + H.remove_a_modifier_of_type(/datum/modifier/trait/colorblind_taj) + // Body shape traits /datum/trait/neutral/taller name = "Tall" @@ -740,30 +877,66 @@ cost = 0 custom_only = FALSE + // Traitgenes made into a genetrait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your mind feels more powerful." + /datum/trait/neutral/dominate_predator/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..() add_verb(H, /mob/proc/dominate_predator) +// Traitgenes made into a genetrait +/datum/trait/neutral/dominate_predator/unapply(datum/species/S, mob/living/carbon/human/H, trait_prefs) + ..() + if(!(/mob/proc/dominate_predator in S.inherent_verbs)) + remove_verb(H,/mob/proc/dominate_predator) + /datum/trait/neutral/dominate_prey name = "Dominate Prey" desc = "Connect to and dominate the brain of your prey." cost = 0 custom_only = FALSE + // Traitgenes made into a genetrait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your mind feels more powerful." + /datum/trait/neutral/dominate_prey/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..() add_verb(H, /mob/living/proc/dominate_prey) +// Traitgenes made into a genetrait +/datum/trait/neutral/dominate_prey/unapply(datum/species/S, mob/living/carbon/human/H, trait_prefs) + ..() + if(!(/mob/living/proc/dominate_prey in S.inherent_verbs)) + remove_verb(H,/mob/living/proc/dominate_prey) + /datum/trait/neutral/submit_to_prey name = "Submit To Prey" desc = "Allow prey's mind to control your own body." cost = 0 custom_only = FALSE + // Traitgenes made into a genetrait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your mind feels more fluid." + /datum/trait/neutral/submit_to_prey/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..() add_verb(H, /mob/living/proc/lend_prey_control) +// Traitgenes made into a genetrait +/datum/trait/neutral/submit_to_prey/unapply(datum/species/S, mob/living/carbon/human/H, trait_prefs) + ..() + if(!(/mob/living/proc/lend_prey_control in S.inherent_verbs)) + remove_verb(H,/mob/living/proc/lend_prey_control) + /datum/trait/neutral/vertical_nom name = "Vertical Nom" desc = "Allows you to consume people from up above." @@ -1226,6 +1399,19 @@ input += "s" return input +/datum/trait/neutral/drippy + name = "Drippy" + desc = "You cannot hold your form together, or produce a constant film of sludge that drips off of your body. Hope the station has a janitor." + cost = 0 + var_changes = list("drippy" = 1) + + // Traitgenes Made into a genetrait + is_genetrait = TRUE + hidden = FALSE + + activation_message="You feel softer..." + primitive_expression_messages=list("drips.") + /datum/trait/neutral/mudking name = "Mudking" desc = "Somehow you are so filthy that tiles get dirty four times as quick from you walking on them." diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm index f32827b8ce..327d8a7254 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm @@ -10,6 +10,13 @@ // banned_species = list(SPECIES_ALRAUNE, SPECIES_SHADEKIN_CREW, SPECIES_TESHARI, SPECIES_TAJARAN, SPECIES_DIONA, SPECIES_UNATHI) //Either not applicable or buffs ruin species flavour/balance // custom_only = FALSE //Keeping these in comments in case we decide to open them up in future, so the species are already organised. + // Traitgenes Replaces /datum/trait/positive/superpower_increaserun, made into a genetrait + is_genetrait = TRUE + hidden = FALSE + + activation_message="Your leg muscles pulsate." + primitive_expression_messages=list("dances around.") + /datum/trait/positive/hardy name = "Hardy" desc = "Allows you to carry heavy equipment with less slowdown." @@ -30,8 +37,8 @@ /datum/trait/positive/endurance_high name = "High Endurance" - desc = "Increases your maximum total hitpoints to 125. You require 250 damage in total to die, compared to 200 normally. You will still go into crit after losing 125 HP, compared to crit at 100 HP." // CHOMPEdit: Clarity for players' sake. - cost = 3 // CHOMPEdit + desc = "Increases your maximum total hitpoints to 125. You require 250 damage in total to die, compared to 200 normally. You will still go into crit after losing 125 HP, compared to crit at 100 HP." + cost = 3 var_changes = list("total_health" = 125) custom_only = FALSE banned_species = list(SPECIES_TESHARI, SPECIES_UNATHI, SPECIES_SHADEKIN_CREW) //Either not applicable or buffs are too strong @@ -42,20 +49,24 @@ /datum/trait/positive/nonconductive name = "Non-Conductive" - desc = "Decreases your susceptibility to electric shocks by 25%." //CHOMP Edit - GRAMMAR PLS. - cost = 2 //This effects tasers! - var_changes = list("siemens_coefficient" = 0.75) //CHOMP Edit + desc = "Decreases your susceptibility to electric shocks by 25%." + cost = 2 + var_changes = list("siemens_coefficient" = 0.75) /datum/trait/positive/nonconductive_plus name = "Non-Conductive, Major" - desc = "Decreases your susceptibility to electric shocks by 50%." //CHOMP Edit - GRAMMAR PLS. - cost = 3 //Let us not forget this effects tasers! - var_changes = list("siemens_coefficient" = 0.5) //CHOMP Edit + desc = "Decreases your susceptibility to electric shocks by 50%." + cost = 3 + var_changes = list("siemens_coefficient" = 0.5) + + is_genetrait = TRUE + + activation_message="Your skin feels strange." /* //Chompedit, moving to Positive_ch.dm so it wont be messed with from upstream /datum/trait/positive/darksight name = "Darksight" - desc = "Allows you to see a short distance in the dark and 10% more susceptible to flashes." //CHOMP Edit + desc = "Allows you to see a short distance in the dark and 10% more susceptible to flashes." cost = 1 var_changes = list("darksight" = 3) //CHOMP Edit custom_only = FALSE @@ -63,7 +74,7 @@ /datum/trait/positive/darksight_plus name = "Darksight, Major" - desc = "Allows you to see in the dark for almost the whole screen and 20% more susceptible to flashes." //CHOMP Edit + desc = "Allows you to see in the dark for almost the whole screen and 20% more susceptible to flashes." cost = 2 var_changes = list("darksight" = 6) //CHOMP Edit custom_only = FALSE @@ -201,7 +212,7 @@ name = "Aquatic" desc = "You can breathe under water and can traverse water more efficiently. Additionally, you can eat others in the water." cost = 1 - custom_only = FALSE //CHOMPEdit: honestly within the bounds of genemods, just hopefully people actually design characters around it + custom_only = FALSE var_changes = list("water_breather" = 1, "water_movement" = -4) //Negate shallow water. Half the speed in deep water. allowed_species = list(SPECIES_HANNER, SPECIES_CUSTOM) //So it only shows up for custom species and hanner custom_only = FALSE @@ -317,3 +328,59 @@ varchange_type = TRAIT_VARCHANGE_LESS_BETTER excludes = list(/datum/trait/negative/bad_swimmer) banned_species = list(SPECIES_AKULA) // They already swim better than this + +/datum/trait/positive/table_passer + name = "Table Passer" + desc = "You move over or under tables with ease of a Teshari." + cost = 2 + + // Traitgenes Replacement for /datum/trait/positive/superpower_midget, made into a genetrait + is_genetrait = TRUE + hidden = FALSE + activation_message="Your skin feels rubbery." + + has_preferences = list("pass_table" = list(TRAIT_PREF_TYPE_BOOLEAN, "On spawn", TRAIT_NO_VAREDIT_TARGET, TRUE)) + +/datum/trait/positive/table_passer/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/list/trait_prefs) + ..() + if (trait_prefs?["pass_table"] || !trait_prefs) + H.pass_flags |= PASSTABLE + add_verb(H,/mob/living/proc/toggle_pass_table) + +// Traitgenes All genetraits need an unapply proc if they do anything special +/datum/trait/positive/table_passer/unapply(datum/species/S, mob/living/carbon/human/H) + . = ..() + if (H.pass_flags & PASSTABLE) + H.pass_flags ^= PASSTABLE + if(!(/mob/living/proc/toggle_pass_table in S.inherent_verbs)) // Teshari shouldn't lose agility + remove_verb(H,/mob/living/proc/toggle_pass_table) + +/datum/trait/positive/photosynth + name = "Photosynthesis" + desc = "Your body is able to produce nutrition from being in light." + cost = 3 + var_changes = list("photosynthesizing" = TRUE) + can_take = ORGANICS|SYNTHETICS //Synths actually use nutrition, just with a fancy covering. + +/datum/trait/positive/rad_resistance + name = "Radiation Resistance" + desc = "You are generally more resistant to radiation, and it dissipates faster from your body." + cost = 1 + var_changes = list("radiation_mod" = 0.65, "rad_removal_mod" = 3.5, "rad_levels" = list("safe" = 70, "danger_1" = 150, "danger_2" = 450, "danger_3" = 600, "danger_4" = 2250)) + +/datum/trait/positive/rad_resistance_extreme + name = "Radiation Resistance, Major" + desc = "You are much more resistant to radiation, and it dissipates much faster from your body." + cost = 2 + var_changes = list("radiation_mod" = 0.5, "rad_removal_mod" = 5, "rad_levels" = list("safe" = 150, "danger_1" = 300, "danger_2" = 600, "danger_3" = 1000, "danger_4" = 3000)) + +/datum/trait/positive/rad_immune + name = "Radiation Immunity" + desc = "For whatever reason, be it a more dense build or some quirk of your genetic code, your body is completely immune to radiation." + cost = 3 + var_changes = list("radiation_mod" = 0.0, "rad_removal_mod" = 10, "rad_levels" = list("safe" = 10000, "danger_1" = 10001, "danger_2" = 10002, "danger_3" = 10003, "danger_4" = 10004)) + + // Traitgenes + is_genetrait = TRUE + hidden = FALSE + activation_message="Your body feels mundane." diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/positive_ch.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/positive_ch.dm index 3606283213..f1b7f6bf28 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/positive_ch.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/positive_ch.dm @@ -86,31 +86,6 @@ ) excludes = list(/datum/trait/positive/lowpressureresminor,/datum/trait/positive/lowpressureresmajor,/datum/trait/positive/highpressureresminor,/datum/trait/positive/highpressureresmajor,/datum/trait/positive/pressureres) -/datum/trait/positive/photosynth - name = "Photosynthesis" - desc = "Your body is able to produce nutrition from being in light." - cost = 3 - var_changes = list("photosynthesizing" = TRUE) - can_take = ORGANICS|SYNTHETICS //Synths actually use nutrition, just with a fancy covering. - -/datum/trait/positive/rad_resistance - name = "Radiation Resistance" - desc = "You are generally more resistant to radiation, and it dissipates faster from your body." - cost = 1 - var_changes = list("radiation_mod" = 0.65, "rad_removal_mod" = 3.5, "rad_levels" = list("safe" = 20, "danger_1" = 75, "danger_2" = 100, "danger_3" = 200)) - -/datum/trait/positive/rad_resistance_extreme - name = "Radiation Resistance, Major" - desc = "You are much more resistant to radiation, and it dissipates much faster from your body." - cost = 2 - var_changes = list("radiation_mod" = 0.5, "rad_removal_mod" = 5, "rad_levels" = list("safe" = 40, "danger_1" = 100, "danger_2" = 150, "danger_3" = 250)) - -/datum/trait/positive/rad_immune - name = "Radiation Immunity" - desc = "For whatever reason, be it a more dense build or some quirk of your genetic code, your body is completely immune to radiation." - cost = 3 - var_changes = list("radiation_mod" = 0.0, "rad_removal_mod" = 10, "rad_levels" = list("safe" = 300, "danger_1" = 300, "danger_2" = 300, "danger_3" = 300)) - /datum/trait/positive/more_blood name = "Blood Volume, High" desc = "You have 50% more blood." @@ -138,18 +113,6 @@ H.mob_size = MOB_LARGE H.mob_bump_flag = HEAVY -/datum/trait/positive/table_passer - name = "Table Passer" - desc = "You move over or under tables with ease of a Teshari." - cost = 2 - has_preferences = list("pass_table" = list(TRAIT_PREF_TYPE_BOOLEAN, "On spawn", TRAIT_NO_VAREDIT_TARGET, TRUE)) - -/datum/trait/positive/table_passer/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/list/trait_prefs) - ..() - if (trait_prefs?["pass_table"] || !trait_prefs) - H.pass_flags |= PASSTABLE - add_verb(H,/mob/living/proc/toggle_pass_table) //CHOMPEdit TGPanel - /datum/trait/positive/grappling_expert name = "Grappling Expert" desc = "Your grabs are much harder to escape from, and you are better at escaping from other's grabs!" diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/positive_genes.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/positive_genes.dm new file mode 100644 index 0000000000..61ef6c7c8b --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/positive_genes.dm @@ -0,0 +1,205 @@ +/datum/trait/positive/superpower_nobreathe + name = "No Breathing" + desc = "You do not need to breathe." + cost = 5 + custom_only = FALSE + + is_genetrait = TRUE + hidden = TRUE // Cannot start with superpowers + + mutation = mNobreath + activity_bounds = DNA_HARD_BOUNDS + activation_message="You feel no need to breathe." + +/datum/trait/positive/superpower_remoteview + name = "Remote Viewing" + desc = "Remotely view other locations." + cost = 5 + custom_only = FALSE + + is_genetrait = TRUE + activity_bounds = DNA_HARDER_BOUNDS + hidden = TRUE // Cannot start with superpowers + + mutation = mRemote + activation_message="Your mind expands." + +/datum/trait/positive/superpower_remoteview/apply(datum/species/S, mob/living/carbon/human/H) + . = ..() + add_verb(H, /mob/living/carbon/human/proc/remoteobserve) + +/datum/trait/positive/superpower_remoteview/unapply(datum/species/S, mob/living/carbon/human/H) + . = ..() + if(/mob/living/carbon/human/proc/remoteobserve in S.inherent_verbs) + remove_verb(H, /mob/living/carbon/human/proc/remoteobserve) + +/datum/trait/positive/superpower_regenerate + name = "Regenerate" + desc = "Repairs wounds slowly, including internal bleeding." + cost = 5 + custom_only = FALSE + + is_genetrait = TRUE + activity_bounds = DNA_HARDER_BOUNDS + hidden = TRUE // Cannot start with superpowers + + mutation = mRegen + activation_message="You feel better." + primitive_expression_messages=list("'s skin shift's strangely.") + +/* Replaced by /datum/trait/positive/speed_fast +/datum/trait/positive/superpower_increaserun + name = "Super Speed" + desc = "Remotely communicate" + cost = 5 + custom_only = FALSE + + is_genetrait = TRUE + activity_bounds = DNA_HARDER_BOUNDS + hidden = TRUE // Cannot start with superpowers + + mutation = mRun + activation_message="Your leg muscles pulsate." +*/ + +/datum/trait/positive/superpower_remotetalk + name = "Telepathy" + desc = "Remotely communicate" + cost = 5 + custom_only = FALSE + + is_genetrait = TRUE + hidden = TRUE // Cannot start with superpowers + + mutation = mRemotetalk + activity_bounds = DNA_HARDER_BOUNDS + activation_message="You expand your mind outwards." + primitive_expression_messages=list("makes noises to itself.") + +/datum/trait/positive/superpower_remotetalk/apply(datum/species/S, mob/living/carbon/human/H) + . = ..() + add_verb(H, /mob/living/carbon/human/proc/remotesay) + +/datum/trait/positive/superpower_remotetalk/unapply(datum/species/S, mob/living/carbon/human/H) + . = ..() + if(!(/mob/living/carbon/human/proc/remotesay in S.inherent_verbs)) + remove_verb(H, /mob/living/carbon/human/proc/remotesay) + +/datum/trait/positive/superpower_noprints + name = "No Prints" + desc = "Your hands leave no fingerprints behind." + cost = 5 + custom_only = FALSE + + is_genetrait = TRUE + hidden = TRUE // Cannot start with superpowers + + mutation = mFingerprints + activation_message="Your fingers feel numb." + primitive_expression_messages=list("flexes its digits.") + + +/datum/trait/positive/superpower_xray //This is effectively thermals. + name = "X-Ray Vision" + desc = "You can see through walls." + cost = 5 + custom_only = FALSE + + is_genetrait = TRUE + activity_bounds = DNA_HARDER_BOUNDS + hidden = TRUE // Cannot start with superpowers + + mutation = XRAY + activation_message="The walls suddenly disappear." + primitive_expression_messages=list("stares at something it cannot see.") + +/datum/trait/positive/superpower_tk + name = "Telekenesis" + desc = "You can move objects with your mind." + cost = 5 + custom_only = FALSE + + is_genetrait = TRUE + activity_bounds = DNA_HARD_BOUNDS + hidden = TRUE // Cannot start with superpowers + + mutation = TK + activation_message="You feel smarter." + primitive_expression_messages=list("grabs at something it cannot reach.") + +/datum/trait/positive/superpower_laser + name = "Laser Vision" + desc = "You can blast lasers from your eyes." + cost = 5 + custom_only = FALSE + + is_genetrait = TRUE + activity_bounds = DNA_HARD_BOUNDS + hidden = TRUE // Cannot start with superpowers + + mutation = LASER + activation_message="Your eyes feel strange..." + +/datum/trait/positive/superpower_hulk + name = "Hulk" + desc = "UURGG SMASH TINY TESHARI" + cost = 5 + custom_only = FALSE + + is_genetrait = TRUE + activity_bounds = DNA_HARD_BOUNDS + hidden = TRUE // Cannot start with superpowers + + mutation = HULK + activation_message="Your muscles hurt." + deactivation_message=span_warning("You suddenly feel very weak.") + +/datum/trait/positive/superpower_hulk/handle_environment_special(mob/living/carbon/human/H) + if(H.health <= 25) + if(H.dna) + H.dna.SetSEState(linked_gene.block, FALSE, FALSE) // Turn this thing off or so help me-- + domutcheck(H,null,MUTCHK_FORCED) + H.UpdateAppearance() + H.mutations.Remove(HULK) + H.Weaken(3) + H.emote("collapse") + +/datum/trait/positive/superpower_flashproof + name = "Flash Resistance" + desc = "Your eyes are protected against sudden flashes of intense light." + cost = 5 + custom_only = FALSE + + is_genetrait = TRUE + activity_bounds = DNA_HARDER_BOUNDS + hidden = TRUE // Cannot start with superpowers + + mutation = FLASHPROOF + activation_message="Your eyes feel more robust, how nifty..." + +/datum/trait/positive/superpower_morph + name = "Morph" + desc = "Allows complex bodily transformations." + cost = 5 + custom_only = FALSE + + is_genetrait = TRUE + activity_bounds = DNA_HARDER_BOUNDS + hidden = TRUE // Cannot start with superpowers + + activation_message="You feel more fluid." + primitive_expression_messages=list("twitches and distorts.") + +/datum/trait/positive/superpower_morph/apply(datum/species/S, mob/living/carbon/human/H) + . = ..() + add_verb(H, /mob/living/carbon/human/proc/shapeshfit_form) + +/datum/trait/positive/superpower_morph/unapply(datum/species/S, mob/living/carbon/human/H) + . = ..() + remove_verb(H, /mob/living/carbon/human/proc/shapeshfit_form) + +/mob/living/carbon/human/proc/shapeshfit_form() + set name = "Transform Shape" + set category = "Abilities.Superpower" + var/datum/tgui_module/appearance_changer/superpower/V = new(src, src) + V.tgui_interact(src) diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/trait.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/trait.dm index 36704e3219..c4c1563e2c 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/trait.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/trait.dm @@ -11,19 +11,44 @@ var/list/excludes // Store a list of paths of traits to exclude, but done automatically if they change the same vars. var/can_take = ORGANICS|SYNTHETICS // Can freaking synths use those. var/list/banned_species // A list of species that can't take this trait - var/list/allowed_species // VORESTATION EDIT:chomp port. A list of species that CAN take this trait, use this if only a few species can use it. -shark + var/list/allowed_species // A list of species that CAN take this trait, use this if only a few species can use it. -shark var/custom_only = TRUE // Trait only available for custom species var/varchange_type = TRAIT_VARCHANGE_ALWAYS_OVERRIDE //Mostly used for non-custom species. var/has_preferences //if set, should be a list of the preferences for this trait in the format: list("identifier/name of var to edit" = list(typeofpref, "text to display in prefs", TRAIT_NO_VAREDIT_TARGET/TRAIT_VAREDIT_TARGET_SPECIES/etc, (optional: default value)), etc) typeofpref should follow the defines in _traits.dm (eg. TRAIT_PREF_TYPE_BOOLEAN) + var/special_env = FALSE + + + + + // Traitgenes Traits can toggle mutations and disabilities + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // IMPORTANT - in 99% of situations you should NOT need to edit gene code when adding a new traitgene. Genes only handle the on/off state of traits, traits control the changes and behaviors! + // Just keep pretending genecode doesn't exist and you should be fine. Traitgenes were made with that in mind, and are not intended to be something you need to edit every time you add a traitgene. + // Traitgenes only require that your trait has both an apply() and unapply() if it does anything like adding verbs. Otherwise, you don't even need to add trait exceptions. traitgenes handle it automatically. + // You probably shouldn't mark traits as traitgenes if they are custom species only, species locked, or species banned traits however... - Willbird + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + var/is_genetrait = FALSE // When their trait's datum is init, it will be added to the library of genes a carbon can be mutated to have or not have + var/list/activity_bounds = DNA_DEFAULT_BOUNDS // Activation requirement for trait to turn on/off. Dna is automatically configured for this when first spawned + var/hidden = FALSE // If a trait does not show on the list, only useful for genetics only traits that cannot be taken at character creation + var/mutation = 0 // Mutation to give (or 0) + var/disability = 0 // Disability to give (or 0) + var/sdisability = 0 // SDisability to give (or 0) + var/activation_message = null // If not null, shows a message when activated as a gene + var/deactivation_message = null // If not null, shows a message when deactivated as a gene + var/list/primitive_expression_messages=list() // Monkey's custom emote when they have this gene! + + var/datum/gene/trait/linked_gene = null // Internal use, do not assign. + + + //Proc can be overridden lower to include special changes, make sure to call up though for the vars changes -/datum/trait/proc/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/trait_prefs = null) //VOREStation edit: trait_prefs is a list in the format: list(identifier = value, etc) +/datum/trait/proc/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/trait_prefs = null) ASSERT(S) if(var_changes) for(var/V in var_changes) - //CHOMPEdit removal - //if((category == TRAIT_TYPE_POSITIVE && ((varchange_type == TRAIT_VARCHANGE_LESS_BETTER && var_changes[V] > S.vars[V]) || (varchange_type == TRAIT_VARCHANGE_MORE_BETTER && var_changes[V] < S.vars[V]))) || (category == TRAIT_TYPE_NEGATIVE && ((varchange_type == TRAIT_VARCHANGE_LESS_BETTER && var_changes[V] < S.vars[V]) || (varchange_type == TRAIT_VARCHANGE_MORE_BETTER && var_changes[V] > S.vars[V])))) - // continue S.vars[V] = var_changes[V] if (trait_prefs) for (var/trait in trait_prefs) @@ -34,9 +59,55 @@ S.vars[trait] = trait_prefs[trait] if(TRAIT_VAREDIT_TARGET_MOB) H.vars[trait] = trait_prefs[trait] + // Traitgenes Traits can toggle mutations and disabilities + if(mutation) + if(!(mutation in H.mutations)) + H.mutations.Add(mutation) + if(disability) + H.disabilities |= disability // bitflag + if(sdisability) + H.sdisabilities |= sdisability // bitflag add_verb(H, /mob/living/carbon/human/proc/trait_tutorial) + if(special_env) + S.env_traits += src return +// Traitgenes Disabling traits, genes can be turned off after all! +/datum/trait/proc/unapply(var/datum/species/S,var/mob/living/carbon/human/H, var/trait_prefs = null) + ASSERT(S) + if(var_changes) + for(var/V in var_changes) + S.vars[V] = initial(S.vars[V]) + if (trait_prefs) + for (var/trait in trait_prefs) + switch(has_preferences[trait][3]) + if(TRAIT_NO_VAREDIT_TARGET) + continue + if(TRAIT_VAREDIT_TARGET_SPECIES) + S.vars[trait] = initial(S.vars[trait]) + if(TRAIT_VAREDIT_TARGET_MOB) + H.vars[trait] = initial(H.vars[trait]) + if(mutation) + H.mutations.Remove(mutation) + if(disability) + H.disabilities &= ~disability // bitflag + if(sdisability) + H.sdisabilities &= ~sdisability // bitflag + if(special_env) + S.env_traits -= src + return + +/datum/trait/proc/send_message(var/mob/living/carbon/human/H, var/enabled) + if(enabled) + if(!activation_message) + return + to_chat(H,activation_message) + else + if(!deactivation_message) + return + to_chat(H,deactivation_message) +// Traitgenes edit end + //Applying trait to preferences rather than just us. /datum/trait/proc/apply_pref(var/datum/preferences/P) ASSERT(P) @@ -58,7 +129,6 @@ P.vars[V] = initial(P.vars[V]) return -//VOREStation edit: trait preferences /datum/trait/proc/get_default_prefs() if (!LAZYLEN(has_preferences)) return null @@ -87,3 +157,6 @@ if (length(input) <= 0) return default_value_for_pref(pref) return input + +/datum/trait/proc/handle_environment_special(var/mob/living/carbon/human/H) + return diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/trait_ch.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/trait_ch.dm deleted file mode 100644 index 1163ae2ef4..0000000000 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/trait_ch.dm +++ /dev/null @@ -1,15 +0,0 @@ -/datum/trait - var/special_env = FALSE - -/datum/trait/proc/handle_environment_special(var/mob/living/carbon/human/H) - return - -/datum/trait/apply(var/datum/species/S,var/mob/living/carbon/human/H) - . = ..() - if(special_env) - S.env_traits += src - -/datum/trait/remove(var/datum/species/S) - . = ..() - if(special_env) - S.env_traits -= src diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index ba5f7346c5..072d57767c 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -606,21 +606,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) //see UpdateDamageIcon() if(!LAZYLEN(mutations)) return //No mutations, no icons. - //TODO: THIS PROC??? - var/fat - if(FAT in mutations) - fat = "fat" - var/image/standing = image(icon = 'icons/effects/genetics.dmi', layer = BODY_LAYER+MUTATIONS_LAYER) - var/g = gender == FEMALE ? "f" : "m" - - for(var/datum/dna/gene/gene in dna_genes) - if(!gene.block) - continue - if(gene.is_active(src)) - var/underlay = gene.OnDrawUnderlays(src,g,fat) - if(underlay) - standing.underlays += underlay for(var/mut in mutations) if(mut == LASER) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 2bbb249bc6..31fb4523a2 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -6,7 +6,7 @@ if (transforming) return - handle_modifiers() //VOREStation Edit - Needs to be done even if in nullspace. + handle_modifiers() //Needs to be done even if in nullspace. if(!loc) return @@ -16,8 +16,6 @@ else environment = loc.return_air() - //handle_modifiers() // Do this early since it might affect other things later. //VOREStation Edit - handle_light() if(stat != DEAD) @@ -66,7 +64,6 @@ handle_ambience() //stuff in the stomach - //handle_stomach() //VOREStation Code update_gravity(mob_get_gravity()) @@ -85,7 +82,9 @@ handle_vision() - handle_tf_holder() //VOREStation Addition + handle_tf_holder() + + handle_dripping() handle_vr_derez() // CHOMPedit diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 3073b9e439..7d97b5e448 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -865,17 +865,15 @@ /mob/living/proc/slip(var/slipped_on,stun_duration=8) return 0 -// CHOMPAdd - Drop both things on hands +/mob/living/carbon/drop_from_inventory(var/obj/item/W, var/atom/target = null) + return !(W in internal_organs) && ..() + /mob/living/proc/drop_both_hands() if(l_hand) unEquip(l_hand) if(r_hand) unEquip(r_hand) return -// CHOMPEnd - -/mob/living/carbon/drop_from_inventory(var/obj/item/W, var/atom/target = null) - return !(W in internal_organs) && ..() /mob/living/touch_map_edge() @@ -1422,3 +1420,47 @@ to_chat(src, span_notice("You are [toggled_sleeping ? "now sleeping. Use the Sleep verb again to wake up" : "no longer sleeping"].")) if(toggled_sleeping) Sleeping(1) + +/mob/living/proc/handle_dripping() + if(prob(95)) + return + if(!isturf(src.loc)) + return + if(ishuman(src)) + var/mob/living/carbon/human/H = src + if(H.species && H.species.drippy) + // drip body color if human + var/obj/effect/decal/cleanable/blood/B + var/decal_type = /obj/effect/decal/cleanable/blood/splatter + var/turf/T = get_turf(src.loc) + + // Are we dripping or splattering? + var/list/drips = list() + // Only a certain number of drips (or one large splatter) can be on a given turf. + for(var/obj/effect/decal/cleanable/blood/drip/drop in T) + drips |= drop.drips + qdel(drop) + if(drips.len < 6) + decal_type = /obj/effect/decal/cleanable/blood/drip + + // Find a blood decal or create a new one. + B = locate(decal_type) in T + if(!B) + B = new decal_type(T) + + var/obj/effect/decal/cleanable/blood/drip/drop = B + if(istype(drop) && drips && drips.len) + drop.add_overlay(drips) + drop.drips |= drips + + // Update appearance. + drop.name = "drips of something" + drop.desc = "It's thick and gooey. Perhaps it's the chef's cooking?" + drop.dryname = "dried something" + drop.drydesc = "It's dry and crusty. The janitor isn't doing their job." + drop.basecolor = rgb(H.r_skin,H.g_skin,H.b_skin) + drop.update_icon() + drop.fluorescent = 0 + drop.invisibility = 0 + //else + // come up with drips for other mobs someday diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index 2564b3bed9..675da18d5a 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -126,12 +126,10 @@ default behaviour is: tmob.forceMove(oldloc) now_pushing = 0 return - //VOREStation Edit - Begin else if((tmob.mob_always_swap || (tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || src.restrained())) && canmove && can_swap && handle_micro_bump_helping(tmob)) forceMove(tmob.loc) now_pushing = 0 return - //VOREStation Edit - End if(!can_move_mob(tmob, 0, 0)) now_pushing = 0 @@ -139,11 +137,12 @@ default behaviour is: if(a_intent == I_HELP || src.restrained()) now_pushing = 0 return - // VOREStation Edit - Begin // Plow that nerd. if(ishuman(tmob)) var/mob/living/carbon/human/H = tmob if(H.species.lightweight == 1 && prob(50)) + if(HULK in H.mutations) //No knocking over the hulk + return H.visible_message(span_warning("[src] bumps into [H], knocking them off balance!")) H.Weaken(5) now_pushing = 0 diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index e777344d96..377df43a9a 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -100,6 +100,10 @@ var/list/channel_to_radio_key = new if(S.speaking && (S.speaking.flags & NO_STUTTER || S.speaking.flags & SIGNLANG)) continue + if(disabilities & CENSORED) + S.message = censor_swears(S.message) // Googlybonkers + . = 1 + if((HULK in mutations) && health >= 25 && length(S.message)) S.message = "[uppertext(S.message)]!!!" verb = pick("yells","roars","hollers") @@ -113,17 +117,15 @@ var/list/channel_to_radio_key = new S.message = stutter(S.message) verb = pick("stammers","stutters") . = 1 - //VOREStation Edit Start if(muffled) verb = pick("muffles") whispering = 1 . = 1 - //VOREStation Edit End - //YW Edit start - if(wingdings) - S.message = span_wingdings(S.message) + if(disabilities & WINGDINGS) + verb = pick("gibbers","gabbers","gahoos","gazonks") // Yeah lets just be stupid + S.message = Gibberish(S.message, 100) // Googlybonkers + S.message = span_wingdings((S.message)) . = 1 - //YW Edit End message_data[1] = message_pieces message_data[2] = verb diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index a17f125e84..8a47d8a220 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -465,6 +465,14 @@ var/obj/belly/B = loc src.forceMove(card) card.forceMove(B) + + if(istype( src.loc,/obj/structure/disposalholder)) + var/obj/structure/disposalholder/hold = loc + src.loc = card + card.loc = hold + src.forceMove(card) + card.forceMove(hold) + else //Otherwise go on floor src.loc = card card.loc = get_turf(card) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 81de85cb8a..a7ae77ac44 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -255,8 +255,11 @@ if(p >= 70) letter = "" + var/rand_set = list("#","@","*","&","%","$","/", "<", ">", ";","*","*","*","*","*","*","*") + if(p >= 80) + rand_set += alphabet_uppercase for(var/j = 1, j <= rand(0, 2), j++) - letter += pick("#","@","*","&","%","$","/", "<", ">", ";","*","*","*","*","*","*","*") + letter += pick(rand_set) returntext += letter @@ -692,3 +695,42 @@ var/global/image/backplane /mob/proc/can_feed() return TRUE + +/proc/censor_swears(t) + /* Bleeps our swearing */ + var/static/swear_censoring_list = list("fuck", + "shit", + "damn", + "piss", + "whore", + "cunt", + "bitch", + "bastard", + "dick", + "cock", + "slut", + "dong", + "pussy", + "twat", + "snatch", + "schlong", + "damn", + "dammit", + "damnit", + "ass", + "tit", + "douch", + "prick", + "hell", + "crap") + var/haystack = t + for(var/filter in swear_censoring_list) + var/regex/needle = regex(filter, "i") + while(TRUE) + var/pos = needle.Find(haystack) + if(!pos) + break + var/partial_start = copytext(haystack,1,pos) + var/partial_end = copytext(haystack,pos+length(filter),length(haystack)+1) + haystack = "[partial_start][pick("BEEP","BLEEP","BOINK","BEEEEEP")][partial_end]" + return haystack diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 0ee5b0ddbf..a274bbe90d 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -66,11 +66,11 @@ if(ready) output += "

\[ " + span_linkOn(span_bold("Ready")) + " | Not Ready \]

" //ChompEDIT - fixed height else - output += "

\[ Ready | " + span_linkOn(span_bold("Not Ready")) + " \]

" //ChompEDIT - fixed height - output += "

Join Game!

" //ChompEDIT - fixed height + output += "

\[ Ready | " + span_linkOn(span_bold("Not Ready")) + " \]

" + output += "

Join Game!

" else - output += "

View the Crew Manifest

" //ChompEDIT - fixed height + output += "

View the Crew Manifest

" output += "

Join Game!

" output += "

Observe

" @@ -93,23 +93,23 @@ break qdel(query) if(newpoll) - output += "

Show Player Polls
(NEW!)

" //ChompEDIT - fixed height + output += "

Show Player Polls
(NEW!)

" else - output += "

Show Player Polls
No Changes

" //ChompEDIT - fixed height + output += "

Show Player Polls
No Changes

" if(client?.check_for_new_server_news()) - output += "

Show Server News
(NEW!)

" //ChompEDIT 'Game updates' --> 'Server news' + output += "

Show Server News
(NEW!)

" else - output += "

Show Server News
No Changes

" //ChompEDIT 'Game updates' --> 'Server news' + output += "

Show Server News
No Changes

" if(SSsqlite.can_submit_feedback(client)) output += "

[href(src, list("give_feedback" = 1), "Give Feedback")]

" if(GLOB.news_data.station_newspaper) if(client.prefs.lastlorenews == GLOB.news_data.newsindex) - output += "

Show [using_map.station_name] News
No Changes

" //ChompEDIT - fixed height + output += "

Show [using_map.station_name] News
No Changes

" else - output += "

Show [using_map.station_name] News
(NEW!)

" //ChompEDIT - fixed height + output += "

Show [using_map.station_name] News
(NEW!)

" //ChompEDIT start: Show Changelog if(client?.prefs?.lastchangelog == changelog_hash) @@ -128,7 +128,7 @@ client.prefs.lastlorenews = GLOB.news_data.newsindex SScharacter_setup.queue_preferences_save(client.prefs) - panel = new(src, "Welcome","Welcome", 210, 500, src) // VOREStation Edit //ChompEDIT, height 320 -> 500 + panel = new(src, "Welcome","Welcome", 210, 500, src) panel.set_window_options("can_close=0") panel.set_content(output) panel.open() @@ -182,7 +182,6 @@ ready = 0 if(href_list["refresh"]) - //src << browse(null, "window=playersetup") //closes the player setup window panel.close() new_player_panel_proc() @@ -195,7 +194,6 @@ client.prefs.dress_preview_mob(mannequin) var/mob/observer/dead/observer = new(mannequin) observer.moveToNullspace() //Let's not stay in our doomed mannequin - //qdel(mannequin) spawning = 1 if(client.media) @@ -237,13 +235,6 @@ else if(time_till_respawn) // Nonzero time to respawn to_chat(usr, span_warning("You can't respawn yet! You need to wait another [round(time_till_respawn/10/60, 0.1)] minutes.")) return -/* - if(client.prefs.species != "Human" && !check_rights(R_ADMIN, 0)) //VORESTATION EDITS: THE COMMENTED OUT AREAS FROM LINE 154 TO 178 - if (config.usealienwhitelist) - if(!is_alien_whitelisted(src, client.prefs.species)) - tgui_alert(src, "You are currently not whitelisted to Play [client.prefs.species].") - return 0 -*/ LateChoices() if(href_list["manifest"]) @@ -428,14 +419,12 @@ return 0 if(!job.player_old_enough(src.client)) return 0 - //VOREStation Add if(!job.player_has_enough_playtime(src.client)) return 0 if(!is_job_whitelisted(src,rank)) return 0 if(!job.player_has_enough_pto(src.client)) return 0 - //VOREStation Add End return 1 @@ -451,7 +440,7 @@ if(!IsJobAvailable(rank)) tgui_alert_async(src,"[rank] is not available. Please try another.") return 0 - if(!spawn_checks_vr(rank)) return 0 // VOREStation Insert + if(!spawn_checks_vr(rank)) return 0 if(!client) return 0 @@ -530,8 +519,6 @@ // Equip our custom items only AFTER deploying to spawn points eh? equip_custom_items(character) //CHOMPEdit readded to enable custom_item.txt - //character.apply_traits() //VOREStation Removal - // Moving wheelchair if they have one if(character.buckled && istype(character.buckled, /obj/structure/bed/chair/wheelchair)) character.buckled.loc = character.loc @@ -653,27 +640,18 @@ if(mind) mind.active = 0 //we wish to transfer the key manually - // VOREStation edit to disable the destructive forced renaming for our responsible whitelist clowns. - //if(mind.assigned_role == JOB_CLOWN) //give them a clownname if they are a clown - // new_character.real_name = pick(clown_names) //I hate this being here of all places but unfortunately dna is based on real_name! - // new_character.rename_self("clown") mind.original = new_character - // VOREStation mind.loaded_from_ckey = client.ckey mind.loaded_from_slot = client.prefs.default_slot - // VOREStation - //mind.traits = client.prefs.traits.Copy() // VOREStation conflict mind.transfer_to(new_character) //won't transfer key since the mind is not active new_character.name = real_name client.init_verbs() new_character.dna.ready_dna(new_character) new_character.dna.b_type = client.prefs.b_type + new_character.sync_dna_traits(TRUE) // Traitgenes Sync traits to genetics if needed new_character.sync_organ_dna() - if(client.prefs.disabilities) - // Set defer to 1 if you add more crap here so it only recalculates struc_enzymes once. - N3X - new_character.dna.SetSEState(GLASSESBLOCK,1,0) - new_character.disabilities |= NEARSIGHTED + new_character.initialize_vessel() for(var/lang in client.prefs.alternate_languages) var/datum/language/chosen_language = GLOB.all_languages[lang] @@ -718,7 +696,6 @@ src << browse(null, "window=latechoices") //closes late choices window src << browse(null, "window=preferences_window") //VOREStation Edit? src << browse(null, "window=News") //closes news window - //src << browse(null, "window=playersetup") //closes the player setup window panel.close() /mob/new_player/proc/has_admin_rights() diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index df38a2d66c..f1780c31ec 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -224,7 +224,7 @@ // Determine what job is marked as 'High' priority, and dress them up as such. if(job_civilian_low & ASSISTANT) previewJob = job_master.GetJob(JOB_ALT_VISITOR) - else if(ispAI(client.mob)) //VOREStation Edit! - pAIs shouldn't wear job gear~! + else if(client && ispAI(client.mob)) //VOREStation Edit! - pAIs shouldn't wear job gear~! //Don't do anything! else for(var/datum/job/job in job_master.occupations) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 3ce48a784a..21422ef3d6 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -33,8 +33,6 @@ for(var/obj/item/W in src) drop_from_inventory(W) set_species(species.primitive_form) - dna.SetSEState(MONKEYBLOCK,1) - dna.SetSEValueRange(MONKEYBLOCK,0xDAC, 0xFFF) to_chat(src, span_infoplain(span_bold("You are now [species.name]. "))) qdel(animation) @@ -51,12 +49,10 @@ for(var/t in organs) qdel(t) - //VOREStation Edit Start - Hologram examine flavor var/mob/living/silicon/ai/O = ..(move) if(O) O.flavor_text = O.client?.prefs?.flavor_texts["general"] return O - //VOREStation Edit End return ..(move) diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm index e3e9fc9fa0..5b4dbb313e 100644 --- a/code/modules/organs/internal/brain.dm +++ b/code/modules/organs/internal/brain.dm @@ -33,7 +33,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) if(!owner || owner.stat == DEAD) defib_timer = max(--defib_timer, 0) else - defib_timer = min(++defib_timer, (CONFIG_GET(number/defib_timer) MINUTES) / 2) // CHOMPEdit + defib_timer = min(++defib_timer, (CONFIG_GET(number/defib_timer) MINUTES) / 2) /obj/item/organ/internal/brain/proc/can_assist() return can_assist @@ -108,7 +108,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) if(istype(H)) qdel_swap(brainmob.dna, H.dna.Clone()) brainmob.timeofhostdeath = H.timeofdeath - brainmob.ooc_notes = H.ooc_notes //VOREStation Edit + brainmob.ooc_notes = H.ooc_notes brainmob.ooc_notes_likes = H.ooc_notes_likes brainmob.ooc_notes_dislikes = H.ooc_notes_dislikes //CHOMPEdit Start @@ -149,7 +149,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) var/obj/item/organ/internal/brain/B = src if(istype(B) && owner) - if(istype(owner, /mob/living/carbon) && owner.ckey) //CHOMPEdit - Make sure owner's mind isn't elsewhere otherwise on brain removal brings them back + if(istype(owner, /mob/living/carbon) && owner.ckey) B.transfer_identity(owner) ..() @@ -189,7 +189,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) can_assist = FALSE /obj/item/organ/internal/brain/slime - icon = 'icons/obj/surgery_vr.dmi' // Vorestation edit + icon = 'icons/obj/surgery_vr.dmi' name = "slime core" desc = "A complex, organic knot of jelly and crystalline particles." icon_state = "core" @@ -263,7 +263,9 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) qdel_swap(H.dna, R.dna.Clone()) H.UpdateAppearance() + H.sync_dna_traits(FALSE) // Traitgenes Sync traits to genetics if needed H.sync_organ_dna() + H.initialize_vessel() if(!R.dna.real_name) //to prevent null names R.dna.real_name = "promethean ([rand(0,999)])" H.real_name = R.dna.real_name diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index ced6e67256..e3fd134837 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -958,6 +958,16 @@ Note that amputating the affected organ does in fact remove the infection from t span_bolddanger("Your [src.name] explodes[gore]!"),\ span_danger("You hear the [gore_sound].")) + if(DROPLIMB_ACID) + if(cannot_gib) + return + var/gore = "[(robotic >= ORGAN_ROBOT) ? "": " in gush of gore"]" + var/gore_sound = "[(status >= ORGAN_ROBOT) ? "sizzling sound of melting metal" : "sickening drips of melting flesh"]" + owner.visible_message( + span_danger("\The [owner]'s [src.name] sloughs off[gore]!"),\ + span_bolddanger("Your [src.name] sloughs off of your body[gore]!"),\ + span_danger("You hear the [gore_sound].")) + var/mob/living/carbon/human/victim = owner //Keep a reference for post-removed(). var/obj/item/organ/external/parent_organ = parent @@ -1036,6 +1046,14 @@ Note that amputating the affected organ does in fact remove the infection from t qdel(src) + if(DROPLIMB_ACID) + appearance_flags &= ~PIXEL_SCALE + compile_icon() + add_blood(victim) + var/matrix/M = matrix() + M.Turn(rand(180)) + transform = M + if(victim.l_hand) if(istype(victim.l_hand,/obj/item/material/twohanded)) //if they're holding a two-handed weapon, drop it now they've lost a hand victim.l_hand.update_held_icon() diff --git a/code/modules/organs/wound.dm b/code/modules/organs/wound.dm index 164307ba68..459be11ca2 100644 --- a/code/modules/organs/wound.dm +++ b/code/modules/organs/wound.dm @@ -396,6 +396,15 @@ "scarred stump" = 0 ) + if(DROPLIMB_ACID) + damage_type = BURN + stages = list( + "disfigured mass" = damage_amt*1.3, + "melted stump" = damage_amt, + "deformed stump" = damage_amt*0.5, + "scarred stump" = 0 + ) + ..(damage_amt) /datum/wound/lost_limb/can_merge(var/datum/wound/other) diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index e4206c30c9..26fd05bf6b 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -578,3 +578,7 @@ M.adjustToxLoss(-5) M.adjustOxyLoss(-5) return 1 + +/obj/item/projectile/beam/laser_vision + name = "laser" + damage = 10 diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 31c9d00fa1..10afbca44e 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -173,6 +173,7 @@ else randmutg(M) domutcheck(M,null) + H.UpdateAppearance() else M.adjustFireLoss(rand(5,15)) M.show_message(span_red("The radiation beam singes you!")) diff --git a/code/modules/reagents/reagents/medicine.dm b/code/modules/reagents/reagents/medicine.dm index 912d8c4ede..f32f4b94bd 100644 --- a/code/modules/reagents/reagents/medicine.dm +++ b/code/modules/reagents/reagents/medicine.dm @@ -725,7 +725,6 @@ M.heal_organ_damage(3 * removed, 0) //Gives the bones a chance to set properly even without other meds if(ishuman(M)) var/mob/living/carbon/human/H = M - //CHOMPEdit Begin var/totalvol = 0 if(H.ingested) for(var/datum/reagent/R in H.ingested.reagent_list) @@ -736,10 +735,10 @@ for(var/obj/item/organ/external/O in H.bad_external_organs) if(O.status & ORGAN_BROKEN) O.mend_fracture() //Only works if the bone won't rebreak, as usual - H.custom_pain("You feel a terrible agony tear through your bones!",60) + H.custom_pain(span_danger("You feel a terrible agony tear through your [O.name]!"),60,TRUE) + H.AdjustWeakened(10) //Bones being regrown will knock you over H.adjustHalLoss(60) - H.AdjustStunned(1) //Bones being regrown will knock you over - CHOMPEdit - Crawling made this trivial, get stunned - //CHOMPEdit End + H.AdjustStunned(1) //Bones being regrown will knock you over /datum/reagent/myelamine name = REAGENT_MYELAMINE @@ -747,11 +746,11 @@ description = "Used to rapidly clot internal hemorrhages by increasing the effectiveness of platelets." reagent_state = LIQUID color = "#4246C7" - metabolism = REM * 0.75 //CHOMPEdit + metabolism = REM * 0.75 overdose = REAGENTS_OVERDOSE * 0.5 overdose_mod = 1.5 scannable = 1 - var/repair_strength = 6 //CHOMPEdit + var/repair_strength = 6 /datum/reagent/myelamine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_DIONA) @@ -925,6 +924,7 @@ overdose = 20 overdose_mod = 1.5 scannable = 1 + metabolism = REM * 0.06 /datum/reagent/immunosuprizine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) var/strength_mod = 1 * M.species.chem_strength_heal @@ -972,14 +972,14 @@ H.adjustToxLoss((15 / strength_mod)) I.take_damage(1) -/datum/reagent/skrellimmuno +/datum/reagent/skrellimmuno //skrell exist? name = REAGENT_MALISHQUALEM id = REAGENT_ID_MALISHQUALEM description = "A strange, oily powder used by Malish-Katish to prevent organ rejection." taste_description = "mordant" reagent_state = SOLID color = "#84B2B0" - metabolism = REM * 0.75 + metabolism = REM * 0.06 overdose = 20 overdose_mod = 1.5 scannable = 1 @@ -1021,49 +1021,18 @@ /datum/reagent/ryetalyn name = REAGENT_RYETALYN id = REAGENT_ID_RYETALYN - description = REAGENT_RYETALYN + " can cure all genetic abnomalities via a catalytic process." + description = REAGENT_RYETALYN + " can cure DNA, Cloning, and genetic damage via a catalytic process." taste_description = "acid" reagent_state = SOLID color = "#004000" overdose = REAGENTS_OVERDOSE /datum/reagent/ryetalyn/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) - var/needs_update = M.mutations.len > 0 - - M.mutations = list() - M.disabilities = 0 - M.sdisabilities = 0 - - var/mob/living/carbon/human/H = M - if(alien == IS_SLIME && istype(H)) //Shifts them toward white, faster than Rezadone does toward grey. - if(prob(50)) - if(H.r_skin) - H.r_skin = round((H.r_skin + 510)/3) - if(H.r_hair) - H.r_hair = round((H.r_hair + 510)/3) - if(H.r_facial) - H.r_facial = round((H.r_facial + 510)/3) - H.adjustToxLoss(6 * removed) - if(prob(50)) - if(H.g_skin) - H.g_skin = round((H.g_skin + 510)/3) - if(H.g_hair) - H.g_hair = round((H.g_hair + 510)/3) - if(H.g_facial) - H.g_facial = round((H.g_facial + 510)/3) - H.adjustToxLoss(6 * removed) - if(prob(50)) - if(H.b_skin) - H.b_skin = round((H.b_skin + 510)/3) - if(H.b_hair) - H.b_hair = round((H.b_hair + 510)/3) - if(H.b_facial) - H.b_facial = round((H.b_facial + 510)/3) - H.adjustToxLoss(6 * removed) - - // Might need to update appearance for hulk etc. - if(needs_update && ishuman(M)) - H.update_mutations() + //Ryetalyn is for genetics damage curing not resetting mutations, breaks traitgenes + if(alien == IS_DIONA) + return + var/chem_effective = 1 * M.species.chem_strength_heal + M.adjustCloneLoss(-2 * removed * chem_effective) /*/datum/reagent/hyperzine name = REAGENT_HYPERZINE @@ -1232,7 +1201,7 @@ var/obj/item/organ/external/O = pick(H.organs) if(prob(20) && !istype(O, /obj/item/organ/external/chest/unbreakable/slime) && !istype(O, /obj/item/organ/external/groin/unbreakable/slime)) to_chat(M, span_critical("You feel your [O] begin to dissolve, before it sloughs from your body.")) - O.droplimb() //Splat. + O.droplimb(TRUE, DROPLIMB_ACID) return //Based roughly on Levofloxacin's rather severe side-effects @@ -1246,7 +1215,7 @@ M.hallucination = max(M.hallucination, 10) //One of the levofloxacin side effects is 'spontaneous tendon rupture', which I'll immitate here. 1:1000 chance, so, pretty darn rare. - if(ishuman(M) && rand(1,10000) == 1) //VOREStation Edit (more rare) + if(ishuman(M) && rand(1,10000) == 1) //Adjusted to 1:10000 var/obj/item/organ/external/eo = pick(H.organs) //Misleading variable name, 'organs' is only external organs eo.fracture() diff --git a/code/modules/reagents/reagents/toxins.dm b/code/modules/reagents/reagents/toxins.dm index 06126f6854..bf95c1a8ea 100644 --- a/code/modules/reagents/reagents/toxins.dm +++ b/code/modules/reagents/reagents/toxins.dm @@ -186,12 +186,12 @@ taste_mult = 0.6 reagent_state = LIQUID color = "#CF3600" - strength = 15 //CHOMPEdit this shit needs to be changed sheesh - metabolism = REM * 0.5 //CHOMPEdit holy balls + strength = 15 + metabolism = REM * 0.5 /datum/reagent/toxin/cyanide/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) ..() - M.adjustOxyLoss(10 * removed) //CHOMPEdit the fucking toxins are already crazy enough, calm down + M.adjustOxyLoss(10 * removed) M.Sleeping(1) /datum/reagent/toxin/mold @@ -624,16 +624,12 @@ if(M.dna) if(prob(removed * 10)) // Removed is .2 per tick. Multiplying it by 10 makes it a 2% chance per tick. 10 units has 50 ticks, so 10 units injected should give a single good/bad mutation. - randmuti(M) if(prob(98)) randmutb(M) else randmutg(M) domutcheck(M, null) M.UpdateAppearance() - if(prob(removed * 40)) //Additionally, let's make it so there's an 8% chance per tick for a random cosmetic/not guranteed good/bad mutation. - randmuti(M)//This should equate to 4 random cosmetic mutations per 10 injected/20 ingested/30 touching units - to_chat(M, span_warning("You feel odd!")) M.apply_effect(10 * removed, IRRADIATE, 0) /datum/reagent/slimejelly @@ -896,16 +892,12 @@ if(M.dna) if(prob(removed * 10)) - randmuti(M) if(prob(98)) randmutb(M) else randmutg(M) domutcheck(M, null) M.UpdateAppearance() - if(prob(removed * 40)) - randmuti(M) - to_chat(M, span_warning("You feel odd!")) M.apply_effect(16 * removed, IRRADIATE, 0) /datum/reagent/aslimetoxin @@ -916,7 +908,7 @@ reagent_state = LIQUID color = "#FF69B4" -/datum/reagent/aslimetoxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) // TODO: check if there's similar code anywhere else +/datum/reagent/aslimetoxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(M.isSynthetic()) return @@ -926,16 +918,12 @@ if(M.dna) if(prob(removed * 10)) - randmuti(M) if(prob(98)) randmutb(M) else randmutg(M) domutcheck(M, null) M.UpdateAppearance() - if(prob(removed * 40)) - randmuti(M) - to_chat(M, span_warning("You feel odd!")) M.apply_effect(6 * removed, IRRADIATE, 0) /* diff --git a/code/modules/resleeving/autoresleever.dm b/code/modules/resleeving/autoresleever.dm index e8442649cb..f23b84c9fd 100644 --- a/code/modules/resleeving/autoresleever.dm +++ b/code/modules/resleeving/autoresleever.dm @@ -133,8 +133,15 @@ spawn_slots -- return + var/slot = ghost.client.prefs.default_slot if(tgui_alert(ghost, "Would you like to be resleeved?", "Resleeve", list("No","Yes")) != "Yes") return + //This keeps people from dying in round, clicking the autoresleever, then swapping savefiles and clicking 'yes' + if(slot != ghost.client.prefs.default_slot && (!equip_body || !ghost_spawns)) + var/turf/T = get_turf(src) + to_chat(ghost, span_warning("It appears as though your loaded character has not been spawned this round, or has quit the round. If you died as a different character, please load them, and try again.")) + message_admins("[key_name_admin(ghost)] swapped savefiles while using the autosleever and tried to spawn as another character! [ADMIN_JMP(T)]") + return var/mob/living/carbon/human/new_character new_character = new(spawnloc) @@ -147,7 +154,9 @@ ghost_client.prefs.copy_to(new_character) if(new_character.dna) new_character.dna.ResetUIFrom(new_character) + new_character.sync_dna_traits(TRUE) // Traitgenes Sync traits to genetics if needed new_character.sync_organ_dna() + new_character.initialize_vessel() if(ghost.mind) ghost.mind.transfer_to(new_character) @@ -172,12 +181,10 @@ var/datum/language/keylang = GLOB.all_languages[ghost_client.prefs.language_custom_keys[key]] if(keylang) new_character.language_keys[key] = keylang - // VOREStation Add: Preferred Language Setting; if(ghost_client.prefs.preferred_language) // Do we have a preferred language? var/datum/language/def_lang = GLOB.all_languages[ghost_client.prefs.preferred_language] if(def_lang) new_character.default_language = def_lang - // VOREStation Add End //If desired, apply equipment. if(equip_body) @@ -217,6 +224,9 @@ new path(nif) nif.durability = record.nif_durability + if(!new_character.dna) + CRASH("[new_character] just came out of an autosleever and has no DNA! Species: [new_character.species] as mob: [new_character.type]. NIF Status: [new_character.nif]") + if(spawn_slots == -1) return else if(spawn_slots == 0) diff --git a/code/modules/resleeving/computers.dm b/code/modules/resleeving/computers.dm index 7518d62dc9..49c160179c 100644 --- a/code/modules/resleeving/computers.dm +++ b/code/modules/resleeving/computers.dm @@ -8,6 +8,7 @@ icon_keyboard = "med_key" icon_screen = "dna" light_color = "#315ab4" + bubble_icon = "medical" circuit = /obj/item/circuitboard/resleeving_control req_access = list(access_heads) //Only used for record deletion right now. var/list/pods = null //Linked grower pods. @@ -32,6 +33,8 @@ var/db_key var/datum/transcore_db/our_db // These persist all round and are never destroyed, just keep a hard ref + var/gene_sequencing = FALSE // Traitgenes edit - create a dna injector for fixing dna, but don't let it be abusable + /obj/machinery/computer/transhuman/resleeving/Initialize() . = ..() pods = list() @@ -444,10 +447,35 @@ if("menu") menu = clamp(text2num(params["num"]), MENU_MAIN, MENU_MIND) . = TRUE + // Traitgenes edit begin - create a dna injector based off the BR currently selected, to allow normal doctors to reset someone's SEs + if("genereset") + if(gene_sequencing) + set_temp("Sequencing Record... Please wait.") + tgui_modal_clear(src) + else if(istype(active_br)) + set_temp("Sequencing Record...") + tgui_modal_clear(src) + gene_sequencing = TRUE + // Make the injector here, so no desync + var/obj/item/dnainjector/I = new(src) + I.name += " ([active_br.mydna.name] - Resequencer)" + I.desc = "Resequences structural enzymes to match the body record this was created from." + I.buf = active_br.mydna.copy() + I.buf.types = DNA2_BUF_SE + atom_say("Beginning injector synthesis.") + addtimer(CALLBACK(src, PROC_REF(dispense_injector), I), 10 SECONDS, TIMER_DELETE_ME) + . = TRUE if("cleartemp") temp = null . = TRUE +/obj/machinery/computer/transhuman/resleeving/proc/dispense_injector(var/obj/item/dnainjector/I) + I.forceMove(loc) + gene_sequencing = FALSE + set_temp("Injector dispensed...") + visible_message(span_notice("\The [src] ejects \the [I].")) + playsound(src, 'sound/machines/ding.ogg', 50, 1) + // In here because only relevant to computer /obj/item/cmo_disk_holder name = "cmo emergency packet" diff --git a/code/modules/resleeving/machines.dm b/code/modules/resleeving/machines.dm index 03ca720a28..5c4b315248 100644 --- a/code/modules/resleeving/machines.dm +++ b/code/modules/resleeving/machines.dm @@ -75,20 +75,6 @@ else if(status == 3) //Digital organ I.digitize() - //Give breathing equipment if needed - if(current_project.breath_type != GAS_O2) - H.equip_to_slot_or_del(new /obj/item/clothing/mask/breath(H), slot_wear_mask) - var/obj/item/tank/tankpath - if(current_project.breath_type == GAS_PHORON) - tankpath = /obj/item/tank/vox - else - tankpath = text2path("/obj/item/tank/" + current_project.breath_type) - - if(tankpath) - H.equip_to_slot_or_del(new tankpath(H), slot_back) - H.internal = H.back - if(istype(H.internal,/obj/item/tank) && H.internals) - H.internals.icon_state = "internal1" occupant = H @@ -111,20 +97,32 @@ H.dna.digitigrade = R.dna.digitigrade // ensure cloned DNA is set appropriately from record??? for some reason it doesn't get set right despite the override to datum/dna/Clone() //Apply damage - H.adjustCloneLoss((H.getMaxHealth() - CONFIG_GET(number/health_threshold_dead))*-0.75) // CHOMPEdit + H.adjustCloneLoss((H.getMaxHealth() - CONFIG_GET(number/health_threshold_dead))*-0.75) H.Paralyse(4) H.updatehealth() - //Grower specific mutations - if(heal_level < 60) - randmutb(H) - H.dna.UpdateSE() - H.dna.UpdateUI() - //Update appearance, remake icons H.UpdateAppearance() + H.sync_dna_traits(FALSE) // Traitgenes Sync traits to genetics if needed H.sync_organ_dna() H.regenerate_icons() + H.initialize_vessel() + + // Traitgenes Moved breathing equipment to AFTER the genes set it + //Give breathing equipment if needed + if(current_project.breath_type != null && current_project.breath_type != GAS_O2) + H.equip_to_slot_or_del(new /obj/item/clothing/mask/breath(H), slot_wear_mask) + var/obj/item/tank/tankpath + if(current_project.breath_type == GAS_PHORON) + tankpath = /obj/item/tank/vox + else + tankpath = text2path("/obj/item/tank/" + current_project.breath_type) + + if(tankpath) + H.equip_to_slot_or_del(new tankpath(H), slot_back) + H.internal = H.back + if(istype(H.internal,/obj/item/tank) && H.internals) + H.internals.icon_state = "internal1" //Basically all the VORE stuff H.ooc_notes = current_project.body_oocnotes @@ -357,6 +355,11 @@ qdel_swap(H.dna, R.dna.Clone()) H.original_player = current_project.ckey + //Apply legs + H.digitigrade = R.dna.digitigrade // ensure clone mob has digitigrade var set appropriately + if(H.dna.digitigrade <> R.dna.digitigrade) + H.dna.digitigrade = R.dna.digitigrade // ensure cloned DNA is set appropriately from record??? for some reason it doesn't get set right despite the override to datum/dna/Clone() + //Apply damage H.adjustBruteLoss(brute_value) H.adjustFireLoss(burn_value) @@ -364,8 +367,10 @@ //Update appearance, remake icons H.UpdateAppearance() + H.sync_dna_traits(FALSE) // Traitgenes Sync traits to genetics if needed H.sync_organ_dna() H.regenerate_icons() + H.initialize_vessel() //Basically all the VORE stuff H.ooc_notes = current_project.body_oocnotes @@ -466,7 +471,6 @@ anchored = TRUE var/blur_amount var/confuse_amount - // var/sickness_duration // CHOMPRemove var/mob/living/carbon/human/occupant = null var/connected = null @@ -496,12 +500,7 @@ manip_rating += M.rating blur_amount = (48 - manip_rating * 8) - /* CHOMPRemove Start - var/total_rating = manip_rating + scan_rating - sickness_duration = (45 - (total_rating-4)*1.875) MINUTES // 45 minutes default, 30 minutes with max non-anomaly upgrades, 15 minutes with max anomaly ones - */// CHOMPRemove End - -/obj/machinery/transhuman/resleever/attack_hand(mob/user) +/obj/machinery/transhuman/resleever/attack_hand(mob/user as mob) tgui_interact(user) /obj/machinery/transhuman/resleever/tgui_interact(mob/user, datum/tgui/ui = null) @@ -524,18 +523,6 @@ data["stat"] = occupant.stat data["mindStatus"] = !!occupant.mind data["mindName"] = occupant.mind?.name -/* CHOMP Edit: Get rid of resleeving sickness stuff - if(occupant.has_modifier_of_type(/datum/modifier/resleeving_sickness) || occupant.has_modifier_of_type(/datum/modifier/faux_resleeving_sickness)) - data["resleeveSick"] = TRUE - else - data["resleeveSick"] = FALSE - - if(occupant.confused || occupant.eye_blurry) - data["initialSick"] = TRUE - else - data["initialSick"] = FALSE -*/ -//End chomp edit return data /obj/machinery/transhuman/resleever/attackby(obj/item/W, mob/user) @@ -668,19 +655,10 @@ occupant.confused = max(occupant.confused, confuse_amount) occupant.eye_blurry = max(occupant.eye_blurry, blur_amount) - /* CHOMPRemove Start // Vore deaths get a fake modifier labeled as such if(!occupant.mind) log_debug("[occupant] didn't have a mind to check for vore_death, which may be problematic.") - if(occupant.mind?.vore_death) - occupant.add_modifier(/datum/modifier/faux_resleeving_sickness, sickness_duration) - occupant.mind.vore_death = FALSE - // Normal ones get a normal modifier to nerf charging into combat - else - occupant.add_modifier(/datum/modifier/resleeving_sickness, sickness_duration) - */// CHOMPRemove End - if(occupant.mind && occupant.original_player && ckey(occupant.mind.key) != occupant.original_player) log_and_message_admins("is now a cross-sleeved character. Body originally belonged to [occupant.real_name]. Mind is now [occupant.mind.name].",occupant) diff --git a/code/modules/tgui/modules/appearance_changer.dm b/code/modules/tgui/modules/appearance_changer.dm index e97890bd25..d07835079d 100644 --- a/code/modules/tgui/modules/appearance_changer.dm +++ b/code/modules/tgui/modules/appearance_changer.dm @@ -993,7 +993,7 @@ // ******************************************************* /datum/tgui_module/appearance_changer/cocoon name ="Appearance Editor (Cocoon)" - flags = APPEARANCE_ALL_HAIR + flags = APPEARANCE_ALL_HAIR | APPEARANCE_EYE_COLOR | APPEARANCE_SKIN customize_usr = TRUE /datum/tgui_module/appearance_changer/cocoon/tgui_status(mob/user, datum/tgui_state/state) @@ -1002,6 +1002,20 @@ return STATUS_CLOSE return ..() +// ******************************************************* +// Morph Superpower +// ******************************************************* +/datum/tgui_module/appearance_changer/superpower + name ="Appearance Editor (Superpower)" + flags = APPEARANCE_ALL_HAIR | APPEARANCE_EYE_COLOR | APPEARANCE_SKIN + customize_usr = TRUE + +/datum/tgui_module/appearance_changer/superpower/tgui_status(mob/user, datum/tgui_state/state) + var/datum/gene/G = get_gene_from_trait(/datum/trait/positive/superpower_morph) + if(!owner.dna.GetSEState(G.block)) + return STATUS_CLOSE + return ..() + // ******************************************************* // Body design console // ******************************************************* @@ -1079,8 +1093,9 @@ owner.dna.digitigrade = R.dna.digitigrade // ensure cloned DNA is set appropriately from record??? for some reason it doesn't get set right despite the override to datum/dna/Clone() //Update appearance, remake icons owner.UpdateAppearance() - //owner.sync_dna_traits(FALSE) //Needs trait genetics first + owner.sync_dna_traits(FALSE) owner.sync_organ_dna() + owner.initialize_vessel() owner.dna.blood_reagents = R.dna.blood_reagents owner.dna.blood_color = R.dna.blood_color owner.regenerate_icons() diff --git a/code/modules/vchat/css/ss13styles.css b/code/modules/vchat/css/ss13styles.css index f5cce8a32a..275d93d02f 100644 --- a/code/modules/vchat/css/ss13styles.css +++ b/code/modules/vchat/css/ss13styles.css @@ -194,10 +194,8 @@ h1.alert, h2.alert {color: #000000;} .say_quote_italics {font-style: italic; font-family: Georgia, Verdana, sans-serif;} .terminus {font-family: "Times New Roman", Times, serif, sans-serif} .interface {color: #330033;} -/* YW Edit start */ -.psionic {color: #993399;} -.wingdings {font-family: Wingdings, Webdings} -/* YW Edit End */ +.psionic {color: #993399;} +.wingdings {color: #0077FF;font-family: Wingdings, Webdings} .spacer {color: #9c660b;} /* VOREStation Add */ .blob {color: #ff950d; font-weight: bold; font-style: italic;} .teppi {color: #816540; word-spacing:4pt; font-family: "Segoe Script Bold","Segoe Script",sans-serif,Verdana;} diff --git a/code/modules/vore/eating/inbelly_spawn.dm b/code/modules/vore/eating/inbelly_spawn.dm index d763c0f073..655ad0e483 100644 --- a/code/modules/vore/eating/inbelly_spawn.dm +++ b/code/modules/vore/eating/inbelly_spawn.dm @@ -68,7 +68,7 @@ Please do not abuse this ability. return // Are we cool with this prey spawning in at all? - var/answer = tgui_alert(src, "[potential_prey.prefs.real_name] wants to spawn in one of your bellies. Do you accept?", "Inbelly Spawning", list("Yes", "No")) //CHOMPEdit - hides ckey + var/answer = tgui_alert(src, "[potential_prey.prefs.real_name] wants to spawn in one of your bellies. Do you accept?", "Inbelly Spawning", list("Yes", "No")) if(answer != "Yes") to_chat(potential_prey, span_notice("Your request was turned down.")) return @@ -144,7 +144,9 @@ Please do not abuse this ability. prey.prefs.copy_to(new_character) if(new_character.dna) new_character.dna.ResetUIFrom(new_character) + new_character.sync_dna_traits(TRUE) // Traitgenes Sync traits to genetics if needed new_character.sync_organ_dna() + new_character.initialize_vessel() new_character.key = player_key if(new_character.mind) var/datum/antagonist/antag_data = get_antag_data(new_character.mind.special_role) diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm index 898cf356fc..4788761078 100644 --- a/code/modules/vore/eating/living_vr.dm +++ b/code/modules/vore/eating/living_vr.dm @@ -458,14 +458,14 @@ return load_character(slotnum) - attempt_vr(user.client?.prefs_vr,"load_vore","") //VOREStation Edit + attempt_vr(user.client?.prefs_vr,"load_vore","") sanitize_preferences() return remember_default /datum/preferences/proc/return_to_character_slot(mob/user, var/remembered_default) load_character(remembered_default) - attempt_vr(user.client?.prefs_vr,"load_vore","") //VOREStation Edit + attempt_vr(user.client?.prefs_vr,"load_vore","") sanitize_preferences() // diff --git a/code/unit_tests/genetics_tests.dm b/code/unit_tests/genetics_tests.dm new file mode 100644 index 0000000000..f5da724d54 --- /dev/null +++ b/code/unit_tests/genetics_tests.dm @@ -0,0 +1,160 @@ +/datum/unit_test/enough_free_gene_slots_must_be_available + name = "GENETICS: Enough free gene slots must be available." + +/datum/unit_test/enough_free_gene_slots_must_be_available/start_test() + var/failed = FALSE + + if(GLOB.dna_genes.len > (DNA_SE_LENGTH - 10)) // Based off of traitgenes scanned on startup + failed = TRUE + + if(failed) + fail("Too few geneslots are empty, minimum 10. Increase DNA_SE_LENGTH.") + else + pass("DNA_SE_LENGTH has enough free space remaining.") + return failed + + +/datum/unit_test/enough_positive_genes_must_exist + name = "GENETICS: Must be at least one positive gene." + +/datum/unit_test/enough_positive_genes_must_exist/start_test() + var/failed = FALSE + + if(GLOB.dna_genes_good.len < 1) // Based off of traitgenes scanned on startup + failed = TRUE + + if(failed) + fail("Must have at least one positive gene.") + else + pass("Has at least one positive gene.") + return failed + + +/datum/unit_test/enough_neutral_genes_must_exist + name = "GENETICS: Must be at least one neutral gene." + +/datum/unit_test/enough_neutral_genes_must_exist/start_test() + var/failed = FALSE + + if(GLOB.dna_genes_neutral.len < 1) // Based off of traitgenes scanned on startup + failed = TRUE + + if(failed) + fail("Must have at least one neutral gene.") + else + pass("Has at least one neutral gene.") + return failed + + +/datum/unit_test/enough_bad_genes_must_exist + name = "GENETICS: Must be at least one bad gene." + +/datum/unit_test/enough_bad_genes_must_exist/start_test() + var/failed = FALSE + + if(GLOB.dna_genes_bad.len < 1) // Based off of traitgenes scanned on startup + failed = TRUE + + if(failed) + fail("Must have at least one bad gene.") + else + pass("Has at least one bad gene.") + return failed + + +/datum/unit_test/all_dna_injectors_must_be_valid + name = "GENETICS: All dna injectors must be valid." + +/datum/unit_test/all_dna_injectors_must_be_valid/start_test() + var/failed = FALSE + + for(var/injector_path in subtypesof(/obj/item/dnainjector/set_trait)) + var/obj/item/dnainjector/D = new injector_path() + if(!D.block) + log_unit_test("[injector_path]: Genetics - Injector could not resolve geneblock for trait. Missing traitgene?") + failed = TRUE + qdel(D) + + if(failed) + fail("Dna injectors have traits that are not genetraits or are missing.") + else + pass("No invalid dna injectors.") + return failed + + +/datum/unit_test/all_genes_shall_have_unique_name + name = "GENETICS: All genes shall be init with unique names." + +/datum/unit_test/all_genes_shall_have_unique_name/start_test() + var/failed = FALSE + + var/collection = list() + for(var/datum/gene/G in GLOB.dna_genes) + if(collection[G.name]) + log_unit_test("[G.name]: Genetics - Gene name was already in use.") + failed = TRUE + else + collection[G.name] = G.name + + if(failed) + fail("Genes shared names. This should not be possible on init, all genes should have their blocknumber attached to them to ensure unique names.") + else + pass("All genes have unique names to use as list ids.") + return failed + + + +/datum/unit_test/genetraits_should_have_valid_dna_bounds + name = "GENETICS: All genes should have valid activation bounds." + +/datum/unit_test/genetraits_should_have_valid_dna_bounds/start_test() + var/failed = FALSE + + for(var/datum/gene/trait/G in GLOB.trait_to_dna_genes) + if(!G.linked_trait) + log_unit_test("[G.name]: Genetics - Has missing linked trait.") + failed = TRUE + continue + + if(!G.linked_trait.activity_bounds) + log_unit_test("[G.name]: Genetics - Has no activation bounds.") + failed = TRUE + continue + + if(!G.linked_trait.activity_bounds.len) + log_unit_test("[G.name]: Genetics - Has empty activation bounds.") + failed = TRUE + continue + + // DNA activation bounds. Usually they are in a list as follows: + // [1]DNA_OFF_LOWERBOUND = 1, begining of the threshold where a gene turns off. + // [2]DNA_OFF_UPPERBOUND = a number above 1, end of the treshold where a gene turns off. + // [3]DNA_ON_LOWERBOUND = a number above DNA_OFF_UPPERBOUND(even if just by 1), threshold where a gene turns on. + // [4]DNA_ON_UPPERBOUND = 4095, end of the threshold where a gene turns on. + + var/list/bounds = G.linked_trait.activity_bounds + if(bounds[1] < 1) // lowest value a gene can be to turn off + log_unit_test("[G.name]: Genetics - DNA_OFF_LOWERBOUND, was smaller than 1.") + failed = TRUE + + if(bounds[2] < bounds[1]) + log_unit_test("[G.name]: Genetics - DNA_OFF_UPPERBOUND must be larger than DNA_OFF_LOWERBOUND, and never equal.") + failed = TRUE + + if(bounds[2] >= bounds[3]) + log_unit_test("[G.name]: Genetics - DNA_OFF_UPPERBOUND must be smaller than DNA_ON_LOWERBOUND, and never equal.") + failed = TRUE + + if(bounds[3] > bounds[4]) + log_unit_test("[G.name]: Genetics - DNA_ON_LOWERBOUND must be smaller than DNA_ON_UPPERBOUND, and never equal.") + failed = TRUE + + if(bounds[4] > 4095) // highest value a gene can be to turn on + log_unit_test("[G.name]: Genetics - DNA_ON_UPPERBOUND, was larger than 4095.") + failed = TRUE + + if(failed) + fail("Invalid activity bounds for one or more traitgenes") + else + pass("All traitgenes have activity bounds, and activity bounds are legal.") + return failed diff --git a/maps/stellar_delight/stellar_delight.dm b/maps/stellar_delight/stellar_delight.dm index 91f26246b7..d6ee68db94 100644 --- a/maps/stellar_delight/stellar_delight.dm +++ b/maps/stellar_delight/stellar_delight.dm @@ -21,6 +21,6 @@ #elif !defined(MAP_OVERRIDE) - #warn A map has already been included, ignoring Tether + #warn A map has already been included, ignoring Stellar Delight #endif diff --git a/maps/yw/cryogaia-04-maintenance.dmm b/maps/yw/cryogaia-04-maintenance.dmm index 9184978011..9b5341ade2 100644 --- a/maps/yw/cryogaia-04-maintenance.dmm +++ b/maps/yw/cryogaia-04-maintenance.dmm @@ -4349,16 +4349,16 @@ /obj/structure/safe/floor{ name = "Vault of Memories" }, -/obj/item/dnainjector/tourmut{ +/obj/item/dnainjector/set_trait/tourettes{ name = "\improper DNA injector (???)" }, -/obj/item/dnainjector/hallucination{ +/obj/item/dnainjector/set_trait/flashproof{ name = "\improper DNA injector (???)" }, -/obj/item/dnainjector/firemut{ +/obj/item/dnainjector/set_trait/heatadapt{ name = "\improper DNA injector (???)" }, -/obj/item/dnainjector/firemut{ +/obj/item/dnainjector/set_trait/heatadapt{ name = "\improper DNA injector (???)" }, /obj/item/clothing/under/rank/geneticist{ diff --git a/maps/yw/submaps/beach/backup/beach.dmm b/maps/yw/submaps/beach/backup/beach.dmm index 98fd7672d0..e5407fc3c3 100644 --- a/maps/yw/submaps/beach/backup/beach.dmm +++ b/maps/yw/submaps/beach/backup/beach.dmm @@ -85,7 +85,7 @@ /turf/simulated/mineral/floor/ignore_mapgen, /area/tether_away/beach/jungle) "ax" = ( -/obj/item/dnainjector/regenerate, +/obj/item/dnainjector/set_trait/regenerate, /turf/simulated/mineral/floor/ignore_mapgen, /area/tether_away/beach/jungle) "ay" = ( diff --git a/maps/yw/submaps/beach/beach.dmm b/maps/yw/submaps/beach/beach.dmm index 11f60fdf97..f70ab6288c 100644 --- a/maps/yw/submaps/beach/beach.dmm +++ b/maps/yw/submaps/beach/beach.dmm @@ -658,7 +658,7 @@ /turf/simulated/floor/tiled/asteroid_steel, /area/tether_away/beach/outpost) "Ji" = ( -/obj/item/dnainjector/regenerate, +/obj/item/dnainjector/set_trait/regenerate, /turf/simulated/mineral/floor/ignore_mapgen, /area/tether_away/beach/jungle) "Jv" = ( diff --git a/modular_chomp/code/__defines/span.dm b/modular_chomp/code/__defines/span.dm deleted file mode 100644 index e9ef173f51..0000000000 --- a/modular_chomp/code/__defines/span.dm +++ /dev/null @@ -1,4 +0,0 @@ -#define span_major_announcement_text(str) ("" + str + "") -#define span_major_announcement_title(str) ("" + str + "") -#define span_ooc_announcement_text(str) ("" + str + "") -#define span_subheader_announcement_text(str) ("" + str + "") diff --git a/modular_chomp/code/game/objects/effects/step_triggers.dm b/modular_chomp/code/game/objects/effects/step_triggers.dm deleted file mode 100644 index 00014dccb4..0000000000 --- a/modular_chomp/code/game/objects/effects/step_triggers.dm +++ /dev/null @@ -1,103 +0,0 @@ -GLOBAL_LIST_EMPTY(mapped_autostrips) -GLOBAL_LIST_EMPTY(mapped_autostrips_mob) - -/* -This should actually be refactored if it ever needs to be used again into just being -an event controller with more graceful solutions. -Creating lockers was not graceful, in practice, and creates clutter, for example. -Repurpose this idea into a self contained machine in the future that stores and auto-equips someones gear. - -But for now, for what it's been used for, it works. - -*/ - -//Admin tool to automatically strip a human victim of all their equipment and genetics powers, and store them in a closet. -//Equips Vox/Zaddat survival gear, and a few basic pieces of clothing -/obj/effect/step_trigger/autostrip - name = "Autostrip trigger. Set the targetid to match the effect/autostriptarget" - var/targetid = "Default" - var/obj/effect/autostriptarget/target - var/obj/effect/autostriptarget/mob/Mtarget - var/remove_implants = 0 //Havn't bothered to implement this yet - var/remove_mutations = 0 - -/obj/effect/step_trigger/autostrip/Initialize(mapload) - . = ..() - initMappedLink() - -/obj/effect/step_trigger/autostrip/Trigger(mob/living/carbon/human/H as mob) - if(!istype(H)) - return - if(!target) - if(!initMappedLink()) - return - if(Mtarget) - H.forceMove(Mtarget.loc) - var/obj/locker = new /obj/structure/closet/secure_closet/mind(target.loc, mind_target = H.mind) - for(var/obj/item/W in H) - if(istype(W, /obj/item/implant/backup) || istype(W, /obj/item/nif)) - continue //VOREStation Edit - if(H.drop_from_inventory(W)) - W.forceMove(locker) - - if(remove_mutations) - var/needs_update = H.mutations.len > 0 - for(var/entry in H.mutations) - var/mut - switch(entry) - if(TK) - mut = TELEBLOCK - if(XRAY) - mut = XRAYBLOCK - if(HULK) - mut = HULKBLOCK - if(mRemotetalk) - mut = REMOTETALKBLOCK - if(COLD_RESISTANCE) - mut = FIREBLOCK - if(mut) - new /obj/item/dnainjector/safe(locker, block_type = mut) - H.dna.SetSEState(mut,0) - H.mutations = list() - H.disabilities = 0 - H.sdisabilities = 0 - if(needs_update) - domutcheck(H,null,MUTCHK_FORCED) - H.update_mutations() - if(H.species.name == SPECIES_VOX || SPECIES_ZADDAT) //Species that 'actually' require survival gear to live. The rest don't. - H.species.equip_survival_gear(H) - H.equip_to_slot_or_del(new /obj/item/clothing/under/chameleon(H), slot_w_uniform) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H),slot_shoes) - H.equip_to_slot_or_del(new /obj/item/radio/headset(H),slot_l_ear) - H.equip_to_slot_or_del(new /obj/item/clothing/under/permit(H), slot_l_hand) - - -/obj/effect/step_trigger/autostrip/proc/initMappedLink() - . = FALSE - target = GLOB.mapped_autostrips[targetid] - Mtarget = GLOB.mapped_autostrips_mob[targetid] - if(target) - . = TRUE - -/obj/effect/autostriptarget - name = "Autostrip target. Link me via targetid to an autostrip trigger." - icon = 'icons/mob/screen1.dmi' - icon_state = "no_item1" - var/targetid = "Default" - unacidable = 1 - layer = 99 - anchored = 1 - invisibility = 99 - - -/obj/effect/autostriptarget/Initialize(mapload) - . = ..() - if(targetid) - GLOB.mapped_autostrips[targetid] = src - -/obj/effect/autostriptarget/mob - name = "Autostrip target to send mobs to." - -/obj/effect/autostriptarget/mob/Initialize(mapload) - if(targetid) - GLOB.mapped_autostrips_mob[targetid] = src diff --git a/modular_chomp/code/game/objects/items/weapons/dna_injector.dm b/modular_chomp/code/game/objects/items/weapons/dna_injector.dm deleted file mode 100644 index 810d7718c2..0000000000 --- a/modular_chomp/code/game/objects/items/weapons/dna_injector.dm +++ /dev/null @@ -1,46 +0,0 @@ -//Same as regular injector, but without the radiation -//Using for events, set the block to the desired gene -//Note, genetics code is incredibly scuffed, sometimes blocks just won't activate unless you do it multiple times???? -/obj/item/dnainjector/safe - desc = "A slightly safer DNA injector" - datatype = DNA2_BUF_SE - value = 0xFFF - -/obj/item/dnainjector/safe/New(var/block_type) - block = block_type - ..() - -/obj/item/dnainjector/safe/inject(mob/M as mob, mob/user as mob) - /* - if (!(NOCLONE in M.mutations)) // prevents drained people from having their DNA changed - if (buf.types & DNA2_BUF_UI) - if (!block) //isolated block? - M.UpdateAppearance(buf.dna.UI.Copy()) - if (buf.types & DNA2_BUF_UE) //unique enzymes? yes - M.real_name = buf.dna.real_name - M.name = buf.dna.real_name - uses-- - else - M.dna.SetUIValue(block,src.GetValue()) - M.UpdateAppearance() - uses-- - if (buf.types & DNA2_BUF_SE) - if (!block) //isolated block? - M.dna.SE = buf.dna.SE.Copy() - M.dna.UpdateSE() - else - M.dna.SetSEValue(block,src.GetValue()) - domutcheck(M, null, block!=null) - uses-- - if(prob(5)) - trigger_side_effect(M) - */ - M.dna.SetSEState(block,1) - domutcheck(M,null,MUTCHK_FORCED) - M.update_mutations() - - spawn(0)//this prevents the collapse of space-time continuum - if (user) - user.drop_from_inventory(src) - qdel(src) - return uses \ No newline at end of file diff --git a/modular_chomp/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/modular_chomp/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm deleted file mode 100644 index d2cafb2e2f..0000000000 --- a/modular_chomp/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ /dev/null @@ -1,42 +0,0 @@ -/obj/structure/closet/secure_closet/mind - name = "mind secured locker" - var/datum/mind/owner - var/self_del = 1 - anchored = 0 - -/obj/structure/closet/secure_closet/mind/New(var/datum/mind/mind_target, var/del_self = 1) - .=..() - self_del = del_self - if(mind_target) - owner = mind_target - name = "Owned by [owner.name]" - if(owner.current) - var/icon/I = get_flat_icon(owner.current, dir=SOUTH, no_anim=TRUE) - var/image/IM = image(I, pixel_x = (32 - I.Width())) - //icon2base64(get_flat_icon(owner.current,dir=SOUTH,no_anim=TRUE)) - /* - I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE) - I.plane = MOB_PLANE - I.layer = MOB_LAYER - */ - add_overlay(IM) - qdel(I) - -/obj/structure/closet/secure_closet/mind/allowed(mob/user) - if(user.mind == owner) - return TRUE - else - return FALSE - -/obj/structure/closet/secure_closet/mind/open() - .=..() - if(self_del) - qdel(src) - -/obj/structure/closet/secure_closet/mind/LateInitialize() - if(ispath(closet_appearance)) - closet_appearance = GLOB.closet_appearances[closet_appearance] - if(istype(closet_appearance)) - icon = closet_appearance.icon - color = null - update_icon() \ No newline at end of file diff --git a/modular_chomp/code/modules/mob/living/carbon/human/human_defines.dm b/modular_chomp/code/modules/mob/living/carbon/human/human_defines.dm index 22dd1b10e5..71e7ed64f0 100644 --- a/modular_chomp/code/modules/mob/living/carbon/human/human_defines.dm +++ b/modular_chomp/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,7 +1,5 @@ /mob/living/carbon/human var/gender_change_cooldown = 0 // A cooldown for gender and gender indentify changing procs to make it easy to avoid spam of gender change - var/loneliness_stage = 0 - var/next_loneliness_time = 0 var/hide_headset = FALSE var/hide_glasses = FALSE var/speech_sound_enabled = TRUE diff --git a/modular_chomp/code/modules/mob/living/carbon/human/species/species.dm b/modular_chomp/code/modules/mob/living/carbon/human/species/species.dm index 19168c8c41..4789ecab8e 100644 --- a/modular_chomp/code/modules/mob/living/carbon/human/species/species.dm +++ b/modular_chomp/code/modules/mob/living/carbon/human/species/species.dm @@ -1,11 +1,4 @@ /datum/species - var/crit_mod = 1 - var/list/env_traits = list() - var/photosynthesizing = FALSE - var/grows = FALSE - var/shrinks = FALSE - var/rad_levels = list("safe" = 2.5, "danger_1" = 50, "danger_2" = 75, "danger_3" = 150) - var/rad_removal_mod = 1 var/bite_mod = 1 var/grab_resist_divisor_victims = 1 var/grab_resist_divisor_self = 1 diff --git a/modular_chomp/maps/overmap/space_pois/debris1_60x60.dmm b/modular_chomp/maps/overmap/space_pois/debris1_60x60.dmm index 3a6780cddd..4e35eaafcc 100644 --- a/modular_chomp/maps/overmap/space_pois/debris1_60x60.dmm +++ b/modular_chomp/maps/overmap/space_pois/debris1_60x60.dmm @@ -219,9 +219,9 @@ /area/submap/debris1) "nt" = ( /obj/structure/safe, -/obj/item/dnainjector/xraymut, -/obj/item/dnainjector/runfast, -/obj/item/dnainjector/antistutt, +/obj/item/dnainjector/set_trait/xray, +/obj/item/dnainjector/set_trait/haste, +/obj/item/dnainjector/set_trait/anxiety/disable, /turf/simulated/floor/tiled/airless, /area/submap/debris1) "oh" = ( diff --git a/modular_chomp/maps/overmap/space_pois/debris2_20x20.dmm b/modular_chomp/maps/overmap/space_pois/debris2_20x20.dmm index fbf0e1f7d2..18fdd8c04a 100644 --- a/modular_chomp/maps/overmap/space_pois/debris2_20x20.dmm +++ b/modular_chomp/maps/overmap/space_pois/debris2_20x20.dmm @@ -105,9 +105,9 @@ /area/submap/debris2) "G" = ( /obj/structure/safe, -/obj/item/dnainjector/xraymut, -/obj/item/dnainjector/runfast, -/obj/item/dnainjector/antistutt, +/obj/item/dnainjector/set_trait/xray, +/obj/item/dnainjector/set_trait/haste, +/obj/item/dnainjector/set_trait/anxiety/disable, /turf/simulated/floor/tiled/airless, /area/submap/debris2) "H" = ( diff --git a/modular_chomp/maps/overmap/space_pois/ussp_84x90.dmm b/modular_chomp/maps/overmap/space_pois/ussp_84x90.dmm index 4f1396f4cd..6b106f311c 100644 --- a/modular_chomp/maps/overmap/space_pois/ussp_84x90.dmm +++ b/modular_chomp/maps/overmap/space_pois/ussp_84x90.dmm @@ -1659,7 +1659,7 @@ }) "gQ" = ( /obj/structure/table/standard, -/obj/item/disk/data/demo{ +/obj/item/disk/body_record{ pixel_x = -14; pixel_y = -1 }, diff --git a/modular_chomp/maps/soluna_nexus/soluna_nexus-3.dmm b/modular_chomp/maps/soluna_nexus/soluna_nexus-3.dmm index 93dcdb3195..a3816d50dd 100644 --- a/modular_chomp/maps/soluna_nexus/soluna_nexus-3.dmm +++ b/modular_chomp/maps/soluna_nexus/soluna_nexus-3.dmm @@ -34677,18 +34677,18 @@ pixel_y = 1; pixel_x = 2 }, -/obj/item/dnainjector/hallucination{ +/obj/item/dnainjector/set_trait/flashproof{ pixel_y = 3 }, -/obj/item/dnainjector/anticlumsy{ +/obj/item/dnainjector/set_trait/clumsy/disable{ pixel_y = 5; pixel_x = 1 }, -/obj/item/dnainjector/antiblind{ +/obj/item/dnainjector/set_trait/blind/disable{ pixel_y = 7; pixel_x = 2 }, -/obj/item/dnainjector/tourmut{ +/obj/item/dnainjector/set_trait/tourettes{ pixel_y = 9; pixel_x = 1 }, diff --git a/modular_chomp/maps/submaps/surface_submaps/valley/piratefortress.dmm b/modular_chomp/maps/submaps/surface_submaps/valley/piratefortress.dmm index 8cea62d78e..1a8dae4fa6 100644 --- a/modular_chomp/maps/submaps/surface_submaps/valley/piratefortress.dmm +++ b/modular_chomp/maps/submaps/surface_submaps/valley/piratefortress.dmm @@ -283,7 +283,7 @@ /turf/template_noop, /area/template_noop) "nj" = ( -/obj/item/dnainjector/telemut, +/obj/item/dnainjector/set_trait/tk, /obj/structure/closet/grave{ opened = 0 }, @@ -510,7 +510,7 @@ /turf/simulated/floor/tiled/red, /area/submap/piratefortress) "Di" = ( -/obj/item/dnainjector/telemut, +/obj/item/dnainjector/set_trait/tk, /turf/simulated/floor/outdoors/rocks, /area/submap/piratefortress) "DD" = ( diff --git a/modular_chomp/maps/virtual_reality/constructVR.dmm b/modular_chomp/maps/virtual_reality/constructVR.dmm index 59aabd0384..97f932b618 100644 --- a/modular_chomp/maps/virtual_reality/constructVR.dmm +++ b/modular_chomp/maps/virtual_reality/constructVR.dmm @@ -14688,22 +14688,22 @@ /area/vr/powered) "lQK" = ( /obj/structure/table/darkglass, -/obj/item/dnainjector/xraymut{ +/obj/item/dnainjector/set_trait/xray{ pixel_y = 1 }, -/obj/item/dnainjector/xraymut{ +/obj/item/dnainjector/set_trait/xray{ pixel_y = -5 }, -/obj/item/dnainjector/xraymut{ +/obj/item/dnainjector/set_trait/xray{ pixel_y = -2 }, -/obj/item/dnainjector/regenerate{ +/obj/item/dnainjector/set_trait/regenerate{ pixel_y = 10 }, -/obj/item/dnainjector/regenerate{ +/obj/item/dnainjector/set_trait/regenerate{ pixel_y = 4 }, -/obj/item/dnainjector/regenerate{ +/obj/item/dnainjector/set_trait/regenerate{ pixel_y = 7 }, /turf/simulated/shuttle/floor/voidcraft/light, @@ -22913,20 +22913,20 @@ /area/vr/powered) "sfW" = ( /obj/structure/table/darkglass, -/obj/item/dnainjector/insulation, -/obj/item/dnainjector/insulation{ +/obj/item/dnainjector/set_trait/coldadapt, +/obj/item/dnainjector/set_trait/coldadapt{ pixel_y = -5 }, -/obj/item/dnainjector/insulation{ +/obj/item/dnainjector/set_trait/coldadapt{ pixel_y = -3 }, -/obj/item/dnainjector/telemut{ +/obj/item/dnainjector/set_trait/tk{ pixel_y = 9 }, -/obj/item/dnainjector/telemut{ +/obj/item/dnainjector/set_trait/tk{ pixel_y = 3 }, -/obj/item/dnainjector/telemut{ +/obj/item/dnainjector/set_trait/tk{ pixel_y = 6 }, /turf/simulated/shuttle/floor/voidcraft/dark, diff --git a/sound/misc/bloop.ogg b/sound/misc/bloop.ogg new file mode 100644 index 0000000000..260e9e926e Binary files /dev/null and b/sound/misc/bloop.ogg differ diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss index f31c0a8054..1aa5fe24fb 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss @@ -1428,5 +1428,6 @@ $border-width-px: $border-width * 1px; } .wingdings { + color: #0077ff; font-family: Wingdings, Webdings; } diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss index 932f1bafd2..a769314e1b 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss @@ -1454,6 +1454,11 @@ $border-width-px: $border-width * 1px; line-height: 0.3; } +.psionic { + color: #993399; +} + .wingdings { + color: #0077ff; font-family: Wingdings, Webdings; } diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-vchatdark.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-vchatdark.scss index e63d171d33..b660428ad9 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-vchatdark.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-vchatdark.scss @@ -1428,6 +1428,11 @@ $border-width-px: $border-width * 1px; line-height: 0.3; } +.psionic { + color: #993399; +} + .wingdings { + color: #0077ff; font-family: Wingdings, Webdings; } diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-vchatlight.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-vchatlight.scss index ba8b03e007..0345879cb0 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-vchatlight.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-vchatlight.scss @@ -1452,6 +1452,11 @@ $border-width-px: $border-width * 1px; line-height: 0.3; } +.psionic { + color: #993399; +} + .wingdings { + color: #0077ff; font-family: Wingdings, Webdings; } diff --git a/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierMain.tsx b/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierMain.tsx index b384543774..28478ff3e6 100644 --- a/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierMain.tsx +++ b/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierMain.tsx @@ -1,73 +1,25 @@ import { useBackend } from 'tgui/backend'; -import { - Box, - Button, - Icon, - Knob, - LabeledList, - Section, - Stack, - Tabs, -} from 'tgui-core/components'; -import { BooleanLike } from 'tgui-core/react'; +import { Icon, Section, Tabs } from 'tgui-core/components'; -import { operations, rejuvenatorsDoses } from './constants'; -import { DNAModifierBlocks } from './DNAModifierBlocks'; +import { operations } from './constants'; import { DNAModifierMainBuffers } from './DNAModifierMainBuffers'; +import { DNAModifierMainRejuvenators } from './DNAMofifierMainTabs/DNAModifierMainRejuvenators'; +import { DNAModifierMainSE } from './DNAMofifierMainTabs/DNAModifierMainSE'; import { Data } from './types'; -export const DNAModifierMain = (props: { isDNAInvalid: BooleanLike }) => { +export const DNAModifierMain = (props) => { const { act, data } = useBackend(); - const { selectedMenuKey, hasOccupant } = data; + const { selectedMenuKey } = data; + + const tabs: React.JSX.Element[] = []; + + tabs['se'] = ; + tabs['buffer'] = ; + tabs['rejuvenators'] = ; - if (!hasOccupant) { - return ( -
- - - -
- No occupant in DNA modifier. -
-
-
- ); - } else if (props.isDNAInvalid) { - return ( -
- - - -
- No operation possible on this subject. -
-
-
- ); - } - let body; - if (selectedMenuKey === 'ui') { - body = ( - <> - - - - ); - } else if (selectedMenuKey === 'se') { - body = ( - <> - - - - ); - } else if (selectedMenuKey === 'buffer') { - body = ; - } else if (selectedMenuKey === 'rejuvenators') { - body = ; - } return ( -
+
{operations.map((op, i) => ( { ))} - {body} -
- ); -}; - -const DNAModifierMainUI = (props) => { - const { act, data } = useBackend(); - - const { - selectedUIBlock, - selectedUISubBlock, - selectedUITarget, - dnaBlockSize, - occupant, - } = data; - - return ( -
- - - - value.toString(16).toUpperCase()} - ml="0" - onChange={(e, val) => act('changeUITarget', { value: val })} - /> - - - -
- ); -}; - -const DNAModifierMainSE = (props) => { - const { act, data } = useBackend(); - - const { selectedSEBlock, selectedSESubBlock, dnaBlockSize, occupant } = data; - - return ( -
- - -
- ); -}; - -const DNAModifierMainRadiationEmitter = (props) => { - const { act, data } = useBackend(); - - const { radiationIntensity, radiationDuration } = data; - - return ( -
- - - act('radiationIntensity', { value: val })} - /> - - - act('radiationDuration', { value: val })} - /> - - - -
- ); -}; - -const DNAModifierMainRejuvenators = (props) => { - const { act, data } = useBackend(); - - const { isBeakerLoaded, beakerVolume, beakerLabel } = data; - - return ( -
act('ejectBeaker')} - > - Eject - - } - > - {isBeakerLoaded ? ( - - - {rejuvenatorsDoses.map((a, i) => ( - - ))} - - - - {beakerLabel ? beakerLabel : 'No label'} - {beakerVolume ? ( - - {beakerVolume} unit{beakerVolume === 1 ? '' : 's'} remaining - - ) : ( - Empty - )} - - - ) : ( - - -
- No beaker loaded. -
- )} + {tabs[selectedMenuKey]}
); }; diff --git a/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierMainBuffers.tsx b/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierMainBuffers.tsx index 3fda2fc960..f4e16b0f21 100644 --- a/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierMainBuffers.tsx +++ b/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierMainBuffers.tsx @@ -1,26 +1,42 @@ import { useBackend } from 'tgui/backend'; -import { Box, Button, Icon, LabeledList, Section } from 'tgui-core/components'; +import { + Box, + Button, + Icon, + LabeledList, + Section, + Stack, +} from 'tgui-core/components'; -import { buffData, Data } from './types'; +import type { buffData, Data } from './types'; export const DNAModifierMainBuffers = (props) => { const { data } = useBackend(); const { buffers } = data; - let bufferElements = buffers.map((buffer, i) => ( - + const bufferElements = buffers.map((buffer, i) => ( + + + )); return ( - <> -
{bufferElements}
- - + + +
+ + {bufferElements} + +
+
+ + + +
); }; @@ -31,94 +47,86 @@ const DNAModifierMainBuffersElement = (props: { }) => { const { act, data } = useBackend(); const { id, name, buffer } = props; - const { isInjectorReady } = data; + const { isInjectorReady, hasOccupant, occupant } = data; const realName: string = name + (buffer.data ? ' - ' + buffer.label : ''); return ( - -
- - act('bufferOption', { - option: 'clear', - id: id, - }) - } - > - Clear - - - - - } - > +
+ + act('bufferOption', { + option: 'clear', + id: id, + }) + } + > + Clear + + + + + + } + > + - -
- + +
); }; @@ -206,6 +217,7 @@ const DNAModifierMainBuffersDisk = (props) => { const { hasDisk, disk } = data; return (
diff --git a/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierOccupant.tsx b/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierOccupant.tsx index 1868cac4dc..570522b989 100644 --- a/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierOccupant.tsx +++ b/tgui/packages/tgui/interfaces/DNAModifier/DNAModifierOccupant.tsx @@ -7,10 +7,10 @@ import { ProgressBar, Section, } from 'tgui-core/components'; -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; import { stats } from './constants'; -import { Data } from './types'; +import type { Data } from './types'; export const DNAModifierOccupant = (props: { isDNAInvalid: BooleanLike }) => { const { act, data } = useBackend(); diff --git a/tgui/packages/tgui/interfaces/DNAModifier/DNAMofifierMainTabs/DNAModifierMainRadiationEmitter.tsx b/tgui/packages/tgui/interfaces/DNAModifier/DNAMofifierMainTabs/DNAModifierMainRadiationEmitter.tsx new file mode 100644 index 0000000000..bc0e3fe1e5 --- /dev/null +++ b/tgui/packages/tgui/interfaces/DNAModifier/DNAMofifierMainTabs/DNAModifierMainRadiationEmitter.tsx @@ -0,0 +1,95 @@ +import { useBackend } from 'tgui/backend'; +import { + Box, + Button, + Divider, + Knob, + Section, + Stack, +} from 'tgui-core/components'; + +import type { Data } from '../types'; + +export const DNAModifierMainRadiationEmitter = (props) => { + const { act, data } = useBackend(); + + const { radiationIntensity, radiationDuration, occupant } = data; + + return ( + (occupant && occupant.isViableSubject && ( +
+ + + + + + Intensity + + + + act('radiationIntensity', { value: val }) + } + /> + + + + + + + + Duration + + + + act('radiationDuration', { value: val }) + } + /> + + + + + + + + + + + + + + + + + +
+ )) || + null + ); +}; diff --git a/tgui/packages/tgui/interfaces/DNAModifier/DNAMofifierMainTabs/DNAModifierMainRejuvenators.tsx b/tgui/packages/tgui/interfaces/DNAModifier/DNAMofifierMainTabs/DNAModifierMainRejuvenators.tsx new file mode 100644 index 0000000000..b28635c17a --- /dev/null +++ b/tgui/packages/tgui/interfaces/DNAModifier/DNAMofifierMainTabs/DNAModifierMainRejuvenators.tsx @@ -0,0 +1,75 @@ +import { useBackend } from 'tgui/backend'; +import { Box, Button, Icon, LabeledList, Section } from 'tgui-core/components'; + +import { rejuvenatorsDoses } from '../constants'; +import type { Data } from '../types'; + +export const DNAModifierMainRejuvenators = (props) => { + const { act, data } = useBackend(); + + const { isBeakerLoaded, beakerVolume, beakerLabel, hasOccupant } = data; + + return ( +
act('ejectBeaker')} + > + Eject + + } + > + {isBeakerLoaded ? ( + + + {rejuvenatorsDoses.map((a, i) => ( + + ))} + + + + {beakerLabel ? beakerLabel : 'No label'} + {beakerVolume ? ( + + {beakerVolume} unit{beakerVolume === 1 ? '' : 's'} remaining + + ) : ( + Empty + )} + + + ) : ( + + +
+ No beaker loaded. +
+ )} +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/DNAModifier/DNAMofifierMainTabs/DNAModifierMainSE.tsx b/tgui/packages/tgui/interfaces/DNAModifier/DNAMofifierMainTabs/DNAModifierMainSE.tsx new file mode 100644 index 0000000000..d8530e6bda --- /dev/null +++ b/tgui/packages/tgui/interfaces/DNAModifier/DNAMofifierMainTabs/DNAModifierMainSE.tsx @@ -0,0 +1,57 @@ +import { useBackend } from 'tgui/backend'; +import { Icon, Section, Stack } from 'tgui-core/components'; + +import { DNAModifierBlocks } from '../DNAModifierBlocks'; +import type { Data } from '../types'; +import { DNAModifierMainRadiationEmitter } from './DNAModifierMainRadiationEmitter'; + +export const DNAModifierMainSE = (props) => { + return ( + + + + + + + + + ); +}; + +const DNAModifierMainBlocks = (props) => { + const { act, data } = useBackend(); + + const { selectedSEBlock, selectedSESubBlock, dnaBlockSize, occupant } = data; + + return !occupant ? ( +
+ + + +
+ No occupant in DNA modifier. +
+
+
+ ) : !occupant.isViableSubject ? ( +
+ + + +
+ No operation possible on this subject. +
+
+
+ ) : ( +
+ +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/DNAModifier/constants.ts b/tgui/packages/tgui/interfaces/DNAModifier/constants.ts index d247c8a51a..6541f47f74 100644 --- a/tgui/packages/tgui/interfaces/DNAModifier/constants.ts +++ b/tgui/packages/tgui/interfaces/DNAModifier/constants.ts @@ -5,7 +5,6 @@ export const stats: string[][] = [ ]; export const operations: string[][] = [ - ['ui', 'Modify U.I.', 'dna'], ['se', 'Modify S.E.', 'dna'], ['buffer', 'Transfer Buffers', 'syringe'], ['rejuvenators', 'Rejuvenators', 'flask'], diff --git a/tgui/packages/tgui/interfaces/DNAModifier/index.tsx b/tgui/packages/tgui/interfaces/DNAModifier/index.tsx index f978576e45..43c100a25c 100644 --- a/tgui/packages/tgui/interfaces/DNAModifier/index.tsx +++ b/tgui/packages/tgui/interfaces/DNAModifier/index.tsx @@ -1,29 +1,43 @@ import { useBackend } from 'tgui/backend'; import { Window } from 'tgui/layouts'; +import { Stack } from 'tgui-core/components'; import { ComplexModal } from '../common/ComplexModal'; import { DNAModifierIrradiating } from './DNAModifierIrradiating'; import { DNAModifierMain } from './DNAModifierMain'; import { DNAModifierOccupant } from './DNAModifierOccupant'; -import { Data } from './types'; +import type { Data } from './types'; export const DNAModifier = (props) => { const { data } = useBackend(); const { irradiating, occupant } = data; - const isDNAInvalid: boolean = - !occupant.isViableSubject || - !occupant.uniqueIdentity || - !occupant.structuralEnzymes; - return ( - {irradiating && } + {irradiating ? : ''} - - + + + + + + + + ); diff --git a/tgui/packages/tgui/interfaces/DNAModifier/types.ts b/tgui/packages/tgui/interfaces/DNAModifier/types.ts index f2270f8888..253bef9677 100644 --- a/tgui/packages/tgui/interfaces/DNAModifier/types.ts +++ b/tgui/packages/tgui/interfaces/DNAModifier/types.ts @@ -1,4 +1,4 @@ -import { BooleanLike } from 'tgui-core/react'; +import type { BooleanLike } from 'tgui-core/react'; export type Data = { selectedMenuKey: string; @@ -46,7 +46,15 @@ type modalData = { }; export type buffData = { - data: number[] | null; + data: { + data: number[]; + owner: string; + label: string; + type: string; + ue: string; + ui: string; + se: string; + } | null; // Traitgenes Fixed data structure owner: string | null; label: string | null; type: string | null; diff --git a/tgui/packages/tgui/interfaces/ResleevingConsole/BodyRecordModal.tsx b/tgui/packages/tgui/interfaces/ResleevingConsole/BodyRecordModal.tsx index 7aab7736df..e287219c04 100644 --- a/tgui/packages/tgui/interfaces/ResleevingConsole/BodyRecordModal.tsx +++ b/tgui/packages/tgui/interfaces/ResleevingConsole/BodyRecordModal.tsx @@ -46,6 +46,21 @@ export const BodyRecordModal = (props: { data: ActiveBodyRecordData }) => { > {synthetic ? 'Build' : 'Grow'} + {/* Traitgenes create a dna injector based off the BR currently selected, to allow normal doctors to reset someone's SEs */} + {!synthetic ? ( + + ) : ( + '' + )} diff --git a/vorestation.dme b/vorestation.dme index 6041b9af13..3fed6677db 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -143,7 +143,7 @@ #include "code\__defines\size.dm" #include "code\__defines\slosh.dm" #include "code\__defines\sound.dm" -#include "code\__defines\span_vr.dm" +#include "code\__defines\span.dm" #include "code\__defines\species_languages.dm" #include "code\__defines\species_languages_vr.dm" #include "code\__defines\species_languages_YW.dm" @@ -207,6 +207,7 @@ #include "code\_helpers\_global_objects.dm" #include "code\_helpers\_global_objects_vr.dm" #include "code\_helpers\_lists.dm" +#include "code\_helpers\announcements.dm" #include "code\_helpers\atmospherics.dm" #include "code\_helpers\atom_movables.dm" #include "code\_helpers\distance_ch.dm" @@ -795,9 +796,7 @@ #include "code\game\dna\dna2_domutcheck.dm" #include "code\game\dna\dna2_helpers.dm" #include "code\game\dna\dna_modifier.dm" -#include "code\game\dna\genes\disabilities.dm" #include "code\game\dna\genes\gene.dm" -#include "code\game\dna\genes\powers.dm" #include "code\game\gamemodes\events.dm" #include "code\game\gamemodes\game_mode.dm" #include "code\game\gamemodes\game_mode_latespawn.dm" @@ -2207,7 +2206,6 @@ #include "code\modules\client\preferences_tgui.dm" #include "code\modules\client\preferences_toggle_procs.dm" #include "code\modules\client\preferences_vr.dm" -#include "code\modules\client\preferences_yw.dm" #include "code\modules\client\record_updater.dm" #include "code\modules\client\spam_prevention.dm" #include "code\modules\client\stored_item.dm" @@ -3254,7 +3252,6 @@ #include "code\modules\mob\living\carbon\human\human_vr.dm" #include "code\modules\mob\living\carbon\human\inventory.dm" #include "code\modules\mob\living\carbon\human\life.dm" -#include "code\modules\mob\living\carbon\human\life_ch.dm" #include "code\modules\mob\living\carbon\human\life_vr.dm" #include "code\modules\mob\living\carbon\human\login.dm" #include "code\modules\mob\living\carbon\human\logout.dm" @@ -3324,12 +3321,13 @@ #include "code\modules\mob\living\carbon\human\species\station\traits_vr\_traits.dm" #include "code\modules\mob\living\carbon\human\species\station\traits_vr\negative.dm" #include "code\modules\mob\living\carbon\human\species\station\traits_vr\negative_ch.dm" +#include "code\modules\mob\living\carbon\human\species\station\traits_vr\negative_genes.dm" #include "code\modules\mob\living\carbon\human\species\station\traits_vr\neutral.dm" #include "code\modules\mob\living\carbon\human\species\station\traits_vr\neutral_ch.dm" #include "code\modules\mob\living\carbon\human\species\station\traits_vr\positive.dm" #include "code\modules\mob\living\carbon\human\species\station\traits_vr\positive_ch.dm" +#include "code\modules\mob\living\carbon\human\species\station\traits_vr\positive_genes.dm" #include "code\modules\mob\living\carbon\human\species\station\traits_vr\trait.dm" -#include "code\modules\mob\living\carbon\human\species\station\traits_vr\trait_ch.dm" #include "code\modules\mob\living\carbon\human\species\station\traits_vr\traits_tutorial.dm" #include "code\modules\mob\living\carbon\human\species\station\traits_vr\weaver_objs.dm" #include "code\modules\mob\living\carbon\human\species\station\traits_vr\weaver_recipies.dm" @@ -4721,6 +4719,7 @@ #include "code\modules\xgm\xgm_gas_mixture.dm" #include "code\unit_tests\cosmetic_tests.dm" #include "code\unit_tests\decl_tests.dm" +#include "code\unit_tests\genetics_tests.dm" #include "code\unit_tests\language_tests.dm" #include "code\unit_tests\loadout_tests.dm" #include "code\unit_tests\map_tests.dm" @@ -4765,11 +4764,9 @@ #include "modular_chomp\code\coalesce_ch.dm" #include "modular_chomp\code\global.dm" #include "modular_chomp\code\__defines\_planes+layers.dm" -#include "modular_chomp\code\__defines\span.dm" #include "modular_chomp\code\__defines\text.dm" #include "modular_chomp\code\_global_vars\tgui.dm" #include "modular_chomp\code\_global_vars\list\names.dm" -#include "modular_chomp\code\_HELPERS\announcements.dm" #include "modular_chomp\code\_HELPERS\game.dm" #include "modular_chomp\code\_HELPERS\mobs.dm" #include "modular_chomp\code\_onclick\hud\alert.dm" @@ -4825,7 +4822,6 @@ #include "modular_chomp\code\game\objects\mob_spawner.dm" #include "modular_chomp\code\game\objects\effects\dark_growth.dm" #include "modular_chomp\code\game\objects\effects\explosion.dm" -#include "modular_chomp\code\game\objects\effects\step_triggers.dm" #include "modular_chomp\code\game\objects\items\contraband.dm" #include "modular_chomp\code\game\objects\items\holosign_creator.dm" #include "modular_chomp\code\game\objects\items\target_toy.dm" @@ -4838,7 +4834,6 @@ #include "modular_chomp\code\game\objects\items\devices\radio\radio.dm" #include "modular_chomp\code\game\objects\items\weapons\capture_crystal.dm" #include "modular_chomp\code\game\objects\items\weapons\cigs_lighters.dm" -#include "modular_chomp\code\game\objects\items\weapons\dna_injector.dm" #include "modular_chomp\code\game\objects\items\weapons\id_cards.dm" #include "modular_chomp\code\game\objects\items\weapons\RCD.dm" #include "modular_chomp\code\game\objects\items\weapons\circutboards\computer\research.dm" @@ -4855,7 +4850,6 @@ #include "modular_chomp\code\game\objects\structures\watercloset_ch.dm" #include "modular_chomp\code\game\objects\structures\weathersignal.dm" #include "modular_chomp\code\game\objects\structures\crate_lockers\largecrate.dm" -#include "modular_chomp\code\game\objects\structures\crates_lockers\closets\secure\secure_closets.dm" #include "modular_chomp\code\game\turfs\simulated\alien.dm" #include "modular_chomp\code\game\turfs\simulated\blackholeturfs.dm" #include "modular_chomp\code\game\turfs\simulated\outdoors\desert_planet.dm"