From 043028db83600fb4b43850f26298992cc8f011ef Mon Sep 17 00:00:00 2001 From: carnie Date: Sun, 21 Apr 2013 21:03:37 +0100 Subject: [PATCH 1/3] Resolves #283 DNA modification uses normally distributed random numbers. Radiation strength dictates the standard deviation of the change in the hex character which is hit (higher output means greater chance for a large change) . Similarly, radiation duration dictates how likely we are to hit the hex-character we clicked on (longer duration means more likely to hit). Irradiation is strength*duration. All balancing is done via multiplier defines so you can rebalance it easily. DNA blocks and structuring all use defines. Making modification/expansion easier. I'll likely expand this into a datum-based system to allow more interesting features, reduce code further and allow admins to interact with the way dna strings behave. DNA strings can be spliced together using merge_text(). e.g. string 1: "Hello World" string 2: "Seeya______" result: "Seeya World" This isn't used except for admin-spawnable SE injectors at the moment. r_hair, g_hair, b_hair, r_facial, g_facial, b_facial, r_eyes, g_eyes, b_eyes were removed and made into 3 short hex-colors. Skin tones now support colours other than shades of brown. I've had to restrict it heavily until other stuff is done. Skin tones include Albino Caucasian, Oriental, Mediterranean, etc. Data disks and DNA injectors were reworked to use associative lists so transferring data is just a matter of doing list.Copy() var/dna is now defined at /mob/living/carbon level. Only monkeys and humans may have dna currently. Support is there for all carbon-based lifeforms to have dna. DNA modifier console has almost all controls on one screen. UIs and UEs can be injected separately (appearance and name, respectively) dna helper procs like ready_dna() and such were changed to make them more versatile. There is now a hardset_dna() proc as an alternative to ready_dna which can initialize dna with properties passed into it or update an existing dna string (useful for cloning and antag spawning) Every block of SEs are in randomised positions. Disabled automatic logging of world.log, as it produced undesirable behaviour. Mr Muggles and God Emperor of Mankind disks removed. Floor() removed. (it was completely uneccesary, that is what round() is). Fixed spelling mistakes in modularchangling.dm (thanks tenebrosity) Tanning removed from beaches (again) Experimental: monkeys and humans do not have dna until first attempt to read dna (using check_dna_integrity(mob)) This is mainly due to the way everything is hardcoded into New(). Changelog.html updated Signed-off-by: carnie --- code/__DEFINES.dm | 15 + code/__HELPERS/game.dm | 9 - code/__HELPERS/global_lists.dm | 11 +- code/__HELPERS/maths.dm | 32 +- code/__HELPERS/mobs.dm | 56 +- code/__HELPERS/sanitize_values.dm | 22 +- code/__HELPERS/text.dm | 68 +- code/__HELPERS/type2type.dm | 117 +- code/__HELPERS/unsorted.dm | 6 +- code/datums/diseases/dna_spread.dm | 4 +- code/datums/diseases/retrovirus.dm | 12 +- code/datums/mind.dm | 20 +- code/datums/mixed.dm | 25 +- code/game/area/Space Station 13 areas.dm | 6 - code/game/atoms.dm | 5 +- code/game/dna.dm | 2084 +++++++---------- code/game/gamemodes/changeling/changeling.dm | 6 +- .../gamemodes/changeling/changeling_powers.dm | 321 ++- .../gamemodes/changeling/modularchangling.dm | 69 +- .../game/gamemodes/changeling/traitor_chan.dm | 2 +- code/game/gamemodes/setupgame.dm | 72 +- code/game/machinery/cloning.dm | 38 +- code/game/machinery/computer/cloning.dm | 164 +- code/game/mecha/mecha.dm | 6 +- code/game/objects/effects/gibs.dm | 2 +- code/game/objects/items/devices/PDA/PDA.dm | 8 +- code/game/objects/items/devices/paicard.dm | 7 +- .../objects/items/weapons/dna_injector.dm | 228 +- code/game/supplyshuttle.dm | 2 +- code/global.dm | 18 +- code/modules/admin/verbs/one_click_antag.dm | 33 +- code/modules/admin/verbs/randomverbs.dm | 8 +- code/modules/awaymissions/maploader/reader.dm | 4 +- code/modules/client/preferences.dm | 71 +- code/modules/client/preferences_savefile.dm | 39 +- code/modules/clothing/head/misc_special.dm | 6 +- code/modules/detectivework/detective_work.dm | 6 +- code/modules/events/ninja.dm | 2 +- code/modules/hydroponics/hydroponics.dm | 16 +- code/modules/mob/death.dm | 3 +- code/modules/mob/living/carbon/alien/alien.dm | 6 - code/modules/mob/living/carbon/carbon.dm | 9 - .../mob/living/carbon/carbon_defines.dm | 4 +- code/modules/mob/living/carbon/human/human.dm | 15 - .../mob/living/carbon/human/human_defines.dm | 14 +- .../mob/living/carbon/human/update_icons.dm | 24 +- .../mob/living/carbon/monkey/monkey.dm | 18 +- .../mob/living/silicon/pai/software.dm | 10 +- code/modules/mob/mob.dm | 9 - code/modules/mob/mob_defines.dm | 2 - code/modules/mob/mob_helpers.dm | 6 +- code/modules/mob/mob_transformation_simple.dm | 8 +- code/modules/mob/new_player/new_player.dm | 4 +- .../mob/new_player/preferences_setup.dm | 127 +- code/modules/mob/transform_procs.dm | 4 +- code/modules/projectiles/gun.dm | 3 +- .../modules/projectiles/projectile/special.dm | 21 +- code/modules/reagents/Chemistry-Reagents.dm | 16 +- code/unused/dna_mutations.dm | 4 +- code/unused/pda2/base_program.dm | 2 +- code/unused/specops.dm | 2 +- code/unused/tensioner.dm | 5 +- code/world.dm | 8 +- html/changelog.html | 9 +- icons/mob/human.dmi | Bin 12196 -> 11483 bytes maps/tgstation.2.1.2.dmm | 2 +- 66 files changed, 1515 insertions(+), 2440 deletions(-) diff --git a/code/__DEFINES.dm b/code/__DEFINES.dm index 9b651160878..c1e1a010381 100644 --- a/code/__DEFINES.dm +++ b/code/__DEFINES.dm @@ -433,3 +433,18 @@ var/list/be_special_flags = list( "Monkey" = BE_MONKEY, "Ninja" = BE_NINJA ) + +//DNA - Because fuck you and your magic numbers being all over the codebase. +#define DNA_BLOCK_SIZE 3 + +#define DNA_UNI_IDENTITY_BLOCKS 7 +#define DNA_HAIR_COLOR_BLOCK 1 +#define DNA_FACIAL_HAIR_COLOR_BLOCK 2 +#define DNA_SKIN_TONE_BLOCK 3 +#define DNA_EYE_COLOR_BLOCK 4 +#define DNA_GENDER_BLOCK 5 +#define DNA_FACIAL_HAIR_STYLE_BLOCK 6 +#define DNA_HAIR_STYLE_BLOCK 7 + +#define DNA_STRUC_ENZYMES_BLOCKS 14 +#define DNA_UNIQUE_ENZYMES_LEN 32 \ No newline at end of file diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index a661ab83040..f4d15025868 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -1,14 +1,5 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 -/proc/dopage(src,target = null) - var/href_list - var/href - href_list = params2list("src=\ref[src][target ? "&[target]" : ""]") - href = "src=\ref[src];[target]" - src:temp_html = null - src:Topic(href, href_list) - return null - /proc/get_area(O) var/atom/location = O var/i diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 151abae29c5..35e7f4850ce 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -64,4 +64,13 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel") for(var/t in L) . += " has: [t]\n" world << . -*/ \ No newline at end of file +*/ + +//creates every subtype of prototype (excluding prototype) and adds it to list L. +//if no list/L is provided, one is created. +/proc/init_subtypes(prototype, list/L) + if(!istype(L)) L = list() + for(var/path in typesof(prototype)) + if(path == prototype) continue + L += new path() + return L diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm index b174147d583..fc5ad930680 100644 --- a/code/__HELPERS/maths.dm +++ b/code/__HELPERS/maths.dm @@ -26,9 +26,6 @@ var/const/Sqrt2 = 1.41421356 /proc/Default(a, b) return a ? a : b -/proc/Floor(x) - return round(x) - // Greatest Common Divisor - Euclid's algorithm /proc/Gcd(a, b) return b ? Gcd(b, a % b) : a @@ -47,7 +44,7 @@ var/const/Sqrt2 = 1.41421356 return min <= val && val <= max /proc/IsInteger(x) - return Floor(x) == x + return round(x) == x /proc/IsOdd(x) return !IsEven(x) @@ -110,5 +107,28 @@ var/const/Sqrt2 = 1.41421356 // min is inclusive, max is exclusive /proc/Wrap(val, min, max) var/d = max - min - var/t = Floor((val - min) / d) - return val - (t * d) \ No newline at end of file + var/t = round((val - min) / d) + return val - (t * d) + +//polar variant of a gaussian distributed PRNG +//since this method produces two random numbers, one is saved for subsequent calls +//(making the cost negligble for every second call) +//This will return +/- decimals, situated about mean with standard deviation stddev +var/gaussian_next +#define ACCURACY 10000 +/proc/gaussian(mean, stddev) + var/R1;var/R2;var/working + if(gaussian_next != null) + R1 = gaussian_next + gaussian_next = null + else + do + R1 = rand(-ACCURACY,ACCURACY)/ACCURACY + R2 = rand(-ACCURACY,ACCURACY)/ACCURACY + working = R1*R1 + R2*R2 + while(working >= 1) + R1 *= working + R2 *= working + gaussian_next = R2 + return (mean + stddev * R1) +#undef ACCURACY \ No newline at end of file diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 366052ba80d..0da2da6deec 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -1,3 +1,17 @@ +/proc/random_blood_type() + return pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") + +/proc/random_eye_color() + switch(pick(20;"brown",20;"hazel",20;"grey",15;"blue",15;"green",1;"amber",1;"albino")) + if("brown") return "630" + if("hazel") return "542" + if("grey") return pick("666","777","888","999","aaa","bbb","ccc") + if("blue") return "36c" + if("green") return "060" + if("amber") return "fc0" + if("albino") return pick("c","d","e","f") + pick("0","1","2","3","4","5","6","7","8","9") + pick("0","1","2","3","4","5","6","7","8","9") + else return "000" + /proc/random_underwear(gender) switch(gender) if(MALE) return pick(underwear_m) @@ -16,31 +30,29 @@ proc/random_facial_hair_style(gender) if(FEMALE) return pick(facial_hair_styles_female_list) else return pick(facial_hair_styles_list) -proc/random_name(gender) - if(gender==FEMALE) return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) - else return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) +proc/random_name(gender, attempts_to_find_unique_name=10) + for(var/i=1, i<=attempts_to_find_unique_name, i++) + if(gender==FEMALE) . = capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) + else . = capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) + + if(i != attempts_to_find_unique_name && !findname(.)) + break proc/random_skin_tone() - switch(pick(60;"caucasian", 15;"afroamerican", 10;"african", 10;"latino", 5;"albino")) - if("caucasian") . = -10 - if("afroamerican") . = -115 - if("african") . = -165 - if("latino") . = -55 - if("albino") . = 34 - else . = rand(-185,34) - return min(max( .+rand(-25, 25), -185),34) + return pick(60;"caucasian", 15;"afroamerican", 10;"african", 10;"latino", 5;"albino", 20;"oriental", 10;"mediteranian") -proc/skintone2racedescription(tone) - switch (tone) - if(30 to INFINITY) return "albino" - if(20 to 30) return "pale" - if(5 to 15) return "light skinned" - if(-10 to 5) return "white" - if(-25 to -10) return "tan" - if(-45 to -25) return "darker skinned" - if(-65 to -45) return "brown" - if(-INFINITY to -65) return "black" - else return "unknown" +var/list/skin_tones = list( + "caucasian" = "fdc", + "afroamerican" = "963", + "african" = "630", + "latino" = "c90", + "albino" = "fff", + "oriental" = "ff6", + "mediteranian" = "cc0" + ) +/proc/skin_tone2color(skin_tone) + . = skin_tones[skin_tone] + if(!.) . = "fdc" proc/age2agedescription(age) switch(age) diff --git a/code/__HELPERS/sanitize_values.dm b/code/__HELPERS/sanitize_values.dm index 1be69032cf1..2ce093e3003 100644 --- a/code/__HELPERS/sanitize_values.dm +++ b/code/__HELPERS/sanitize_values.dm @@ -30,17 +30,23 @@ else return default return default -/proc/sanitize_hexcolor(color, default="#000000") - if(!istext(color)) return default + +/proc/sanitize_hexcolor(color, desired_format=3, include_bang=0) + var/bang = include_bang ? "#" : "" + if(!istext(color)) + return bang + random_string(desired_format, zero_character_only) + + var/start = 1 + (text2ascii(color,1)==35) var/len = length(color) - if(len != 7 && len !=4) return default - if(text2ascii(color,1) != 35) return default //35 is the ascii code for "#" - . = "#" - for(var/i=2,i<=len,i++) + var/step_size = 1 + ((len+1)-start != desired_format) + + . = bang + for(var/i=start, i<=len, i+=step_size) var/ascii = text2ascii(color,i) switch(ascii) if(48 to 57) . += ascii2text(ascii) //numbers 0 to 9 if(97 to 102) . += ascii2text(ascii) //letters a to f if(65 to 70) . += ascii2text(ascii+32) //letters A to F - translates to lowercase - else return default - return . + else return bang + random_string(desired_format, zero_character_only) + + return . \ No newline at end of file diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index da9d8b34bce..ead4290bfde 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -329,4 +329,70 @@ var/new_text = "" for(var/i = length(text); i > 0; i--) new_text += copytext(text, i, i+1) - return new_text \ No newline at end of file + return new_text + +var/list/zero_character_only = list("0") +var/list/hex_characters = list("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f") +var/list/alphabet = list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z") +var/list/binary = list("0","1") +/proc/random_string(length, list/characters) + . = "" + for(var/i=1, i<=length, i++) + . += pick(characters) + +/proc/repeat_string(length, string="") + var/len = length(string) + if(!len) return string + while(len u) + temp1 = copytext(t,2,u+1) + return temp1 + +//merges non-null characters (3rd argument) from "from" into "into". Returns result +//e.g. into = "Hello World" +// from = "Seeya______" +// returns"Seeya World" +//The returned text is always the same length as into +//This was coded to handle DNA gene-splicing. +/proc/merge_text(into, from, null_char="_") + . = "" + if(!istext(into)) into = "" + if(!istext(from)) from = "" + var/null_ascii = istext(null_char) ? text2ascii(null_char,1) : null_char + + var/previous = 0 + var/start = 1 + var/end = length(into) + 1 + + for(var/i=1, i 0) - var/char = copytext(hex, i, i + 1) - switch(char) - if("0") - //Apparently, switch works with empty statements, yay! If that doesn't work, blame me, though. -- Urist - if("9", "8", "7", "6", "5", "4", "3", "2", "1") - num += text2num(char) * 16 ** power - if("a", "A") - num += 16 ** power * 10 - if("b", "B") - num += 16 ** power * 11 - if("c", "C") - num += 16 ** power * 12 - if("d", "D") - num += 16 ** power * 13 - if("e", "E") - num += 16 ** power * 14 - if("f", "F") - num += 16 ** power * 15 - else - return - power++ - i-- - return num - -//Returns the hex value of a number given a value assumed to be a base-ten value -/proc/num2hex(num, placeholder) - - if (placeholder == null) - placeholder = 2 - if (!( isnum(num) )) - return - if (!( num )) - return "0" - var/hex = "" - var/i = 0 - while(16 ** i < num) +//Returns the hex value of a decimal number +//len == length of returned string +//if len < 0 then the returned string will be as long as it needs to be to contain the data +//Only supports positive numbers +//if an invalid number is provided, it assumes num==0 +/proc/num2hex(num, len=2) + if(!isnum(num)) + num = 0 + num = round(abs(num)) + . = "" + var/i=0 + while(1) + if(len<0) + if(!num) break + else + if(i>=len) break + var/remainder = num/16 + num = round(remainder) + remainder = (remainder - num) * 16 + switch(remainder) + if(9,8,7,6,5,4,3,2,1) . = "[remainder]" + . + if(10,11,12,13,14,15) . = ascii2text(remainder+87) + . + else . = "0" + . i++ - var/power = null - power = i - 1 - while(power >= 0) - var/val = round(num / 16 ** power) - num -= val * 16 ** power - switch(val) - if(9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0) - hex += text("[]", val) - if(10.0) - hex += "A" - if(11.0) - hex += "B" - if(12.0) - hex += "C" - if(13.0) - hex += "D" - if(14.0) - hex += "E" - if(15.0) - hex += "F" - else - power-- - while(length(hex) < placeholder) - hex = text("0[]", hex) - return hex + return . //Attaches each element of a list to a single string seperated by 'seperator'. @@ -265,4 +242,4 @@ proc/tg_list2text(list/list, glue=",") switch(ui_style) if("Retro") return 'icons/mob/screen_retro.dmi' if("Plasmafire") return 'icons/mob/screen_plasmafire.dmi' - else return 'icons/mob/screen_midnight.dmi' + else return 'icons/mob/screen_midnight.dmi' \ No newline at end of file diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 5f40eea6e63..a7c982e108b 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -259,8 +259,10 @@ Turf and target are seperate in case you want to teleport some distance from a t name = newname if(mind) mind.name = newname - if(dna) - dna.real_name = real_name + if(istype(src, /mob/living/carbon)) + var/mob/living/carbon/C = src + if(C.dna) + C.dna.real_name = real_name if(oldname) //update the datacore records! This is goig to be a bit costly. diff --git a/code/datums/diseases/dna_spread.dm b/code/datums/diseases/dna_spread.dm index 3712ad2d25d..49bdb4caa1d 100644 --- a/code/datums/diseases/dna_spread.dm +++ b/code/datums/diseases/dna_spread.dm @@ -44,7 +44,7 @@ affected_mob << "\red You don't feel like yourself.." affected_mob.dna.uni_identity = strain_data["UI"] - updateappearance(affected_mob, affected_mob.dna.uni_identity) + updateappearance(affected_mob) affected_mob.dna.struc_enzymes = strain_data["SE"] affected_mob.real_name = strain_data["name"] domutcheck(affected_mob) @@ -57,7 +57,7 @@ /datum/disease/dnaspread/Del() if ((original_dna["name"]) && (original_dna["UI"]) && (original_dna["SE"])) affected_mob.dna.uni_identity = original_dna["UI"] - updateappearance(affected_mob, affected_mob.dna.uni_identity) + updateappearance(affected_mob) affected_mob.dna.struc_enzymes = original_dna["SE"] affected_mob.real_name = original_dna["name"] diff --git a/code/datums/diseases/retrovirus.dm b/code/datums/diseases/retrovirus.dm index 9ab69e217a8..521176fbf1a 100644 --- a/code/datums/diseases/retrovirus.dm +++ b/code/datums/diseases/retrovirus.dm @@ -84,10 +84,8 @@ affected_mob << "\red Your entire body vibrates." if (prob(35)) - if(prob(50)) - scramble(1, affected_mob, rand(15,45)) - else - scramble(0, affected_mob, rand(15,45)) + if(prob(50)) scramble_dna(affected_mob, 1, 0, rand(15,45)) + else scramble_dna(affected_mob, 0, 1, rand(15,45)) if(4) if(restcure) @@ -102,7 +100,5 @@ cure() return if (prob(60)) - if(prob(50)) - scramble(1, affected_mob, rand(50,75)) - else - scramble(0, affected_mob, rand(50,75)) \ No newline at end of file + if(prob(50)) scramble_dna(affected_mob, 1, 0, rand(50,75)) + else scramble_dna(affected_mob, 0, 1, rand(50,75)) \ No newline at end of file diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 10cb4527844..cbd1d07eade 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -76,8 +76,9 @@ datum/mind current = new_character //associate ourself with our new body new_character.mind = src //and associate our new body with ourself - if(changeling) //if we are a changeling mind, re-add any powers - new_character.make_changeling() + if(changeling && istype(new_character, /mob/living/carbon)) //if we are a changeling mind, re-add any powers + var/mob/living/carbon/C = new_character + C.make_changeling() if(active) new_character.key = key //now transfer the key to link the client to our new body @@ -659,7 +660,7 @@ datum/mind if("changeling") if(!(src in ticker.mode.changelings)) ticker.mode.changelings += src - ticker.mode.grant_changeling_powers(current) + current.make_changeling() special_role = "Changeling" current << "Your powers are awoken. A flash of memory returns to us...we are a changeling!" log_admin("[key_name_admin(usr)] has changeling'ed [current].") @@ -668,13 +669,14 @@ datum/mind usr << "\blue The objectives for changeling [key] have been generated. You can edit them and anounce manually." if("initialdna") - if( !changeling || !changeling.absorbed_dna.len ) + if( !changeling || !changeling.absorbed_dna.len || !istype(current, /mob/living/carbon)) usr << "\red Resetting DNA failed!" else - current.dna = changeling.absorbed_dna[1] - current.real_name = current.dna.real_name - updateappearance(current, current.dna.uni_identity) - domutcheck(current, null) + var/mob/living/carbon/C = current + C.dna = changeling.absorbed_dna[1] + C.real_name = C.dna.real_name + updateappearance(C) + domutcheck(C, null) else if (href_list["nuclear"]) switch(href_list["nuclear"]) @@ -1001,7 +1003,7 @@ datum/mind proc/make_Changling() if(!(src in ticker.mode.changelings)) ticker.mode.changelings += src - ticker.mode.grant_changeling_powers(current) + current.make_changeling() special_role = "Changeling" ticker.mode.forge_changeling_objectives(src) ticker.mode.greet_changeling(src) diff --git a/code/datums/mixed.dm b/code/datums/mixed.dm index 6732e2a8b94..1430901e296 100644 --- a/code/datums/mixed.dm +++ b/code/datums/mixed.dm @@ -2,33 +2,10 @@ /datum/data var/name = "data" - var/size = 1.0 - - -/datum/data/function - name = "function" - size = 2.0 - - -/datum/data/function/data_control - name = "data control" - - -/datum/data/function/id_changer - name = "id changer" - /datum/data/record name = "record" - size = 5.0 - var/list/fields = list( ) - - -/datum/data/text - name = "text" - var/data = null - - + var/list/fields = list() /datum/powernet var/list/cables = list() // all cables & junctions diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 87bc6b4d9df..7ef90d907d3 100644 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -1549,9 +1549,6 @@ proc/process_ghost_teleport_locs() sound_delay = rand(0, 50) for(var/mob/living/carbon/human/H in src) - if(H.s_tone > -55) - H.s_tone-- - H.update_body() if(H.client) mysound.status = SOUND_UPDATE H << mysound @@ -1669,9 +1666,6 @@ var/list/the_station_areas = list ( sound_delay = rand(0, 50) for(var/mob/living/carbon/human/H in src) -// if(H.s_tone > -55) //ugh...nice/novel idea but please no. -// H.s_tone-- -// H.update_body() if(H.client) mysound.status = SOUND_UPDATE H << mysound diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 8afa176ebad..98777f7e0ac 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -310,10 +310,7 @@ its easier to just keep the beam vertical. /atom/proc/add_blood(mob/living/carbon/human/M as mob) if (!( istype(M, /mob/living/carbon/human) )) return 0 - if (!istype(M.dna, /datum/dna)) - M.dna = new /datum/dna(null) - M.dna.real_name = M.real_name - M.check_dna() + check_dna_integrity(M) //check dna is valid and create/setup if necessary if (!( src.flags ) & FPRINT) return 0 if(!blood_DNA || !istype(blood_DNA, /list)) //if our list of DNA doesn't exist yet (or isn't a list) initialise it. diff --git a/code/game/dna.dm b/code/game/dna.dm index c5633d5f70d..7cdc41530c5 100644 --- a/code/game/dna.dm +++ b/code/game/dna.dm @@ -1,461 +1,319 @@ +#define INJECTOR_TIMEOUT 300 #define REJUVENATORS_INJECT 15 #define REJUVENATORS_MAX 90 +#define NUMBER_OF_BUFFERS 3 +#define RADIATION_STRENGTH_MAX 15 +#define RADIATION_STRENGTH_MULTIPLIER 5 //larger has a more range +#define RADIATION_STRENGTH_BIAS 0 //skews the randomisation based on radstrength*num + +#define RADIATION_DURATION_MAX 30 +#define RADIATION_ACCURACY_MULTIPLIER 12 //larger is less accurate +#define RADIATION_ACCURACY_BIAS 0 //skews the randomisation based on radduration*num + +#define RADIATION_IRRADIATION_MULTIPLIER 0.3 //multiplier for how much radiation a test subject recieves + +#define BAD_MUTATION_DIFFICULTY 2 +#define GOOD_MUTATION_DIFFICULTY 4 +#define OP_MUTATION_DIFFICULTY 5 /////////////////////////// DNA DATUM /datum/dna - var/unique_enzymes = null - var/struc_enzymes = null - var/uni_identity = null - var/b_type = "A+" + var/unique_enzymes + var/struc_enzymes + var/uni_identity + var/b_type var/mutantrace = null //The type of mutant race the player is if applicable (i.e. potato-man) var/real_name //Stores the real name of the person who originally got this dna datum. Used primarely for changelings, -/datum/dna/proc/check_integrity(var/mob/living/carbon/human/character) - if(character) - if(length(uni_identity) != 39) - //Lazy. - var/temp +/datum/dna/New() + if(!b_type) b_type = random_blood_type() - //Hair - var/hair = 0 - if(!character.h_style) - character.h_style = "Skinhead" +/datum/dna/proc/generate_uni_identity(mob/living/carbon/character) + . = "" + var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS) + if(istype(character)) + L[DNA_GENDER_BLOCK] = construct_block((character.gender!=MALE)+1, 2) + if(istype(character, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = character + L[DNA_HAIR_STYLE_BLOCK] = construct_block(hair_styles_list.Find(H.h_style), hair_styles_list.len) + L[DNA_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.h_color) + L[DNA_FACIAL_HAIR_STYLE_BLOCK] = construct_block(hair_styles_list.Find(H.f_style), facial_hair_styles_list.len) + L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.f_color) + L[DNA_SKIN_TONE_BLOCK] = construct_block(skin_tones.Find(H.s_tone), skin_tones.len) + L[DNA_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.eye_color) + + for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++) + if(L[i]) . += L[i] + else . += random_string(DNA_BLOCK_SIZE,hex_characters) + return . - var/hrange = round(4095 / hair_styles_list.len) - var/index = hair_styles_list.Find(character.h_style) - if(index) - hair = index * hrange - rand(1,hrange-1) +/datum/dna/proc/generate_struc_enzymes(mob/living/carbon/character) + var/list/L = list("0","1","2","3","4","5","6") + . = "" + for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++) + if(i == RACEBLOCK) + . += construct_block(istype(character,/mob/living/carbon/monkey)+1, 2) + else + . += random_string(DNA_BLOCK_SIZE, L) + return . - //Facial Hair - var/beard = 0 - if(!character.f_style) - character.f_style = "Shaved" - - var/f_hrange = round(4095 / facial_hair_styles_list.len) - index = facial_hair_styles_list.Find(character.f_style) - if(index) - beard = index * f_hrange - rand(1,f_hrange-1) - - temp = add_zero2(num2hex((character.r_hair),1), 3) - temp += add_zero2(num2hex((character.b_hair),1), 3) - temp += add_zero2(num2hex((character.g_hair),1), 3) - temp += add_zero2(num2hex((character.r_facial),1), 3) - temp += add_zero2(num2hex((character.b_facial),1), 3) - temp += add_zero2(num2hex((character.g_facial),1), 3) - temp += add_zero2(num2hex(((character.s_tone + 220) * 16),1), 3) - temp += add_zero2(num2hex((character.r_eyes),1), 3) - temp += add_zero2(num2hex((character.g_eyes),1), 3) - temp += add_zero2(num2hex((character.b_eyes),1), 3) - - var/gender - - if (character.gender == MALE) - gender = add_zero2(num2hex((rand(1,(2050+BLOCKADD))),1), 3) - else - gender = add_zero2(num2hex((rand((2051+BLOCKADD),4094)),1), 3) - - temp += gender - temp += add_zero2(num2hex((beard),1), 3) - temp += add_zero2(num2hex((hair),1), 3) - - uni_identity = temp - if(length(struc_enzymes)!= 42) - var/mutstring = "" - for(var/i = 1, i <= 13, i++) - mutstring += add_zero2(num2hex(rand(1,1024)),3) - - struc_enzymes = mutstring - if(length(unique_enzymes) != 32) - unique_enzymes = md5(character.real_name) +/datum/dna/proc/generate_unique_enzymes(mob/living/carbon/character) + . = "" + if(istype(character)) + real_name = character.real_name + . += md5(character.real_name) + reg_dna[.] = real_name else - if(length(uni_identity) != 39) uni_identity = "00600200A00E0110148FC01300B0095BD7FD3F4" - if(length(struc_enzymes)!= 42) struc_enzymes = "0983E840344C39F4B059D5145FC5785DC6406A4000" + . += repeat_string(DNA_UNIQUE_ENZYMES_LEN, "000") + return . -/datum/dna/proc/ready_dna(mob/living/carbon/human/character) - var/temp +/proc/hardset_dna(mob/living/carbon/owner, ui, se, real_name, mutantrace, blood_type) + if(!istype(owner)) + return + if(!owner.dna) + owner.dna = new /datum/dna() + + if(real_name) + owner.real_name = real_name + owner.dna.generate_unique_enzymes(owner) + + if(blood_type) + owner.dna.b_type = blood_type + + if(ui) + owner.dna.uni_identity = ui + updateappearance(owner) + + var/update_mutantrace = (mutantrace != owner.dna.mutantrace) + owner.dna.mutantrace = mutantrace + if(update_mutantrace && istype(owner, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = owner + H.update_mutantrace() + + if(se) + owner.dna.struc_enzymes = se + domutcheck(owner) + + check_dna_integrity(owner) + +/proc/check_dna_integrity(mob/living/carbon/character) + if(!istype(character)) + return 0 + if(!character.dna) + if(ready_dna(character)) + return 1 + return 0 + + if(length(character.dna.uni_identity) != DNA_UNI_IDENTITY_BLOCKS*DNA_BLOCK_SIZE) + character.dna.uni_identity = character.dna.generate_uni_identity(character) + if(length(character.dna.struc_enzymes)!= DNA_STRUC_ENZYMES_BLOCKS*DNA_BLOCK_SIZE) + character.dna.struc_enzymes = character.dna.generate_struc_enzymes() + if(!character.dna.real_name || length(character.dna.unique_enzymes) != DNA_UNIQUE_ENZYMES_LEN) + character.dna.unique_enzymes = character.dna.generate_unique_enzymes(character) + return 1 - //Hair - var/hair = 0 - if(!character.h_style) - character.h_style = random_hair_style(character.gender) - - var/hrange = round(4095 / hair_styles_list.len) - var/index = hair_styles_list.Find(character.h_style) - if(index) - hair = index * hrange - rand(1,hrange-1) - - //Facial Hair - var/beard = 0 - if(!character.f_style) - character.f_style = random_facial_hair_style(character.gender) - - var/f_hrange = round(4095 / facial_hair_styles_list.len) - index = facial_hair_styles_list.Find(character.f_style) - if(index) - beard = index * f_hrange - rand(1,f_hrange-1) - - temp = add_zero2(num2hex((character.r_hair),1), 3) - temp += add_zero2(num2hex((character.b_hair),1), 3) - temp += add_zero2(num2hex((character.g_hair),1), 3) - temp += add_zero2(num2hex((character.r_facial),1), 3) - temp += add_zero2(num2hex((character.b_facial),1), 3) - temp += add_zero2(num2hex((character.g_facial),1), 3) - temp += add_zero2(num2hex(((character.s_tone + 220) * 16),1), 3) - temp += add_zero2(num2hex((character.r_eyes),1), 3) - temp += add_zero2(num2hex((character.g_eyes),1), 3) - temp += add_zero2(num2hex((character.b_eyes),1), 3) - - var/gender - - if (character.gender == MALE) - gender = add_zero2(num2hex((rand(1,(2050+BLOCKADD))),1), 3) - else - gender = add_zero2(num2hex((rand((2051+BLOCKADD),4094)),1), 3) - - temp += gender - temp += add_zero2(num2hex((beard),1), 3) - temp += add_zero2(num2hex((hair),1), 3) - - uni_identity = temp - - var/mutstring = "" - for(var/i = 1, i <= 13, i++) - mutstring += add_zero2(num2hex(rand(1,1024)),3) - - struc_enzymes = mutstring - - unique_enzymes = md5(character.real_name) - reg_dna[unique_enzymes] = character.real_name +/proc/ready_dna(mob/living/carbon/character, blood_type) + if(!istype(character, /mob/living/carbon/monkey) && !istype(character, /mob/living/carbon/human)) + return 0 + if(!character.dna) + character.dna = new /datum/dna() + if(blood_type) + character.dna.b_type = blood_type + character.dna.real_name = character.real_name + character.dna.uni_identity = character.dna.generate_uni_identity(character) + character.dna.struc_enzymes = character.dna.generate_struc_enzymes(character) + character.dna.unique_enzymes = character.dna.generate_unique_enzymes(character) + return 1 /////////////////////////// DNA DATUM /////////////////////////// DNA HELPER-PROCS /proc/getleftblocks(input,blocknumber,blocksize) - var/string - - if (blocknumber > 1) - string = copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) - return string - else - return null + if(blocknumber > 1) + return copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) /proc/getrightblocks(input,blocknumber,blocksize) - var/string - if (blocknumber < (length(input)/blocksize)) - string = copytext(input,blocksize*blocknumber+1,length(input)+1) - return string - else - return null + if(blocknumber < (length(input)/blocksize)) + return copytext(input,blocksize*blocknumber+1,length(input)+1) +/* /proc/getblockstring(input,block,subblock,blocksize,src,ui) // src is probably used here just for urls; ui is 1 when requesting for the unique identifier screen, 0 for structural enzymes screen - var/string = "
" + . = "
" var/subpos = 1 // keeps track of the current sub block var/blockpos = 1 // keeps track of the current block - for(var/i = 1, i <= length(input), i++) // loop through each letter - - var/pushstring - if(subpos == subblock && blockpos == block) // if the current block/subblock is selected, mark it - pushstring = "[copytext(input, i, i+1)]" + . += "[copytext(input, i, i+1)]" else - if(ui) //This is for allowing block clicks to be differentiated - pushstring = "[copytext(input, i, i+1)]" - else - pushstring = "[copytext(input, i, i+1)]" - - string += pushstring // push the string to the return string + . += "[copytext(input, i, i+1)]" if(subpos >= blocksize) // add a line break for every block - string += "
" + . += "
" subpos = 0 blockpos++ - subpos++ - string += "
" - - return string + . += "
" + return . +*/ -/proc/getblock(input,blocknumber,blocksize) - var/result - result = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1) - return result +/proc/getblock(input, blocknumber, blocksize=DNA_BLOCK_SIZE) + return copytext(input, blocksize*(blocknumber-1)+1, (blocksize*blocknumber)+1) /proc/getblockbuffer(input,blocknumber,blocksize) - var/result[3] - var/block = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1) - for(var/i = 1, i <= 3, i++) - result[i] = copytext(block, i, i+1) + var/result[blocksize] + var/start = (blocksize*blocknumber)-blocksize + for(var/i=1, i<=blocksize, i++) + result[i] = copytext(input, start+i, start+i+1) return result -/proc/setblock(istring, blocknumber, replacement, blocksize) +/proc/setblock(istring, blocknumber, replacement, blocksize=DNA_BLOCK_SIZE) if(!istring || !blocknumber || !replacement || !blocksize) return 0 - var/result = getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize) - return result + return getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize) -/proc/add_zero2(t, u) - var/temp1 - while (length(t) < u) - t = "0[t]" - temp1 = t - if (length(t) > u) - temp1 = copytext(t,2,u+1) - return temp1 +/proc/scramble(input,rs,rd) + var/length = length(input) + var/num = hex2num(input) + num = round(num + gaussian(rs*RADIATION_STRENGTH_BIAS, rs*RADIATION_STRENGTH_MULTIPLIER), 1) + return num2hex(Wrap(num, 0, 16**length), length) -/proc/miniscramble(input,rs,rd) - var/output - output = null - if (input == "C" || input == "D" || input == "E" || input == "F") - output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"6",prob((rs*10));"7",prob((rs*5)+(rd));"0",prob((rs*5)+(rd));"1",prob((rs*10)-(rd));"2",prob((rs*10)-(rd));"3") - if (input == "8" || input == "9" || input == "A" || input == "B") - output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3") - if (input == "4" || input == "5" || input == "6" || input == "7") - output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3") - if (input == "0" || input == "1" || input == "2" || input == "3") - output = pick(prob((rs*10));"8",prob((rs*10));"9",prob((rs*10));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C",prob((rs*10)-(rd));"D",prob((rs*5)+(rd));"E",prob((rs*5)+(rd));"F") - if (!output) output = "5" - return output +/proc/randomize_radiation_accuracy(position_we_were_supposed_to_hit, radduration, number_of_blocks) + return Wrap(round(position_we_were_supposed_to_hit + gaussian(radduration*RADIATION_ACCURACY_BIAS, RADIATION_ACCURACY_MULTIPLIER/radduration), 1), 1, number_of_blocks+1) -//Instead of picking a value far from the input, this will pick values closer to it. -//Sorry for the block of code, but it's more efficient then calling text2hex -> loop -> hex2text -/proc/miniscrambletarget(input,rs,rd) - var/output = null - switch(input) - if("0") - output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10));"2",prob((rs*10)-(rd));"3") - if("1") - output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10));"3",prob((rs*10)-(rd));"4") - if("2") - output = pick(prob((rs*10));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10));"4",prob((rs*10)-(rd));"5") - if("3") - output = pick(prob((rs*10)-(rd));"0",prob((rs*10));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10));"5",prob((rs*10)-(rd));"6") - if("4") - output = pick(prob((rs*10)-(rd));"1",prob((rs*10));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10));"6",prob((rs*10)-(rd));"7") - if("5") - output = pick(prob((rs*10)-(rd));"2",prob((rs*10));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10));"7",prob((rs*10)-(rd));"8") - if("6") - output = pick(prob((rs*10)-(rd));"3",prob((rs*10));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10));"8",prob((rs*10)-(rd));"9") - if("7") - output = pick(prob((rs*10)-(rd));"4",prob((rs*10));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10));"9",prob((rs*10)-(rd));"A") - if("8") - output = pick(prob((rs*10)-(rd));"5",prob((rs*10));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10));"A",prob((rs*10)-(rd));"B") - if("9") - output = pick(prob((rs*10)-(rd));"6",prob((rs*10));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C") - if("10")//A - output = pick(prob((rs*10)-(rd));"7",prob((rs*10));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10));"C",prob((rs*10)-(rd));"D") - if("11")//B - output = pick(prob((rs*10)-(rd));"8",prob((rs*10));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10));"D",prob((rs*10)-(rd));"E") - if("12")//C - output = pick(prob((rs*10)-(rd));"9",prob((rs*10));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10));"E",prob((rs*10)-(rd));"F") - if("13")//D - output = pick(prob((rs*10)-(rd));"A",prob((rs*10));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10));"F") - if("14")//E - output = pick(prob((rs*10)-(rd));"B",prob((rs*10));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F") - if("15")//F - output = pick(prob((rs*10)-(rd));"C",prob((rs*10));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F") - - if(!input || !output) //How did this happen? - output = "8" - - return output - -/proc/isblockon(hnumber, bnumber , var/UI = 0) - - var/temp2 - temp2 = hex2num(hnumber) - - if(UI) - if(temp2 >= 2050) - return 1 - else - return 0 - - if (bnumber == HULKBLOCK || bnumber == TELEBLOCK) - if (temp2 >= 3500 + BLOCKADD) - return 1 - else - return 0 - if (bnumber == XRAYBLOCK || bnumber == FIREBLOCK) - if (temp2 >= 3050 + BLOCKADD) - return 1 - else - return 0 - - - if (temp2 >= 2050 + BLOCKADD) - return 1 - else - return 0 - -/proc/randmutb(mob/M as mob) - if(!M) return +/proc/randmutb(mob/living/carbon/M) + if(!check_dna_integrity(M)) return var/num var/newdna - num = pick(1,3,FAKEBLOCK,5,CLUMSYBLOCK,7,9,BLINDBLOCK,DEAFBLOCK) - M.dna.check_integrity() - newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3) + num = pick(bad_se_blocks) + newdna = setblock(M.dna.struc_enzymes, num, construct_block(2,2)) M.dna.struc_enzymes = newdna return -/proc/randmutg(mob/M as mob) - if(!M) return +/proc/randmutg(mob/living/carbon/M) + if(!check_dna_integrity(M)) return var/num var/newdna - num = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK) - M.dna.check_integrity() - newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3) + num = pick(good_se_blocks | op_se_blocks) + newdna = setblock(M.dna.struc_enzymes, num, construct_block(2,2)) M.dna.struc_enzymes = newdna return -/proc/scramble(var/type, mob/M as mob, var/p) - if(!M) return - M.dna.check_integrity() - if(type) - for(var/i = 1, i <= 13, i++) - if(prob(p)) - M.dna.uni_identity = setblock(M.dna.uni_identity, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3) - updateappearance(M, M.dna.uni_identity) - - else - for(var/i = 1, i <= 13, i++) - if(prob(p)) - M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3) - domutcheck(M, null) - return - -/proc/randmuti(mob/M as mob) - if(!M) return +/proc/randmuti(mob/living/carbon/M) + if(!check_dna_integrity(M)) return var/num var/newdna - num = pick(1,2,3,4,5,6,7,8,9,10,11,12,13) - M.dna.check_integrity() - newdna = setblock(M.dna.uni_identity,num,add_zero2(num2hex(rand(1,4095),1),3),3) + num = rand(1, DNA_STRUC_ENZYMES_BLOCKS) + newdna = setblock(M.dna.uni_identity, num, random_string(DNA_BLOCK_SIZE, hex_characters)) M.dna.uni_identity = newdna return -/proc/toggledblock(hnumber) //unused - var/temp3 - var/chtemp - temp3 = hex2num(hnumber) - if (temp3 < 2050) - chtemp = rand(2050,4095) - return add_zero2(num2hex(chtemp,1),3) - else - chtemp = rand(1,2049) - return add_zero2(num2hex(chtemp,1),3) +/proc/scramble_dna(mob/living/carbon/M, ui=FALSE, se=FALSE, probability) + if(!check_dna_integrity(M)) + return 0 + if(se) + for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++) + if(prob(probability)) + M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, random_string(DNA_BLOCK_SIZE, hex_characters)) + domutcheck(M, null) + if(ui) + for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++) + if(prob(probability)) + M.dna.uni_identity = setblock(M.dna.uni_identity, i, random_string(DNA_BLOCK_SIZE, hex_characters)) + updateappearance(M) + return 1 + /////////////////////////// DNA HELPER-PROCS /////////////////////////// DNA MISC-PROCS -/proc/updateappearance(mob/M as mob , structure) - if(istype(M, /mob/living/carbon/human)) - M.dna.check_integrity() - var/mob/living/carbon/human/H = M - H.r_hair = hex2num(getblock(structure,1,3)) - H.b_hair = hex2num(getblock(structure,2,3)) - H.g_hair = hex2num(getblock(structure,3,3)) - H.r_facial = hex2num(getblock(structure,4,3)) - H.b_facial = hex2num(getblock(structure,5,3)) - H.g_facial = hex2num(getblock(structure,6,3)) - H.s_tone = round(((hex2num(getblock(structure,7,3)) / 16) - 220)) - H.r_eyes = hex2num(getblock(structure,8,3)) - H.g_eyes = hex2num(getblock(structure,9,3)) - H.b_eyes = hex2num(getblock(structure,10,3)) - - if (isblockon(getblock(structure, 11,3),11 , 1)) - H.gender = FEMALE - else - H.gender = MALE - - //Hair - var/hairnum = hex2num(getblock(structure,13,3)) - var/index = round(1 +(hairnum / 4096)*hair_styles_list.len) - if((0 < index) && (index <= hair_styles_list.len)) - H.h_style = hair_styles_list[index] - - //Facial Hair - var/beardnum = hex2num(getblock(structure,12,3)) - index = round(1 +(beardnum / 4096)*facial_hair_styles_list.len) - if((0 < index) && (index <= facial_hair_styles_list.len)) - H.f_style = facial_hair_styles_list[index] - - H.update_body(0) - H.update_hair() - - return 1 - else +/proc/updateappearance(mob/living/carbon/human/H) + if(!istype(H) || !istype(H.dna)) return 0 + check_dna_integrity() + var/structure = H.dna.uni_identity + H.h_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK)) + H.f_color = sanitize_hexcolor(getblock(structure, DNA_FACIAL_HAIR_COLOR_BLOCK)) + H.s_tone = skin_tones[deconstruct_block(getblock(structure, DNA_SKIN_TONE_BLOCK), skin_tones.len)] + H.eye_color = sanitize_hexcolor(getblock(structure, DNA_EYE_COLOR_BLOCK)) + H.gender = (deconstruct_block(getblock(structure, DNA_GENDER_BLOCK), 2)-1) ? MALE : FEMALE + H.f_style = facial_hair_styles_list[deconstruct_block(getblock(structure, DNA_FACIAL_HAIR_STYLE_BLOCK), facial_hair_styles_list.len)] + H.h_style = hair_styles_list[deconstruct_block(getblock(structure, DNA_HAIR_STYLE_BLOCK), hair_styles_list.len)] -/proc/domutcheck(mob/living/M as mob, connected, inj) - //telekinesis = 1 - //firemut = 2 - //xray = 4 - //hulk = 8 - //clumsy = 16 - M.dna.check_integrity() + H.update_body(0) + H.update_hair() + return 1 + +/proc/domutcheck(mob/living/carbon/M, connected, inj) + if(!check_dna_integrity(M)) + return 0 M.disabilities = 0 M.sdisabilities = 0 - M.mutations = list() + M.mutations.Cut() - M.see_in_dark = 2 - M.see_invisible = SEE_INVISIBLE_LIVING + M.see_in_dark = initial(M.see_in_dark) + M.see_invisible = initial(M.see_invisible) - if (isblockon(getblock(M.dna.struc_enzymes, 1,3),1)) + var/list/blocks = new /list(DNA_STRUC_ENZYMES_BLOCKS) //on-off status for each block + for(var/i in bad_se_blocks) //bad mutations + blocks[i] = (deconstruct_block(getblock(M.dna.struc_enzymes, i), BAD_MUTATION_DIFFICULTY) == BAD_MUTATION_DIFFICULTY) + for(var/i in good_se_blocks) //good mutations + blocks[i] = (deconstruct_block(getblock(M.dna.struc_enzymes, i), GOOD_MUTATION_DIFFICULTY) == GOOD_MUTATION_DIFFICULTY) + for(var/i in op_se_blocks) //Overpowered mutations...extra difficult to obtain + blocks[i] = (deconstruct_block(getblock(M.dna.struc_enzymes, i), OP_MUTATION_DIFFICULTY) == GOOD_MUTATION_DIFFICULTY) + + if(blocks[NEARSIGHTEDBLOCK]) M.disabilities |= NEARSIGHTED M << "\red Your eyes feel strange." - if (isblockon(getblock(M.dna.struc_enzymes, HULKBLOCK,3),2)) - if(inj || prob(10)) - M << "\blue Your muscles hurt." - M.mutations.Add(HULK) - if (isblockon(getblock(M.dna.struc_enzymes, 3,3),3)) + if(blocks[EPILEPSYBLOCK]) M.disabilities |= EPILEPSY M << "\red You get a headache." - if (isblockon(getblock(M.dna.struc_enzymes, FAKEBLOCK,3),4)) + if(blocks[STRANGEBLOCK]) M << "\red You feel strange." - if (prob(95)) - if(prob(50)) - randmutb(M) - else - randmuti(M) - else - randmutg(M) - if (isblockon(getblock(M.dna.struc_enzymes, 5,3),5)) + if(prob(95)) + if(prob(50)) randmutb(M) + else randmuti(M) + else randmutg(M) + if(blocks[COUGHBLOCK]) M.disabilities |= COUGHING M << "\red You start coughing." - if (isblockon(getblock(M.dna.struc_enzymes, CLUMSYBLOCK,3),6)) + if(blocks[CLUMSYBLOCK]) M << "\red You feel lightheaded." - M.mutations.Add(CLUMSY) - if (isblockon(getblock(M.dna.struc_enzymes, 7,3),7)) + M.mutations |= CLUMSY + if(blocks[TOURETTESBLOCK]) M.disabilities |= TOURETTES M << "\red You twitch." - if (isblockon(getblock(M.dna.struc_enzymes, XRAYBLOCK,3),8)) - if(inj || prob(30)) - M << "\blue The walls suddenly disappear." - M.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) - M.see_in_dark = 8 - M.see_invisible = SEE_INVISIBLE_LEVEL_TWO - M.mutations.Add(XRAY) - if (isblockon(getblock(M.dna.struc_enzymes, 9,3),9)) + if(blocks[NERVOUSBLOCK]) M.disabilities |= NERVOUS M << "\red You feel nervous." - if (isblockon(getblock(M.dna.struc_enzymes, FIREBLOCK,3),10)) - if(inj || prob(30)) - M << "\blue Your body feels warm." - M.mutations.Add(COLD_RESISTANCE) - if (isblockon(getblock(M.dna.struc_enzymes, BLINDBLOCK,3),11)) - M.sdisabilities |= BLIND - M << "\red You can't seem to see anything." - if (isblockon(getblock(M.dna.struc_enzymes, TELEBLOCK,3),12)) - if(inj || prob(25)) - M << "\blue You feel smarter." - M.mutations.Add(TK) - if (isblockon(getblock(M.dna.struc_enzymes, DEAFBLOCK,3),13)) + if(blocks[DEAFBLOCK]) M.sdisabilities |= DEAF M.ear_deaf = 1 M << "\red You can't seem to hear anything..." + if(blocks[BLINDBLOCK]) + M.sdisabilities |= BLIND + M << "\red You can't seem to see anything." + if(blocks[HULKBLOCK]) + if(inj || prob(10)) + M.mutations |= HULK + M << "\blue Your muscles hurt." + if(blocks[XRAYBLOCK]) + if(inj || prob(30)) + M.mutations |= XRAY + M << "\blue The walls suddenly disappear." + M.sight |= SEE_MOBS|SEE_OBJS|SEE_TURFS + M.see_in_dark = 8 + M.see_invisible = SEE_INVISIBLE_LEVEL_TWO + if(blocks[FIREBLOCK]) + if(inj || prob(30)) + M.mutations |= COLD_RESISTANCE + M << "\blue Your body feels warm." + if(blocks[TELEBLOCK]) + if(inj || prob(25)) + M.mutations |= TK + M << "\blue You feel smarter." + /* If you want the new mutations to work, UNCOMMENT THIS. if(istype(M, /mob/living/carbon)) @@ -464,162 +322,143 @@ */ //////////////////////////////////////////////////////////// Monkey Block - if (isblockon(getblock(M.dna.struc_enzymes, 14,3),14) && istype(M, /mob/living/carbon/human)) - // human > monkey - var/mob/living/carbon/human/H = M - H.monkeyizing = 1 - var/list/implants = list() //Try to preserve implants. - for(var/obj/item/weapon/implant/W in H) - implants += W - W.loc = null + if(blocks[RACEBLOCK]) + if(istype(M, /mob/living/carbon/human)) // human > monkey + var/mob/living/carbon/human/H = M + H.monkeyizing = 1 + var/list/implants = list() //Try to preserve implants. + for(var/obj/item/weapon/implant/W in H) + implants += W + W.loc = null - if(!connected) - for(var/obj/item/W in (H.contents-implants)) - if (W==H.w_uniform) // will be teared - continue - H.drop_from_inventory(W) - M.monkeyizing = 1 - M.canmove = 0 - M.icon = null - M.invisibility = 101 - var/atom/movable/overlay/animation = new( M.loc ) - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = src - flick("h2monkey", animation) - sleep(48) - del(animation) + if(!connected) + for(var/obj/item/W in (H.contents-implants)) + if(W==H.w_uniform) // will be teared + continue + H.drop_from_inventory(W) + M.monkeyizing = 1 + M.canmove = 0 + M.icon = null + M.invisibility = 101 + var/atom/movable/overlay/animation = new( M.loc ) + animation.icon_state = "blank" + animation.icon = 'icons/mob/mob.dmi' + animation.master = src + flick("h2monkey", animation) + sleep(48) + del(animation) - var/mob/living/carbon/monkey/O = new(src) + var/mob/living/carbon/monkey/O = new(src) - if(M) - if (M.dna) - O.dna = M.dna - M.dna = null + if(M) + if(M.dna) + O.dna = M.dna + M.dna = null - if (M.suiciding) - O.suiciding = M.suiciding - M.suiciding = null + if(M.suiciding) + O.suiciding = M.suiciding + M.suiciding = null - for(var/datum/disease/D in M.viruses) - O.viruses += D - D.affected_mob = O - M.viruses -= D + for(var/datum/disease/D in M.viruses) + O.viruses += D + D.affected_mob = O + M.viruses -= D - for(var/obj/T in (M.contents-implants)) - del(T) - //for(var/R in M.organs) - // del(M.organs[text("[]", R)]) + for(var/obj/T in (M.contents-implants)) + del(T) - O.loc = M.loc + O.loc = M.loc - if(M.mind) - M.mind.transfer_to(O) //transfer our mind to the cute little monkey + if(M.mind) + M.mind.transfer_to(O) //transfer our mind to the cute little monkey - if (connected) //inside dna thing - var/obj/machinery/dna_scannernew/C = connected - O.loc = C - C.occupant = O - connected = null - O.real_name = text("monkey ([])",copytext(md5(M.real_name), 2, 6)) - O.take_overall_damage(M.getBruteLoss() + 40, M.getFireLoss()) - O.adjustToxLoss(M.getToxLoss() + 20) - O.adjustOxyLoss(M.getOxyLoss()) - O.stat = M.stat - O.a_intent = "harm" - for (var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O -// O.update_icon = 1 //queue a full icon update at next life() call - del(M) - return + if(connected) //inside dna thing + var/obj/machinery/dna_scannernew/C = connected + O.loc = C + C.occupant = O + connected = null + O.real_name = text("monkey ([])",copytext(md5(M.real_name), 2, 6)) + O.take_overall_damage(M.getBruteLoss() + 40, M.getFireLoss()) + O.adjustToxLoss(M.getToxLoss() + 20) + O.adjustOxyLoss(M.getOxyLoss()) + O.stat = M.stat + O.a_intent = "harm" + for (var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O + // O.update_icon = 1 //queue a full icon update at next life() call + del(M) + return 1 + else + if(istype(M, /mob/living/carbon/monkey)) // monkey > human, + var/mob/living/carbon/monkey/Mo = M + Mo.monkeyizing = 1 + var/list/implants = list() //Still preserving implants + for(var/obj/item/weapon/implant/W in Mo) + implants += W + W.loc = null + if(!connected) + for(var/obj/item/W in (Mo.contents-implants)) + Mo.drop_from_inventory(W) + M.monkeyizing = 1 + M.canmove = 0 + M.icon = null + M.invisibility = 101 + var/atom/movable/overlay/animation = new( M.loc ) + animation.icon_state = "blank" + animation.icon = 'icons/mob/mob.dmi' + animation.master = src + flick("monkey2h", animation) + sleep(48) + del(animation) - if (!isblockon(getblock(M.dna.struc_enzymes, 14,3),14) && !istype(M, /mob/living/carbon/human)) - // monkey > human, - var/mob/living/carbon/monkey/Mo = M - Mo.monkeyizing = 1 - var/list/implants = list() //Still preserving implants - for(var/obj/item/weapon/implant/W in Mo) - implants += W - W.loc = null - if(!connected) - for(var/obj/item/W in (Mo.contents-implants)) - Mo.drop_from_inventory(W) - M.monkeyizing = 1 - M.canmove = 0 - M.icon = null - M.invisibility = 101 - var/atom/movable/overlay/animation = new( M.loc ) - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = src - flick("monkey2h", animation) - sleep(48) - del(animation) + var/mob/living/carbon/human/O = new( src ) + O.gender = (deconstruct_block(getblock(M.dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? MALE : FEMALE - var/mob/living/carbon/human/O = new( src ) - if (isblockon(getblock(M.dna.uni_identity, 11,3),11)) - O.gender = FEMALE - else - O.gender = MALE + if(M) + if(M.dna) + O.dna = M.dna + M.dna = null - if (M) - if (M.dna) - O.dna = M.dna - M.dna = null + if(M.suiciding) + O.suiciding = M.suiciding + M.suiciding = null - if (M.suiciding) - O.suiciding = M.suiciding - M.suiciding = null + O.viruses = M.viruses.Copy() + M.viruses.Cut() + for(var/datum/disease/D in O.viruses) + D.affected_mob = O - for(var/datum/disease/D in M.viruses) - O.viruses += D - D.affected_mob = O - M.viruses -= D + O.loc = M.loc - //for(var/obj/T in M) - // del(T) + if(M.mind) + M.mind.transfer_to(O) //transfer our mind to the human - O.loc = M.loc + if(connected) //inside dna thing + var/obj/machinery/dna_scannernew/C = connected + O.loc = C + C.occupant = O + connected = null - if(M.mind) - M.mind.transfer_to(O) //transfer our mind to the human - - if (connected) //inside dna thing - var/obj/machinery/dna_scannernew/C = connected - O.loc = C - C.occupant = O - connected = null - - var/i - while (!i) - var/randomname - if (O.gender == MALE) - randomname = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names))) - else - randomname = capitalize(pick(first_names_female) + " " + capitalize(pick(last_names))) - if (findname(randomname)) - continue - else - O.real_name = randomname - i++ - updateappearance(O,O.dna.uni_identity) - O.take_overall_damage(M.getBruteLoss(), M.getFireLoss()) - O.adjustToxLoss(M.getToxLoss()) - O.adjustOxyLoss(M.getOxyLoss()) - O.stat = M.stat - for (var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O -// O.update_icon = 1 //queue a full icon update at next life() call - del(M) - return + O.real_name = random_name(O.gender) + + updateappearance(O) + O.take_overall_damage(M.getBruteLoss(), M.getFireLoss()) + O.adjustToxLoss(M.getToxLoss()) + O.adjustOxyLoss(M.getOxyLoss()) + O.stat = M.stat + for (var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O + // O.update_icon = 1 //queue a full icon update at next life() call + del(M) + return 1 //////////////////////////////////////////////////////////// Monkey Block if(M) M.update_icon = 1 //queue a full icon update at next life() call - return null + return 1 /////////////////////////// DNA MISC-PROCS @@ -653,9 +492,9 @@ return 0 /obj/machinery/dna_scannernew/relaymove(mob/user as mob) - if (user.stat) + if(user.stat) return - src.go_out() + go_out() return /obj/machinery/dna_scannernew/verb/eject() @@ -663,9 +502,9 @@ set category = "Object" set name = "Eject DNA Scanner" - if (usr.stat != 0) + if(usr.stat != 0) return - src.go_out() + go_out() for(var/obj/O in src) if((!istype(O,/obj/item/weapon/circuitboard/clonescanner)) && (!istype(O,/obj/item/weapon/stock_parts)) && (!istype(O,/obj/item/weapon/cable_coil))) O.loc = get_turf(src)//Ejects items that manage to get in there (exluding the components) @@ -688,6 +527,9 @@ if(occupant) usr << "The scanner is already occupied!" return + if(locked) + usr << "The bolts are locked." + return if(usr.abiotic()) usr << "Subject cannot have abiotic items on." return @@ -695,15 +537,15 @@ usr.client.perspective = EYE_PERSPECTIVE usr.client.eye = src usr.loc = src - src.occupant = usr - src.icon_state = "scanner_1" + occupant = usr + icon_state = "scanner_1" /* for(var/obj/O in src) // THIS IS P. STUPID -- LOVE, DOOHL //O = null del(O) //Foreach goto(124) */ - src.add_fingerprint(usr) + add_fingerprint(usr) return /obj/machinery/dna_scannernew/attackby(obj/item/weapon/grab/G, mob/user) @@ -712,6 +554,9 @@ if(occupant) user << "The scanner is already occupied!" return + if(locked) + user << "The scanner is locked." + return if(G.affecting.abiotic()) user << "Subject cannot have abiotic items on." return @@ -741,46 +586,46 @@ return /obj/machinery/dna_scannernew/proc/go_out() - if ((!( src.occupant ) || src.locked)) + if(!occupant || locked) return /* // it's like this was -just- here to break constructed dna scanners -Pete // if that's not the case, slap my shit and uncomment this. // for(var/obj/O in src) -// O.loc = src.loc +// O.loc = loc */ //Foreach goto(30) - if (src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - src.occupant.loc = src.loc - src.occupant = null - src.icon_state = "scanner_0" + if(occupant.client) + occupant.client.eye = occupant.client.mob + occupant.client.perspective = MOB_PERSPECTIVE + occupant.loc = loc + occupant = null + icon_state = "scanner_0" return /obj/machinery/dna_scannernew/ex_act(severity) switch(severity) if(1.0) for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc + A.loc = loc ex_act(severity) //Foreach goto(35) //SN src = null del(src) return if(2.0) - if (prob(50)) + if(prob(50)) for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc + A.loc = loc ex_act(severity) //Foreach goto(108) //SN src = null del(src) return if(3.0) - if (prob(25)) + if(prob(25)) for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc + A.loc = loc ex_act(severity) //Foreach goto(181) //SN src = null @@ -793,10 +638,71 @@ /obj/machinery/dna_scannernew/blob_act() if(prob(75)) for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc + A.loc = loc del(src) +/obj/machinery/computer/scan_consolenew + name = "DNA Scanner Access Console" + desc = "Scan DNA." + icon = 'icons/obj/computer.dmi' + icon_state = "scanner" + density = 1 + var/radduration = 2 + var/radstrength = 1 + + var/list/buffer[NUMBER_OF_BUFFERS] + + var/injectorready = 0 //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete + var/current_screen = "mainmenu" + var/obj/machinery/dna_scannernew/connected = null + var/obj/item/weapon/disk/data/diskette = null + anchored = 1.0 + use_power = 1 + 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/weapon/screwdriver)) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + if(do_after(user, 20)) + if (src.stat & BROKEN) + user << "\blue The broken glass falls out." + var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) + new /obj/item/weapon/shard( src.loc ) + var/obj/item/weapon/circuitboard/scan_consolenew/M = new /obj/item/weapon/circuitboard/scan_consolenew( A ) + for (var/obj/C in src) + C.loc = src.loc + A.circuit = M + A.state = 3 + A.icon_state = "3" + A.anchored = 1 + del(src) + else + user << "\blue You disconnect the monitor." + var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) + var/obj/item/weapon/circuitboard/scan_consolenew/M = new /obj/item/weapon/circuitboard/scan_consolenew( A ) + for (var/obj/C in src) + C.loc = src.loc + A.circuit = M + A.state = 4 + A.icon_state = "4" + A.anchored = 1 + del(src) + if (istype(I, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES + if (!src.diskette) + user.drop_item() + I.loc = src + src.diskette = I + user << "You insert [I]." + src.updateUsrDialog() + return + else + src.attack_hand(user) + return + + + /obj/machinery/computer/scan_consolenew/ex_act(severity) switch(severity) @@ -805,7 +711,7 @@ del(src) return if(2.0) - if (prob(50)) + if(prob(50)) //SN src = null del(src) return @@ -825,7 +731,7 @@ stat &= ~NOPOWER else spawn(rand(0, 15)) - src.icon_state = "c_unpowered" + icon_state = "c_unpowered" stat |= NOPOWER /obj/machinery/computer/scan_consolenew/New() @@ -837,802 +743,380 @@ if(!isnull(connected)) break spawn(250) - src.injectorready = 1 + injectorready = 1 return return /obj/machinery/computer/scan_consolenew/attackby(obj/item/W as obj, mob/user as mob) - if ((istype(W, /obj/item/weapon/disk/data)) && (!src.diskette)) + if((istype(W, /obj/item/weapon/disk/data)) && (!diskette)) user.drop_item() W.loc = src - src.diskette = W + diskette = W user << "You insert [W]." - src.updateUsrDialog() -/* -/obj/machinery/computer/scan_consolenew/process() //not really used right now - if(stat & (NOPOWER|BROKEN)) - return - if (!( src.status )) //remove this - return - return -*/ + updateUsrDialog() + /obj/machinery/computer/scan_consolenew/attack_paw(user as mob) - return src.attack_hand(user) + return attack_hand(user) /obj/machinery/computer/scan_consolenew/attack_ai(user as mob) - return src.attack_hand(user) + return attack_hand(user) -/obj/machinery/computer/scan_consolenew/attack_hand(user as mob) +/obj/machinery/computer/scan_consolenew/attack_hand(mob/user) if(..()) return - dopage(src) + ShowInterface(user) + +/obj/machinery/computer/scan_consolenew/proc/ShowInterface(mob/user) + if(!user) return + var/datum/browser/popup = new(user, "scannernew", "DNA Modifier Console", 880, 450) // Set up the popup browser window + popup.add_stylesheet("scannernew", 'html/browser/scannernew.css') + + var/mob/living/carbon/viable_occupant + var/occupant_status + var/scanner_status + var/temp_html + if(connected) + if(connected.occupant) //set occupant_status message + viable_occupant = connected.occupant + if(check_dna_integrity(viable_occupant) && !(NOCLONE in viable_occupant.mutations)) //occupent is viable for dna modification + switch(viable_occupant.stat) + if(CONSCIOUS) occupant_status = "Conscious" + if(UNCONSCIOUS) occupant_status = "Unconscious" + else occupant_status = "DEAD" + occupant_status = "[viable_occupant.name] => [occupant_status]
" + occupant_status += "
Health:
[viable_occupant.health]%
" + occupant_status += "
Radiation Level:
[viable_occupant.radiation]%
" + var/rejuvenators = viable_occupant.reagents.get_reagent_amount("inaprovaline") + occupant_status += "
Rejuvenators:
[rejuvenators] units
" + else + viable_occupant = null + occupant_status = "Invalid DNA structure" + else + occupant_status = "No subject detected" + + if(connected.locked) + scanner_status = "Locked" + else + scanner_status = "Unlocked" + else + occupant_status = "Error: Undefined" + scanner_status = "Error: No scanner detected" + var/status = "
Scanner Status: [scanner_status]
Subject Status: [occupant_status]
Emitter Array Output Level: [radstrength]
Emitter Array Pulse Duration: [radduration]
" + + var/buttons = "Scan " + if(connected) buttons += "Toggle Bolts " + else buttons += "Toggle Bolts " + if(viable_occupant) buttons += "Inject Rejuvenators " + else buttons += "Inject Rejuvenators " + if(diskette) buttons += "Eject Disk " + else buttons += "Eject Disk " + if(current_screen == "buffer") buttons += "Main Menu " + else buttons += "Buffers " + buttons += "
-- Emitter Array Output Level ++" + buttons += "
-- Emitter Array Pulse Duration ++" + + switch(current_screen) + if("working") + temp_html += "

