Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit616
This commit is contained in:
+11
-1
@@ -63,6 +63,9 @@
|
||||
var/xenobiology_compatible = FALSE //Can the Xenobio management console transverse this area by default?
|
||||
var/list/canSmoothWithAreas //typecache to limit the areas that atoms in this area can smooth with
|
||||
|
||||
/// Color on minimaps, if it's null (which is default) it makes one at random.
|
||||
var/minimap_color
|
||||
|
||||
/**
|
||||
* These two vars allow for multiple unique areas to be linked to a master area
|
||||
* and share some functionalities such as APC powernet nodes, fire alarms etc, without sacrificing
|
||||
@@ -96,7 +99,14 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
// ===
|
||||
|
||||
/area/New()
|
||||
// This interacts with the map loader, so it needs to be set immediately
|
||||
if(!minimap_color) // goes in New() because otherwise it doesn't fucking work
|
||||
// generate one using the icon_state
|
||||
if(icon_state && icon_state != "unknown")
|
||||
var/icon/I = new(icon, icon_state, dir)
|
||||
I.Scale(1,1)
|
||||
minimap_color = I.GetPixel(1,1)
|
||||
else // no icon state? use random.
|
||||
minimap_color = rgb(rand(50,70),rand(50,70),rand(50,70)) // This interacts with the map loader, so it needs to be set immediately
|
||||
// rather than waiting for atoms to initialize.
|
||||
if (unique)
|
||||
GLOB.areas_by_type[type] = src
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
ruletype = "Event"
|
||||
var/typepath // typepath of the event
|
||||
var/triggering
|
||||
var/earliest_start = 20 MINUTES
|
||||
|
||||
/datum/dynamic_ruleset/event/get_blackbox_info()
|
||||
var/list/ruleset_data = list()
|
||||
@@ -25,8 +26,10 @@
|
||||
|
||||
return E
|
||||
|
||||
/datum/dynamic_ruleset/event/ready(forced = FALSE) // same as midround cause we're still using enemy system
|
||||
/datum/dynamic_ruleset/event/ready(forced = FALSE)
|
||||
if (!forced)
|
||||
if(earliest_start >= world.time-SSticker.round_start_time)
|
||||
return FALSE
|
||||
var/job_check = 0
|
||||
if (enemy_roles.len > 0)
|
||||
for (var/mob/M in mode.current_players[CURRENT_LIVING_PLAYERS])
|
||||
@@ -56,6 +59,7 @@
|
||||
required_enemies = list(2,2,1,1,0,0,0,0,0,0)
|
||||
weight = 5
|
||||
cost = 10
|
||||
earliest_start = 30 MINUTES
|
||||
blocking_rules = list(/datum/dynamic_ruleset/roundstart/nuclear,/datum/dynamic_ruleset/midround/from_ghosts/nuclear)
|
||||
requirements = list(70,60,50,50,40,40,40,30,20,15)
|
||||
property_weights = list("story_potential" = 1, "trust" = 1, "chaos" = 1)
|
||||
@@ -157,17 +161,18 @@
|
||||
required_enemies = list(3,3,3,3,3,3,3,3,3,3)
|
||||
cost = 15
|
||||
weight = 3
|
||||
earliest_start = 25 MINUTES
|
||||
repeatable_weight_decrease = 2
|
||||
requirements = list(60,50,40,30,30,30,30,30,30,30)
|
||||
high_population_requirement = 30
|
||||
property_weights = list("extended" = -2)
|
||||
|
||||
/datum/dynamic_ruleset/event/meteor_wave/ready()
|
||||
if(mode.threat_level > 40 && mode.threat >= 25 && prob(20))
|
||||
if(world.time-SSticker.round_start_time > 35 MINUTES && mode.threat_level > 40 && mode.threat >= 25 && prob(30))
|
||||
name = "Meteor Wave: Threatening"
|
||||
cost = 25
|
||||
typepath = /datum/round_event/meteor_wave/threatening
|
||||
else if(mode.threat_level > 50 && mode.threat >= 40 && prob(30))
|
||||
else if(world.time-SSticker.round_start_time > 45 MINUTES && mode.threat_level > 50 && mode.threat >= 40 && prob(30))
|
||||
name = "Meteor Wave: Catastrophic"
|
||||
cost = 40
|
||||
typepath = /datum/round_event/meteor_wave/catastrophic
|
||||
@@ -280,6 +285,7 @@
|
||||
cost = 4
|
||||
requirements = list(10,10,10,10,10,10,10,10,10,10)
|
||||
high_population_requirement = 10
|
||||
earliest_start = 10 MINUTES
|
||||
repeatable = TRUE
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
@@ -324,6 +330,7 @@
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
earliest_start = 0 MINUTES
|
||||
property_weights = list("extended" = 1)
|
||||
always_max_weight = TRUE
|
||||
|
||||
@@ -381,3 +388,67 @@
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
property_weights = list("extended" = 1,"chaos" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/portal_storm_syndicate
|
||||
name = "Portal Storm"
|
||||
config_tag = "portal_storm"
|
||||
typepath = /datum/round_event/portal_storm/syndicate_shocktroop
|
||||
cost = 10
|
||||
weight = 1
|
||||
enemy_roles = list("Head of Security","Security Officer","AI","Captain","Shaft Miner")
|
||||
required_enemies = list(2,2,2,2,2,2,2,2,2,2)
|
||||
requirements = list(101,101,101,30,30,30,30,30,30,30)
|
||||
high_population_requirement = 30
|
||||
earliest_start = 30 MINUTES
|
||||
property_weights = list("teamwork" = 1,"chaos" = 1, "extended" = -1)
|
||||
|
||||
/datum/dynamic_ruleset/event/wormholes
|
||||
name = "Wormholes"
|
||||
config_tag = "wormhole"
|
||||
typepath = /datum/round_event/wormholes
|
||||
cost = 3
|
||||
weight = 4
|
||||
enemy_roles = list("AI","Medical Doctor","Station Engineer","Head of Personnel","Captain")
|
||||
required_enemies = list(2,2,2,2,2,2,2,2,2,2)
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
property_weights = list("extended" = 1)
|
||||
|
||||
/datum/dynamic_ruleset/event/swarmers
|
||||
name = "Swarmers"
|
||||
config_tag = "swarmer"
|
||||
typepath = /datum/round_event/spawn_swarmer
|
||||
cost = 10
|
||||
weight = 1
|
||||
earliest_start = 30 MINUTES
|
||||
enemy_roles = list("AI","Security Officer","Head of Security","Captain","Station Engineer","Atmos Technician","Chief Engineer")
|
||||
required_enemies = list(4,4,4,4,3,3,2,2,1,1)
|
||||
requirements = list(101,101,101,101,101,101,101,101,101,101)
|
||||
high_population_requirement = 5
|
||||
property_weights = list("extended" = -2)
|
||||
|
||||
/datum/dynamic_ruleset/event/sentient_disease
|
||||
name = "Sentient Disease"
|
||||
config_tag = "sentient_disease"
|
||||
typepath = /datum/round_event/ghost_role/sentient_disease
|
||||
enemy_roles = list("Virologist","Chief Medical Officer","Captain","Chemist")
|
||||
required_enemies = list(2,1,1,1,0,0,0,0,0,0)
|
||||
required_candidates = 1
|
||||
weight = 4
|
||||
cost = 5
|
||||
requirements = list(30,30,20,20,15,10,10,10,10,5) // yes, it can even happen in "extended"!
|
||||
property_weights = list("story_potential" = 1, "extended" = 1, "valid" = -2)
|
||||
high_population_requirement = 5
|
||||
|
||||
/datum/dynamic_ruleset/event/revenant
|
||||
name = "Revenant"
|
||||
config_tag = "revenant"
|
||||
typepath = /datum/round_event/ghost_role/revenant
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Captain","Chaplain","AI")
|
||||
required_enemies = list(2,1,1,1,0,0,0,0,0,0)
|
||||
required_candidates = 1
|
||||
weight = 4
|
||||
cost = 5
|
||||
requirements = list(30,30,30,30,20,15,15,15,15,15)
|
||||
high_population_requirement = 15
|
||||
property_weights = list("story_potential" = -2, "extended" = -1)
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
living_players = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS])
|
||||
living_antags = trim_list(mode.current_players[CURRENT_LIVING_ANTAGS])
|
||||
list_observers = trim_list(mode.current_players[CURRENT_OBSERVERS])
|
||||
var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(/datum/element/ghost_role_eligibility)
|
||||
var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(list(/datum/element/ghost_role_eligibility))
|
||||
ghost_eligible = trim_list(eligibility.get_all_ghost_role_eligible())
|
||||
|
||||
/datum/dynamic_ruleset/midround/proc/trim_list(list/L = list())
|
||||
@@ -273,10 +273,14 @@
|
||||
var/ion_announce = 33
|
||||
var/removeDontImproveChance = 10
|
||||
|
||||
/datum/dynamic_ruleset/midround/malf/ready()
|
||||
if(!candidates || !candidates.len)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/malf/trim_candidates()
|
||||
..()
|
||||
living_players = candidates[CURRENT_LIVING_PLAYERS]
|
||||
for(var/mob/living/player in candidates)
|
||||
for(var/mob/living/player in living_players)
|
||||
if(!isAI(player))
|
||||
candidates -= player
|
||||
continue
|
||||
@@ -287,8 +291,6 @@
|
||||
candidates -= player
|
||||
|
||||
/datum/dynamic_ruleset/midround/malf/execute()
|
||||
if(!candidates || !candidates.len)
|
||||
return FALSE
|
||||
var/mob/living/silicon/ai/M = pick_n_take(candidates)
|
||||
assigned += M.mind
|
||||
var/datum/antagonist/traitor/AI = new
|
||||
@@ -337,6 +339,7 @@
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/wizard/finish_setup(mob/new_character, index)
|
||||
..()
|
||||
new_character.forceMove(pick(GLOB.wizardstart))
|
||||
wizard = new_character.mind
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/wizard/rule_process() // i can literally copy this from are_special_antags_dead it's great
|
||||
if(isliving(wizard.current) && wizard.current.stat!=DEAD)
|
||||
@@ -447,9 +450,7 @@
|
||||
property_weights = list("story_potential" = -1, "trust" = 1, "chaos" = 2, "extended" = -2, "valid" = 2)
|
||||
var/list/vents = list()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/execute()
|
||||
// 50% chance of being incremented by one
|
||||
required_candidates += prob(50)
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/ready()
|
||||
for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in GLOB.machines)
|
||||
if(QDELETED(temp_vent))
|
||||
continue
|
||||
@@ -463,6 +464,12 @@
|
||||
vents += temp_vent
|
||||
if(!vents.len)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/execute()
|
||||
// 50% chance of being incremented by one
|
||||
required_candidates += prob(50)
|
||||
. = ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/generate_ruleset_body(mob/applicant)
|
||||
@@ -497,7 +504,7 @@
|
||||
property_weights = list("story_potential" = 1, "trust" = 1, "extended" = 1, "valid" = 2, "integrity" = 1)
|
||||
var/list/spawn_locs = list()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/nightmare/execute()
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/nightmare/ready()
|
||||
for(var/X in GLOB.xeno_spawn)
|
||||
var/turf/T = X
|
||||
var/light_amount = T.get_lumcount()
|
||||
@@ -505,7 +512,7 @@
|
||||
spawn_locs += T
|
||||
if(!spawn_locs.len)
|
||||
return FALSE
|
||||
. = ..()
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/nightmare/generate_ruleset_body(mob/applicant)
|
||||
var/datum/mind/player_mind = new /datum/mind(applicant.key)
|
||||
@@ -523,88 +530,6 @@
|
||||
log_game("DYNAMIC: [key_name(S)] was spawned as a Nightmare by the midround ruleset.")
|
||||
return S
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// SENTIENT DISEASE //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease
|
||||
name = "Sentient Disease"
|
||||
config_tag = "sentient_disease"
|
||||
antag_flag = ROLE_ALIEN
|
||||
enemy_roles = list("Virologist","Chief Medical Officer","Captain","Chemist")
|
||||
required_enemies = list(2,1,1,1,0,0,0,0,0,0)
|
||||
required_candidates = 1
|
||||
weight = 4
|
||||
cost = 5
|
||||
requirements = list(30,30,20,20,15,10,10,10,10,5) // yes, it can even happen in "extended"!
|
||||
property_weights = list("story_potential" = 1, "extended" = 1, "valid" = -2)
|
||||
high_population_requirement = 5
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/generate_ruleset_body(mob/applicant)
|
||||
var/mob/camera/disease/virus = new /mob/camera/disease(SSmapping.get_station_center())
|
||||
applicant.transfer_ckey(virus, FALSE)
|
||||
INVOKE_ASYNC(virus, /mob/camera/disease/proc/pick_name)
|
||||
message_admins("[ADMIN_LOOKUPFLW(virus)] has been made into a sentient disease by the midround ruleset.")
|
||||
log_game("[key_name(virus)] was spawned as a sentient disease by the midround ruleset.")
|
||||
return virus
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// REVENANT //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/revenant
|
||||
name = "Revenant"
|
||||
config_tag = "revenant"
|
||||
antag_flag = ROLE_REVENANT
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Captain","Chaplain","AI")
|
||||
required_enemies = list(2,1,1,1,0,0,0,0,0,0)
|
||||
required_candidates = 1
|
||||
weight = 4
|
||||
cost = 5
|
||||
requirements = list(30,30,30,30,20,15,15,15,15,15)
|
||||
high_population_requirement = 15
|
||||
property_weights = list("story_potential" = -2, "extended" = -1)
|
||||
var/list/spawn_locs = list()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/revenant/acceptable(population = 0,threat = 0)
|
||||
var/deadMobs = 0
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
deadMobs++
|
||||
if(deadMobs < REVENANT_SPAWN_THRESHOLD)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/revenant/ready(forced = FALSE)
|
||||
for(var/mob/living/L in GLOB.dead_mob_list) //look for any dead bodies
|
||||
var/turf/T = get_turf(L)
|
||||
if(T && is_station_level(T.z))
|
||||
spawn_locs += T
|
||||
if(!spawn_locs.len || spawn_locs.len < 15) //look for any morgue trays, crematoriums, ect if there weren't alot of dead bodies on the station to pick from
|
||||
for(var/obj/structure/bodycontainer/bc in GLOB.bodycontainers)
|
||||
var/turf/T = get_turf(bc)
|
||||
if(T && is_station_level(T.z))
|
||||
spawn_locs += T
|
||||
if(!spawn_locs.len) //If we can't find any valid spawnpoints, try the carp spawns
|
||||
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
|
||||
if(isturf(L.loc))
|
||||
spawn_locs += L.loc
|
||||
if(!spawn_locs.len) //If we can't find THAT, then just give up and cry
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/revenant/generate_ruleset_body(mob/applicant)
|
||||
var/mob/living/simple_animal/revenant/revvie = new(pick(spawn_locs))
|
||||
applicant.transfer_ckey(revvie, FALSE)
|
||||
message_admins("[ADMIN_LOOKUPFLW(revvie)] has been made into a revenant by the midround ruleset.")
|
||||
log_game("[key_name(revvie)] was spawned as a revenant by the midround ruleset.")
|
||||
return revvie
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// SLAUGHTER DEMON //
|
||||
@@ -668,11 +593,11 @@
|
||||
required_candidates = 2
|
||||
weight = 8
|
||||
cost = 10
|
||||
requirements = list(101,101,70,50,40,30,30,20,15,15)
|
||||
requirements = list(101,101,70,50,40,30,30,30,30,30)
|
||||
blocking_rules = list(/datum/dynamic_ruleset/roundstart/nuclear,/datum/dynamic_ruleset/midround/from_ghosts/nuclear)
|
||||
high_population_requirement = 15
|
||||
var/datum/team/abductor_team/team
|
||||
property_weights = list("story_potential" = 1, "extended" = -2, "valid" = 1, "trust" = -1, "chaos" = 2)
|
||||
property_weights = list("extended" = -2, "valid" = 1, "trust" = -1, "chaos" = 2)
|
||||
repeatable_weight_decrease = 4
|
||||
repeatable = TRUE
|
||||
|
||||
@@ -742,7 +667,8 @@
|
||||
var/datum/antagonist/ninja/ninjadatum = new
|
||||
ninjadatum.helping_station = pick(TRUE,FALSE)
|
||||
if(ninjadatum.helping_station)
|
||||
mode.refund_threat(5)
|
||||
mode.refund_threat(cost+5)
|
||||
mode.log_threat("Ninja was helping station; [cost+5] cost refunded.")
|
||||
Mind.add_antag_datum(ninjadatum)
|
||||
|
||||
if(Ninja.mind != Mind) //something has gone wrong!
|
||||
|
||||
@@ -623,8 +623,7 @@
|
||||
config_tag = "clownops"
|
||||
antag_datum = /datum/antagonist/nukeop/clownop
|
||||
antag_leader_datum = /datum/antagonist/nukeop/leader/clownop
|
||||
requirements = list(101,101,101,101,101,101,101,101,101,101)
|
||||
high_population_requirement = 101
|
||||
weight = 1
|
||||
property_weights = list("trust" = 2, "chaos" = 2, "extended" = -2, "story_potential" = 2, "valid" = 2)
|
||||
|
||||
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
/datum/dynamic_storyteller
|
||||
var/name = "none"
|
||||
var/config_tag = null
|
||||
var/desc = "A coder's idiocy."
|
||||
var/list/property_weights = list()
|
||||
var/curve_centre = 0
|
||||
var/curve_width = 1.8
|
||||
var/name = "none" // Name for voting.
|
||||
var/config_tag = null // Config tag for config weights.
|
||||
var/desc = "A coder's idiocy." // Description for voting.
|
||||
var/list/property_weights = list() // See below.
|
||||
var/curve_centre = 0 // As GLOB.dynamic_curve_centre.
|
||||
var/curve_width = 1.8 // As GLOB.dynamic_curve_width.
|
||||
var/forced_threat_level = -1
|
||||
/*
|
||||
NO_ASSASSIN: Will not have permanent assassination targets.
|
||||
WAROPS_ALWAYS_ALLOWED: Can always do warops, regardless of threat level.
|
||||
USE_PREF_WEIGHTS: Will use peoples' preferences to change the threat centre.
|
||||
*/
|
||||
var/flags = 0
|
||||
var/weight = 3 // how many rounds need to have been recently played for this storyteller to be left out of the vote
|
||||
var/event_frequency_lower = 6 MINUTES
|
||||
var/event_frequency_upper = 20 MINUTES
|
||||
var/datum/game_mode/dynamic/mode = null
|
||||
var/weight = 3 // Weights for randomly picking storyteller. Multiplied by score after voting.
|
||||
var/event_frequency_lower = 6 MINUTES // How rare events will be, at least.
|
||||
var/event_frequency_upper = 20 MINUTES // How rare events will be, at most.
|
||||
var/pop_antag_ratio = 5 // How many non-antags there should be vs antags.
|
||||
var/datum/game_mode/dynamic/mode = null // Cached as soon as it's made, by dynamic.
|
||||
|
||||
/**
|
||||
Property weights are:
|
||||
@@ -80,7 +86,7 @@ Property weights are:
|
||||
var/chance = 0
|
||||
// If the high pop override is in effect, we reduce the impact of population on the antag injection chance
|
||||
var/high_pop_factor = (mode.current_players[CURRENT_LIVING_PLAYERS].len >= GLOB.dynamic_high_pop_limit)
|
||||
var/max_pop_per_antag = max(5,15 - round(mode.threat_level/10) - round(mode.current_players[CURRENT_LIVING_PLAYERS].len/(high_pop_factor ? 10 : 5)))
|
||||
var/max_pop_per_antag = max(pop_antag_ratio,15 - round(mode.threat_level/10) - round(mode.current_players[CURRENT_LIVING_PLAYERS].len/(high_pop_factor ? 10 : 5)))
|
||||
if (!mode.current_players[CURRENT_LIVING_ANTAGS].len)
|
||||
chance += 80 // No antags at all? let's boost those odds!
|
||||
else
|
||||
@@ -173,12 +179,13 @@ Property weights are:
|
||||
name = "Chaotic"
|
||||
config_tag = "chaotic"
|
||||
curve_centre = 10
|
||||
desc = "Chaos: high. Variation: high. Likely antags: clock cult, revs, wizard."
|
||||
desc = "High chaos modes. Revs, wizard, clock cult. Multiple antags at once. Chaos is kept up all round."
|
||||
property_weights = list("extended" = -1, "chaos" = 10)
|
||||
weight = 1
|
||||
event_frequency_lower = 2 MINUTES
|
||||
event_frequency_upper = 10 MINUTES
|
||||
flags = WAROPS_ALWAYS_ALLOWED
|
||||
pop_antag_ratio = 4
|
||||
var/refund_cooldown = 0
|
||||
|
||||
/datum/dynamic_storyteller/cowabunga/get_midround_cooldown()
|
||||
@@ -189,14 +196,14 @@ Property weights are:
|
||||
|
||||
/datum/dynamic_storyteller/cowabunga/do_process()
|
||||
if(refund_cooldown < world.time)
|
||||
mode.refund_threat(20)
|
||||
mode.log_threat("Cowabunga it is. Refunded 20 threat. Threat is now [mode.threat].")
|
||||
refund_cooldown = world.time + 600 SECONDS
|
||||
mode.refund_threat(40)
|
||||
mode.log_threat("Chaotic storyteller refunded 40 threat. Threat is now [mode.threat].")
|
||||
refund_cooldown = world.time + 1200 SECONDS
|
||||
|
||||
/datum/dynamic_storyteller/team
|
||||
name = "Teamwork"
|
||||
config_tag = "teamwork"
|
||||
desc = "Chaos: high. Variation: low. Likely antags: nukies, clockwork cult, wizard, blob, xenomorph."
|
||||
desc = "Modes where the crew must band together. Nukies, xenos, blob. Only one antag threat at once."
|
||||
curve_centre = 2
|
||||
curve_width = 1.5
|
||||
weight = 2
|
||||
@@ -209,56 +216,71 @@ Property weights are:
|
||||
/datum/dynamic_storyteller/conversion
|
||||
name = "Conversion"
|
||||
config_tag = "conversion"
|
||||
desc = "Chaos: high. Variation: medium. Likely antags: cults, bloodsuckers, revs."
|
||||
desc = "Conversion antags. Cults, revs."
|
||||
curve_centre = 3
|
||||
curve_width = 1
|
||||
weight = 2
|
||||
weight = 0
|
||||
flags = WAROPS_ALWAYS_ALLOWED
|
||||
property_weights = list("valid" = 1, "conversion" = 20)
|
||||
|
||||
/datum/dynamic_storyteller/classic
|
||||
name = "Random"
|
||||
config_tag = "random"
|
||||
desc = "Chaos: varies. Variation: highest. No special weights attached."
|
||||
weight = 6
|
||||
flags = USE_PREF_WEIGHTS
|
||||
desc = "No special weights attached. Anything goes."
|
||||
weight = 4
|
||||
curve_width = 4
|
||||
pop_antag_ratio = 7
|
||||
flags = USE_PREF_WEIGHTS
|
||||
|
||||
/datum/dynamic_storyteller/memes
|
||||
/datum/dynamic_storyteller/story
|
||||
name = "Story"
|
||||
config_tag = "story"
|
||||
desc = "Chaos: varies. Variation: high. Likely antags: abductors, nukies, wizard, traitor."
|
||||
weight = 4
|
||||
flags = USE_PREF_WEIGHTS
|
||||
curve_width = 4
|
||||
desc = "Antags with options for loadouts and gimmicks. Traitor, wizard, nukies."
|
||||
weight = 2
|
||||
curve_width = 2
|
||||
pop_antag_ratio = 7
|
||||
property_weights = list("story_potential" = 10)
|
||||
|
||||
/datum/dynamic_storyteller/suspicion
|
||||
name = "Intrigue"
|
||||
config_tag = "intrigue"
|
||||
desc = "Chaos: low. Variation: high. Likely antags: traitor, bloodsucker. Rare: revs, blood cult."
|
||||
weight = 4
|
||||
flags = USE_PREF_WEIGHTS
|
||||
curve_width = 4
|
||||
desc = "Antags that instill distrust in the crew. Traitors, bloodsuckers."
|
||||
weight = 2
|
||||
curve_width = 2
|
||||
pop_antag_ratio = 7
|
||||
property_weights = list("trust" = -5)
|
||||
|
||||
/datum/dynamic_storyteller/liteextended
|
||||
name = "Calm"
|
||||
config_tag = "calm"
|
||||
desc = "Chaos: low. Variation: medium. Likely antags: bloodsuckers, traitors, sentient disease, revenant."
|
||||
desc = "Low-chaos round. Few antags. No conversion."
|
||||
curve_centre = -3
|
||||
curve_width = 0.5
|
||||
flags = NO_ASSASSIN
|
||||
weight = 1
|
||||
pop_antag_ratio = 10
|
||||
property_weights = list("extended" = 1, "chaos" = -1, "valid" = -1, "story_potential" = 1, "conversion" = -10)
|
||||
|
||||
/datum/dynamic_storyteller/no_antag
|
||||
name = "Extended"
|
||||
config_tag = "semiextended"
|
||||
desc = "No standard antags. Threatening events may still spawn."
|
||||
curve_centre = -5
|
||||
curve_width = 0.5
|
||||
flags = NO_ASSASSIN
|
||||
weight = 2
|
||||
property_weights = list("extended" = 1, "chaos" = -1, "valid" = -1, "story_potential" = 1, "conversion" = -10)
|
||||
weight = 1
|
||||
property_weights = list("extended" = 2)
|
||||
|
||||
/datum/dynamic_storyteller/liteextended/get_injection_chance(dry_run = FALSE)
|
||||
return ..()/2
|
||||
/datum/dynamic_storyteller/no_antag/roundstart_draft()
|
||||
return list()
|
||||
|
||||
/datum/dynamic_storyteller/no_antag/get_injection_chance(dry_run)
|
||||
return 0
|
||||
|
||||
/datum/dynamic_storyteller/extended
|
||||
name = "Extended"
|
||||
name = "Super Extended"
|
||||
config_tag = "extended"
|
||||
desc = "Chaos: none. Variation: none. Likely antags: none."
|
||||
desc = "No antags. No dangerous events."
|
||||
curve_centre = -20
|
||||
weight = 0
|
||||
curve_width = 0.5
|
||||
|
||||
@@ -1163,12 +1163,17 @@ GLOBAL_LIST_EMPTY(possible_sabotages)
|
||||
var/payout = 0
|
||||
var/payout_bonus = 0
|
||||
var/area/dropoff = null
|
||||
var/static/list/blacklisted_areas = typecacheof(list(/area/ai_monitored/turret_protected,
|
||||
/area/solar/,
|
||||
/area/ruin/, //thank you station space ruins
|
||||
/area/science/test_area/,
|
||||
/area/shuttle/))
|
||||
|
||||
/datum/objective/contract/proc/generate_dropoff() // Generate a random valid area on the station that the dropoff will happen.
|
||||
var/found = FALSE
|
||||
while(!found)
|
||||
var/area/dropoff_area = pick(GLOB.sortedAreas)
|
||||
if(dropoff_area && is_station_level(dropoff_area.z) && !dropoff_area.outdoors && !istype(dropoff_area, /area/shuttle/))
|
||||
if(dropoff_area && is_station_level(dropoff_area.z) && !dropoff_area.outdoors && !is_type_in_typecache(dropoff_area, blacklisted_areas))
|
||||
dropoff = dropoff_area
|
||||
found = TRUE
|
||||
|
||||
|
||||
@@ -47,8 +47,8 @@
|
||||
)
|
||||
|
||||
/obj/machinery/autolathe/Initialize()
|
||||
AddComponent(/datum/component/material_container,
|
||||
list(/datum/material/iron,
|
||||
var/static/list/allowed_types = list(
|
||||
/datum/material/iron,
|
||||
/datum/material/glass,
|
||||
/datum/material/gold,
|
||||
/datum/material/silver,
|
||||
@@ -62,10 +62,9 @@
|
||||
/datum/material/plastic,
|
||||
/datum/material/adamantine,
|
||||
/datum/material/mythril
|
||||
),
|
||||
0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
|
||||
)
|
||||
AddComponent(/datum/component/material_container, allowed_types, _show_on_examine=TRUE, _after_insert=CALLBACK(src, .proc/AfterMaterialInsert))
|
||||
. = ..()
|
||||
|
||||
wires = new /datum/wires/autolathe(src)
|
||||
stored_research = new /datum/techweb/specialized/autounlocking/autolathe
|
||||
matching_designs = list()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ Buildable meters
|
||||
if(make_from.flipped)
|
||||
do_a_flip()
|
||||
|
||||
/obj/item/pipe/dropped()
|
||||
/obj/item/pipe/dropped(mob/user)
|
||||
if(loc)
|
||||
setPipingLayer(piping_layer)
|
||||
return ..()
|
||||
@@ -225,7 +225,7 @@ Buildable meters
|
||||
to_chat(user, "<span class='notice'>You fasten the meter to the [loc.name].</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/item/pipe_meter/dropped()
|
||||
/obj/item/pipe_meter/dropped(mob/user)
|
||||
. = ..()
|
||||
if(loc)
|
||||
setAttachLayer(piping_layer)
|
||||
|
||||
@@ -46,7 +46,12 @@
|
||||
)
|
||||
|
||||
/obj/machinery/autoylathe/Initialize()
|
||||
AddComponent(/datum/component/material_container, list(/datum/material/iron, /datum/material/glass, /datum/material/plastic), 0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
|
||||
var/static/list/allowed_materials = list(
|
||||
/datum/material/iron,
|
||||
/datum/material/glass,
|
||||
/datum/material/plastic
|
||||
)
|
||||
AddComponent(/datum/component/material_container, allowed_materials, 0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
|
||||
. = ..()
|
||||
|
||||
wires = new /datum/wires/autoylathe(src)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -35,9 +35,19 @@
|
||||
)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/Initialize()
|
||||
var/datum/component/material_container/materials = AddComponent(/datum/component/material_container,
|
||||
list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/gold, /datum/material/diamond, /datum/material/plasma, /datum/material/uranium, /datum/material/bananium, /datum/material/titanium, /datum/material/bluespace), 0,
|
||||
TRUE, /obj/item/stack, CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert))
|
||||
var/static/list/allowed_types = list(
|
||||
/datum/material/iron,
|
||||
/datum/material/glass,
|
||||
/datum/material/silver,
|
||||
/datum/material/gold,
|
||||
/datum/material/diamond,
|
||||
/datum/material/plasma,
|
||||
/datum/material/uranium,
|
||||
/datum/material/bananium,
|
||||
/datum/material/titanium,
|
||||
/datum/material/bluespace
|
||||
)
|
||||
var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, allowed_types, 0, TRUE, /obj/item/stack, CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert))
|
||||
materials.precise_insertion = TRUE
|
||||
stored_research = new
|
||||
return ..()
|
||||
|
||||
@@ -320,11 +320,7 @@
|
||||
clearInternalDamage(MECHA_INT_CONTROL_LOST)
|
||||
|
||||
/obj/mecha/narsie_act()
|
||||
if(occupant)
|
||||
var/mob/living/L = occupant
|
||||
go_out(TRUE)
|
||||
if(L)
|
||||
L.narsie_act()
|
||||
emp_act(EMP_HEAVY)
|
||||
|
||||
/obj/mecha/ratvar_act()
|
||||
if((GLOB.ratvar_awakens || GLOB.clockwork_gateway_activated) && occupant)
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
|
||||
@@ -117,7 +117,7 @@
|
||||
. = ..()
|
||||
if(!isinhands || !(loaded?.amount))
|
||||
return
|
||||
var/mutable_appearance/cable_overlay = mutable_appearance(icon, "rcl-[CEILING(loaded.amount/(max_amount/3), 1)]")
|
||||
var/mutable_appearance/cable_overlay = mutable_appearance(icon_file, "rcl-[CEILING(loaded.amount/(max_amount/3), 1)]")
|
||||
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
|
||||
. += cable_overlay
|
||||
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
@@ -18,15 +18,11 @@
|
||||
/obj/item/chrono_eraser/proc/pass_mind(datum/mind/M)
|
||||
erased_minds += M
|
||||
|
||||
/obj/item/chrono_eraser/dropped()
|
||||
/obj/item/chrono_eraser/dropped(mob/user)
|
||||
..()
|
||||
if(PA)
|
||||
qdel(PA)
|
||||
|
||||
/obj/item/chrono_eraser/Destroy()
|
||||
dropped()
|
||||
return ..()
|
||||
|
||||
/obj/item/chrono_eraser/ui_action_click(mob/user)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
var/obj/item/cigbutt/butt = /obj/item/cigbutt
|
||||
saved_appearance = initial(butt.appearance)
|
||||
|
||||
/obj/item/chameleon/dropped()
|
||||
/obj/item/chameleon/dropped(mob/user)
|
||||
..()
|
||||
disrupt()
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
/obj/item/geiger_counter/cyborg/proc/redirect_rad_act(datum/source, amount)
|
||||
rad_act(amount)
|
||||
|
||||
/obj/item/geiger_counter/cyborg/dropped()
|
||||
/obj/item/geiger_counter/cyborg/dropped(mob/user)
|
||||
. = ..()
|
||||
if(listeningTo)
|
||||
UnregisterSignal(listeningTo, COMSIG_ATOM_RAD_ACT)
|
||||
|
||||
@@ -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 = ""
|
||||
@@ -326,8 +329,8 @@ SLIME SCANNER
|
||||
breathes = FALSE
|
||||
if(NOBLOOD in C.dna.species.species_traits)
|
||||
blooded = FALSE
|
||||
var/has_liver = (!(NOLIVER in C.dna.species.species_traits))
|
||||
var/has_stomach = (!(NOSTOMACH in C.dna.species.species_traits))
|
||||
var/has_liver = C.dna && !(NOLIVER in C.dna.species.species_traits)
|
||||
var/has_stomach = C.dna && !(NOSTOMACH in C.dna.species.species_traits)
|
||||
if(!M.getorganslot(ORGAN_SLOT_EYES))
|
||||
msg += "\t<span class='alert'><b>Subject does not have eyes.</b></span>\n"
|
||||
if(!M.getorganslot(ORGAN_SLOT_EARS))
|
||||
@@ -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
|
||||
@@ -63,10 +63,10 @@
|
||||
if(attached_device)
|
||||
attached_device.holder_movement()
|
||||
|
||||
/obj/item/transfer_valve/dropped()
|
||||
/obj/item/transfer_valve/dropped(mob/user)
|
||||
. = ..()
|
||||
if(attached_device)
|
||||
attached_device.dropped()
|
||||
attached_device.dropped(user)
|
||||
|
||||
/obj/item/transfer_valve/on_found(mob/finder)
|
||||
if(attached_device)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/obj/item/book/granter/proc/turn_page(mob/user)
|
||||
playsound(user, pick('sound/effects/pageturn1.ogg','sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg'), 30, 1)
|
||||
if(do_after(user,50, user))
|
||||
if(do_after(user,50, TRUE, user))
|
||||
if(remarks.len)
|
||||
to_chat(user, "<span class='notice'>[pick(remarks)]</span>")
|
||||
else
|
||||
@@ -53,7 +53,7 @@
|
||||
on_reading_stopped()
|
||||
reading = FALSE
|
||||
return
|
||||
if(do_after(user,50, user))
|
||||
if(do_after(user,50, TRUE, user))
|
||||
on_reading_finished(user)
|
||||
reading = FALSE
|
||||
return TRUE
|
||||
@@ -402,10 +402,11 @@
|
||||
martialname = "sleeping carp"
|
||||
desc = "A scroll filled with strange markings. It seems to be drawings of some sort of martial art."
|
||||
greet = "<span class='sciradio'>You have learned the ancient martial art of the Sleeping Carp! Your hand-to-hand combat has become much more effective, and you are now able to deflect any projectiles \
|
||||
directed toward you. However, you are also unable to use any ranged weaponry. You can learn more about your newfound art by using the Recall Teachings verb in the Sleeping Carp tab.</span>"
|
||||
directed toward you while in Throw Mode. Your body is also honed to protect you from damage and punctures, and even briefly survive space. \
|
||||
However, you are also unable to use any ranged weaponry, and some medical supplies will prove useless to you. You can learn more about your newfound art by using the Recall Teachings verb in the Sleeping Carp tab.</span>"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "scroll2"
|
||||
remarks = list("I must prove myself worthy to the masters of the sleeping carp...", "Stance means everything...", "Focus... And you'll be able to incapacitate any foe in seconds...", "I must pierce armor for maximum damage...", "I don't think this would combine with other martial arts...", "Grab them first so they don't retaliate...", "I must prove myself worthy of this power...")
|
||||
remarks = list("Wait, a high protein diet is really all it takes to become bulletproof...?", "Overwhelming force, immovable object...", "Focus... And you'll be able to incapacitate any foe in seconds...", "I must pierce armor for maximum damage...", "I don't think this would combine with other martial arts...", "Become one with the carp...", "Glub...")
|
||||
|
||||
/obj/item/book/granter/martial/carp/onlearned(mob/living/carbon/user)
|
||||
..()
|
||||
|
||||
@@ -357,7 +357,7 @@
|
||||
/obj/item/borg/lollipop/equipped()
|
||||
check_amount()
|
||||
|
||||
/obj/item/borg/lollipop/dropped()
|
||||
/obj/item/borg/lollipop/dropped(mob/user)
|
||||
check_amount()
|
||||
|
||||
/obj/item/borg/lollipop/proc/check_amount() //Doesn't even use processing ticks.
|
||||
@@ -620,7 +620,7 @@
|
||||
return host.loc
|
||||
return null
|
||||
|
||||
/obj/item/borg/projectile_dampen/dropped()
|
||||
/obj/item/borg/projectile_dampen/dropped(mob/user)
|
||||
. = ..()
|
||||
host = loc
|
||||
|
||||
|
||||
@@ -462,7 +462,7 @@
|
||||
desc = "An upgrade to the Medical module's hypospray, containing \
|
||||
stronger versions of existing chemicals."
|
||||
additional_reagents = list(/datum/reagent/medicine/oxandrolone, /datum/reagent/medicine/sal_acid,
|
||||
/datum/reagent/medicine/rezadone, /datum/reagent/medicine/pen_acid)
|
||||
/datum/reagent/medicine/rezadone, /datum/reagent/medicine/pen_acid, /datum/reagent/medicine/prussian_blue)
|
||||
|
||||
/obj/item/borg/upgrade/piercing_hypospray
|
||||
name = "cyborg piercing hypospray"
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/Pickup_ores)
|
||||
listeningTo = user
|
||||
|
||||
/obj/item/storage/bag/ore/dropped()
|
||||
/obj/item/storage/bag/ore/dropped(mob/user)
|
||||
. = ..()
|
||||
if(listeningTo)
|
||||
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
|
||||
|
||||
@@ -525,14 +525,6 @@
|
||||
desc = "A kit containing a Deluxe hypospray and Vials."
|
||||
icon_state = "tactical-mini"
|
||||
|
||||
/obj/item/storage/hypospraykit/cmo/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.can_hold = typecacheof(list(
|
||||
/obj/item/hypospray/mkii,
|
||||
/obj/item/reagent_containers/glass/bottle/vial))
|
||||
|
||||
/obj/item/storage/hypospraykit/cmo/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
/obj/item/melee/baton/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Right click attack while in combat mode or attack while in disarm intent to disarm instead of stun.</span>"
|
||||
. += "<span class='notice'>Right click attack while in combat mode to disarm instead of stun.</span>"
|
||||
|
||||
/obj/item/melee/baton/get_cell()
|
||||
. = cell
|
||||
@@ -149,8 +149,6 @@
|
||||
|
||||
//return TRUE to interrupt attack chain.
|
||||
/obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, disarming = FALSE)
|
||||
if(user.a_intent == INTENT_DISARM)
|
||||
disarming = TRUE //override if they're in disarm intent.
|
||||
if(iscyborg(M) || !isliving(M)) //can't baton cyborgs
|
||||
return FALSE
|
||||
if(status && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
||||
|
||||
@@ -246,11 +246,11 @@
|
||||
user.visible_message("<span class='suicide'>[user] axes [user.p_them()]self from head to toe! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/twohanded/fireaxe/afterattack(atom/A, mob/user, proximity)
|
||||
/obj/item/twohanded/fireaxe/afterattack(atom/A, mob/living/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
if(!proximity || (user.getStaminaLoss() > STAMINA_SOFTCRIT))
|
||||
return
|
||||
if(wielded) //destroys windows and grilles in one hit
|
||||
if(wielded) //destroys windows and grilles in one hit (or more if it has a ton of health like plasmaglass)
|
||||
if(istype(A, /obj/structure/window))
|
||||
var/obj/structure/window/W = A
|
||||
W.take_damage(200, BRUTE, "melee", 0)
|
||||
@@ -1217,7 +1217,7 @@
|
||||
target.lastattackerckey = user.ckey
|
||||
target.visible_message("<span class='danger'>[user] has shocked [target] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has shocked you with [src]!</span>")
|
||||
log_combat(user, user, "stunned with an electrostaff")
|
||||
log_combat(user, target, "stunned with an electrostaff")
|
||||
playsound(src, 'sound/weapons/staff.ogg', 50, 1, -1)
|
||||
target.apply_status_effect(stun_status_effect, stun_status_duration)
|
||||
if(ishuman(user))
|
||||
@@ -1242,9 +1242,9 @@
|
||||
if(user)
|
||||
target.lastattacker = user.real_name
|
||||
target.lastattackerckey = user.ckey
|
||||
target.visible_message("<span class='danger'>[user] has seared [user] with [src]!</span>", \
|
||||
target.visible_message("<span class='danger'>[user] has seared [target] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has seared you with [src]!</span>")
|
||||
log_combat(user, user, "burned with an electrostaff")
|
||||
log_combat(user, target, "burned with an electrostaff")
|
||||
playsound(src, 'sound/weapons/sear.ogg', 50, 1, -1)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -127,11 +127,10 @@
|
||||
if ((M.client && M.machine == src))
|
||||
is_in_use = TRUE
|
||||
ui_interact(M)
|
||||
if(isAI(usr) || iscyborg(usr) || IsAdminGhost(usr) || hasSiliconAccessInArea(usr))
|
||||
if (!(usr in nearby))
|
||||
if (usr.client && usr.machine==src) // && M.machine == src is omitted because if we triggered this by using the dialog, it doesn't matter if our machine changed in between triggering it and this - the dialog is probably still supposed to refresh.
|
||||
is_in_use = TRUE
|
||||
ui_interact(usr)
|
||||
if(usr && hasSiliconAccessInArea(usr) && !(usr in nearby))
|
||||
if (usr.client && usr.machine==src) // && M.machine == src is omitted because if we triggered this by using the dialog, it doesn't matter if our machine changed in between triggering it and this - the dialog is probably still supposed to refresh.
|
||||
is_in_use = TRUE
|
||||
ui_interact(usr)
|
||||
|
||||
// check for TK users
|
||||
|
||||
|
||||
@@ -315,13 +315,8 @@
|
||||
|
||||
/obj/structure/windoor_assembly/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(
|
||||
/datum/component/simple_rotation,
|
||||
ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS,
|
||||
null,
|
||||
CALLBACK(src, .proc/can_be_rotated),
|
||||
CALLBACK(src,.proc/after_rotation)
|
||||
)
|
||||
var/static/rotation_flags = ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS
|
||||
AddComponent(/datum/component/simple_rotation, rotation_flags, can_be_rotated=CALLBACK(src, .proc/can_be_rotated), after_rotation=CALLBACK(src,.proc/after_rotation))
|
||||
|
||||
/obj/structure/windoor_assembly/proc/can_be_rotated(mob/user,rotation_type)
|
||||
if(anchored)
|
||||
|
||||
Reference in New Issue
Block a user