From 5869a3fc38f1045246bc67c4533ced95d4256be7 Mon Sep 17 00:00:00 2001 From: RKF45 Date: Fri, 7 Feb 2014 23:28:40 +0100 Subject: [PATCH 01/53] PDA bombs are now more balanced and random. --- code/game/objects/items/devices/PDA/PDA.dm | 157 ++++++++++++++++----- 1 file changed, 121 insertions(+), 36 deletions(-) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 09300be121..18e85a0dda 100755 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -41,7 +41,7 @@ var/global/list/obj/item/device/pda/PDAs = list() var/active_conversation = null // New variable that allows us to only view a single conversation. var/list/conversations = list() // For keeping up with who we have PDA messsages from. var/newmessage = 0 //To remove hackish overlay check - + var/obj/item/weapon/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both. var/ownjob = null //related to above @@ -321,7 +321,7 @@ var/global/list/obj/item/device/pda/PDAs = list() /obj/item/device/pda/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null) var/title = "Personal Data Assistant" - + var/data[0] // This is the data that will be sent to the PDA @@ -336,7 +336,7 @@ var/global/list/obj/item/device/pda/PDAs = list() data["silent"] = silent // does the pda make noise when it receives a message? data["toff"] = toff // is the messenger function turned off? data["active_conversation"] = active_conversation // Which conversation are we following right now? - + data["idInserted"] = (id ? 1 : 0) data["idLink"] = (id ? text("[id.registered_name], [id.assignment]") : "--------") @@ -375,10 +375,10 @@ var/global/list/obj/item/device/pda/PDAs = list() cartdata["type"] = cartridge.type cartdata["charges"] = cartridge.charges ? cartridge.charges : 0 data["cartridge"] = cartdata - + data["stationTime"] = worldtime2text() data["newMessage"] = newmessage - + if(mode==2) var/convopdas[0] var/pdas[0] @@ -388,7 +388,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if(conversations.Find("\ref[P]")) convopdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "1"))) else - pdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "0"))) + pdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "0"))) count++ data["convopdas"] = convopdas @@ -411,7 +411,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if(mode==41) data["manifest"] = data_core.get_manifest_json() - + if(mode==3) var/turf/T = get_turf_or_move(user.loc) if(!isnull(T) || mode!=3) @@ -438,15 +438,15 @@ var/global/list/obj/item/device/pda/PDAs = list() ) if(isnull(data["aircontents"])) data["aircontents"] = list("reading" = 0) - + // update the ui if it exists, returns null if no ui is passed/found - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data) + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data) if (!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm ui = new(user, src, ui_key, "pda.tmpl", title, 630, 600) // when the ui is first opened this is the data it will use - ui.set_initial_data(data) + ui.set_initial_data(data) // open the new ui window ui.open() // auto update every Master Controller tick @@ -484,17 +484,17 @@ var/global/list/obj/item/device/pda/PDAs = list() U.unset_machine() ui.close() return 0 - + add_fingerprint(U) U.set_machine(src) switch(href_list["choice"]) - + //BASIC FUNCTIONS=================================== if("Close")//Self explanatory U.unset_machine() - ui.close() + ui.close() return 0 if("Refresh")//Refresh, goes to the end of the proc. if("Return")//Return @@ -518,7 +518,7 @@ var/global/list/obj/item/device/pda/PDAs = list() var/turf/T = loc if(ismob(T)) T = T.loc - cartridge.loc = T + cartridge.loc = T mode = 0 scanmode = 0 if (cartridge.radio) @@ -681,14 +681,14 @@ var/global/list/obj/item/device/pda/PDAs = list() else M.close() - if("Detonate")//Detonate PDA + if("Detonate")//Detonate PDA... maybe if(istype(cartridge, /obj/item/weapon/cartridge/syndicate)) var/obj/item/device/pda/P = locate(href_list["target"]) if(!isnull(P)) if (!P.toff && cartridge.charges > 0) cartridge.charges-- - var/difficulty = 0 + var/difficulty = 2 if(P.cartridge) difficulty += P.cartridge.access_medical @@ -696,22 +696,23 @@ var/global/list/obj/item/device/pda/PDAs = list() difficulty += P.cartridge.access_engine difficulty += P.cartridge.access_clown difficulty += P.cartridge.access_janitor - else - difficulty += 2 + difficulty += 3 * P.hidden_uplink - if(prob(difficulty * 12) || (P.hidden_uplink)) + if(prob(difficulty)) U.show_message("\red An error flashes on your [src].", 1) - else if (prob(difficulty * 3)) + else if (prob(difficulty * 7)) U.show_message("\red Energy feeds back into your [src]!", 1) ui.close() - explode() + detonate_act(src) log_admin("[key_name(U)] just attempted to blow up [P] with the Detomatix cartridge but failed, blowing themselves up") - message_admins("[key_name_admin(U)] just attempted to blow up [P] with the Detomatix cartridge but failed, blowing themselves up", 1) + message_admins("[key_name_admin(U)] just attempted to blow up [P] with the Detomatix cartridge but failed.", 1) else U.show_message("\blue Success!", 1) - log_admin("[key_name(U)] just attempted to blow up [P] with the Detomatix cartridge and succeded") - message_admins("[key_name_admin(U)] just attempted to blow up [P] with the Detomatix cartridge and succeded", 1) - P.explode() + log_admin("[key_name(U)] just attempted to blow up [P] with the Detomatix cartridge and succeeded") + message_admins("[key_name_admin(U)] just attempted to blow up [P] with the Detomatix cartridge and succeeded.", 1) + detonate_act(P) + else + U << "No charges left." else U << "PDA not found." else @@ -747,6 +748,90 @@ var/global/list/obj/item/device/pda/PDAs = list() return 1 // return 1 tells it to refresh the UI in NanoUI +/obj/item/device/pda/proc/detonate_act(var/obj/item/device/pda/P) + //TODO: sometimes these attacks show up on the message server? + var/i = rand(1,100) + var/j = rand(0,1) //Possibility of losing the PDA after the detonation + var/message = "" + var/mob/living/M = null + if(ismob(P.loc)) + M = P.loc + + //switch(i) //Yes, the overlapping cases are intended. + if(i<=10) //The traditional explosion + P.explode() + message += "Your [P] suddenly explodes!" + if(i>=10 && i<= 20) //The PDA burns a hole in the holder. + j=1 + if(M && isliving(M)) + M.apply_damage( rand(30,60) , BURN) + message += "You feels a searing heat! Your [P] is burning!" + if(i>=20 && i<=25) //EMP + empulse(P.loc, 3, 6, 1) + message += "Your [P] emits a wave of electomagnetic energy!" + if(i>=25 && i<=40) //Smoke + var/datum/effect/effect/system/smoke_spread/chem/S = new /datum/effect/effect/system/smoke_spread/chem + S.attach(P.loc) + S.set_up(P, 10, 0, P.loc) + playsound(P.loc, 'sound/effects/smoke.ogg', 50, 1, -3) + S.start() + message += "Large clouds of smoke billow forth from your [P]!" + if(i>=40 && i<=45) //Bad smoke + var/datum/effect/effect/system/smoke_spread/bad/B = new /datum/effect/effect/system/smoke_spread/bad + B.attach(P.loc) + B.set_up(P, 10, 0, P.loc) + playsound(P.loc, 'sound/effects/smoke.ogg', 50, 1, -3) + B.start() + message += "Large clouds of noxious smoke billow forth from your [P]!" + if(i>=45 && i<= 50) //Mustard gas + var/datum/effect/effect/system/smoke_spread/mustard/Q = new /datum/effect/effect/system/smoke_spread/mustard + Q.attach(P.loc) + Q.set_up(P, 10, 0, P.loc) + playsound(P.loc, 'sound/effects/smoke.ogg', 50, 1, -3) + Q.start() + message += "Large clouds of yellowish smoke billow forth from your [P]!" + if(i>=50 && i<=55) //Sleepy gas + var/datum/effect/effect/system/smoke_spread/sleepy/G = new /datum/effect/effect/system/smoke_spread/sleepy + G.attach(P.loc) + G.set_up(P, 10, 0, P.loc) + playsound(P.loc, 'sound/effects/smoke.ogg', 50, 1, -3) + G.start() + message += "Large clouds of eerie smoke billow forth from your [P]!" + if(i>=55 && i<=60) //Foam + var/datum/effect/effect/system/foam_spread/f = new() + f.set_up(20, P.loc, P, 0) + f.start() + message += "Foam starts to bubble from your [P]!" + if(i>=60 && i<=65) //Metal foam + var/datum/effect/effect/system/foam_spread/K = new() + K.set_up(20, P.loc, P, 1) + K.start() + message += "Dense foam starts to ooze from your [P]!" + if(i>=65 && i<=75) //Weaken + if(M && isliving(M)) + M.apply_effects(0,1) + message += "Your [P] flashes with a blinding white light! You feel weaker." + if(i>=75 && i<=85) //Stun and stutter + if(M && isliving(M)) + M.apply_effects(1,0,0,0,1) + message += "Your [P] flashes with a blinding white light! You feel weaker." + if(i>=85) //Sparks + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, P.loc) + s.start() + message += "Your [P] begins to spark violently!" + + if(j) //This kills the PDA + P.Del() + if(message) + message += "It melts in a puddle of plastic." + else + message += "Your [P] shatters in a thousand pieces!" + + if(M && isliving(M)) + message = "\red" + message + M.show_message(message, 1) + /obj/item/device/pda/proc/remove_id() if (id) if (ismob(loc)) @@ -774,7 +859,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if(!can_use()) return - + last_text = world.time // check if telecomms I/O route 1459 is stable //var/telecomms_intact = telecomms_process(P.owner, owner, t) @@ -821,7 +906,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if(ai.aiPDA != P && ai.aiPDA != src) ai.show_message("Intercepted message from [who]: [t]") - + if (!P.silent) playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1) for (var/mob/O in hearers(3, P.loc)) @@ -838,7 +923,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if(L) L << "\icon[P] Message from [src.owner] ([ownjob]), \"[t]\" (Reply)" nanomanager.update_user_uis(L, P) // Update the recieving user's PDA UI so that they can see the new message - + nanomanager.update_user_uis(U, P) // Update the sending user's PDA UI so that they can see the new message log_pda("[usr] (PDA: [src.name]) sent \"[t]\" to [P.name]") @@ -920,7 +1005,7 @@ var/global/list/obj/item/device/pda/PDAs = list() user << "You insert [cartridge] into [src]." nanomanager.update_uis(src) // update all UIs attached to src if(cartridge.radio) - cartridge.radio.hostpda = src + cartridge.radio.hostpda = src else if(istype(C, /obj/item/weapon/card/id)) var/obj/item/weapon/card/id/idcard = C @@ -1094,20 +1179,20 @@ var/global/list/obj/item/device/pda/PDAs = list() user << "\blue Paper scanned." //concept of scanning paper copyright brainoblivion 2009 -/obj/item/device/pda/proc/explode() //This needs tuning. +/obj/item/device/pda/proc/explode() //This needs tuning. //Sure did. if(!src.detonate) return var/turf/T = get_turf(src.loc) - if (ismob(loc)) var/mob/M = loc M.show_message("\red Your [src] explodes!", 1) - if(T) T.hotspot_expose(700,125) - - explosion(T, -1, -1, 2, 3) - - del(src) + explosion(T, 0, 0, 1, rand(1,2)) + if(prob(90)) //IDs are kept in 90% of the cases + Del() + else + PDAs -= src + del(src) return /obj/item/device/pda/Del() From 054df7a28b43d426df83175a315ead0a8e8a11d4 Mon Sep 17 00:00:00 2001 From: RKF45 Date: Mon, 10 Feb 2014 21:14:04 +0100 Subject: [PATCH 02/53] Keeping the PDA sane. --- code/game/objects/items/devices/PDA/PDA.dm | 31 ++++------------------ 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 18e85a0dda..e9d865ba20 100755 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -749,7 +749,7 @@ var/global/list/obj/item/device/pda/PDAs = list() return 1 // return 1 tells it to refresh the UI in NanoUI /obj/item/device/pda/proc/detonate_act(var/obj/item/device/pda/P) - //TODO: sometimes these attacks show up on the message server? + //TODO: sometimes these attacks show up on the message server var/i = rand(1,100) var/j = rand(0,1) //Possibility of losing the PDA after the detonation var/message = "" @@ -765,7 +765,7 @@ var/global/list/obj/item/device/pda/PDAs = list() j=1 if(M && isliving(M)) M.apply_damage( rand(30,60) , BURN) - message += "You feels a searing heat! Your [P] is burning!" + message += "You feel a searing heat! Your [P] is burning!" if(i>=20 && i<=25) //EMP empulse(P.loc, 3, 6, 1) message += "Your [P] emits a wave of electomagnetic energy!" @@ -783,30 +783,6 @@ var/global/list/obj/item/device/pda/PDAs = list() playsound(P.loc, 'sound/effects/smoke.ogg', 50, 1, -3) B.start() message += "Large clouds of noxious smoke billow forth from your [P]!" - if(i>=45 && i<= 50) //Mustard gas - var/datum/effect/effect/system/smoke_spread/mustard/Q = new /datum/effect/effect/system/smoke_spread/mustard - Q.attach(P.loc) - Q.set_up(P, 10, 0, P.loc) - playsound(P.loc, 'sound/effects/smoke.ogg', 50, 1, -3) - Q.start() - message += "Large clouds of yellowish smoke billow forth from your [P]!" - if(i>=50 && i<=55) //Sleepy gas - var/datum/effect/effect/system/smoke_spread/sleepy/G = new /datum/effect/effect/system/smoke_spread/sleepy - G.attach(P.loc) - G.set_up(P, 10, 0, P.loc) - playsound(P.loc, 'sound/effects/smoke.ogg', 50, 1, -3) - G.start() - message += "Large clouds of eerie smoke billow forth from your [P]!" - if(i>=55 && i<=60) //Foam - var/datum/effect/effect/system/foam_spread/f = new() - f.set_up(20, P.loc, P, 0) - f.start() - message += "Foam starts to bubble from your [P]!" - if(i>=60 && i<=65) //Metal foam - var/datum/effect/effect/system/foam_spread/K = new() - K.set_up(20, P.loc, P, 1) - K.start() - message += "Dense foam starts to ooze from your [P]!" if(i>=65 && i<=75) //Weaken if(M && isliving(M)) M.apply_effects(0,1) @@ -820,6 +796,9 @@ var/global/list/obj/item/device/pda/PDAs = list() s.set_up(2, 1, P.loc) s.start() message += "Your [P] begins to spark violently!" + if(i>45 && i<65 && prob(50)) //Nothing happens + message += "Your [P] bleeps loudly." + j = prob(10) if(j) //This kills the PDA P.Del() From 108888879188cb45fd739635bdb77ed8e0c2fb7f Mon Sep 17 00:00:00 2001 From: Rob Nelson Date: Thu, 19 Dec 2013 08:15:42 -0800 Subject: [PATCH 03/53] DNA2 EPISODE 2: Revenge of the Bugs Made after DNA2 hit /vg/'s main server after no one tested anything. * Gene activation/deactivation made modular, refactors domutcheck. * Standardized genetics disks and injectors a bit in response to buffer corruption issues. (Untested) * Lots of major bug fixes. * Skin tones fixed. Still needs further testing. All I did was mess around with monkeys. Conflicts: code/game/dna/dna2.dm code/game/dna/dna2_domutcheck.dm code/game/dna/dna2_helpers.dm code/game/dna/genes/disabilities.dm code/game/dna/genes/powers.dm code/modules/mob/living/carbon/monkey/monkey.dm --- baystation12.int | 5 +++++ code/game/dna/dna2.dm | 6 +++++- code/game/dna/dna2_domutcheck.dm | 3 --- code/game/dna/dna2_helpers.dm | 5 +---- code/game/dna/genes/disabilities.dm | 10 +++++----- code/game/dna/genes/powers.dm | 2 +- code/modules/mob/living/carbon/monkey/monkey.dm | 2 +- 7 files changed, 18 insertions(+), 15 deletions(-) diff --git a/baystation12.int b/baystation12.int index b82874fded..fb3d85be3c 100644 --- a/baystation12.int +++ b/baystation12.int @@ -1,6 +1,11 @@ // BEGIN_INTERNALS /* MAP_ICON_TYPE: 0 +WINDOW: code\__HELPERS\unsorted.dm;code\game\dna\dna2.dm;code\game\dna\dna2_domutcheck.dm;code\game\dna\dna2_helpers.dm;code\game\dna\dna_modifier.dm;code\game\machinery\cloning.dm;code\game\objects\items\weapons\dna_injector.dm;code\game\dna\genes\disabilities.dm;code\game\gamemodes\setupgame.dm;code\setup.dm;code\global.dm +LAST_COMPILE_VERSION: 501.1217 +DIR: code code\game code\game\dna code\game\dna\genes code\game\gamemodes code\game\objects code\game\objects\items code\game\objects\items\weapons +FILE: code\game\objects\items\weapons\dna_injector.dm +LAST_COMPILE_TIME: 1387468589 AUTO_FILE_DIR: OFF */ // END_INTERNALS diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index e8f4ddc4a8..74d8a66148 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -46,6 +46,9 @@ var/global/list/datum/dna/gene/dna_genes[0] ///////////////// // GENE DEFINES ///////////////// +// Skip checking if it's already active. +// Used for genes that check for value rather than a binary on/off. +#define GENE_ALWAYS_ACTIVATE 1 // Skip checking if it's already active. // Used for genes that check for value rather than a binary on/off. @@ -75,6 +78,7 @@ var/global/list/datum/dna/gene/dna_genes[0] // New stuff var/species = "Human" +/* // Make a copy of this strand. // USE THIS WHEN COPYING STUFF OR YOU'LL GET CORRUPTION! /datum/dna/proc/Clone() @@ -91,7 +95,7 @@ var/global/list/datum/dna/gene/dna_genes[0] new_dna.UpdateUI() new_dna.UpdateSE() return new_dna - +/* /////////////////////////////////////// // UNIQUE IDENTITY /////////////////////////////////////// diff --git a/code/game/dna/dna2_domutcheck.dm b/code/game/dna/dna2_domutcheck.dm index a53fc49c29..3327d700f4 100644 --- a/code/game/dna/dna2_domutcheck.dm +++ b/code/game/dna/dna2_domutcheck.dm @@ -40,9 +40,6 @@ //else // testing("[M] - Failed to activate [gene.name] - [gene_active?"+":"-"]active, [gene_prior_status?"+":"-"]prior") - - // PROC CONTINUES BELOW AFTER COMMENTED CODE. - /* Old, inflexibile /proc/domutcheck(var/mob/living/M, var/connected, var/flags) if (!M) return diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 216832f3cf..6f180993fb 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -143,8 +143,7 @@ H.g_eyes = dna.GetUIValueRange(DNA_UI_EYES_G, 255) H.b_eyes = dna.GetUIValueRange(DNA_UI_EYES_B, 255) - var/new_s_tone = dna.GetUIValueRange(DNA_UI_SKIN_TONE, 220) - H.s_tone = 35 - max(min( round(new_s_tone), 220),1) //Warning MATH. Blame the person that wrote modules/client/preferences.dm, line 994 + H.s_tone = 35 - dna.GetUIValueRange(DNA_UI_SKIN_TONE, 220) // Value can be negative. if (dna.GetUIState(DNA_UI_GENDER)) H.gender = FEMALE @@ -171,5 +170,3 @@ // Used below, simple injection modifier. /proc/probinj(var/pr, var/inj) return prob(pr+inj*pr) - -/////////////////////////// DNA MISC-PROCS diff --git a/code/game/dna/genes/disabilities.dm b/code/game/dna/genes/disabilities.dm index e312111f6f..a06a3a0364 100644 --- a/code/game/dna/genes/disabilities.dm +++ b/code/game/dna/genes/disabilities.dm @@ -32,7 +32,7 @@ M.mutations.Add(mutation) if(disability) M.disabilities|=disability - if(sdisability) + if(mutation) M.sdisabilities|=sdisability if(activation_message) M << "\red [activation_message]" @@ -41,9 +41,9 @@ if(mutation && (mutation in M.mutations)) M.mutations.Remove(mutation) if(disability) - M.disabilities &= ~disability - if(sdisability) - M.sdisabilities &= ~sdisability + M.disabilities-=disability + if(mutation) + M.sdisabilities-=sdisability if(deactivation_message) M << "\red [deactivation_message]" @@ -122,4 +122,4 @@ disability=NEARSIGHTED New() - block=GLASSESBLOCK \ No newline at end of file + block=GLASSESBLOCK diff --git a/code/game/dna/genes/powers.dm b/code/game/dna/genes/powers.dm index a8a9eefee7..9ac9f06b0d 100644 --- a/code/game/dna/genes/powers.dm +++ b/code/game/dna/genes/powers.dm @@ -164,4 +164,4 @@ activation_prob=15 New() - block=TELEBLOCK \ No newline at end of file + block=TELEBLOCK diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 42fbb8fa02..a37f16ff1a 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -14,7 +14,7 @@ //var/uni_append = "12C4E2" // Small appearance modifier for different species. var/list/uni_append = list(0x12C,0x4E2) // Same as above for DNA2. var/update_muts = 1 // Monkey gene must be set at start. - var/alien = 0 //Used for reagent metabolism. + var/alien = 0 //Used for reagent metabolism. /mob/living/carbon/monkey/tajara name = "farwa" From fa20b9c2ee198666d4a386aaba2277f14edcaf6a Mon Sep 17 00:00:00 2001 From: Rob Nelson Date: Thu, 6 Feb 2014 23:07:35 -0800 Subject: [PATCH 04/53] DNA2 Bug Fixes - Part 2 (CHERRY PICK) We discovered that most of the problems were were having was because of BYOND passing lists (e.g. SE and UI) by-ref instead of the assumed by-val. This commit adds dna.Clone() and (UI|SE).Copy() where needed. These should be used where DNA or SE/UI lists are COPIED, otherwise changes made in the reference will affect the real strand. This change also messes with the gene activation logic. Conflicts: code/game/dna/dna2_domutcheck.dm code/game/dna/genes/powers.dm --- code/datums/diseases/dna_spread.dm | 16 +- code/game/dna/dna2.dm | 39 +- code/game/dna/dna2_domutcheck.dm | 342 +----------------- code/game/dna/dna2_helpers.dm | 4 +- code/game/dna/dna_modifier.dm | 62 ++-- code/game/dna/genes/disabilities.dm | 4 + code/game/dna/genes/gene.dm | 52 ++- code/game/dna/genes/monkey.dm | 6 +- code/game/dna/genes/powers.dm | 30 +- .../gamemodes/changeling/changeling_powers.dm | 10 +- code/game/gamemodes/events.dm | 8 +- code/game/machinery/cloning.dm | 4 +- .../objects/items/weapons/dna_injector.dm | 4 +- code/modules/admin/admin.dm | 19 + code/modules/admin/verbs/debug.dm | 18 +- code/modules/admin/verbs/randomverbs.dm | 8 +- code/modules/events/disease_outbreak.dm | 4 +- .../mob/living/carbon/brain/brain_item.dm | 2 +- .../mob/living/carbon/human/update_icons.dm | 11 + code/modules/mob/mob_transformation_simple.dm | 2 +- code/modules/mob/transform_procs.dm | 7 +- code/modules/organs/organ_external.dm | 2 +- 22 files changed, 240 insertions(+), 414 deletions(-) diff --git a/code/datums/diseases/dna_spread.dm b/code/datums/diseases/dna_spread.dm index 69a8eb6500..a4d85a5640 100644 --- a/code/datums/diseases/dna_spread.dm +++ b/code/datums/diseases/dna_spread.dm @@ -39,12 +39,14 @@ //Save original dna for when the disease is cured. src.original_dna["name"] = affected_mob.real_name - src.original_dna["UI"] = affected_mob.dna.UI - src.original_dna["SE"] = affected_mob.dna.SE + src.original_dna["UI"] = affected_mob.dna.UI.Copy() + src.original_dna["SE"] = affected_mob.dna.SE.Copy() affected_mob << "\red You don't feel like yourself.." - affected_mob.UpdateAppearance(strain_data["UI"]) - affected_mob.dna.SE = strain_data["SE"] + var/list/newUI=strain_data["UI"] + var/list/newSE=strain_data["SE"] + affected_mob.UpdateAppearance(newUI.Copy()) + affected_mob.dna.SE = newSE.Copy() affected_mob.dna.UpdateSE() affected_mob.real_name = strain_data["name"] domutcheck(affected_mob) @@ -56,8 +58,10 @@ /datum/disease/dnaspread/Del() if ((original_dna["name"]) && (original_dna["UI"]) && (original_dna["SE"])) - affected_mob.UpdateAppearance(original_dna["UI"]) - affected_mob.dna.SE = original_dna["SE"] + var/list/newUI=original_dna["UI"] + var/list/newSE=original_dna["SE"] + affected_mob.UpdateAppearance(newUI.Copy()) + affected_mob.dna.SE = newSE.Copy() affected_mob.dna.UpdateSE() affected_mob.real_name = original_dna["name"] diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index 74d8a66148..1ebcbb4457 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -16,17 +16,6 @@ #define DNA_HARDER_BOUNDS list(1,3049,3050,4095) #define DNA_HARD_BOUNDS list(1,3490,3500,4095) -// Defines which values mean "on" or "off". -// This is to make some of the more OP superpowers a larger PITA to activate, -// and to tell our new DNA datum which values to set in order to turn something -// on or off. -var/global/list/dna_activity_bounds[STRUCDNASIZE] - -// Used to determine what each block means (admin hax and species stuff on /vg/, mostly) -var/global/list/assigned_blocks[STRUCDNASIZE] - -var/global/list/datum/dna/gene/dna_genes[0] - // UI Indices (can change to mutblock style, if desired) #define DNA_UI_HAIR_R 1 #define DNA_UI_HAIR_G 2 @@ -43,6 +32,22 @@ var/global/list/datum/dna/gene/dna_genes[0] #define DNA_UI_HAIR_STYLE 13 #define DNA_UI_LENGTH 13 // Update this when you add something, or you WILL break shit. +#define DNA_SE_LENGTH 27 +// For later: +//#define DNA_SE_LENGTH 50 // Was STRUCDNASIZE, size 27. 15 new blocks added = 42, plus room to grow. + + +// Defines which values mean "on" or "off". +// This is to make some of the more OP superpowers a larger PITA to activate, +// and to tell our new DNA datum which values to set in order to turn something +// on or off. +var/global/list/dna_activity_bounds[DNA_SE_LENGTH] + +// Used to determine what each block means (admin hax and species stuff on /vg/, mostly) +var/global/list/assigned_blocks[DNA_SE_LENGTH] + +var/global/list/datum/dna/gene/dna_genes[0] + ///////////////// // GENE DEFINES ///////////////// @@ -67,7 +72,7 @@ var/global/list/datum/dna/gene/dna_genes[0] // Okay to read, but you're an idiot if you do. // BLOCK = VALUE - var/list/SE[STRUCDNASIZE] + var/list/SE[DNA_SE_LENGTH] var/list/UI[DNA_UI_LENGTH] // From old dna. @@ -88,7 +93,7 @@ var/global/list/datum/dna/gene/dna_genes[0] new_dna.mutantrace=mutantrace new_dna.real_name=real_name new_dna.species=species - for(var/b=1;b<=STRUCDNASIZE;b++) + for(var/b=1;b<=DNA_SE_LENGTH;b++) new_dna.SE[b]=SE[b] if(b<=DNA_UI_LENGTH) new_dna.UI[b]=UI[b] @@ -228,13 +233,12 @@ var/global/list/datum/dna/gene/dna_genes[0] // "Zeroes out" all of the blocks. /datum/dna/proc/ResetSE() - for(var/i = 1, i <= STRUCDNASIZE, i++) + for(var/i = 1, i <= DNA_SE_LENGTH, i++) SetSEValue(i,rand(1,1024),1) UpdateSE() // Set a DNA SE block's raw value. /datum/dna/proc/SetSEValue(var/block,var/value,var/defer=0) - //testing("SetSEBlock([block],[value],[defer]): [value] -> [nval]") if (block<=0) return ASSERT(value>=0) ASSERT(value<=4095) @@ -339,7 +343,7 @@ var/global/list/datum/dna/gene/dna_genes[0] if(UI.len != DNA_UI_LENGTH) ResetUIFrom(character) - if(length(struc_enzymes)!= 3*STRUCDNASIZE) + if(length(struc_enzymes)!= 3*DNA_SE_LENGTH) ResetSE() if(length(unique_enzymes) != 32) @@ -347,7 +351,7 @@ var/global/list/datum/dna/gene/dna_genes[0] else if(length(uni_identity) != 3*DNA_UI_LENGTH) uni_identity = "00600200A00E0110148FC01300B0095BD7FD3F4" - if(length(struc_enzymes)!= 3*STRUCDNASIZE) + if(length(struc_enzymes)!= 3*DNA_SE_LENGTH) struc_enzymes = "43359156756131E13763334D1C369012032164D4FE4CD61544B6C03F251B6C60A42821D26BA3B0FD6" // BACK-COMPAT! @@ -359,4 +363,3 @@ var/global/list/datum/dna/gene/dna_genes[0] unique_enzymes = md5(character.real_name) reg_dna[unique_enzymes] = character.real_name - diff --git a/code/game/dna/dna2_domutcheck.dm b/code/game/dna/dna2_domutcheck.dm index 3327d700f4..954c86f2a6 100644 --- a/code/game/dna/dna2_domutcheck.dm +++ b/code/game/dna/dna2_domutcheck.dm @@ -23,333 +23,21 @@ // Prior state var/gene_prior_status = (gene.type in M.active_genes) + var/changed = gene_active != gene_prior_status || (gene.flags & GENE_ALWAYS_ACTIVATE) - if((gene_active && !gene_prior_status) || (gene.flags & GENE_ALWAYS_ACTIVATE)) - //testing("[gene.name] activated!") - gene.activate(M,connected,flags) - if(M) - if(!(gene.flags & GENE_ALWAYS_ACTIVATE)) + // If gene state has changed: + if(changed) + // Gene active (or ALWAYS ACTIVATE) + if(gene_active || (gene.flags & GENE_ALWAYS_ACTIVATE)) + testing("[gene.name] activated!") + gene.activate(M,connected,flags) + if(M) M.active_genes |= gene.type - M.update_icon=1 - else if(!gene_active && gene_prior_status) - //testing("[gene.name] deactivated!") - gene.deactivate(M,connected,flags) - if(M) - M.active_genes -= gene.type - M.update_icon = 1 - //else - // testing("[M] - Failed to activate [gene.name] - [gene_active?"+":"-"]active, [gene_prior_status?"+":"-"]prior") - -/* Old, inflexibile -/proc/domutcheck(var/mob/living/M, var/connected, var/flags) - if (!M) return - - M.dna.check_integrity() - - M.disabilities = 0 - M.sdisabilities = 0 - var/old_mutations = M.mutations - M.mutations = list() - M.pass_flags = 0 -// M.see_in_dark = 2 -// M.see_invisible = 0 - - if(PLANT in old_mutations) - M.mutations.Add(PLANT) - if(SKELETON in old_mutations) - M.mutations.Add(SKELETON) - if(FAT in old_mutations) - M.mutations.Add(FAT) - if(HUSK in old_mutations) - M.mutations.Add(HUSK) - - var/inj = (flags & MUTCHK_FROM_INJECTOR) == MUTCHK_FROM_INJECTOR - var/forced = (flags & MUTCHK_FORCED) == MUTCHK_FORCED - - if(M.dna.GetSEState(NOBREATHBLOCK)) - if(forced || probinj(45,inj) || (mNobreath in old_mutations)) - M << "\blue You feel no need to breathe." - M.mutations.Add(mNobreath) - if(M.dna.GetSEState(REMOTEVIEWBLOCK)) - if(forced || probinj(45,inj) || (mRemote in old_mutations)) - M << "\blue Your mind expands" - M.mutations.Add(mRemote) - M.verbs += /mob/living/carbon/human/proc/remoteobserve - if(M.dna.GetSEState(REGENERATEBLOCK)) - if(forced || probinj(45,inj) || (mRegen in old_mutations)) - M << "\blue You feel better" - M.mutations.Add(mRegen) - if(M.dna.GetSEState(INCREASERUNBLOCK)) - if(forced || probinj(45,inj) || (mRun in old_mutations)) - M << "\blue Your leg muscles pulsate." - M.mutations.Add(mRun) - if(M.dna.GetSEState(REMOTETALKBLOCK)) - if(forced || probinj(45,inj) || (mRemotetalk in old_mutations)) - M << "\blue You expand your mind outwards" - M.mutations.Add(mRemotetalk) - M.verbs += /mob/living/carbon/human/proc/remotesay - if(M.dna.GetSEState(MORPHBLOCK)) - if(forced || probinj(45,inj) || (mMorph in old_mutations)) - M.mutations.Add(mMorph) - M << "\blue Your skin feels strange" - M.verbs += /mob/living/carbon/human/proc/morph - if(M.dna.GetSEState(COLDBLOCK)) - if(!(COLD_RESISTANCE in old_mutations)) - if(forced || probinj(15,inj) || (mHeatres in old_mutations)) - M.mutations.Add(mHeatres) - M << "\blue Your skin is icy to the touch" - else - if(forced || probinj(5,inj) || (mHeatres in old_mutations)) - M.mutations.Add(mHeatres) - M << "\blue Your skin is icy to the touch" - if(M.dna.GetSEState(HALLUCINATIONBLOCK)) - if(forced || probinj(45,inj) || (mHallucination in old_mutations)) - M.mutations.Add(mHallucination) - M << "\red Your mind says 'Hello'" - if(M.dna.GetSEState(NOPRINTSBLOCK)) - if(forced || probinj(45,inj) || (mFingerprints in old_mutations)) - M.mutations.Add(mFingerprints) - M << "\blue Your fingers feel numb" - if(M.dna.GetSEState(SHOCKIMMUNITYBLOCK)) - if(forced || probinj(45,inj) || (mShock in old_mutations)) - M.mutations.Add(mShock) - M << "\blue Your skin feels strange" - if(M.dna.GetSEState(SMALLSIZEBLOCK)) - if(forced || probinj(45,inj) || (mSmallsize in old_mutations)) - M << "\blue Your skin feels rubbery" - M.mutations.Add(mSmallsize) - M.pass_flags |= 1 - - - - if (M.dna.GetSEState(HULKBLOCK)) - if(forced || probinj(5,inj) || (HULK in old_mutations)) - M << "\blue Your muscles hurt." - M.mutations.Add(HULK) - if (M.dna.GetSEState(HEADACHEBLOCK)) - M.disabilities |= EPILEPSY - M << "\red You get a headache." - if (M.dna.GetSEState(FAKEBLOCK)) - M << "\red You feel strange." - if (prob(95)) - if(prob(50)) - randmutb(M) + M.update_icon = 1 + // If Gene is NOT active: else - randmuti(M) - else - randmutg(M) - if (M.dna.GetSEState(COUGHBLOCK)) - M.disabilities |= COUGHING - M << "\red You start coughing." - if (M.dna.GetSEState(CLUMSYBLOCK)) - M << "\red You feel lightheaded." - M.mutations.Add(CLUMSY) - if (M.dna.GetSEState(TWITCHBLOCK)) - M.disabilities |= TOURETTES - M << "\red You twitch." - if (M.dna.GetSEState(XRAYBLOCK)) - if(forced || probinj(30,inj) || (XRAY in old_mutations)) - M << "\blue The walls suddenly disappear." -// M.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) -// M.see_in_dark = 8 -// M.see_invisible = 2 - M.mutations.Add(XRAY) - if (M.dna.GetSEState(NERVOUSBLOCK)) - M.disabilities |= NERVOUS - M << "\red You feel nervous." - if (M.dna.GetSEState(FIREBLOCK)) - if(!(mHeatres in old_mutations)) - if(forced || probinj(30,inj) || (COLD_RESISTANCE in old_mutations)) - M << "\blue Your body feels warm." - M.mutations.Add(COLD_RESISTANCE) - else - if(forced || probinj(5,inj) || (COLD_RESISTANCE in old_mutations)) - M << "\blue Your body feels warm." - M.mutations.Add(COLD_RESISTANCE) - if (M.dna.GetSEState(BLINDBLOCK)) - M.sdisabilities |= BLIND - M << "\red You can't seem to see anything." - if (M.dna.GetSEState(TELEBLOCK)) - if(forced || probinj(15,inj) || (TK in old_mutations)) - M << "\blue You feel smarter." - M.mutations.Add(TK) - if (M.dna.GetSEState(DEAFBLOCK)) - M.sdisabilities |= DEAF - M.ear_deaf = 1 - M << "\red Its kinda quiet.." - if (M.dna.GetSEState(GLASSESBLOCK)) - M.disabilities |= NEARSIGHTED - M << "Your eyes feel weird..." - - /* If you want the new mutations to work, UNCOMMENT THIS. - if(istype(M, /mob/living/carbon)) - for (var/datum/mutations/mut in global_mutations) - mut.check_mutation(M) - */ - -//////////////////////////////////////////////////////////// Monkey Block - if (M.dna.GetSEState(MONKEYBLOCK) && 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) - - - var/mob/living/carbon/monkey/O = null - if(H.species.primitive) - O = new H.species.primitive(src) - else - H.gib() //Trying to change the species of a creature with no primitive var set is messy. - return - - if(M) - if (M.dna) - O.dna = M.dna - M.dna = 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/obj/T in (M.contents-implants)) - del(T) - - O.loc = M.loc - - 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 = "hurt" - 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 (!M.dna.GetSEState(MONKEYBLOCK) && !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 ) - if(Mo.greaterform) - O.set_species(Mo.greaterform) - - if (M.dna.GetUIState(DNA_UI_GENDER)) - O.gender = FEMALE - else - O.gender = MALE - - if (M) - if (M.dna) - O.dna = M.dna - M.dna = 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/obj/T in M) - // del(T) - - O.loc = M.loc - - 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++ - O.UpdateAppearance() - 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 -//////////////////////////////////////////////////////////// Monkey Block - if(M) - M.update_icon = 1 //queue a full icon update at next life() call - return null -/////////////////////////// DNA MISC-PROCS -*/ + testing("[gene.name] deactivated!") + gene.deactivate(M,connected,flags) + if(M) + M.active_genes -= gene.type + M.update_icon = 1 diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 6f180993fb..4cdefb36ec 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -38,7 +38,7 @@ /proc/randmuti(var/mob/living/M) if(!M) return M.dna.check_integrity() - M.dna.SetUIValue(rand(1,UNIDNASIZE),rand(1,4095)) + M.dna.SetUIValue(rand(1,DNA_UI_LENGTH),rand(1,4095)) // Scramble UI or SE. /proc/scramble(var/UI, var/mob/M, var/prob) @@ -52,7 +52,7 @@ M.UpdateAppearance() else - for(var/i = 1, i <= STRUCDNASIZE-1, i++) + for(var/i = 1, i <= DNA_SE_LENGTH-1, i++) if(prob(prob)) M.dna.SetSEValue(i,rand(1,4095),1) M.dna.UpdateSE() diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 6b91a6c491..d15b8085f5 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -19,17 +19,18 @@ /datum/dna2/record/proc/GetData() var/list/ser=list("data" = null, "owner" = null, "label" = null, "type" = null, "ue" = 0) - ser["ue"] = (types & DNA2_BUF_UE) == DNA2_BUF_UE - if(types & DNA2_BUF_SE) - ser["data"] = dna.SE - else - ser["data"] = dna.UI - ser["owner"] = src.dna.real_name - ser["label"] = name - if(types & DNA2_BUF_UI) - ser["type"] = "ui" - else - ser["type"] = "se" + if(dna) + ser["ue"] = (types & DNA2_BUF_UE) == DNA2_BUF_UE + if(types & DNA2_BUF_SE) + ser["data"] = dna.SE + else + ser["data"] = dna.UI + ser["owner"] = src.dna.real_name + ser["label"] = name + if(types & DNA2_BUF_UI) + ser["type"] = "ui" + else + ser["type"] = "se" return ser /////////////////////////// DNA MACHINES @@ -311,6 +312,8 @@ /obj/machinery/computer/scan_consolenew/New() ..() + for(var/i=0;i<3;i++) + buffers[i+1]=new /datum/dna2/record spawn(5) for(dir in list(NORTH,EAST,SOUTH,WEST)) connected = locate(/obj/machinery/dna_scannernew, get_step(src, dir)) @@ -400,8 +403,8 @@ data["disk"] = diskData var/list/new_buffers = list() - for(var/datum/dna2/record/buf in buffers) - new_buffers.Add(buf.GetData()) + for(var/datum/dna2/record/buf in src.buffers) + new_buffers += list(buf.GetData()) data["buffers"]=new_buffers data["radiationIntensity"] = radiation_intensity @@ -635,7 +638,7 @@ if (href_list["selectSEBlock"] && href_list["selectSESubblock"]) // This chunk of code updates selected block / sub-block based on click (se stands for strutural enzymes) var/select_block = text2num(href_list["selectSEBlock"]) var/select_subblock = text2num(href_list["selectSESubblock"]) - if ((select_block <= STRUCDNASIZE) && (select_block >= 1)) + if ((select_block <= DNA_SE_LENGTH) && (select_block >= 1)) src.selected_se_block = select_block if ((select_subblock <= DNA_BLOCK_SIZE) && (select_subblock >= 1)) src.selected_se_subblock = select_subblock @@ -663,9 +666,9 @@ var/real_SE_block=selected_se_block block = miniscramble(block, src.radiation_intensity, src.radiation_duration) if(prob(20)) - if (src.selected_se_block > 1 && src.selected_se_block < STRUCDNASIZE/2) + if (src.selected_se_block > 1 && src.selected_se_block < DNA_SE_LENGTH/2) real_SE_block++ - else if (src.selected_se_block > STRUCDNASIZE/2 && src.selected_se_block < STRUCDNASIZE) + else if (src.selected_se_block > DNA_SE_LENGTH/2 && src.selected_se_block < DNA_SE_LENGTH) real_SE_block-- //testing("Irradiated SE block [real_SE_block]:[src.selected_se_subblock] ([original_block] now [block]) [(real_SE_block!=selected_se_block) ? "(SHIFTED)":""]!") @@ -730,7 +733,9 @@ if(src.connected.occupant && src.connected.occupant.dna) var/datum/dna2/record/databuf=new databuf.types = DNA2_BUF_UE - databuf.dna = src.connected.occupant.dna + databuf.dna = src.connected.occupant.dna.Clone() + if(ishuman(connected.occupant)) + databuf.dna.real_name=connected.occupant.name databuf.name = "Unique Identifier" src.buffers[bufferId] = databuf return 1 @@ -739,7 +744,9 @@ if(src.connected.occupant && src.connected.occupant.dna) var/datum/dna2/record/databuf=new databuf.types = DNA2_BUF_UI|DNA2_BUF_UE - databuf.dna = src.connected.occupant.dna + databuf.dna = src.connected.occupant.dna.Clone() + if(ishuman(connected.occupant)) + databuf.dna.real_name=connected.occupant.name databuf.name = "Unique Identifier + Unique Enzymes" src.buffers[bufferId] = databuf return 1 @@ -748,19 +755,21 @@ if(src.connected.occupant && src.connected.occupant.dna) var/datum/dna2/record/databuf=new databuf.types = DNA2_BUF_SE - databuf.dna = src.connected.occupant.dna + databuf.dna = src.connected.occupant.dna.Clone() + if(ishuman(connected.occupant)) + databuf.dna.real_name=connected.occupant.name databuf.name = "Structural Enzymes" src.buffers[bufferId] = databuf return 1 if (bufferOption == "clear") - src.buffers[bufferId]=null + src.buffers[bufferId]=new /datum/dna2/record() return 1 if (bufferOption == "changeLabel") var/datum/dna2/record/buf = src.buffers[bufferId] - buf.name = buf.name ? src.buffers[bufferId]["label"] : "New Label" - buf.name = sanitize(input("New Label:", "Edit Label", buf.name)) + var/text = sanitize(input(usr, "New Label:", "Edit Label", buf.name) as text|null) + buf.name = text src.buffers[bufferId] = buf return 1 @@ -784,7 +793,7 @@ if ((buf.types & DNA2_BUF_UE)) src.connected.occupant.real_name = buf.dna.real_name src.connected.occupant.name = buf.dna.real_name - src.connected.occupant.UpdateAppearance(buf.dna.UI) + src.connected.occupant.UpdateAppearance(buf.dna.UI.Copy()) else if (buf.types & DNA2_BUF_SE) src.connected.occupant.dna.SE = buf.dna.SE src.connected.occupant.dna.UpdateSE() @@ -800,7 +809,12 @@ var/datum/dna2/record/buf = src.buffers[bufferId] if(href_list["createBlockInjector"]) waiting_for_user_input=1 - var/blk = input(usr,"Select Block","Block") in all_dna_blocks(buf.GetData()) + var/list/selectedbuf + if(buf.types & DNA2_BUF_SE) + selectedbuf=buf.dna.SE + else + selectedbuf=buf.dna.UI + var/blk = input(usr,"Select Block","Block") in all_dna_blocks(selectedbuf) success = setInjectorBlock(I,blk,buf) else I.buf = buf diff --git a/code/game/dna/genes/disabilities.dm b/code/game/dna/genes/disabilities.dm index a06a3a0364..a119a0cf4b 100644 --- a/code/game/dna/genes/disabilities.dm +++ b/code/game/dna/genes/disabilities.dm @@ -36,6 +36,8 @@ M.sdisabilities|=sdisability if(activation_message) M << "\red [activation_message]" + else + testing("[name] has no activation message.") /datum/dna/gene/disability/deactivate(var/mob/M, var/connected, var/flags) if(mutation && (mutation in M.mutations)) @@ -46,6 +48,8 @@ M.sdisabilities-=sdisability if(deactivation_message) M << "\red [deactivation_message]" + else + testing("[name] has no deactivation message.") // Note: Doesn't seem to do squat, at the moment. /datum/dna/gene/disability/hallucinate diff --git a/code/game/dna/genes/gene.dm b/code/game/dna/genes/gene.dm index 3bf5b5e5f7..21eec348bd 100644 --- a/code/game/dna/genes/gene.dm +++ b/code/game/dna/genes/gene.dm @@ -23,6 +23,12 @@ // Any of a number of GENE_ flags. var/flags=0 +/** +* Is the gene active in this mob's DNA? +*/ +/datum/dna/gene/proc/is_active(var/mob/M) + return M.active_genes && type in M.active_genes + // Return 1 if we can activate. // HANDLE MUTCHK_FORCED HERE! /datum/dna/gene/proc/can_activate(var/mob/M, var/flags) @@ -32,11 +38,43 @@ /datum/dna/gene/proc/activate(var/mob/M, var/connected, var/flags) return -// Called when the gene deactivates. Undo your magic here. -// Only called when the block is deactivated. +/** +* Called when the gene deactivates. Undo your magic here. +* Only called when the block is deactivated. +*/ /datum/dna/gene/proc/deactivate(var/mob/M, var/connected, var/flags) return +// This section inspired by goone's bioEffects. + +/** +* Called in each life() tick. +*/ +/datum/dna/gene/proc/OnMobLife(var/mob/M) + return + +/** +* Called when the mob dies +*/ +/datum/dna/gene/proc/OnMobDeath(var/mob/M) + return + +/** +* Called when the mob says shit +*/ +/datum/dna/gene/proc/OnSay(var/mob/M, var/message) + return message + +/** +* Called after the mob runs update_icons. +* +* @params M The subject. +* @params g Gender (m or f) +* @params fat Fat? (0 or 1) +*/ +/datum/dna/gene/proc/OnDrawUnderlays(var/mob/M, var/g, var/fat) + return 0 + ///////////////////// // BASIC GENES @@ -66,14 +104,10 @@ var/list/deactivation_messages=list() /datum/dna/gene/basic/can_activate(var/mob/M,var/flags) - if(mutation==0) - return 0 - - // Probability check - if(flags & MUTCHK_FORCED || probinj(activation_prob,(flags&MUTCHK_FORCED))) + if(flags & MUTCHK_FORCED) return 1 - - return 0 + // Probability check + return probinj(activation_prob,(flags&MUTCHK_FORCED)) /datum/dna/gene/basic/activate(var/mob/M) M.mutations.Add(mutation) diff --git a/code/game/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm index 952f7df0f4..c3f1b0db88 100644 --- a/code/game/dna/genes/monkey.dm +++ b/code/game/dna/genes/monkey.dm @@ -9,6 +9,7 @@ /datum/dna/gene/monkey/activate(var/mob/living/M, var/connected, var/flags) if(!istype(M,/mob/living/carbon/human)) + //testing("Cannot monkey-ify [M], type is [M.type].") return var/mob/living/carbon/human/H = M H.monkeyizing = 1 @@ -44,7 +45,7 @@ if(M) if (M.dna) - O.dna = M.dna + O.dna = M.dna.Clone() M.dna = null if (M.suiciding) @@ -86,6 +87,7 @@ /datum/dna/gene/monkey/deactivate(var/mob/living/M, var/connected, var/flags) if(!istype(M,/mob/living/carbon/monkey)) + //testing("Cannot humanize [M], type is [M.type].") return var/mob/living/carbon/monkey/Mo = M Mo.monkeyizing = 1 @@ -119,7 +121,7 @@ if (M) if (M.dna) - O.dna = M.dna + O.dna = M.dna.Clone() M.dna = null if (M.suiciding) diff --git a/code/game/dna/genes/powers.dm b/code/game/dna/genes/powers.dm index 9ac9f06b0d..3381894f8a 100644 --- a/code/game/dna/genes/powers.dm +++ b/code/game/dna/genes/powers.dm @@ -72,12 +72,17 @@ block=COLDBLOCK can_activate(var/mob/M,var/flags) + if(flags & MUTCHK_FORCED) + return !(/datum/dna/gene/basic/cold_resist in M.active_genes) // Probability check var/_prob = 15 if(COLD_RESISTANCE in M.mutations) _prob=5 if(probinj(_prob,(flags&MUTCHK_FORCED))) return 1 + + OnDrawUnderlays(var/mob/M,var/g,var/fat) + return "cold[fat]_s" */ /datum/dna/gene/basic/cold_resist @@ -89,7 +94,9 @@ block=FIREBLOCK can_activate(var/mob/M,var/flags) - + if(flags & MUTCHK_FORCED) + return 1 + // return !(/datum/dna/gene/basic/heat_resist in M.active_genes) // Probability check var/_prob=30 //if(mHeatres in M.mutations) @@ -97,6 +104,9 @@ if(probinj(_prob,(flags&MUTCHK_FORCED))) return 1 + OnDrawUnderlays(var/mob/M,var/g,var/fat) + return "fire[fat]_s" + /datum/dna/gene/basic/noprints name="No Prints" activation_messages=list("Your fingers feel numb.") @@ -149,6 +159,22 @@ return 0 return ..(M,flags) + OnDrawUnderlays(var/mob/M,var/g,var/fat) + if(fat) + return "hulk_[fat]_s" + else + return "hulk_[g]_s" + return 0 + + OnMobLife(var/mob/living/carbon/human/M) + if(!istype(M)) return + if(M.health <= 25) + M.mutations.Remove(HULK) + M.update_mutations() //update our mutation overlays + M << "\red You suddenly feel very weak." + M.Weaken(3) + M.emote("collapse") + /datum/dna/gene/basic/xray name="X-Ray Vision" activation_messages=list("The walls suddenly disappear.") @@ -165,3 +191,5 @@ New() block=TELEBLOCK + OnDrawUnderlays(var/mob/M,var/g,var/fat) + return "telekinesishead[fat]_s" diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index a552ac1cd7..9652a90978 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -184,7 +184,7 @@ changeling.chem_charges -= 5 src.visible_message("[src] transforms!") changeling.geneticdamage = 30 - src.dna = chosen_dna + src.dna = chosen_dna.Clone() src.real_name = chosen_dna.real_name src.flavor_text = "" src.UpdateAppearance() @@ -236,7 +236,7 @@ del(animation) var/mob/living/carbon/monkey/O = new /mob/living/carbon/monkey(src) - O.dna = C.dna + O.dna = C.dna.Clone() C.dna = null for(var/obj/item/W in C) @@ -289,7 +289,7 @@ changeling.chem_charges-- C.remove_changeling_powers() C.visible_message("[C] transforms!") - C.dna = chosen_dna + C.dna = chosen_dna.Clone() var/list/implants = list() for (var/obj/item/weapon/implant/I in C) //Still preserving implants @@ -322,7 +322,7 @@ O.gender = FEMALE else O.gender = MALE - O.dna = C.dna + O.dna = C.dna.Clone() C.dna = null O.real_name = chosen_dna.real_name @@ -721,7 +721,7 @@ var/list/datum/dna/hivemind_bank = list() src << "Our sting appears ineffective against its DNA." return 0 T.visible_message("[T] transforms!") - T.dna = chosen_dna + T.dna = chosen_dna.Clone() T.real_name = chosen_dna.real_name T.UpdateAppearance() domutcheck(T, null) diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 5b1b1494b5..51bcc39a37 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -163,8 +163,8 @@ continue var/datum/disease/dnaspread/D = new D.strain_data["name"] = H.real_name - D.strain_data["UI"] = H.dna.UI - D.strain_data["SE"] = H.dna.SE + D.strain_data["UI"] = H.dna.uni_identity + D.strain_data["SE"] = H.dna.struc_enzymes D.carrier = 1 D.holder = H D.affected_mob = H @@ -233,10 +233,10 @@ if (prob(25)) if (prob(75)) randmutb(H) - domutcheck(H,null,1) + domutcheck(H,null,MUTCHK_FORCED) else randmutg(H) - domutcheck(H,null,1) + domutcheck(H,null,MUTCHK_FORCED) for(var/mob/living/carbon/monkey/M in living_mob_list) var/turf/T = get_turf(M) if(!T) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index a7ad25934a..6f9d50053b 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -60,10 +60,10 @@ Initialize() buf.types=DNA2_BUF_SE var/list/new_SE=list(0x098,0x3E8,0x403,0x44C,0x39F,0x4B0,0x59D,0x514,0x5FC,0x578,0x5DC,0x640,0x6A4) - for(var/i=new_SE.len;i<=STRUCDNASIZE;i++) + for(var/i=new_SE.len;i<=DNA_SE_LENGTH;i++) new_SE += rand(1,1024) buf.dna.SE=new_SE - buf.dna.SetSEValue(MONKEYBLOCK,0xFFF) + buf.dna.SetSEValueRange(MONKEYBLOCK,0xDAC, 0xFFF) //Find a dead mob with a brain and client. diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index d0b19f88e9..95cf77dd21 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -72,7 +72,7 @@ if (!(NOCLONE in M.mutations)) // prevents drained people from having their DNA changed if (buf.types & DNA2_BUF_UI) if (!block) //isolated block? - M.UpdateAppearance(buf.dna) + M.UpdateAppearance(buf.dna.UI.Copy()) if (buf.types & DNA2_BUF_UE) //unique enzymes? yes M.real_name = buf.dna.real_name M.name = buf.dna.real_name @@ -83,7 +83,7 @@ uses-- if (buf.types & DNA2_BUF_SE) if (!block) //isolated block? - M.dna.SE = buf.dna.SE + M.dna.SE = buf.dna.SE.Copy() M.dna.UpdateSE() else M.dna.SetSEValue(block,src.GetValue()) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 3a5c7c2393..16b94ba54e 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -119,6 +119,25 @@ var/global/floorIsLava = 0 else body += "Animalize | " + // DNA2 - Admin Hax + if(iscarbon(M)) + body += "