System Busy

" + temp_html += status + temp_html += "Working ... Please wait ([radduration] Seconds)" + if("buffer") + temp_html += "

Buffer Menu

" + temp_html += status + temp_html += buttons + + if(istype(buffer)) + for(var/i=1, i<=buffer.len, i++) + temp_html += "
Slot [i]: " + var/list/buffer_slot = buffer[i] + if( !buffer_slot || !buffer_slot.len || !buffer_slot["name"] || !((buffer_slot["UI"] && buffer_slot["UE"]) || buffer_slot["SE"]) ) + temp_html += "
\tNo Data" + if(viable_occupant) temp_html += "
Save to Buffer " + else temp_html += "
Save to Buffer " + temp_html += "Clear Buffer " + if(diskette) temp_html += "Load from Disk " + else temp_html += "Load from Disk " + temp_html += "Save to Disk " + else + var/ui = buffer_slot["UI"] + var/se = buffer_slot["SE"] + var/ue = buffer_slot["UE"] + var/name = buffer_slot["name"] + var/label = buffer_slot["label"] + var/b_type = buffer_slot["b_type"] + temp_html += "
\tLabel: [label ? label : name]" + temp_html += "
\tSubject: [name]" + if(ue && name && b_type) + temp_html += "
\tBlood Type: [b_type]" + temp_html += "
\tUE: [ue] " + if(viable_occupant) temp_html += "Occupant " + else temp_html += "Occupant" + if(injectorready) temp_html += "Injector" + else temp_html += "Injector" + else + temp_html += "
\tBlood Type: No Data" + temp_html += "
\tUE: No Data" + if(ui) + temp_html += "
\tUI: [ui] " + if(viable_occupant) temp_html += "Occupant " + else temp_html += "Occupant" + if(injectorready) temp_html += "Injector" + else temp_html += "Injector" + else + temp_html += "
\tUI: No Data" + if(se) + temp_html += "
\tSE: [se] " + if(viable_occupant) temp_html += "Occupant " + else temp_html += "Occupant " + if(injectorready) temp_html += "Injector" + else temp_html += "Injector" + else + temp_html += "
\tSE: No Data" + if(viable_occupant) temp_html += "
Save to Buffer " + else temp_html += "
Save to Buffer " + temp_html += "Clear Buffer " + if(diskette) temp_html += "Load from Disk " + else temp_html += "Load from Disk " + if(diskette && !diskette.read_only) temp_html += "Save to Disk " + else temp_html += "Save to Disk " + else + temp_html += "

