mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-28 01:51:46 +00:00
252 lines
9.3 KiB
Plaintext
252 lines
9.3 KiB
Plaintext
|
|
/// Negatives that are virtually harmless and mostly just funny (language)
|
|
// Set to 0 because munchkinning via miscommunication = bad
|
|
#define NEGATIVE_STABILITY_MINI 0
|
|
/// Negatives that are slightly annoying (unused)
|
|
#define NEGATIVE_STABILITY_MINOR -20
|
|
/// Negatives that present an uncommon or weak, consistent hindrance to gameplay (cough, paranoia)
|
|
#define NEGATIVE_STABILITY_MODERATE -30
|
|
/// Negatives that present a major consistent hindrance to gameplay (deaf, mute, acid flesh)
|
|
#define NEGATIVE_STABILITY_MAJOR -40
|
|
|
|
/// Positives that provide basically no benefit (glowy)
|
|
#define POSITIVE_INSTABILITY_MINI 5
|
|
/// Positives that are niche in application or useful in rare circumstances (parlor tricks, geladikinesis, autotomy)
|
|
#define POSITIVE_INSTABILITY_MINOR 10
|
|
/// Positives that provide a new ability that's roughly par with station equipment (insulated, cryokinesis)
|
|
#define POSITIVE_INSTABILITY_MODERATE 25
|
|
/// Positives that are unique, very powerful, and noticeably change combat/gameplay (hulk, tk)
|
|
#define POSITIVE_INSTABILITY_MAJOR 35
|
|
|
|
/datum/mutation
|
|
var/name
|
|
|
|
/datum/mutation
|
|
name = "mutation"
|
|
/// Description of the mutation
|
|
var/desc = "A mutation."
|
|
/// Is this mutation currently locked?
|
|
var/locked
|
|
/// Quality of the mutation
|
|
var/quality
|
|
/// 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 path of action we grant to our user on mutation gain
|
|
var/datum/action/cooldown/power_path
|
|
/// 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
|
|
/// 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
|
|
/// '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 sources of the mutation (found in defines/dna.dm)
|
|
var/list/sources = list()
|
|
/**
|
|
* 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/remove_on_aheal = TRUE
|
|
|
|
/**
|
|
* 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
|
|
|
|
//Chromosome stuff - set to -1 to prevent people from changing it. Example: It'd be a waste to decrease cooldown on mutism
|
|
/// genetic stability coeff
|
|
var/stabilizer_coeff = 1
|
|
/// Makes the mutation hurt the user less
|
|
var/synchronizer_coeff = MUTATION_COEFFICIENT_UNMODIFIABLE
|
|
/// Boosts mutation strength
|
|
var/power_coeff = MUTATION_COEFFICIENT_UNMODIFIABLE
|
|
/// Lowers mutation cooldown
|
|
var/energy_coeff = MUTATION_COEFFICIENT_UNMODIFIABLE
|
|
/// List of strings of valid chromosomes this mutation can accept.
|
|
var/list/valid_chrom_list = list()
|
|
/// List of traits that are added or removed by the mutation with GENETIC_TRAIT source.
|
|
var/list/mutation_traits
|
|
|
|
/datum/mutation/New()
|
|
. = ..()
|
|
|
|
/datum/mutation/Destroy()
|
|
power_path = null
|
|
dna = null
|
|
owner = null
|
|
return ..()
|
|
|
|
/datum/mutation/proc/make_copy()
|
|
var/datum/mutation/copy = new type
|
|
|
|
copy.chromosome_name = chromosome_name
|
|
copy.stabilizer_coeff = stabilizer_coeff
|
|
copy.synchronizer_coeff = synchronizer_coeff
|
|
copy.power_coeff = power_coeff
|
|
copy.energy_coeff = energy_coeff
|
|
copy.can_chromosome = can_chromosome
|
|
copy.valid_chrom_list = valid_chrom_list
|
|
update_valid_chromosome_list()
|
|
|
|
return copy
|
|
|
|
/datum/mutation/proc/on_acquiring(mob/living/carbon/human/acquirer)
|
|
if(!acquirer || !istype(acquirer) || acquirer.stat == DEAD || (src in acquirer.dna.mutations))
|
|
return FALSE
|
|
if(species_allowed && !species_allowed.Find(acquirer.dna.species.id))
|
|
return FALSE
|
|
if(health_req && acquirer.health < health_req)
|
|
return FALSE
|
|
if(limb_req && !acquirer.get_bodypart(limb_req))
|
|
return FALSE
|
|
for(var/datum/mutation/mewtayshun as anything in acquirer.dna.mutations) //check for conflicting powers
|
|
if(!(mewtayshun.type in conflicts) && !(type in mewtayshun.conflicts))
|
|
continue
|
|
to_chat(acquirer, span_warning("You feel your genes resisting something."))
|
|
return FALSE
|
|
owner = acquirer
|
|
dna = acquirer.dna
|
|
dna.mutations += src
|
|
SEND_SIGNAL(src, COMSIG_MUTATION_GAINED, acquirer)
|
|
if(text_gain_indication)
|
|
to_chat(owner, text_gain_indication)
|
|
if(visual_indicators.len)
|
|
var/list/mut_overlay = list(get_visual_indicator())
|
|
if(owner.overlays_standing[layer_used])
|
|
mut_overlay = owner.overlays_standing[layer_used]
|
|
mut_overlay |= get_visual_indicator()
|
|
owner.remove_overlay(layer_used)
|
|
owner.overlays_standing[layer_used] = mut_overlay
|
|
owner.apply_overlay(layer_used)
|
|
grant_power() //we do checks here so nothing about hulk getting magic
|
|
if(mutation_traits)
|
|
owner.add_traits(mutation_traits, GENETIC_MUTATION)
|
|
return TRUE
|
|
|
|
/datum/mutation/proc/get_visual_indicator()
|
|
return
|
|
|
|
/datum/mutation/proc/on_life(seconds_per_tick, times_fired)
|
|
return
|
|
|
|
/datum/mutation/proc/on_losing(mob/living/carbon/human/owner)
|
|
if(!istype(owner) || !(owner.dna.mutations.Remove(src)))
|
|
return TRUE
|
|
. = FALSE
|
|
SEND_SIGNAL(src, COMSIG_MUTATION_LOST, owner)
|
|
if(text_lose_indication && owner.stat != DEAD)
|
|
to_chat(owner, text_lose_indication)
|
|
if(visual_indicators.len)
|
|
var/list/mut_overlay = list()
|
|
if(owner.overlays_standing[layer_used])
|
|
mut_overlay = owner.overlays_standing[layer_used]
|
|
owner.remove_overlay(layer_used)
|
|
mut_overlay.Remove(get_visual_indicator())
|
|
owner.overlays_standing[layer_used] = mut_overlay
|
|
owner.apply_overlay(layer_used)
|
|
|
|
if(mutation_traits)
|
|
owner.remove_traits(mutation_traits, GENETIC_MUTATION)
|
|
|
|
/mob/living/carbon/proc/update_mutations_overlay()
|
|
return
|
|
|
|
/mob/living/carbon/human/update_mutations_overlay()
|
|
for(var/datum/mutation/mutation as anything in dna.mutations)
|
|
if(mutation.species_allowed && !mutation.species_allowed.Find(dna.species.id))
|
|
dna.remove_mutation(mutation, mutation.sources) //shouldn't have that mutation at all
|
|
continue
|
|
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)
|
|
|
|
/**
|
|
* Called after on_aquiring, or when a chromosome is applied.
|
|
* returns the instance of 'power_path' for children calls to use without calling locate() again.
|
|
*/
|
|
/datum/mutation/proc/setup()
|
|
if(!power_path || QDELETED(owner))
|
|
return
|
|
var/datum/action/cooldown/modified_power = locate(power_path) in owner.actions
|
|
if(!modified_power)
|
|
CRASH("Genetic mutation [type] called setup(), but could not find a action to modify!")
|
|
modified_power.cooldown_time = initial(modified_power.cooldown_time) * GET_MUTATION_ENERGY(src)
|
|
return modified_power
|
|
|
|
/datum/mutation/proc/remove_chromosome()
|
|
stabilizer_coeff = initial(stabilizer_coeff)
|
|
synchronizer_coeff = initial(synchronizer_coeff)
|
|
power_coeff = initial(power_coeff)
|
|
energy_coeff = initial(energy_coeff)
|
|
can_chromosome = initial(can_chromosome)
|
|
chromosome_name = null
|
|
|
|
/datum/mutation/proc/grant_power()
|
|
if(!ispath(power_path) || !owner)
|
|
return FALSE
|
|
|
|
var/datum/action/cooldown/new_power = new power_path(src)
|
|
new_power.background_icon_state = "bg_tech_blue"
|
|
new_power.base_background_icon_state = new_power.background_icon_state
|
|
new_power.active_background_icon_state = "[new_power.base_background_icon_state]_active"
|
|
new_power.overlay_icon_state = "bg_tech_blue_border"
|
|
new_power.active_overlay_icon_state = "bg_spell_border_active_blue"
|
|
new_power.panel = "Genetic"
|
|
new_power.Grant(owner)
|
|
|
|
return new_power
|
|
|
|
// Runs through all the coefficients and uses this to determine which chromosomes the
|
|
// mutation can take. Stores these as text strings in a list.
|
|
/datum/mutation/proc/update_valid_chromosome_list()
|
|
valid_chrom_list.Cut()
|
|
|
|
if(can_chromosome == CHROMOSOME_NEVER)
|
|
valid_chrom_list += "none"
|
|
return
|
|
|
|
if(stabilizer_coeff != MUTATION_COEFFICIENT_UNMODIFIABLE)
|
|
valid_chrom_list += "Stabilizer"
|
|
if(synchronizer_coeff != MUTATION_COEFFICIENT_UNMODIFIABLE)
|
|
valid_chrom_list += "Synchronizer"
|
|
if(power_coeff != MUTATION_COEFFICIENT_UNMODIFIABLE)
|
|
valid_chrom_list += "Power"
|
|
if(energy_coeff != MUTATION_COEFFICIENT_UNMODIFIABLE)
|
|
valid_chrom_list += "Energetic"
|