" + body += "DNA Blocks:
" + var/bname + for(var/block=1;block<=DNA_SE_LENGTH;block++) + if(((block-1)%5)==0) + body += "" + bname = assigned_blocks[block] + body += "" + body += "
 12345
[block-1]" + if(bname) + var/bstate=M.dna.GetSEState(block) + var/bcolor="[(bstate)?"#006600":"#ff0000"]" + body += "[bname][block]" + else + body += "[block]" + body+="
" + body += {"

Rudimentary transformation:
These transformations only create a new mob type and copy stuff over. They do not take into account MMIs and similar mob-specific things. The buttons in 'Transformations' are preferred, when possible.

Observer | diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 241c34d5d8..4131e46411 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -273,7 +273,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that if(istype(M, /mob/living/carbon/human)) log_admin("[key_name(src)] has made [M.key] a changeling.") spawn(10) - M.absorbed_dna[M.real_name] = M.dna + M.absorbed_dna[M.real_name] = M.dna.Clone() M.make_changeling() if(M.mind) M.mind.special_role = "Changeling" @@ -986,3 +986,19 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that usr << list2text(dead_mob_list,",") if("Clients") usr << list2text(clients,",") + +// DNA2 - Admin Hax +/client/proc/cmd_admin_toggle_block(var/mob/M,var/block) + if(!ticker) + alert("Wait until the game starts") + return + if(istype(M, /mob/living/carbon)) + M.dna.SetSEState(block,!M.dna.GetSEState(block)) + domutcheck(M,null,MUTCHK_FORCED) + M.update_mutations() + var/state="[M.dna.GetSEState(block)?"on":"off"]" + var/blockname=assigned_blocks[block] + message_admins("[key_name_admin(src)] has toggled [M.key]'s [blockname] block [state]!") + log_admin("[key_name(src)] has toggled [M.key]'s [blockname] block [state]!") + else + alert("Invalid mob") diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 871567cc0a..77c972a40d 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -447,9 +447,13 @@ Traitors and the like can also be revived with the previous role mostly intact. 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.SE = record_found.fields["enzymes"]//This is the default of enzymes so I think it's safe to go with. + + // I HATE BYOND. HATE. HATE. - N3X + var/list/newSE= record_found.fields["enzymes"] + var/list/newUI = record_found.fields["identity"] + new_character.dna.SE = newSE.Copy() //This is the default of enzymes so I think it's safe to go with. new_character.dna.UpdateSE() - new_character.UpdateAppearance(record_found.fields["identity"])//Now we configure their appearance based on their unique identity, same as with a DNA machine or somesuch. + new_character.UpdateAppearance(newUI.Copy())//Now we configure their appearance based on their unique identity, same as with a DNA machine or somesuch. 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) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index a424cdd72a..37ec642259 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -30,8 +30,8 @@ continue var/datum/disease/dnaspread/D = new D.strain_data["name"] = H.real_name - D.strain_data["UI"] = H.dna.UI - D.strain_data["SE"] = H.dna.SE + D.strain_data["UI"] = H.dna.UI.Copy() + D.strain_data["SE"] = H.dna.SE.Copy() D.carrier = 1 D.holder = H D.affected_mob = H diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 8fdf3c7976..93f56618a0 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -28,7 +28,7 @@ brainmob = new(src) brainmob.name = H.real_name brainmob.real_name = H.real_name - brainmob.dna = H.dna + brainmob.dna = H.dna.Clone() brainmob.timeofhostdeath = H.timeofdeath if(H.mind) H.mind.transfer_to(brainmob) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index d8b8da1056..b1da82e6fc 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -365,8 +365,18 @@ proc/get_damage_icon_part(damage_state, body_part) var/add_image = 0 var/g = "m" if(gender == FEMALE) g = "f" + // DNA2 - Drawing underlays. + for(var/datum/dna/gene/gene in dna_genes) + if(!gene.block) + continue + if(gene.is_active(src)) + var/underlay=gene.OnDrawUnderlays(src,g,fat) + if(underlay) + standing.underlays += underlay + add_image = 1 for(var/mut in mutations) switch(mut) + /* if(HULK) if(fat) standing.underlays += "hulk_[fat]_s" @@ -379,6 +389,7 @@ proc/get_damage_icon_part(damage_state, body_part) if(TK) standing.underlays += "telekinesishead[fat]_s" add_image = 1 + */ if(LASER) standing.overlays += "lasereyes_s" add_image = 1 diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm index d4c91e4cfc..bea08693fb 100644 --- a/code/modules/mob/mob_transformation_simple.dm +++ b/code/modules/mob/mob_transformation_simple.dm @@ -41,7 +41,7 @@ M.real_name = src.real_name if(src.dna) - M.dna = src.dna + M.dna = src.dna.Clone() if(mind) mind.transfer_to(M) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 5ae6f0a7a3..9a2493f23a 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -29,10 +29,9 @@ O = new species.primitive(loc) - O.dna = dna - //O.dna.uni_identity = "000000000000000000DC00000660004DA0A0E00" - //O.dna.struc_enzymes = "[copytext(O.dna.struc_enzymes,1,1+3*(STRUCDNASIZE-1))]BB8" + O.dna = dna.Clone() O.dna.SetSEState(MONKEYBLOCK,1) + O.dna.SetSEValueRange(MONKEYBLOCK,0xDAC, 0xFFF) O.loc = loc O.viruses = viruses O.a_intent = "hurt" @@ -166,7 +165,7 @@ mind.transfer_to(O) if(O.mind.assigned_role == "Cyborg") O.mind.original = O - else if(mind.special_role) + else if(mind&&mind.special_role) O.mind.store_memory("In case you look at this after being borged, the objectives are only here until I find a way to make them not show up for you, as I can't simply delete them without screwing up round-end reporting. --NeoFite") else O.key = key diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 4261299848..afc5515bf7 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -887,7 +887,7 @@ obj/item/weapon/organ/head/proc/transfer_identity(var/mob/living/carbon/human/H) brainmob = new(src) brainmob.name = H.real_name brainmob.real_name = H.real_name - brainmob.dna = H.dna + brainmob.dna = H.dna.Clone() if(H.mind) H.mind.transfer_to(brainmob) brainmob.container = src From 9d3396406180b3d6cd740a21ccd9361d49cf393c Mon Sep 17 00:00:00 2001 From: Rob Nelson Date: Thu, 6 Feb 2014 23:19:52 -0800 Subject: [PATCH 05/53] Missed the gene Life() call. --- code/modules/mob/living/carbon/human/life.dm | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index b2a2180ead..eae1cc405c 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -220,12 +220,13 @@ if((COLD_RESISTANCE in mutations) || (prob(1))) heal_organ_damage(0,1) - if ((HULK in mutations) && health <= 25) - mutations.Remove(HULK) - update_mutations() //update our mutation overlays - src << "\red You suddenly feel very weak." - Weaken(3) - emote("collapse") + // DNA2 - Gene processing. + // The HULK stuff that was here is now in the hulk gene. + for(var/datum/dna/gene/gene in dna_genes) + if(!gene.block) + continue + if(gene.is_active(src)) + gene.OnMobLife(src) if (radiation) if (radiation > 100) From c3623ff882656f337a611de0f39d4a4adacd53bc Mon Sep 17 00:00:00 2001 From: Rob Nelson Date: Thu, 6 Feb 2014 23:24:19 -0800 Subject: [PATCH 06/53] Fix earlier screwed commit --- baystation12.int | 5 ----- 1 file changed, 5 deletions(-) diff --git a/baystation12.int b/baystation12.int index fb3d85be3c..b82874fded 100644 --- a/baystation12.int +++ b/baystation12.int @@ -1,11 +1,6 @@ // BEGIN_INTERNALS /* MAP_ICON_TYPE: 0 -WINDOW: code\__HELPERS\unsorted.dm;code\game\dna\dna2.dm;code\game\dna\dna2_domutcheck.dm;code\game\dna\dna2_helpers.dm;code\game\dna\dna_modifier.dm;code\game\machinery\cloning.dm;code\game\objects\items\weapons\dna_injector.dm;code\game\dna\genes\disabilities.dm;code\game\gamemodes\setupgame.dm;code\setup.dm;code\global.dm -LAST_COMPILE_VERSION: 501.1217 -DIR: code code\game code\game\dna code\game\dna\genes code\game\gamemodes code\game\objects code\game\objects\items code\game\objects\items\weapons -FILE: code\game\objects\items\weapons\dna_injector.dm -LAST_COMPILE_TIME: 1387468589 AUTO_FILE_DIR: OFF */ // END_INTERNALS From 64f83c51ad05ef1608f0a37a14bcf8d53dde6f16 Mon Sep 17 00:00:00 2001 From: Rob Nelson Date: Thu, 6 Feb 2014 23:52:58 -0800 Subject: [PATCH 07/53] And now tested in game, with some fixes. --- code/game/gamemodes/setupgame.dm | 18 +++++++++++++++--- code/modules/admin/topic.dm | 13 +++++++++++++ .../modules/mob/living/carbon/monkey/monkey.dm | 3 +++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/setupgame.dm b/code/game/gamemodes/setupgame.dm index 813bbbabf2..d2b54fe5ba 100644 --- a/code/game/gamemodes/setupgame.dm +++ b/code/game/gamemodes/setupgame.dm @@ -6,6 +6,9 @@ // The name is used on /vg/ for species with predefined genetic traits, // and for the DNA panel in the player panel. /proc/getAssignedBlock(var/name,var/list/blocksLeft, var/activity_bounds=DNA_DEFAULT_BOUNDS) + if(blocksLeft.len==0) + warning("[name]: No more blocks left to assign!") + return 0 var/assigned = pick(blocksLeft) blocksLeft.Remove(assigned) assigned_blocks[assigned]=name @@ -60,7 +63,7 @@ BLINDBLOCK = tempnum */ var/list/numsToAssign=new() - for(var/i=1;i