Main Menu

" + temp_html += status + temp_html += buttons + + temp_html += "
Unique Enzymes :
" + if(viable_occupant) + temp_html += "[viable_occupant.dna.unique_enzymes]" + else + temp_html += " - " + temp_html += "
" + + temp_html += "
Unique Identifier:
" + if(viable_occupant) + var/len = length(viable_occupant.dna.uni_identity) + for(var/i=1, i<=len, i++) + temp_html += "[copytext(viable_occupant.dna.uni_identity,i,i+1)]" + else + temp_html += " - " + temp_html += "
" + + temp_html += "
Structural Enzymes:
" + if(viable_occupant) + var/len = length(viable_occupant.dna.struc_enzymes) + for(var/i=1, i<=len, i++) + temp_html += "[copytext(viable_occupant.dna.struc_enzymes,i,i+1)]" + else + temp_html += " - " + temp_html += "
" + + popup.set_content(temp_html) + popup.open() + /obj/machinery/computer/scan_consolenew/Topic(href, href_list) if(..()) return - if(!istype(usr.loc, /turf)) + if(!isturf(usr.loc)) return - if(!src ) + if(!( (isturf(loc) && in_range(src, usr)) || istype(usr, /mob/living/silicon) )) return - if (!((usr.contents.Find(src) || in_range(src, usr) && istype(src.loc, /turf)) || (istype(usr, /mob/living/silicon)))) + if(current_screen == "working") return - src.add_fingerprint(usr) - - var/datum/browser/popup = new(usr, "scannernew", "DNA Modifier Console", 520, 620) // Set up the popup browser window - popup.add_stylesheet("scannernew", 'html/browser/scannernew.css') - popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state)) - - src.scanner_status_html = null // Scanner status is reset each update - src.temp_html = null - var/temp_header_html = null - var/temp_footer_html = null - + add_fingerprint(usr) usr.set_machine(src) + + var/mob/living/carbon/viable_occupant + if(connected) + viable_occupant = connected.occupant + if(!istype(viable_occupant) || !viable_occupant.dna || (NOCLONE in viable_occupant.mutations)) + viable_occupant = null - var/mob/living/occupant = null - var/viable_occupant = null - var/mob/living/carbon/human/human_occupant = null + //Basic Tasks/////////////////////////////////////////// + var/num = round(text2num(href_list["num"])) + switch(href_list["task"]) + if("togglelock") + if(connected) connected.locked = !connected.locked + if("setduration") + if(!num) + num = round(input(usr, "Choose pulse duration:", "Input an Integer", null) as num|null) + if(num) + radduration = Wrap(num, 1, RADIATION_DURATION_MAX+1) + if("setstrength") + if(!num) + num = round(input(usr, "Choose pulse strength:", "Input an Integer", null) as num|null) + if(num) + radstrength = Wrap(num, 1, RADIATION_STRENGTH_MAX+1) + if("screen") + current_screen = href_list["text"] + if("rejuv") + if(viable_occupant && viable_occupant.reagents) + var/inaprovaline_amount = viable_occupant.reagents.get_reagent_amount("inaprovaline") + var/can_add = max(min(REJUVENATORS_MAX - inaprovaline_amount, REJUVENATORS_INJECT), 0) + viable_occupant.reagents.add_reagent("inaprovaline", can_add) + if("setbufferlabel") + var/text = sanitize(input(usr, "Input a new label:", "Input an Text", null) as text|null) + if(num && text) + num = Clamp(num, 1, NUMBER_OF_BUFFERS) + var/list/buffer_slot = buffer[num] + if(istype(buffer_slot)) + buffer_slot["label"] = text + if("setbuffer") + if(num && viable_occupant) + num = Clamp(num, 1, NUMBER_OF_BUFFERS) + buffer[num] = list( + "label"="Buffer[num]:[viable_occupant.real_name]", + "UI"=viable_occupant.dna.uni_identity, + "SE"=viable_occupant.dna.struc_enzymes, + "UE"=viable_occupant.dna.unique_enzymes, + "name"=viable_occupant.real_name, + "b_type"=viable_occupant.dna.b_type + ) + if("clearbuffer") + if(num) + num = Clamp(num, 1, NUMBER_OF_BUFFERS) + var/list/buffer_slot = buffer[num] + if(istype(buffer_slot)) + buffer_slot.Cut() + if("transferbuffer") + if(num && viable_occupant) + num = Clamp(num, 1, NUMBER_OF_BUFFERS) + var/list/buffer_slot = buffer[num] + if(istype(buffer_slot)) + switch(href_list["text"]) + if("se") + if(buffer_slot["SE"]) + viable_occupant.dna.struc_enzymes = buffer_slot["SE"] + domutcheck(viable_occupant, connected) + if("ui") + if(buffer_slot["UI"]) + viable_occupant.dna.uni_identity = buffer_slot["UI"] + updateappearance(viable_occupant) + else + if(buffer_slot["name"] && buffer_slot["UE"] && buffer_slot["b_type"]) + viable_occupant.real_name = buffer_slot["name"] + viable_occupant.name = buffer_slot["name"] + viable_occupant.dna.unique_enzymes = buffer_slot["UE"] + viable_occupant.dna.b_type = buffer_slot["b_type"] + updateappearance(viable_occupant) + viable_occupant.radiation += rand(15,40) + if("injector") + if(num && injectorready) + num = Clamp(num, 1, NUMBER_OF_BUFFERS) + var/list/buffer_slot = buffer[num] + if(istype(buffer_slot)) + var/obj/item/weapon/dnainjector/I + switch(href_list["text"]) + if("se") + if(buffer_slot["SE"]) + I = new /obj/item/weapon/dnainjector(loc) + I.fields = list("SE"=buffer_slot["SE"]) + if("ui") + if(buffer_slot["UI"]) + I = new /obj/item/weapon/dnainjector(loc) + I.fields = list("UI"=buffer_slot["UI"]) + else + if(buffer_slot["name"] && buffer_slot["UE"] && buffer_slot["b_type"]) + I = new /obj/item/weapon/dnainjector(loc) + I.fields = list("name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "b_type"=buffer_slot["b_type"]) + if(I) + injectorready = 0 + spawn(INJECTOR_TIMEOUT) + injectorready = 1 + if("loaddisk") + if(num && diskette && diskette.fields) + num = Clamp(num, 1, NUMBER_OF_BUFFERS) + buffer[num] = diskette.fields.Copy() + if("savedisk") + if(num && diskette && !diskette.read_only) + num = Clamp(num, 1, NUMBER_OF_BUFFERS) + var/list/buffer_slot = buffer[num] + if(istype(buffer_slot)) + diskette.name = "data disk \[[buffer_slot["label"]]\]" + diskette.fields = buffer_slot.Copy() + if("ejectdisk") + if(diskette) + diskette.loc = get_turf(src) + diskette = null + if("pulseui","pulsese") + if(num && viable_occupant && connected) + radduration = Wrap(radduration, 1, RADIATION_DURATION_MAX+1) + radstrength = Wrap(radstrength, 1, RADIATION_STRENGTH_MAX+1) - if (href_list["screen"]) // Passing a screen is only a request, we set current_screen here but it can be overridden below if necessary - src.current_screen = href_list["screen"] - - if (!src.current_screen) // If no screen is set default to mainmenu - src.current_screen = "mainmenu" - - if (!src.connected) //Is the scanner not connected? - src.scanner_status_html = "
Build a DNA Modifier adjacent to this computer and try again.
" - src.current_screen = null // blank does not exist in the switch below, so no screen will be outputted - href_list = new /list(0) //Clear out whatever button the user might have pressed - else - occupant = src.connected.occupant - viable_occupant = (occupant && occupant.dna && !(NOCLONE in occupant.mutations)) - human_occupant = src.connected.occupant - - if (!viable_occupant && src.connected) // If there is no viable occupant only allow certain screens - var/allowed_no_occupant_screens = list("mainmenu", "radsetmenu", "buffermenu") //These are the screens which will be allowed if there's no occupant - if (!(src.current_screen in allowed_no_occupant_screens)) - href_list = new /list(0) // clear list of options - src.current_screen = "mainmenu" - - if (href_list["locked"]) - if (src.connected.occupant) - src.connected.locked = !( src.connected.locked ) - //////////////////////////////////////////////////////// - if (href_list["genpulse"]) - if(!viable_occupant)//Makes sure someone is in there (And valid) before trying anything - src.temp_html = text("No viable occupant detected.")//More than anything, this just acts as a sanity check in case the option DOES appear for whatever reason - //usr << browse(temp_html, "window=scannernew;size=550x650") - //onclose(usr, "scannernew") - popup.set_content(src.temp_html) - popup.open() - else - - src.temp_html = text("Working ... Please wait ([] Seconds)", src.radduration) - popup.set_content(src.temp_html) - popup.open() - var/lock_state = src.connected.locked - src.connected.locked = 1//lock it - sleep(10*src.radduration) - if (!src.connected.occupant) - src.temp_html = null - return null - if (prob(95)) - if(prob(75)) - randmutb(src.connected.occupant) + var/locked_state = connected.locked + connected.locked = 1 + + current_screen = "working" + ShowInterface(usr) + + sleep(radduration*10) + current_screen = "mainmenu" + + if(viable_occupant && connected && connected.occupant==viable_occupant) + viable_occupant.radiation += RADIATION_IRRADIATION_MULTIPLIER*radduration*radstrength + switch(href_list["task"]) + if("pulseui") + var/len = length(viable_occupant.dna.uni_identity) + num = Wrap(num, 1, len+1) + num = randomize_radiation_accuracy(num, radduration, len) + + var/hex = copytext(viable_occupant.dna.uni_identity, num, num+1) + hex = scramble(hex, radstrength, radduration) + + viable_occupant.dna.uni_identity = copytext(viable_occupant.dna.uni_identity, 1, num) + hex + copytext(viable_occupant.dna.uni_identity, num+1, 0) + updateappearance(viable_occupant) + if("pulsese") + var/len = length(viable_occupant.dna.struc_enzymes) + num = Wrap(num, 1, len+1) + num = randomize_radiation_accuracy(num, radduration, len) + + var/hex = copytext(viable_occupant.dna.struc_enzymes, num, num+1) + hex = scramble(hex, radstrength, radduration) + + viable_occupant.dna.struc_enzymes = copytext(viable_occupant.dna.struc_enzymes, 1, num) + hex + copytext(viable_occupant.dna.struc_enzymes, num+1, 0) + domutcheck(viable_occupant, connected) else - randmuti(src.connected.occupant) - else - if(prob(95)) - randmutg(src.connected.occupant) - else - randmuti(src.connected.occupant) - src.connected.occupant.radiation += ((src.radstrength*3)+src.radduration*3) - src.connected.locked = lock_state - src.temp_html = null - dopage(src,"screen=radsetmenu") - if (href_list["radleplus"]) - if(!viable_occupant) - src.temp_html = text("No viable occupant detected.") - popup.set_content(src.temp_html) - popup.open() - if (src.radduration < 20) - src.radduration++ - src.radduration++ - dopage(src,"screen=radsetmenu") - if (href_list["radleminus"]) - if(!viable_occupant) - src.temp_html = text("No viable occupant detected.") - popup.set_content(src.temp_html) - popup.open() - if (src.radduration > 2) - src.radduration-- - src.radduration-- - dopage(src,"screen=radsetmenu") - if (href_list["radinplus"]) - if (src.radstrength < 10) - src.radstrength++ - dopage(src,"screen=radsetmenu") - if (href_list["radinminus"]) - if (src.radstrength > 1) - src.radstrength-- - dopage(src,"screen=radsetmenu") - //////////////////////////////////////////////////////// - if (href_list["unimenuplus"]) - if (src.uniblock < 13) - src.uniblock++ - else - src.uniblock = 1 - dopage(src,"screen=unimenu") - if (href_list["unimenuminus"]) - if (src.uniblock > 1) - src.uniblock-- - else - src.uniblock = 13 - dopage(src,"screen=unimenu") - if (href_list["unimenusubplus"]) - if (src.subblock < 3) - src.subblock++ - else - src.subblock = 1 - dopage(src,"screen=unimenu") - if (href_list["unimenusubminus"]) - if (src.subblock > 1) - src.subblock-- - else - src.subblock = 3 - dopage(src,"screen=unimenu") - if (href_list["unimenutargetplus"]) - if (src.unitarget < 15) - src.unitarget++ - src.unitargethex = src.unitarget - switch(unitarget) - if(10) - src.unitargethex = "A" - if(11) - src.unitargethex = "B" - if(12) - src.unitargethex = "C" - if(13) - src.unitargethex = "D" - if(14) - src.unitargethex = "E" - if(15) - src.unitargethex = "F" - else - src.unitarget = 0 - src.unitargethex = 0 - dopage(src,"screen=unimenu") - if (href_list["unimenutargetminus"]) - if (src.unitarget > 0) - src.unitarget-- - src.unitargethex = src.unitarget - switch(unitarget) - if(10) - src.unitargethex = "A" - if(11) - src.unitargethex = "B" - if(12) - src.unitargethex = "C" - if(13) - src.unitargethex = "D" - if(14) - src.unitargethex = "E" - else - src.unitarget = 15 - src.unitargethex = "F" - dopage(src,"screen=unimenu") - if (href_list["uimenuset"] && href_list["uimenusubset"]) // This chunk of code updates selected block / sub-block based on click - var/menuset = text2num(href_list["uimenuset"]) - var/menusubset = text2num(href_list["uimenusubset"]) - if ((menuset <= 13) && (menuset >= 1)) - src.uniblock = menuset - if ((menusubset <= 3) && (menusubset >= 1)) - src.subblock = menusubset - dopage(src, "unimenu") - if (href_list["unipulse"]) - if(src.connected.occupant) - var/block - var/newblock - var/tstructure2 - block = getblock(getblock(src.connected.occupant.dna.uni_identity,src.uniblock,3),src.subblock,1) + current_screen = "mainmenu" + + if(connected) + connected.locked = locked_state - src.temp_html = text("Working ... Please wait ([] Seconds)", src.radduration) - popup.set_content(src.temp_html) - popup.open() - var/lock_state = src.connected.locked - src.connected.locked = 1//lock it - sleep(10*src.radduration) - if (!src.connected.occupant) - src.temp_html = null - return null - /// - if (prob((80 + (src.radduration / 2)))) - block = miniscrambletarget(num2text(unitarget), src.radstrength, src.radduration) - newblock = null - if (src.subblock == 1) newblock = block + getblock(getblock(src.connected.occupant.dna.uni_identity,src.uniblock,3),2,1) + getblock(getblock(src.connected.occupant.dna.uni_identity,src.uniblock,3),3,1) - if (src.subblock == 2) newblock = getblock(getblock(src.connected.occupant.dna.uni_identity,src.uniblock,3),1,1) + block + getblock(getblock(src.connected.occupant.dna.uni_identity,src.uniblock,3),3,1) - if (src.subblock == 3) newblock = getblock(getblock(src.connected.occupant.dna.uni_identity,src.uniblock,3),1,1) + getblock(getblock(src.connected.occupant.dna.uni_identity,src.uniblock,3),2,1) + block - tstructure2 = setblock(src.connected.occupant.dna.uni_identity, src.uniblock, newblock,3) - src.connected.occupant.dna.uni_identity = tstructure2 - updateappearance(src.connected.occupant,src.connected.occupant.dna.uni_identity) - src.connected.occupant.radiation += (src.radstrength+src.radduration) - else - if (prob(20+src.radstrength)) - randmutb(src.connected.occupant) - domutcheck(src.connected.occupant,src.connected) - else - randmuti(src.connected.occupant) - updateappearance(src.connected.occupant,src.connected.occupant.dna.uni_identity) - src.connected.occupant.radiation += ((src.radstrength*2)+src.radduration) - src.connected.locked = lock_state - dopage(src,"screen=unimenu") + ShowInterface(usr) + - //////////////////////////////////////////////////////// - if (href_list["rejuv"]) - if(!viable_occupant) - src.temp_html = text("No viable occupant detected.") - popup.set_content(src.temp_html) - popup.open() - else - if(human_occupant) - if (human_occupant.reagents.get_reagent_amount("inaprovaline") < REJUVENATORS_MAX) - if (human_occupant.reagents.get_reagent_amount("inaprovaline") < (REJUVENATORS_MAX - REJUVENATORS_INJECT)) - human_occupant.reagents.add_reagent("inaprovaline", REJUVENATORS_INJECT) - else - human_occupant.reagents.add_reagent("inaprovaline", round(REJUVENATORS_MAX - human_occupant.reagents.get_reagent_amount("inaprovaline"))) - //usr << text("Occupant now has [] units of rejuvenation in his/her bloodstream.", human_occupant.reagents.get_reagent_amount("inaprovaline")) - - //////////////////////////////////////////////////////// - if (href_list["strucmenuplus"]) - if (src.strucblock < 14) - src.strucblock++ - else - src.strucblock = 1 - dopage(src,"screen=strucmenu") - if (href_list["strucmenuminus"]) - if (src.strucblock > 1) - src.strucblock-- - else - src.strucblock = 14 - dopage(src,"screen=strucmenu") - if (href_list["strucmenusubplus"]) - if (src.subblock < 3) - src.subblock++ - else - src.subblock = 1 - dopage(src,"screen=strucmenu") - if (href_list["strucmenusubminus"]) - if (src.subblock > 1) - src.subblock-- - else - src.subblock = 3 - dopage(src,"screen=strucmenu") - if (href_list["semenuset"] && href_list["semenusubset"]) // This chunk of code updates selected block / sub-block based on click (se stands for strutural enzymes) - var/menuset = text2num(href_list["semenuset"]) - var/menusubset = text2num(href_list["semenusubset"]) - if ((menuset <= 14) && (menuset >= 1)) - src.strucblock = menuset - if ((menusubset <= 3) && (menusubset >= 1)) - src.subblock = menusubset - dopage(src, "strucmenu") - if (href_list["strucpulse"]) - var/block - var/newblock - var/tstructure2 - var/oldblock - var/lock_state = src.connected.locked - src.connected.locked = 1//lock it - if (viable_occupant) - block = getblock(getblock(src.connected.occupant.dna.struc_enzymes,src.strucblock,3),src.subblock,1) - - src.temp_html = text("Working ... Please wait ([] Seconds)", src.radduration) - popup.set_content(src.temp_html) - popup.open() - sleep(10*src.radduration) - else - src.temp_html = null - return null - /// - if(viable_occupant) - if (prob((80 + (src.radduration / 2)))) - if ((src.strucblock != 2 || src.strucblock != 12 || src.strucblock != 8 || src.strucblock || 10) && prob (20)) - oldblock = src.strucblock - block = miniscramble(block, src.radstrength, src.radduration) - newblock = null - if (src.strucblock > 1 && src.strucblock < 5) - src.strucblock++ - else if (src.strucblock > 5 && src.strucblock < 14) - src.strucblock-- - if (src.subblock == 1) newblock = block + getblock(getblock(src.connected.occupant.dna.struc_enzymes,src.strucblock,3),2,1) + getblock(getblock(src.connected.occupant.dna.struc_enzymes,src.strucblock,3),3,1) - if (src.subblock == 2) newblock = getblock(getblock(src.connected.occupant.dna.struc_enzymes,src.strucblock,3),1,1) + block + getblock(getblock(src.connected.occupant.dna.struc_enzymes,src.strucblock,3),3,1) - if (src.subblock == 3) newblock = getblock(getblock(src.connected.occupant.dna.struc_enzymes,src.strucblock,3),1,1) + getblock(getblock(src.connected.occupant.dna.struc_enzymes,src.strucblock,3),2,1) + block - tstructure2 = setblock(src.connected.occupant.dna.struc_enzymes, src.strucblock, newblock,3) - src.connected.occupant.dna.struc_enzymes = tstructure2 - domutcheck(src.connected.occupant,src.connected) - src.connected.occupant.radiation += (src.radstrength+src.radduration) - src.strucblock = oldblock - else - // - block = miniscramble(block, src.radstrength, src.radduration) - newblock = null - if (src.subblock == 1) newblock = block + getblock(getblock(src.connected.occupant.dna.struc_enzymes,src.strucblock,3),2,1) + getblock(getblock(src.connected.occupant.dna.struc_enzymes,src.strucblock,3),3,1) - if (src.subblock == 2) newblock = getblock(getblock(src.connected.occupant.dna.struc_enzymes,src.strucblock,3),1,1) + block + getblock(getblock(src.connected.occupant.dna.struc_enzymes,src.strucblock,3),3,1) - if (src.subblock == 3) newblock = getblock(getblock(src.connected.occupant.dna.struc_enzymes,src.strucblock,3),1,1) + getblock(getblock(src.connected.occupant.dna.struc_enzymes,src.strucblock,3),2,1) + block - tstructure2 = setblock(src.connected.occupant.dna.struc_enzymes, src.strucblock, newblock,3) - src.connected.occupant.dna.struc_enzymes = tstructure2 - domutcheck(src.connected.occupant,src.connected) - src.connected.occupant.radiation += (src.radstrength+src.radduration) - else - if (prob(80-src.radduration)) - randmutb(src.connected.occupant) - domutcheck(src.connected.occupant,src.connected) - else - randmuti(src.connected.occupant) - updateappearance(src.connected.occupant,src.connected.occupant.dna.uni_identity) - src.connected.occupant.radiation += ((src.radstrength*2)+src.radduration) - src.connected.locked = lock_state - /// - dopage(src,"screen=strucmenu") - - //////////////////////////////////////////////////////// - if (href_list["b1addui"]) - if(src.connected.occupant && src.connected.occupant.dna) - src.buffer1iue = 0 - src.buffer1 = src.connected.occupant.dna.uni_identity - if (!istype(src.connected.occupant,/mob/living/carbon/human)) - src.buffer1owner = src.connected.occupant.name - else - src.buffer1owner = src.connected.occupant.real_name - src.buffer1label = "Unique Identifier" - src.buffer1type = "ui" - dopage(src,"screen=buffermenu") - if (href_list["b1adduiue"]) - if(src.connected.occupant && src.connected.occupant.dna) - src.buffer1 = src.connected.occupant.dna.uni_identity - if (!istype(src.connected.occupant,/mob/living/carbon/human)) - src.buffer1owner = src.connected.occupant.name - else - src.buffer1owner = src.connected.occupant.real_name - src.buffer1label = "Unique Identifier & Unique Enzymes" - src.buffer1type = "ui" - src.buffer1iue = 1 - dopage(src,"screen=buffermenu") - if (href_list["b2adduiue"]) - if(src.connected.occupant && src.connected.occupant.dna) - src.buffer2 = src.connected.occupant.dna.uni_identity - if (!istype(src.connected.occupant,/mob/living/carbon/human)) - src.buffer2owner = src.connected.occupant.name - else - src.buffer2owner = src.connected.occupant.real_name - src.buffer2label = "Unique Identifier & Unique Enzymes" - src.buffer2type = "ui" - src.buffer2iue = 1 - dopage(src,"screen=buffermenu") - if (href_list["b3adduiue"]) - if(src.connected.occupant && src.connected.occupant.dna) - src.buffer3 = src.connected.occupant.dna.uni_identity - if (!istype(src.connected.occupant,/mob/living/carbon/human)) - src.buffer3owner = src.connected.occupant.name - else - src.buffer3owner = src.connected.occupant.real_name - src.buffer3label = "Unique Identifier & Unique Enzymes" - src.buffer3type = "ui" - src.buffer3iue = 1 - dopage(src,"screen=buffermenu") - if (href_list["b2addui"]) - if(src.connected.occupant && src.connected.occupant.dna) - src.buffer2iue = 0 - src.buffer2 = src.connected.occupant.dna.uni_identity - if (!istype(src.connected.occupant,/mob/living/carbon/human)) - src.buffer2owner = src.connected.occupant.name - else - src.buffer2owner = src.connected.occupant.real_name - src.buffer2label = "Unique Identifier" - src.buffer2type = "ui" - dopage(src,"screen=buffermenu") - if (href_list["b3addui"]) - if(src.connected.occupant && src.connected.occupant.dna) - src.buffer3iue = 0 - src.buffer3 = src.connected.occupant.dna.uni_identity - if (!istype(src.connected.occupant,/mob/living/carbon/human)) - src.buffer3owner = src.connected.occupant.name - else - src.buffer3owner = src.connected.occupant.real_name - src.buffer3label = "Unique Identifier" - src.buffer3type = "ui" - dopage(src,"screen=buffermenu") - if (href_list["b1addse"]) - if(src.connected.occupant && src.connected.occupant.dna) - src.buffer1iue = 0 - src.buffer1 = src.connected.occupant.dna.struc_enzymes - if (!istype(src.connected.occupant,/mob/living/carbon/human)) - src.buffer1owner = src.connected.occupant.name - else - src.buffer1owner = src.connected.occupant.real_name - src.buffer1label = "Structural Enzymes" - src.buffer1type = "se" - dopage(src,"screen=buffermenu") - if (href_list["b2addse"]) - if(src.connected.occupant && src.connected.occupant.dna) - src.buffer2iue = 0 - src.buffer2 = src.connected.occupant.dna.struc_enzymes - if (!istype(src.connected.occupant,/mob/living/carbon/human)) - src.buffer2owner = src.connected.occupant.name - else - src.buffer2owner = src.connected.occupant.real_name - src.buffer2label = "Structural Enzymes" - src.buffer2type = "se" - dopage(src,"screen=buffermenu") - if (href_list["b3addse"]) - if(src.connected.occupant && src.connected.occupant.dna) - src.buffer3iue = 0 - src.buffer3 = src.connected.occupant.dna.struc_enzymes - if (!istype(src.connected.occupant,/mob/living/carbon/human)) - src.buffer3owner = src.connected.occupant.name - else - src.buffer3owner = src.connected.occupant.real_name - src.buffer3label = "Structural Enzymes" - src.buffer3type = "se" - dopage(src,"screen=buffermenu") - if (href_list["b1clear"]) - src.buffer1 = null - src.buffer1owner = null - src.buffer1label = null - src.buffer1iue = null - dopage(src,"screen=buffermenu") - if (href_list["b2clear"]) - src.buffer2 = null - src.buffer2owner = null - src.buffer2label = null - src.buffer2iue = null - dopage(src,"screen=buffermenu") - if (href_list["b3clear"]) - src.buffer3 = null - src.buffer3owner = null - src.buffer3label = null - src.buffer3iue = null - dopage(src,"screen=buffermenu") - if (href_list["b1label"]) - src.buffer1label = sanitize(input("New Label:","Edit Label","Infos here")) - dopage(src,"screen=buffermenu") - if (href_list["b2label"]) - src.buffer2label = sanitize(input("New Label:","Edit Label","Infos here")) - dopage(src,"screen=buffermenu") - if (href_list["b3label"]) - src.buffer3label = sanitize(input("New Label:","Edit Label","Infos here")) - dopage(src,"screen=buffermenu") - if (href_list["b1transfer"]) - if (!src.connected.occupant || (NOCLONE in src.connected.occupant.mutations) || !src.connected.occupant.dna) - return - if (src.buffer1type == "ui") - if (src.buffer1iue) - src.connected.occupant.real_name = src.buffer1owner - src.connected.occupant.name = src.buffer1owner - src.connected.occupant.dna.uni_identity = src.buffer1 - updateappearance(src.connected.occupant,src.connected.occupant.dna.uni_identity) - else if (src.buffer1type == "se") - src.connected.occupant.dna.struc_enzymes = src.buffer1 - domutcheck(src.connected.occupant,src.connected) - src.temp_html = "Transfered." - src.connected.occupant.radiation += rand(20,50) - - if (href_list["b2transfer"]) - if (!src.connected.occupant || (NOCLONE in src.connected.occupant.mutations) || !src.connected.occupant.dna) - return - if (src.buffer2type == "ui") - if (src.buffer2iue) - src.connected.occupant.real_name = src.buffer2owner - src.connected.occupant.name = src.buffer2owner - src.connected.occupant.dna.uni_identity = src.buffer2 - updateappearance(src.connected.occupant,src.connected.occupant.dna.uni_identity) - else if (src.buffer2type == "se") - src.connected.occupant.dna.struc_enzymes = src.buffer2 - domutcheck(src.connected.occupant,src.connected) - src.temp_html = "Transfered." - src.connected.occupant.radiation += rand(20,50) - - if (href_list["b3transfer"]) - if (!src.connected.occupant || (NOCLONE in src.connected.occupant.mutations) || !src.connected.occupant.dna) - return - if (src.buffer3type == "ui") - if (src.buffer3iue) - src.connected.occupant.real_name = src.buffer3owner - src.connected.occupant.name = src.buffer3owner - src.connected.occupant.dna.uni_identity = src.buffer3 - updateappearance(src.connected.occupant,src.connected.occupant.dna.uni_identity) - else if (src.buffer3type == "se") - src.connected.occupant.dna.struc_enzymes = src.buffer3 - domutcheck(src.connected.occupant,src.connected) - src.temp_html = "Transfered." - src.connected.occupant.radiation += rand(20,50) - - if (href_list["b1injector"]) - if (src.injectorready) - var/obj/item/weapon/dnainjector/I = new /obj/item/weapon/dnainjector - I.dna = src.buffer1 - I.dnatype = src.buffer1type - I.loc = src.loc - I.name += " ([src.buffer1label])" - if (src.buffer1iue) I.ue = src.buffer1owner //lazy haw haw - src.temp_html = "Injector created." - - src.injectorready = 0 - spawn(300) - src.injectorready = 1 - else - src.temp_html = "Replicator not ready yet." - - if (href_list["b2injector"]) - if (src.injectorready) - var/obj/item/weapon/dnainjector/I = new /obj/item/weapon/dnainjector - I.dna = src.buffer2 - I.dnatype = src.buffer2type - I.loc = src.loc - I.name += " ([src.buffer2label])" - if (src.buffer2iue) I.ue = src.buffer2owner //lazy haw haw - src.temp_html = "Injector created." - - src.injectorready = 0 - spawn(300) - src.injectorready = 1 - else - src.temp_html = "Replicator not ready yet." - - if (href_list["b3injector"]) - if (src.injectorready) - var/obj/item/weapon/dnainjector/I = new /obj/item/weapon/dnainjector - I.dna = src.buffer3 - I.dnatype = src.buffer3type - I.loc = src.loc - I.name += " ([src.buffer3label])" - if (src.buffer3iue) I.ue = src.buffer3owner //lazy haw haw - src.temp_html = "Injector created." - - src.injectorready = 0 - spawn(300) - src.injectorready = 1 - else - src.temp_html = "Replicator not ready yet." - - //////////////////////////////////////////////////////// - if (href_list["load_disk"]) - var/buffernum = text2num(href_list["load_disk"]) - if ((buffernum > 3) || (buffernum < 1)) - return - if ((isnull(src.diskette)) || (!src.diskette.data) || (src.diskette.data == "")) - return - switch(buffernum) - if(1) - src.buffer1 = src.diskette.data - src.buffer1type = src.diskette.data_type - src.buffer1iue = src.diskette.ue - src.buffer1owner = src.diskette.owner - if(2) - src.buffer2 = src.diskette.data - src.buffer2type = src.diskette.data_type - src.buffer2iue = src.diskette.ue - src.buffer2owner = src.diskette.owner - if(3) - src.buffer3 = src.diskette.data - src.buffer3type = src.diskette.data_type - src.buffer3iue = src.diskette.ue - src.buffer3owner = src.diskette.owner - src.temp_html = "Data loaded." - - if (href_list["save_disk"]) - var/buffernum = text2num(href_list["save_disk"]) - if ((buffernum > 3) || (buffernum < 1)) - return - if ((isnull(src.diskette)) || (src.diskette.read_only)) - return - switch(buffernum) - if(1) - src.diskette.data = buffer1 - src.diskette.data_type = src.buffer1type - src.diskette.ue = src.buffer1iue - src.diskette.owner = src.buffer1owner - src.diskette.name = "data disk - '[src.buffer1owner]'" - if(2) - src.diskette.data = buffer2 - src.diskette.data_type = src.buffer2type - src.diskette.ue = src.buffer2iue - src.diskette.owner = src.buffer2owner - src.diskette.name = "data disk - '[src.buffer2owner]'" - if(3) - src.diskette.data = buffer3 - src.diskette.data_type = src.buffer3type - src.diskette.ue = src.buffer3iue - src.diskette.owner = src.buffer3owner - src.diskette.name = "data disk - '[src.buffer3owner]'" - src.temp_html = "Data saved." - if (href_list["eject_disk"]) - if (!src.diskette) - return - src.diskette.loc = get_turf(src) - src.diskette = null - //////////////////////////////////////////////////////// - - src.temp_html = temp_header_html - switch(src.current_screen) - if ("mainmenu") - src.temp_html += "

