Merge pull request #10327 from Seris02/tggenetics

ports tg genetics
This commit is contained in:
kevinz000
2020-03-11 17:01:37 -07:00
committed by GitHub
77 changed files with 2776 additions and 514 deletions
+6 -3
View File
@@ -77,6 +77,8 @@
name = "cloning data disk"
icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk.
var/list/fields = list()
var/list/mutations = list()
var/max_mutations = 6
var/read_only = 0 //Well,it's still a floppy disk
//Disk stuff.
@@ -129,7 +131,7 @@
return examine(user)
//Start growing a human clone in the pod!
/obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, se, mindref, datum/species/mrace, list/features, factions, list/quirks)
/obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, mutation_index, mindref, datum/species/mrace, list/features, factions, list/quirks)
if(panel_open)
return FALSE
if(mess || attempting)
@@ -165,8 +167,9 @@
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
H.hardset_dna(ui, se, H.real_name, null, mrace, features)
H.randmutb() //100% bad mutation. Can be cured with mutadone.
H.hardset_dna(ui, mutation_index, H.real_name, null, mrace, features)
H.easy_randmut(NEGATIVE+MINOR_NEGATIVE) //100% bad mutation. Can be cured with mutadone.
H.silent = 20 //Prevents an extreme edge case where clones could speak if they said something at exactly the right moment.
occupant = H
+1 -1
View File
@@ -485,7 +485,7 @@
R.fields["id"] = copytext_char(md5(mob_occupant.real_name), 2, 6)
R.fields["UE"] = dna.unique_enzymes
R.fields["UI"] = dna.uni_identity
R.fields["SE"] = dna.struc_enzymes
R.fields["SE"] = dna.mutation_index
R.fields["blood_type"] = dna.blood_type
R.fields["features"] = dna.features
R.fields["factions"] = mob_occupant.faction
+592 -142
View File
@@ -1,14 +1,16 @@
#define INJECTOR_TIMEOUT 100
#define REJUVENATORS_INJECT 15
#define REJUVENATORS_MAX 90
#define NUMBER_OF_BUFFERS 3
#define SCRAMBLE_TIMEOUT 600
#define JOKER_TIMEOUT 12000 //20 minutes
#define JOKER_UPGRADE 1800
#define RADIATION_STRENGTH_MAX 15
#define RADIATION_STRENGTH_MULTIPLIER 1 //larger has a more range
#define RADIATION_STRENGTH_MULTIPLIER 1 //larger has more range
#define RADIATION_DURATION_MAX 30
#define RADIATION_ACCURACY_MULTIPLIER 3 //larger is less accurate
#define RADIATION_IRRADIATION_MULTIPLIER 1 //multiplier for how much radiation a test subject receives
#define SCANNER_ACTION_SE 1
@@ -23,22 +25,44 @@
icon_keyboard = "med_key"
density = TRUE
circuit = /obj/item/circuitboard/computer/scan_consolenew
var/radduration = 2
var/radstrength = 1
var/list/buffer[NUMBER_OF_BUFFERS]
var/injectorready = 0 //world timer cooldown var
var/current_screen = "mainmenu"
var/obj/machinery/dna_scannernew/connected = null
var/obj/item/disk/data/diskette = null
var/list/delayed_action = null
use_power = IDLE_POWER_USE
idle_power_usage = 10
active_power_usage = 400
light_color = LIGHT_COLOR_BLUE
var/datum/techweb/stored_research
var/max_storage = 6
var/combine
var/radduration = 2
var/radstrength = 1
var/max_chromosomes = 6
///Amount of mutations we can store
var/list/buffer[NUMBER_OF_BUFFERS]
///mutations we have stored
var/list/stored_mutations = list()
///chromosomes we have stored
var/list/stored_chromosomes = list()
///combinations of injectors for the 'injector selection'. format is list("Elsa" = list(Cryokinesis, Geladikinesis), "The Hulk" = list(Hulk, Gigantism), etc) Glowy and the gang being an initialized datum
var/list/injector_selection = list()
///max amount of selections you can make
var/max_injector_selections = 2
///hard-cap on the advanced dna injector
var/max_injector_mutations = 10
///the max instability of the advanced injector.
var/max_injector_instability = 50
var/injectorready = 0 //world timer cooldown var
var/jokerready = 0
var/scrambleready = 0
var/current_screen = "mainmenu"
var/current_mutation //what block are we inspecting? only used when screen = "info"
var/current_storage //what storage block are we looking at?
var/obj/machinery/dna_scannernew/connected = null
var/obj/item/disk/data/diskette = null
var/list/delayed_action = null
/obj/machinery/computer/scan_consolenew/attackby(obj/item/I, mob/user, params)
if (istype(I, /obj/item/disk/data)) //INSERT SOME DISKETTES
if (!src.diskette)
@@ -48,6 +72,28 @@
to_chat(user, "<span class='notice'>You insert [I].</span>")
src.updateUsrDialog()
return
if (istype(I, /obj/item/chromosome))
if(LAZYLEN(stored_chromosomes) < max_chromosomes)
I.forceMove(src)
stored_chromosomes += I
to_chat(user, "<span class='notice'>You insert [I].</span>")
else
to_chat(user, "<span class='warning'>You cannot store any more chromosomes!</span>")
return
if(istype(I, /obj/item/dnainjector/activator))
var/obj/item/dnainjector/activator/A = I
if(A.used)
to_chat(user,"<span class='notice'>Recycled [I].</span>")
if(A.research)
var/c_typepath = generate_chromosome()
var/obj/item/chromosome/CM = new c_typepath (drop_location())
to_chat(user,"<span class='notice'>Recycled [I].</span>")
if((LAZYLEN(stored_chromosomes) < max_chromosomes) && prob(60))
CM.forceMove(src)
stored_chromosomes += CM
to_chat(user,"<span class='notice'>[capitalize(CM.name)] added to storage.</span>")
qdel(I)
return
else
return ..()
@@ -58,12 +104,26 @@
if(!isnull(connected))
break
injectorready = world.time + INJECTOR_TIMEOUT
scrambleready = world.time + SCRAMBLE_TIMEOUT
jokerready = world.time + JOKER_TIMEOUT
stored_research = SSresearch.science_tech
/obj/machinery/computer/scan_consolenew/examine(mob/user)
. = ..()
if(jokerready < world.time)
. += "<span class='notice'>JOKER algorithm available.</span>"
else
. += "<span class='notice'>JOKER algorithm available in about [round(0.00166666667 * (jokerready - world.time))] minutes."
/obj/machinery/computer/scan_consolenew/ui_interact(mob/user, last_change)
. = ..()
if(!user)
return
var/datum/browser/popup = new(user, "scannernew", "DNA Modifier Console", 800, 630) // Set up the popup browser window
if(user.client)
var/datum/asset/simple/assets = get_asset_datum(/datum/asset/simple/genetics)
assets.send(user.client)
if(!(in_range(src, user) || hasSiliconAccessInArea(user)))
popup.close()
return
@@ -88,8 +148,6 @@
occupant_status += "</div></div>"
occupant_status += "<div class='line'><div class='statusLabel'>Health:</div><div class='progressBar'><div style='width: [viable_occupant.health]%;' class='progressFill good'></div></div><div class='statusValue'>[viable_occupant.health] %</div></div>"
occupant_status += "<div class='line'><div class='statusLabel'>Radiation Level:</div><div class='progressBar'><div style='width: [viable_occupant.radiation/(RAD_MOB_SAFE/100)]%;' class='progressFill bad'></div></div><div class='statusValue'>[viable_occupant.radiation/(RAD_MOB_SAFE/100)] %</div></div>"
var/rejuvenators = viable_occupant.reagents.get_reagent_amount(/datum/reagent/medicine/potass_iodide)
occupant_status += "<div class='line'><div class='statusLabel'>Rejuvenators:</div><div class='progressBar'><div style='width: [round((rejuvenators / REJUVENATORS_MAX) * 100)]%;' class='progressFill highlight'></div></div><div class='statusValue'>[rejuvenators] units</div></div>"
occupant_status += "<div class='line'><div class='statusLabel'>Unique Enzymes :</div><div class='statusValue'><span class='highlight'>[viable_occupant.dna.unique_enzymes]</span></div></div>"
occupant_status += "<div class='line'><div class='statusLabel'>Last Operation:</div><div class='statusValue'>[last_change ? last_change : "----"]</div></div>"
else
@@ -147,28 +205,61 @@
buttons += "<a href='?src=[REF(src)];task=togglelock;'>[connected.locked ? "Unlock" : "Lock"] Scanner</a>"
else
buttons += "<span class='linkOff'>Open Scanner</span> <span class='linkOff'>Lock Scanner</span>"
if(viable_occupant)
buttons += "<a href='?src=[REF(src)];task=rejuv'>Inject Rejuvenators</a>"
if(viable_occupant && (scrambleready < world.time))
buttons += "<a href='?src=[REF(src)];task=scramble'>Scramble DNA</a>"
else
buttons += "<span class='linkOff'>Inject Rejuvenators</span>"
buttons += "<span class='linkOff'>Scramble DNA</span>"
if(diskette)
buttons += "<a href='?src=[REF(src)];task=ejectdisk'>Eject Disk</a>"
buttons += "<a href='?src=[REF(src)];task=screen;text=disk;'>Disk</a>"
else
buttons += "<span class='linkOff'>Eject Disk</span>"
if(current_screen == "buffer")
buttons += "<a href='?src=[REF(src)];task=screen;text=mainmenu;'>Radiation Emitter Menu</a>"
buttons += "<span class='linkOff'>Disk</span>"
if(current_screen == "mutations")
buttons += "<span class='linkOff'>Mutations</span>"
else
buttons += "<a href='?src=[REF(src)];task=screen;text=buffer;'>Buffer Menu</a>"
buttons += "<a href='?src=[REF(src)];task=screen;text=mutations;'>Mutations</a>"
if((current_screen == "mainmenu") || !current_screen)
buttons += "<span class='linkOff'>Genetic Sequencer</span>"
else
buttons += "<a href='?src=[REF(src)];task=screen;text=mainmenu;'>Genetic Sequencer</a>"
if(current_screen == "ui")
buttons += "<span class='linkOff'>Unique Identifiers</span>"
else
buttons += "<a href='?src=[REF(src)];task=screen;text=ui;'>Unique Identifiers</a>"
if(current_screen == "advinjector")
buttons += "<span class='linkOff'>Adv. Injectors</span>"
else
buttons += "<a href='?src=[REF(src)];task=screen;text=advinjector;'>Adv. Injectors</a>"
switch(current_screen)
if("working")
temp_html += status
temp_html += "<h1>System Busy</h1>"
temp_html += "Working ... Please wait ([DisplayTimeText(radduration*10)])"
if("buffer")
if("ui")
temp_html += status
temp_html += buttons
temp_html += "<h1>Buffer Menu</h1>"
temp_html += "<h1>Unique Identifiers</h1>"
temp_html += "<a href='?src=[REF(src)];task=setstrength;num=[radstrength-1];'>--</a> <a href='?src=[REF(src)];task=setstrength;'>Output Level</a> <a href='?src=[REF(src)];task=setstrength;num=[radstrength+1];'>++</a>"
temp_html += "<br><a href='?src=[REF(src)];task=setduration;num=[radduration-1];'>--</a> <a href='?src=[REF(src)];task=setduration;'>Pulse Duration</a> <a href='?src=[REF(src)];task=setduration;num=[radduration+1];'>++</a>"
temp_html += "<h3>Irradiate Subject</h3>"
temp_html += "<div class='line'><div class='statusLabel'>Unique Identifier:</div><div class='statusValue'><div class='clearBoth'>"
var/max_line_len = 7*DNA_BLOCK_SIZE
if(viable_occupant)
temp_html += "<div class='dnaBlockNumber'>1</div>"
var/char = ""
var/ui_text = viable_occupant.dna.uni_identity
var/len_byte = length(ui_text)
var/char_it = 0
for(var/byte_it = 1, byte_it <= len_byte, byte_it += length(char))
char_it++
char = ui_text[byte_it]
temp_html += "<a class='dnaBlock' href='?src=[REF(src)];task=pulseui;num=[char_it];'>[char]</a>"
if((char_it % max_line_len) == 0)
temp_html += "</div><div class='clearBoth'>"
if((char_it % DNA_BLOCK_SIZE) == 0 && byte_it < len_byte)
temp_html += "<div class='dnaBlockNumber'>[(char_it / DNA_BLOCK_SIZE) + 1]</div>"
else
temp_html += "---------"
temp_html += "</div></div><br><h1>Buffer Menu</h1>"
if(istype(buffer))
for(var/i=1, i<=buffer.len, i++)
@@ -188,7 +279,6 @@
temp_html += "<span class='linkOff'>Save to Disk</span>"
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"]
@@ -234,19 +324,6 @@
temp_html += "<a href='?src=[REF(src)];task=injector;num=[i];text=mixed'>UI+UE Injector</a>"
else
temp_html += "<span class='linkOff'>UI+UE Injector</span>"
if(se)
temp_html += "<br>\tSE: [se] "
if(viable_occupant)
temp_html += "<a href='?src=[REF(src)];task=transferbuffer;num=[i];text=se'>Occupant</a>"
else
temp_html += "<span class='linkOff'>Occupant</span>"
temp_html += "<a href='?src=[REF(src)];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_SE]'>Occupant:Delayed</a>"
if(injectorready < world.time )
temp_html += "<a href='?src=[REF(src)];task=injector;num=[i];text=se'>Injector</a>"
else
temp_html += "<span class='linkOff'>Injector</span>"
else
temp_html += "<br>\tSE: No Data"
if(viable_occupant)
temp_html += "<br><a href='?src=[REF(src)];task=setbuffer;num=[i];'>Save to Buffer</a>"
else
@@ -260,58 +337,225 @@
temp_html += "<a href='?src=[REF(src)];task=savedisk;num=[i];'>Save to Disk</a>"
else
temp_html += "<span class='linkOff'>Save to Disk</span>"
if("disk")
temp_html += status
temp_html += buttons
if(diskette)
temp_html += "<h3>[diskette.name]</h3><br>"
temp_html += "<a href='?src=[REF(src)];task=ejectdisk'>Eject Disk</a><br>"
if(LAZYLEN(diskette.mutations))
temp_html += "<table>"
for(var/datum/mutation/human/A in diskette.mutations)
temp_html += "<tr><td><span class='linkOff'>[A.name]</span></td>"
temp_html += "<td><a href='?src=[REF(src)];task=deletediskmut;num=[diskette.mutations.Find(A)];'>Delete</a></td>"
if(LAZYLEN(stored_mutations) < max_storage)
temp_html += "<td><a href='?src=[REF(src)];task=importdiskmut;num=[diskette.mutations.Find(A)];'>Import</a></td>"
else
temp_html += "<td><td><span class='linkOff'>Import</span></td>"
temp_html += "</tr>"
temp_html += "</table>"
else
temp_html += "<br>Load diskette to start ----------"
if("info")
if(LAZYLEN(stored_mutations))
if(LAZYLEN(stored_mutations) >= current_storage)
var/datum/mutation/human/HM = stored_mutations[current_storage]
if(HM)
temp_html += display_sequence(HM.type, current_storage)
else
current_screen = "mainmenu"
if("mutations")
temp_html += status
temp_html += buttons
temp_html += "<h3>Mutation Storage:<br></h3>"
temp_html += "<table>"
for(var/datum/mutation/human/HM in stored_mutations)
var/i = stored_mutations.Find(HM)
temp_html += "<tr><td><a href='?src=[REF(src)];task=inspectstorage;num=[i]'>[HM.name]</a></td>"
temp_html += "<td><a href='?src=[REF(src)];task=exportdiskmut;path=[HM.type]'>Export</a></td>"
temp_html += "<td><a href='?src=[REF(src)];task=deletemut;num=[i]'>Delete</a></td>"
if(combine == HM.type)
temp_html += "<td><span class='linkOff'>Combine</span></td></tr>"
else
temp_html += "<td><a href='?src=[REF(src)];task=combine;num=[i]'>Combine</a></td></tr>"
temp_html += "</table><br>"
temp_html += "<h3>Chromosome Storage:<br></h3>"
temp_html += "<table>"
for(var/i in 1 to stored_chromosomes.len)
var/obj/item/chromosome/CM = stored_chromosomes[i]
temp_html += "<td><a href='?src=[REF(src)];task=ejectchromosome;num=[i]'>[CM.name]</a></td><br>"
temp_html += "</table>"
if("advinjector")
temp_html += status
temp_html += buttons
temp_html += "<div class='line'><div class='statusLabel'><b>Advanced Injectors:</b></div></div><br>"
temp_html += "<div class='statusLine'><a href='?src=[REF(src)];task=add_advinjector;'>New Selection</a></div>"
for(var/A in injector_selection)
temp_html += "<div class='statusDisplay'><b>[A]</b>"
var/list/true_selection = injector_selection[A]
temp_html += "<br>"
for(var/B in true_selection)
var/datum/mutation/human/HM = B
var/mutcolor
switch(HM.quality)
if(POSITIVE)
mutcolor = "good"
if(MINOR_NEGATIVE)
mutcolor = "average"
if(NEGATIVE)
mutcolor = "bad"
temp_html += "<div class='statusLine'><span class='[mutcolor]'>[HM.name] </span>"
temp_html += "<a href='?src=[REF(src)];task=remove_from_advinjector;injector=[A];path=[HM.type];'>Remove</a></div>"
if (injectorready < world.time)
temp_html += "<div class='statusLine'> <a href='?src=[REF(src)];task=advinjector;injector=[A];'>Print Advanced Injector</a>"
else
temp_html += "<div class='statusLine'> <span class='linkOff'>Print Advanced Injector</span>"
temp_html += "<a href='?src=[REF(src)];task=remove_advinjector;injector=[A];'>Remove Injector</a></div>"
temp_html += "<br></div>"
else
temp_html += status
temp_html += buttons
temp_html += "<h1>Radiation Emitter Menu</h1>"
temp_html += "<a href='?src=[REF(src)];task=setstrength;num=[radstrength-1];'>--</a> <a href='?src=[REF(src)];task=setstrength;'>Output Level</a> <a href='?src=[REF(src)];task=setstrength;num=[radstrength+1];'>++</a>"
temp_html += "<br><a href='?src=[REF(src)];task=setduration;num=[radduration-1];'>--</a> <a href='?src=[REF(src)];task=setduration;'>Pulse Duration</a> <a href='?src=[REF(src)];task=setduration;num=[radduration+1];'>++</a>"
temp_html += "<h3>Irradiate Subject</h3>"
temp_html += "<div class='line'><div class='statusLabel'>Unique Identifier:</div><div class='statusValue'><div class='clearBoth'>"
var/max_line_len = 7*DNA_BLOCK_SIZE
temp_html += "<div class='line'><div class='statusLabel'>Genetic Sequence:</div><br>"
if(viable_occupant)
temp_html += "<div class='dnaBlockNumber'>1</div>"
var/char = ""
var/ui_text = viable_occupant.dna.uni_identity
var/len_byte = length(ui_text)
var/char_it = 0
for(var/byte_it = 1, byte_it <= len_byte, byte_it += length(char))
char_it++
char = ui_text[byte_it]
temp_html += "<a class='dnaBlock' href='?src=[REF(src)];task=pulseui;num=[char_it];'>[char]</a>"
if((char_it % max_line_len) == 0)
temp_html += "</div><div class='clearBoth'>"
if((char_it % DNA_BLOCK_SIZE) == 0 && byte_it < len_byte)
temp_html += "<div class='dnaBlockNumber'>[(char_it / DNA_BLOCK_SIZE) + 1]</div>"
if(viable_occupant)
for(var/A in get_mutation_list())
temp_html += display_inactive_sequence(A)
temp_html += "<br>"
else
temp_html += "----"
if(viable_occupant && (current_mutation in get_mutation_list(viable_occupant)))
temp_html += display_sequence(current_mutation)
temp_html += "</div><br>"
else
temp_html += "----"
temp_html += "</div></div></div><br>"
temp_html += "<br><div class='line'><div class='statusLabel'>Structural Enzymes:</div><div class='statusValue'><div class='clearBoth'>"
if(viable_occupant)
temp_html += "<div class='dnaBlockNumber'>1</div>"
var/char = ""
var/se_text = viable_occupant.dna.struc_enzymes
var/len_byte = length(se_text)
var/char_it = 0
for(var/byte_it = 1, byte_it <= len_byte, byte_it += length(char))
char_it++
char = se_text[byte_it]
temp_html += "<a class='dnaBlock' href='?src=[REF(src)];task=pulsese;num=[char_it];'>[char]</a>"
if((char_it % max_line_len) == 0)
temp_html += "</div><div class='clearBoth'>"
if((char_it % DNA_BLOCK_SIZE) == 0 && byte_it < len_byte)
temp_html += "<div class='dnaBlockNumber'>[(char_it / DNA_BLOCK_SIZE) + 1]</div>"
else
temp_html += "----"
temp_html += "</div></div></div>"
temp_html += "----------"
popup.set_content(temp_html.Join())
popup.open()
/obj/machinery/computer/scan_consolenew/proc/display_inactive_sequence(mutation)
var/temp_html = ""
var/class = "unselected"
var/mob/living/carbon/viable_occupant = get_viable_occupant()
if(!viable_occupant)
return
var/location = viable_occupant.dna.mutation_index.Find(mutation) //We do this because we dont want people using sysexp or similair tools to just read the mutations.
if(!location) //Do this only when needed, dont make a list with mutations for every iteration if you dont need to
var/list/mutations = get_mutation_list(TRUE)
if(mutation in mutations)
location = mutations.Find(mutation)
if(mutation == current_mutation)
class = "selected"
if(location > DNA_MUTATION_BLOCKS)
temp_html += "<a class='clean' href='?src=[REF(src)];task=inspect;num=[location];'><img class='[class]' src='dna_extra.gif' width = '65' alt='Extra Mutation'></a>"
else if(mutation in stored_research.discovered_mutations)
temp_html += "<a class='clean' href='?src=[REF(src)];task=inspect;num=[location];'><img class='[class]' src='dna_discovered.gif' width = '65' alt='Discovered Mutation'></a>"
else
temp_html += "<a class='clean' clean href='?src=[REF(src)];task=inspect;num=[location];'><img class='[class]' src='dna_undiscovered.gif' width = '65' alt=Undiscovered Mutation'></a>"
return temp_html
/obj/machinery/computer/scan_consolenew/proc/display_sequence(mutation, storage_slot) //Storage slot is for when viewing from the stored mutations
var/temp_html = ""
if(!mutation)
temp_html += "ERR-"
return
var/mut_name = "Unknown gene"
var/mut_desc = "No information available."
var/alias
var/discovered = FALSE
var/active = FALSE
var/scrambled = FALSE
var/instability
var/mob/living/carbon/viable_occupant = get_viable_occupant()
var/datum/mutation/human/HM = get_valid_mutation(mutation)
if(viable_occupant)
var/datum/mutation/human/M = viable_occupant.dna.get_mutation(mutation)
if(M)
scrambled = M.scrambled
active = TRUE
var/datum/mutation/human/A = GET_INITIALIZED_MUTATION(mutation)
alias = A.alias
if(active && !scrambled)
discover(mutation)
if(stored_research && (mutation in stored_research.discovered_mutations))
mut_name = A.name
mut_desc = A.desc
discovered = TRUE
instability = A.instability
var/extra
if(viable_occupant && !(storage_slot || viable_occupant.dna.mutation_in_sequence(mutation)))
extra = TRUE
if(discovered && !scrambled)
var/mutcolor
switch(A.quality)
if(POSITIVE)
mutcolor = "good"
if(MINOR_NEGATIVE)
mutcolor = "average"
if(NEGATIVE)
mutcolor = "bad"
if(HM)
instability *= GET_MUTATION_STABILIZER(HM)
temp_html += "<div class='statusDisplay'><div class='statusLine'><span class='[mutcolor]'><b>[mut_name]</b></span><small> ([alias])</small><br>"
temp_html += "<div class='statusLine'>Instability : [round(instability)]</span><br>"
else
temp_html += "<div class='statusDisplay'><div class='statusLine'><b>[alias]</b><br>"
temp_html += "<div class='statusLine'>[mut_desc]<br></div>"
if(active && !storage_slot)
if(HM?.can_chromosome && (HM in viable_occupant.dna.mutations))
var/i = viable_occupant.dna.mutations.Find(HM)
var/chromosome_name = "<a href='?src=[REF(src)];task=applychromosome;path=[mutation];num=[i];'>----</a>"
if(HM.chromosome_name)
chromosome_name = HM.chromosome_name
temp_html += "<div class='statusLine'>Chromosome status: [chromosome_name]<br></div>"
temp_html += "<div class='statusLine'>Sequence:<br><br></div>"
if(!scrambled)
for(var/block in 1 to A.blocks)
var/whole_sequence = get_valid_gene_string(mutation)
var/sequence = copytext(whole_sequence, 1+(block-1)*(DNA_SEQUENCE_LENGTH*2),(DNA_SEQUENCE_LENGTH*2*block+1))
temp_html += "<div class='statusLine'><table class='statusDisplay'><tr>"
for(var/i in 1 to DNA_SEQUENCE_LENGTH)
var/num = 1+(i-1)*2
var/genenum = num+(DNA_SEQUENCE_LENGTH*2*(block-1))
temp_html += "<td><div class='statusLine'><span class='dnaBlockNumber'><a href='?src=[REF(src)];task=pulsegene;num=[genenum];path=[mutation];'>[sequence[num]]</span></a></div></td>"
temp_html += "</tr><tr>"
for(var/i in 1 to DNA_SEQUENCE_LENGTH)
temp_html += "<td><div class='statusLine'>|</div></td>"
temp_html += "</tr><tr>"
for(var/i in 1 to DNA_SEQUENCE_LENGTH)
var/num = i*2
var/genenum = num+(DNA_SEQUENCE_LENGTH*2*(block-1))
temp_html += "<td><div class='statusLine'><span class='dnaBlockNumber'><a href='?src=[REF(src)];task=pulsegene;num=[genenum];path=[mutation];'>[sequence[num]]</span></a></div></td>"
temp_html += "</tr></table></div>"
temp_html += "<br><br><br><br><br>"
else
temp_html = "<div class='statusLine'>Sequence unreadable due to unpredictable mutation.</div>"
if((active || storage_slot) && (injectorready < world.time) && !scrambled)
temp_html += "<a href='?src=[REF(src)];task=activator;path=[mutation];slot=[storage_slot];'>Print Activator</a>"
temp_html += "<a href='?src=[REF(src)];task=mutator;path=[mutation];slot;=[storage_slot];'>Print Mutator</a>"
else
temp_html += "<span class='linkOff'>Print Activator</span>"
temp_html += "<span class='linkOff'>Print Mutator</span>"
temp_html += "<br><div class='statusLine'>"
if(storage_slot)
temp_html += "<a href='?src=[REF(src)];task=deletemut;num=[storage_slot];'>Delete</a>"
if((LAZYLEN(stored_mutations) < max_storage) && diskette && !diskette.read_only)
temp_html += "<a href='?src=[REF(src)];task=exportdiskmut;path=[mutation];'>Export</a>"
else
temp_html += "<span class='linkOff'>Export</span>"
temp_html += "<a href='?src=[REF(src)];task=screen;text=mutations;'>Back</a>"
else if(active && !scrambled)
temp_html += "<a href='?src=[REF(src)];task=savemut;path=[mutation];'>Store</a>"
temp_html += "<a href='?src=[REF(src)];task=expand_advinjector;path=[mutation];'>Adv. Injector</a>"
if(extra || scrambled)
temp_html += "<a href='?src=[REF(src)];task=nullify;'>Nullify</a>"
else
temp_html += "<span class='linkOff'>Nullify</span>"
temp_html += "</div></div>"
return temp_html
/obj/machinery/computer/scan_consolenew/Topic(href, href_list)
if(..())
@@ -350,13 +594,15 @@
radstrength = WRAP(num, 1, RADIATION_STRENGTH_MAX+1)
if("screen")
current_screen = href_list["text"]
if("rejuv")
if(viable_occupant && viable_occupant.reagents)
var/potassiodide_amount = viable_occupant.reagents.get_reagent_amount(/datum/reagent/medicine/potass_iodide)
var/can_add = max(min(REJUVENATORS_MAX - potassiodide_amount, REJUVENATORS_INJECT), 0)
viable_occupant.reagents.add_reagent(/datum/reagent/medicine/potass_iodide, can_add)
if("scramble")
if(viable_occupant && (scrambleready < world.time))
viable_occupant.dna.remove_all_mutations(list(MUT_NORMAL, MUT_EXTRA))
viable_occupant.dna.generate_dna_blocks()
scrambleready = world.time + SCRAMBLE_TIMEOUT
to_chat(usr,"<span class'notice'>DNA scrambled.</span>")
viable_occupant.radiation += RADIATION_STRENGTH_MULTIPLIER*50/(connected.damage_coeff ** 2)
if("setbufferlabel")
var/text = sanitize(input(usr, "Input a new label:", "Input an Text", null) as text|null)
var/text = sanitize(input(usr, "Input a new label:", "Input a Text", null) as text|null)
if(num && text)
num = CLAMP(num, 1, NUMBER_OF_BUFFERS)
var/list/buffer_slot = buffer[num]
@@ -368,7 +614,6 @@
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,
"blood_type"=viable_occupant.dna.blood_type
@@ -382,8 +627,6 @@
if("transferbuffer")
if(num && viable_occupant)
switch(href_list["text"]) //Numbers are this high because other way upgrading laser is just not worth the hassle, and i cant think of anything better to inmrove
if("se")
apply_buffer(SCANNER_ACTION_SE,num)
if("ui")
apply_buffer(SCANNER_ACTION_UI,num)
if("ue")
@@ -397,28 +640,6 @@
if(istype(buffer_slot))
var/obj/item/dnainjector/timed/I
switch(href_list["text"])
if("se")
if(buffer_slot["SE"])
I = new /obj/item/dnainjector/timed(loc)
var/powers = 0
for(var/datum/mutation/human/HM in GLOB.good_mutations + GLOB.bad_mutations + GLOB.not_good_mutations)
if(HM.check_block_string(buffer_slot["SE"]))
I.add_mutations.Add(HM)
if(HM in GLOB.good_mutations)
powers += 1
if(HM in GLOB.bad_mutations + GLOB.not_good_mutations)
powers -= 1 //To prevent just unlocking everything to get all powers to a syringe for max tech
else
I.remove_mutations.Add(HM)
var/time_coeff
for(var/datum/mutation/human/HM in I.add_mutations)
if(!time_coeff)
time_coeff = HM.time_coeff
continue
time_coeff = min(time_coeff,HM.time_coeff)
if(connected)
I.duration = I.duration * time_coeff * connected.damage_coeff
I.damage_coeff = connected.damage_coeff
if("ui")
if(buffer_slot["UI"])
I = new /obj/item/dnainjector/timed(loc)
@@ -457,7 +678,7 @@
if("setdelayed")
if(num)
delayed_action = list("action"=text2num(href_list["delayaction"]),"buffer"=num)
if("pulseui","pulsese")
if("pulseui")
if(num && viable_occupant && connected)
radduration = WRAP(radduration, 1, RADIATION_DURATION_MAX+1)
radstrength = WRAP(radstrength, 1, RADIATION_STRENGTH_MAX+1)
@@ -469,7 +690,7 @@
ui_interact(usr)
sleep(radduration*10)
current_screen = "mainmenu"
current_screen = "ui"
if(viable_occupant && connected && connected.occupant==viable_occupant)
viable_occupant.radiation += (RADIATION_IRRADIATION_MULTIPLIER*radduration*radstrength)/(connected.damage_coeff ** 2) //Read comment in "transferbuffer" section above for explanation
@@ -478,7 +699,7 @@
var/len = length_char(viable_occupant.dna.uni_identity)
num = WRAP(num, 1, len+1)
num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len) //Each manipulator level above 1 makes randomization as accurate as selected time + manipulator lvl^2
//Value is this high for the same reason as with laser - not worth the hassle of upgrading if the bonus is low
//Value is this high for the same reason as with laser - not worth the hassle of upgrading if the bonus is low
var/block = round((num-1)/DNA_BLOCK_SIZE)+1
var/subblock = num - block*DNA_BLOCK_SIZE
last_change = "UI #[block]-[subblock]; "
@@ -490,35 +711,229 @@
viable_occupant.dna.uni_identity = copytext_char(viable_occupant.dna.uni_identity, 1, num) + hex + copytext_char(viable_occupant.dna.uni_identity, num + 1)
viable_occupant.updateappearance(mutations_overlay_update=1)
if("pulsese")
var/len = length(viable_occupant.dna.struc_enzymes)
num = WRAP(num, 1, len+1)
num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len)
var/block = round((num-1)/DNA_BLOCK_SIZE)+1
var/subblock = num - block*DNA_BLOCK_SIZE
last_change = "SE #[block]-[subblock]; "
var/hex = copytext_char(viable_occupant.dna.struc_enzymes, num, num+1)
last_change += "[hex]"
hex = scramble(hex, radstrength, radduration)
last_change += "->[hex]"
viable_occupant.dna.struc_enzymes = copytext_char(viable_occupant.dna.struc_enzymes, 1, num) + hex + copytext_char(viable_occupant.dna.struc_enzymes, num + 1)
viable_occupant.domutcheck()
else
current_screen = "mainmenu"
if(connected)
connected.locked = locked_state
if("inspect")
if(viable_occupant)
var/list/mutations = get_mutation_list(TRUE)
if(current_mutation == mutations[num])
current_mutation = null
else
current_mutation = mutations[num]
if("inspectstorage")
current_storage = num
current_screen = "info"
if("savemut")
if(viable_occupant)
var/succes
if(LAZYLEN(stored_mutations) < max_storage)
var/mutation = text2path(href_list["path"])
if(ispath(mutation, /datum/mutation/human)) //sanity checks
var/datum/mutation/human/HM = viable_occupant.dna.get_mutation(mutation)
if(HM)
var/datum/mutation/human/A = new HM.type()
A.copy_mutation(HM)
succes = TRUE
stored_mutations += A
to_chat(usr,"<span class='notice'>Mutation succesfully stored.</span>")
if(!succes) //we can exactly return here
to_chat(usr,"<span class='warning'>Mutation storage is full.</span>")
if("deletemut")
var/datum/mutation/human/HM = stored_mutations[num]
if(HM)
stored_mutations.Remove(HM)
qdel(HM)
current_screen = "mutations"
if("activator")
if(injectorready < world.time)
var/mutation = text2path(href_list["path"])
if(ispath(mutation, /datum/mutation/human))
var/datum/mutation/human/HM = get_valid_mutation(mutation)
if(HM)
var/obj/item/dnainjector/activator/I = new /obj/item/dnainjector/activator(loc)
I.add_mutations += new HM.type (copymut = HM)
I.name = "[HM.name] activator"
I.research = TRUE
if(connected)
I.damage_coeff = connected.damage_coeff*4
injectorready = world.time + INJECTOR_TIMEOUT * (1 - 0.1 * connected.precision_coeff) //precision_coeff being the matter bin rating
else
injectorready = world.time + INJECTOR_TIMEOUT
if("mutator")
if(injectorready < world.time)
var/mutation = text2path(href_list["path"])
if(ispath(mutation, /datum/mutation/human))
var/datum/mutation/human/HM = get_valid_mutation(mutation)
if(HM)
var/obj/item/dnainjector/activator/I = new /obj/item/dnainjector/activator(loc)
I.add_mutations += new HM.type (copymut = HM)
I.doitanyway = TRUE
I.name = "[HM.name] injector"
if(connected)
I.damage_coeff = connected.damage_coeff
injectorready = world.time + INJECTOR_TIMEOUT * 5 * (1 - 0.1 * connected.precision_coeff)
else
injectorready = world.time + INJECTOR_TIMEOUT * 5
if("advinjector")
var/selection = href_list["injector"]
if(injectorready < world.time)
if(injector_selection.Find(selection))
var/list/true_selection = injector_selection[selection]
if(LAZYLEN(injector_selection))
var/obj/item/dnainjector/activator/I = new /obj/item/dnainjector/activator(loc)
for(var/A in true_selection)
var/datum/mutation/human/HM = A
I.add_mutations += new HM.type (copymut = HM)
I.doitanyway = TRUE
I.name = "Advanced [selection] injector"
if(connected)
I.damage_coeff = connected.damage_coeff
injectorready = world.time + INJECTOR_TIMEOUT * 8 * (1 - 0.1 * connected.precision_coeff)
else
injectorready = world.time + INJECTOR_TIMEOUT * 8
if("nullify")
if(viable_occupant)
var/datum/mutation/human/A = viable_occupant.dna.get_mutation(current_mutation)
if(A && (!viable_occupant.dna.mutation_in_sequence(current_mutation) || A.scrambled))
viable_occupant.dna.remove_mutation(current_mutation)
current_screen = "mainmenu"
current_mutation = null
if("pulsegene")
if(current_screen != "info")
var/path = text2path(href_list["path"])
if(viable_occupant && num && (path in viable_occupant.dna.mutation_index))
var/list/genes = list("A","T","G","C","X")
if(jokerready < world.time)
genes += "JOKER"
var/sequence = GET_GENE_STRING(path, viable_occupant.dna)
var/original = sequence[num]
var/new_gene = input("From [original] to-", "New block", original) as null|anything in genes
if(!new_gene)
new_gene = original
if(viable_occupant == get_viable_occupant()) //No cheesing
if((new_gene == "JOKER") && (jokerready < world.time))
var/true_genes = GET_SEQUENCE(current_mutation)
new_gene = true_genes[num]
jokerready = world.time + JOKER_TIMEOUT - (JOKER_UPGRADE * (connected.precision_coeff-1))
sequence = copytext(sequence, 1, num) + new_gene + copytext(sequence, num+1, length(sequence)+1)
viable_occupant.dna.mutation_index[path] = sequence
viable_occupant.radiation += RADIATION_STRENGTH_MULTIPLIER/connected.damage_coeff
viable_occupant.domutcheck()
if("exportdiskmut")
if(diskette && !diskette.read_only)
var/path = text2path(href_list["path"])
if(ispath(path, /datum/mutation/human))
var/datum/mutation/human/A = get_valid_mutation(path)
if(A && diskette && (LAZYLEN(diskette.mutations) < diskette.max_mutations))
var/datum/mutation/human/HM = new A.type()
diskette.mutations += HM
HM.copy_mutation(A)
to_chat(usr, "<span class='notice'>Succesfully written [A.name] to [diskette.name].</span>")
if("deletediskmut")
if(diskette && !diskette.read_only)
if(num && (LAZYLEN(diskette.mutations) >= num))
var/datum/mutation/human/A = diskette.mutations[num]
diskette.mutations.Remove(A)
qdel(A)
if("importdiskmut")
if(diskette && (LAZYLEN(diskette.mutations) >= num))
if(LAZYLEN(stored_mutations) < max_storage)
var/datum/mutation/human/A = diskette.mutations[num]
var/datum/mutation/human/HM = new A.type()
HM.copy_mutation(A)
stored_mutations += HM
to_chat(usr,"<span class='notice'>Succesfully written [A.name] to storage.")
if("combine")
if(num && (LAZYLEN(stored_mutations) >= num))
if(LAZYLEN(stored_mutations) < max_storage)
var/datum/mutation/human/A = stored_mutations[num]
var/path = A.type
if(combine)
var/result_path = get_mixed_mutation(combine, path)
if(result_path)
stored_mutations += new result_path()
to_chat(usr, "<span class='boldnotice'>Succes! New mutation has been added to storage</span>")
discover(result_path)
combine = null
else
to_chat(usr, "<span class='warning'>Failed. No mutation could be created.</span>")
combine = null
else
combine = path
to_chat(usr,"<span class='notice'>Selected [A.name] for combining</span>")
else
to_chat(usr, "<span class='warning'>Not enough space to store potential mutation.</span>")
if("ejectchromosome")
if(LAZYLEN(stored_chromosomes) <= num)
var/obj/item/chromosome/CM = stored_chromosomes[num]
CM.forceMove(drop_location())
adjust_item_drop_location(CM)
stored_chromosomes -= CM
if("applychromosome")
if(viable_occupant && (LAZYLEN(viable_occupant.dna.mutations) <= num))
var/datum/mutation/human/HM = viable_occupant.dna.mutations[num]
var/list/chromosomes = list()
for(var/obj/item/chromosome/CM in stored_chromosomes)
if(CM.can_apply(HM))
chromosomes += CM
if(chromosomes.len)
var/obj/item/chromosome/CM = input("Select a chromosome to apply", "Apply Chromosome") as null|anything in sortNames(chromosomes)
if(CM)
to_chat(usr, "<span class='notice'>You apply [CM] to [HM.name].</span>")
stored_chromosomes -= CM
CM.apply(HM)
if("expand_advinjector")
var/mutation = text2path(href_list["path"])
var/datum/mutation/human/HM = get_valid_mutation(mutation)
if(HM && LAZYLEN(injector_selection))
var/which_injector = input(usr, "Select Adv. Injector", "Advanced Injectors") as null|anything in injector_selection
if(injector_selection.Find(which_injector))
var/list/true_selection = injector_selection[which_injector]
var/total_instability
for(var/B in true_selection)
var/datum/mutation/human/mootacion = B
total_instability += mootacion.instability
total_instability += HM.instability
if((total_instability > max_injector_instability) || (true_selection.len + 1) > max_injector_mutations)
to_chat(usr, "<span class='warning'>Adding more mutations would make the advanced injector too unstable!</span>")
else
true_selection += HM //reminder that this works. because I keep forgetting this works
if("remove_from_advinjector")
var/mutation = text2path(href_list["path"])
var/selection = href_list["injector"]
if(injector_selection.Find(selection))
var/list/true_selection = injector_selection[selection]
for(var/B in true_selection)
var/datum/mutation/human/HM = B
if(HM.type == mutation)
true_selection -= HM
break
if("remove_advinjector")
var/selection = href_list["injector"]
for(selection in injector_selection)
if(selection == selection)
injector_selection.Remove(selection)
if("add_advinjector")
if(LAZYLEN(injector_selection) < max_injector_selections)
var/new_selection = input(usr, "Enter Adv. Injector name", "Advanced Injectors") as text|null
if(new_selection && !(new_selection in injector_selection))
injector_selection[new_selection] = list()
ui_interact(usr,last_change)
/obj/machinery/computer/scan_consolenew/proc/scramble(input,rs,rd)
/obj/machinery/computer/scan_consolenew/proc/scramble(input,rs,rd) //hexadecimal genetics. dont confuse with scramble button
var/length = length(input)
var/ran = gaussian(0, rs*RADIATION_STRENGTH_MULTIPLIER)
if(ran == 0)
ran = pick(-1,1) //hacky, statistically should almost never happen. 0-change makes people mad though
ran = pick(-1,1) //hacky, statistically should almost never happen. 0-chance makes people mad though
else if(ran < 0)
ran = round(ran) //negative, so floor it
else
@@ -547,10 +962,6 @@
//Each laser level reduces damage by lvl^2, so no effect on 1 lvl, 4 times less damage on 2 and 9 times less damage on 3
//Numbers are this high because other way upgrading laser is just not worth the hassle, and i cant think of anything better to inmrove
switch(action)
if(SCANNER_ACTION_SE)
if(buffer_slot["SE"])
viable_occupant.dna.struc_enzymes = buffer_slot["SE"]
viable_occupant.domutcheck()
if(SCANNER_ACTION_UI)
if(buffer_slot["UI"])
viable_occupant.dna.uni_identity = buffer_slot["UI"]
@@ -572,15 +983,54 @@
viable_occupant.dna.blood_type = buffer_slot["blood_type"]
/obj/machinery/computer/scan_consolenew/proc/on_scanner_close()
if(delayed_action && connected)
if(delayed_action && get_viable_occupant())
to_chat(connected.occupant, "<span class='notice'>[src] activates!</span>")
apply_buffer(delayed_action["action"],delayed_action["buffer"])
delayed_action = null //or make it stick + reset button ?
/obj/machinery/computer/scan_consolenew/proc/get_valid_mutation(mutation)
var/mob/living/carbon/C = get_viable_occupant()
if(C)
var/datum/mutation/human/HM = C.dna.get_mutation(mutation)
if(HM)
return HM
for(var/datum/mutation/human/A in stored_mutations)
if(A.type == mutation)
return A
/obj/machinery/computer/scan_consolenew/proc/get_mutation_list(include_storage) //Returns a list of the mutation index types and any extra mutations
var/mob/living/carbon/viable_occupant = get_viable_occupant()
var/list/paths = list()
if(viable_occupant)
for(var/A in viable_occupant.dna.mutation_index)
paths += A
for(var/datum/mutation/human/A in viable_occupant.dna.mutations)
if(A.class == MUT_EXTRA)
paths += A.type
if(include_storage)
for(var/datum/mutation/human/A in stored_mutations)
paths += A.type
return paths
/obj/machinery/computer/scan_consolenew/proc/get_valid_gene_string(mutation)
var/mob/living/carbon/C = get_viable_occupant()
if(C && (mutation in C.dna.mutation_index))
return GET_GENE_STRING(mutation, C.dna)
else if(C && (LAZYLEN(C.dna.mutations)))
for(var/datum/mutation/human/A in C.dna.mutations)
if(A.type == mutation)
return GET_SEQUENCE(mutation)
for(var/datum/mutation/human/A in stored_mutations)
if(A.type == mutation)
return GET_SEQUENCE(mutation)
/obj/machinery/computer/scan_consolenew/proc/discover(mutation)
if(stored_research && !(mutation in stored_research.discovered_mutations))
stored_research.discovered_mutations += mutation
return TRUE
/////////////////////////// DNA MACHINES
#undef INJECTOR_TIMEOUT
#undef REJUVENATORS_INJECT
#undef REJUVENATORS_MAX
#undef NUMBER_OF_BUFFERS
#undef RADIATION_STRENGTH_MAX
+1 -1
View File
@@ -22,7 +22,7 @@
precision_coeff = 0
for(var/obj/item/stock_parts/scanning_module/P in component_parts)
scan_level += P.rating
for(var/obj/item/stock_parts/manipulator/P in component_parts)
for(var/obj/item/stock_parts/matter_bin/P in component_parts)
precision_coeff = P.rating
for(var/obj/item/stock_parts/micro_laser/P in component_parts)
damage_coeff = P.rating
+13 -13
View File
@@ -9,7 +9,7 @@
internal_radio = FALSE
//Start growing a human clone in the pod!
/obj/machinery/clonepod/experimental/growclone(ckey, clonename, ui, se, datum/species/mrace, list/features, factions)
/obj/machinery/clonepod/experimental/growclone(clonename, ui, mutation_index, mindref, last_death, blood_type, datum/species/mrace, list/features, factions, list/quirks)
if(panel_open)
return FALSE
if(mess || attempting)
@@ -20,15 +20,15 @@
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
H.hardset_dna(ui, se, H.real_name, null, mrace, features)
H.hardset_dna(ui, mutation_index, H.real_name, blood_type, mrace, features)
if(efficiency > 2)
var/list/unclean_mutations = (GLOB.not_good_mutations|GLOB.bad_mutations)
H.dna.remove_mutation_group(unclean_mutations)
if(efficiency > 5 && prob(20))
H.randmutvg()
H.easy_randmut(POSITIVE)
if(efficiency < 3 && prob(50))
var/mob/M = H.randmutb()
var/mob/M = H.easy_randmut(NEGATIVE+MINOR_NEGATIVE)
if(ismob(M))
H = M
@@ -42,18 +42,17 @@
icon_state = "pod_1"
//Get the clone body ready
maim_clone(H)
ADD_TRAIT(H, TRAIT_STABLEHEART, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_STABLELIVER, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_EMOTEMUTE, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_MUTE, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_NOBREATH, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_STABLEHEART, "cloning")
ADD_TRAIT(H, TRAIT_EMOTEMUTE, "cloning")
ADD_TRAIT(H, TRAIT_MUTE, "cloning")
ADD_TRAIT(H, TRAIT_NOBREATH, "cloning")
ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, "cloning")
H.Unconscious(80)
var/list/candidates = pollCandidatesForMob("Do you want and agree to play as a [clonename]'s defective clone, respect their character and not engage in ERP without permission from the original?", null, null, null, 100, H, POLL_IGNORE_CLONE)
var/list/candidates = pollCandidatesForMob("Do you want to play as [clonename]'s defective clone?", null, null, null, 100, H)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
C.transfer_ckey(H)
H.key = C.key
if(grab_ghost_when == CLONER_FRESH_CLONE)
H.grab_ghost()
@@ -293,6 +292,7 @@
temp = "<font class='bad'>Cloning cycle already in progress.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else
pod.growclone(null, mob_occupant.real_name, dna.uni_identity, dna.struc_enzymes, clone_species, dna.features, mob_occupant.faction)
pod.growclone(mob_occupant.real_name, dna.uni_identity, dna.mutation_index, null, null, dna.blood_type, clone_species, dna.features, mob_occupant.faction)
temp = "[mob_occupant.real_name] => <font class='good'>Cloning data sent to pod.</font>"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
@@ -283,13 +283,13 @@
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_charge()
if(equip_ready) //disabled
return
var/area/A = get_base_area(chassis)
var/pow_chan = get_power_channel(A)
var/area/A = get_area(chassis)
var/pow_chan = get_MUTATION_POWER_channel(A)
if(pow_chan)
return 1000 //making magic
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_power_channel(var/area/A)
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_MUTATION_POWER_channel(var/area/A)
var/pow_chan
if(A)
for(var/c in use_channels)
+24
View File
@@ -28,6 +28,7 @@
take_damage(5, BURN, 0, 0)
/obj/structure/spider/stickyweb
var/genetic = FALSE
icon_state = "stickyweb1"
/obj/structure/spider/stickyweb/Initialize()
@@ -36,6 +37,8 @@
. = ..()
/obj/structure/spider/stickyweb/CanPass(atom/movable/mover, turf/target)
if (genetic)
return
if(istype(mover, /mob/living/simple_animal/hostile/poison/giant_spider))
return TRUE
else if(isliving(mover))
@@ -48,6 +51,27 @@
return prob(30)
return TRUE
/obj/structure/spider/stickyweb/genetic //for the spider genes in genetics
genetic = TRUE
var/mob/living/allowed_mob
/obj/structure/spider/stickyweb/genetic/Initialize(mapload, allowedmob)
allowed_mob = allowedmob
. = ..()
/obj/structure/spider/stickyweb/genetic/CanPass(atom/movable/mover, turf/target)
. = ..() //this is the normal spider web return aka a spider would make this TRUE
if(mover == allowed_mob)
return TRUE
else if(isliving(mover)) //we change the spider to not be able to go through here
if(mover.pulledby == allowed_mob)
return TRUE
if(prob(50))
to_chat(mover, "<span class='danger'>You get stuck in \the [src] for a moment.</span>")
return FALSE
else if(istype(mover, /obj/item/projectile))
return prob(30)
/obj/structure/spider/eggcluster
name = "egg cluster"
desc = "They seem to pulse slightly with an inner life."
+6
View File
@@ -850,3 +850,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
if (HAS_TRAIT(src, TRAIT_NODROP))
return
return ..()
/obj/item/proc/embedded(mob/living/carbon/human/embedded_mob)
return
/obj/item/proc/unembedded()
return
+92
View File
@@ -0,0 +1,92 @@
/obj/item/chromosome
name = "blank chromosome"
icon = 'icons/obj/chromosomes.dmi'
icon_state = ""
desc = "A tube holding chromosomic data."
force = 0
w_class = WEIGHT_CLASS_SMALL
var/stabilizer_coeff = 1 //lower is better, affects genetic stability
var/synchronizer_coeff = 1 //lower is better, affects chance to backfire
var/power_coeff = 1 //higher is better, affects "strength"
var/energy_coeff = 1 //lower is better. affects recharge time
var/weight = 5
/obj/item/chromosome/proc/can_apply(datum/mutation/human/HM)
if(!HM || !(HM.can_chromosome == CHROMOSOME_NONE))
return FALSE
if((stabilizer_coeff != 1) && (HM.stabilizer_coeff != -1)) //if the chromosome is 1, we dont change anything. If the mutation is -1, we cant change it. sorry
return TRUE
if((synchronizer_coeff != 1) && (HM.synchronizer_coeff != -1))
return TRUE
if((power_coeff != 1) && (HM.power_coeff != -1))
return TRUE
if((energy_coeff != 1) && (HM.energy_coeff != -1))
return TRUE
/obj/item/chromosome/proc/apply(datum/mutation/human/HM)
if(HM.stabilizer_coeff != -1)
HM.stabilizer_coeff = stabilizer_coeff
if(HM.synchronizer_coeff != -1)
HM.synchronizer_coeff = synchronizer_coeff
if(HM.power_coeff != -1)
HM.power_coeff = power_coeff
if(HM.energy_coeff != -1)
HM.energy_coeff = energy_coeff
HM.can_chromosome = 2
HM.chromosome_name = name
HM.modify()
qdel(src)
/proc/generate_chromosome()
var/static/list/chromosomes
if(!chromosomes)
chromosomes = list()
for(var/A in subtypesof(/obj/item/chromosome))
var/obj/item/chromosome/CM = A
if(!initial(CM.weight))
break
chromosomes[A] = initial(CM.weight)
return pickweight(chromosomes)
/obj/item/chromosome/stabilizer
name = "stabilizer chromosome"
desc = "A chromosome that adjusts to the body to reduce genetic damage by 20%."
icon_state = "stabilizer"
stabilizer_coeff = 0.8
weight = 1
/obj/item/chromosome/synchronizer
name = "synchronizer chromosome"
desc = "A chromosome that gives the mind more controle over the mutation, reducing knockback and downsides by 50%."
icon_state = "synchronizer"
synchronizer_coeff = 0.5
/obj/item/chromosome/power
name = "power chromosome"
desc = "A power chromosome for boosting certain mutation's power by 50%."
icon_state = "power"
power_coeff = 1.5
/obj/item/chromosome/energy
name = "energetic chromosome"
desc = "A chromosome that reduces cooldown on action based mutations by 50%."
icon_state = "energy"
energy_coeff = 0.5
/obj/item/chromosome/reinforcer
name = "reinforcement chromosome"
desc = "Renders the mutation immune to mutadone."
icon_state = "reinforcer"
weight = 3
/obj/item/chromosome/reinforcer/can_apply(datum/mutation/human/HM)
if(!HM || !(HM.can_chromosome == CHROMOSOME_NONE))
return FALSE
return !HM.mutadone_proof
/obj/item/chromosome/reinforcer/apply(datum/mutation/human/HM)
HM.mutadone_proof = TRUE
..()
@@ -74,7 +74,7 @@
build_path = /obj/machinery/dna_scannernew
req_components = list(
/obj/item/stock_parts/scanning_module = 1,
/obj/item/stock_parts/manipulator = 1,
/obj/item/stock_parts/matter_bin = 1,
/obj/item/stock_parts/micro_laser = 1,
/obj/item/stack/sheet/glass = 1,
/obj/item/stack/cable_coil = 2)
+105 -1
View File
@@ -150,7 +150,10 @@ SLIME SCANNER
msg += "\n\t<span class='alert'>Subject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage.</span>"
if(advanced)
msg += "\n\t<span class='info'>Cellular Damage Level: [M.getCloneLoss()].</span>"
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(advanced && H.has_dna())
msg += "\n\t<span class='info'>Genetic Stability: [H.dna.stability]%.</span>"
to_chat(user, msg)
msg = ""
@@ -776,3 +779,104 @@ SLIME SCANNER
var/response = SEND_SIGNAL(M, COMSIG_NANITE_SCAN, user, TRUE)
if(!response)
to_chat(user, "<span class='info'>No nanites detected in the subject.</span>")
/obj/item/sequence_scanner
name = "genetic sequence scanner"
icon = 'icons/obj/device.dmi'
icon_state = "gene"
item_state = "healthanalyzer"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
desc = "A hand-held scanner for analyzing someones gene sequence on the fly. Hold near a DNA console to update the internal database."
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
slot_flags = ITEM_SLOT_BELT
throwforce = 3
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
custom_materials = list(/datum/material/iron=200)
var/list/discovered = list() //hit a dna console to update the scanners database
var/list/buffer
var/ready = TRUE
var/cooldown = 200
/obj/item/sequence_scanner/attack(mob/living/M, mob/living/carbon/human/user)
add_fingerprint(user)
if (!HAS_TRAIT(M, TRAIT_RADIMMUNE)) //no scanning if its a husk or DNA-less Species
user.visible_message("<span class='notice'>[user] analyzes [M]'s genetic sequence.</span>", \
"<span class='notice'>You analyze [M]'s genetic sequence.</span>")
gene_scan(M, user)
else
user.visible_message("<span class='notice'>[user] failed to analyse [M]'s genetic sequence.</span>", "<span class='warning'>[M] has no readable genetic sequence!</span>")
/obj/item/sequence_scanner/attack_self(mob/user)
display_sequence(user)
/obj/item/sequence_scanner/attack_self_tk(mob/user)
return
/obj/item/sequence_scanner/afterattack(obj/O, mob/user, proximity)
. = ..()
if(!istype(O) || !proximity)
return
if(istype(O, /obj/machinery/computer/scan_consolenew))
var/obj/machinery/computer/scan_consolenew/C = O
if(C.stored_research)
to_chat(user, "<span class='notice'>[name] linked to central research database.</span>")
discovered = C.stored_research.discovered_mutations
else
to_chat(user,"<span class='warning'>No database to update from.</span>")
/obj/item/sequence_scanner/proc/gene_scan(mob/living/carbon/C, mob/living/user)
if(!iscarbon(C) || !C.has_dna())
return
buffer = C.dna.mutation_index
to_chat(user, "<span class='notice'>Subject [C.name]'s DNA sequence has been saved to buffer.</span>")
if(LAZYLEN(buffer))
for(var/A in buffer)
to_chat(user, "<span class='notice'>[get_display_name(A)]</span>")
/obj/item/sequence_scanner/proc/display_sequence(mob/living/user)
if(!LAZYLEN(buffer) || !ready)
return
var/list/options = list()
for(var/A in buffer)
options += get_display_name(A)
var/answer = input(user, "Analyze Potential", "Sequence Analyzer") as null|anything in sortList(options)
if(answer && ready && user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
var/sequence
for(var/A in buffer) //this physically hurts but i dont know what anything else short of an assoc list
if(get_display_name(A) == answer)
sequence = buffer[A]
break
if(sequence)
var/display
for(var/i in 0 to length_char(sequence) / DNA_MUTATION_BLOCKS-1)
if(i)
display += "-"
display += copytext_char(sequence, 1 + i*DNA_MUTATION_BLOCKS, DNA_MUTATION_BLOCKS*(1+i) + 1)
to_chat(user, "<span class='boldnotice'>[display]</span><br>")
ready = FALSE
icon_state = "[icon_state]_recharging"
addtimer(CALLBACK(src, .proc/recharge), cooldown, TIMER_UNIQUE)
/obj/item/sequence_scanner/proc/recharge()
icon_state = initial(icon_state)
ready = TRUE
/obj/item/sequence_scanner/proc/get_display_name(mutation)
var/datum/mutation/human/HM = GET_INITIALIZED_MUTATION(mutation)
if(!HM)
return "ERROR"
if(mutation in discovered)
return "[HM.name] ([HM.alias])"
else
return HM.alias
+256 -75
View File
@@ -14,33 +14,25 @@
var/list/add_mutations = list()
var/list/remove_mutations = list()
var/list/add_mutations_static = list()
var/list/remove_mutations_static = list()
var/used = 0
/obj/item/dnainjector/attack_paw(mob/user)
return attack_hand(user)
/obj/item/dnainjector/proc/prepare()
for(var/mut_key in add_mutations_static)
add_mutations.Add(GLOB.mutations_list[mut_key])
for(var/mut_key in remove_mutations_static)
remove_mutations.Add(GLOB.mutations_list[mut_key])
/obj/item/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
prepare()
if(M.has_dna() && !HAS_TRAIT(M, TRAIT_RADIMMUNE) && !HAS_TRAIT(M, TRAIT_NOCLONE))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/datum/mutation/human/HM in remove_mutations)
HM.force_lose(M)
for(var/datum/mutation/human/HM in add_mutations)
if(HM.name == RACEMUT)
for(var/HM in remove_mutations)
M.dna.remove_mutation(HM)
for(var/HM in add_mutations)
if(HM == RACEMUT)
message_admins("[ADMIN_LOOKUPFLW(user)] injected [key_name_admin(M)] with the [name] <span class='danger'>(MONKEY)</span>")
log_msg += " (MONKEY)"
HM.force_give(M)
if(M.dna.mutation_in_sequence(HM))
M.dna.activate_mutation(HM)
else
M.dna.add_mutation(HM, MUT_EXTRA)
if(fields)
if(fields["name"] && fields["UE"] && fields["blood_type"])
M.real_name = fields["name"]
@@ -90,123 +82,123 @@
/obj/item/dnainjector/antihulk
name = "\improper DNA injector (Anti-Hulk)"
desc = "Cures green skin."
remove_mutations_static = list(HULK)
remove_mutations = list(HULK)
/obj/item/dnainjector/hulkmut
name = "\improper DNA injector (Hulk)"
desc = "This will make you big and strong, but give you a bad skin condition."
add_mutations_static = list(HULK)
add_mutations = list(HULK)
/obj/item/dnainjector/xraymut
name = "\improper DNA injector (X-ray)"
desc = "Finally you can see what the Captain does."
add_mutations_static = list(XRAY)
add_mutations = list(XRAY)
/obj/item/dnainjector/antixray
name = "\improper DNA injector (Anti-X-ray)"
desc = "It will make you see harder."
remove_mutations_static = list(XRAY)
remove_mutations = list(XRAY)
/////////////////////////////////////
/obj/item/dnainjector/antiglasses
name = "\improper DNA injector (Anti-Glasses)"
desc = "Toss away those glasses!"
remove_mutations_static = list(BADSIGHT)
remove_mutations = list(BADSIGHT)
/obj/item/dnainjector/glassesmut
name = "\improper DNA injector (Glasses)"
desc = "Will make you need dorkish glasses."
add_mutations_static = list(BADSIGHT)
add_mutations = list(BADSIGHT)
/obj/item/dnainjector/epimut
name = "\improper DNA injector (Epi.)"
desc = "Shake shake shake the room!"
add_mutations_static = list(EPILEPSY)
add_mutations = list(EPILEPSY)
/obj/item/dnainjector/antiepi
name = "\improper DNA injector (Anti-Epi.)"
desc = "Will fix you up from shaking the room."
remove_mutations_static = list(EPILEPSY)
remove_mutations = list(EPILEPSY)
////////////////////////////////////
/obj/item/dnainjector/anticough
name = "\improper DNA injector (Anti-Cough)"
desc = "Will stop that awful noise."
remove_mutations_static = list(COUGH)
remove_mutations = list(COUGH)
/obj/item/dnainjector/coughmut
name = "\improper DNA injector (Cough)"
desc = "Will bring forth a sound of horror from your throat."
add_mutations_static = list(COUGH)
add_mutations = list(COUGH)
/obj/item/dnainjector/antidwarf
name = "\improper DNA injector (Anti-Dwarfism)"
desc = "Helps you grow big and strong."
remove_mutations_static = list(DWARFISM)
remove_mutations = list(DWARFISM)
/obj/item/dnainjector/dwarf
name = "\improper DNA injector (Dwarfism)"
desc = "It's a small world after all."
add_mutations_static = list(DWARFISM)
add_mutations = list(DWARFISM)
/obj/item/dnainjector/clumsymut
name = "\improper DNA injector (Clumsy)"
desc = "Makes clown minions."
add_mutations_static = list(CLOWNMUT)
add_mutations = list(CLOWNMUT)
/obj/item/dnainjector/anticlumsy
name = "\improper DNA injector (Anti-Clumsy)"
desc = "Apply this for Security Clown."
remove_mutations_static = list(CLOWNMUT)
remove_mutations = list(CLOWNMUT)
/obj/item/dnainjector/antitour
name = "\improper DNA injector (Anti-Tour.)"
desc = "Will cure Tourette's."
remove_mutations_static = list(TOURETTES)
remove_mutations = list(TOURETTES)
/obj/item/dnainjector/tourmut
name = "\improper DNA injector (Tour.)"
desc = "Gives you a nasty case of Tourette's."
add_mutations_static = list(TOURETTES)
add_mutations = list(TOURETTES)
/obj/item/dnainjector/stuttmut
name = "\improper DNA injector (Stutt.)"
desc = "Makes you s-s-stuttterrr."
add_mutations_static = list(NERVOUS)
add_mutations = list(NERVOUS)
/obj/item/dnainjector/antistutt
name = "\improper DNA injector (Anti-Stutt.)"
desc = "Fixes that speaking impairment."
remove_mutations_static = list(NERVOUS)
remove_mutations = list(NERVOUS)
/obj/item/dnainjector/antifire
name = "\improper DNA injector (Anti-Fire)"
desc = "Cures fire."
remove_mutations_static = list(COLDRES)
remove_mutations = list(SPACEMUT)
/obj/item/dnainjector/firemut
name = "\improper DNA injector (Fire)"
desc = "Gives you fire."
add_mutations_static = list(COLDRES)
add_mutations = list(SPACEMUT)
/obj/item/dnainjector/blindmut
name = "\improper DNA injector (Blind)"
desc = "Makes you not see anything."
add_mutations_static = list(BLINDMUT)
add_mutations = list(BLINDMUT)
/obj/item/dnainjector/antiblind
name = "\improper DNA injector (Anti-Blind)"
desc = "IT'S A MIRACLE!!!"
remove_mutations_static = list(BLINDMUT)
remove_mutations = list(BLINDMUT)
/obj/item/dnainjector/antitele
name = "\improper DNA injector (Anti-Tele.)"
desc = "Will make you not able to control your mind."
remove_mutations_static = list(TK)
remove_mutations = list(TK)
/obj/item/dnainjector/telemut
name = "\improper DNA injector (Tele.)"
desc = "Super brain man!"
add_mutations_static = list(TK)
add_mutations = list(TK)
/obj/item/dnainjector/telemut/darkbundle
name = "\improper DNA injector"
@@ -215,100 +207,258 @@
/obj/item/dnainjector/deafmut
name = "\improper DNA injector (Deaf)"
desc = "Sorry, what did you say?"
add_mutations_static = list(DEAFMUT)
add_mutations = list(DEAFMUT)
/obj/item/dnainjector/antideaf
name = "\improper DNA injector (Anti-Deaf)"
desc = "Will make you hear once more."
remove_mutations_static = list(DEAFMUT)
remove_mutations = list(DEAFMUT)
/obj/item/dnainjector/h2m
name = "\improper DNA injector (Human > Monkey)"
desc = "Will make you a flea bag."
add_mutations_static = list(RACEMUT)
add_mutations = list(RACEMUT)
/obj/item/dnainjector/m2h
name = "\improper DNA injector (Monkey > Human)"
desc = "Will make you...less hairy."
remove_mutations_static = list(RACEMUT)
remove_mutations = list(RACEMUT)
/obj/item/dnainjector/antichameleon
name = "\improper DNA injector (Anti-Chameleon)"
remove_mutations_static = list(CHAMELEON)
remove_mutations = list(CHAMELEON)
/obj/item/dnainjector/chameleonmut
name = "\improper DNA injector (Chameleon)"
add_mutations_static = list(CHAMELEON)
add_mutations = list(CHAMELEON)
/obj/item/dnainjector/antiwacky
name = "\improper DNA injector (Anti-Wacky)"
remove_mutations_static = list(WACKY)
remove_mutations = list(WACKY)
/obj/item/dnainjector/wackymut
name = "\improper DNA injector (Wacky)"
add_mutations_static = list(WACKY)
add_mutations = list(WACKY)
/obj/item/dnainjector/antimute
name = "\improper DNA injector (Anti-Mute)"
remove_mutations_static = list(MUT_MUTE)
remove_mutations = list(MUT_MUTE)
/obj/item/dnainjector/mutemut
name = "\improper DNA injector (Mute)"
add_mutations_static = list(MUT_MUTE)
add_mutations = list(MUT_MUTE)
/obj/item/dnainjector/antismile
name = "\improper DNA injector (Anti-Smile)"
remove_mutations_static = list(SMILE)
remove_mutations = list(SMILE)
/obj/item/dnainjector/smilemut
name = "\improper DNA injector (Smile)"
add_mutations_static = list(SMILE)
add_mutations = list(SMILE)
/obj/item/dnainjector/unintelligiblemut
name = "\improper DNA injector (Unintelligible)"
add_mutations_static = list(UNINTELLIGIBLE)
add_mutations = list(UNINTELLIGIBLE)
/obj/item/dnainjector/antiunintelligible
name = "\improper DNA injector (Anti-Unintelligible)"
remove_mutations_static = list(UNINTELLIGIBLE)
remove_mutations = list(UNINTELLIGIBLE)
/obj/item/dnainjector/swedishmut
name = "\improper DNA injector (Swedish)"
add_mutations_static = list(SWEDISH)
add_mutations = list(SWEDISH)
/obj/item/dnainjector/antiswedish
name = "\improper DNA injector (Anti-Swedish)"
remove_mutations_static = list(SWEDISH)
remove_mutations = list(SWEDISH)
/obj/item/dnainjector/chavmut
name = "\improper DNA injector (Chav)"
add_mutations_static = list(CHAV)
add_mutations = list(CHAV)
/obj/item/dnainjector/antichav
name = "\improper DNA injector (Anti-Chav)"
remove_mutations_static = list(CHAV)
remove_mutations = list(CHAV)
/obj/item/dnainjector/elvismut
name = "\improper DNA injector (Elvis)"
add_mutations_static = list(ELVIS)
add_mutations = list(ELVIS)
/obj/item/dnainjector/antielvis
name = "\improper DNA injector (Anti-Elvis)"
remove_mutations_static = list(ELVIS)
remove_mutations = list(ELVIS)
/obj/item/dnainjector/lasereyesmut
name = "\improper DNA injector (Laser Eyes)"
add_mutations_static = list(LASEREYES)
add_mutations = list(LASEREYES)
/obj/item/dnainjector/antilasereyes
name = "\improper DNA injector (Anti-Laser Eyes)"
remove_mutations_static = list(LASEREYES)
remove_mutations = list(LASEREYES)
/obj/item/dnainjector/void
name = "\improper DNA injector (Void)"
add_mutations = list(VOID)
/obj/item/dnainjector/antivoid
name = "\improper DNA injector (Anti-Void)"
remove_mutations = list(VOID)
/obj/item/dnainjector/antenna
name = "\improper DNA injector (Antenna)"
add_mutations = list(ANTENNA)
/obj/item/dnainjector/antiantenna
name = "\improper DNA injector (Anti-Antenna)"
remove_mutations = list(ANTENNA)
/obj/item/dnainjector/paranoia
name = "\improper DNA injector (Paranoia)"
add_mutations = list(PARANOIA)
/obj/item/dnainjector/antiparanoia
name = "\improper DNA injector (Anti-Paranoia)"
remove_mutations = list(PARANOIA)
/obj/item/dnainjector/mindread
name = "\improper DNA injector (Mindread)"
add_mutations = list(MINDREAD)
/obj/item/dnainjector/antimindread
name = "\improper DNA injector (Anti-Mindread)"
remove_mutations = list(MINDREAD)
/obj/item/dnainjector/radioactive
name = "\improper DNA injector (Radioactive)"
add_mutations = list(RADIOACTIVE)
/obj/item/dnainjector/antiradioactive
name = "\improper DNA injector (Anti-Radioactive)"
remove_mutations = list(RADIOACTIVE)
/obj/item/dnainjector/olfaction
name = "\improper DNA injector (Olfaction)"
add_mutations = list(OLFACTION)
/obj/item/dnainjector/antiolfaction
name = "\improper DNA injector (Anti-Olfaction)"
remove_mutations = list(OLFACTION)
/obj/item/dnainjector/insulated
name = "\improper DNA injector (Insulated)"
add_mutations = list(INSULATED)
/obj/item/dnainjector/antiinsulated
name = "\improper DNA injector (Anti-Insulated)"
remove_mutations = list(INSULATED)
/obj/item/dnainjector/shock
name = "\improper DNA injector (Shock Touch)"
add_mutations = list(SHOCKTOUCH)
/obj/item/dnainjector/antishock
name = "\improper DNA injector (Anti-Shock Touch)"
remove_mutations = list(SHOCKTOUCH)
/obj/item/dnainjector/spacialinstability
name = "\improper DNA injector (Spacial Instability)"
add_mutations = list(BADBLINK)
/obj/item/dnainjector/antispacialinstability
name = "\improper DNA injector (Anti-Spacial Instability)"
remove_mutations = list(BADBLINK)
/obj/item/dnainjector/acidflesh
name = "\improper DNA injector (Acid Flesh)"
add_mutations = list(ACIDFLESH)
/obj/item/dnainjector/antiacidflesh
name = "\improper DNA injector (Acid Flesh)"
remove_mutations = list(ACIDFLESH)
/obj/item/dnainjector/gigantism
name = "\improper DNA injector (Gigantism)"
add_mutations = list(GIGANTISM)
/obj/item/dnainjector/antigigantism
name = "\improper DNA injector (Anti-Gigantism)"
remove_mutations = list(GIGANTISM)
/obj/item/dnainjector/spastic
name = "\improper DNA injector (Spastic)"
add_mutations = list(SPASTIC)
/obj/item/dnainjector/antispastic
name = "\improper DNA injector (Anti-Spastic)"
remove_mutations = list(SPASTIC)
/obj/item/dnainjector/geladikinesis
name = "\improper DNA injector (Geladikinesis)"
add_mutations = list(GELADIKINESIS)
/obj/item/dnainjector/antigeladikinesis
name = "\improper DNA injector (Anti-Geladikinesis)"
remove_mutations = list(GELADIKINESIS)
/obj/item/dnainjector/cryokinesis
name = "\improper DNA injector (Cryokinesis)"
add_mutations = list(CRYOKINESIS)
/obj/item/dnainjector/anticryokinesis
name = "\improper DNA injector (Anti-Cryokinesis)"
remove_mutations = list(CRYOKINESIS)
/obj/item/dnainjector/thermal
name = "\improper DNA injector (Thermal Vision)"
add_mutations = list(THERMAL)
/obj/item/dnainjector/antithermal
name = "\improper DNA injector (Anti-Thermal Vision)"
remove_mutations = list(THERMAL)
/obj/item/dnainjector/glow
name = "\improper DNA injector (Glowy)"
add_mutations = list(GLOWY)
/obj/item/dnainjector/removeglow
name = "\improper DNA injector (Anti-Glowy)"
remove_mutations = list(GLOWY)
/obj/item/dnainjector/antiglow
name = "\improper DNA injector (Antiglowy)"
add_mutations = list(ANTIGLOWY)
/obj/item/dnainjector/removeantiglow
name = "\improper DNA injector (Anti-Antiglowy)"
remove_mutations = list(ANTIGLOWY)
/obj/item/dnainjector/firebreath
name = "\improper DNA injector (Firebreath)"
add_mutations = list(FIREBREATH)
/obj/item/dnainjector/antifirebreath
name = "\improper DNA injector (Anti-Firebreath)"
remove_mutations = list(FIREBREATH)
/obj/item/dnainjector/tonguespike
name = "\improper DNA injector (Tongue Spike)"
add_mutations = list(TONGUESPIKE)
/obj/item/dnainjector/antitonguespike
name = "\improper DNA injector (Anti-Tongue Spike)"
remove_mutations = list(TONGUESPIKE)
/obj/item/dnainjector/spiderweb
name = "\improper DNA injector (Spider Web)"
add_mutations = list(SPIDER_WEB)
/obj/item/dnainjector/antispiderweb
name = "\improper DNA injector (Anti-Spider Web)"
remove_mutations = list(SPIDER_WEB)
/obj/item/dnainjector/timed
var/duration = 600
/obj/item/dnainjector/timed/inject(mob/living/carbon/M, mob/user)
prepare()
if(M.stat == DEAD) //prevents dead people from having their DNA changed
to_chat(user, "<span class='notice'>You can't modify [M]'s DNA while [M.p_theyre()] dead.</span>")
return FALSE
@@ -317,23 +467,22 @@
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
var/endtime = world.time+duration
for(var/datum/mutation/human/HM in remove_mutations)
if(HM.name == RACEMUT)
for(var/mutation in remove_mutations)
if(mutation == RACEMUT)
if(ishuman(M))
continue
M = HM.force_lose(M)
M = M.dna.remove_mutation(mutation)
else
HM.force_lose(M)
for(var/datum/mutation/human/HM in add_mutations)
if((HM in M.dna.mutations) && !(M.dna.temporary_mutations[HM.name]))
M.dna.remove_mutation(mutation)
for(var/mutation in add_mutations)
if(M.dna.get_mutation(mutation))
continue //Skip permanent mutations we already have.
if(HM.name == RACEMUT && ishuman(M))
if(mutation == RACEMUT && ishuman(M))
message_admins("[ADMIN_LOOKUPFLW(user)] injected [key_name_admin(M)] with the [name] <span class='danger'>(MONKEY)</span>")
log_msg += " (MONKEY)"
M = HM.force_give(M)
M = M.dna.add_mutation(mutation, MUT_OTHER, endtime)
else
HM.force_give(M)
M.dna.temporary_mutations[HM.name] = endtime
M.dna.add_mutation(mutation, MUT_OTHER, endtime)
if(fields)
if(fields["name"] && fields["UE"] && fields["blood_type"])
if(!M.dna.previous["name"])
@@ -361,9 +510,41 @@
/obj/item/dnainjector/timed/hulk
name = "\improper DNA injector (Hulk)"
desc = "This will make you big and strong, but give you a bad skin condition."
add_mutations_static = list(HULK)
add_mutations = list(HULK)
/obj/item/dnainjector/timed/h2m
name = "\improper DNA injector (Human > Monkey)"
desc = "Will make you a flea bag."
add_mutations_static = list(RACEMUT)
add_mutations = list(RACEMUT)
/obj/item/dnainjector/activator
name = "\improper DNA activator"
desc = "Activates the current mutation on injection, if the subject has it."
var/doitanyway = FALSE
var/research = FALSE //Set to true to get expended and filled injectors for chromosomes
var/filled = FALSE
/obj/item/dnainjector/activator/inject(mob/living/carbon/M, mob/user)
if(M.has_dna() && !HAS_TRAIT(M, TRAIT_RADIMMUNE) && !HAS_TRAIT(M,TRAIT_NOCLONE))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/mutation in add_mutations)
var/datum/mutation/human/HM = mutation
if(istype(HM, /datum/mutation/human))
mutation = HM.type
if(!M.dna.activate_mutation(HM))
if(!doitanyway)
log_msg += "(FAILED)"
else
M.dna.add_mutation(HM, MUT_EXTRA)
name = "expended [name]"
else if(research && M.client)
filled = TRUE
name = "filled [name]"
else
name = "expended [name]"
log_msg += "([mutation])"
log_attack("[log_msg] [loc_name(user)]")
return TRUE
return FALSE