|
|
|
@@ -4,51 +4,82 @@
|
|
|
|
|
|
|
|
|
|
/datum/mutation/human
|
|
|
|
|
name = "mutation"
|
|
|
|
|
/// Description of the mutation
|
|
|
|
|
var/desc = "A mutation."
|
|
|
|
|
/// Is this mutation currently locked?
|
|
|
|
|
var/locked
|
|
|
|
|
/// Quality of the mutation
|
|
|
|
|
var/quality
|
|
|
|
|
var/get_chance = 100
|
|
|
|
|
var/lowest_value = 256 * 8
|
|
|
|
|
/// Message given to the user upon gaining this mutation
|
|
|
|
|
var/text_gain_indication = ""
|
|
|
|
|
/// Message given to the user upon losing this mutation
|
|
|
|
|
var/text_lose_indication = ""
|
|
|
|
|
/// Visual indicators upon the character of the owner of this mutation
|
|
|
|
|
var/static/list/visual_indicators = list()
|
|
|
|
|
/// The proc holder (ew) o
|
|
|
|
|
var/obj/effect/proc_holder/spell/power
|
|
|
|
|
var/layer_used = MUTATIONS_LAYER //which mutation layer to use
|
|
|
|
|
var/list/species_allowed //to restrict mutation to only certain species
|
|
|
|
|
var/health_req //minimum health required to acquire the mutation
|
|
|
|
|
var/limb_req //required limbs to acquire this mutation
|
|
|
|
|
var/time_coeff = 1 //coefficient for timed mutations
|
|
|
|
|
/// Which mutation layer to use
|
|
|
|
|
var/layer_used = MUTATIONS_LAYER
|
|
|
|
|
/// To restrict mutation to only certain species
|
|
|
|
|
var/list/species_allowed
|
|
|
|
|
/// Minimum health required to acquire the mutation
|
|
|
|
|
var/health_req
|
|
|
|
|
/// Required limbs to acquire this mutation
|
|
|
|
|
var/limb_req
|
|
|
|
|
/// The owner of this mutation's DNA
|
|
|
|
|
var/datum/dna/dna
|
|
|
|
|
/// Owner of this mutation
|
|
|
|
|
var/mob/living/carbon/human/owner
|
|
|
|
|
var/instability = 0 //instability the holder gets when the mutation is not native
|
|
|
|
|
var/blocks = 4 //Amount of those big blocks with gene sequences
|
|
|
|
|
var/difficulty = 8 //Amount of missing sequences. Sometimes it removes an entire pair for 2 points
|
|
|
|
|
var/timeout //Time between mutation creation and removal. If this exists, we have a timer
|
|
|
|
|
var/alias //'Mutation #49', decided every round to get some form of distinction between undiscovered mutations
|
|
|
|
|
var/scrambled = FALSE //Wheter we can read it if it's active. To avoid cheesing with mutagen
|
|
|
|
|
var/class //Decides player accesibility, sorta
|
|
|
|
|
var/list/conflicts //any mutations that might conflict. put mutation typepath defines in here. make sure to enter it both ways (so that A conflicts with B, and B with A)
|
|
|
|
|
var/allow_transfer //Do we transfer upon cloning?
|
|
|
|
|
//MUT_NORMAL - A mutation that can be activated and deactived by completing a sequence
|
|
|
|
|
//MUT_EXTRA - A mutation that is in the mutations tab, and can be given and taken away through though the DNA console. Has a 0 before it's name in the mutation section of the dna console
|
|
|
|
|
//MUT_OTHER Cannot be interacted with by players through normal means. I.E. wizards mutate
|
|
|
|
|
/// Instability the holder gets when the mutation is not native
|
|
|
|
|
var/instability = 0
|
|
|
|
|
/// Amount of those big blocks with gene sequences
|
|
|
|
|
var/blocks = 4
|
|
|
|
|
/// Amount of missing sequences. Sometimes it removes an entire pair for 2 points
|
|
|
|
|
var/difficulty = 8
|
|
|
|
|
/// Time between mutation creation and removal. If this exists, we have a timer
|
|
|
|
|
var/timeout
|
|
|
|
|
/// 'Mutation #49', decided every round to get some form of distinction between undiscovered mutations
|
|
|
|
|
var/alias
|
|
|
|
|
/// Whether we can read it if it's active. To avoid cheesing with mutagen
|
|
|
|
|
var/scrambled = FALSE
|
|
|
|
|
/// The class of mutation (MUT_NORMAL, MUT_EXTRA, MUT_OTHER)
|
|
|
|
|
var/class
|
|
|
|
|
/**
|
|
|
|
|
* any mutations that might conflict.
|
|
|
|
|
* put mutation typepath defines in here.
|
|
|
|
|
* make sure to enter it both ways (so that A conflicts with B, and B with A)
|
|
|
|
|
*/
|
|
|
|
|
var/list/conflicts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var/can_chromosome = CHROMOSOME_NONE //can we take chromosomes? 0: CHROMOSOME_NEVER never, 1:CHROMOSOME_NONE yeah, 2: CHROMOSOME_USED no, already have one
|
|
|
|
|
var/chromosome_name //purely cosmetic
|
|
|
|
|
var/modified = FALSE //ugly but we really don't want chromosomes and on_acquiring to overlap and apply double the powers
|
|
|
|
|
/**
|
|
|
|
|
* can we take chromosomes?
|
|
|
|
|
* 0: CHROMOSOME_NEVER never
|
|
|
|
|
* 1: CHROMOSOME_NONE yeah
|
|
|
|
|
* 2: CHROMOSOME_USED no, already have one
|
|
|
|
|
*/
|
|
|
|
|
var/can_chromosome = CHROMOSOME_NONE
|
|
|
|
|
/// Name of the chromosome
|
|
|
|
|
var/chromosome_name
|
|
|
|
|
/// Has the chromosome been modified
|
|
|
|
|
var/modified = FALSE //ugly but we really don't want chromosomes and on_acquiring to overlap and apply double the powers
|
|
|
|
|
/// Is this mutation mutadone proof
|
|
|
|
|
var/mutadone_proof = FALSE
|
|
|
|
|
|
|
|
|
|
//Chromosome stuff - set to -1 to prevent people from changing it. Example: It'd be a waste to decrease cooldown on mutism
|
|
|
|
|
var/stabilizer_coeff = 1 //genetic stability coeff
|
|
|
|
|
var/synchronizer_coeff = -1 //makes the mutation hurt the user less
|
|
|
|
|
var/power_coeff = -1 //boosts mutation strength
|
|
|
|
|
var/energy_coeff = -1 //lowers mutation cooldown
|
|
|
|
|
var/list/valid_chrom_list = list() //List of strings of valid chromosomes this mutation can accept.
|
|
|
|
|
/// genetic stability coeff
|
|
|
|
|
var/stabilizer_coeff = 1
|
|
|
|
|
/// Makes the mutation hurt the user less
|
|
|
|
|
var/synchronizer_coeff = -1
|
|
|
|
|
/// Boosts mutation strength
|
|
|
|
|
var/power_coeff = -1
|
|
|
|
|
/// Lowers mutation cooldown
|
|
|
|
|
var/energy_coeff = -1
|
|
|
|
|
/// List of strings of valid chromosomes this mutation can accept.
|
|
|
|
|
var/list/valid_chrom_list = list()
|
|
|
|
|
|
|
|
|
|
/datum/mutation/human/New(class_ = MUT_OTHER, timer, datum/mutation/human/copymut)
|
|
|
|
|
/datum/mutation/human/New(class = MUT_OTHER, timer, datum/mutation/human/copymut)
|
|
|
|
|
. = ..()
|
|
|
|
|
class = class_
|
|
|
|
|
src.class = class
|
|
|
|
|
if(timer)
|
|
|
|
|
addtimer(CALLBACK(src, .proc/remove), timer)
|
|
|
|
|
timeout = timer
|
|
|
|
@@ -56,23 +87,22 @@
|
|
|
|
|
copy_mutation(copymut)
|
|
|
|
|
update_valid_chromosome_list()
|
|
|
|
|
|
|
|
|
|
/datum/mutation/human/proc/on_acquiring(mob/living/carbon/human/H)
|
|
|
|
|
if(!H || !istype(H) || H.stat == DEAD || (src in H.dna.mutations))
|
|
|
|
|
/datum/mutation/human/proc/on_acquiring(mob/living/carbon/human/acquirer)
|
|
|
|
|
if(!acquirer || !istype(acquirer) || acquirer.stat == DEAD || (src in acquirer.dna.mutations))
|
|
|
|
|
return TRUE
|
|
|
|
|
if(species_allowed && !species_allowed.Find(H.dna.species.id))
|
|
|
|
|
if(species_allowed && !species_allowed.Find(acquirer.dna.species.id))
|
|
|
|
|
return TRUE
|
|
|
|
|
if(health_req && H.health < health_req)
|
|
|
|
|
if(health_req && acquirer.health < health_req)
|
|
|
|
|
return TRUE
|
|
|
|
|
if(limb_req && !H.get_bodypart(limb_req))
|
|
|
|
|
if(limb_req && !acquirer.get_bodypart(limb_req))
|
|
|
|
|
return TRUE
|
|
|
|
|
for(var/M in H.dna.mutations)//check for conflicting powers
|
|
|
|
|
var/datum/mutation/human/mewtayshun = M
|
|
|
|
|
for(var/datum/mutation/human/mewtayshun as anything in acquirer.dna.mutations) //check for conflicting powers
|
|
|
|
|
if(!(mewtayshun.type in conflicts) && !(type in mewtayshun.conflicts))
|
|
|
|
|
continue
|
|
|
|
|
to_chat(H, span_warning("You feel your genes resisting something."))
|
|
|
|
|
to_chat(acquirer, span_warning("You feel your genes resisting something."))
|
|
|
|
|
return TRUE
|
|
|
|
|
owner = H
|
|
|
|
|
dna = H.dna
|
|
|
|
|
owner = acquirer
|
|
|
|
|
dna = acquirer.dna
|
|
|
|
|
dna.mutations += src
|
|
|
|
|
if(text_gain_indication)
|
|
|
|
|
to_chat(owner, text_gain_indication)
|
|
|
|
@@ -86,7 +116,7 @@
|
|
|
|
|
owner.apply_overlay(layer_used)
|
|
|
|
|
grant_spell() //we do checks here so nothing about hulk getting magic
|
|
|
|
|
if(!modified)
|
|
|
|
|
addtimer(CALLBACK(src, .proc/modify, 5)) //gonna want children calling ..() to run first
|
|
|
|
|
addtimer(CALLBACK(src, .proc/modify, 0.5 SECONDS)) //gonna want children calling ..() to run first
|
|
|
|
|
|
|
|
|
|
/datum/mutation/human/proc/get_visual_indicator()
|
|
|
|
|
return
|
|
|
|
@@ -116,22 +146,23 @@
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
/mob/living/carbon/human/update_mutations_overlay()
|
|
|
|
|
for(var/datum/mutation/human/CM in dna.mutations)
|
|
|
|
|
if(CM.species_allowed && !CM.species_allowed.Find(dna.species.id))
|
|
|
|
|
dna.force_lose(CM) //shouldn't have that mutation at all
|
|
|
|
|
for(var/datum/mutation/human/mutation in dna.mutations)
|
|
|
|
|
if(mutation.species_allowed && !mutation.species_allowed.Find(dna.species.id))
|
|
|
|
|
dna.force_lose(mutation) //shouldn't have that mutation at all
|
|
|
|
|
continue
|
|
|
|
|
if(CM.visual_indicators.len)
|
|
|
|
|
var/list/mut_overlay = list()
|
|
|
|
|
if(overlays_standing[CM.layer_used])
|
|
|
|
|
mut_overlay = overlays_standing[CM.layer_used]
|
|
|
|
|
var/mutable_appearance/V = CM.get_visual_indicator()
|
|
|
|
|
if(!mut_overlay.Find(V)) //either we lack the visual indicator or we have the wrong one
|
|
|
|
|
remove_overlay(CM.layer_used)
|
|
|
|
|
for(var/mutable_appearance/MA in CM.visual_indicators[CM.type])
|
|
|
|
|
mut_overlay.Remove(MA)
|
|
|
|
|
mut_overlay |= V
|
|
|
|
|
overlays_standing[CM.layer_used] = mut_overlay
|
|
|
|
|
apply_overlay(CM.layer_used)
|
|
|
|
|
if(mutation.visual_indicators.len == 0)
|
|
|
|
|
continue
|
|
|
|
|
var/list/mut_overlay = list()
|
|
|
|
|
if(overlays_standing[mutation.layer_used])
|
|
|
|
|
mut_overlay = overlays_standing[mutation.layer_used]
|
|
|
|
|
var/mutable_appearance/indicator_to_add = mutation.get_visual_indicator()
|
|
|
|
|
if(!mut_overlay.Find(indicator_to_add)) //either we lack the visual indicator or we have the wrong one
|
|
|
|
|
remove_overlay(mutation.layer_used)
|
|
|
|
|
for(var/mutable_appearance/indicator_to_remove in mutation.visual_indicators[mutation.type])
|
|
|
|
|
mut_overlay.Remove(indicator_to_remove)
|
|
|
|
|
mut_overlay |= indicator_to_add
|
|
|
|
|
overlays_standing[mutation.layer_used] = mut_overlay
|
|
|
|
|
apply_overlay(mutation.layer_used)
|
|
|
|
|
|
|
|
|
|
/datum/mutation/human/proc/modify() //called when a genome is applied so we can properly update some stats without having to remove and reapply the mutation from someone
|
|
|
|
|
if(modified || !power || !owner)
|
|
|
|
@@ -140,17 +171,17 @@
|
|
|
|
|
power.charge_counter *= GET_MUTATION_ENERGY(src)
|
|
|
|
|
modified = TRUE
|
|
|
|
|
|
|
|
|
|
/datum/mutation/human/proc/copy_mutation(datum/mutation/human/HM)
|
|
|
|
|
if(!HM)
|
|
|
|
|
/datum/mutation/human/proc/copy_mutation(datum/mutation/human/mutation_to_copy)
|
|
|
|
|
if(!mutation_to_copy)
|
|
|
|
|
return
|
|
|
|
|
chromosome_name = HM.chromosome_name
|
|
|
|
|
stabilizer_coeff = HM.stabilizer_coeff
|
|
|
|
|
synchronizer_coeff = HM.synchronizer_coeff
|
|
|
|
|
power_coeff = HM.power_coeff
|
|
|
|
|
energy_coeff = HM.energy_coeff
|
|
|
|
|
mutadone_proof = HM.mutadone_proof
|
|
|
|
|
can_chromosome = HM.can_chromosome
|
|
|
|
|
valid_chrom_list = HM.valid_chrom_list
|
|
|
|
|
chromosome_name = mutation_to_copy.chromosome_name
|
|
|
|
|
stabilizer_coeff = mutation_to_copy.stabilizer_coeff
|
|
|
|
|
synchronizer_coeff = mutation_to_copy.synchronizer_coeff
|
|
|
|
|
power_coeff = mutation_to_copy.power_coeff
|
|
|
|
|
energy_coeff = mutation_to_copy.energy_coeff
|
|
|
|
|
mutadone_proof = mutation_to_copy.mutadone_proof
|
|
|
|
|
can_chromosome = mutation_to_copy.can_chromosome
|
|
|
|
|
valid_chrom_list = mutation_to_copy.valid_chrom_list
|
|
|
|
|
|
|
|
|
|
/datum/mutation/human/proc/remove_chromosome()
|
|
|
|
|
stabilizer_coeff = initial(stabilizer_coeff)
|
|
|
|
|