Main Menu

" - if (viable_occupant) //is there REALLY someone in there who can be modified? - src.temp_html += text("Modify Unique Identifier
", src) - src.temp_html += text("Modify Structural Enzymes

", src) - else - src.temp_html += "Modify Unique Identifier
" - src.temp_html += "Modify Structural Enzymes

" - src.temp_html += text("Radiation Emitter Settings

", src) - src.temp_html += text("Transfer Buffer

", src) - - if ("unimenu") - if(!viable_occupant) - src.temp_html = text("No viable occupant detected.") - popup.set_content(src.temp_html) - popup.open() - else - src.temp_html = "<< Main Menu
" - src.temp_html += "

Modify Unique Identifier

" - src.temp_html += "
Unique Identifier:
[getblockstring(src.connected.occupant.dna.uni_identity,uniblock,subblock,3, src,1)]

" - src.temp_html += "Selected Block: <- [src.uniblock] ->

" - src.temp_html += "Selected Sub-Block: <- [src.subblock] ->

" - src.temp_html += "Selected Target: <- [src.unitargethex] ->

" - src.temp_html += "Modify Block
" - src.temp_html += "Irradiate
" - - if ("strucmenu") - if(!viable_occupant) - src.temp_html = text("No viable occupant detected.") - popup.set_content(src.temp_html) - popup.open() - else - src.temp_html = "<< Main Menu
" - src.temp_html += "

Modify Structural Enzymes

" - src.temp_html += "
Structural Enzymes: [getblockstring(src.connected.occupant.dna.struc_enzymes,strucblock,subblock,3,src,0)]

" - src.temp_html += "Selected Block: <- [src.strucblock] ->

" - src.temp_html += "Selected Sub-Block: <- [src.subblock] ->

" - src.temp_html += "Modify Block
" - src.temp_html += "Irradiate
" - - if ("radsetmenu") - src.temp_html = "<< Main Menu
" - src.temp_html += "

Radiation Emitter Settings

" - if (viable_occupant) - src.temp_html += text("Pulse Radiation", src) - else - src.temp_html += "Pulse Radiation" - src.temp_html += "

Radiation Duration: - [src.radduration] +
" - src.temp_html += "Radiation Intensity: - [src.radstrength] +

" - - if ("buffermenu") - src.temp_html = "<< Main Menu
" - src.temp_html += "

Transfer Buffer

" - src.temp_html += "

Buffer 1:

" - if (!(src.buffer1)) - src.temp_html += "Buffer Empty
" - else - src.temp_html += text("Data: []
", src.buffer1) - src.temp_html += text("By: []
", src.buffer1owner) - src.temp_html += text("Label: []
", src.buffer1label) - if (viable_occupant) src.temp_html += text("Save : UI - UI+UE - SE
", src, src, src) - if (src.buffer1) src.temp_html += text("Transfer to: Occupant - Injector
", src, src) - //if (src.buffer1) src.temp_html += text("Isolate Block
", src) - if (src.buffer1) src.temp_html += "Disk: Save To | Load From
" - if (src.buffer1) src.temp_html += text("Edit Label
", src) - if (src.buffer1) src.temp_html += text("Clear Buffer

", src) - if (!src.buffer1) src.temp_html += "
" - src.temp_html += "

Buffer 2:

" - if (!(src.buffer2)) - src.temp_html += "Buffer Empty
" - else - src.temp_html += text("Data: []
", src.buffer2) - src.temp_html += text("By: []
", src.buffer2owner) - src.temp_html += text("Label: []
", src.buffer2label) - if (viable_occupant) src.temp_html += text("Save : UI - UI+UE - SE
", src, src, src) - if (src.buffer2) src.temp_html += text("Transfer to: Occupant - Injector
", src, src) - //if (src.buffer2) src.temp_html += text("Isolate Block
", src) - if (src.buffer2) src.temp_html += "Disk: Save To | Load From
" - if (src.buffer2) src.temp_html += text("Edit Label
", src) - if (src.buffer2) src.temp_html += text("Clear Buffer

", src) - if (!src.buffer2) src.temp_html += "
" - src.temp_html += "

Buffer 3:

" - if (!(src.buffer3)) - src.temp_html += "Buffer Empty
" - else - src.temp_html += text("Data: []
", src.buffer3) - src.temp_html += text("By: []
", src.buffer3owner) - src.temp_html += text("Label: []
", src.buffer3label) - if (viable_occupant) src.temp_html += text("Save : UI - UI+UE - SE
", src, src, src) - if (src.buffer3) src.temp_html += text("Transfer to: Occupant - Injector
", src, src) - //if (src.buffer3) src.temp_html += text("Isolate Block
", src) - if (src.buffer3) src.temp_html += "Disk: Save To | Load From
" - if (src.buffer3) src.temp_html += text("Edit Label
", src) - if (src.buffer3) src.temp_html += text("Clear Buffer

", src) - if (!src.buffer3) src.temp_html += "
" - src.temp_html += temp_footer_html - - if(viable_occupant && !src.scanner_status_html && occupant) //is there REALLY someone in there? - src.scanner_status_html = "
Health:
[occupant.health]%
" - src.scanner_status_html += "
Radiation Level:
[occupant.radiation]%
" - if(human_occupant) - var/rejuvenators = round(human_occupant.reagents.get_reagent_amount("inaprovaline") / REJUVENATORS_MAX * 100) - src.scanner_status_html += "
Rejuvenators:
[human_occupant.reagents.get_reagent_amount("inaprovaline")] units
" - - if (src.current_screen == "mainmenu") - src.scanner_status_html += "
Unique Enzymes :
[uppertext(occupant.dna.unique_enzymes)]
" - src.scanner_status_html += "
Unique Identifier:
[occupant.dna.uni_identity]
" - src.scanner_status_html += "
Structural Enzymes:
[occupant.dna.struc_enzymes]
" - - var/dat = "

Scanner Status

" - - dat += "Scan " - - var/occupant_status = "Scanner Unoccupied" - if(!src.connected) - occupant_status = "No Scanner Detected!" - if(occupant && occupant.dna) //is there REALLY someone in there? - if (!istype(occupant,/mob/living/carbon/human)) //Why is this here? - sleep(1) - if(NOCLONE in occupant.mutations) - occupant_status = "Invalid DNA structure" - else - switch(occupant.stat) // obvious, see what their status is - if(0) - occupant_status = "Conscious" - if(1) - occupant_status = "Unconscious" - else - occupant_status = "DEAD" - - occupant_status = "[occupant.name] => [occupant_status]
" - - dat += "
[occupant_status][src.scanner_status_html]
" - - var/scanner_access_text = "Lock Scanner" - if (src.connected && src.connected.locked) - scanner_access_text = "Unlock Scanner" - if (occupant && occupant.dna) - dat += "[scanner_access_text] " - if (human_occupant) - dat += "Inject Rejuvenators
" - else - dat += "Inject Rejuvenators
" - else - dat += "[scanner_access_text] " - dat += "Inject Rejuvenators
" - - if (!isnull(src.diskette)) - dat += text("Eject Disk
", src) - - dat += "
" - - if (src.temp_html) - dat += src.temp_html - - popup.set_content(dat) - popup.open() /////////////////////////// DNA MACHINES - +#undef INJECTOR_TIMEOUT #undef REJUVENATORS_INJECT -#undef REJUVENATORS_MAX \ No newline at end of file +#undef REJUVENATORS_MAX +#undef NUMBER_OF_BUFFERS + +#undef RADIATION_STRENGTH_MAX +#undef RADIATION_STRENGTH_MULTIPLIER +#undef RADIATION_STRENGTH_BIAS + +#undef RADIATION_DURATION_MAX +#undef RADIATION_ACCURACY_MULTIPLIER +#undef RADIATION_ACCURACY_BIAS + +#undef RADIATION_IRRADIATION_MULTIPLIER + +//#undef BAD_MUTATION_DIFFICULTY +//#undef GOOD_MUTATION_DIFFICULTY +//#undef OP_MUTATION_DIFFICULTY + +//value in range 1 to values. values must be greater than 0 +//all arguments assumed to be positive integers +proc/construct_block(value, values, blocksize=DNA_BLOCK_SIZE) + var/width = round((16**blocksize)/values) + if(value < 1) + value = 1 + value = (value * width) - rand(1,width) + return num2hex(value, blocksize) + +//value is hex +proc/deconstruct_block(value, values, blocksize=DNA_BLOCK_SIZE) + var/width = round((16**blocksize)/values) + value = round(hex2num(value) / width) + 1 + if(value > values) + value = values + return value \ No newline at end of file diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index b988cf24470..30cc32c2d86 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -67,7 +67,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" /datum/game_mode/changeling/post_setup() for(var/datum/mind/changeling in changelings) - grant_changeling_powers(changeling.current) + changeling.current.make_changeling() changeling.special_role = "Changeling" forge_changeling_objectives(changeling) greet_changeling(changeling) @@ -152,10 +152,6 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" return ..() return 0*/ -/datum/game_mode/proc/grant_changeling_powers(mob/living/carbon/changeling_mob) - if(!istype(changeling_mob)) return - changeling_mob.make_changeling() - /datum/game_mode/proc/auto_declare_completion_changeling() if(changelings.len) var/text = "The changelings were:" diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index 3e05162af07..b4901597126 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -2,13 +2,14 @@ /mob/proc/make_changeling() if(!mind) return if(!mind.changeling) mind.changeling = new /datum/changeling(gender) + if(!iscarbon(src)) return + verbs += /datum/changeling/proc/EvolutionMenu var/lesser_form = !ishuman(src) - if(!powerinstances.len) - for(var/P in powers) - powerinstances += new P() + if(!powerinstances) + powerinstances = init_subtypes(/datum/power/changeling) // Code to auto-purchase free powers. for(var/datum/power/changeling/P in powerinstances) @@ -19,30 +20,27 @@ for(var/datum/power/changeling/P in mind.changeling.purchasedpowers) if(P.isVerb) if(lesser_form && !P.allowduringlesserform) continue - if(!(P in src.verbs)) - src.verbs += P.verbpath + verbs += P.verbpath //byond won't allow two of the same verb to be added to the verbs list. No additional checks necessary - mind.changeling.absorbed_dna |= dna + var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste + mind.changeling.absorbed_dna |= C.dna return 1 //removes our changeling verbs /mob/proc/remove_changeling_powers() - if(!mind || !mind.changeling) return - for(var/datum/power/changeling/P in mind.changeling.purchasedpowers) + for(var/datum/power/changeling/P in powerinstances) if(P.isVerb) verbs -= P.verbpath //Helper proc. Does all the checks and stuff for us to avoid copypasta +//includes a check to see if we're a carbon mob. This means that you can't use powers (even with the verbs) unless you're a carbon-based mob. /mob/proc/changeling_power(var/required_chems=0, var/required_dna=0, var/max_genetic_damage=100, var/max_stat=0) - if(!src.mind) return if(!iscarbon(src)) return var/datum/changeling/changeling = src.mind.changeling - if(!changeling) - world.log << "[src] has the changeling_transform() verb but is not a changeling." - return + if(!changeling) return if(src.stat > max_stat) src << "We are incapacitated." @@ -65,10 +63,10 @@ //Absorbs the victim's DNA making them uncloneable. Requires a strong grip on the victim. //Doesn't cost anything as it's the most basic ability. -/mob/proc/changeling_absorb_dna() +/mob/living/carbon/proc/changeling_absorb_dna() set category = "Changeling" set name = "Absorb DNA" - + var/datum/changeling/changeling = changeling_power(0,0,100) if(!changeling) return @@ -143,7 +141,7 @@ if(!Tp.isVerb) call(Tp.verbpath)() else - src.make_changeling() + make_changeling() changeling.chem_charges += T.mind.changeling.chem_charges changeling.geneticpoints += T.mind.changeling.geneticpoints @@ -160,7 +158,7 @@ //Change our DNA to that of somebody we've absorbed. -/mob/proc/changeling_transform() +/mob/living/carbon/proc/changeling_transform() set category = "Changeling" set name = "Transform (5)" @@ -183,43 +181,42 @@ changeling.geneticdamage = 30 src.dna = chosen_dna src.real_name = chosen_dna.real_name - updateappearance(src, src.dna.uni_identity) + updateappearance(src) domutcheck(src, null) - src.verbs -= /mob/proc/changeling_transform - spawn(10) src.verbs += /mob/proc/changeling_transform + src.verbs -= /mob/living/carbon/proc/changeling_transform + spawn(10) src.verbs += /mob/living/carbon/proc/changeling_transform feedback_add_details("changeling_powers","TR") return 1 //Transform into a monkey. -/mob/proc/changeling_lesser_form() +/mob/living/carbon/proc/changeling_lesser_form() set category = "Changeling" set name = "Lesser Form (1)" var/datum/changeling/changeling = changeling_power(1,0,0) if(!changeling) return - var/mob/living/carbon/C = src changeling.chem_charges-- - C.remove_changeling_powers() - C.visible_message("[C] transforms!") + remove_changeling_powers() + visible_message("[src] transforms!") changeling.geneticdamage = 30 - C << "Our genes cry out!" + src << "Our genes cry out!" //TODO replace with monkeyize proc var/list/implants = list() //Try to preserve implants. - for(var/obj/item/weapon/implant/W in C) + for(var/obj/item/weapon/implant/W in src) implants += W - C.monkeyizing = 1 - C.canmove = 0 - C.icon = null - C.overlays.Cut() - C.invisibility = 101 + monkeyizing = 1 + canmove = 0 + icon = null + overlays.Cut() + invisibility = 101 - var/atom/movable/overlay/animation = new /atom/movable/overlay( C.loc ) + var/atom/movable/overlay/animation = new /atom/movable/overlay( loc ) animation.icon_state = "blank" animation.icon = 'icons/mob/mob.dmi' animation.master = src @@ -228,37 +225,37 @@ del(animation) var/mob/living/carbon/monkey/O = new /mob/living/carbon/monkey(src) - O.dna = C.dna - C.dna = null + O.dna = dna + dna = null - for(var/obj/item/W in C) - C.drop_from_inventory(W) - for(var/obj/T in C) + for(var/obj/item/W in src) + drop_from_inventory(W) + for(var/obj/T in src) del(T) - O.loc = C.loc - O.name = "monkey ([copytext(md5(C.real_name), 2, 6)])" - O.setToxLoss(C.getToxLoss()) - O.adjustBruteLoss(C.getBruteLoss()) - O.setOxyLoss(C.getOxyLoss()) - O.adjustFireLoss(C.getFireLoss()) - O.stat = C.stat + O.loc = loc + O.name = "monkey ([copytext(md5(real_name), 2, 6)])" + O.setToxLoss(getToxLoss()) + O.adjustBruteLoss(getBruteLoss()) + O.setOxyLoss(getOxyLoss()) + O.adjustFireLoss(getFireLoss()) + O.stat = stat O.a_intent = "harm" for(var/obj/item/weapon/implant/I in implants) I.loc = O I.implanted = O - C.mind.transfer_to(O) + mind.transfer_to(O) O.make_changeling(1) - O.verbs += /mob/proc/changeling_lesser_transform + O.verbs += /mob/living/carbon/proc/changeling_lesser_transform feedback_add_details("changeling_powers","LF") - del(C) + del(src) return 1 //Transform into a human -/mob/proc/changeling_lesser_transform() +/mob/living/carbon/proc/changeling_lesser_transform() set category = "Changeling" set name = "Transform (1)" @@ -276,23 +273,21 @@ if(!chosen_dna) return - var/mob/living/carbon/C = src - changeling.chem_charges-- - C.remove_changeling_powers() - C.visible_message("[C] transforms!") - C.dna = chosen_dna + remove_changeling_powers() + visible_message("[src] transforms!") + dna = chosen_dna var/list/implants = list() - for (var/obj/item/weapon/implant/I in C) //Still preserving implants + for (var/obj/item/weapon/implant/I in src) //Still preserving implants implants += I - C.monkeyizing = 1 - C.canmove = 0 - C.icon = null - C.overlays.Cut() - C.invisibility = 101 - var/atom/movable/overlay/animation = new /atom/movable/overlay( C.loc ) + monkeyizing = 1 + canmove = 0 + icon = null + overlays.Cut() + invisibility = 101 + var/atom/movable/overlay/animation = new /atom/movable/overlay( loc ) animation.icon_state = "blank" animation.icon = 'icons/mob/mob.dmi' animation.master = src @@ -301,96 +296,92 @@ del(animation) for(var/obj/item/W in src) - C.u_equip(W) - if (C.client) - C.client.screen -= W + u_equip(W) + if (client) + client.screen -= W if (W) - W.loc = C.loc - W.dropped(C) + W.loc = loc + W.dropped(src) W.layer = initial(W.layer) var/mob/living/carbon/human/O = new /mob/living/carbon/human( src ) - if (isblockon(getblock(C.dna.uni_identity, 11,3),11)) - O.gender = FEMALE - else - O.gender = MALE - O.dna = C.dna - C.dna = null + O.gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? MALE : FEMALE + O.dna = dna + dna = null O.real_name = chosen_dna.real_name - for(var/obj/T in C) + for(var/obj/T in src) del(T) - O.loc = C.loc + O.loc = loc - updateappearance(O,O.dna.uni_identity) + updateappearance(O) domutcheck(O, null) - O.setToxLoss(C.getToxLoss()) - O.adjustBruteLoss(C.getBruteLoss()) - O.setOxyLoss(C.getOxyLoss()) - O.adjustFireLoss(C.getFireLoss()) - O.stat = C.stat + O.setToxLoss(getToxLoss()) + O.adjustBruteLoss(getBruteLoss()) + O.setOxyLoss(getOxyLoss()) + O.adjustFireLoss(getFireLoss()) + O.stat = stat for (var/obj/item/weapon/implant/I in implants) I.loc = O I.implanted = O - C.mind.transfer_to(O) + mind.transfer_to(O) O.make_changeling() feedback_add_details("changeling_powers","LFT") - del(C) + del(src) return 1 //Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay. -/mob/proc/changeling_fakedeath() +/mob/living/carbon/proc/changeling_fakedeath() set category = "Changeling" set name = "Regenerative Stasis (20)" - + var/datum/changeling/changeling = changeling_power(20,1,100,DEAD) if(!changeling) return - var/mob/living/carbon/C = src - if(!C.stat && alert("Are we sure we wish to fake our death?",,"Yes","No") == "No")//Confirmation for living changelings if they want to fake their death + if(!stat && alert("Are we sure we wish to fake our death?",,"Yes","No") == "No")//Confirmation for living changelings if they want to fake their death return - C << "We will attempt to regenerate our form." + src << "We will attempt to regenerate our form." - C.status_flags |= FAKEDEATH //play dead - C.update_canmove() - C.remove_changeling_powers() + status_flags |= FAKEDEATH //play dead + update_canmove() + remove_changeling_powers() - C.emote("gasp") - C.tod = worldtime2text() + emote("gasp") + tod = worldtime2text() spawn(rand(800,2000)) if(changeling_power(20,1,100,DEAD)) changeling.chem_charges -= 20 - if(C.stat == DEAD) - dead_mob_list -= C - living_mob_list += C - C.stat = CONSCIOUS - C.tod = null - C.setToxLoss(0) - C.setOxyLoss(0) - C.setCloneLoss(0) - C.SetParalysis(0) - C.SetStunned(0) - C.SetWeakened(0) - C.radiation = 0 - C.heal_overall_damage(C.getBruteLoss(), C.getFireLoss()) - C.reagents.clear_reagents() - C << "We have regenerated." - C.visible_message("[src] appears to wake from the dead, having healed all wounds.") + if(stat == DEAD) + dead_mob_list -= src + living_mob_list += src + stat = CONSCIOUS + tod = null + setToxLoss(0) + setOxyLoss(0) + setCloneLoss(0) + SetParalysis(0) + SetStunned(0) + SetWeakened(0) + radiation = 0 + heal_overall_damage(getBruteLoss(), getFireLoss()) + reagents.clear_reagents() + src << "We have regenerated." + visible_message("[src] appears to wake from the dead, having healed all wounds.") - C.status_flags &= ~(FAKEDEATH) - C.update_canmove() - C.make_changeling() + status_flags &= ~(FAKEDEATH) + update_canmove() + make_changeling() feedback_add_details("changeling_powers","FD") return 1 //Boosts the range of your next sting attack by 1 -/mob/proc/changeling_boost_range() +/mob/living/carbon/proc/changeling_boost_range() set category = "Changeling" set name = "Ranged Sting (10)" set desc="Your next sting ability can be used against targets 2 squares away." @@ -400,14 +391,14 @@ changeling.chem_charges -= 10 src << "Your throat adjusts to launch the sting." changeling.sting_range = 2 - src.verbs -= /mob/proc/changeling_boost_range - spawn(5) src.verbs += /mob/proc/changeling_boost_range + src.verbs -= /mob/living/carbon/proc/changeling_boost_range + spawn(5) src.verbs += /mob/living/carbon/proc/changeling_boost_range feedback_add_details("changeling_powers","RS") return 1 //Recover from stuns. -/mob/proc/changeling_unstun() +/mob/living/carbon/proc/changeling_unstun() set category = "Changeling" set name = "Epinephrine Sacs (45)" set desc = "Removes all stuns" @@ -416,16 +407,15 @@ if(!changeling) return 0 changeling.chem_charges -= 45 - var/mob/living/carbon/human/C = src - C.stat = 0 - C.SetParalysis(0) - C.SetStunned(0) - C.SetWeakened(0) - C.lying = 0 - C.update_canmove() + stat = 0 + SetParalysis(0) + SetStunned(0) + SetWeakened(0) + lying = 0 + update_canmove() - src.verbs -= /mob/proc/changeling_unstun - spawn(5) src.verbs += /mob/proc/changeling_unstun + src.verbs -= /mob/living/carbon/proc/changeling_unstun + spawn(5) src.verbs += /mob/living/carbon/proc/changeling_unstun feedback_add_details("changeling_powers","UNS") return 1 @@ -442,7 +432,7 @@ //Prevents AIs tracking you but makes you easily detectable to the human-eye. -/mob/proc/changeling_digitalcamo() +/mob/living/carbon/proc/changeling_digitalcamo() set category = "Changeling" set name = "Toggle Digital Camoflague" set desc = "The AI can no longer track us, but we will look different if examined. Has a constant cost while active." @@ -450,24 +440,23 @@ var/datum/changeling/changeling = changeling_power() if(!changeling) return 0 - var/mob/living/carbon/human/C = src - if(C.digitalcamo) C << "We return to normal." - else C << "We distort our form to prevent AI-tracking." - C.digitalcamo = !C.digitalcamo + if(digitalcamo) src << "We return to normal." + else src << "We distort our form to prevent AI-tracking." + digitalcamo = !digitalcamo spawn(0) - while(C && C.digitalcamo && C.mind && C.mind.changeling) - C.mind.changeling.chem_charges = max(C.mind.changeling.chem_charges - 1, 0) + while(src && digitalcamo && mind && mind.changeling) + mind.changeling.chem_charges = max(mind.changeling.chem_charges - 1, 0) sleep(40) - src.verbs -= /mob/proc/changeling_digitalcamo - spawn(5) src.verbs += /mob/proc/changeling_digitalcamo + src.verbs -= /mob/living/carbon/proc/changeling_digitalcamo + spawn(5) src.verbs += /mob/living/carbon/proc/changeling_digitalcamo feedback_add_details("changeling_powers","CAM") return 1 //Starts healing you every second for 10 seconds. Can be used whilst unconscious. -/mob/proc/changeling_rapidregen() +/mob/living/carbon/proc/changeling_rapidregen() set category = "Changeling" set name = "Rapid Regeneration (30)" set desc = "Begins rapidly regenerating. Does not effect stuns or chemicals." @@ -476,18 +465,16 @@ if(!changeling) return 0 src.mind.changeling.chem_charges -= 30 - var/mob/living/carbon/human/C = src spawn(0) for(var/i = 0, i<10,i++) - if(C) - C.adjustBruteLoss(-10) - C.adjustToxLoss(-10) - C.adjustOxyLoss(-10) - C.adjustFireLoss(-10) - sleep(10) + adjustBruteLoss(-10) + adjustToxLoss(-10) + adjustOxyLoss(-10) + adjustFireLoss(-10) + sleep(10) - src.verbs -= /mob/proc/changeling_rapidregen - spawn(5) src.verbs += /mob/proc/changeling_rapidregen + src.verbs -= /mob/living/carbon/proc/changeling_rapidregen + spawn(5) src.verbs += /mob/living/carbon/proc/changeling_rapidregen feedback_add_details("changeling_powers","RR") return 1 @@ -495,7 +482,7 @@ var/list/datum/dna/hivemind_bank = list() -/mob/proc/changeling_hiveupload() +/mob/living/carbon/proc/changeling_hiveupload() set category = "Changeling" set name = "Hive Channel (10)" set desc = "Allows you to channel DNA in the airwaves to allow other changelings to absorb it." @@ -525,7 +512,7 @@ var/list/datum/dna/hivemind_bank = list() feedback_add_details("changeling_powers","HU") return 1 -/mob/proc/changeling_hivedownload() +/mob/living/carbon/proc/changeling_hivedownload() set category = "Changeling" set name = "Hive Absorb (20)" set desc = "Allows you to absorb DNA that is being channeled in the airwaves." @@ -556,7 +543,7 @@ var/list/datum/dna/hivemind_bank = list() // Fake Voice -/mob/proc/changeling_mimicvoice() +/mob/living/carbon/proc/changeling_mimicvoice() set category = "Changeling" set name = "Mimic Voice" set desc = "Shape our vocal glands to form a voice of someone we choose. We cannot regenerate chemicals when mimicing." @@ -615,8 +602,8 @@ var/list/datum/dna/hivemind_bank = list() changeling.chem_charges -= required_chems changeling.sting_range = 1 - src.verbs -= verb_path - spawn(10) src.verbs += verb_path + verbs -= verb_path + spawn(10) verbs += verb_path src << "We stealthily sting [T]." if(!T.mind || !T.mind.changeling) return T //T will be affected by the sting @@ -624,35 +611,35 @@ var/list/datum/dna/hivemind_bank = list() return -/mob/proc/changeling_lsdsting() +/mob/living/carbon/proc/changeling_lsdsting() set category = "Changeling" set name = "Hallucination Sting (15)" set desc = "Causes terror in the target." - var/mob/living/carbon/T = changeling_sting(15,/mob/proc/changeling_lsdsting) + var/mob/living/carbon/T = changeling_sting(15,/mob/living/carbon/proc/changeling_lsdsting) if(!T) return 0 spawn(rand(300,600)) if(T) T.hallucination += 400 feedback_add_details("changeling_powers","HS") return 1 -/mob/proc/changeling_silence_sting() +/mob/living/carbon/proc/changeling_silence_sting() set category = "Changeling" set name = "Silence sting (10)" set desc="Sting target" - var/mob/living/carbon/T = changeling_sting(10,/mob/proc/changeling_silence_sting) + var/mob/living/carbon/T = changeling_sting(10,/mob/living/carbon/proc/changeling_silence_sting) if(!T) return 0 T.silent += 30 feedback_add_details("changeling_powers","SS") return 1 -/mob/proc/changeling_blind_sting() +/mob/living/carbon/proc/changeling_blind_sting() set category = "Changeling" set name = "Blind sting (20)" set desc="Sting target" - var/mob/living/carbon/T = changeling_sting(20,/mob/proc/changeling_blind_sting) + var/mob/living/carbon/T = changeling_sting(20,/mob/living/carbon/proc/changeling_blind_sting) if(!T) return 0 T << "Your eyes burn horrificly!" T.disabilities |= NEARSIGHTED @@ -662,12 +649,12 @@ var/list/datum/dna/hivemind_bank = list() feedback_add_details("changeling_powers","BS") return 1 -/mob/proc/changeling_deaf_sting() +/mob/living/carbon/proc/changeling_deaf_sting() set category = "Changeling" set name = "Deaf sting (5)" set desc="Sting target:" - var/mob/living/carbon/T = changeling_sting(5,/mob/proc/changeling_deaf_sting) + var/mob/living/carbon/T = changeling_sting(5,/mob/living/carbon/proc/changeling_deaf_sting) if(!T) return 0 T << "Your ears pop and begin ringing loudly!" T.sdisabilities |= DEAF @@ -675,19 +662,19 @@ var/list/datum/dna/hivemind_bank = list() feedback_add_details("changeling_powers","DS") return 1 -/mob/proc/changeling_paralysis_sting() +/mob/living/carbon/proc/changeling_paralysis_sting() set category = "Changeling" set name = "Paralysis sting (30)" set desc="Sting target" - var/mob/living/carbon/T = changeling_sting(30,/mob/proc/changeling_paralysis_sting) + var/mob/living/carbon/T = changeling_sting(30,/mob/living/carbon/proc/changeling_paralysis_sting) if(!T) return 0 T << "Your muscles begin to painfully tighten." T.Weaken(20) feedback_add_details("changeling_powers","PS") return 1 -/mob/proc/changeling_transformation_sting() +/mob/living/carbon/proc/changeling_transformation_sting() set category = "Changeling" set name = "Transformation sting (40)" set desc="Sting target" @@ -695,11 +682,9 @@ var/list/datum/dna/hivemind_bank = list() var/datum/changeling/changeling = changeling_power(40) if(!changeling) return 0 - - var/list/names = list() for(var/datum/dna/DNA in changeling.absorbed_dna) - names += "[DNA.real_name]" + names += DNA.real_name var/S = input("Select the target DNA: ", "Target DNA", null) as null|anything in names if(!S) return @@ -708,7 +693,7 @@ var/list/datum/dna/hivemind_bank = list() if(!chosen_dna) return - var/mob/living/carbon/T = changeling_sting(40,/mob/proc/changeling_transformation_sting) + var/mob/living/carbon/T = changeling_sting(40,/mob/living/carbon/proc/changeling_transformation_sting) if(!T) return 0 if((HUSK in T.mutations) || (!ishuman(T) && !ismonkey(T))) src << "Our sting appears ineffective against its DNA." @@ -716,17 +701,17 @@ var/list/datum/dna/hivemind_bank = list() T.visible_message("[T] transforms!") T.dna = chosen_dna T.real_name = chosen_dna.real_name - updateappearance(T, T.dna.uni_identity) + updateappearance(T) domutcheck(T, null) feedback_add_details("changeling_powers","TS") return 1 -/mob/proc/changeling_unfat_sting() +/mob/living/carbon/proc/changeling_unfat_sting() set category = "Changeling" set name = "Unfat sting (5)" set desc = "Sting target" - var/mob/living/carbon/T = changeling_sting(5,/mob/proc/changeling_unfat_sting) + var/mob/living/carbon/T = changeling_sting(5,/mob/living/carbon/proc/changeling_unfat_sting) if(!T) return 0 T << "you feel a small prick as stomach churns violently and you become to feel skinnier." T.overeatduration = 0 @@ -734,12 +719,12 @@ var/list/datum/dna/hivemind_bank = list() feedback_add_details("changeling_powers","US") return 1 -/mob/proc/changeling_DEATHsting() +/mob/living/carbon/proc/changeling_DEATHsting() set category = "Changeling" set name = "Death Sting (40)" set desc = "Causes spasms onto death." - var/mob/living/carbon/T = changeling_sting(40,/mob/proc/changeling_DEATHsting) + var/mob/living/carbon/T = changeling_sting(40,/mob/living/carbon/proc/changeling_DEATHsting) if(!T) return 0 T << "You feel a small prick and your chest becomes tight." T.silent = 10 @@ -749,7 +734,7 @@ var/list/datum/dna/hivemind_bank = list() feedback_add_details("changeling_powers","DTHS") return 1 -/mob/proc/changeling_extract_dna_sting() +/mob/living/carbon/proc/changeling_extract_dna_sting() set category = "Changeling" set name = "Extract DNA Sting (40)" set desc="Stealthily sting a target to extract their DNA." @@ -760,7 +745,7 @@ var/list/datum/dna/hivemind_bank = list() if(!changeling) return 0 - var/mob/living/carbon/T = changeling_sting(40, /mob/proc/changeling_extract_dna_sting) + var/mob/living/carbon/T = changeling_sting(40, /mob/living/carbon/proc/changeling_extract_dna_sting) if(!T) return 0 T.dna.real_name = T.real_name diff --git a/code/game/gamemodes/changeling/modularchangling.dm b/code/game/gamemodes/changeling/modularchangling.dm index be8338526f7..34a2e978276 100644 --- a/code/game/gamemodes/changeling/modularchangling.dm +++ b/code/game/gamemodes/changeling/modularchangling.dm @@ -1,7 +1,6 @@ // READ: Don't use the apostrophe in name or desc. Causes script errors. -var/list/powers = typesof(/datum/power/changeling) - /datum/power/changeling //needed for the badmin verb for now -var/list/datum/power/changeling/powerinstances = list() +var/list/powerinstances /datum/power //Could be used by other antags too var/name = "Power" @@ -18,13 +17,13 @@ var/list/datum/power/changeling/powerinstances = list() name = "Absorb DNA" desc = "Permits us to syphon the DNA from a human. They become one with us, and we become stronger." genomecost = 0 - verbpath = /mob/proc/changeling_absorb_dna + verbpath = /mob/living/carbon/proc/changeling_absorb_dna /datum/power/changeling/transform name = "Transform" - desc = "We take on the apperance and voice of one we have absorbed." + desc = "We take on the appearance and voice of one we have absorbed." genomecost = 0 - verbpath = /mob/proc/changeling_transform + verbpath = /mob/living/carbon/proc/changeling_transform /datum/power/changeling/fakedeath name = "Regenerative Stasis" @@ -32,7 +31,7 @@ var/list/datum/power/changeling/powerinstances = list() helptext = "Can be used before or after death. Duration varies greatly." genomecost = 0 allowduringlesserform = 1 - verbpath = /mob/proc/changeling_fakedeath + verbpath = /mob/living/carbon/proc/changeling_fakedeath // Hivemind @@ -41,34 +40,34 @@ var/list/datum/power/changeling/powerinstances = list() desc = "We can channel a DNA into the airwaves, allowing our fellow changelings to absorb it and transform into it as if they acquired the DNA themselves." helptext = "Allows other changelings to absorb the DNA you channel from the airwaves. Will not help them towards their absorb objectives." genomecost = 0 - verbpath = /mob/proc/changeling_hiveupload + verbpath = /mob/living/carbon/proc/changeling_hiveupload /datum/power/changeling/hive_download name = "Hive Absorb" desc = "We can absorb a single DNA from the airwaves, allowing us to use more disguises with help from our fellow changelings." helptext = "Allows you to absorb a single DNA and use it. Does not count towards your absorb objective." genomecost = 0 - verbpath = /mob/proc/changeling_hivedownload + verbpath = /mob/living/carbon/proc/changeling_hivedownload /datum/power/changeling/lesser_form name = "Lesser Form" desc = "We debase ourselves and become lesser. We become a monkey." genomecost = 1 - verbpath = /mob/proc/changeling_lesser_form + verbpath = /mob/living/carbon/proc/changeling_lesser_form /datum/power/changeling/deaf_sting name = "Deaf Sting" desc = "We silently sting a human, completely deafening them for a short time." genomecost = 1 allowduringlesserform = 1 - verbpath = /mob/proc/changeling_deaf_sting + verbpath = /mob/living/carbon/proc/changeling_deaf_sting /datum/power/changeling/blind_sting name = "Blind Sting" desc = "We silently sting a human, completely blinding them for a short time." genomecost = 2 allowduringlesserform = 1 - verbpath = /mob/proc/changeling_blind_sting + verbpath = /mob/living/carbon/proc/changeling_blind_sting /datum/power/changeling/silence_sting name = "Silence Sting" @@ -76,14 +75,14 @@ var/list/datum/power/changeling/powerinstances = list() helptext = "Does not provide a warning to a victim that they have been stung, until they try to speak and cannot." genomecost = 2 allowduringlesserform = 1 - verbpath = /mob/proc/changeling_silence_sting + verbpath = /mob/living/carbon/proc/changeling_silence_sting /datum/power/changeling/mimicvoice name = "Mimic Voice" desc = "We shape our vocal glands to sound like a desired voice." helptext = "Will turn your voice into the name that you enter. We must constantly expend chemicals to maintain our form like this" genomecost = 3 - verbpath = /mob/proc/changeling_mimicvoice + verbpath = /mob/living/carbon/proc/changeling_mimicvoice /datum/power/changeling/extractdna name = "Extract DNA" @@ -91,53 +90,53 @@ var/list/datum/power/changeling/powerinstances = list() helptext = "Will give you the DNA of your target, allowing you to transform into them. Does not count towards absorb objectives." genomecost = 4 allowduringlesserform = 1 - verbpath = /mob/proc/changeling_extract_dna_sting + verbpath = /mob/living/carbon/proc/changeling_extract_dna_sting /datum/power/changeling/transformation_sting name = "Transformation Sting" desc = "We silently sting a human, injecting a retrovirus that forces them to transform into another." helptext = "Does not provide a warning to others. The victim will transform much like a changeling would." genomecost = 3 - verbpath = /mob/proc/changeling_transformation_sting + verbpath = /mob/living/carbon/proc/changeling_transformation_sting /datum/power/changeling/paralysis_sting name = "Paralysis Sting" desc = "We silently sting a human, paralyzing them for a short time." genomecost = 3 - verbpath = /mob/proc/changeling_paralysis_sting + verbpath = /mob/living/carbon/proc/changeling_paralysis_sting /datum/power/changeling/LSDSting name = "Hallucination Sting" - desc = "We evolve the ability to sting a target with a powerful hallunicationary chemical." + desc = "We evolve the ability to sting a target with a powerful hallucinogenic chemical." helptext = "The target does not notice they have been stung. The effect occurs after 30 to 60 seconds." genomecost = 3 - verbpath = /mob/proc/changeling_lsdsting + verbpath = /mob/living/carbon/proc/changeling_lsdsting /datum/power/changeling/DeathSting name = "Death Sting" desc = "We silently sting a human, filling him with potent chemicals. His rapid death is all but assured." genomecost = 10 - verbpath = /mob/proc/changeling_DEATHsting + verbpath = /mob/living/carbon/proc/changeling_DEATHsting /datum/power/changeling/unfat_sting name = "Unfat Sting" - desc = "We silently sting a human, forcing them to rapidly metobolize their fat." + desc = "We silently sting a human, forcing them to rapidly metabolize their fat." genomecost = 1 - verbpath = /mob/proc/changeling_unfat_sting + verbpath = /mob/living/carbon/proc/changeling_unfat_sting /datum/power/changeling/boost_range name = "Boost Range" desc = "We evolve the ability to shoot our stingers at humans, with some preperation." genomecost = 2 allowduringlesserform = 1 - verbpath = /mob/proc/changeling_boost_range + verbpath = /mob/living/carbon/proc/changeling_boost_range /datum/power/changeling/Epinephrine name = "Epinephrine sacs" desc = "We evolve additional sacs of adrenaline throughout our body." helptext = "Gives the ability to instantly recover from stuns. High chemical cost." genomecost = 4 - verbpath = /mob/proc/changeling_unstun + verbpath = /mob/living/carbon/proc/changeling_unstun /datum/power/changeling/ChemicalSynth name = "Rapid Chemical-Synthesis" @@ -153,7 +152,7 @@ var/list/datum/power/changeling/powerinstances = list() helptext = "Doubles the rate at which we naturally recharge chemicals." genomecost = 8 isVerb = 0 - verbpath = /mob/proc/changeling_fastchemical + verbpath = /mob/living/carbon/proc/changeling_fastchemical */ /datum/power/changeling/EngorgedGlands name = "Engorged Chemical Glands" @@ -169,14 +168,14 @@ var/list/datum/power/changeling/powerinstances = list() helptext = "We cannot be tracked by camera while using this skill. However, humans looking at us will find us.. uncanny. We must constantly expend chemicals to maintain our form like this." genomecost = 3 allowduringlesserform = 1 - verbpath = /mob/proc/changeling_digitalcamo + verbpath = /mob/living/carbon/proc/changeling_digitalcamo /datum/power/changeling/rapidregeneration name = "Rapid Regeneration" desc = "We evolve the ability to rapidly regenerate, negating the need for stasis." helptext = "Heals a moderate amount of damage every tick." genomecost = 8 - verbpath = /mob/proc/changeling_rapidregen + verbpath = /mob/living/carbon/proc/changeling_rapidregen @@ -188,9 +187,8 @@ var/list/datum/power/changeling/powerinstances = list() if(!usr || !usr.mind || !usr.mind.changeling) return src = usr.mind.changeling - if(!powerinstances.len) - for(var/P in powers) - powerinstances += new P() + if(!powerinstances) + powerinstances = init_subtypes(/datum/power/changeling) var/dat = "Changling Evolution Menu" @@ -463,9 +461,10 @@ var/list/datum/power/changeling/powerinstances = list() /datum/changeling/proc/purchasePower(var/datum/mind/M, var/Pname, var/remake_verbs = 1) - if(!M || !M.changeling) + if(!M || !M.changeling || !istype(M.current, /mob/living/carbon)) return + var/mob/living/carbon/C = M.current var/datum/power/changeling/Thepower = Pname @@ -477,16 +476,16 @@ var/list/datum/power/changeling/powerinstances = list() if(Thepower == null) - M.current << "This is awkward. Changeling power purchase failed, please report this bug to a coder!" + C << "This is awkward. Changeling power purchase failed, please report this bug to a coder!" return if(Thepower in purchasedpowers) - M.current << "We have already evolved this ability!" + C << "We have already evolved this ability!" return if(geneticpoints < Thepower.genomecost) - M.current << "We cannot evolve this... yet. We must acquire more DNA." + C << "We cannot evolve this... yet. We must acquire more DNA." return geneticpoints -= Thepower.genomecost @@ -494,7 +493,7 @@ var/list/datum/power/changeling/powerinstances = list() purchasedpowers += Thepower if(!Thepower.isVerb && Thepower.verbpath) - call(M.current, Thepower.verbpath)() + call(C, Thepower.verbpath)() else if(remake_verbs) - M.current.make_changeling() + C.make_changeling() diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm index ca077575a00..6ddbb223978 100644 --- a/code/game/gamemodes/changeling/traitor_chan.dm +++ b/code/game/gamemodes/changeling/traitor_chan.dm @@ -34,7 +34,7 @@ /datum/game_mode/traitor/changeling/post_setup() for(var/datum/mind/changeling in changelings) - grant_changeling_powers(changeling.current) + changeling.current.make_changeling(changeling.current) changeling.special_role = "Changeling" forge_changeling_objectives(changeling) greet_changeling(changeling) diff --git a/code/game/gamemodes/setupgame.dm b/code/game/gamemodes/setupgame.dm index 0168bbf2049..c38c18b7f90 100644 --- a/code/game/gamemodes/setupgame.dm +++ b/code/game/gamemodes/setupgame.dm @@ -1,48 +1,36 @@ /proc/setupgenetics() +// if (prob(50)) +// BLOCKADD = rand(-300,300) +// if (prob(75)) +// DIFFMUT = rand(0,20) - if (prob(50)) - BLOCKADD = rand(-300,300) - if (prob(75)) - DIFFMUT = rand(0,20) - - var/list/avnums = new/list() - var/tempnum - - avnums.Add(2) - avnums.Add(12) - avnums.Add(10) - avnums.Add(8) - avnums.Add(4) - avnums.Add(11) - avnums.Add(13) - avnums.Add(6) - - tempnum = pick(avnums) - avnums.Remove(tempnum) - HULKBLOCK = tempnum - tempnum = pick(avnums) - avnums.Remove(tempnum) - TELEBLOCK = tempnum - tempnum = pick(avnums) - avnums.Remove(tempnum) - FIREBLOCK = tempnum - tempnum = pick(avnums) - avnums.Remove(tempnum) - XRAYBLOCK = tempnum - tempnum = pick(avnums) - avnums.Remove(tempnum) - CLUMSYBLOCK = tempnum - tempnum = pick(avnums) - avnums.Remove(tempnum) - FAKEBLOCK = tempnum - tempnum = pick(avnums) - avnums.Remove(tempnum) - DEAFBLOCK = tempnum - tempnum = pick(avnums) - avnums.Remove(tempnum) - BLINDBLOCK = tempnum - + var/list/avnums = new /list(DNA_STRUC_ENZYMES_BLOCKS) + for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++) + avnums[i] = i + + HULKBLOCK = pick_n_take(avnums) + TELEBLOCK = pick_n_take(avnums) + + FIREBLOCK = pick_n_take(avnums) + XRAYBLOCK = pick_n_take(avnums) + + CLUMSYBLOCK = pick_n_take(avnums) + STRANGEBLOCK = pick_n_take(avnums) + DEAFBLOCK = pick_n_take(avnums) + BLINDBLOCK = pick_n_take(avnums) + NEARSIGHTEDBLOCK = pick_n_take(avnums) + EPILEPSYBLOCK = pick_n_take(avnums) + COUGHBLOCK = pick_n_take(avnums) + TOURETTESBLOCK = pick_n_take(avnums) + NERVOUSBLOCK = pick_n_take(avnums) + RACEBLOCK = pick_n_take(avnums) + bad_se_blocks = list(RACEBLOCK,NEARSIGHTEDBLOCK,EPILEPSYBLOCK,STRANGEBLOCK,COUGHBLOCK,CLUMSYBLOCK,TOURETTESBLOCK,NERVOUSBLOCK,DEAFBLOCK,BLINDBLOCK) + good_se_blocks = list(FIREBLOCK,XRAYBLOCK) + op_se_blocks = list(HULKBLOCK,TELEBLOCK) + + NULLED_SE = repeat_string(DNA_STRUC_ENZYMES_BLOCKS, "___") + NULLED_UI = repeat_string(DNA_UNI_IDENTITY_BLOCKS, "___") // HIDDEN MUTATIONS / SUPERPOWERS INITIALIZTION /* diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index b3cd8c38a90..e41028bcc59 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -27,24 +27,9 @@ icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk. item_state = "card-id" w_class = 1.0 - var/data = "" - var/ue = 0 - var/data_type = "ui" //ui|se - var/owner = "God Emperor of Mankind" + var/list/fields = list() var/read_only = 0 //Well,it's still a floppy disk -/obj/item/weapon/disk/data/demo - name = "data disk - 'God Emperor of Mankind'" - data = "066000033000000000AF00330660FF4DB002690" - //data = "0C80C80C80C80C80C8000000000000161FBDDEF" - Farmer Jeff - ue = 1 - read_only = 1 - -/obj/item/weapon/disk/data/monkey - name = "data disk - 'Mr. Muggles'" - data_type = "se" - data = "0983E840344C39F4B059D5145FC5785DC6406A4FFF" - read_only = 1 //Find a dead mob with a brain and client. /proc/find_dead_player(var/find_key) @@ -68,17 +53,16 @@ //Disk stuff. /obj/item/weapon/disk/data/New() ..() - var/diskcolor = pick(0,1,2) - src.icon_state = "datadisk[diskcolor]" + icon_state = "datadisk[pick(0,1,2)]" /obj/item/weapon/disk/data/attack_self(mob/user as mob) - src.read_only = !src.read_only + read_only = !read_only user << "You flip the write-protect tab to [src.read_only ? "protected" : "unprotected"]." /obj/item/weapon/disk/data/examine() set src in oview(5) ..() - usr << text("The write-protect tab is set to [src.read_only ? "protected" : "unprotected"].") + usr << "The write-protect tab is set to [src.read_only ? "protected" : "unprotected"]." return //Health Tracker Implant @@ -178,22 +162,12 @@ // -- End mode specific stuff - if(!H.dna) - H.dna = new /datum/dna() - H.dna.real_name = H.real_name - if(ui) - H.dna.uni_identity = ui - updateappearance(H, ui) - if(se) - H.dna.struc_enzymes = se - randmutb(H) //Sometimes the clones come out wrong. + hardset_dna(H, ui, se, null, mrace) + randmutb(H) //Sometimes the clones come out wrong. H.f_style = "Shaved" H.h_style = pick("Bedhead", "Bedhead 2", "Bedhead 3") - if(H.dna) - H.dna.mutantrace = mrace - H.update_mutantrace() H.suiciding = 0 src.attempting = 0 return 1 diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 7bbfb604bf5..da99eb150ea 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -1,82 +1,3 @@ -/obj/machinery/computer/scan_consolenew - name = "DNA Scanner Access Console" - desc = "Scan DNA." - icon = 'icons/obj/computer.dmi' - icon_state = "scanner" - density = 1 - var/uniblock = 1.0 - var/strucblock = 1.0 - var/subblock = 1.0 - var/unitarget = 1 - var/unitargethex = 1 - var/status = null - var/radduration = 2.0 - var/radstrength = 1.0 - var/radacc = 1.0 - var/buffer1 = null - var/buffer2 = null - var/buffer3 = null - var/buffer1owner = null - var/buffer2owner = null - var/buffer3owner = null - var/buffer1label = null - var/buffer2label = null - var/buffer3label = null - var/buffer1type = null - var/buffer2type = null - var/buffer3type = null - var/buffer1iue = 0 - var/buffer2iue = 0 - var/buffer3iue = 0 - var/injectorready = 0 //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete - var/current_screen = null - var/scanner_status_html = null - var/temp_html = null - var/obj/machinery/dna_scannernew/connected = null - var/obj/item/weapon/disk/data/diskette = null - anchored = 1.0 - use_power = 1 - 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/weapon/screwdriver)) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - if(do_after(user, 20)) - if (src.stat & BROKEN) - user << "\blue The broken glass falls out." - var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - new /obj/item/weapon/shard( src.loc ) - var/obj/item/weapon/circuitboard/scan_consolenew/M = new /obj/item/weapon/circuitboard/scan_consolenew( A ) - for (var/obj/C in src) - C.loc = src.loc - A.circuit = M - A.state = 3 - A.icon_state = "3" - A.anchored = 1 - del(src) - else - user << "\blue You disconnect the monitor." - var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - var/obj/item/weapon/circuitboard/scan_consolenew/M = new /obj/item/weapon/circuitboard/scan_consolenew( A ) - for (var/obj/C in src) - C.loc = src.loc - A.circuit = M - A.state = 4 - A.icon_state = "4" - A.anchored = 1 - del(src) - if (istype(I, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES - if (!src.diskette) - user.drop_item() - I.loc = src - src.diskette = I - user << "You insert [I]." - src.updateUsrDialog() - return - else - src.attack_hand(user) - return /obj/machinery/computer/cloning name = "Cloning Console" @@ -241,26 +162,21 @@ dat += "Unique Identifier:
[src.active_record.fields["UI"]]
" dat += "Structural Enzymes:
[src.active_record.fields["SE"]]
" - if (!isnull(src.diskette)) + if(diskette && diskette.fields) dat += "
" dat += "

Inserted Disk

" dat += "Contents: " - if (src.diskette.data == "") - dat += "Empty" - else - if (src.diskette.data_type == "ui") - dat += "Unique Identifier" - if (src.diskette.ue) - dat += " + Unique Enzymes" - else if (src.diskette.data_type == "se") - dat += "Structural Enzymes" - dat += "
Load from Disk" + var/list/L = list() + if(diskette.fields["UI"]) + L += "Unique Identifier" + if(diskette.fields["UE"] && diskette.fields["name"] && diskette.fields["b_type"]) + L += "Unique Enzymes" + if(diskette.fields["SE"]) + L += "Structural Enzymes" + dat += english_list(L, "Empty", " + ", " + ") + dat += "
Load from Disk" - - dat += "

Save to Disk:
" - dat += "Unique Identifier + Unique Enzymes
" - dat += "Unique Identifier
" - dat += "Structural Enzymes" + dat += "
Save to Disk" dat += "
" dat += "Delete Record" @@ -313,7 +229,7 @@ else if (href_list["view_rec"]) src.active_record = locate(href_list["view_rec"]) if(istype(src.active_record,/datum/data/record)) - if ((isnull(src.active_record.fields["ckey"])) || (src.active_record.fields["ckey"] == "")) + if (!active_record.fields["ckey"]) del(src.active_record) src.temp = "Record Corrupt" else @@ -343,51 +259,32 @@ else if (href_list["disk"]) //Load or eject. switch(href_list["disk"]) if("load") - if ((isnull(src.diskette)) || (src.diskette.data == "")) + if (!diskette || !istype(diskette.fields) || !diskette.fields["name"] || !diskette.fields) src.temp = "Load error." src.updateUsrDialog() return - if (isnull(src.active_record)) + if (!src.active_record) src.temp = "Record error." src.menu = 1 src.updateUsrDialog() return - - if (src.diskette.data_type == "ui") - src.active_record.fields["UI"] = src.diskette.data - if (src.diskette.ue) - src.active_record.fields["name"] = src.diskette.owner - else if (src.diskette.data_type == "se") - src.active_record.fields["SE"] = src.diskette.data - + + src.active_record.fields = diskette.fields.Copy() src.temp = "Load successful." + if("eject") - if (!isnull(src.diskette)) + if(src.diskette) src.diskette.loc = src.loc src.diskette = null - - else if (href_list["save_disk"]) //Save to disk! - if ((isnull(src.diskette)) || (src.diskette.read_only) || (isnull(src.active_record))) - src.temp = "Save error." - src.updateUsrDialog() - return - - switch(href_list["save_disk"]) //Save as Ui/Ui+Ue/Se - if("ui") - src.diskette.data = src.active_record.fields["UI"] - src.diskette.ue = 0 - src.diskette.data_type = "ui" - if("ue") - src.diskette.data = src.active_record.fields["UI"] - src.diskette.ue = 1 - src.diskette.data_type = "ui" - if("se") - src.diskette.data = src.active_record.fields["SE"] - src.diskette.ue = 0 - src.diskette.data_type = "se" - src.diskette.owner = src.active_record.fields["name"] - src.diskette.name = "data disk - '[src.diskette.owner]'" - src.temp = "Save \[[href_list["save_disk"]]\] successful." + if("save") + if(!diskette || diskette.read_only || !active_record || !active_record.fields) + src.temp = "Save error." + src.updateUsrDialog() + return + + diskette.fields = active_record.fields.Copy() + diskette.name = "data disk - '[src.diskette.fields["name"]]'" + src.temp = "Save successful." else if (href_list["refresh"]) src.updateUsrDialog() @@ -424,7 +321,7 @@ return /obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject as mob) - if ((isnull(subject)) || (!(ishuman(subject))) || (!subject.dna)) + if (!check_dna_integrity(subject) || !istype(subject)) scantemp = "Unable to locate valid genetic data." return if (!getbrain(subject)) @@ -443,9 +340,7 @@ scantemp = "Subject already in database." return - subject.dna.check_integrity() - - var/datum/data/record/R = new /datum/data/record( ) + var/datum/data/record/R = new /datum/data/record() if(subject.dna) R.fields["mrace"] = subject.dna.mutantrace else @@ -453,6 +348,7 @@ R.fields["ckey"] = subject.ckey R.fields["name"] = subject.real_name R.fields["id"] = copytext(md5(subject.real_name), 2, 6) + R.fields["UE"] = subject.dna.unique_enzymes R.fields["UI"] = subject.dna.uni_identity R.fields["SE"] = subject.dna.struc_enzymes diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 47e7464dd66..0e3011e9f16 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -958,8 +958,10 @@ */ var/passed if(src.dna) - if(usr.dna.unique_enzymes==src.dna) - passed = 1 + if(check_dna_integrity(usr)) + var/mob/living/carbon/C = usr + if(C.dna.unique_enzymes==src.dna) + passed = 1 else if(src.operation_allowed(usr)) passed = 1 if(!passed) diff --git a/code/game/objects/effects/gibs.dm b/code/game/objects/effects/gibs.dm index ae8fc7220a0..09453b00df8 100644 --- a/code/game/objects/effects/gibs.dm +++ b/code/game/objects/effects/gibs.dm @@ -1,4 +1,4 @@ -/proc/gibs(atom/location, var/list/viruses, var/datum/dna/MobDNA) //CARN MARKER +/proc/gibs(atom/location, var/list/viruses, var/datum/dna/MobDNA) new /obj/effect/gibspawner/generic(get_turf(location),viruses,MobDNA) /proc/hgibs(atom/location, var/list/viruses, var/datum/dna/MobDNA) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 8570ea8909f..bb1ce45aa6a 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -888,8 +888,8 @@ var/global/list/obj/item/device/pda/PDAs = list() user << "You slide \the [C] into \the [src]." return -/obj/item/device/pda/attack(mob/living/C as mob, mob/living/user as mob) - if (istype(C, /mob/living/carbon)) +/obj/item/device/pda/attack(mob/living/carbon/C, mob/living/user as mob) + if(istype(C)) switch(scanmode) if(1) @@ -918,13 +918,13 @@ var/global/list/obj/item/device/pda/PDAs = list() user.show_message(text("\red Warning: [D.form] Detected\nName: [D.name].\nType: [D.spread].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure]")) if(2) - if (!istype(C:dna, /datum/dna)) + if(!istype(C.dna)) user << "\blue No fingerprints found on [C]" else if(!istype(C, /mob/living/carbon/monkey)) if(!isnull(C:gloves)) user << "\blue No fingerprints found on [C]" else - user << text("\blue [C]'s Fingerprints: [md5(C:dna.uni_identity)]") + user << text("\blue [C]'s Fingerprints: [md5(C.dna.uni_identity)]") if ( !(C:blood_DNA) ) user << "\blue No blood found on [C]" if(C:blood_DNA) diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index 9c0114ed626..4172df49e43 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -68,13 +68,12 @@ if(href_list["setdna"]) if(pai.master_dna) return - var/mob/M = usr - if(!istype(M, /mob/living/carbon)) + if(!istype(usr, /mob/living/carbon)) usr << "You don't have any DNA, or your DNA is incompatible with this device." else - var/datum/dna/dna = usr.dna + var/mob/living/carbon/M = usr pai.master = M.real_name - pai.master_dna = dna.unique_enzymes + pai.master_dna = M.dna.unique_enzymes pai << "

You have been bound to a new master.

" if(href_list["wipe"]) var/confirm = input("Are you CERTAIN you wish to delete the current personality? This action cannot be undone.", "Personality Wipe") in list("Yes", "No") diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index 4ce6271997c..2ac9286206b 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -6,72 +6,52 @@ throw_speed = 1 throw_range = 5 w_class = 1.0 - var/dnatype = null - var/dna = null - var/block = null - var/ue = null + + var/list/fields /obj/item/weapon/dnainjector/attack_paw(mob/user) return attack_hand(user) -/obj/item/weapon/dnainjector/proc/inject(mob/M, mob/user) - if(M.stat == DEAD) //prevents dead people from having their DNA changed - user << "You can't modify [M]'s DNA while \he's dead." - return - - if(isliving(M)) +/obj/item/weapon/dnainjector/proc/inject(mob/living/carbon/M, mob/user) + if(check_dna_integrity(M) && !(NOCLONE in M.mutations)) + if(M.stat == DEAD) //prevents dead people from having their DNA changed + user << "You can't modify [M]'s DNA while \he's dead." + return M.radiation += rand(20, 50) - - if(dnatype == "ui") - if(!block) //isolated block? - if(ue) //unique enzymes? yes - M.dna.uni_identity = dna - updateappearance(M, M.dna.uni_identity) - M.real_name = ue - M.name = ue - else //unique enzymes? no - M.dna.uni_identity = dna - updateappearance(M, M.dna.uni_identity) - else - M.dna.uni_identity = setblock(M.dna.uni_identity,block, dna, 3) - updateappearance(M, M.dna.uni_identity) - - else if(dnatype == "se") - if(!block) //isolated block? - M.dna.struc_enzymes = dna - domutcheck(M, null) - else - M.dna.struc_enzymes = setblock(M.dna.struc_enzymes,block, dna, 3) - domutcheck(M, null, 1) - + if(fields) + var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]" + if(fields["name"] && fields["UE"] && fields["b_type"]) + M.real_name = fields["name"] + M.dna.unique_enzymes = fields["UE"] + M.name = M.real_name + M.dna.b_type = fields["b_type"] + if(fields["UI"]) //UI+UE + M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"]) + updateappearance(M) + if(fields["SE"]) + M.dna.struc_enzymes = merge_text(M.dna.struc_enzymes, fields["SE"]) + if(ishuman(M) && (deconstruct_block(getblock(M.dna.struc_enzymes, RACEBLOCK), BAD_MUTATION_DIFFICULTY) == BAD_MUTATION_DIFFICULTY)) //check for monkeying people. + message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] \red(MONKEY)") + log_msg += " (MONKEY)" + domutcheck(M, null) + log_attack(log_msg) + else + user << "It appears that [M] does not have compatible DNA." + return /obj/item/weapon/dnainjector/attack(mob/target, mob/user) if(!ishuman(user)) user << "You don't have the dexterity to do this!" return - if(!ishuman(target) && !ismonkey(target)) - user << "You can't inject [target]." - return - - target.attack_log += text("\[[time_stamp()]\] [user.name] ([user.ckey]) attempted to inject with [name]") - user.attack_log += text("\[[time_stamp()]\] Used the [name] to attempt to inject [target.name] ([target.ckey])") + + target.attack_log += "\[[time_stamp()]\] [user.name] ([user.ckey]) attempted to inject with [name]" + user.attack_log += "\[[time_stamp()]\] Used the [name] to attempt to inject [target.name] ([target.ckey])" log_attack("[user.name] ([user.ckey]) used the [name] to attempt to inject [target.name] ([target.ckey])") if(target != user) - target.visible_message("[user] is trying to inject [target] with [src]!", \ - "[user] is trying to inject [target] with [src]!") - - if(!do_mob(user, target)) - return - if(!src) - return - - if(ishuman(target)) //check for monkeying people. - if(dnatype == "se") - if(isblockon(getblock(dna, 14,3),14)) - message_admins("[key_name_admin(user)] injected [key_name_admin(target)] with the [name] \red(MONKEY)") - + target.visible_message("[user] is trying to inject [target] with [src]!", "[user] is trying to inject [target] with [src]!") + if(!do_mob(user, target)) return target.visible_message("[user] injects [target] with the syringe with [src]!", \ "[user] injects [target] with the syringe with [src]!") @@ -90,193 +70,159 @@ /obj/item/weapon/dnainjector/antihulk name = "\improper DNA injector (Anti-Hulk)" desc = "Cures green skin." - dnatype = "se" - dna = "708" - //block = 2 New() ..() - block = HULKBLOCK + fields = list("SE"=setblock(NULLED_SE, HULKBLOCK, repeat_string(DNA_BLOCK_SIZE,"0"))) /obj/item/weapon/dnainjector/hulkmut name = "\improper DNA injector (Hulk)" desc = "This will make you big and strong, but give you a bad skin condition." - dnatype = "se" - dna = "FED" - //block = 2 New() ..() - block = HULKBLOCK + fields = list("SE"=setblock(NULLED_SE, HULKBLOCK, repeat_string(DNA_BLOCK_SIZE,"f"))) /obj/item/weapon/dnainjector/xraymut name = "\improper DNA injector (Xray)" desc = "Finally you can see what the Captain does." - dnatype = "se" - dna = "FED" - //block = 8 New() ..() - block = XRAYBLOCK + fields = list("SE"=setblock(NULLED_SE, XRAYBLOCK, repeat_string(DNA_BLOCK_SIZE,"f"))) /obj/item/weapon/dnainjector/antixray name = "\improper DNA injector (Anti-Xray)" desc = "It will make you see harder." - dnatype = "se" - dna = "708" - //block = 8 New() ..() - block = XRAYBLOCK + fields = list("SE"=setblock(NULLED_SE, XRAYBLOCK, repeat_string(DNA_BLOCK_SIZE,"0"))) ///////////////////////////////////// /obj/item/weapon/dnainjector/antiglasses name = "\improper DNA injector (Anti-Glasses)" desc = "Toss away those glasses!" - dnatype = "se" - dna = "708" - block = 1 + New() + ..() + fields = list("SE"=setblock(NULLED_SE, NEARSIGHTEDBLOCK, repeat_string(DNA_BLOCK_SIZE,"0"))) /obj/item/weapon/dnainjector/glassesmut name = "\improper DNA injector (Glasses)" desc = "Will make you need dorkish glasses." - dnatype = "se" - dna = "BD6" - block = 1 + New() + ..() + fields = list("SE"=setblock(NULLED_SE, NEARSIGHTEDBLOCK, repeat_string(DNA_BLOCK_SIZE,"f"))) /obj/item/weapon/dnainjector/epimut name = "\improper DNA injector (Epi.)" desc = "Shake shake shake the room!" - dnatype = "se" - dna = "FA0" - block = 3 + New() + ..() + fields = list("SE"=setblock(NULLED_SE, EPILEPSYBLOCK, repeat_string(DNA_BLOCK_SIZE,"f"))) /obj/item/weapon/dnainjector/antiepi name = "\improper DNA injector (Anti-Epi.)" desc = "Will fix you up from shaking the room." - dnatype = "se" - dna = "708" - block = 3 + New() + ..() + fields = list("SE"=setblock(NULLED_SE, EPILEPSYBLOCK, repeat_string(DNA_BLOCK_SIZE,"0"))) //////////////////////////////////// /obj/item/weapon/dnainjector/anticough name = "\improper DNA injector (Anti-Cough)" desc = "Will stop that aweful noise." - dnatype = "se" - dna = "708" - block = 5 + New() + ..() + fields = list("SE"=setblock(NULLED_SE, COUGHBLOCK, repeat_string(DNA_BLOCK_SIZE,"0"))) /obj/item/weapon/dnainjector/coughmut name = "\improper DNA injector (Cough)" desc = "Will bring forth a sound of horror from your throat." - dnatype = "se" - dna = "BD6" - block = 5 + New() + ..() + fields = list("SE"=setblock(NULLED_SE, COUGHBLOCK, repeat_string(DNA_BLOCK_SIZE,"f"))) + /obj/item/weapon/dnainjector/clumsymut name = "\improper DNA injector (Clumsy)" desc = "Makes clown minions." - dnatype = "se" - dna = "FA0" - //block = 6 New() ..() - block = CLUMSYBLOCK + fields = list("SE"=setblock(NULLED_SE, CLUMSYBLOCK, repeat_string(DNA_BLOCK_SIZE,"f"))) + /obj/item/weapon/dnainjector/anticlumsy name = "\improper DNA injector (Anti-Clumy)" desc = "Apply this for Security Clown." - dnatype = "se" - dna = "708" - //block = 6 New() ..() - block = CLUMSYBLOCK + fields = list("SE"=setblock(NULLED_SE, CLUMSYBLOCK, repeat_string(DNA_BLOCK_SIZE,"0"))) /obj/item/weapon/dnainjector/antitour name = "\improper DNA injector (Anti-Tour.)" desc = "Will cure tourrets." - dnatype = "se" - dna = "708" - block = 7 + New() + ..() + fields = list("SE"=setblock(NULLED_SE, TOURETTESBLOCK, repeat_string(DNA_BLOCK_SIZE,"0"))) /obj/item/weapon/dnainjector/tourmut name = "\improper DNA injector (Tour.)" desc = "Gives you a nasty case off tourrets." - dnatype = "se" - dna = "BD6" - block = 7 + New() + ..() + fields = list("SE"=setblock(NULLED_SE, TOURETTESBLOCK, repeat_string(DNA_BLOCK_SIZE,"f"))) /obj/item/weapon/dnainjector/stuttmut name = "\improper DNA injector (Stutt.)" desc = "Makes you s-s-stuttterrr" - dnatype = "se" - dna = "FA0" - block = 9 + New() + ..() + fields = list("SE"=setblock(NULLED_SE, NERVOUSBLOCK, repeat_string(DNA_BLOCK_SIZE,"f"))) /obj/item/weapon/dnainjector/antistutt name = "\improper DNA injector (Anti-Stutt.)" desc = "Fixes that speaking impairment." - dnatype = "se" - dna = "708" - block = 9 + New() + ..() + fields = list("SE"=setblock(NULLED_SE, NERVOUSBLOCK, repeat_string(DNA_BLOCK_SIZE,"0"))) /obj/item/weapon/dnainjector/antifire name = "\improper DNA injector (Anti-Fire)" desc = "Cures fire." - dnatype = "se" - dna = "708" - //block = 10 New() ..() - block = FIREBLOCK + fields = list("SE"=setblock(NULLED_SE, FIREBLOCK, repeat_string(DNA_BLOCK_SIZE,"0"))) /obj/item/weapon/dnainjector/firemut name = "\improper DNA injector (Fire)" desc = "Gives you fire." - dnatype = "se" - dna = "FED" - //block = 10 New() ..() - block = FIREBLOCK + fields = list("SE"=setblock(NULLED_SE, FIREBLOCK, repeat_string(DNA_BLOCK_SIZE,"0"))) /obj/item/weapon/dnainjector/blindmut name = "\improper DNA injector (Blind)" desc = "Makes you not see anything." - dnatype = "se" - dna = "FA0" - //block = 11 New() ..() - block = BLINDBLOCK + fields = list("SE"=setblock(NULLED_SE, BLINDBLOCK, repeat_string(DNA_BLOCK_SIZE,"f"))) /obj/item/weapon/dnainjector/antiblind name = "\improper DNA injector (Anti-Blind)" desc = "ITS A MIRACLE!!!" - dnatype = "se" - dna = "708" - //block = 11 New() ..() - block = BLINDBLOCK + fields = list("SE"=setblock(NULLED_SE, BLINDBLOCK, repeat_string(DNA_BLOCK_SIZE,"0"))) /obj/item/weapon/dnainjector/antitele name = "\improper DNA injector (Anti-Tele.)" desc = "Will make you not able to control your mind." - dnatype = "se" - dna = "708" - //block = 12 New() ..() - block = TELEBLOCK + fields = list("SE"=setblock(NULLED_SE, TELEBLOCK, repeat_string(DNA_BLOCK_SIZE,"0"))) /obj/item/weapon/dnainjector/telemut name = "\improper DNA injector (Tele.)" desc = "Super brain man!" - dnatype = "se" - dna = "FED" - //block = 12 New() ..() - block = TELEBLOCK + fields = list("SE"=setblock(NULLED_SE, TELEBLOCK, repeat_string(DNA_BLOCK_SIZE,"f"))) /obj/item/weapon/dnainjector/telemut/darkbundle name = "\improper DNA injector" @@ -288,33 +234,27 @@ /obj/item/weapon/dnainjector/deafmut name = "\improper DNA injector (Deaf)" desc = "Sorry, what did you say?" - dnatype = "se" - dna = "FA0" - //block = 13 New() ..() - block = DEAFBLOCK + fields = list("SE"=setblock(NULLED_SE, DEAFBLOCK, repeat_string(DNA_BLOCK_SIZE,"f"))) /obj/item/weapon/dnainjector/antideaf name = "\improper DNA injector (Anti-Deaf)" desc = "Will make you hear once more." - dnatype = "se" - dna = "708" - //block = 13 New() ..() - block = DEAFBLOCK + fields = list("SE"=setblock(NULLED_SE, DEAFBLOCK, repeat_string(DNA_BLOCK_SIZE,"0"))) /obj/item/weapon/dnainjector/h2m name = "\improper DNA injector (Human > Monkey)" desc = "Will make you a flea bag." - dnatype = "se" - dna = "FA0" - block = 14 + New() + ..() + fields = list("SE"=setblock(NULLED_SE, RACEBLOCK, repeat_string(DNA_BLOCK_SIZE,"f"))) /obj/item/weapon/dnainjector/m2h name = "\improper DNA injector (Monkey > Human)" desc = "Will make you...less hairy." - dnatype = "se" - dna = "708" - block = 14 \ No newline at end of file + New() + ..() + fields = list("SE"=setblock(NULLED_SE, RACEBLOCK, repeat_string(DNA_BLOCK_SIZE,"0"))) \ No newline at end of file diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index abbc13a8b2a..3e88bd53eba 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -245,7 +245,7 @@ var/datum/controller/supply_shuttle/supply_shuttle = new() del(MA) if(plasma_count) - points += Floor(plasma_count / plasma_per_point) + points += round(plasma_count / plasma_per_point) //Buyin proc/buy() diff --git a/code/global.dm b/code/global.dm index 9a99a7ac518..97064e128b3 100644 --- a/code/global.dm +++ b/code/global.dm @@ -25,7 +25,11 @@ var/global/list/global_map = null ////////////// - +var/NEARSIGHTEDBLOCK = 0 +var/EPILEPSYBLOCK = 0 +var/COUGHBLOCK = 0 +var/TOURETTESBLOCK = 0 +var/NERVOUSBLOCK = 0 var/BLINDBLOCK = 0 var/DEAFBLOCK = 0 var/HULKBLOCK = 0 @@ -33,9 +37,15 @@ var/TELEBLOCK = 0 var/FIREBLOCK = 0 var/XRAYBLOCK = 0 var/CLUMSYBLOCK = 0 -var/FAKEBLOCK = 0 -var/BLOCKADD = 0 -var/DIFFMUT = 0 +var/STRANGEBLOCK = 0 +var/RACEBLOCK = 0 + +var/list/bad_se_blocks +var/list/good_se_blocks +var/list/op_se_blocks + +var/NULLED_SE +var/NULLED_UI var/skipupdate = 0 /////////////// diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 44757fef817..295cdd877ea 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -393,36 +393,7 @@ client/proc/one_click_antag() var/datum/preferences/A = new() A.copy_to(new_character) - new_character.dna.ready_dna(new_character) + ready_dna(new_character) new_character.key = G_found.key - return new_character -/* DEATH SQUADS -/datum/admins/proc/create_syndicate_death_commando(obj/spawn_location, syndicate_leader_selected = 0) - var/mob/living/carbon/human/new_syndicate_commando = new(spawn_location.loc) - var/syndicate_commando_leader_rank = pick("Lieutenant", "Captain", "Major") - var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major") - var/syndicate_commando_name = pick(last_names) - - new_syndicate_commando.gender = pick(MALE, FEMALE) - - var/datum/preferences/A = new()//Randomize appearance for the commando. - A.randomize_appearance_for(new_syndicate_commando) - - new_syndicate_commando.real_name = "[!syndicate_leader_selected ? syndicate_commando_rank : syndicate_commando_leader_rank] [syndicate_commando_name]" - new_syndicate_commando.name = new_syndicate_commando.real_name - new_syndicate_commando.age = !syndicate_leader_selected ? rand(23,35) : rand(35,45) - - new_syndicate_commando.dna.ready_dna(new_syndicate_commando)//Creates DNA. - - //Creates mind stuff. - new_syndicate_commando.mind_initialize() - new_syndicate_commando.mind.assigned_role = "MODE" - new_syndicate_commando.mind.special_role = "Syndicate Commando" - - //Adds them to current traitor list. Which is really the extra antagonist list. - ticker.mode.traitors += new_syndicate_commando.mind - new_syndicate_commando.equip_syndicate_commando(syndicate_leader_selected) - - return new_syndicate_commando - */ \ No newline at end of file + return new_character diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index f55ed33c49b..56bbc795911 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -326,13 +326,9 @@ Traitors and the like can also be revived with the previous role mostly intact. //DNA if(record_found)//Pull up their name from database records if they did have a mind. - new_character.dna = new()//Let's first give them a new DNA. - new_character.dna.unique_enzymes = record_found.fields["b_dna"]//Enzymes are based on real name but we'll use the record for conformity. - new_character.dna.struc_enzymes = record_found.fields["enzymes"]//This is the default of enzymes so I think it's safe to go with. - new_character.dna.uni_identity = record_found.fields["identity"]//DNA identity is carried over. - updateappearance(new_character,new_character.dna.uni_identity)//Now we configure their appearance based on their unique identity, same as with a DNA machine or somesuch. + hardset_dna(new_character, record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], null, record_found.fields["b_type"]) else//If they have no records, we just do a random DNA for them, based on their random appearance/savefile. - new_character.dna.ready_dna(new_character) + ready_dna(new_character) new_character.key = G_found.key diff --git a/code/modules/awaymissions/maploader/reader.dm b/code/modules/awaymissions/maploader/reader.dm index 13aef86f46d..427f1bdad59 100644 --- a/code/modules/awaymissions/maploader/reader.dm +++ b/code/modules/awaymissions/maploader/reader.dm @@ -88,7 +88,7 @@ dmm_suite{ } } //Construct attributes associative list - var/list/fields = new(0) + var/list/fields = list() for(var/index=1;index<=attributes.len;index++){ var/trim_left = trim_text(copytext(attributes[index],1,findtext(attributes[index],"="))) var/trim_right = trim_text(copytext(attributes[index],findtext(attributes[index],"=")+1,0)) @@ -164,7 +164,7 @@ dmm_suite{ } } //Construct attributes associative list - var/list/fields = new(0) + var/list/fields = list() for(var/index=1;index<=attributes.len;index++){ var/trim_left = trim_text(copytext(attributes[index],1,findtext(attributes[index],"="))) var/trim_right = trim_text(copytext(attributes[index],findtext(attributes[index],"=")+1,0)) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 2e2a9bbf1c4..04378d48110 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -47,17 +47,11 @@ datum/preferences var/underwear = "Nude" //underwear type var/backbag = 2 //backpack type var/h_style = "Bald" //Hair type - var/r_hair = 0 //Hair color - var/g_hair = 0 //Hair color - var/b_hair = 0 //Hair color + var/h_color = "000" //Hair color var/f_style = "Shaved" //Face hair type - var/r_facial = 0 //Face hair color - var/g_facial = 0 //Face hair color - var/b_facial = 0 //Face hair color - var/s_tone = 0 //Skin color - var/r_eyes = 0 //Eye color - var/g_eyes = 0 //Eye color - var/b_eyes = 0 //Eye color + var/f_color = "000" //Facial hair color + var/s_tone = "caucasian" //Skin color + var/eye_color = "000" //Eye color //Mob preview var/icon/preview_icon_front = null @@ -86,7 +80,7 @@ datum/preferences var/metadata = "" /datum/preferences/New(client/C) - b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") + b_type = random_blood_type() if(istype(C)) if(!IsGuestKey(C.key)) load_path(C.ckey) @@ -163,7 +157,7 @@ datum/preferences dat += "
" dat += "Blood Type: [b_type]
" - dat += "Skin Tone:
[-s_tone + 35]/220
" + dat += "Skin Tone:
    [s_tone]
" dat += "Underwear:
[underwear]
" dat += "Backpack:
[backbaglist[backbag]]
" @@ -173,7 +167,7 @@ datum/preferences dat += "

Hair Style

" dat += "[h_style]
" - dat += "    Change
" + dat += "    Change
" dat += "
" @@ -181,14 +175,14 @@ datum/preferences dat += "

Facial Hair Style

" dat += "[f_style]
" - dat += "    Change
" + dat += "    Change
" dat += "
" dat += "

Eye Color

" - dat += "    Change
" + dat += "    Change
" dat += "
" @@ -487,23 +481,17 @@ datum/preferences if("age") age = rand(AGE_MIN, AGE_MAX) if("hair") - r_hair = rand(0,255) - g_hair = rand(0,255) - b_hair = rand(0,255) + h_color = random_short_color() if("h_style") h_style = random_hair_style(gender) if("facial") - r_facial = rand(0,255) - g_facial = rand(0,255) - b_facial = rand(0,255) + f_color = random_short_color() if("f_style") f_style = random_facial_hair_style(gender) if("underwear") underwear = random_underwear(gender) if("eyes") - r_eyes = rand(0,255) - g_eyes = rand(0,255) - b_eyes = rand(0,255) + eye_color = random_eye_color() if("s_tone") s_tone = random_skin_tone() if("bag") @@ -531,11 +519,10 @@ datum/preferences metadata = sanitize(copytext(new_metadata,1,MAX_MESSAGE_LEN)) if("hair") - var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference") as color|null + var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference") as null|color if(new_hair) - r_hair = hex2num(copytext(new_hair, 2, 4)) - g_hair = hex2num(copytext(new_hair, 4, 6)) - b_hair = hex2num(copytext(new_hair, 6, 8)) + h_color = sanitize_hexcolor(new_hair) + if("h_style") var/new_h_style @@ -547,11 +534,9 @@ datum/preferences h_style = new_h_style if("facial") - var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference") as color|null + var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference") as null|color if(new_facial) - r_facial = hex2num(copytext(new_facial, 2, 4)) - g_facial = hex2num(copytext(new_facial, 4, 6)) - b_facial = hex2num(copytext(new_facial, 6, 8)) + f_color = sanitize_hexcolor(new_facial) if("f_style") var/new_f_style @@ -574,14 +559,12 @@ datum/preferences if("eyes") var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference") as color|null if(new_eyes) - r_eyes = hex2num(copytext(new_eyes, 2, 4)) - g_eyes = hex2num(copytext(new_eyes, 4, 6)) - b_eyes = hex2num(copytext(new_eyes, 6, 8)) + eye_color = sanitize_hexcolor(new_eyes) if("s_tone") - var/new_s_tone = input(user, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Character Preference") as num|null + var/new_s_tone = input(user, "Choose your character's skin-tone:", "Character Preference") as null|anything in skin_tones if(new_s_tone) - s_tone = 35 - max(min( round(new_s_tone), 220),1) + s_tone = new_s_tone if("ooccolor") var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference") as color|null @@ -680,17 +663,9 @@ datum/preferences character.age = age character.b_type = b_type - character.r_eyes = r_eyes - character.g_eyes = g_eyes - character.b_eyes = b_eyes - - character.r_hair = r_hair - character.g_hair = g_hair - character.b_hair = b_hair - - character.r_facial = r_facial - character.g_facial = g_facial - character.b_facial = b_facial + character.eye_color = eye_color + character.h_color = h_color + character.f_color = f_color character.s_tone = s_tone character.h_style = h_style diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 90551a2dcb7..b079a33ece1 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -160,19 +160,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["name_is_always_random"] >> be_random_name S["gender"] >> gender S["age"] >> age - //colors to be consolidated into hex strings (requires some work with dna code) - S["hair_red"] >> r_hair - S["hair_green"] >> g_hair - S["hair_blue"] >> b_hair - S["facial_red"] >> r_facial - S["facial_green"] >> g_facial - S["facial_blue"] >> b_facial + S["hair_color"] >> h_color + S["facial_hair_color"] >> f_color + S["eye_color"] >> eye_color S["skin_tone"] >> s_tone S["hair_style_name"] >> h_style S["facial_style_name"] >> f_style - S["eyes_red"] >> r_eyes - S["eyes_green"] >> g_eyes - S["eyes_blue"] >> b_eyes S["underwear"] >> underwear S["backbag"] >> backbag @@ -207,16 +200,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car f_style = sanitize_inlist(f_style, facial_hair_styles_female_list) underwear = sanitize_inlist(underwear, underwear_f) age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age)) - r_hair = sanitize_integer(r_hair, 0, 255, initial(r_hair)) - g_hair = sanitize_integer(g_hair, 0, 255, initial(g_hair)) - b_hair = sanitize_integer(b_hair, 0, 255, initial(b_hair)) - r_facial = sanitize_integer(r_facial, 0, 255, initial(r_facial)) - g_facial = sanitize_integer(g_facial, 0, 255, initial(g_facial)) - b_facial = sanitize_integer(b_facial, 0, 255, initial(b_facial)) - s_tone = sanitize_integer(s_tone, -185, 34, initial(s_tone)) - r_eyes = sanitize_integer(r_eyes, 0, 255, initial(r_eyes)) - g_eyes = sanitize_integer(g_eyes, 0, 255, initial(g_eyes)) - b_eyes = sanitize_integer(b_eyes, 0, 255, initial(b_eyes)) + h_color = sanitize_hexcolor(h_color, 3, 0) + f_color = sanitize_hexcolor(f_color, 3, 0) + eye_color = sanitize_hexcolor(eye_color, 3, 0) + s_tone = sanitize_inlist(s_tone, skin_tones) backbag = sanitize_integer(backbag, 1, backbaglist.len, initial(backbag)) userandomjob = sanitize_integer(userandomjob, 0, 1, initial(userandomjob)) @@ -246,18 +233,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["name_is_always_random"] << be_random_name S["gender"] << gender S["age"] << age - S["hair_red"] << r_hair - S["hair_green"] << g_hair - S["hair_blue"] << b_hair - S["facial_red"] << r_facial - S["facial_green"] << g_facial - S["facial_blue"] << b_facial + S["hair_color"] << h_color + S["facial_hair_color"] << f_color + S["eye_color"] << eye_color S["skin_tone"] << s_tone S["hair_style_name"] << h_style S["facial_style_name"] << f_style - S["eyes_red"] << r_eyes - S["eyes_green"] << g_eyes - S["eyes_blue"] << b_eyes S["underwear"] << underwear S["backbag"] << backbag diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 8e321b098ad..ed54cc8f403 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -168,10 +168,10 @@ if(!istype(user)) return mob = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kitty") mob2 = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kitty2") - mob.Blend(rgb(user.r_hair, user.g_hair, user.b_hair), ICON_ADD) - mob2.Blend(rgb(user.r_hair, user.g_hair, user.b_hair), ICON_ADD) + mob.Blend("#[user.h_color]", ICON_ADD) + mob2.Blend("#[user.h_color]", ICON_ADD) var/icon/earbit = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kittyinner") var/icon/earbit2 = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kittyinner2") mob.Blend(earbit, ICON_OVERLAY) - mob2.Blend(earbit2, ICON_OVERLAY) \ No newline at end of file + mob2.Blend(earbit2, ICON_OVERLAY) diff --git a/code/modules/detectivework/detective_work.dm b/code/modules/detectivework/detective_work.dm index 5bd530db1cc..f648654900b 100644 --- a/code/modules/detectivework/detective_work.dm +++ b/code/modules/detectivework/detective_work.dm @@ -89,11 +89,7 @@ atom/proc/add_fibers(mob/living/carbon/human/M) //Now, lets get to the dirty work. //First, make sure their DNA makes sense. var/mob/living/carbon/human/H = M - if(!istype(H.dna, /datum/dna) || !H.dna.uni_identity || (length(H.dna.uni_identity) != 32)) - if(!istype(H.dna, /datum/dna)) - H.dna = new /datum/dna(null) - H.dna.real_name = H.real_name - H.check_dna() + check_dna_integrity(H) //sets up dna and its variables if it was missing somehow //Now, deal with gloves. if(!ignoregloves) diff --git a/code/modules/events/ninja.dm b/code/modules/events/ninja.dm index e827699554a..f0a6961d936 100644 --- a/code/modules/events/ninja.dm +++ b/code/modules/events/ninja.dm @@ -347,7 +347,7 @@ ________________________________________________________________________________ var/datum/preferences/A = new()//Randomize appearance for the ninja. A.real_name = "[pick(ninja_titles)] [pick(ninja_names)]" A.copy_to(new_ninja) - new_ninja.dna.ready_dna(new_ninja) + ready_dna(new_ninja) new_ninja.equip_space_ninja() return new_ninja diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 643c300d02e..10f3d883186 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -744,21 +744,9 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob) // -- End mode specific stuff podman.gender = ghost.gender - if(podman.gender in list(NEUTER, PLURAL)) //Sanity check, which should never actually happen. - podman.gender = pick(MALE,FEMALE) - if(!podman.dna) - podman.dna = new /datum/dna() - podman.dna.real_name = podman.real_name - if(ui) - podman.dna.uni_identity = ui - updateappearance(podman, ui) - if(se) - podman.dna.struc_enzymes = se - if(!prob(potency)) //if it fails, plantman! - if(podman.dna) - podman.dna.mutantrace = "plant" - podman.update_mutantrace() + //dna stuff + hardset_dna(podman, ui, se, null, !prob(potency) ? "plant" : null) //makes sure podman has dna and sets the dna's ui/se/mutantrace/real_name etc variables else //else, one packet of seeds. maybe two var/seed_count = 1 diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm index 5f50e4f06b5..d0c60fb4609 100644 --- a/code/modules/mob/death.dm +++ b/code/modules/mob/death.dm @@ -13,8 +13,7 @@ animation.icon = 'icons/mob/mob.dmi' animation.master = src -// flick("gibbed-m", animation) - gibs(loc, viruses, dna) + gibs(loc, viruses) dead_mob_list -= src spawn(15) diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index e1bdc2f3b2d..a6c6c9b60ba 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -170,12 +170,6 @@ move_delay_add = min(move_delay_add + round(amount / 2), 10) // a maximum delay of 10 return -/mob/living/carbon/alien/getDNA() - return null - -/mob/living/carbon/alien/setDNA() - return - /*---------------------------------------- Proc: AddInfectionImages() Des: Gives the client of the alien an image on each infected mob. diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index e1a3d2ad2ab..84abccad38d 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -204,15 +204,6 @@ /mob/living/carbon/proc/eyecheck() return 0 -// ++++ROCKDTBEN++++ MOB PROCS -- Ask me before touching. -// Stop! ... Hammertime! ~Carn - -/mob/living/carbon/proc/getDNA() - return dna - -/mob/living/carbon/proc/setDNA(var/datum/dna/newDNA) - dna = newDNA - // ++++ROCKDTBEN++++ MOB PROCS //END /mob/living/carbon/proc/handle_ventcrawl() // -- TLE -- Merged by Carn diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 2e0b944a659..5f41f4c3cda 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -13,4 +13,6 @@ //inventory slots var/obj/item/back = null var/obj/item/clothing/mask/wear_mask = null - var/obj/item/weapon/tank/internal = null \ No newline at end of file + var/obj/item/weapon/tank/internal = null + + var/datum/dna/dna = null//Carbon diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 0bc741ac63f..7053ad48074 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -17,27 +17,17 @@ reagents = R R.my_atom = src - if(!dna) - dna = new /datum/dna(null) - //initialise organs organs = newlist(/datum/limb/chest, /datum/limb/head, /datum/limb/l_arm, /datum/limb/r_arm, /datum/limb/r_leg, /datum/limb/l_leg) for(var/datum/limb/O in organs) O.owner = src - internal_organs += new /obj/item/organ/appendix internal_organs += new /obj/item/organ/heart internal_organs += new /obj/item/organ/brain ..() - if(dna) - dna.real_name = real_name - - prev_gender = gender // Debug for plural genders - - /mob/living/carbon/human/Bump(atom/movable/AM as mob|obj, yes) if ((!( yes ) || now_pushing)) return @@ -582,11 +572,6 @@ return 0 - -/mob/living/carbon/human/proc/check_dna() - dna.check_integrity(src) - - /mob/living/carbon/human/proc/play_xylophone() if(!src.xylophone) visible_message("[src] begins playing \his ribcage like a xylophone. It's quite spooky.","You begin to play a spooky refrain on your ribcage.","You hear a spooky xylophone melody.") diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 1034ca23104..3cb7acc54ac 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,22 +1,16 @@ /mob/living/carbon/human //Hair colour and style - var/r_hair = 0 - var/g_hair = 0 - var/b_hair = 0 + var/h_color = "000" var/h_style = "Bald" //Facial hair colour and style - var/r_facial = 0 - var/g_facial = 0 - var/b_facial = 0 + var/f_color = "000" var/f_style = "Shaved" //Eye colour - var/r_eyes = 0 - var/g_eyes = 0 - var/b_eyes = 0 + var/eye_color = "000" - var/s_tone = 0 //Skin tone + var/s_tone = "caucasian" //Skin tone var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 55267f4dcbc..bfb3d939e24 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -211,19 +211,17 @@ Please contact me on #coderbus IRC. ~Carn x //Skin tone if(!skeleton) - if(s_tone >= 0) - stand_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD) - lying_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD) - else - stand_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT) - lying_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT) + var/color = skin_tones[s_tone] + if(color) + color = "#" + color + stand_icon.Blend(color, ICON_MULTIPLY) + lying_icon.Blend(color, ICON_MULTIPLY) //Eyes - if(!skeleton) var/icon/eyes_s = new/icon('icons/mob/human_face.dmi', "eyes_s") var/icon/eyes_l = new/icon('icons/mob/human_face.dmi', "eyes_l") - eyes_s.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD) - eyes_l.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD) + eyes_s.Blend("#[eye_color]", ICON_ADD) + eyes_l.Blend("#[eye_color]", ICON_ADD) stand_icon.Blend(eyes_s, ICON_OVERLAY) lying_icon.Blend(eyes_l, ICON_OVERLAY) @@ -264,8 +262,8 @@ Please contact me on #coderbus IRC. ~Carn x if(facial_hair_style) var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") var/icon/facial_l = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_l") - facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD) - facial_l.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD) + facial_s.Blend("#[f_color]", ICON_ADD) + facial_l.Blend("#[f_color]", ICON_ADD) face_standing.Blend(facial_s, ICON_OVERLAY) face_lying.Blend(facial_l, ICON_OVERLAY) @@ -274,8 +272,8 @@ Please contact me on #coderbus IRC. ~Carn x if(hair_style) var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") var/icon/hair_l = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_l") - hair_s.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD) - hair_l.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD) + hair_s.Blend("#[h_color]", ICON_ADD) + hair_l.Blend("#[h_color]", ICON_ADD) face_standing.Blend(hair_s, ICON_OVERLAY) face_lying.Blend(hair_l, ICON_OVERLAY) diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index e5819e1de83..d892cc8ed4f 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -21,23 +21,7 @@ if(name == "monkey") name = text("monkey ([rand(1, 1000)])") real_name = name - if (!(dna)) - if(gender == NEUTER) - gender = pick(MALE, FEMALE) - dna = new /datum/dna( null ) - dna.real_name = real_name - dna.uni_identity = "00600200A00E0110148FC01300B009" - dna.struc_enzymes = "0983E840344C39F4B059D5145FC5785DC6406A4BB8" - dna.unique_enzymes = md5(name) - //////////blah - var/gendervar - if (gender == MALE) - gendervar = add_zero2(num2hex((rand(1,2049)),1), 3) - else - gendervar = add_zero2(num2hex((rand(2051,4094)),1), 3) - dna.uni_identity += gendervar - dna.uni_identity += "12C" - dna.uni_identity += "4E2" + gender = pick(MALE, FEMALE) ..() diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index dc3bd9d0f60..d97e8c1f691 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -367,15 +367,17 @@ "} return dat -/mob/living/silicon/pai/proc/CheckDNA(var/mob/M, var/mob/living/silicon/pai/P) +/mob/living/silicon/pai/proc/CheckDNA(mob/living/carbon/M, mob/living/silicon/pai/P) var/answer = input(M, "[P] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[P] Check DNA", "No") in list("Yes", "No") if(answer == "Yes") var/turf/T = get_turf_or_move(P.loc) for (var/mob/v in viewers(T)) v.show_message("\blue [M] presses \his thumb against [P].", 3, "\blue [P] makes a sharp clicking sound as it extracts DNA material from [M].", 2) - var/datum/dna/dna = M.dna - P << "

[M]'s UE string : [dna.unique_enzymes]

" - if(dna.unique_enzymes == P.master_dna) + if(!check_dna_integrity(M)) + P << "No DNA detected" + return + P << "

[M]'s UE string : [M.dna.unique_enzymes]

" + if(M.dna.unique_enzymes == P.master_dna) P << "DNA is a match to stored Master DNA." else P << "DNA does not match stored Master DNA." diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index a2afe2c03f2..b5d143a9c45 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -87,19 +87,10 @@ var/next_mob_id = 0 if(I && istype(I)) //The istype is necessary for things like bodybags which are structures that do not have an attack() proc. I.attack(src, user) - -/mob/proc/findname(msg) - for(var/mob/M in mob_list) - if (M.real_name == text("[]", msg)) - return M - return 0 - /mob/proc/movement_delay() return 0 /mob/proc/Life() -// if(organStructure) -// organStructure.ProcessOrgans() return /mob/proc/get_item_by_slot(slot_id) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 184b3271c19..791ae20269b 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -126,8 +126,6 @@ var/const/deafness = 2//Carbon var/const/muteness = 4//Carbon - - var/datum/dna/dna = null//Carbon var/radiation = 0.0//Carbon var/list/mutations = list() //Carbon -- Doohl diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 684dff518e4..2198c13a243 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -269,9 +269,11 @@ It's fairly easy to fix if dealing with single letters but not so much with comp /proc/findname(msg) + if(!istext(msg)) + msg = "[msg]" for(var/mob/M in mob_list) - if (M.real_name == text("[msg]")) - return 1 + if(M.real_name == msg) + return M return 0 diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm index 01ac7bf2860..7d1907c74ef 100644 --- a/code/modules/mob/mob_transformation_simple.dm +++ b/code/modules/mob/mob_transformation_simple.dm @@ -40,8 +40,12 @@ M.name = src.name M.real_name = src.real_name - if(src.dna) - M.dna = src.dna + if(check_dna_integrity(src) && istype(M, /mob/living/carbon)) + var/mob/living/carbon/C = src + var/mob/living/carbon/D = M + D.dna = C.dna + else + ready_dna(M) if(mind) mind.transfer_to(M) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index f3d113d7025..27d4d5d80c0 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -324,8 +324,8 @@ mind.transfer_to(new_character) //won't transfer key since the mind is not active new_character.name = real_name - new_character.dna.ready_dna(new_character) - new_character.dna.b_type = client.prefs.b_type + + ready_dna(new_character, client.prefs.b_type) new_character.key = key //Manually transfer the key to log them in diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 8a36c953e74..d4447280d2a 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -9,122 +9,12 @@ datum/preferences s_tone = random_skin_tone() h_style = random_hair_style(gender) f_style = random_facial_hair_style(gender) - randomize_hair_color("hair") - randomize_hair_color("facial") - randomize_eyes_color() + h_color = random_short_color() + f_color = h_color + eye_color = random_eye_color() backbag = 2 age = rand(AGE_MIN,AGE_MAX) - - proc/randomize_hair_color(var/target = "hair") - if(prob (75) && target == "facial") // Chance to inherit hair color - r_facial = r_hair - g_facial = g_hair - b_facial = b_hair - return - - var/red - var/green - var/blue - - var/col = pick ("blonde", "black", "chestnut", "copper", "brown", "wheat", "old", "punk") - switch(col) - if("blonde") - red = 255 - green = 255 - blue = 0 - if("black") - red = 0 - green = 0 - blue = 0 - if("chestnut") - red = 153 - green = 102 - blue = 51 - if("copper") - red = 255 - green = 153 - blue = 0 - if("brown") - red = 102 - green = 51 - blue = 0 - if("wheat") - red = 255 - green = 255 - blue = 153 - if("old") - red = rand (100, 255) - green = red - blue = red - if("punk") - red = rand (0, 255) - green = rand (0, 255) - blue = rand (0, 255) - - red = max(min(red + rand (-25, 25), 255), 0) - green = max(min(green + rand (-25, 25), 255), 0) - blue = max(min(blue + rand (-25, 25), 255), 0) - - switch(target) - if("hair") - r_hair = red - g_hair = green - b_hair = blue - if("facial") - r_facial = red - g_facial = green - b_facial = blue - - proc/randomize_eyes_color() - var/red - var/green - var/blue - - var/col = pick ("black", "grey", "brown", "chestnut", "blue", "lightblue", "green", "albino") - switch(col) - if("black") - red = 0 - green = 0 - blue = 0 - if("grey") - red = rand (100, 200) - green = red - blue = red - if("brown") - red = 102 - green = 51 - blue = 0 - if("chestnut") - red = 153 - green = 102 - blue = 0 - if("blue") - red = 51 - green = 102 - blue = 204 - if("lightblue") - red = 102 - green = 204 - blue = 255 - if("green") - red = 0 - green = 102 - blue = 0 - if("albino") - red = rand (200, 255) - green = rand (0, 150) - blue = rand (0, 150) - - red = max(min(red + rand (-25, 25), 255), 0) - green = max(min(green + rand (-25, 25), 255), 0) - blue = max(min(blue + rand (-25, 25), 255), 0) - - r_eyes = red - g_eyes = green - b_eyes = blue - - proc/update_preview_icon() //seriously. This is horrendous. del(preview_icon_front) del(preview_icon_side) @@ -136,10 +26,7 @@ datum/preferences preview_icon = new /icon('icons/mob/human.dmi', "body_[g]_s") // Skin tone - if (s_tone >= 0) - preview_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD) - else - preview_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT) + preview_icon.Blend("#[skin_tones[s_tone]]", ICON_MULTIPLY) if(underwear) var/datum/sprite_accessory/underwear/U = underwear_all[underwear] @@ -147,18 +34,18 @@ datum/preferences preview_icon.Blend(new /icon(U.icon, "[U.icon_state]_s"), ICON_OVERLAY) var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = "eyes_s") - eyes_s.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD) + eyes_s.Blend("#[eye_color]", ICON_ADD) var/datum/sprite_accessory/hair_style = hair_styles_list[h_style] if(hair_style) var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - hair_s.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD) + hair_s.Blend("#[h_color]", ICON_ADD) eyes_s.Blend(hair_s, ICON_OVERLAY) var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style] if(facial_hair_style) var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD) + facial_s.Blend("#[f_color]", ICON_ADD) eyes_s.Blend(facial_s, ICON_OVERLAY) var/icon/clothes_s = null diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 3eeb5685334..dc14043b5e9 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -26,9 +26,7 @@ O.name = "monkey" O.dna = dna dna = null - O.dna.uni_identity = "00600200A00E0110148FC01300B009" - //O.dna.struc_enzymes = "0983E840344C39F4B059D5145FC5785DC6406A4BB8" - O.dna.struc_enzymes = "[copytext(O.dna.struc_enzymes,1,1+3*13)]BB8" + O.dna.struc_enzymes = setblock(O.dna.struc_enzymes, RACEBLOCK, construct_block(BAD_MUTATION_DIFFICULTY,BAD_MUTATION_DIFFICULTY)) O.loc = loc O.viruses = viruses viruses = list() diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 728ad546191..82defac7c71 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -59,7 +59,8 @@ M << "Your meaty finger is much too large for the trigger guard!" return if(ishuman(user)) - if(user.dna && user.dna.mutantrace == "adamantine") + var/mob/living/carbon/human/H = user + if(H.dna && H.dna.mutantrace == "adamantine") user << "Your metal fingers don't fit in the trigger guard!" return diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 1d30005f0b1..f0da51b9224 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -78,8 +78,8 @@ flag = "energy" on_hit(var/atom/target, var/blocked = 0) - var/mob/living/M = target - if(ishuman(target) && M.dna && M.dna.mutantrace == "plant") //Plantmen possibly get mutated and damaged by the rays. + var/mob/living/carbon/M = target + if(check_dna_integrity(M) && M.dna.mutantrace == "plant") //Plantmen possibly get mutated and damaged by the rays. if(prob(15)) M.apply_effect((rand(30,80)),IRRADIATE) M.Weaken(5) @@ -99,12 +99,10 @@ M.show_message("\red The radiation beam singes you!") // for (var/mob/V in viewers(src)) // V.show_message("\red [M] is singed by the radiation beam.", 3, "\red You hear the crackle of burning leaves.", 2) - else if(istype(target, /mob/living/carbon/)) + else // for (var/mob/V in viewers(src)) // V.show_message("The radiation beam dissipates harmlessly through [M]", 3) M.show_message("\blue The radiation beam dissipates harmlessly through your body.") - else - return 1 /obj/item/projectile/energy/florayield name = "beta somatoray" @@ -114,13 +112,12 @@ nodamage = 1 flag = "energy" - on_hit(var/atom/target, var/blocked = 0) - var/mob/M = target - if(ishuman(target) && M.dna && M.dna.mutantrace == "plant") //These rays make plantmen fat. - if(M.nutrition < 500) //sanity check - M.nutrition += 30 - else if (istype(target, /mob/living/carbon/)) - M.show_message("\blue The radiation beam dissipates harmlessly through your body.") + on_hit(mob/living/carbon/target, var/blocked = 0) + if(iscarbon(target)) + if(ishuman(target) && target.dna && target.dna.mutantrace == "plant") //These rays make plantmen fat. + target.nutrition = min(target.nutrition+30, 500) + else + target.show_message("\blue The radiation beam dissipates harmlessly through your body.") else return 1 diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 70061e29bea..5ee22062017 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -1302,21 +1302,19 @@ datum color = "#13BC5E" // rgb: 19, 188, 94 toxpwr = 0 - reaction_mob(var/mob/M, var/method=TOUCH, var/volume) + reaction_mob(var/mob/living/carbon/M, var/method=TOUCH, var/volume) if(!..()) return - if(!M.dna) return //No robots, AIs, aliens, Ians or other mobs should be affected by this. + if(!istype(M) || !M.dna) return //No robots, AIs, aliens, Ians or other mobs should be affected by this. src = null if((method==TOUCH && prob(33)) || method==INGEST) randmuti(M) - if(prob(98)) - randmutb(M) - else - randmutg(M) + if(prob(98)) randmutb(M) + else randmutg(M) domutcheck(M, null) - updateappearance(M,M.dna.uni_identity) + updateappearance(M) return - on_mob_life(var/mob/living/M as mob) - if(!M.dna) return //No robots, AIs, aliens, Ians or other mobs should be affected by this. + on_mob_life(var/mob/living/carbon/M) + if(!istype(M)) return if(!M) M = holder.my_atom M.apply_effect(10,IRRADIATE,0) ..() diff --git a/code/unused/dna_mutations.dm b/code/unused/dna_mutations.dm index 205798cd6ff..b03fb6257ea 100644 --- a/code/unused/dna_mutations.dm +++ b/code/unused/dna_mutations.dm @@ -94,8 +94,8 @@ mob/verb/checkmuts() src << "Required ID: [R.reqID]" src << "" -mob/verb/editSE(t as text) - src:dna:struc_enzymes = t +mob/living/carbon/verb/editSE(t as text) + dna.struc_enzymes = t domutcheck(src) */ diff --git a/code/unused/pda2/base_program.dm b/code/unused/pda2/base_program.dm index f5c11efc077..ab06e16f806 100644 --- a/code/unused/pda2/base_program.dm +++ b/code/unused/pda2/base_program.dm @@ -9,7 +9,7 @@ name = "record" extension = "REC" - var/list/fields = list( ) + var/list/fields = list() //base pda program diff --git a/code/unused/specops.dm b/code/unused/specops.dm index 1c8cc989c92..1c267f2172f 100644 --- a/code/unused/specops.dm +++ b/code/unused/specops.dm @@ -111,7 +111,7 @@ var/global/sent_strike_team = 0 A.real_name = "[!leader_selected ? commando_rank : A.copy_to(new_commando) - new_commando.dna.ready_dna(new_commando)//Creates DNA. + ready_dna(new_commando) //Creates mind stuff. new_commando.mind_initialize() diff --git a/code/unused/tensioner.dm b/code/unused/tensioner.dm index eba4083ea96..064b1629353 100644 --- a/code/unused/tensioner.dm +++ b/code/unused/tensioner.dm @@ -768,7 +768,7 @@ var/global/datum/tension/tension_master var/datum/preferences/A = new() A.copy_to(new_character) - new_character.dna.ready_dna(new_character) + ready_dna(new_character) new_character.key = G_found.key return new_character @@ -787,8 +787,7 @@ var/global/datum/tension/tension_master A.real_name = "[syndicate_commando_rank] [syndicate_commano_name]" A.copy_to(new_syndicate_commando) - - new_syndicate_commando.dna.ready_dna(new_syndicate_commando)//Creates DNA. + ready_dna(new_syndicate_commando) //Creates mind stuff. new_syndicate_commando.mind_initialize() diff --git a/code/world.dm b/code/world.dm index 758585776a2..c7fa563a996 100644 --- a/code/world.dm +++ b/code/world.dm @@ -10,10 +10,10 @@ /world/New() //logs var/date_string = time2text(world.realtime, "YYYY/MM-Month/DD-Day") - if(revdata && istext(revdata.revision) && length(revdata.revision)>7) - log = file("data/logs/runtime/[copytext(revdata.revision,1,8)].log") - else - log = file("data/logs/runtime/[time2text(world.realtime,"YYYY-MM")].log") //funtimelog +// if(revdata && istext(revdata.revision) && length(revdata.revision)>7) +// log = file("data/logs/runtime/[copytext(revdata.revision,1,8)].log") +// else +// log = file("data/logs/runtime/[time2text(world.realtime,"YYYY-MM")].log") //funtimelog href_logfile = file("data/logs/[date_string] hrefs.htm") diary = file("data/logs/[date_string].log") diaryofmeanpeople = file("data/logs/[date_string] Attack.log") diff --git a/html/changelog.html b/html/changelog.html index 8be38ccc45b..434be3912c6 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -49,7 +49,14 @@ should be listed in the changelog upon commit tho. Thanks. --> - +
+

24 April 2013

+

Carnie updated:

+
    +
  • DNA reworked: All SE blocks are randomised. DNA-modifier emitter strength affects the size of the change in the hex-character hit. Emitter duration makes it more likely to hit the character you click on. Almost all DNA-modifier functions are on one screen.
    Balancing -will- be off a bit. Is getting halk to hard/easy? Please report bugs/balancing issues/concerns here: http://forums.nanotrasen.com/viewtopic.php?f=15&t=13083 <3
  • +
+
+

22 April 2013

Cheridan updated:

diff --git a/icons/mob/human.dmi b/icons/mob/human.dmi index afac50b3dc7c7b7b897c6a0bd6ca35cfeb2eac2c..2edfe8382e8fc67a1b37b0e264a69e533d17bafb 100644 GIT binary patch literal 11483 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 diff --git a/maps/tgstation.2.1.2.dmm b/maps/tgstation.2.1.2.dmm index 85668d59a57..3ca733cf62c 100644 --- a/maps/tgstation.2.1.2.dmm +++ b/maps/tgstation.2.1.2.dmm @@ -7088,7 +7088,7 @@ "cGp" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor,/area/derelict/arrival) "cGq" = (/obj/machinery/light/small,/turf/simulated/floor{icon_state = "dark"},/area/derelict/medical/chapel) "cGr" = (/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) -"cGs" = (/obj/item/weapon/disk/data/demo,/turf/simulated/floor/plating/airless,/area) +"cGs" = (/turf/simulated/floor/plating/airless,/area) "cGt" = (/turf/simulated/floor/airless{icon_state = "damaged4"},/area) "cGu" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor,/area/derelict/arrival) "cGv" = (/obj/structure/stool/bed/chair{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor,/area/derelict/arrival) From 7ca4c39ec0e3043b38c8057b770100bc35b86775 Mon Sep 17 00:00:00 2001 From: carnie Date: Thu, 25 Apr 2013 05:09:43 +0100 Subject: [PATCH 2/3] Added spacing between blocks in the DNA-modifier interface. --- code/game/dna.dm | 59 +++++++++++------------------------------------- 1 file changed, 13 insertions(+), 46 deletions(-) diff --git a/code/game/dna.dm b/code/game/dna.dm index 7cdc41530c5..43bcc87bcfc 100644 --- a/code/game/dna.dm +++ b/code/game/dna.dm @@ -136,39 +136,16 @@ if(blocknumber < (length(input)/blocksize)) return copytext(input,blocksize*blocknumber+1,length(input)+1) -/* -/proc/getblockstring(input,block,subblock,blocksize,src,ui) // src is probably used here just for urls; ui is 1 when requesting for the unique identifier screen, 0 for structural enzymes screen - . = "
" - var/subpos = 1 // keeps track of the current sub block - var/blockpos = 1 // keeps track of the current block - - for(var/i = 1, i <= length(input), i++) // loop through each letter - if(subpos == subblock && blockpos == block) // if the current block/subblock is selected, mark it - . += "[copytext(input, i, i+1)]" - else - . += "[copytext(input, i, i+1)]" - - if(subpos >= blocksize) // add a line break for every block - . += "
" - subpos = 0 - blockpos++ - subpos++ - - . += "
" - return . -*/ - - /proc/getblock(input, blocknumber, blocksize=DNA_BLOCK_SIZE) return copytext(input, blocksize*(blocknumber-1)+1, (blocksize*blocknumber)+1) - +/* /proc/getblockbuffer(input,blocknumber,blocksize) var/result[blocksize] var/start = (blocksize*blocknumber)-blocksize for(var/i=1, i<=blocksize, i++) result[i] = copytext(input, start+i, start+i+1) return result - +*/ /proc/setblock(istring, blocknumber, replacement, blocksize=DNA_BLOCK_SIZE) if(!istring || !blocknumber || !replacement || !blocksize) return 0 return getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize) @@ -539,12 +516,7 @@ usr.loc = src occupant = usr icon_state = "scanner_1" - /* - for(var/obj/O in src) // THIS IS P. STUPID -- LOVE, DOOHL - //O = null - del(O) - //Foreach goto(124) - */ + add_fingerprint(usr) return @@ -588,13 +560,7 @@ /obj/machinery/dna_scannernew/proc/go_out() if(!occupant || locked) return -/* -// it's like this was -just- here to break constructed dna scanners -Pete -// if that's not the case, slap my shit and uncomment this. -// for(var/obj/O in src) -// O.loc = loc -*/ - //Foreach goto(30) + if(occupant.client) occupant.client.eye = occupant.client.mob occupant.client.perspective = MOB_PERSPECTIVE @@ -609,8 +575,6 @@ for(var/atom/movable/A as mob|obj in src) A.loc = loc ex_act(severity) - //Foreach goto(35) - //SN src = null del(src) return if(2.0) @@ -618,8 +582,6 @@ for(var/atom/movable/A as mob|obj in src) A.loc = loc ex_act(severity) - //Foreach goto(108) - //SN src = null del(src) return if(3.0) @@ -627,8 +589,6 @@ for(var/atom/movable/A as mob|obj in src) A.loc = loc ex_act(severity) - //Foreach goto(181) - //SN src = null del(src) return else @@ -707,12 +667,10 @@ switch(severity) if(1.0) - //SN src = null del(src) return if(2.0) if(prob(50)) - //SN src = null del(src) return else @@ -892,10 +850,15 @@ temp_html += "
" temp_html += "
Unique Identifier:
" + var/max_line_len = DNA_BLOCK_SIZE * 10 if(viable_occupant) var/len = length(viable_occupant.dna.uni_identity) for(var/i=1, i<=len, i++) temp_html += "[copytext(viable_occupant.dna.uni_identity,i,i+1)]" + if((i % max_line_len) == 0) + temp_html += "
" + else if((i % DNA_BLOCK_SIZE) == 0) + temp_html += " " else temp_html += " - " temp_html += "
" @@ -905,6 +868,10 @@ var/len = length(viable_occupant.dna.struc_enzymes) for(var/i=1, i<=len, i++) temp_html += "[copytext(viable_occupant.dna.struc_enzymes,i,i+1)]" + if((i % max_line_len) == 0) + temp_html += "
" + else if((i % DNA_BLOCK_SIZE) == 0) + temp_html += " " else temp_html += " - " temp_html += "
" From fea2fc3fef5bb0d35ae4ee0b28e05cf390289435 Mon Sep 17 00:00:00 2001 From: carnie Date: Sat, 27 Apr 2013 06:40:17 +0100 Subject: [PATCH 3/3] Fixes for admin-spawned dnainjectors: repeat_string has been simplified (it wasn't making NULLED_SE and NULLED_UI to the correct size). Fix for Overpowered mutations (HULK and TELE) not manifesting. A typo was the cause. Admin-spawnable injectors always succeed. This code already existed (I believe this is how they used to function), but it did not work as the argument was not passed correctly. This also removed snowflake code for the darkbundle telemut injector. Thanks to Giacom, wouldn't have found these without him. --- code/__HELPERS/text.dm | 13 ++++--------- code/game/dna.dm | 4 ++-- code/game/gamemodes/setupgame.dm | 4 ++-- code/game/objects/items/weapons/dna_injector.dm | 5 +---- 4 files changed, 9 insertions(+), 17 deletions(-) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index ead4290bfde..88c1be1a59d 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -340,15 +340,10 @@ var/list/binary = list("0","1") for(var/i=1, i<=length, i++) . += pick(characters) -/proc/repeat_string(length, string="") - var/len = length(string) - if(!len) return string - while(len
" @@ -227,9 +227,6 @@ /obj/item/weapon/dnainjector/telemut/darkbundle name = "\improper DNA injector" desc = "Good. Let the hate flow through you." -/obj/item/weapon/dnainjector/telemut/darkbundle/attack(mob/M, mob/user) - ..() - domutcheck(M,null) //guarantees that it works instead of getting a dud injector. /obj/item/weapon/dnainjector/deafmut name = "\improper DNA injector (Deaf)"