Merge branch 'punishesarchie' of https://github.com/MalricB/Hyper-Station-13 into punishesarchie

This commit is contained in:
CygnusB
2021-01-19 06:39:56 -03:00
1465 changed files with 377136 additions and 202652 deletions
+15 -9
View File
@@ -44,6 +44,7 @@
var/rad_insulation = RAD_NO_INSULATION
var/icon/blood_splatter_icon
var/icon/cum_splatter_icon
var/list/fingerprints
var/list/fingerprintshidden
var/list/blood_DNA
@@ -52,7 +53,7 @@
/atom/New(loc, ...)
//atom creation method that preloads variables at creation
if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New()
GLOB._preloader.load(src)
world.preloader_load(src)
if(datum_flags & DF_USE_TAG)
GenerateTag()
@@ -313,7 +314,7 @@
/atom/proc/examine(mob/user)
. = list("[get_examine_string(user, TRUE)].")
if(desc)
. += desc
@@ -344,9 +345,6 @@
to_chat(user, "<span class='warning'>You can't move while buckled to [src]!</span>")
return
/atom/proc/prevent_content_explosion()
return FALSE
/atom/proc/contents_explosion(severity, target)
return //For handling the effects of explosions on contents that would not normally be effected
@@ -377,13 +375,13 @@
//returns the mob's dna info as a list, to be inserted in an object's blood_DNA list
/mob/living/proc/get_blood_dna_list()
var/blood_id = get_blood_id()
if(!(blood_id =="blood" || blood_id == "jellyblood"))
if(!(blood_id in GLOB.blood_reagent_types))
return
return list("ANIMAL DNA" = "Y-")
/mob/living/carbon/get_blood_dna_list()
var/blood_id = get_blood_id()
if(!(blood_id =="blood" || blood_id == "jellyblood"))
if(!(blood_id in GLOB.blood_reagent_types))
return
var/list/blood_dna = list()
if(dna)
@@ -687,7 +685,7 @@
var/atom/L = loc
if(!L)
return null
return L.AllowDrop() ? L : get_turf(L)
return L.AllowDrop() ? L : L.drop_location()
/atom/Entered(atom/movable/AM, atom/oldLoc)
SEND_SIGNAL(src, COMSIG_ATOM_ENTERED, AM, oldLoc)
@@ -730,6 +728,13 @@
/atom/proc/multitool_act(mob/living/user, obj/item/I)
return
/atom/proc/multitool_check_buffer(user, obj/item/I, silent = FALSE)
if(!istype(I, /obj/item/multitool))
if(user && !silent)
to_chat(user, "<span class='warning'>[I] has no data buffer!</span>")
return FALSE
return TRUE
/atom/proc/screwdriver_act(mob/living/user, obj/item/I)
SEND_SIGNAL(src, COMSIG_ATOM_SCREWDRIVER_ACT, user, I)
@@ -866,4 +871,5 @@ Proc for attack log creation, because really why not
return TRUE
/atom/proc/intercept_zImpact(atom/movable/AM, levels = 1)
. |= SEND_SIGNAL(src, COMSIG_ATOM_INTERCEPT_Z_FALL, AM, levels)
. |= SEND_SIGNAL(src, COMSIG_ATOM_INTERCEPT_Z_FALL, AM, levels)
@@ -0,0 +1,292 @@
/datum/game_mode
var/list/datum/mind/bloodsuckers = list() // List of minds belonging to this game mode.
var/list/datum/mind/vassals = list() // List of minds that have been turned into Vassals.
//var/list/datum/mind/vamphunters = list() // List of minds hunting vampires. Disabled at the moment
var/obj/effect/sunlight/bloodsucker_sunlight // Sunlight Timer. Created on first Bloodsucker assign. Destroyed on last removed Bloodsucker.
// LISTS //
var/list/vassal_allowed_antags = list(/datum/antagonist/brother, /datum/antagonist/traitor, /datum/antagonist/traitor/internal_affairs, /datum/antagonist/survivalist, \
/datum/antagonist/rev, /datum/antagonist/nukeop, /datum/antagonist/pirate, /datum/antagonist/cult, /datum/antagonist/abductee)
// The antags you're allowed to be if turning Vassal.
/datum/game_mode/bloodsucker
name = "bloodsucker"
config_tag = "bloodsucker"
traitor_name = "Bloodsucker"
antag_flag = ROLE_BLOODSUCKER
false_report_weight = 1
restricted_jobs = list("AI","Cyborg")
protected_jobs = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
required_players = 20
required_enemies = 2
recommended_enemies = 4
reroll_friendly = FALSE
enemy_minimum_age = 7
round_ends_with_antag_death = FALSE
announce_span = "danger"
announce_text = "Filthy, bloodsucking vampires are crawling around disguised as crewmembers!\n\
<span class='danger'>Bloodsuckers</span>: The crew are cattle, while you are both shepherd and slaughterhouse.\n\
<span class='notice'>Crew</span>: Put an end to the undead infestation before the station is overcome!"
/datum/game_mode/bloodsucker/generate_report()
return "Reports indicate that some of your crew may have toppled statues in the past week, angering the gods and becoming cursed with undeath and a desire for blood. Watch out for crewmembers that seem to shun the light or are found pale and delirious."
// Seems to be run by game ONCE, and finds all potential players to be antag.
/datum/game_mode/bloodsucker/pre_setup()
// Set Restricted Jobs
if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
// Set number of Vamps
recommended_enemies = CLAMP(round(num_players()/10), 1, 6);
// Select Antags
for(var/i = 0, i < recommended_enemies, i++)
if (!antag_candidates.len)
break
var/datum/mind/bloodsucker = pick(antag_candidates)
// Can we even BE a bloodsucker?
//if (can_make_bloodsucker(bloodsucker, display_warning=FALSE))
bloodsuckers += bloodsucker
bloodsucker.restricted_roles = restricted_jobs
log_game("[bloodsucker.key] (ckey) has been selected as a Bloodsucker.")
antag_candidates.Remove(bloodsucker) // Apparently you can also write antag_candidates -= bloodsucker
// Assign Hunters (as many as monsters, plus one)
//assign_monster_hunters(bloodsuckers.len, TRUE, bloodsuckers) // Disabled for now
// Do we have enough vamps to continue?
return bloodsuckers.len >= required_enemies
// Gamemode is all done being set up. We have all our Vamps. We now pick objectives and let them know what's happening.
/datum/game_mode/bloodsucker/post_setup()
// Sunlight (Creating Bloodsuckers manually will check to create this, too)
check_start_sunlight()
// Vamps
for(var/datum/mind/bloodsucker in bloodsuckers)
// spawn() --> Run block of code but game continues on past it.
// sleep() --> Run block of code and freeze code there (including whoever called us) until it's resolved.
//Clean Bloodsucker Species (racist?)
//clean_invalid_species(bloodsucker)
// TO-DO !!!
// Add Bloodsucker Antag Datum (or remove from list on Fail)
if (!make_bloodsucker(bloodsucker))
bloodsuckers -= bloodsucker
// NOTE: Hunters are done in ..() parent proc
return ..()
// Checking for ACTUALLY Dead Vamps
/datum/game_mode/bloodsucker/are_special_antags_dead()
// Bloodsucker not Final Dead
for(var/datum/mind/bloodsucker in bloodsuckers)
if(!bloodsucker.AmFinalDeath())
return FALSE
return TRUE
// Init Sunlight (called from datum_bloodsucker.on_gain(), in case game mode isn't even Bloodsucker
/datum/game_mode/proc/check_start_sunlight()
// Already Sunlight (and not about to cancel)
if (istype(bloodsucker_sunlight) && !bloodsucker_sunlight.cancel_me)
return
bloodsucker_sunlight = new ()
// End Sun (last bloodsucker removed)
/datum/game_mode/proc/check_cancel_sunlight()
// No Sunlight
if (!istype(bloodsucker_sunlight))
return
if (bloodsuckers.len <= 0)
bloodsucker_sunlight.cancel_me = TRUE
qdel(bloodsucker_sunlight)
bloodsucker_sunlight = null
/datum/game_mode/proc/is_daylight()
return istype(bloodsucker_sunlight) && bloodsucker_sunlight.amDay
//////////////////////////////////////////////////////////////////////////////
/datum/game_mode/proc/can_make_bloodsucker(datum/mind/bloodsucker, datum/mind/creator, display_warning=TRUE) // Creator is just here so we can display fail messages to whoever is turning us.
// No Mind
if(!bloodsucker || !bloodsucker.key) // KEY is client login?
//if(creator) // REMOVED. You wouldn't see their name if there is no mind, so why say anything?
// to_chat(creator, "<span class='danger'>[bloodsucker] isn't self-aware enough to be raised as a Bloodsucker!</span>")
return FALSE
// Current body is invalid
if(!ishuman(bloodsucker.current))// && !ismonkey(bloodsucker.current))
if(display_warning && creator)
to_chat(creator, "<span class='danger'>[bloodsucker] isn't evolved enough to be raised as a Bloodsucker!</span>")
return FALSE
// Species Must have a HEART (Sorry Plasmabois)
var/mob/living/carbon/human/H = bloodsucker.current
if(NOBLOOD in H.dna.species.species_traits)
if(display_warning && creator)
to_chat(creator, "<span class='danger'>[bloodsucker]'s DNA isn't compatible!</span>")
return FALSE
// Already a Non-Human Antag
if(bloodsucker.has_antag_datum(/datum/antagonist/abductor) || bloodsucker.has_antag_datum(/datum/antagonist/devil) || bloodsucker.has_antag_datum(/datum/antagonist/changeling))
return FALSE
// Already a vamp
if(bloodsucker.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
if(display_warning && creator)
to_chat(creator, "<span class='danger'>[bloodsucker] is already a Bloodsucker!</span>")
return FALSE
// Not High Enough
if(creator)
var/datum/antagonist/bloodsucker/creator_bloodsucker = creator.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
if(!istype(creator_bloodsucker) || creator_bloodsucker.vamplevel < BLOODSUCKER_LEVEL_TO_EMBRACE)
to_chat(creator, "<span class='danger'>Your blood is too thin to turn this corpse!</span>")
return FALSE
return TRUE
/datum/game_mode/proc/make_bloodsucker(datum/mind/bloodsucker, datum/mind/creator = null) // NOTE: This is a game_mode/proc, NOT a game_mode/bloodsucker/proc! We need to access this function despite the game mode.
if (!can_make_bloodsucker(bloodsucker))
return FALSE
// Create Datum: Fledgling
var/datum/antagonist/bloodsucker/A
// [FLEDGLING]
if (creator)
A = new (bloodsucker)
A.creator = creator
bloodsucker.add_antag_datum(A)
// Log
message_admins("[bloodsucker] has become a Bloodsucker, and was created by [creator].")
log_admin("[bloodsucker] has become a Bloodsucker, and was created by [creator].")
// [MASTER]
else
A = bloodsucker.add_antag_datum(ANTAG_DATUM_BLOODSUCKER)
return TRUE
/datum/game_mode/proc/remove_bloodsucker(datum/mind/bloodsucker)
bloodsucker.remove_antag_datum(ANTAG_DATUM_BLOODSUCKER)
/datum/game_mode/proc/clean_invalid_species(datum/mind/bloodsucker)
// Only checking for Humans here
if (!ishuman(bloodsucker.current) || !bloodsucker.current.client)
return
var/am_valid = TRUE
var/mob/living/carbon/human/H = bloodsucker.current
// Check if PLASMAMAN?
if(NOBLOOD in H.dna.species.species_traits)
am_valid = FALSE
// PROBLEM:
//
// Setting species leaves clothes on. If you were a plasmaman, we need to reassign your entire outfit. Otherwise
// everyone will wonder why you're a human with Plasma clothes (jk they'll know you're antag)
// Convert to HUMAN (along with ID and PDA)
if (!am_valid)
H.set_species(/datum/species/human)
H.real_name = H.client.prefs.custom_names["human"]
var/obj/item/card/id/ID = H.wear_id?.GetID()
if(ID)
ID.registered_name = H.real_name
ID.update_label()
/datum/game_mode/proc/can_make_vassal(mob/living/target, datum/mind/creator, display_warning=TRUE)//, check_antag_or_loyal=FALSE)
// Not Correct Type: Abort
if (!iscarbon(target) || !creator)
return FALSE
if (target.stat > UNCONSCIOUS)
return FALSE
// Check Overdose: Am I even addicted to blood? Do I even have any in me?
//if (!target.reagents.addiction_list || !target.reagents.reagent_list)
//message_admins("DEBUG2: can_make_vassal() Abort: No reagents")
// return 0
// Check Overdose: Did my current volume go over the Overdose threshold?
//var/am_addicted = 0
//for (var/datum/reagent/blood/vampblood/blood in target.reagents.addiction_list) // overdosed is tracked in reagent_list, not addiction_list.
//message_admins("DEBUG3: can_make_vassal() Found Blood! [blood] [blood.overdose]")
//if (blood.overdosed)
// am_addicted = 1 // Blood is present in addiction? That's all we need.
// break
//if (!am_addicted)
//message_admins("DEBUG4: can_make_vassal() Abort: No Blood")
// return 0
// No Mind!
if (!target.mind || !target.mind.key)
if (display_warning)
to_chat(creator, "<span class='danger'>[target] isn't self-aware enough to be made into a Vassal.</span>")
return FALSE
// Already MY Vassal
var/datum/antagonist/vassal/V = target.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
if (istype(V) && V.master)
if (V.master.owner == creator)
if (display_warning)
to_chat(creator, "<span class='danger'>[target] is already your loyal Vassal!</span>")
else
if (display_warning)
to_chat(creator, "<span class='danger'>[target] is the loyal Vassal of another Bloodsucker!</span>")
return FALSE
// Already Antag or Loyal (Vamp Hunters count as antags)
if (target.mind.enslaved_to || AmInvalidAntag(target.mind)) //!VassalCheckAntagValid(target.mind, check_antag_or_loyal)) // HAS_TRAIT(target, TRAIT_MINDSHIELD, "implant") ||
if (display_warning)
to_chat(creator, "<span class='danger'>[target] resists the power of your blood to dominate their mind!</span>")
return FALSE
return TRUE
/datum/game_mode/proc/AmValidAntag(datum/mind/M)
// No List?
if(!islist(M.antag_datums) || M.antag_datums.len == 0)
return FALSE
// Am I NOT an invalid Antag? NOTE: We already excluded non-antags above. Don't worry about the "No List?" check in AmInvalidIntag()
return !AmInvalidAntag(M)
/datum/game_mode/proc/AmInvalidAntag(datum/mind/M)
// No List?
if(!islist(M.antag_datums) || M.antag_datums.len == 0)
return FALSE
// Does even ONE antag appear in this mind that isn't in the list? Then FAIL!
for(var/datum/antagonist/antag_datum in M.antag_datums)
if (!(antag_datum.type in vassal_allowed_antags)) // vassal_allowed_antags is a list stored in the game mode, above.
//message_admins("DEBUG VASSAL: Found Invalid: [antag_datum] // [antag_datum.type]")
return TRUE
//message_admins("DEBUG VASSAL: Valid Antags! (total of [M.antag_datums.len])")
// WHEN YOU DELETE THE ABOVE: Remove the 3 second timer on converting the vassal too.
return FALSE
/datum/game_mode/proc/make_vassal(mob/living/target, datum/mind/creator)
if (!can_make_vassal(target,creator))
return FALSE
// Make Vassal
var/datum/antagonist/vassal/V = new (target.mind)
var/datum/antagonist/bloodsucker/B = creator.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
V.master = B
target.mind.add_antag_datum(V, V.master.get_team())
// Update Bloodsucker Title (we're a daddy now)
B.SelectTitle(am_fledgling = FALSE) // Only works if you have no title yet.
// Log
message_admins("[target] has become a Vassal, and is enslaved to [creator].")
log_admin("[target] has become a Vassal, and is enslaved to [creator].")
return TRUE
/datum/game_mode/proc/remove_vassal(datum/mind/vassal)
vassal.remove_antag_datum(ANTAG_DATUM_VASSAL)
+42
View File
@@ -0,0 +1,42 @@
/*
// Called from game mode pre_setup()
/datum/game_mode/proc/assign_monster_hunters(monster_count = 4, guaranteed_hunters = FALSE, list/datum/mind/exclude_from_hunter)
// Not all game modes GUARANTEE a hunter
if (rand(0,2) == 0) // 50% of the time, we get fewer or NO Hunters
if (!guaranteed_hunters)
return
else
monster_count /= 2
var/list/no_hunter_jobs = list("AI","Cyborg")
// Set Restricted Jobs
if(CONFIG_GET(flag/protect_roles_from_antagonist))
no_hunter_jobs += list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
no_hunter_jobs += "Assistant"
// Find Valid Hunters
var/list/datum/mind/hunter_candidates = get_players_for_role(ROLE_MONSTERHUNTER)
// Assign Hunters (as many as vamps, plus one)
for(var/i = 1, i < monster_count, i++) // Start at 1 so we skip Hunters if there's only one sucker.
if (!hunter_candidates.len)
break
// Assign Hunter
var/datum/mind/hunter = pick(hunter_candidates)
hunter_candidates.Remove(hunter) // Remove Either Way
// Already Antag? Skip
if (islist(exclude_from_hunter) && (locate(hunter) in exclude_from_hunter)) //if (islist(hunter.antag_datums) && hunter.antag_datums.len)
i --
continue
// NOTE:
vamphunters += hunter
hunter.restricted_roles = no_hunter_jobs
log_game("[hunter.key] (ckey) has been selected as a Hunter.")
// Called from game mode post_setup()
/datum/game_mode/proc/finalize_monster_hunters(monster_count = 4)
var/amEvil = TRUE // First hunter is always an evil boi
for(var/datum/mind/hunter in vamphunters)
var/datum/antagonist/vamphunter/A = new (hunter)
A.bad_dude = amEvil
hunter.add_antag_datum(A)
amEvil = FALSE // Every other hunter is just a boring greytider
*/
+2 -2
View File
@@ -6,7 +6,7 @@
name = "traitor+brothers"
config_tag = "traitorbro"
restricted_jobs = list("AI", "Cyborg")
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Research Director")
protected_jobs = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Research Director")
announce_span = "danger"
announce_text = "There are Syndicate agents and Blood Brothers on the station!\n\
@@ -59,7 +59,7 @@
return ..()
/datum/game_mode/traitor/bros/generate_report()
return "It's Syndicate recruiting season. Be alert for potential Syndicate infiltrators, but also watch out for disgruntled employees trying to defect. Unlike Nanotrasen, the Syndicate prides itself in teamwork and will only recruit pairs that share a brotherly trust."
return "It's Syndicate recruiting season. Be alert for potential Syndicate infiltrators, but also watch out for disgruntled employees trying to defect. Unlike Kinaris, the Syndicate prides itself in teamwork and will only recruit pairs that share a brotherly trust."
/datum/game_mode/proc/update_brother_icons_added(datum/mind/brother_mind)
var/datum/atom_hud/antag/brotherhud = GLOB.huds[ANTAG_HUD_BROTHER]
+2 -5
View File
@@ -11,7 +11,7 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th
antag_flag = ROLE_CHANGELING
false_report_weight = 10
restricted_jobs = list("AI", "Cyborg")
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") //citadel change - adds HoP, CE, CMO, and RD to ling role blacklist
protected_jobs = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") //citadel change - adds HoP, CE, CMO, and RD to ling role blacklist
required_players = 15
required_enemies = 1
recommended_enemies = 4
@@ -91,13 +91,12 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th
user.shirt_color =chosen_prof.shirt_color
user.socks = chosen_prof.socks
user.socks_color =chosen_prof.socks_color
user.size_multiplier = chosen_prof.size_multiplier
chosen_dna.transfer_identity(user, 1)
user.updateappearance(mutcolor_update=1)
user.update_body()
user.domutcheck()
user.previous_size = chosen_prof.size_multiplier
user.size_multiplier = chosen_prof.size_multiplier
//vars hackery. not pretty, but better than the alternative.
for(var/slot in GLOB.slots)
@@ -125,5 +124,3 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th
C.item_state = chosen_prof.item_state_list[slot]
if(equip)
user.equip_to_slot_or_del(C, GLOB.slot2slot[slot])
user.regenerate_icons()
@@ -79,6 +79,6 @@
..()
/datum/game_mode/traitor/changeling/generate_report()
return "The Syndicate has started some experimental research regarding humanoid shapeshifting. There are rumors that this technology will be field tested on a Nanotrasen station \
return "The Syndicate has started some experimental research regarding humanoid shapeshifting. There are rumors that this technology will be field tested on a Kinaris station \
for infiltration purposes. Be advised that support personel may also be deployed to defend these shapeshifters. Trust nobody - suspect everybody. Do not announce this to the crew, \
as paranoia may spread and inhibit workplace efficiency."
@@ -8,7 +8,7 @@
spray_range = 1
stream_range = 1
volume = 30
list_reagents = list("lube" = 30)
list_reagents = list(/datum/reagent/lube = 30)
//COMBAT CLOWN SHOES
//Clown shoes with combat stats and noslip. Of course they still squeak.
@@ -165,7 +165,7 @@
customfoodfilling = FALSE
seed = null
tastes = list("explosives" = 10)
list_reagents = list("vitamin" = 1)
list_reagents = list(/datum/reagent/consumable/nutriment/vitamin = 1)
/obj/item/grown/bananapeel/bombanana
desc = "A peel from a banana. Why is it beeping?"
+1 -1
View File
@@ -57,7 +57,7 @@
return 1
/datum/game_mode/devil/generate_report()
return "Infernal creatures have been seen nearby offering great boons in exchange for souls. This is considered theft against Nanotrasen, as all employment contracts contain a lien on the \
return "Infernal creatures have been seen nearby offering great boons in exchange for souls. This is considered theft against Kinaris, as all employment contracts contain a lien on the \
employee's soul. If anyone sells their soul in error, contact an attorney to overrule the sale. Be warned that if the devil purchases enough souls, a gateway to hell may open."
/datum/game_mode/devil/proc/post_setup_finalize(datum/mind/devil)
+1 -1
View File
@@ -224,7 +224,7 @@ GLOBAL_VAR_INIT(dynamic_chaos_level, 1.5)
. += "Although your station lies within what is generally considered Kinaris-controlled space, the course of its orbit has caused it to cross unusually close to exogeological features with anomalous readings. Although these features offer opportunities for our research department, it is known that these little understood readings are often correlated with increased activity from competing interstellar organizations and individuals, among them the Wizard Federation and Cult of the Geometer of Blood - all known competitors for Anomaly Type B sites. Exercise elevated caution."
if(40 to 49)
. += "<b>Contested System</b></center><BR>"
. += "Your station's orbit passes along the edge of Kinaris allied influence. While subversive elements remain the most likely threat against your station, Nanotrasen and hostile organizations are bolder here, where our grip is weaker. Exercise increased caution against potential Syndicate agents, and be on the lookout for any potentially anomalous activity."
. += "Your station's orbit passes along the edge of Kinaris allied influence. While subversive elements remain the most likely threat against your station, Kinaris and hostile organizations are bolder here, where our grip is weaker. Exercise increased caution against potential Syndicate agents, and be on the lookout for any potentially anomalous activity."
if(50 to 64)
. += "<b>Uncharted Space</b></center><BR>"
. += "Congratulations and thank you for participating in the Kinaris 'Frontier' space program! Your station is actively orbiting a high value system far from the nearest support stations. Little is known about your region of space, and the opportunity to encounter the unknown invites greater glory. You are encouraged to elevate security as necessary to protect your lives and station assets."
@@ -54,7 +54,7 @@
antag_datum = /datum/antagonist/traitor
antag_flag = ROLE_TRAITOR
restricted_roles = list("AI", "Cyborg")
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
protected_roles = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
required_candidates = 1
weight = 7
cost = 5
@@ -108,4 +108,4 @@
new_head.remove_clumsy = TRUE
new_head = M.mind.add_antag_datum(new_head)
new_head.rev_team.max_headrevs = 1 // Only one revhead if it is latejoin.
return TRUE
return TRUE
@@ -208,7 +208,7 @@
antag_datum = /datum/antagonist/traitor
antag_flag = ROLE_TRAITOR
restricted_roles = list("AI", "Cyborg", "Positronic Brain")
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
protected_roles = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
required_candidates = 1
weight = 4
cost = 10
@@ -224,7 +224,7 @@
antag_datum = /datum/antagonist/traitor/thief
antag_flag = ROLE_TRAITOR
restricted_roles = list("AI", "Cyborg", "Positronic Brain")
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
protected_roles = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
required_candidates = 1
weight = 4
cost = 5
@@ -287,7 +287,7 @@
required_candidates = 1
weight = 2
cost = 0
requirements = list(10,10,10,10,10,10,10,10,10,10)
requirements = list(101,101,101,101,101,101,101,101,101,101)
high_population_requirement = 10
chaos_min = 0.1
chaos_max = 2.0
@@ -367,7 +367,7 @@
return 1
return 0
/datum/dynamic_ruleset/midround/autotraitor/lewd/execute()
var/mob/M = pick(lewd_candidates)
lewd_candidates -= M
@@ -533,6 +533,70 @@
var/body = applicant.become_overmind()
return body
//////////////////////////////////////////////
// //
// BLOOD CULT (MIDROUND) //
// //
//////////////////////////////////////////////
/datum/dynamic_ruleset/midround/bloodcult
name = "Blood Cult"
antag_flag = ROLE_CULTIST
antag_datum = /datum/antagonist/cult
minimum_required_age = 14
restricted_roles = list("AI", "Cyborg")
protected_roles = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
required_candidates = 1
weight = 5
cost = 20
requirements = list(101,101,101,95,70,60,60,60,50,50)
high_population_requirement = 10
pop_per_requirement = 5
flags = HIGHLANDER_RULESET
var/cultist_cap = list(2,2,2,3,3,4,4,4,4,4)
var/datum/team/cult/main_cult
chaos_min = 4.5
/datum/dynamic_ruleset/midround/bloodcult/ready(forced = FALSE)
var/indice_pop = min(10,round(living_players.len/5)+1)
required_candidates = cultist_cap[indice_pop]
. = ..()
datum/dynamic_ruleset/midround/bloodcult/trim_candidates()
..()
for(var/mob/living/player in living_players)
if(issilicon(player)) // Your assigned role doesn't change when you are turned into a silicon.
living_players -= player
continue
if(is_centcom_level(player.z))
living_players -= player // We don't autotator people in CentCom
continue
if(player.mind && (player.mind.special_role || player.mind.antag_datums?.len > 0))
living_players -= player // We don't autotator people with roles already
/datum/dynamic_ruleset/midround/bloodcult/execute()
var/mob/H = pick(living_players)
assigned += H.mind
living_players -= H
main_cult = new
for(var/datum/mind/M in assigned)
var/datum/antagonist/cult/new_cultist = new antag_datum()
new_cultist.cult_team = main_cult
new_cultist.give_equipment = TRUE
M.add_antag_datum(new_cultist)
main_cult.setup_objectives()
return TRUE
/datum/dynamic_ruleset/midround/bloodcult/round_result()
..()
if(main_cult.check_cult_victory())
SSticker.mode_result = "win - cult win"
SSticker.news_report = CULT_SUMMON
else
SSticker.mode_result = "loss - staff stopped the cult"
SSticker.news_report = CULT_FAILURE
//////////////////////////////////////////////
// //
// XENOMORPH (GHOST) //
@@ -601,9 +665,9 @@
cost = 10
requirements = list(101,50,40,30,20,20,20,20,15,10)
high_population_requirement = 50
repeatable = TRUE
repeatable = FALSE
var/list/spawn_locs = list()
chaos_min = 2.5
chaos_min = 3
/datum/dynamic_ruleset/midround/from_ghosts/nightmare/execute()
for(var/X in GLOB.xeno_spawn)
@@ -745,3 +809,52 @@
#undef ABDUCTOR_MAX_TEAMS
#undef REVENANT_SPAWN_THRESHOLD
//////////////////////////////////////////////
// //
// BLOODSUCKERS //
// //
//////////////////////////////////////////////
/datum/dynamic_ruleset/midround/bloodsucker
name = "Bloodsucker Infiltrator"
//config_tag = "latejoin_bloodsucker"
antag_datum = ANTAG_DATUM_BLOODSUCKER
antag_flag = ROLE_TRAITOR
restricted_roles = list("AI", "Cyborg")
protected_roles = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
required_candidates = 1
enemy_roles = list("Security Officer","Head of Security","Captain","AI","Cyborg","Chaplain","Curator")
required_enemies = list(3,2,2,2,2,2,2,2,2,2)
weight = 3
cost = 10
requirements = list(101,101,101,60,55,50,45,40,35,30)
high_population_requirement = 30
repeatable = FALSE
chaos_min = 4.0
datum/dynamic_ruleset/midround/bloodsucker/trim_candidates()
..()
for(var/mob/living/player in living_players)
if(issilicon(player)) // Your assigned role doesn't change when you are turned into a silicon.
living_players -= player
continue
if(is_centcom_level(player.z))
living_players -= player // We don't autotator people in CentCom
continue
if(player.mind && (player.mind.special_role || player.mind.antag_datums?.len > 0))
living_players -= player // We don't autotator people with roles already
/datum/dynamic_ruleset/midround/bloodsucker/ready(forced = FALSE)
if (required_candidates > living_players.len)
return FALSE
return ..()
/datum/dynamic_ruleset/midround/bloodsucker/execute()
var/mob/M = pick(living_players)
assigned += M
living_players -= M
var/datum/antagonist/bloodsucker/newVamp = new
M.mind.add_antag_datum(newVamp)
return TRUE
@@ -11,7 +11,7 @@
antag_flag = ROLE_TRAITOR
antag_datum = /datum/antagonist/traitor/
minimum_required_age = 0
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Cyborg", "Quartermaster")
protected_roles = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Cyborg", "Quartermaster")
restricted_roles = list("Cyborg", "AI") //Malf is it's own ruleset
required_candidates = 1
weight = 5
@@ -28,7 +28,7 @@
antag_flag = ROLE_TRAITOR
antag_datum = /datum/antagonist/traitor/thief
minimum_required_age = 0
//protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Cyborg")
//protected_roles = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Cyborg")
restricted_roles = list("Cyborg", "AI") //Malf is it's own ruleset
//required_candidates = 1
weight = 5
@@ -103,7 +103,7 @@
return 1
return 0
/datum/dynamic_ruleset/roundstart/traitor/lewd/pre_execute()
var/traitor_scaling_coeff = 10 - max(0,round(mode.threat_level/10)-5) // Above 50 threat level, coeff goes down by 1 for every 10 levels
var/num_traitors = min(round(mode.candidates.len / traitor_scaling_coeff) + 1, candidates.len)
@@ -127,7 +127,7 @@
antag_flag = ROLE_BROTHER
antag_datum = /datum/antagonist/brother/
restricted_roles = list("AI", "Cyborg")
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
protected_roles = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
required_candidates = 2
weight = 4
cost = 10
@@ -181,7 +181,7 @@
antag_flag = ROLE_CHANGELING
antag_datum = /datum/antagonist/changeling
restricted_roles = list("AI", "Cyborg")
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
protected_roles = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
required_candidates = 1
weight = 3
cost = 10
@@ -279,7 +279,7 @@
antag_datum = /datum/antagonist/cult
minimum_required_age = 14
restricted_roles = list("AI", "Cyborg")
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
protected_roles = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
required_candidates = 2
weight = 1
cost = 30
@@ -825,4 +825,43 @@
var/ramp_up_final = CLAMP(round(meteorminutes/rampupdelta), 1, 10)
spawn_meteors(ramp_up_final, wavetype)
spawn_meteors(ramp_up_final, wavetype)
//////////////////////////////////////////////
// //
// BLOODSUCKERS //
// //
//////////////////////////////////////////////
/datum/dynamic_ruleset/roundstart/bloodsucker
name = "Bloodsuckers"
persistent = TRUE
antag_flag = ROLE_BLOODSUCKER
antag_datum = ANTAG_DATUM_BLOODSUCKER
minimum_required_age = 0
protected_roles = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
restricted_roles = list("Cyborg", "AI")
required_candidates = 1
weight = 3
cost = 0
requirements = list(101,101,101,70,60,60,50,50,50,40)
high_population_requirement = 10
chaos_min = 4.0
/datum/dynamic_ruleset/roundstart/bloodsucker/pre_execute()
var/num_bloodsuckers = min(round(mode.candidates.len / 10) +1, candidates.len)
for (var/i = 1 to num_bloodsuckers)
var/mob/M = pick_n_take(candidates)
assigned += M.mind
M.mind.special_role = ROLE_BLOODSUCKER
M.mind.restricted_roles = restricted_roles
return TRUE
/datum/dynamic_ruleset/roundstart/bloodsucker/pre_execute()
var/mob/M = pick_n_take(candidates)
assigned += M.mind
M.mind.special_role = ROLE_BLOODSUCKER
M.mind.restricted_roles = restricted_roles
return TRUE
+2 -1
View File
@@ -79,6 +79,7 @@
///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things
/datum/game_mode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report.
//finalize_monster_hunters() Disabled for now
if(!report)
report = !CONFIG_GET(flag/no_intercept_report)
addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME)
@@ -549,4 +550,4 @@
/// Mode specific admin panel.
/datum/game_mode/proc/admin_panel()
return
return
+2 -2
View File
@@ -247,8 +247,8 @@ GLOBAL_LIST_EMPTY(objectives)
human_check = FALSE
/datum/objective/hijack
explanation_text = "Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive and out of custody."
team_explanation_text = "Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive and out of custody. Leave no team member behind."
explanation_text = "Hijack the shuttle to ensure no loyalist Kinaris crew escape alive and out of custody."
team_explanation_text = "Hijack the shuttle to ensure no loyalist Kinaris crew escape alive and out of custody. Leave no team member behind."
martyr_compatible = 0 //Technically you won't get both anyway.
/datum/objective/hijack/check_completion() // Requires all owners to escape.
+3 -3
View File
@@ -10,14 +10,14 @@
required_enemies = 5
recommended_enemies = 8
reroll_friendly = 0
traitor_name = "Nanotrasen Internal Affairs Agent"
traitor_name = "Kinaris Internal Affairs Agent"
antag_flag = ROLE_INTERNAL_AFFAIRS
traitors_possible = 10 //hard limit on traitors if scaling is turned off
num_modifier = 4 // Four additional traitors
antag_datum = /datum/antagonist/traitor/internal_affairs
announce_text = "There are Nanotrasen Internal Affairs Agents trying to kill each other!\n\
announce_text = "There are Kinaris Internal Affairs Agents trying to kill each other!\n\
<span class='danger'>IAA</span>: Eliminate your targets and protect yourself!\n\
<span class='notice'>Crew</span>: Stop the IAA agents before they can cause too much mayhem."
@@ -78,5 +78,5 @@
/datum/game_mode/traitor/internal_affairs/generate_report()
return "Nanotrasen denies any accusations of placing internal affairs agents onboard your station to eliminate inconvenient employees. Any further accusations against CentCom for such \
return "Kinaris denies any accusations of placing internal affairs agents onboard your station to eliminate inconvenient employees. Any further accusations against CentCom for such \
actions will be met with a conversation with an official internal affairs agent."
+1 -1
View File
@@ -96,4 +96,4 @@
/datum/game_mode/traitor/generate_report()
return "Although more specific threats are commonplace, you should always remain vigilant for Syndicate agents aboard your station. Syndicate communications have implied that many \
Nanotrasen employees are Syndicate agents with hidden memories that may be activated at a moment's notice, so it's possible that these agents might not even know their positions."
Kinaris employees are Syndicate agents with hidden memories that may be activated at a moment's notice, so it's possible that these agents might not even know their positions."
+422 -410
View File
@@ -1,410 +1,422 @@
/obj/machinery/sleep_console
name = "sleeper console"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "console"
density = FALSE
/obj/machinery/sleeper
name = "sleeper"
desc = "An enclosed machine used to stabilize and heal patients."
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
density = FALSE
state_open = TRUE
circuit = /obj/item/circuitboard/machine/sleeper
req_access = list(ACCESS_CMO) //Used for reagent deletion and addition of non medicines
var/efficiency = 1
var/min_health = -25
var/list/available_chems
var/controls_inside = FALSE
var/list/possible_chems = list(
list("epinephrine", "morphine", "salbutamol", "bicaridine", "kelotane"),
list("oculine","inacusiate"),
list("antitoxin", "mutadone", "mannitol", "pen_acid"),
list("omnizine")
)
var/list/chem_buttons //Used when emagged to scramble which chem is used, eg: antitoxin -> morphine
var/scrambled_chems = FALSE //Are chem buttons scrambled? used as a warning
var/enter_message = "<span class='notice'><b>You feel cool air surround you. You go numb as your senses turn inward.</b></span>"
/obj/machinery/sleeper/Initialize()
. = ..()
create_reagents(500, NO_REACT)
occupant_typecache = GLOB.typecache_living
update_icon()
reset_chem_buttons()
RefreshParts()
add_inital_chems()
/obj/machinery/sleeper/on_deconstruction()
var/obj/item/reagent_containers/sleeper_buffer/buffer = new (loc)
buffer.volume = reagents.maximum_volume
buffer.reagents.maximum_volume = reagents.maximum_volume
reagents.trans_to(buffer.reagents, reagents.total_volume)
/obj/machinery/sleeper/proc/add_inital_chems()
for(var/i in available_chems)
var/datum/reagent/R = reagents.has_reagent(i)
if(!R)
reagents.add_reagent(i, (20))
continue
if(R.volume < 20)
reagents.add_reagent(i, (20 - R.volume))
/obj/machinery/sleeper/RefreshParts()
var/E
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
E += B.rating
var/I
for(var/obj/item/stock_parts/manipulator/M in component_parts)
I += M.rating
efficiency = initial(efficiency)* E
min_health = initial(min_health) - (10*(E-1)) // CIT CHANGE - changes min health equation to be min_health - (matterbin rating * 10)
available_chems = list()
for(var/i in 1 to I)
available_chems |= possible_chems[i]
reset_chem_buttons()
//Total container size 500 - 2000u
if(reagents)
reagents.maximum_volume = (500*E)
/obj/machinery/sleeper/update_icon()
icon_state = initial(icon_state)
if(state_open)
icon_state += "-open"
/obj/machinery/sleeper/container_resist(mob/living/user)
visible_message("<span class='notice'>[occupant] emerges from [src]!</span>",
"<span class='notice'>You climb out of [src]!</span>")
open_machine()
/obj/machinery/sleeper/Exited(atom/movable/user)
if (!state_open && user == occupant)
container_resist(user)
/obj/machinery/sleeper/relaymove(mob/user)
if (!state_open)
container_resist(user)
/obj/machinery/sleeper/open_machine()
if(!state_open && !panel_open)
..()
/obj/machinery/sleeper/close_machine(mob/user)
if((isnull(user) || istype(user)) && state_open && !panel_open)
..(user)
var/mob/living/mob_occupant = occupant
if(mob_occupant && mob_occupant.stat != DEAD)
to_chat(occupant, "[enter_message]")
/obj/machinery/sleeper/emp_act(severity)
. = ..()
if (. & EMP_PROTECT_SELF)
return
if(is_operational() && occupant)
var/datum/reagent/R = pick(reagents.reagent_list)
inject_chem(R.id, occupant)
open_machine()
//Is this too much?
if(severity == EMP_HEAVY)
var/chem = pick(available_chems)
available_chems -= chem
available_chems += get_random_reagent_id()
reset_chem_buttons()
/obj/machinery/sleeper/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/reagent_containers/sleeper_buffer))
var/obj/item/reagent_containers/sleeper_buffer/SB = I
if((SB.reagents.total_volume + reagents.total_volume) < reagents.maximum_volume)
SB.reagents.trans_to(reagents, SB.reagents.total_volume)
visible_message("[user] places the [SB] into the [src].")
qdel(SB)
return
else
SB.reagents.trans_to(reagents, SB.reagents.total_volume)
visible_message("[user] adds as much as they can to the [src] from the [SB].")
return
if(istype(I, /obj/item/reagent_containers))
var/obj/item/reagent_containers/RC = I
if(RC.reagents.total_volume == 0)
to_chat(user, "<span class='notice'>The [I] is empty!</span>")
for(var/datum/reagent/R in RC.reagents.reagent_list)
if((obj_flags & EMAGGED) || (allowed(usr)))
break
if(!istype(R, /datum/reagent/medicine))
visible_message("The [src] gives out a hearty boop and rejects the [I]. The Sleeper's screen flashes with a pompous \"Medicines only, please.\"")
return
RC.reagents.trans_to(reagents, 1000)
visible_message("[user] adds as much as they can to the [src] from the [I].")
return
/obj/machinery/sleeper/MouseDrop_T(mob/target, mob/user)
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
return
close_machine(target)
/obj/machinery/sleeper/screwdriver_act(mob/living/user, obj/item/I)
. = TRUE
if(..())
return
if(occupant)
to_chat(user, "<span class='warning'>[src] is currently occupied!</span>")
return
if(state_open)
to_chat(user, "<span class='warning'>[src] must be closed to [panel_open ? "close" : "open"] its maintenance hatch!</span>")
return
if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I))
return
return FALSE
/obj/machinery/sleeper/wrench_act(mob/living/user, obj/item/I)
. = ..()
if(default_change_direction_wrench(user, I))
return TRUE
/obj/machinery/sleeper/crowbar_act(mob/living/user, obj/item/I)
. = ..()
if(default_pry_open(I))
return TRUE
if(default_deconstruction_crowbar(I))
return TRUE
/obj/machinery/sleeper/default_pry_open(obj/item/I) //wew
. = !(state_open || panel_open || (flags_1 & NODECONSTRUCT_1)) && I.tool_behaviour == TOOL_CROWBAR
if(.)
I.play_tool_sound(src, 50)
visible_message("<span class='notice'>[usr] pries open [src].</span>", "<span class='notice'>You pry open [src].</span>")
open_machine()
/obj/machinery/sleeper/AltClick(mob/user)
if(!user.canUseTopic(src, !issilicon(user)))
return
if(state_open)
close_machine()
else
open_machine()
/obj/machinery/sleeper/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click [src] to [state_open ? "close" : "open"] it.</span>"
/obj/machinery/sleeper/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
if(controls_inside && state == GLOB.notcontained_state)
state = GLOB.default_state // If it has a set of controls on the inside, make it actually controllable by the mob in it.
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "sleeper", name, 550, 700, master_ui, state)
ui.open()
/obj/machinery/sleeper/ui_data()
var/list/data = list()
data["occupied"] = occupant ? 1 : 0
data["open"] = state_open
data["efficiency"] = efficiency
data["current_vol"] = reagents.total_volume
data["tot_capacity"] = reagents.maximum_volume
data["chems"] = list()
for(var/chem in available_chems)
var/datum/reagent/R = reagents.has_reagent(chem)
R = GLOB.chemical_reagents_list[chem]
data["synthchems"] += list(list("name" = R.name, "id" = R.id, "synth_allowed" = synth_allowed(chem)))
for(var/datum/reagent/R in reagents.reagent_list)
data["chems"] += list(list("name" = R.name, "id" = R.id, "vol" = R.volume, "purity" = R.purity, "allowed" = chem_allowed(R.id)))
data["occupant"] = list()
var/mob/living/mob_occupant = occupant
if(mob_occupant)
data["occupant"]["name"] = mob_occupant.name
switch(mob_occupant.stat)
if(CONSCIOUS)
data["occupant"]["stat"] = "Conscious"
data["occupant"]["statstate"] = "good"
if(SOFT_CRIT)
data["occupant"]["stat"] = "Conscious"
data["occupant"]["statstate"] = "average"
if(UNCONSCIOUS)
data["occupant"]["stat"] = "Unconscious"
data["occupant"]["statstate"] = "average"
if(DEAD)
data["occupant"]["stat"] = "Dead"
data["occupant"]["statstate"] = "bad"
data["occupant"]["health"] = mob_occupant.health
data["occupant"]["maxHealth"] = mob_occupant.maxHealth
data["occupant"]["minHealth"] = HEALTH_THRESHOLD_DEAD
data["occupant"]["bruteLoss"] = mob_occupant.getBruteLoss()
data["occupant"]["oxyLoss"] = mob_occupant.getOxyLoss()
data["occupant"]["toxLoss"] = mob_occupant.getToxLoss()
data["occupant"]["fireLoss"] = mob_occupant.getFireLoss()
data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss()
data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN)
data["occupant"]["reagents"] = list()
if(mob_occupant.reagents && mob_occupant.reagents.reagent_list.len)
for(var/datum/reagent/R in mob_occupant.reagents.reagent_list)
data["occupant"]["reagents"] += list(list("name" = R.name, "volume" = R.volume))
data["occupant"]["failing_organs"] = list()
var/mob/living/carbon/C = mob_occupant
if(C)
for(var/obj/item/organ/Or in C.getFailingOrgans())
if(istype(Or, /obj/item/organ/brain))
continue
data["occupant"]["failing_organs"] += list(list("name" = Or.name))
if(mob_occupant.has_dna()) // Blood-stuff is mostly a copy-paste from the healthscanner.
var/blood_id = C.get_blood_id()
if(blood_id)
data["occupant"]["blood"] = list() // We can start populating this list.
var/blood_type = C.dna.blood_type
if(blood_id != "blood") // special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
if(R)
blood_type = R.name
else
blood_type = blood_id
data["occupant"]["blood"]["maxBloodVolume"] = (BLOOD_VOLUME_NORMAL*C.blood_ratio)
data["occupant"]["blood"]["currentBloodVolume"] = C.blood_volume
data["occupant"]["blood"]["dangerBloodVolume"] = BLOOD_VOLUME_SAFE
data["occupant"]["blood"]["bloodType"] = blood_type
return data
/obj/machinery/sleeper/ui_act(action, params)
if(..())
return
var/mob/living/mob_occupant = occupant
switch(action)
if("door")
if(state_open)
close_machine()
else
open_machine()
. = TRUE
if("inject")
var/chem = params["chem"]
var/amount = text2num(params["volume"])
if(!is_operational() || !mob_occupant)
return
if(mob_occupant.health < min_health && chem != "epinephrine")
return
if(inject_chem(chem, usr, amount))
. = TRUE
if(scrambled_chems && prob(5))
to_chat(usr, "<span class='warning'>Chemical system re-route detected, results may not be as expected!</span>")
if("synth")
var/chem = params["chem"]
if(!is_operational())
return
reagents.add_reagent(chem_buttons[chem], 10) //other_purity = 0.75 for when the mechanics are in
if("purge")
var/chem = params["chem"]
if(allowed(usr))
if(!is_operational())
return
reagents.remove_reagent(chem, 10)
return
if(chem in available_chems)
if(!is_operational())
return
/*var/datum/reagent/R = reagents.has_reagent(chem) //For when purity effects are in
if(R.purity < 0.8)*/
reagents.remove_reagent(chem, 10)
else
visible_message("<span class='warning'>Access Denied.</span>")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
/obj/machinery/sleeper/emag_act(mob/user)
. = ..()
obj_flags |= EMAGGED
scramble_chem_buttons()
to_chat(user, "<span class='warning'>You scramble the sleeper's user interface!</span>")
return TRUE
//trans to
/obj/machinery/sleeper/proc/inject_chem(chem, mob/user, volume = 10)
if(chem_allowed(chem))
reagents.trans_id_to(occupant, chem, volume)//emag effect kicks in here so that the "intended" chem is used for all checks, for extra FUUU
if(user)
log_combat(user, occupant, "injected [chem] into", addition = "via [src]")
return TRUE
/obj/machinery/sleeper/proc/chem_allowed(chem)
var/mob/living/mob_occupant = occupant
if(!mob_occupant || !mob_occupant.reagents)
return
var/amount = mob_occupant.reagents.get_reagent_amount(chem) + 10 <= 20 * efficiency
var/occ_health = mob_occupant.health > min_health || chem == "epinephrine"
return amount && occ_health
/obj/machinery/sleeper/proc/synth_allowed(chem)
var/datum/reagent/R = reagents.has_reagent(chem)
if(!R)
return TRUE
if(R.volume < 50)
return TRUE
return FALSE
/obj/machinery/sleeper/proc/reset_chem_buttons()
scrambled_chems = FALSE
LAZYINITLIST(chem_buttons)
for(var/chem in available_chems)
chem_buttons[chem] = chem
/obj/machinery/sleeper/proc/scramble_chem_buttons()
scrambled_chems = TRUE
var/list/av_chem = available_chems.Copy()
for(var/chem in av_chem)
chem_buttons[chem] = pick_n_take(av_chem) //no dupes, allow for random buttons to still be correct
/obj/machinery/sleeper/syndie
icon_state = "sleeper_s"
controls_inside = TRUE
/obj/machinery/sleeper/syndie/Initialize()
. = ..()
component_parts = list()
component_parts += new /obj/item/circuitboard/machine/sleeper/syndie(null)
component_parts += new /obj/item/stock_parts/matter_bin/super(null)
component_parts += new /obj/item/stock_parts/manipulator/pico(null)
component_parts += new /obj/item/stack/sheet/glass(null)
component_parts += new /obj/item/stack/sheet/glass(null)
component_parts += new /obj/item/stack/cable_coil(null)
RefreshParts()
/obj/machinery/sleeper/syndie/fullupgrade/Initialize()
. = ..()
component_parts = list()
component_parts += new /obj/item/circuitboard/machine/sleeper/syndie(null)
component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null)
component_parts += new /obj/item/stock_parts/manipulator/femto(null)
component_parts += new /obj/item/stack/sheet/glass(null)
component_parts += new /obj/item/stack/sheet/glass(null)
component_parts += new /obj/item/stack/cable_coil(null)
RefreshParts()
/obj/machinery/sleeper/clockwork
name = "soothing sleeper"
desc = "A large cryogenics unit built from brass. Its surface is pleasantly cool the touch."
icon_state = "sleeper_clockwork"
enter_message = "<span class='bold inathneq_small'>You hear the gentle hum and click of machinery, and are lulled into a sense of peace.</span>"
possible_chems = list(list("epinephrine", "salbutamol", "bicaridine", "kelotane", "oculine", "inacusiate", "mannitol"))
/obj/machinery/sleeper/clockwork/process()
if(occupant && isliving(occupant))
var/mob/living/L = occupant
if(GLOB.clockwork_vitality) //If there's Vitality, the sleeper has passive healing
GLOB.clockwork_vitality = max(0, GLOB.clockwork_vitality - 1)
L.adjustBruteLoss(-1)
L.adjustFireLoss(-1)
L.adjustOxyLoss(-5)
/obj/machinery/sleeper/old
icon_state = "oldpod"
/obj/machinery/sleep_console
name = "sleeper console"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "console"
density = FALSE
/obj/machinery/sleeper
name = "sleeper"
desc = "An enclosed machine used to stabilize and heal patients."
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
density = FALSE
state_open = TRUE
circuit = /obj/item/circuitboard/machine/sleeper
req_access = list(ACCESS_CMO) //Used for reagent deletion and addition of non medicines
var/efficiency = 1
var/min_health = 30
var/list/available_chems
var/controls_inside = FALSE
var/list/possible_chems = list(
list(/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/morphine, /datum/reagent/medicine/salbutamol, /datum/reagent/medicine/bicaridine, /datum/reagent/medicine/kelotane),
list(/datum/reagent/medicine/oculine,/datum/reagent/medicine/inacusiate),
list(/datum/reagent/medicine/antitoxin, /datum/reagent/medicine/mutadone, /datum/reagent/medicine/mannitol, /datum/reagent/medicine/pen_acid),
list(/datum/reagent/medicine/omnizine)
)
var/list/chem_buttons //Used when emagged to scramble which chem is used, eg: antitoxin -> morphine
var/scrambled_chems = FALSE //Are chem buttons scrambled? used as a warning
var/enter_message = "<span class='notice'><b>You feel cool air surround you. You go numb as your senses turn inward.</b></span>"
/obj/machinery/sleeper/Initialize()
. = ..()
create_reagents(500, NO_REACT)
occupant_typecache = GLOB.typecache_living
update_icon()
reset_chem_buttons()
RefreshParts()
add_inital_chems()
/obj/machinery/sleeper/on_deconstruction()
var/obj/item/reagent_containers/sleeper_buffer/buffer = new (loc)
buffer.volume = reagents.maximum_volume
buffer.reagents.maximum_volume = reagents.maximum_volume
reagents.trans_to(buffer.reagents, reagents.total_volume)
/obj/machinery/sleeper/proc/add_inital_chems()
for(var/i in available_chems)
var/datum/reagent/R = reagents.has_reagent(i)
if(!R)
reagents.add_reagent(i, (20))
continue
if(R.volume < 20)
reagents.add_reagent(i, (20 - R.volume))
/obj/machinery/sleeper/RefreshParts()
var/E
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
E += B.rating
var/I
for(var/obj/item/stock_parts/manipulator/M in component_parts)
I += M.rating
efficiency = initial(efficiency)* E
min_health = initial(min_health) - (10*(E-1)) // CIT CHANGE - changes min health equation to be min_health - (matterbin rating * 10)
available_chems = list()
for(var/i in 1 to I)
available_chems |= possible_chems[i]
reset_chem_buttons()
//Total container size 500 - 2000u
if(reagents)
reagents.maximum_volume = (500*E)
/obj/machinery/sleeper/update_icon()
icon_state = initial(icon_state)
if(state_open)
icon_state += "-open"
/obj/machinery/sleeper/container_resist(mob/living/user)
visible_message("<span class='notice'>[occupant] emerges from [src]!</span>",
"<span class='notice'>You climb out of [src]!</span>")
open_machine()
/obj/machinery/sleeper/Exited(atom/movable/user)
if (!state_open && user == occupant)
container_resist(user)
/obj/machinery/sleeper/relaymove(mob/user)
if (!state_open)
container_resist(user)
/obj/machinery/sleeper/open_machine()
if(!state_open && !panel_open)
..()
/obj/machinery/sleeper/close_machine(mob/user)
if((isnull(user) || istype(user)) && state_open && !panel_open)
..(user)
var/mob/living/mob_occupant = occupant
if(mob_occupant && mob_occupant.stat != DEAD)
to_chat(occupant, "[enter_message]")
/obj/machinery/sleeper/emp_act(severity)
. = ..()
if (. & EMP_PROTECT_SELF)
return
if(is_operational() && occupant)
var/datum/reagent/R = pick(reagents.reagent_list)
inject_chem(R.type, occupant)
open_machine()
//Is this too much?
if(severity == EMP_HEAVY)
var/chem = pick(available_chems)
available_chems -= chem
available_chems += get_random_reagent_id()
reset_chem_buttons()
/obj/machinery/sleeper/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/reagent_containers/sleeper_buffer))
var/obj/item/reagent_containers/sleeper_buffer/SB = I
if((SB.reagents.total_volume + reagents.total_volume) < reagents.maximum_volume)
SB.reagents.trans_to(reagents, SB.reagents.total_volume)
visible_message("[user] places the [SB] into the [src].")
qdel(SB)
return
else
SB.reagents.trans_to(reagents, SB.reagents.total_volume)
visible_message("[user] adds as much as they can to the [src] from the [SB].")
return
if(istype(I, /obj/item/reagent_containers))
var/obj/item/reagent_containers/RC = I
if(RC.reagents.total_volume == 0)
to_chat(user, "<span class='notice'>The [I] is empty!</span>")
for(var/datum/reagent/R in RC.reagents.reagent_list)
if((obj_flags & EMAGGED) || (allowed(usr)))
break
if(!istype(R, /datum/reagent/medicine))
visible_message("The [src] gives out a hearty boop and rejects the [I]. The Sleeper's screen flashes with a pompous \"Medicines only, please.\"")
return
RC.reagents.trans_to(reagents, 1000)
visible_message("[user] adds as much as they can to the [src] from the [I].")
return
/obj/machinery/sleeper/MouseDrop_T(mob/target, mob/user)
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
return
close_machine(target)
/obj/machinery/sleeper/screwdriver_act(mob/living/user, obj/item/I)
. = TRUE
if(..())
return
if(occupant)
to_chat(user, "<span class='warning'>[src] is currently occupied!</span>")
return
if(state_open)
to_chat(user, "<span class='warning'>[src] must be closed to [panel_open ? "close" : "open"] its maintenance hatch!</span>")
return
if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I))
return
return FALSE
/obj/machinery/sleeper/wrench_act(mob/living/user, obj/item/I)
. = ..()
if(default_change_direction_wrench(user, I))
return TRUE
/obj/machinery/sleeper/crowbar_act(mob/living/user, obj/item/I)
. = ..()
if(default_pry_open(I))
return TRUE
if(default_deconstruction_crowbar(I))
return TRUE
/obj/machinery/sleeper/default_pry_open(obj/item/I) //wew
. = !(state_open || panel_open || (flags_1 & NODECONSTRUCT_1)) && I.tool_behaviour == TOOL_CROWBAR
if(.)
I.play_tool_sound(src, 50)
visible_message("<span class='notice'>[usr] pries open [src].</span>", "<span class='notice'>You pry open [src].</span>")
open_machine()
/obj/machinery/sleeper/AltClick(mob/user)
. = ..()
if(!user.canUseTopic(src, !issilicon(user)))
return
if(state_open)
close_machine()
else
open_machine()
return TRUE
/obj/machinery/sleeper/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click [src] to [state_open ? "close" : "open"] it.</span>"
/obj/machinery/sleeper/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
if(controls_inside && state == GLOB.notcontained_state)
state = GLOB.default_state // If it has a set of controls on the inside, make it actually controllable by the mob in it.
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "sleeper", name, 550, 700, master_ui, state)
ui.open()
/obj/machinery/sleeper/ui_data()
var/list/data = list()
var/chemical_list = list()
var/blood_percent = 0
data["occupied"] = occupant ? 1 : 0
data["open"] = state_open
data["blood_levels"] = blood_percent
data["blood_status"] = "Patient either has no blood, or does not require it to function."
data["chemical_list"] = chemical_list
data["chems"] = list()
for(var/chem in available_chems)
var/datum/reagent/R = reagents.has_reagent(chem)
R = GLOB.chemical_reagents_list[chem]
data["synthchems"] += list(list("name" = R.name, "id" = R.type, "synth_allowed" = synth_allowed(chem)))
for(var/datum/reagent/R in reagents.reagent_list)
data["chems"] += list(list("name" = R.name, "id" = R.type, "vol" = R.volume, "purity" = R.purity, "allowed" = chem_allowed(R.type)))
data["occupant"] = list()
var/mob/living/mob_occupant = occupant
if(mob_occupant)
data["occupant"]["name"] = mob_occupant.name
switch(mob_occupant.stat)
if(CONSCIOUS)
data["occupant"]["stat"] = "Conscious"
data["occupant"]["statstate"] = "good"
if(SOFT_CRIT)
data["occupant"]["stat"] = "Conscious"
data["occupant"]["statstate"] = "average"
if(UNCONSCIOUS)
data["occupant"]["stat"] = "Unconscious"
data["occupant"]["statstate"] = "average"
if(DEAD)
data["occupant"]["stat"] = "Dead"
data["occupant"]["statstate"] = "bad"
data["occupant"]["health"] = mob_occupant.health
data["occupant"]["maxHealth"] = mob_occupant.maxHealth
data["occupant"]["minHealth"] = HEALTH_THRESHOLD_DEAD
data["occupant"]["bruteLoss"] = mob_occupant.getBruteLoss()
data["occupant"]["oxyLoss"] = mob_occupant.getOxyLoss()
data["occupant"]["toxLoss"] = mob_occupant.getToxLoss()
data["occupant"]["fireLoss"] = mob_occupant.getFireLoss()
data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss()
data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN)
if(mob_occupant.reagents.reagent_list.len)
for(var/datum/reagent/R in mob_occupant.reagents.reagent_list)
chemical_list += list(list("name" = R.name, "volume" = R.volume))
else
chemical_list = "Patient has no reagents."
data["occupant"]["failing_organs"] = list()
var/mob/living/carbon/C = mob_occupant
if(C)
for(var/obj/item/organ/Or in C.getFailingOrgans())
if(istype(Or, /obj/item/organ/brain))
continue
data["occupant"]["failing_organs"] += list(list("name" = Or.name))
if(istype(C)) //Non-carbons shouldn't be able to enter sleepers, but this is to prevent runtimes if something ever breaks
if(mob_occupant.has_dna()) // Blood-stuff is mostly a copy-paste from the healthscanner.
blood_percent = round((C.blood_volume / BLOOD_VOLUME_NORMAL)*100)
var/blood_id = C.get_blood_id()
var/blood_warning = ""
if(blood_percent < 80)
blood_warning = "Patient has low blood levels."
if(blood_percent < 60)
blood_warning = "Patient has DANGEROUSLY low blood levels."
if(blood_id)
var/blood_type = C.dna.blood_type
if(!(blood_id in GLOB.blood_reagent_types)) // special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
if(R)
blood_type = R.name
else
blood_type = blood_id
data["blood_status"] = "Patient has [blood_type] type blood. [blood_warning]"
data["blood_levels"] = blood_percent
return data
/obj/machinery/sleeper/ui_act(action, params)
if(..())
return
var/mob/living/mob_occupant = occupant
switch(action)
if("door")
if(state_open)
close_machine()
else
open_machine()
. = TRUE
if("inject")
var/chem = text2path(params["chem"])
var/amount = text2num(params["volume"])
if(!is_operational() || !mob_occupant || isnull(chem))
return
if(mob_occupant.health < min_health && chem != /datum/reagent/medicine/epinephrine)
return
if(inject_chem(chem, usr, amount))
. = TRUE
if(scrambled_chems && prob(5))
to_chat(usr, "<span class='warning'>Chemical system re-route detected, results may not be as expected!</span>")
if("synth")
var/chem = text2path(params["chem"])
if(!is_operational())
return
reagents.add_reagent(chem_buttons[chem], 10) //other_purity = 0.75 for when the mechanics are in
if("purge")
var/chem = text2path(params["chem"])
if(allowed(usr))
if(!is_operational())
return
reagents.remove_reagent(chem, 1000)
return
if(chem in available_chems)
if(!is_operational())
return
/*var/datum/reagent/R = reagents.has_reagent(chem) //For when purity effects are in
if(R.purity < 0.8)*/
reagents.remove_reagent(chem, 1000)
else
visible_message("<span class='warning'>Access Denied.</span>")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
/obj/machinery/sleeper/emag_act(mob/user)
. = ..()
obj_flags |= EMAGGED
scramble_chem_buttons()
to_chat(user, "<span class='warning'>You scramble the sleeper's user interface!</span>")
return TRUE
//trans to
/obj/machinery/sleeper/proc/inject_chem(chem, mob/user, volume = 10)
if(chem_allowed(chem))
reagents.trans_id_to(occupant, chem, volume)//emag effect kicks in here so that the "intended" chem is used for all checks, for extra FUUU
if(user)
log_combat(user, occupant, "injected [chem] into", addition = "via [src]")
return TRUE
/obj/machinery/sleeper/proc/chem_allowed(chem)
var/mob/living/mob_occupant = occupant
if(!mob_occupant || !mob_occupant.reagents)
return
var/amount = mob_occupant.reagents.get_reagent_amount(chem) + 10 <= 20 * efficiency
var/occ_health = mob_occupant.health > min_health || chem == /datum/reagent/medicine/epinephrine
return amount && occ_health
/obj/machinery/sleeper/proc/synth_allowed(chem)
var/datum/reagent/R = reagents.has_reagent(chem)
if(!R)
return TRUE
if(R.volume < 50)
return TRUE
return FALSE
/obj/machinery/sleeper/proc/reset_chem_buttons()
scrambled_chems = FALSE
LAZYINITLIST(chem_buttons)
for(var/chem in available_chems)
chem_buttons[chem] = chem
/obj/machinery/sleeper/proc/scramble_chem_buttons()
scrambled_chems = TRUE
var/list/av_chem = available_chems.Copy()
for(var/chem in av_chem)
chem_buttons[chem] = pick_n_take(av_chem) //no dupes, allow for random buttons to still be correct
/obj/machinery/sleeper/syndie
icon_state = "sleeper_s"
controls_inside = TRUE
/obj/machinery/sleeper/syndie/Initialize()
. = ..()
component_parts = list()
component_parts += new /obj/item/circuitboard/machine/sleeper/syndie(null)
component_parts += new /obj/item/stock_parts/matter_bin/super(null)
component_parts += new /obj/item/stock_parts/manipulator/pico(null)
component_parts += new /obj/item/stack/sheet/glass(null)
component_parts += new /obj/item/stack/sheet/glass(null)
component_parts += new /obj/item/stack/cable_coil(null)
RefreshParts()
/obj/machinery/sleeper/syndie/fullupgrade/Initialize()
. = ..()
component_parts = list()
component_parts += new /obj/item/circuitboard/machine/sleeper/syndie(null)
component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null)
component_parts += new /obj/item/stock_parts/manipulator/femto(null)
component_parts += new /obj/item/stack/sheet/glass(null)
component_parts += new /obj/item/stack/sheet/glass(null)
component_parts += new /obj/item/stack/cable_coil(null)
RefreshParts()
/obj/machinery/sleeper/clockwork
name = "soothing sleeper"
desc = "A large cryogenics unit built from brass. Its surface is pleasantly cool the touch."
icon_state = "sleeper_clockwork"
enter_message = "<span class='bold inathneq_small'>You hear the gentle hum and click of machinery, and are lulled into a sense of peace.</span>"
possible_chems = list(list("epinephrine", "salbutamol", "bicaridine", "kelotane", "oculine", "inacusiate", "mannitol"))
/obj/machinery/sleeper/clockwork/process()
if(occupant && isliving(occupant))
var/mob/living/L = occupant
if(GLOB.clockwork_vitality) //If there's Vitality, the sleeper has passive healing
GLOB.clockwork_vitality = max(0, GLOB.clockwork_vitality - 1)
L.adjustBruteLoss(-1)
L.adjustFireLoss(-1)
L.adjustOxyLoss(-5)
/obj/machinery/sleeper/old
icon_state = "oldpod"
+5
View File
@@ -113,6 +113,11 @@ Class Procs:
var/atom/movable/occupant = null
var/speed_process = FALSE // Process as fast as possible?
var/obj/item/circuitboard/circuit // Circuit to be created and inserted when the machinery is created
// For storing and overriding ui id and dimensions
var/tgui_id // ID of TGUI interface
var/ui_style // ID of custom TGUI style (optional)
var/ui_x
var/ui_y
var/interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE
+4 -3
View File
@@ -18,9 +18,10 @@ GLOBAL_LIST_EMPTY(announcement_systems)
var/obj/item/radio/headset/radio
var/arrival = "%PERSON has signed up as %DISP_RANK (%RANK)"
var/arrivalToggle = 1
var/arrivalToggle = TRUE
var/newhead = "%PERSON, %DISP_RANK (%RANK), is the department head."
var/newheadToggle = 1
var/newheadToggle = TRUE
var/cryostorage = "%PERSON, %RANK, has been moved into cryogenic storage." // this shouldnt be changed
var/greenlight = "Light_Green"
var/pinklight = "Light_Pink"
@@ -91,7 +92,7 @@ GLOBAL_LIST_EMPTY(announcement_systems)
message = CompileText(newhead, user, rank, displayed_rank)
//CITADEL EDIT for cryopods
else if(message_type == "CRYOSTORAGE")
message = CompileText("%PERSON, %DISP_RANK (%RANK) has been moved to cryo storage.", user, rank, displayed_rank)
message = CompileText(cryostorage, user, rank, displayed_rank)
//END EDIT
else if(message_type == "ARRIVALS_BROKEN")
message = "The arrivals shuttle has been damaged. Docking for repairs..."
+2 -2
View File
@@ -132,8 +132,8 @@
..()
if(!user.canUseTopic(src))
return
else
eject_part(user)
eject_part(user)
return TRUE
/obj/machinery/aug_manipulator/power_change()
..()
+9 -3
View File
@@ -176,7 +176,7 @@
matching_designs.Cut()
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(findtext(D.name,href_list["to_search"]))
matching_designs.Add(D)
updateUsrDialog()
@@ -220,6 +220,12 @@
T -= M.rating*0.2
prod_coeff = min(1,max(0,T)) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4
/obj/machinery/autolathe/examine(mob/user)
. += ..()
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Storing up to <b>[materials.max_amount]</b> material units.<br>Material consumption at <b>[prod_coeff*100]%</b>.</span>"
/obj/machinery/autolathe/proc/main_win(mob/user)
var/dat = "<div class='statusDisplay'><h3>Autolathe Menu:</h3><br>"
dat += materials_printout()
@@ -252,7 +258,7 @@
dat += materials_printout()
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(!(selected_category in D.category))
continue
@@ -366,7 +372,7 @@
/obj/machinery/autolathe/proc/adjust_hacked(state)
hacked = state
for(var/id in SSresearch.techweb_designs)
var/datum/design/D = SSresearch.techweb_designs[id]
var/datum/design/D = SSresearch.techweb_design_by_id(id)
if((D.build_type & AUTOLATHE) && ("hacked" in D.category))
if(hacked)
stored_research.add_design(D)
+28 -25
View File
@@ -46,34 +46,37 @@
new /obj/item/stack/spacecash/c200(drop_location()) // will autostack
playsound(src.loc, 'sound/items/poster_being_created.ogg', 100, 1)
SSshuttle.points -= 200
if(next_warning < world.time && prob(15))
var/area/A = get_area(loc)
var/message = "Unauthorized credit withdrawal underway in [A.map_name]!!"
radio.talk_into(src, message, radio_channel)
next_warning = world.time + minimum_time_between_warnings
if(next_warning < world.time && prob(15))
var/area/A = get_area(loc)
var/message = "Unauthorized credit withdrawal underway in [A.map_name]!!"
radio.talk_into(src, message, radio_channel)
next_warning = world.time + minimum_time_between_warnings
/obj/machinery/computer/bank_machine/ui_interact(mob/user)
. = ..()
var/dat = "[station_name()] secure vault. Authorized personnel only.<br>"
dat += "Current Balance: [SSshuttle.points] credits.<br>"
if(!siphoning)
dat += "<A href='?src=[REF(src)];siphon=1'>Siphon Credits</A><br>"
else
dat += "<A href='?src=[REF(src)];halt=1'>Halt Credit Siphon</A><br>"
/obj/machinery/computer/bank_machine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "bank_machine", name, 320, 165, master_ui, state)
ui.open()
dat += "<a href='?src=[REF(user)];mach_close=computer'>Close</a>"
/obj/machinery/computer/bank_machine/ui_data(mob/user)
var/list/data = list()
data["current_balance"] = SSshuttle.points
data["siphoning"] = siphoning
data["station_name"] = station_name()
var/datum/browser/popup = new(user, "computer", "Bank Vault", 300, 200)
popup.set_content("<center>[dat]</center>")
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return data
/obj/machinery/computer/bank_machine/Topic(href, href_list)
/obj/machinery/computer/bank_machine/ui_act(action, params)
if(..())
return
if(href_list["siphon"])
say("Siphon of station credits has begun!")
siphoning = TRUE
if(href_list["halt"])
say("Station credit withdrawal halted.")
siphoning = FALSE
switch(action)
if("siphon")
say("Siphon of station credits has begun!")
siphoning = TRUE
. = TRUE
if("halt")
say("Station credit withdrawal halted.")
siphoning = FALSE
. = TRUE
+3 -3
View File
@@ -123,15 +123,15 @@
if(reagents.total_volume >= reagents.maximum_volume || !bag || !bag.reagents.total_volume)
beep_stop_pumping()
return
var/blood_amount = bag.reagents.get_reagent_amount("blood")
var/blood_amount = bag.reagents.get_reagent_amount(/datum/reagent/blood)
//monitor the machine and blood bag's reagents storage.
var/amount = min(blood_amount, min(transfer_amount, reagents.maximum_volume - reagents.total_volume))
if(!amount)
beep_stop_pumping()
return
var/bonus = bag.blood_type == "SY" ? 0 : 5 * efficiency //no infinite loops using synthetics.
reagents.add_reagent("syntheticblood", amount + bonus)
bag.reagents.remove_reagent("blood", amount)
reagents.add_reagent(/datum/reagent/blood/synthetics, amount + bonus)
bag.reagents.remove_reagent(/datum/reagent/blood, amount)
update_icon()
if(filling)
@@ -1,6 +1,6 @@
/obj/item/wallframe/camera
name = "camera assembly"
desc = "The basic construction for Nanotrasen-Always-Watching-You cameras."
desc = "The basic construction for Kinaris-Always-Watching-You cameras."
icon = 'icons/obj/machines/camera.dmi'
icon_state = "cameracase"
materials = list(MAT_METAL=400, MAT_GLASS=250)
@@ -9,7 +9,7 @@
/obj/structure/camera_assembly
name = "camera assembly"
desc = "The basic construction for Nanotrasen-Always-Watching-You cameras."
desc = "The basic construction for Kinaris-Always-Watching-You cameras."
icon = 'icons/obj/machines/camera.dmi'
icon_state = "camera1"
max_integrity = 150
+18 -20
View File
@@ -4,7 +4,7 @@
//Potential replacement for genetics revives or something I dunno (?)
#define CLONE_INITIAL_DAMAGE 150 //Clones in clonepods start with 150 cloneloss damage and 150 brainloss damage, thats just logical
#define MINIMUM_HEAL_LEVEL 40
#define MINIMUM_HEAL_LEVEL 20
#define SPEAK(message) radio.talk_into(src, message, radio_channel)
@@ -61,18 +61,15 @@
QDEL_LIST(unattached_flesh)
. = ..()
/obj/machinery/clonepod/RefreshParts()
/obj/machinery/clonepod/RefreshParts()
speed_coeff = 0
efficiency = 0
for(var/obj/item/stock_parts/scanning_module/S in component_parts)
efficiency += S.rating
for(var/obj/item/stock_parts/manipulator/P in component_parts)
speed_coeff += P.rating
heal_level = (efficiency * 15) + 10
if(heal_level < MINIMUM_HEAL_LEVEL)
heal_level = MINIMUM_HEAL_LEVEL
if(heal_level > 100)
heal_level = 100
speed_coeff += (P.rating / 2)
speed_coeff = max(1, speed_coeff)
heal_level = CLAMP((efficiency * 10) + 10, MINIMUM_HEAL_LEVEL, 100)
//The return of data disks?? Just for transferring between genetics machine/cloning machine.
//TO-DO: Make the genetics machine accept them.
@@ -164,8 +161,7 @@
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
H.hardset_dna(ui, mutation_index, H.real_name, null, mrace, features)
if(prob(50 - efficiency*10)) //Chance to give a bad mutation.
H.easy_randmut(NEGATIVE+MINOR_NEGATIVE) //100% bad mutation. Can be cured with mutadone.
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
@@ -176,11 +172,12 @@
//Get the clone body ready
maim_clone(H)
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")
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)
H.Unconscious(80)
clonemind.transfer_to(H)
@@ -363,11 +360,12 @@
if(!mob_occupant)
return
REMOVE_TRAIT(mob_occupant, TRAIT_STABLEHEART, "cloning")
REMOVE_TRAIT(mob_occupant, TRAIT_EMOTEMUTE, "cloning")
REMOVE_TRAIT(mob_occupant, TRAIT_MUTE, "cloning")
REMOVE_TRAIT(mob_occupant, TRAIT_NOCRITDAMAGE, "cloning")
REMOVE_TRAIT(mob_occupant, TRAIT_NOBREATH, "cloning")
REMOVE_TRAIT(mob_occupant, TRAIT_STABLEHEART, CLONING_POD_TRAIT)
REMOVE_TRAIT(mob_occupant, TRAIT_STABLELIVER, CLONING_POD_TRAIT)
REMOVE_TRAIT(mob_occupant, TRAIT_EMOTEMUTE, CLONING_POD_TRAIT)
REMOVE_TRAIT(mob_occupant, TRAIT_MUTE, CLONING_POD_TRAIT)
REMOVE_TRAIT(mob_occupant, TRAIT_NOCRITDAMAGE, CLONING_POD_TRAIT)
REMOVE_TRAIT(mob_occupant, TRAIT_NOBREATH, CLONING_POD_TRAIT)
if(grab_ghost_when == CLONER_MATURE_CLONE)
mob_occupant.grab_ghost()
+4 -9
View File
@@ -11,7 +11,6 @@
var/obj/structure/table/optable/table
var/list/advanced_surgeries = list()
var/datum/techweb/linked_techweb
var/menu = MENU_OPERATION
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/operating/Initialize()
@@ -32,7 +31,7 @@
/obj/machinery/computer/operating/proc/sync_surgeries()
for(var/i in linked_techweb.researched_designs)
var/datum/design/surgery/D = linked_techweb.researched_designs[i]
var/datum/design/surgery/D = SSresearch.techweb_design_by_id(i)
if(!istype(D))
continue
advanced_surgeries |= D.surgery
@@ -54,8 +53,6 @@
var/list/data = list()
data["table"] = table
if(table)
data["menu"] = menu
var/list/surgeries = list()
for(var/X in advanced_surgeries)
var/datum/surgery/S = X
@@ -64,9 +61,8 @@
surgery["desc"] = initial(S.desc)
surgeries += list(surgery)
data["surgeries"] = surgeries
data["patient"] = list()
if(table.check_patient())
data["patient"] = list()
patient = table.patient
switch(patient.stat)
if(CONSCIOUS)
@@ -110,15 +106,14 @@
"alternative_step" = alternative_step,
"alt_chems_needed" = alt_chems_needed
))
else
data["patient"] = null
return data
/obj/machinery/computer/operating/ui_act(action, params)
if(..())
return
switch(action)
if("change_menu")
menu = text2num(params["menu"])
. = TRUE
if("sync")
sync_surgeries()
. = TRUE
+2 -2
View File
@@ -58,11 +58,11 @@
/obj/item/stack/tile/fakepit/loaded = ARCADE_WEIGHT_TRICK,
/obj/item/restraints/handcuffs/fake = ARCADE_WEIGHT_TRICK,
/obj/item/clothing/gloves/rapid/hug = ARCADE_WEIGHT_TRICK,
/*
/obj/item/grenade/chem_grenade/glitter/pink = ARCADE_WEIGHT_TRICK,
/obj/item/grenade/chem_grenade/glitter/blue = ARCADE_WEIGHT_TRICK,
/obj/item/grenade/chem_grenade/glitter/white = ARCADE_WEIGHT_TRICK,
*/
/obj/item/extendohand/acme = ARCADE_WEIGHT_TRICK,
/obj/item/card/emagfake = ARCADE_WEIGHT_TRICK,
/obj/item/clothing/shoes/wheelys = ARCADE_WEIGHT_RARE,
+31 -12
View File
@@ -91,6 +91,8 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
icon_screen = "tank"
icon_keyboard = "atmos_key"
circuit = /obj/item/circuitboard/computer/atmos_control
ui_x = 400
ui_y = 925
var/frequency = FREQ_ATMOS_STORAGE
var/list/sensors = list(
@@ -125,7 +127,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmos_control", name, 400, 925, master_ui, state)
ui = new(user, src, ui_key, "atmos_control", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_control/ui_data(mob/user)
@@ -161,6 +163,20 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
//Incinerator sensor only
/obj/machinery/computer/atmos_control/incinerator
name = "Incinerator Air Control"
sensors = list(ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber")
ui_x = 400
ui_y = 300
//Toxins mix sensor only
/obj/machinery/computer/atmos_control/toxinsmix
name = "Toxins Mixing Air Control"
sensors = list(ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB = "Toxins Mixing Chamber")
ui_x = 400
ui_y = 300
/////////////////////////////////////////////////////////////
// LARGE TANK CONTROL
/////////////////////////////////////////////////////////////
@@ -174,6 +190,9 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
var/list/input_info
var/list/output_info
ui_x = 500
ui_y = 315
/obj/machinery/computer/atmos_control/tank/oxygen_tank
name = "Oxygen Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_O2
@@ -216,12 +235,6 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
output_tag = ATMOS_GAS_MONITOR_OUTPUT_CO2
sensors = list(ATMOS_GAS_MONITOR_SENSOR_CO2 = "Carbon Dioxide Tank")
/obj/machinery/computer/atmos_control/tank/incinerator
name = "Incinerator Air Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_INCINERATOR
output_tag = ATMOS_GAS_MONITOR_OUTPUT_INCINERATOR
sensors = list(ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber")
// This hacky madness is the evidence of the fact that a lot of machines were never meant to be constructable, im so sorry you had to see this
/obj/machinery/computer/atmos_control/tank/proc/reconnect(mob/user)
var/list/IO = list()
@@ -235,7 +248,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
IO |= text[1]
if(!IO.len)
to_chat(user, "<span class='alert'>No machinery detected.</span>")
var/S = input("Select the device set: ", "Selection", IO[1]) as anything in IO
var/S = input("Select the device set: ", "Selection", IO[1]) as anything in sortList(IO)
if(src)
src.input_tag = "[S]_in"
src.output_tag = "[S]_out"
@@ -256,7 +269,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmos_control", name, 500, 305, master_ui, state)
ui = new(user, src, ui_key, "atmos_control", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_control/tank/ui_data(mob/user)
@@ -280,13 +293,19 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
if("input")
signal.data += list("tag" = input_tag, "power_toggle" = TRUE)
. = TRUE
if("rate")
var/target = text2num(params["rate"])
if(!isnull(target))
target = CLAMP(target, 0, MAX_TRANSFER_RATE)
signal.data += list("tag" = input_tag, "set_volume_rate" = target)
. = TRUE
if("output")
signal.data += list("tag" = output_tag, "power_toggle" = TRUE)
. = TRUE
if("pressure")
var/target = input("New target pressure:", name, output_info ? output_info["internal"] : 0) as num|null
if(!isnull(target) && !..())
target = CLAMP(target, 0, 50 * ONE_ATMOSPHERE)
var/target = text2num(params["pressure"])
if(!isnull(target))
target = CLAMP(target, 0, MAX_OUTPUT_PRESSURE)
signal.data += list("tag" = output_tag, "set_internal_pressure" = target)
. = TRUE
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
+144 -143
View File
@@ -1,143 +1,144 @@
/obj/structure/frame/computer
name = "computer frame"
icon_state = "0"
state = 0
/obj/structure/frame/computer/attackby(obj/item/P, mob/user, params)
add_fingerprint(user)
switch(state)
if(0)
if(istype(P, /obj/item/wrench))
to_chat(user, "<span class='notice'>You start wrenching the frame into place...</span>")
if(P.use_tool(src, user, 20, volume=50))
to_chat(user, "<span class='notice'>You wrench the frame into place.</span>")
setAnchored(TRUE)
state = 1
return
if(istype(P, /obj/item/weldingtool))
if(!P.tool_start_check(user, amount=0))
return
to_chat(user, "<span class='notice'>You start deconstructing the frame...</span>")
if(P.use_tool(src, user, 20, volume=50))
to_chat(user, "<span class='notice'>You deconstruct the frame.</span>")
var/obj/item/stack/sheet/metal/M = new (drop_location(), 5)
M.add_fingerprint(user)
qdel(src)
return
if(1)
if(istype(P, /obj/item/wrench))
to_chat(user, "<span class='notice'>You start to unfasten the frame...</span>")
if(P.use_tool(src, user, 20, volume=50))
to_chat(user, "<span class='notice'>You unfasten the frame.</span>")
setAnchored(FALSE)
state = 0
return
if(istype(P, /obj/item/circuitboard/computer) && !circuit)
if(!user.transferItemToLoc(P, src))
return
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You place [P] inside the frame.</span>")
icon_state = "1"
circuit = P
circuit.add_fingerprint(user)
return
else if(istype(P, /obj/item/circuitboard) && !circuit)
to_chat(user, "<span class='warning'>This frame does not accept circuit boards of this type!</span>")
return
if(istype(P, /obj/item/screwdriver) && circuit)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You screw [circuit] into place.</span>")
state = 2
icon_state = "2"
return
if(istype(P, /obj/item/crowbar) && circuit)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove [circuit].</span>")
state = 1
icon_state = "0"
circuit.forceMove(drop_location())
circuit.add_fingerprint(user)
circuit = null
return
if(2)
if(istype(P, /obj/item/screwdriver) && circuit)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You unfasten the circuit board.</span>")
state = 1
icon_state = "1"
return
if(istype(P, /obj/item/stack/cable_coil))
if(!P.tool_start_check(user, amount=5))
return
to_chat(user, "<span class='notice'>You start adding cables to the frame...</span>")
if(P.use_tool(src, user, 20, volume=50, amount=5))
if(state != 2)
return
to_chat(user, "<span class='notice'>You add cables to the frame.</span>")
state = 3
icon_state = "3"
return
if(3)
if(istype(P, /obj/item/wirecutters))
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove the cables.</span>")
state = 2
icon_state = "2"
var/obj/item/stack/cable_coil/A = new (drop_location(), 5)
A.add_fingerprint(user)
return
if(istype(P, /obj/item/stack/sheet/glass))
if(!P.tool_start_check(user, amount=2))
return
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You start to put in the glass panel...</span>")
if(P.use_tool(src, user, 20, amount=2))
if(state != 3)
return
to_chat(user, "<span class='notice'>You put in the glass panel.</span>")
state = 4
src.icon_state = "4"
return
if(4)
if(istype(P, /obj/item/crowbar))
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove the glass panel.</span>")
state = 3
icon_state = "3"
var/obj/item/stack/sheet/glass/G = new(drop_location(), 2)
G.add_fingerprint(user)
return
if(istype(P, /obj/item/screwdriver))
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You connect the monitor.</span>")
var/obj/B = new circuit.build_path (loc, circuit)
B.setDir(dir)
transfer_fingerprints_to(B)
qdel(src)
return
if(user.a_intent == INTENT_HARM)
return ..()
/obj/structure/frame/computer/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(state == 4)
new /obj/item/shard(drop_location())
new /obj/item/shard(drop_location())
if(state >= 3)
new /obj/item/stack/cable_coil(drop_location(), 5)
..()
/obj/structure/frame/computer/AltClick(mob/user)
..()
if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
if(anchored)
to_chat(usr, "<span class='warning'>You must unwrench [src] before rotating it!</span>")
return
setDir(turn(dir, -90))
/obj/structure/frame/computer
name = "computer frame"
icon_state = "0"
state = 0
/obj/structure/frame/computer/attackby(obj/item/P, mob/user, params)
add_fingerprint(user)
switch(state)
if(0)
if(istype(P, /obj/item/wrench))
to_chat(user, "<span class='notice'>You start wrenching the frame into place...</span>")
if(P.use_tool(src, user, 20, volume=50))
to_chat(user, "<span class='notice'>You wrench the frame into place.</span>")
setAnchored(TRUE)
state = 1
return
if(istype(P, /obj/item/weldingtool))
if(!P.tool_start_check(user, amount=0))
return
to_chat(user, "<span class='notice'>You start deconstructing the frame...</span>")
if(P.use_tool(src, user, 20, volume=50))
to_chat(user, "<span class='notice'>You deconstruct the frame.</span>")
var/obj/item/stack/sheet/metal/M = new (drop_location(), 5)
M.add_fingerprint(user)
qdel(src)
return
if(1)
if(istype(P, /obj/item/wrench))
to_chat(user, "<span class='notice'>You start to unfasten the frame...</span>")
if(P.use_tool(src, user, 20, volume=50))
to_chat(user, "<span class='notice'>You unfasten the frame.</span>")
setAnchored(FALSE)
state = 0
return
if(istype(P, /obj/item/circuitboard/computer) && !circuit)
if(!user.transferItemToLoc(P, src))
return
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You place [P] inside the frame.</span>")
icon_state = "1"
circuit = P
circuit.add_fingerprint(user)
return
else if(istype(P, /obj/item/circuitboard) && !circuit)
to_chat(user, "<span class='warning'>This frame does not accept circuit boards of this type!</span>")
return
if(istype(P, /obj/item/screwdriver) && circuit)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You screw [circuit] into place.</span>")
state = 2
icon_state = "2"
return
if(istype(P, /obj/item/crowbar) && circuit)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove [circuit].</span>")
state = 1
icon_state = "0"
circuit.forceMove(drop_location())
circuit.add_fingerprint(user)
circuit = null
return
if(2)
if(istype(P, /obj/item/screwdriver) && circuit)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You unfasten the circuit board.</span>")
state = 1
icon_state = "1"
return
if(istype(P, /obj/item/stack/cable_coil))
if(!P.tool_start_check(user, amount=5))
return
to_chat(user, "<span class='notice'>You start adding cables to the frame...</span>")
if(P.use_tool(src, user, 20, volume=50, amount=5))
if(state != 2)
return
to_chat(user, "<span class='notice'>You add cables to the frame.</span>")
state = 3
icon_state = "3"
return
if(3)
if(istype(P, /obj/item/wirecutters))
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove the cables.</span>")
state = 2
icon_state = "2"
var/obj/item/stack/cable_coil/A = new (drop_location(), 5)
A.add_fingerprint(user)
return
if(istype(P, /obj/item/stack/sheet/glass))
if(!P.tool_start_check(user, amount=2))
return
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You start to put in the glass panel...</span>")
if(P.use_tool(src, user, 20, amount=2))
if(state != 3)
return
to_chat(user, "<span class='notice'>You put in the glass panel.</span>")
state = 4
src.icon_state = "4"
return
if(4)
if(istype(P, /obj/item/crowbar))
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove the glass panel.</span>")
state = 3
icon_state = "3"
var/obj/item/stack/sheet/glass/G = new(drop_location(), 2)
G.add_fingerprint(user)
return
if(istype(P, /obj/item/screwdriver))
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You connect the monitor.</span>")
var/obj/B = new circuit.build_path (loc, circuit)
B.setDir(dir)
transfer_fingerprints_to(B)
qdel(src)
return
if(user.a_intent == INTENT_HARM)
return ..()
/obj/structure/frame/computer/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(state == 4)
new /obj/item/shard(drop_location())
new /obj/item/shard(drop_location())
if(state >= 3)
new /obj/item/stack/cable_coil(drop_location(), 5)
..()
/obj/structure/frame/computer/AltClick(mob/user)
. = ..()
if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
if(anchored)
to_chat(usr, "<span class='warning'>You must unwrench [src] before rotating it!</span>")
return TRUE
setDir(turn(dir, -90))
return TRUE
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -487,7 +487,7 @@
R.fields["ckey"] = mob_occupant.ckey
R.fields["name"] = mob_occupant.real_name
R.fields["id"] = copytext(md5(mob_occupant.real_name), 2, 6)
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.mutation_index
@@ -449,7 +449,7 @@
var/dat = ""
if(SSshuttle.emergency.mode == SHUTTLE_CALL)
var/timeleft = SSshuttle.emergency.timeLeft()
dat += "<B>Emergency shuttle</B>\n<BR>\nETA: [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]"
dat += "<B>Emergency shuttle</B>\n<BR>\nETA: [timeleft / 60 % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]"
var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500)
+3 -3
View File
@@ -650,7 +650,7 @@
viable_occupant.radiation += (RADIATION_IRRADIATION_MULTIPLIER*radduration*radstrength)/(connected.damage_coeff ** 2) //Read comment in "transferbuffer" section above for explanation
switch(href_list["task"]) //Same thing as there but values are even lower, on best part they are about 0.0*, effectively no damage
if("pulseui")
var/len = length(viable_occupant.dna.uni_identity)
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
@@ -658,12 +658,12 @@
var/subblock = num - block*DNA_BLOCK_SIZE
last_change = "UI #[block]-[subblock]; "
var/hex = copytext(viable_occupant.dna.uni_identity, num, num+1)
var/hex = copytext_char(viable_occupant.dna.uni_identity, num, num+1)
last_change += "[hex]"
hex = scramble(hex, radstrength, radduration)
last_change += "->[hex]"
viable_occupant.dna.uni_identity = copytext(viable_occupant.dna.uni_identity, 1, num) + hex + copytext(viable_occupant.dna.uni_identity, num+1, 0)
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)
else
current_screen = "mainmenu"
+85 -112
View File
@@ -1,11 +1,13 @@
/obj/machinery/computer/launchpad
name = "\improper launchpad control console"
name = "launchpad control console"
desc = "Used to teleport objects to and from a launchpad."
icon_screen = "teleport"
icon_keyboard = "teleport_key"
circuit = /obj/item/circuitboard/computer/launchpad_console
var/sending = TRUE
var/current_pad //current pad viewed on the screen
ui_x = 475
ui_y = 260
var/selected_id
var/list/obj/machinery/launchpad/launchpads
var/maximum_pads = 4
@@ -18,7 +20,9 @@
return
/obj/machinery/computer/launchpad/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/multitool))
if(W.tool_behaviour == TOOL_MULTITOOL)
if(!multitool_check_buffer(user, W))
return
var/obj/item/multitool/M = W
if(M.buffer && istype(M.buffer, /obj/machinery/launchpad))
if(LAZYLEN(launchpads) < maximum_pads)
@@ -36,55 +40,7 @@
return FALSE
return TRUE
/obj/machinery/computer/launchpad/proc/get_pad(number)
var/obj/machinery/launchpad/pad = launchpads[number]
return pad
/obj/machinery/computer/launchpad/ui_interact(mob/user)
. = ..()
var/list/t = list()
if(!LAZYLEN(launchpads))
obj_flags &= ~IN_USE //Yeah so if you deconstruct teleporter while its in the process of shooting it wont disable the console
t += "<div class='statusDisplay'>No launchpad located.</div><BR>"
else
for(var/i in 1 to LAZYLEN(launchpads))
if(pad_exists(i))
var/obj/machinery/launchpad/pad = get_pad(i)
if(pad.stat & NOPOWER)
t+= "<span class='linkOff'>[pad.display_name]</span>"
else
t+= "<A href='?src=[REF(src)];choose_pad=1;pad=[i]'>[pad.display_name]</A>"
else
launchpads -= get_pad(i)
t += "<BR>"
if(current_pad)
var/obj/machinery/launchpad/pad = get_pad(current_pad)
t += "<div class='statusDisplay'><b>[pad.display_name]</b></div>"
t += "<A href='?src=[REF(src)];change_name=1;pad=[current_pad]'>Rename</A>"
t += "<A href='?src=[REF(src)];remove=1;pad=[current_pad]'>Remove</A><BR><BR>"
t += "<A href='?src=[REF(src)];raisey=1;lowerx=1;pad=[current_pad]'>O</A>" //up-left
t += "<A href='?src=[REF(src)];raisey=1;pad=[current_pad]'>^</A>" //up
t += "<A href='?src=[REF(src)];raisey=1;raisex=1;pad=[current_pad]'>O</A><BR>" //up-right
t += "<A href='?src=[REF(src)];lowerx=1;pad=[current_pad]'><</A>"//left
t += "<A href='?src=[REF(src)];reset=1;pad=[current_pad]'>R</A>"//reset to 0
t += "<A href='?src=[REF(src)];raisex=1;pad=[current_pad]'>></A><BR>"//right
t += "<A href='?src=[REF(src)];lowery=1;lowerx=1;pad=[current_pad]'>O</A>"//down-left
t += "<A href='?src=[REF(src)];lowery=1;pad=[current_pad]'>v</A>"//down
t += "<A href='?src=[REF(src)];lowery=1;raisex=1;pad=[current_pad]'>O</A><BR>"//down-right
t += "<BR>"
t += "<div class='statusDisplay'>Current offset:</div><BR>"
t += "<div class='statusDisplay'>[abs(pad.y_offset)] [pad.y_offset > 0 ? "N":"S"] <a href='?src=[REF(src)];sety=1;pad=[current_pad]'>\[SET\]</a></div><BR>"
t += "<div class='statusDisplay'>[abs(pad.x_offset)] [pad.x_offset > 0 ? "E":"W"] <a href='?src=[REF(src)];setx=1;pad=[current_pad]'>\[SET\]</a></div><BR>"
t += "<BR><A href='?src=[REF(src)];launch=1;pad=[current_pad]'>Launch</A>"
t += " <A href='?src=[REF(src)];pull=1;pad=[current_pad]'>Pull</A>"
var/datum/browser/popup = new(user, "launchpad", name, 300, 500)
popup.set_content(t.Join())
popup.open()
/obj/machinery/computer/launchpad/proc/teleport(mob/user, obj/machinery/launchpad/pad)
/obj/machinery/computer/launchpad/proc/teleport(mob/user, obj/machinery/launchpad/pad, sending)
if(QDELETED(pad))
to_chat(user, "<span class='warning'>ERROR: Launchpad not responding. Check launchpad integrity.</span>")
return
@@ -93,66 +49,83 @@
return
pad.doteleport(user, sending)
/obj/machinery/computer/launchpad/Topic(href, href_list)
var/obj/machinery/launchpad/pad
if(href_list["pad"])
pad = get_pad(text2num(href_list["pad"]))
/obj/machinery/computer/launchpad/proc/get_pad(number)
var/obj/machinery/launchpad/pad = launchpads[number]
return pad
/obj/machinery/computer/launchpad/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "launchpad_console", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/launchpad/ui_data(mob/user)
var/list/data = list()
var/list/pad_list = list()
for(var/i in 1 to LAZYLEN(launchpads))
if(pad_exists(i))
var/obj/machinery/launchpad/pad = get_pad(i)
var/list/this_pad = list()
this_pad["name"] = pad.display_name
this_pad["id"] = i
if(pad.stat & NOPOWER)
this_pad["inactive"] = TRUE
pad_list += list(this_pad)
else
launchpads -= get_pad(i)
data["launchpads"] = pad_list
data["selected_id"] = selected_id
if(selected_id)
var/obj/machinery/launchpad/current_pad = launchpads[selected_id]
data["x"] = current_pad.x_offset
data["y"] = current_pad.y_offset
data["pad_name"] = current_pad.display_name
data["range"] = current_pad.range
data["selected_pad"] = current_pad
if(QDELETED(current_pad) || (current_pad.stat & NOPOWER))
data["pad_active"] = FALSE
return data
data["pad_active"] = TRUE
return data
/obj/machinery/computer/launchpad/ui_act(action, params)
if(..())
return
if(!LAZYLEN(launchpads))
updateDialog()
return
var/obj/machinery/launchpad/current_pad = launchpads[selected_id]
switch(action)
if("select_pad")
selected_id = text2num(params["id"])
. = TRUE
if("set_pos")
var/new_x = text2num(params["x"])
var/new_y = text2num(params["y"])
current_pad.set_offset(new_x, new_y)
. = TRUE
if("move_pos")
var/plus_x = text2num(params["x"])
var/plus_y = text2num(params["y"])
current_pad.set_offset(
x = current_pad.x_offset + plus_x,
y = current_pad.y_offset + plus_y
)
. = TRUE
if("rename")
. = TRUE
var/new_name = params["name"]
if(!new_name)
return
current_pad.display_name = new_name
if("remove")
if(usr && alert(usr, "Are you sure?", "Unlink Launchpad", "I'm Sure", "Abort") != "Abort")
launchpads -= current_pad
selected_id = null
. = TRUE
if("launch")
teleport(usr, current_pad, TRUE)
. = TRUE
if(href_list["choose_pad"])
current_pad = text2num(href_list["pad"])
if(href_list["raisex"])
if(pad.x_offset < pad.range)
pad.x_offset++
if(href_list["lowerx"])
if(pad.x_offset > (pad.range * -1))
pad.x_offset--
if(href_list["raisey"])
if(pad.y_offset < pad.range)
pad.y_offset++
if(href_list["lowery"])
if(pad.y_offset > (pad.range * -1))
pad.y_offset--
if(href_list["reset"])
pad.y_offset = 0
pad.x_offset = 0
if(href_list["change_name"])
var/new_name = stripped_input(usr, "What do you wish to name the launchpad?", "Launchpad", pad.display_name, 15)
if(!new_name)
return
pad.display_name = new_name
if(href_list["setx"])
var/newx = input(usr, "Input new x offset", pad.display_name, pad.x_offset) as null|num
if(!isnull(newx))
pad.x_offset = CLAMP(newx, -pad.range, pad.range)
if(href_list["sety"])
var/newy = input(usr, "Input new y offset", pad.display_name, pad.y_offset) as null|num
if(!isnull(newy))
pad.y_offset = CLAMP(newy, -pad.range, pad.range)
if(href_list["remove"])
if(usr && alert(usr, "Are you sure?", "Remove Launchpad", "I'm Sure", "Abort") != "Abort")
launchpads -= pad
if(href_list["launch"])
sending = TRUE
teleport(usr, pad)
if(href_list["pull"])
sending = FALSE
teleport(usr, pad)
updateDialog()
if("pull")
teleport(usr, current_pad, FALSE)
. = TRUE
. = TRUE
+1 -1
View File
@@ -575,7 +575,7 @@
/obj/machinery/computer/med_data/laptop
name = "medical laptop"
desc = "A cheap Nanotrasen medical laptop, it functions as a medical records computer. It's bolted to the table."
desc = "A cheap Kinaris medical laptop, it functions as a medical records computer. It's bolted to the table."
icon_state = "laptop"
icon_screen = "medlaptop"
icon_keyboard = "laptop_key"
@@ -5,7 +5,7 @@
if(contained_id)
contained_id.forceMove(get_turf(src))
return ..()
/obj/machinery/computer/prisoner/examine(mob/user)
. = ..()
@@ -15,8 +15,9 @@
/obj/machinery/computer/prisoner/AltClick(mob/user)
..()
id_eject(user)
return ..()
return TRUE
/obj/machinery/computer/prisoner/proc/id_insert(mob/user, obj/item/card/id/prisoner/P)
if(istype(P))
@@ -6,6 +6,9 @@
icon_keyboard = "security_key"
req_access = list(ACCESS_ARMORY)
circuit = /obj/item/circuitboard/computer/gulag_teleporter_console
ui_x = 350
ui_y = 295
var/default_goal = 200
var/obj/machinery/gulag_teleporter/teleporter = null
var/obj/structure/gulag_beacon/beacon = null
@@ -22,7 +25,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "gulag_console", name, 455, 440, master_ui, state)
ui = new(user, src, ui_key, "gulag_console", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/prisoner/gulag_teleporter_computer/ui_data(mob/user)
@@ -50,13 +53,19 @@
data["teleporter_location"] = "([teleporter.x], [teleporter.y], [teleporter.z])"
data["teleporter_lock"] = teleporter.locked
data["teleporter_state_open"] = teleporter.state_open
else
data["teleporter"] = null
if(beacon)
data["beacon"] = beacon
data["beacon_location"] = "([beacon.x], [beacon.y], [beacon.z])"
else
data["beacon"] = null
if(contained_id)
data["id"] = contained_id
data["id_name"] = contained_id.registered_name
data["goal"] = contained_id.goal
else
data["id"] = null
data["can_teleport"] = can_teleport
return data
@@ -72,36 +81,41 @@
switch(action)
if("scan_teleporter")
teleporter = findteleporter()
return TRUE
if("scan_beacon")
beacon = findbeacon()
return TRUE
if("handle_id")
if(contained_id)
id_eject(usr)
else
id_insert(usr)
return TRUE
if("set_goal")
var/new_goal = input("Set the amount of points:", "Points", contained_id.goal) as num|null
var/new_goal = text2num(params["value"])
if(!isnum(new_goal))
return
if(!new_goal)
new_goal = default_goal
if (new_goal > 1000)
to_chat(usr, "The entered amount of points is too large. Points have instead been set to the maximum allowed amount.")
contained_id.goal = CLAMP(new_goal, 0, 1000) //maximum 1000 points
return TRUE
if("toggle_open")
if(teleporter.locked)
to_chat(usr, "The teleporter is locked")
to_chat(usr, "<span class='alert'>The teleporter must be unlocked first.</span>")
return
teleporter.toggle_open()
return TRUE
if("teleporter_lock")
if(teleporter.state_open)
to_chat(usr, "Close the teleporter before locking!")
to_chat(usr, "<span class='alert'>The teleporter must be closed first.</span>")
return
teleporter.locked = !teleporter.locked
return TRUE
if("teleport")
if(!teleporter || !beacon)
return
addtimer(CALLBACK(src, .proc/teleport, usr), 5)
return TRUE
/obj/machinery/computer/prisoner/gulag_teleporter_computer/proc/scan_machinery()
teleporter = findteleporter()
@@ -129,12 +143,12 @@
say("[contained_id]'s ID card goal defaulting to [contained_id.goal] points.")
log_game("[key_name(user)] teleported [key_name(prisoner)] to the Labor Camp [COORD(beacon)] for [id_goal_not_set ? "default goal of ":""][contained_id.goal] points.")
teleporter.handle_prisoner(contained_id, temporary_record)
playsound(src, 'sound/weapons/emitter.ogg', 50, 1)
playsound(src, 'sound/weapons/emitter.ogg', 50, TRUE)
prisoner.forceMove(get_turf(beacon))
prisoner.Stun(40) // small travel dizziness
to_chat(prisoner, "<span class='warning'>The teleportation makes you a little dizzy.</span>")
new /obj/effect/particle_effect/sparks(get_turf(prisoner))
playsound(src, "sparks", 50, 1)
playsound(src, "sparks", 50, TRUE)
if(teleporter.locked)
teleporter.locked = FALSE
teleporter.toggle_open()
@@ -125,7 +125,7 @@
to_chat(usr, "<span class='danger'>Unauthorized access.</span>")
else if(href_list["warn"])
var/warning = copytext(sanitize(input(usr,"Message:","Enter your message here!","")),1,MAX_MESSAGE_LEN)
var/warning = stripped_input(usr, "Message:", "Enter your message here!", "", MAX_MESSAGE_LEN)
if(!warning)
return
var/obj/item/implant/I = locate(href_list["warn"]) in GLOB.tracked_implants
+4 -4
View File
@@ -25,7 +25,7 @@
/obj/machinery/computer/secure_data/laptop
name = "security laptop"
desc = "A cheap Nanotrasen security laptop, it functions as a security records console. It's bolted to the table."
desc = "A cheap Kinaris security laptop, it functions as a security records console. It's bolted to the table."
icon_state = "laptop"
icon_screen = "seclaptop"
icon_keyboard = "laptop_key"
@@ -405,7 +405,7 @@ What a mess.*/
if(!( printing ))
var/wanted_name = stripped_input(usr, "Please enter an alias for the criminal:", "Print Wanted Poster", active1.fields["name"])
if(wanted_name)
var/default_description = "A poster declaring [wanted_name] to be a dangerous individual, wanted by Nanotrasen. Report any sightings to security immediately."
var/default_description = "A poster declaring [wanted_name] to be a dangerous individual, wanted by Kinaris. Report any sightings to security immediately."
var/list/major_crimes = active2.fields["ma_crim"]
var/list/minor_crimes = active2.fields["mi_crim"]
if(major_crimes.len + minor_crimes.len)
@@ -530,7 +530,7 @@ What a mess.*/
M.fields["alg_d"] = "No allergies have been detected in this patient."
M.fields["cdi"] = "None"
M.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
M.fields["notes"] = "No notes."
M.fields["notes"] = "No Notes."
GLOB.data_core.medical += M
@@ -543,7 +543,7 @@ What a mess.*/
switch(href_list["field"])
if("name")
if(istype(active1, /datum/data/record) || istype(active2, /datum/data/record))
var/t1 = copytext(sanitize(input("Please input name:", "Secure. records", active1.fields["name"], null) as text),1,MAX_MESSAGE_LEN)
var/t1 = stripped_input(usr, "Please input name:", "Secure. records", active1.fields["name"], MAX_MESSAGE_LEN)
if(!canUseSecurityRecordsConsole(usr, t1, a1))
return
if(istype(active1, /datum/data/record))
@@ -20,17 +20,18 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "station_alert", name, 300, 500, master_ui, state)
ui = new(user, src, ui_key, "station_alert", name, 325, 500, master_ui, state)
ui.open()
/obj/machinery/computer/station_alert/ui_data(mob/user)
. = list()
var/list/data = list()
.["alarms"] = list()
data["alarms"] = list()
for(var/class in alarms)
.["alarms"][class] = list()
data["alarms"][class] = list()
for(var/area in alarms[class])
.["alarms"][class] += area
data["alarms"][class] += area
return data
/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/A, O, obj/source)
if(source.z != z)
+53 -54
View File
@@ -5,6 +5,8 @@
icon_keyboard = "teleport_key"
light_color = LIGHT_COLOR_BLUE
circuit = /obj/item/circuitboard/computer/teleporter
ui_x = 475
ui_y = 130
var/regime_set = "Teleporter"
var/id
var/obj/machinery/teleport/station/power_station
@@ -32,34 +34,30 @@
break
return power_station
/obj/machinery/computer/teleporter/ui_interact(mob/user)
. = ..()
var/data = "<h3>Teleporter Status</h3>"
if(!power_station)
data += "<div class='statusDisplay'>No power station linked.</div>"
else if(!power_station.teleporter_hub)
data += "<div class='statusDisplay'>No hub linked.</div>"
obj/machinery/computer/teleporter/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "teleporter", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/teleporter/ui_data(mob/user)
var/list/data = list()
data["power_station"] = power_station ? TRUE : FALSE
data["teleporter_hub"] = power_station?.teleporter_hub ? TRUE : FALSE
data["regime_set"] = regime_set
data["target"] = !target ? "None" : "[get_area(target)] [(regime_set != "Gate") ? "" : "Teleporter"]"
data["calibrating"] = calibrating
if(power_station?.teleporter_hub?.calibrated || power_station?.teleporter_hub?.accuracy >= 3)
data["calibrated"] = TRUE
else
data += "<div class='statusDisplay'>Current regime: [regime_set]<BR>"
data += "Current target: [(!target) ? "None" : "[get_area(target)] [(regime_set != "Gate") ? "" : "Teleporter"]"]<BR>"
if(calibrating)
data += "Calibration: <font color='yellow'>In Progress</font>"
else if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accurate >= 3)
data += "Calibration: <font color='green'>Optimal</font>"
else
data += "Calibration: <font color='red'>Sub-Optimal</font>"
data += "</div><BR>"
data["calibrated"] = FALSE
data += "<A href='?src=[REF(src)];regimeset=1'>Change regime</A><BR>"
data += "<A href='?src=[REF(src)];settarget=1'>Set target</A><BR>"
return data
data += "<BR><A href='?src=[REF(src)];calibrate=1'>Calibrate Hub</A>"
var/datum/browser/popup = new(user, "teleporter", name, 400, 400)
popup.set_content(data)
popup.open()
/obj/machinery/computer/teleporter/Topic(href, href_list)
/obj/machinery/computer/teleporter/ui_act(action, params)
if(..())
return
@@ -70,38 +68,39 @@
say("Error: Calibration in progress. Stand by.")
return
if(href_list["regimeset"])
power_station.engaged = 0
power_station.teleporter_hub.update_icon()
power_station.teleporter_hub.calibrated = 0
reset_regime()
if(href_list["settarget"])
power_station.engaged = 0
power_station.teleporter_hub.update_icon()
power_station.teleporter_hub.calibrated = 0
set_target(usr)
if(href_list["calibrate"])
if(!target)
say("Error: No target set to calibrate to.")
return
if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accurate >= 3)
say("Hub is already calibrated!")
return
say("Processing hub calibration to target...")
switch(action)
if("regimeset")
power_station.engaged = FALSE
power_station.teleporter_hub.update_icon()
power_station.teleporter_hub.calibrated = FALSE
reset_regime()
. = TRUE
if("settarget")
power_station.engaged = FALSE
power_station.teleporter_hub.update_icon()
power_station.teleporter_hub.calibrated = FALSE
set_target(usr)
. = TRUE
if("calibrate")
if(!target)
say("Error: No target set to calibrate to.")
return
if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accuracy >= 3)
say("Hub is already calibrated!")
return
calibrating = 1
power_station.update_icon()
spawn(50 * (3 - power_station.teleporter_hub.accurate)) //Better parts mean faster calibration
calibrating = 0
if(check_hub_connection())
power_station.teleporter_hub.calibrated = 1
say("Calibration complete.")
else
say("Error: Unable to detect hub.")
say("Processing hub calibration to target...")
calibrating = TRUE
power_station.update_icon()
updateDialog()
updateDialog()
spawn(50 * (3 - power_station.teleporter_hub.accuracy)) //Better parts mean faster calibration
calibrating = FALSE
if(check_hub_connection())
power_station.teleporter_hub.calibrated = TRUE
say("Calibration complete.")
else
say("Error: Unable to detect hub.")
power_station.update_icon()
. = TRUE
/obj/machinery/computer/teleporter/proc/check_hub_connection()
if(!power_station)
@@ -115,8 +115,10 @@
return TRUE
/obj/machinery/defibrillator_mount/AltClick(mob/living/carbon/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE))
return
. = TRUE
if(!defib)
to_chat(user, "<span class='warning'>It'd be hard to remove a defib unit from a mount that has none.</span>")
return
+2
View File
@@ -152,9 +152,11 @@
. += "<span class='notice'>Alt-click to toggle modes.</span>"
/obj/item/grenade/barrier/AltClick(mob/living/carbon/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE))
return
toggle_mode(user)
return TRUE
/obj/item/grenade/barrier/proc/toggle_mode(mob/user)
switch(mode)
+2
View File
@@ -97,8 +97,10 @@
do_the_dishes(TRUE)
/obj/machinery/dish_drive/AltClick(mob/living/user)
. = ..()
if(user.canUseTopic(src, !issilicon(user)))
do_the_dishes(TRUE)
return TRUE
/obj/machinery/dish_drive/proc/do_the_dishes(manual)
if(!contents.len)
+7
View File
@@ -143,6 +143,13 @@
/obj/machinery/dna_scannernew/interact(mob/user)
toggle_open(user)
/obj/machinery/dna_scannernew/AltClick(mob/user)
. = ..()
if(!user.canUseTopic(src, !issilicon(user)))
return
interact(user)
return TRUE
/obj/machinery/dna_scannernew/MouseDrop_T(mob/target, mob/user)
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
return
+28 -106
View File
@@ -179,7 +179,7 @@
limit--
while(!FoundDoor && limit)
if (!FoundDoor)
log_world("### MAP WARNING, [src] at [AREACOORD(src)] failed to find a valid airlock to cyclelink with!")
log_mapping("[src] at [AREACOORD(src)] failed to find a valid airlock to cyclelink with!")
return
FoundDoor.cyclelinkedairlock = src
cyclelinkedairlock = FoundDoor
@@ -1434,7 +1434,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "ai_airlock", name, 550, 456, master_ui, state)
ui = new(user, src, ui_key, "ai_airlock", name, 500, 390, master_ui, state)
ui.open()
return TRUE
@@ -1503,83 +1503,24 @@
if("shock-perm")
shock_perm(usr)
. = TRUE
if("idscan-on")
if(wires.is_cut(WIRE_IDSCAN))
to_chat(usr, "You can't enable IdScan - The IdScan wire has been cut.")
else if(src.aiDisabledIdScanner)
aiDisabledIdScanner = FALSE
else
to_chat(usr, "The IdScan feature is not disabled.")
if("idscan-toggle")
aiDisabledIdScanner = !aiDisabledIdScanner
. = TRUE
if("idscan-off")
if(wires.is_cut(WIRE_IDSCAN))
to_chat(usr, "The IdScan wire has been cut - So, you can't disable it, but it is already disabled anyways.")
else if(aiDisabledIdScanner)
to_chat(usr, "You've already disabled the IdScan feature.")
else
aiDisabledIdScanner = TRUE
if("emergency-toggle")
toggle_emergency(usr)
. = TRUE
if("emergency-on")
emergency_on(usr)
if("bolt-toggle")
toggle_bolt(usr)
. = TRUE
if("emergency-off")
emergency_off(usr)
if("light-toggle")
lights = !lights
update_icon()
. = TRUE
if("bolt-raise")
bolt_raise(usr)
if("safe-toggle")
safe = !safe
. = TRUE
if("bolt-drop")
bolt_drop(usr)
. = TRUE
if("light-on")
if(wires.is_cut(WIRE_LIGHT))
to_chat(usr, "Control to door bolt lights has been severed.")
else if (!src.lights)
lights = TRUE
update_icon()
else
to_chat(usr, text("Door bolt lights are already enabled!"))
. = TRUE
if("light-off")
if(wires.is_cut(WIRE_LIGHT))
to_chat(usr, "Control to door bolt lights has been severed.")
else if (lights)
lights = FALSE
update_icon()
else
to_chat(usr, "Door bolt lights are already disabled!")
. = TRUE
if("safe-on")
if(wires.is_cut(WIRE_SAFETY))
to_chat(usr, "Control to door sensors is disabled.")
else if (!src.safe)
safe = TRUE
else
to_chat(usr, "Firmware reports safeties already in place.")
. = TRUE
if("safe-off")
if(wires.is_cut(WIRE_SAFETY))
to_chat(usr, "Control to door sensors is disabled.")
else if (safe)
safe = FALSE
else
to_chat(usr, "Firmware reports safeties already overridden.")
. = TRUE
if("speed-on")
if(wires.is_cut(WIRE_TIMING))
to_chat(usr, "Control to door timing circuitry has been severed.")
else if (!src.normalspeed)
normalspeed = 1
else
to_chat(usr,"Door timing circuitry currently operating normally.")
. = TRUE
if("speed-off")
if(wires.is_cut(WIRE_TIMING))
to_chat(usr, "Control to door timing circuitry has been severed.")
else if (normalspeed)
normalspeed = 0
else
to_chat(usr, "Door timing circuitry already accelerated.")
if("speed-toggle")
normalspeed = !normalspeed
. = TRUE
if("open-close")
@@ -1617,45 +1558,26 @@
log_combat(user, src, "electrified")
set_electrified(ELECTRIFIED_PERMANENT)
/obj/machinery/door/airlock/proc/emergency_on(mob/user)
if(!user_allowed(user))
return
if (!emergency)
emergency = TRUE
update_icon()
else
to_chat(user, "Emergency access is already enabled!")
/obj/machinery/door/airlock/proc/emergency_off(mob/user)
if(!user_allowed(user))
return
if (emergency)
emergency = FALSE
update_icon()
else
to_chat(user, "Emergency access is already disabled!")
/obj/machinery/door/airlock/proc/bolt_raise(mob/user)
/obj/machinery/door/airlock/proc/toggle_bolt(mob/user)
if(!user_allowed(user))
return
if(wires.is_cut(WIRE_BOLTS))
to_chat(user, "The door bolt drop wire is cut - you can't raise the door bolts")
else if(!src.locked)
to_chat(user, "The door bolts are already up")
else
if(src.hasPower())
unbolt()
to_chat(user, "<span class='warning'>The door bolt drop wire is cut - you can't toggle the door bolts.</span>")
return
if(locked)
if(!hasPower())
to_chat(user, "<span class='warning'>The door has no power - you can't raise the door bolts.</span>")
else
to_chat(user, "Cannot raise door bolts due to power failure")
/obj/machinery/door/airlock/proc/bolt_drop(mob/user)
if(!user_allowed(user))
return
if(wires.is_cut(WIRE_BOLTS))
to_chat(user, "You can't drop the door bolts - The door bolt dropping wire has been cut.")
unbolt()
else
bolt()
/obj/machinery/door/airlock/proc/toggle_emergency(mob/user)
if(!user_allowed(user))
return
emergency = !emergency
update_icon()
/obj/machinery/door/airlock/proc/user_toggle_open(mob/user)
if(!user_allowed(user))
return
@@ -14,7 +14,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "airlock_electronics", name, 975, 420, master_ui, state)
ui = new(user, src, ui_key, "airlock_electronics", name, 420, 485, master_ui, state)
ui.open()
/obj/item/electronics/airlock/ui_data()
@@ -43,13 +43,16 @@
if(..())
return
switch(action)
if("clear")
if("clear_all")
accesses = list()
one_access = 0
. = TRUE
if("one_access")
one_access = !one_access
. = TRUE
if("grant_all")
accesses = get_all_accesses()
. = TRUE
if("set")
var/access = text2num(params["access"])
if (!(access in accesses))
+2 -2
View File
@@ -149,7 +149,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "brig_timer", name, 300, 200, master_ui, state)
ui = new(user, src, ui_key, "brig_timer", name, 300, 138, master_ui, state)
ui.open()
//icon update function
@@ -168,7 +168,7 @@
if(timing)
var/disp1 = id
var/time_left = time_left(seconds = TRUE)
var/disp2 = "[add_zero(num2text((time_left / 60) % 60),2)]~[add_zero(num2text(time_left % 60), 2)]"
var/disp2 = "[add_leading(num2text((time_left / 60) % 60), 2, "0")]:[add_leading(num2text(time_left % 60), 2, "0")]"
if(length(disp2) > CHARS_PER_LINE)
disp2 = "Error"
update_display(disp1, disp2)
+1 -1
View File
@@ -22,7 +22,7 @@
if(voice_activated)
flags_1 |= HEAR_1
/obj/machinery/door/password/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
/obj/machinery/door/password/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source)
. = ..()
if(!density || !voice_activated || radio_freq)
return
+6 -5
View File
@@ -42,11 +42,12 @@
icon_state = "pod_1"
//Get the clone body ready
maim_clone(H)
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")
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)
H.Unconscious(80)
var/list/candidates = pollCandidatesForMob("Do you want to play as [clonename]'s defective clone?", null, null, null, 100, H)
+14
View File
@@ -256,6 +256,20 @@
return
return ..()
/obj/machinery/firealarm/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
if((buildstage == 0) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS))
return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 20, "cost" = 1)
return FALSE
/obj/machinery/firealarm/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode)
switch(passed_mode)
if(RCD_UPGRADE_SIMPLE_CIRCUITS)
user.visible_message("<span class='notice'>[user] fabricates a circuit and places it into [src].</span>", \
"<span class='notice'>You adapt a fire alarm circuit and slot it into the assembly.</span>")
buildstage = 1
update_icon()
return TRUE
return FALSE
/obj/machinery/firealarm/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
+1 -1
View File
@@ -29,7 +29,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "gulag_item_reclaimer", name, 455, 440, master_ui, state)
ui = new(user, src, ui_key, "gulag_item_reclaimer", name, 300, 400, master_ui, state)
ui.open()
/obj/machinery/gulag_item_reclaimer/ui_data(mob/user)
+2
View File
@@ -51,10 +51,12 @@
open_machine()
/obj/machinery/harvester/AltClick(mob/user)
. = ..()
if(harvesting || !user || !isliving(user) || state_open)
return
if(can_harvest())
start_harvest()
return TRUE
/obj/machinery/harvester/proc/can_harvest()
if(!powered(EQUIP) || state_open || !occupant || !iscarbon(occupant))
File diff suppressed because it is too large Load Diff
+54 -68
View File
@@ -16,6 +16,7 @@
var/power_efficiency = 1
var/x_offset = 0
var/y_offset = 0
var/indicator_icon = "launchpad_target"
/obj/machinery/launchpad/RefreshParts()
var/E = 0
@@ -29,17 +30,28 @@
return
if(panel_open)
if(istype(I, /obj/item/multitool))
if(I.tool_behaviour == TOOL_MULTITOOL)
if(!multitool_check_buffer(user, I))
return
var/obj/item/multitool/M = I
M.buffer = src
to_chat(user, "<span class='notice'>You save the data in the [I.name]'s buffer.</span>")
return 1
return TRUE
if(default_deconstruction_crowbar(I))
return
return ..()
/obj/machinery/launchpad/attack_ghost(mob/dead/observer/ghost)
. = ..()
if(.)
return
var/target_x = x + x_offset
var/target_y = y + y_offset
var/turf/target = locate(target_x, target_y, z)
ghost.forceMove(target)
/obj/machinery/launchpad/proc/isAvailable()
if(stat & NOPOWER)
return FALSE
@@ -47,6 +59,14 @@
return FALSE
return TRUE
/obj/machinery/launchpad/proc/set_offset(x, y)
if(teleporting)
return
if(!isnull(x))
x_offset = CLAMP(x, -range, range)
if(!isnull(y))
y_offset = CLAMP(y, -range, range)
/obj/machinery/launchpad/proc/doteleport(mob/user, sending)
if(teleporting)
to_chat(user, "<span class='warning'>ERROR: Launchpad busy.</span>")
@@ -64,12 +84,22 @@
var/area/A = get_area(target)
flick(icon_teleport, src)
playsound(get_turf(src), 'sound/weapons/flash.ogg', 25, 1)
//Change the indicator's icon to show that we're teleporting
if(sending)
indicator_icon = "launchpad_launch"
else
indicator_icon = "launchpad_pull"
playsound(get_turf(src), 'sound/weapons/flash.ogg', 25, TRUE)
teleporting = TRUE
sleep(teleport_speed)
//Set the indicator icon back to normal
indicator_icon = "launchpad_target"
if(QDELETED(src) || !isAvailable())
return
@@ -86,25 +116,25 @@
source = dest
dest = target
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, 1)
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, TRUE)
var/first = TRUE
for(var/atom/movable/ROI in source)
if(ROI == src)
continue
// if it's anchored, don't teleport
if(!istype(ROI) || isdead(ROI) || iscameramob(ROI) || istype(ROI, /obj/effect/dummy/phased_mob))
continue//don't teleport these
var/on_chair = ""
if(ROI.anchored)
if(ROI.anchored)// if it's anchored, don't teleport
if(isliving(ROI))
var/mob/living/L = ROI
if(L.buckled)
// TP people on office chairs
if(L.buckled.anchored)
continue
on_chair = " (on a chair)"
else
continue
else if(!isobserver(ROI))
else
continue
if(!first)
log_msg += ", "
@@ -250,7 +280,7 @@
/obj/item/launchpad_remote/ui_interact(mob/user, ui_key = "launchpad_remote", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "launchpad_remote", "Briefcase Launchpad Remote", 550, 400, master_ui, state) //width, height
ui = new(user, src, ui_key, "launchpad_remote", "Briefcase Launchpad Remote", 300, 240, master_ui, state) //width, height
ui.set_style("syndicate")
ui.open()
@@ -265,10 +295,9 @@
return data
data["pad_name"] = pad.display_name
data["abs_x"] = abs(pad.x_offset)
data["abs_y"] = abs(pad.y_offset)
data["north_south"] = pad.y_offset > 0 ? "N":"S"
data["east_west"] = pad.x_offset > 0 ? "E":"W"
data["range"] = pad.range
data["x"] = pad.x_offset
data["y"] = pad.y_offset
return data
/obj/item/launchpad_remote/proc/teleport(mob/user, obj/machinery/launchpad/pad)
@@ -284,76 +313,33 @@
if(..())
return
switch(action)
if("right")
if(pad.x_offset < pad.range)
pad.x_offset++
if("set_pos")
var/new_x = text2num(params["x"])
var/new_y = text2num(params["y"])
pad.set_offset(new_x, new_y)
. = TRUE
if("left")
if(pad.x_offset > (pad.range * -1))
pad.x_offset--
if("move_pos")
var/plus_x = text2num(params["x"])
var/plus_y = text2num(params["y"])
pad.set_offset(
x = pad.x_offset + plus_x,
y = pad.y_offset + plus_y
)
. = TRUE
if("up")
if(pad.y_offset < pad.range)
pad.y_offset++
. = TRUE
if("down")
if(pad.y_offset > (pad.range * -1))
pad.y_offset--
. = TRUE
if("up-right")
if(pad.y_offset < pad.range)
pad.y_offset++
if(pad.x_offset < pad.range)
pad.x_offset++
. = TRUE
if("up-left")
if(pad.y_offset < pad.range)
pad.y_offset++
if(pad.x_offset > (pad.range * -1))
pad.x_offset--
. = TRUE
if("down-right")
if(pad.y_offset > (pad.range * -1))
pad.y_offset--
if(pad.x_offset < pad.range)
pad.x_offset++
. = TRUE
if("down-left")
if(pad.y_offset > (pad.range * -1))
pad.y_offset--
if(pad.x_offset > (pad.range * -1))
pad.x_offset--
. = TRUE
if("reset")
pad.y_offset = 0
pad.x_offset = 0
. = TRUE
if("rename")
. = TRUE
var/new_name = stripped_input(usr, "How do you want to rename the launchpad?", "Launchpad", pad.display_name, 15)
var/new_name = params["name"]
if(!new_name)
return
pad.display_name = new_name
if("remove")
. = TRUE
if(usr && alert(usr, "Are you sure?", "Unlink Launchpad", "I'm Sure", "Abort") != "Abort")
pad = null
if("launch")
sending = TRUE
teleport(usr, pad)
. = TRUE
if("pull")
sending = FALSE
teleport(usr, pad)
+10 -10
View File
@@ -87,7 +87,7 @@
selected_category = href_list["category"]
if(href_list["disposeI"]) //Get rid of a reagent incase you add the wrong one by mistake
reagents.del_reagent(href_list["disposeI"])
reagents.del_reagent(text2path(href_list["disposeI"]))
if(href_list["make"])
@@ -98,10 +98,10 @@
return
var/synth_cost = being_built.reagents_list["synthflesh"]*prod_coeff
var/synth_cost = being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff
var/power = max(2000, synth_cost/5)
if(reagents.has_reagent("synthflesh", being_built.reagents_list["synthflesh"]*prod_coeff))
if(reagents.has_reagent(/datum/reagent/medicine/synthflesh, being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff))
busy = TRUE
use_power(power)
flick("limbgrower_fill",src)
@@ -115,8 +115,8 @@
return
/obj/machinery/limbgrower/proc/build_item()
if(reagents.has_reagent("synthflesh", being_built.reagents_list["synthflesh"]*prod_coeff)) //sanity check, if this happens we are in big trouble
reagents.remove_reagent("synthflesh",being_built.reagents_list["synthflesh"]*prod_coeff)
if(reagents.has_reagent(/datum/reagent/medicine/synthflesh, being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff)) //sanity check, if this happens we are in big trouble
reagents.remove_reagent(/datum/reagent/medicine/synthflesh, being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff)
var/buildpath = being_built.build_path
if(ispath(buildpath, /obj/item/bodypart)) //This feels like spatgheti code, but i need to initilise a limb somehow
build_limb(buildpath)
@@ -177,7 +177,7 @@
dat += materials_printout()
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(!(selected_category in D.category))
continue
if(disabled || !can_build(D))
@@ -197,7 +197,7 @@
for(var/datum/reagent/R in reagents.reagent_list)
dat += "[R.name]: [R.volume]"
dat += "<A href='?src=[REF(src)];disposeI=[R.id]'>Purge</A><BR>"
dat += "<A href='?src=[REF(src)];disposeI=[R]'>Purge</A><BR>"
dat += "</div>"
return dat
@@ -207,19 +207,19 @@
return dat
/obj/machinery/limbgrower/proc/can_build(datum/design/D)
return (reagents.has_reagent("synthflesh", D.reagents_list["synthflesh"]*prod_coeff)) //Return whether the machine has enough synthflesh to produce the design
return (reagents.has_reagent(/datum/reagent/medicine/synthflesh, D.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff)) //Return whether the machine has enough synthflesh to produce the design
/obj/machinery/limbgrower/proc/get_design_cost(datum/design/D)
var/dat
if(D.reagents_list["synthflesh"])
dat += "[D.reagents_list["synthflesh"] * prod_coeff] Synthetic flesh "
dat += "[D.reagents_list[/datum/reagent/medicine/synthflesh] * prod_coeff] Synthetic flesh "
return dat
/obj/machinery/limbgrower/emag_act(mob/user)
if(obj_flags & EMAGGED)
return
for(var/id in SSresearch.techweb_designs)
var/datum/design/D = SSresearch.techweb_designs[id]
var/datum/design/D = SSresearch.techweb_design_by_id(id)
if((D.build_type & LIMBGROWER) && ("emagged" in D.category))
stored_research.add_design(D)
to_chat(user, "<span class='warning'>A warning flashes onto the screen, stating that safety overrides have been deactivated!</span>")
+13 -7
View File
@@ -306,7 +306,7 @@
if(speed <= 0)
speed = 1
if("setpath")
var/newpath = copytext(sanitize(input(usr, "Please define a new path!",,path) as text|null),1,MAX_MESSAGE_LEN)
var/newpath = stripped_input(usr, "Please define a new path!", "New Path", path, MAX_MESSAGE_LEN)
if(newpath && newpath != "")
moving = 0 // stop moving
path = newpath
@@ -368,13 +368,19 @@
// Generates the rpath variable using the path string, think of this as "string2list"
// Doesn't use params2list() because of the akward way it stacks entities
rpath = list() // clear rpath
var/maximum_character = min( 50, length(path) ) // chooses the maximum length of the iterator. 50 max length
var/maximum_characters = 50
for(var/i=1, i<=maximum_character, i++) // iterates through all characters in path
var/lentext = length(path)
var/nextchar = ""
var/charcount = 0
var/nextchar = copytext(path, i, i+1) // find next character
if(!(nextchar in list(";", "&", "*", " "))) // if char is a separator, ignore
rpath += copytext(path, i, i+1) // else, add to list
for(var/i = 1, i <= lentext, i += length(nextchar)) // iterates through all characters in path
nextchar = path[i] // find next character
if(nextchar in list(";", "&", "*", " ")) // if char is a separator, ignore
continue
rpath += nextchar // else, add to list
// there doesn't HAVE to be separators but it makes paths syntatically visible
charcount++
if(charcount >= maximum_characters)
break
+2 -2
View File
@@ -62,7 +62,7 @@
var/index = findtext(e, "=") // format is "key=value"
if(index)
var/key = copytext(e, 1, index)
var/val = copytext(e, index+1)
var/val = copytext(e, index + length(e[index]))
codes[key] = val
else
codes[e] = "1"
@@ -167,7 +167,7 @@ Transponder Codes:<UL>"}
usr.set_machine(src)
if(href_list["locedit"])
var/newloc = copytext(sanitize(input("Enter New Location", "Navigation Beacon", location) as text|null),1,MAX_MESSAGE_LEN)
var/newloc = stripped_input(usr, "Enter New Location", "Navigation Beacon", location, MAX_MESSAGE_LEN)
if(newloc)
location = newloc
updateDialog()
+8 -10
View File
@@ -162,7 +162,7 @@ GLOBAL_LIST_EMPTY(allCasters)
NEWSCASTER.update_icon()
/datum/newscaster/feed_network/proc/save_photo(icon/photo)
var/photo_file = copytext(md5("\icon[photo]"), 1, 6)
var/photo_file = copytext_char(md5("\icon[photo]"), 1, 6)
if(!fexists("[GLOB.log_directory]/photos/[photo_file].png"))
//Clean up repeated frames
var/icon/clean = new /icon()
@@ -287,7 +287,7 @@ GLOBAL_LIST_EMPTY(allCasters)
dat+="<HR><B>Feed Security functions:</B><BR>"
dat+="<BR><A href='?src=[REF(src)];menu_wanted=1'>[(wanted_already) ? ("Manage") : ("Publish")] \"Wanted\" Issue</A>"
dat+="<BR><A href='?src=[REF(src)];menu_censor_story=1'>Censor Feed Stories</A>"
dat+="<BR><A href='?src=[REF(src)];menu_censor_channel=1'>Mark Feed Channel with Nanotrasen D-Notice</A>"
dat+="<BR><A href='?src=[REF(src)];menu_censor_channel=1'>Mark Feed Channel with Kinaris D-Notice</A>"
dat+="<BR><HR>The newscaster recognises you as: <FONT COLOR='green'>[scanned_user]</FONT>"
if(1)
dat+= "Station Feed Channels<HR>"
@@ -368,7 +368,7 @@ GLOBAL_LIST_EMPTY(allCasters)
if(9)
dat+="<B>[viewing_channel.channel_name]: </B><FONT SIZE=1>\[created by: <FONT COLOR='maroon'>[viewing_channel.returnAuthor(-1)]</FONT>\]</FONT><HR>"
if(viewing_channel.censored)
dat+="<FONT COLOR='red'><B>ATTENTION: </B></FONT>This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.<BR>"
dat+="<FONT COLOR='red'><B>ATTENTION: </B></FONT>This channel has been deemed as threatening to the welfare of the station, and marked with a Kinaris D-Notice.<BR>"
dat+="No further feed story additions are allowed while the D-Notice is in effect.</FONT><BR><BR>"
else
if( isemptylist(viewing_channel.messages) )
@@ -395,7 +395,7 @@ GLOBAL_LIST_EMPTY(allCasters)
dat+="<BR><HR><A href='?src=[REF(src)];refresh=1'>Refresh</A>"
dat+="<BR><A href='?src=[REF(src)];setScreen=[1]'>Back</A>"
if(10)
dat+="<B>Nanotrasen Feed Censorship Tool</B><BR>"
dat+="<B>Kinaris Feed Censorship Tool</B><BR>"
dat+="<FONT SIZE=1>NOTE: Due to the nature of news Feeds, total deletion of a Feed Story is not possible.<BR>"
dat+="Keep in mind that users attempting to view a censored feed will instead see the \[REDACTED\] tag above it.</FONT>"
dat+="<HR>Select Feed channel to get Stories from:<BR>"
@@ -406,7 +406,7 @@ GLOBAL_LIST_EMPTY(allCasters)
dat+="<A href='?src=[REF(src)];pick_censor_channel=[REF(CHANNEL)]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ""]<BR>"
dat+="<BR><A href='?src=[REF(src)];setScreen=[0]'>Cancel</A>"
if(11)
dat+="<B>Nanotrasen D-Notice Handler</B><HR>"
dat+="<B>Kinaris D-Notice Handler</B><HR>"
dat+="<FONT SIZE=1>A D-Notice is to be bestowed upon the channel if the handling Authority deems it as harmful for the station's"
dat+="morale, integrity or disciplinary behaviour. A D-Notice will render a channel unable to be updated by anyone, without deleting any feed"
dat+="stories it might contain at the time. You can lift a D-Notice if you have the required access at any time.</FONT><HR>"
@@ -433,7 +433,7 @@ GLOBAL_LIST_EMPTY(allCasters)
dat+="<B>[viewing_channel.channel_name]: </B><FONT SIZE=1>\[ created by: <FONT COLOR='maroon'>[viewing_channel.returnAuthor(-1)]</FONT> \]</FONT><BR>"
dat+="Channel messages listed below. If you deem them dangerous to the station, you can <A href='?src=[REF(src)];toggle_d_notice=[REF(viewing_channel)]'>Bestow a D-Notice upon the channel</A>.<HR>"
if(viewing_channel.censored)
dat+="<FONT COLOR='red'><B>ATTENTION: </B></FONT>This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.<BR>"
dat+="<FONT COLOR='red'><B>ATTENTION: </B></FONT>This channel has been deemed as threatening to the welfare of the station, and marked with a Kinaris D-Notice.<BR>"
dat+="No further feed story additions are allowed while the D-Notice is in effect.</FONT><BR><BR>"
else
if(isemptylist(viewing_channel.messages))
@@ -514,8 +514,6 @@ GLOBAL_LIST_EMPTY(allCasters)
scan_user(usr)
if(href_list["set_channel_name"])
channel_name = stripped_input(usr, "Provide a Feed Channel Name", "Network Channel Handler", "", MAX_NAME_LEN)
while (findtext(channel_name," ") == 1)
channel_name = copytext(channel_name,2,length(channel_name)+1)
updateUsrDialog()
else if(href_list["set_channel_lock"])
c_locked = !c_locked
@@ -690,7 +688,7 @@ GLOBAL_LIST_EMPTY(allCasters)
updateUsrDialog()
else if(href_list["new_comment"])
var/datum/newscaster/feed_message/FM = locate(href_list["new_comment"])
var/cominput = copytext(stripped_input(usr, "Write your message:", "New comment", null),1,141)
var/cominput = copytext_char(stripped_input(usr, "Write your message:", "New comment", null), 140)
if(cominput)
scan_user(usr)
var/datum/newscaster/feed_comment/FC = new/datum/newscaster/feed_comment
@@ -902,7 +900,7 @@ GLOBAL_LIST_EMPTY(allCasters)
switch(screen)
if(0) //Cover
dat+="<DIV ALIGN='center'><B><FONT SIZE=6>The Griffon</FONT></B></div>"
dat+="<DIV ALIGN='center'><FONT SIZE=2>Nanotrasen-standard newspaper, for use on Nanotrasen? Space Facilities</FONT></div><HR>"
dat+="<DIV ALIGN='center'><FONT SIZE=2>Kinaris-standard newspaper, for use on Kinaris? Space Facilities</FONT></div><HR>"
if(isemptylist(news_content))
if(wantedAuthor)
dat+="Contents:<BR><ul><B><FONT COLOR='red'>**</FONT>Important Security Announcement<FONT COLOR='red'>**</FONT></B> <FONT SIZE=2>\[page [pages+2]\]</FONT><BR></ul>"
File diff suppressed because it is too large Load Diff
+6 -8
View File
@@ -263,10 +263,9 @@ GLOBAL_LIST_EMPTY(allConsoles)
usr.set_machine(src)
add_fingerprint(usr)
if(reject_bad_text(href_list["write"]))
dpt = ckey(href_list["write"]) //write contains the string of the receiving department's name
var/new_message = copytext(reject_bad_text(input(usr, "Write your message:", "Awaiting Input", "")),1,MAX_MESSAGE_LEN)
if(href_list["write"])
dpt = ckey(reject_bad_text(href_list["write"])) //write contains the string of the receiving department's name
var/new_message = stripped_input(usr, "Write your message:", "Awaiting Input", "", MAX_MESSAGE_LEN)
if(new_message)
message = new_message
screen = 9
@@ -282,7 +281,7 @@ GLOBAL_LIST_EMPTY(allConsoles)
priority = -1
if(href_list["writeAnnouncement"])
var/new_message = copytext(reject_bad_text(input(usr, "Write your message:", "Awaiting Input", "")),1,MAX_MESSAGE_LEN)
var/new_message = reject_bad_text(stripped_input(usr, "Write your message:", "Awaiting Input", "", MAX_MESSAGE_LEN))
if(new_message)
message = new_message
if (text2num(href_list["priority"]) < 2)
@@ -438,9 +437,8 @@ GLOBAL_LIST_EMPTY(allConsoles)
return
/obj/machinery/requests_console/say_mod(input, message_mode)
var/ending = copytext(input, length(input) - 2)
if (ending == "!!!")
. = "blares"
if(spantext_char(input, "!", -3))
return "blares"
else
. = ..()
+11 -11
View File
@@ -55,14 +55,14 @@
/// Call with no arguments to disable.
/obj/machinery/status_display/proc/set_message(m1, m2)
if(m1)
index1 = (length(m1) > CHARS_PER_LINE)
index1 = (length_char(m1) > CHARS_PER_LINE)
message1 = m1
else
message1 = ""
index1 = 0
if(m2)
index2 = (length(m2) > CHARS_PER_LINE)
index2 = (length_char(m2) > CHARS_PER_LINE)
message2 = m2
else
message2 = ""
@@ -77,19 +77,19 @@
var/line1 = message1
if(index1)
line1 = copytext("[message1]|[message1]", index1, index1+CHARS_PER_LINE)
var/message1_len = length(message1)
line1 = copytext_char("[message1]|[message1]", index1, index1+CHARS_PER_LINE)
var/message1_len = length_char(message1)
index1 += SCROLL_SPEED
if(index1 > message1_len)
index1 -= message1_len
if(index1 > message1_len + 1)
index1 -= (message1_len + 1)
var/line2 = message2
if(index2)
line2 = copytext("[message2]|[message2]", index2, index2+CHARS_PER_LINE)
line2 = copytext_char("[message2]|[message2]", index2, index2+CHARS_PER_LINE)
var/message2_len = length(message2)
index2 += SCROLL_SPEED
if(index2 > message2_len)
index2 -= message2_len
if(index2 > message2_len + 1)
index2 -= (message2_len + 1)
update_display(line1, line2)
if (!index1 && !index2)
@@ -130,7 +130,7 @@
var/line1 = "-[shuttle.getModeStr()]-"
var/line2 = shuttle.getTimerStr()
if(length(line2) > CHARS_PER_LINE)
if(length_char(line2) > CHARS_PER_LINE)
line2 = "error"
update_display(line1, line2)
else
@@ -242,7 +242,7 @@
else
line1 = "CARGO"
line2 = SSshuttle.supply.getTimerStr()
if(length(line2) > CHARS_PER_LINE)
if(length_char(line2) > CHARS_PER_LINE)
line2 = "Error"
update_display(line1, line2)
+11 -1
View File
@@ -388,14 +388,24 @@
data["uv_super"] = uv_super
if(helmet)
data["helmet"] = helmet.name
else
data["helmet"] = null
if(suit)
data["suit"] = suit.name
else
data["suit"] = null
if(mask)
data["mask"] = mask.name
else
data["mask"] = null
if(storage)
data["storage"] = storage.name
else
data["storage"] = null
if(occupant)
data["occupied"] = 1
data["occupied"] = TRUE
else
data["occupied"] = FALSE
return data
/obj/machinery/suit_storage_unit/ui_act(action, params)
+1 -1
View File
@@ -295,7 +295,7 @@
/obj/item/bombcore/training
name = "dummy payload"
desc = "A Nanotrasen replica of a syndicate payload. Its not intended to explode but to announce that it WOULD have exploded, then rewire itself to allow for more training."
desc = "A Kinaris replica of a syndicate payload. Its not intended to explode but to announce that it WOULD have exploded, then rewire itself to allow for more training."
var/defusals = 0
var/attempts = 0
@@ -132,7 +132,7 @@
set waitfor = FALSE
// Perform final composition steps on the message.
var/message = copytext(data["message"], 1, MAX_BROADCAST_LEN)
var/message = copytext_char(data["message"], 1, MAX_BROADCAST_LEN)
if(!message)
return
var/compression = data["compression"]
@@ -179,7 +179,7 @@
if("id")
var/newid = copytext(reject_bad_text(input(usr, "Specify the new ID for this machine", src, id) as null|text),1,MAX_MESSAGE_LEN)
var/newid = reject_bad_text(stripped_input(usr, "Specify the new ID for this machine", src, id, MAX_MESSAGE_LEN))
if(newid && canAccess(usr))
id = newid
temp = "<font color = #666633>-% New ID assigned: \"[id]\" %-</font color>"
+19 -5
View File
@@ -11,7 +11,7 @@
idle_power_usage = 10
active_power_usage = 2000
circuit = /obj/item/circuitboard/machine/teleporter_hub
var/accurate = FALSE
var/accuracy = 0
var/obj/machinery/teleport/station/power_station
var/calibrated //Calibration prevents mutation
@@ -29,7 +29,12 @@
var/A = 0
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
A += M.rating
accurate = A
accuracy = A
/obj/machinery/teleport/hub/examine(mob/user)
..()
if(in_range(user, src) || isobserver(user))
to_chat(user, "<span class='notice'>The status display reads: Probability of malfunction decreased by <b>[(accuracy*25)-25]%</b>.<span>")
/obj/machinery/teleport/hub/proc/link_power_station()
if(power_station)
@@ -69,13 +74,13 @@
if(do_teleport(M, com.target, channel = TELEPORT_CHANNEL_BLUESPACE))
use_power(5000)
if(!calibrated && iscarbon(M) && prob(30 - ((accurate) * 10))) //oh dear a problem
if(!calibrated && iscarbon(M) && prob(30 - ((accuracy) * 10))) //oh dear a problem
var/mob/living/carbon/C = M
if(C.dna?.species && C.dna.species.id != "fly" && !HAS_TRAIT(C, TRAIT_RADIMMUNE))
to_chat(C, "<span class='italics'>You hear a buzzing in your ears.</span>")
C.set_species(/datum/species/fly)
log_game("[C] ([key_name(C)]) was turned into a fly person")
C.apply_effect((rand(120 - accurate * 40, 180 - accurate * 60)), EFFECT_IRRADIATE, 0)
C.apply_effect((rand(120 - accuracy * 40, 180 - accuracy * 60)), EFFECT_IRRADIATE, 0)
calibrated = FALSE
return
@@ -102,7 +107,7 @@
/obj/machinery/teleport/station
name = "station"
name = "teleporter station"
desc = "The power control station for a bluespace teleporter. Used for toggling power, and can activate a test-fire to prevent malfunctions."
icon_state = "controller"
use_power = IDLE_POWER_USE
@@ -125,6 +130,15 @@
E += C.rating
efficiency = E - 1
/obj/machinery/teleport/station/examine(mob/user)
. = ..()
if(!panel_open)
to_chat(user, "<span class='notice'>The panel is <i>screwed</i> in, obstructing the linking device and wiring panel.</span>")
else
to_chat(user, "<span class='notice'>The <i>linking</i> device is now able to be <i>scanned</i> with a multitool.<br>The <i>wiring</i> can be <i>connected<i> to a nearby console and hub with a pair of wirecutters.</span>")
if(in_range(user, src) || isobserver(user))
to_chat(user, "<span class='notice'>The status display reads: This station can be linked to <b>[efficiency]</b> other station(s).<span>")
/obj/machinery/teleport/station/proc/link_console_and_hub()
for(var/direction in GLOB.cardinals)
teleporter_hub = locate(/obj/machinery/teleport/hub, get_step(src, direction))
+284 -282
View File
@@ -1,282 +1,284 @@
/obj/machinery/washing_machine
name = "washing machine"
desc = "Gets rid of those pesky bloodstains, or your money back!"
icon = 'icons/obj/machines/washing_machine.dmi'
icon_state = "wm_1_0"
density = TRUE
state_open = TRUE
var/busy = FALSE
var/bloody_mess = 0
var/has_corgi = 0
var/obj/item/color_source
var/max_wash_capacity = 5
/obj/machinery/washing_machine/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click it to start a wash cycle.</span>"
/obj/machinery/washing_machine/AltClick(mob/user)
if(!user.canUseTopic(src))
return
if(busy)
return
if(state_open)
to_chat(user, "<span class='notice'>Close the door first</span>")
return
if(bloody_mess)
to_chat(user, "<span class='warning'>[src] must be cleaned up first.</span>")
return
if(has_corgi)
bloody_mess = 1
busy = TRUE
update_icon()
addtimer(CALLBACK(src, .proc/wash_cycle), 200)
START_PROCESSING(SSfastprocess, src)
/obj/machinery/washing_machine/process()
if (!busy)
animate(src, transform=matrix(), time=2)
return PROCESS_KILL
if (anchored)
if (prob(5))
var/matrix/M = new
M.Translate(rand(-1, 1), rand(0, 1))
animate(src, transform=M, time=1)
animate(transform=matrix(), time=1)
else
if (prob(1))
step(src, pick(GLOB.cardinals))
var/matrix/M = new
M.Translate(rand(-3, 3), rand(-1, 3))
animate(src, transform=M, time=2)
/obj/machinery/washing_machine/clean_blood()
..()
if(!busy)
bloody_mess = FALSE
update_icon()
/obj/machinery/washing_machine/proc/wash_cycle()
for(var/X in contents)
var/atom/movable/AM = X
SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
AM.clean_blood()
AM.machine_wash(src)
busy = FALSE
if(color_source)
qdel(color_source)
color_source = null
update_icon()
//what happens to this object when washed inside a washing machine
/atom/movable/proc/machine_wash(obj/machinery/washing_machine/WM)
return
/obj/item/stack/sheet/hairlesshide/machine_wash(obj/machinery/washing_machine/WM)
new /obj/item/stack/sheet/wetleather(drop_location(), amount)
qdel(src)
/obj/item/clothing/suit/hooded/ian_costume/machine_wash(obj/machinery/washing_machine/WM)
new /obj/item/reagent_containers/food/snacks/meat/slab/corgi(loc)
qdel(src)
/obj/item/paper/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
if(istype(WM.color_source, /obj/item/toy/crayon))
var/obj/item/toy/crayon/CR = WM.color_source
add_atom_colour(CR.paint_color, WASHABLE_COLOUR_PRIORITY)
/obj/item/reagents_containers/rag/towel/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
if(istype(WM.color_source, /obj/item/toy/crayon))
var/obj/item/toy/crayon/CR = WM.color_source
add_atom_colour(CR.paint_color, WASHABLE_COLOUR_PRIORITY)
/mob/living/simple_animal/pet/dog/corgi/machine_wash(obj/machinery/washing_machine/WM)
gib()
/obj/item/clothing/under/color/machine_wash(obj/machinery/washing_machine/WM)
jumpsuit_wash(WM)
/obj/item/clothing/under/rank/machine_wash(obj/machinery/washing_machine/WM)
jumpsuit_wash(WM)
/obj/item/clothing/under/proc/jumpsuit_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
var/obj/item/clothing/under/U
for(var/T in typesof(/obj/item/clothing/under/color))
var/obj/item/clothing/under/color/J = T
if(wash_color == initial(J.item_color))
U = J
break
if(!U)
for(var/T in typesof(/obj/item/clothing/under/rank))
var/obj/item/clothing/under/rank/R = T
if(wash_color == initial(R.item_color))
U = R
break
if(U)
item_state = initial(U.item_state)
icon_state = initial(U.icon_state)
item_color = wash_color
name = initial(U.name)
desc = "The colors are a bit dodgy."
can_adjust = initial(U.can_adjust)
if(!can_adjust && adjusted) //we deadjust the uniform if it's now unadjustable
toggle_jumpsuit_adjust()
/obj/item/clothing/gloves/color/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
for(var/T in typesof(/obj/item/clothing/gloves/color))
var/obj/item/clothing/gloves/color/G = T
if(wash_color == initial(G.item_color))
item_state = initial(G.item_state)
icon_state = initial(G.icon_state)
item_color = wash_color
name = initial(G.name)
desc = "The colors are a bit dodgy."
break
/obj/item/clothing/shoes/sneakers/machine_wash(obj/machinery/washing_machine/WM)
if(chained)
chained = 0
slowdown = SHOES_SLOWDOWN
new /obj/item/restraints/handcuffs(loc)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
for(var/T in typesof(/obj/item/clothing/shoes/sneakers))
var/obj/item/clothing/shoes/sneakers/S = T
if(wash_color == initial(S.item_color))
icon_state = initial(S.icon_state)
item_color = wash_color
name = initial(S.name)
desc = "The colors are a bit dodgy."
break
/obj/item/bedsheet/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
for(var/T in typesof(/obj/item/bedsheet))
var/obj/item/bedsheet/B = T
if(wash_color == initial(B.item_color))
icon_state = initial(B.icon_state)
item_color = wash_color
name = initial(B.name)
desc = "The colors are a bit dodgy."
break
/obj/item/clothing/head/soft/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
for(var/T in typesof(/obj/item/clothing/head/soft))
var/obj/item/clothing/head/soft/H = T
if(wash_color == initial(H.item_color))
icon_state = initial(H.icon_state)
item_color = wash_color
name = initial(H.name)
desc = "The colors are a bit dodgy."
break
/obj/machinery/washing_machine/relaymove(mob/user)
container_resist(user)
/obj/machinery/washing_machine/container_resist(mob/living/user)
if(!busy)
add_fingerprint(user)
open_machine()
/obj/machinery/washing_machine/update_icon()
cut_overlays()
if(busy)
icon_state = "wm_running_[bloody_mess]"
else if(bloody_mess)
icon_state = "wm_[state_open]_blood"
else
var/full = contents.len ? 1 : 0
icon_state = "wm_[state_open]_[full]"
if(panel_open)
add_overlay("wm_panel")
/obj/machinery/washing_machine/attackby(obj/item/W, mob/user, params)
if(panel_open && !busy && default_unfasten_wrench(user, W))
return
if(default_deconstruction_screwdriver(user, null, null, W))
update_icon()
return
if(istype(W, /obj/item/clothing/head/mob_holder))
to_chat(user, "<span class='warning'>It's too unweildy to put in this way.</span>")
return 1
else if(user.a_intent != INTENT_HARM)
if (!state_open)
to_chat(user, "<span class='warning'>Open the door first!</span>")
return 1
if(bloody_mess)
to_chat(user, "<span class='warning'>[src] must be cleaned up first.</span>")
return 1
if(contents.len >= max_wash_capacity)
to_chat(user, "<span class='warning'>The washing machine is full!</span>")
return 1
if(!user.transferItemToLoc(W, src))
to_chat(user, "<span class='warning'>\The [W] is stuck to your hand, you cannot put it in the washing machine!</span>")
return 1
if(istype(W, /obj/item/toy/crayon) || istype(W, /obj/item/stamp))
color_source = W
update_icon()
else
return ..()
/obj/machinery/washing_machine/attack_hand(mob/user)
. = ..()
if(.)
return
if(busy)
to_chat(user, "<span class='warning'>[src] is busy.</span>")
return
if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling))
var/mob/living/L = user.pulling
if(L.buckled || L.has_buckled_mobs())
return
if(state_open)
if(iscorgi(L))
has_corgi = 1
L.forceMove(src)
update_icon()
return
if(!state_open)
open_machine()
else
state_open = FALSE //close the door
update_icon()
/obj/machinery/washing_machine/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/metal (loc, 2)
qdel(src)
/obj/machinery/washing_machine/open_machine(drop = 1)
..()
density = TRUE //because machinery/open_machine() sets it to 0
color_source = null
has_corgi = 0
/obj/machinery/washing_machine
name = "washing machine"
desc = "Gets rid of those pesky bloodstains, or your money back!"
icon = 'icons/obj/machines/washing_machine.dmi'
icon_state = "wm_1_0"
density = TRUE
state_open = TRUE
var/busy = FALSE
var/bloody_mess = 0
var/has_corgi = 0
var/obj/item/color_source
var/max_wash_capacity = 5
/obj/machinery/washing_machine/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click it to start a wash cycle.</span>"
/obj/machinery/washing_machine/AltClick(mob/user)
. = ..()
if(!user.canUseTopic(src))
return
if(busy)
return
if(state_open)
to_chat(user, "<span class='notice'>Close the door first</span>")
return TRUE
if(bloody_mess)
to_chat(user, "<span class='warning'>[src] must be cleaned up first.</span>")
return TRUE
if(has_corgi)
bloody_mess = 1
busy = TRUE
update_icon()
addtimer(CALLBACK(src, .proc/wash_cycle), 200)
START_PROCESSING(SSfastprocess, src)
return TRUE
/obj/machinery/washing_machine/process()
if (!busy)
animate(src, transform=matrix(), time=2)
return PROCESS_KILL
if (anchored)
if (prob(5))
var/matrix/M = new
M.Translate(rand(-1, 1), rand(0, 1))
animate(src, transform=M, time=1)
animate(transform=matrix(), time=1)
else
if (prob(1))
step(src, pick(GLOB.cardinals))
var/matrix/M = new
M.Translate(rand(-3, 3), rand(-1, 3))
animate(src, transform=M, time=2)
/obj/machinery/washing_machine/clean_blood()
..()
if(!busy)
bloody_mess = FALSE
update_icon()
/obj/machinery/washing_machine/proc/wash_cycle()
for(var/X in contents)
var/atom/movable/AM = X
SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
AM.clean_blood()
AM.machine_wash(src)
busy = FALSE
if(color_source)
qdel(color_source)
color_source = null
update_icon()
//what happens to this object when washed inside a washing machine
/atom/movable/proc/machine_wash(obj/machinery/washing_machine/WM)
return
/obj/item/stack/sheet/hairlesshide/machine_wash(obj/machinery/washing_machine/WM)
new /obj/item/stack/sheet/wetleather(drop_location(), amount)
qdel(src)
/obj/item/clothing/suit/hooded/ian_costume/machine_wash(obj/machinery/washing_machine/WM)
new /obj/item/reagent_containers/food/snacks/meat/slab/corgi(loc)
qdel(src)
/obj/item/paper/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
if(istype(WM.color_source, /obj/item/toy/crayon))
var/obj/item/toy/crayon/CR = WM.color_source
add_atom_colour(CR.paint_color, WASHABLE_COLOUR_PRIORITY)
/obj/item/reagents_containers/rag/towel/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
if(istype(WM.color_source, /obj/item/toy/crayon))
var/obj/item/toy/crayon/CR = WM.color_source
add_atom_colour(CR.paint_color, WASHABLE_COLOUR_PRIORITY)
/mob/living/simple_animal/pet/dog/corgi/machine_wash(obj/machinery/washing_machine/WM)
gib()
/obj/item/clothing/under/color/machine_wash(obj/machinery/washing_machine/WM)
jumpsuit_wash(WM)
/obj/item/clothing/under/rank/machine_wash(obj/machinery/washing_machine/WM)
jumpsuit_wash(WM)
/obj/item/clothing/under/proc/jumpsuit_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
var/obj/item/clothing/under/U
for(var/T in typesof(/obj/item/clothing/under/color))
var/obj/item/clothing/under/color/J = T
if(wash_color == initial(J.item_color))
U = J
break
if(!U)
for(var/T in typesof(/obj/item/clothing/under/rank))
var/obj/item/clothing/under/rank/R = T
if(wash_color == initial(R.item_color))
U = R
break
if(U)
item_state = initial(U.item_state)
icon_state = initial(U.icon_state)
item_color = wash_color
name = initial(U.name)
desc = "The colors are a bit dodgy."
can_adjust = initial(U.can_adjust)
if(!can_adjust && adjusted) //we deadjust the uniform if it's now unadjustable
toggle_jumpsuit_adjust()
/obj/item/clothing/gloves/color/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
for(var/T in typesof(/obj/item/clothing/gloves/color))
var/obj/item/clothing/gloves/color/G = T
if(wash_color == initial(G.item_color))
item_state = initial(G.item_state)
icon_state = initial(G.icon_state)
item_color = wash_color
name = initial(G.name)
desc = "The colors are a bit dodgy."
break
/obj/item/clothing/shoes/sneakers/machine_wash(obj/machinery/washing_machine/WM)
if(chained)
chained = 0
slowdown = SHOES_SLOWDOWN
new /obj/item/restraints/handcuffs(loc)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
for(var/T in typesof(/obj/item/clothing/shoes/sneakers))
var/obj/item/clothing/shoes/sneakers/S = T
if(wash_color == initial(S.item_color))
icon_state = initial(S.icon_state)
item_color = wash_color
name = initial(S.name)
desc = "The colors are a bit dodgy."
break
/obj/item/bedsheet/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
for(var/T in typesof(/obj/item/bedsheet))
var/obj/item/bedsheet/B = T
if(wash_color == initial(B.item_color))
icon_state = initial(B.icon_state)
item_color = wash_color
name = initial(B.name)
desc = "The colors are a bit dodgy."
break
/obj/item/clothing/head/soft/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
for(var/T in typesof(/obj/item/clothing/head/soft))
var/obj/item/clothing/head/soft/H = T
if(wash_color == initial(H.item_color))
icon_state = initial(H.icon_state)
item_color = wash_color
name = initial(H.name)
desc = "The colors are a bit dodgy."
break
/obj/machinery/washing_machine/relaymove(mob/user)
container_resist(user)
/obj/machinery/washing_machine/container_resist(mob/living/user)
if(!busy)
add_fingerprint(user)
open_machine()
/obj/machinery/washing_machine/update_icon()
cut_overlays()
if(busy)
icon_state = "wm_running_[bloody_mess]"
else if(bloody_mess)
icon_state = "wm_[state_open]_blood"
else
var/full = contents.len ? 1 : 0
icon_state = "wm_[state_open]_[full]"
if(panel_open)
add_overlay("wm_panel")
/obj/machinery/washing_machine/attackby(obj/item/W, mob/user, params)
if(panel_open && !busy && default_unfasten_wrench(user, W))
return
if(default_deconstruction_screwdriver(user, null, null, W))
update_icon()
return
if(istype(W, /obj/item/clothing/head/mob_holder))
to_chat(user, "<span class='warning'>It's too unweildy to put in this way.</span>")
return 1
else if(user.a_intent != INTENT_HARM)
if (!state_open)
to_chat(user, "<span class='warning'>Open the door first!</span>")
return 1
if(bloody_mess)
to_chat(user, "<span class='warning'>[src] must be cleaned up first.</span>")
return 1
if(contents.len >= max_wash_capacity)
to_chat(user, "<span class='warning'>The washing machine is full!</span>")
return 1
if(!user.transferItemToLoc(W, src))
to_chat(user, "<span class='warning'>\The [W] is stuck to your hand, you cannot put it in the washing machine!</span>")
return 1
if(istype(W, /obj/item/toy/crayon) || istype(W, /obj/item/stamp))
color_source = W
update_icon()
else
return ..()
/obj/machinery/washing_machine/attack_hand(mob/user)
. = ..()
if(.)
return
if(busy)
to_chat(user, "<span class='warning'>[src] is busy.</span>")
return
if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling))
var/mob/living/L = user.pulling
if(L.buckled || L.has_buckled_mobs())
return
if(state_open)
if(iscorgi(L))
has_corgi = 1
L.forceMove(src)
update_icon()
return
if(!state_open)
open_machine()
else
state_open = FALSE //close the door
update_icon()
/obj/machinery/washing_machine/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/metal (loc, 2)
qdel(src)
/obj/machinery/washing_machine/open_machine(drop = 1)
..()
density = TRUE //because machinery/open_machine() sets it to 0
color_source = null
has_corgi = 0
+1 -1
View File
@@ -1,5 +1,5 @@
/obj/mecha/combat/durand
desc = "An aging combat exosuit utilized by the Nanotrasen corporation. Originally developed to combat hostile alien lifeforms."
desc = "An aging combat exosuit utilized by the Kinaris corporation. Originally developed to combat hostile alien lifeforms."
name = "\improper Durand"
icon_state = "durand"
step_in = 4
+1 -1
View File
@@ -80,7 +80,7 @@
equip_cooldown = 8 //Rapid fire heavy laser cannon, simple yet elegant
energy_drain = 30
name = "Aribter Laser Cannon"
desc = "Please re-attach this to neovgre and stop asking questions about why it looks like a normal Nanotrasen issue Solaris laser cannon - Nezbere"
desc = "Please re-attach this to neovgre and stop asking questions about why it looks like a normal Kinaris issue Solaris laser cannon - Nezbere"
fire_sound = "sound/weapons/neovgre_laser.ogg"
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/can_attach(obj/mecha/combat/neovgre/M)
File diff suppressed because it is too large Load Diff
@@ -13,6 +13,8 @@
energy_drain = 10
force = 15
harmful = TRUE
tool_behaviour = TOOL_DRILL
toolspeed = 0.9
var/drill_delay = 7
var/drill_level = DRILL_BASIC
@@ -141,6 +143,7 @@
drill_delay = 4
drill_level = DRILL_HARDENED
force = 15
toolspeed = 0.7
/obj/item/mecha_parts/mecha_equipment/mining_scanner
@@ -11,6 +11,8 @@
var/dam_force = 20
var/obj/mecha/working/ripley/cargo_holder
harmful = TRUE
tool_behaviour = TOOL_RETRACTOR
toolspeed = 0.8
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/can_attach(obj/mecha/working/ripley/M as obj)
if(..())
@@ -169,7 +171,7 @@
/obj/item/mecha_parts/mecha_equipment/extinguisher/Initialize()
. = ..()
create_reagents(1000)
reagents.add_reagent("water", 1000)
reagents.add_reagent(/datum/reagent/water, 1000)
/obj/item/mecha_parts/mecha_equipment/extinguisher/action(atom/target) //copypasted from extinguisher. TODO: Rewrite from scratch.
if(!action_checks(target) || get_dist(chassis, target)>3)
+3 -3
View File
@@ -9,7 +9,7 @@
/turf/open/floor/mech_bay_recharge_floor/airless
icon_state = "recharge_floor_asteroid"
initial_gas_mix = "TEMP=2.7"
initial_gas_mix = AIRLESS_ATMOS
/obj/machinery/mech_bay_recharge_port
name = "mech bay power port"
@@ -79,7 +79,7 @@
/obj/machinery/computer/mech_bay_power_console/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "mech_bay_power_console", "Mech Bay Power Control Console", 400, 170, master_ui, state)
ui = new(user, src, ui_key, "mech_bay_power_console", "Mech Bay Power Control Console", 400, 200, master_ui, state)
ui.open()
/obj/machinery/computer/mech_bay_power_console/ui_act(action, params)
@@ -96,7 +96,7 @@
if(recharge_port && !QDELETED(recharge_port))
data["recharge_port"] = list("mech" = null)
if(recharge_port.recharging_mech && !QDELETED(recharge_port.recharging_mech))
data["recharge_port"]["mech"] = list("health" = recharge_port.recharging_mech.obj_integrity, "maxhealth" = recharge_port.recharging_mech.max_integrity, "cell" = null)
data["recharge_port"]["mech"] = list("health" = recharge_port.recharging_mech.obj_integrity, "maxhealth" = recharge_port.recharging_mech.max_integrity, "cell" = null, "name" = recharge_port.recharging_mech.name,)
if(recharge_port.recharging_mech.cell && !QDELETED(recharge_port.recharging_mech.cell))
data["recharge_port"]["mech"]["cell"] = list(
"critfail" = recharge_port.recharging_mech.cell.crit_fail,
+11 -11
View File
@@ -79,13 +79,13 @@
sleep(15)
say("User DB corrupted \[Code 0x00FA\]. Truncating data structure...")
sleep(30)
say("User DB truncated. Please contact your Nanotrasen system operator for future assistance.")
say("User DB truncated. Please contact your Kinaris system operator for future assistance.")
/obj/machinery/mecha_part_fabricator/proc/output_parts_list(set_name)
var/output = ""
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(D.build_type & MECHFAB)
if(!(set_name in D.category))
continue
@@ -183,7 +183,7 @@
/obj/machinery/mecha_part_fabricator/proc/add_part_set_to_queue(set_name)
if(set_name in part_sets)
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(D.build_type & MECHFAB)
if(set_name in D.category)
add_to_queue(D)
@@ -338,7 +338,7 @@
if(href_list["part"])
var/T = afilter.getStr("part")
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(D.build_type & MECHFAB)
if(D.id == T)
if(!processing_queue)
@@ -349,7 +349,7 @@
if(href_list["add_to_queue"])
var/T = afilter.getStr("add_to_queue")
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(D.build_type & MECHFAB)
if(D.id == T)
add_to_queue(D)
@@ -387,7 +387,7 @@
if(href_list["part_desc"])
var/T = afilter.getStr("part_desc")
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(D.build_type & MECHFAB)
if(D.id == T)
var/obj/part = D.build_path
@@ -404,11 +404,11 @@
updateUsrDialog()
return
/obj/machinery/mecha_part_fabricator/proc/do_process_queue()
if(processing_queue || being_built)
return FALSE
/obj/machinery/mecha_part_fabricator/proc/do_process_queue()
if(processing_queue || being_built)
return FALSE
processing_queue = 1
process_queue()
process_queue()
processing_queue = 0
/obj/machinery/mecha_part_fabricator/proc/eject_sheets(eject_sheet, eject_amt)
@@ -441,7 +441,7 @@
return ..()
/obj/machinery/mecha_part_fabricator/proc/material2name(ID)
return copytext(ID,2)
return copytext_char(ID,2)
/obj/machinery/mecha_part_fabricator/proc/is_insertion_ready(mob/user)
if(panel_open)
+1087 -1087
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -139,8 +139,10 @@
chassis.toggle_strafe()
/obj/mecha/AltClick(mob/living/user)
. = ..()
if((user == occupant) && user.canUseTopic(src))
toggle_strafe()
return TRUE
/obj/mecha/proc/toggle_strafe()
strafe = !strafe
+4 -4
View File
@@ -289,10 +289,10 @@
/obj/mecha/proc/mech_toxin_damage(mob/living/target)
playsound(src, 'sound/effects/spray2.ogg', 50, 1)
if(target.reagents)
if(target.reagents.get_reagent_amount("cryptobiolin") + force < force*2)
target.reagents.add_reagent("cryptobiolin", force/2)
if(target.reagents.get_reagent_amount("toxin") + force < force*2)
target.reagents.add_reagent("toxin", force/2.5)
if(target.reagents.get_reagent_amount(/datum/reagent/cryptobiolin) + force < force*2)
target.reagents.add_reagent(/datum/reagent/cryptobiolin, force/2)
if(target.reagents.get_reagent_amount(/datum/reagent/toxin) + force < force*2)
target.reagents.add_reagent(/datum/reagent/toxin, force/2.5)
/obj/mecha/mech_melee_attack(obj/mecha/M)
+5 -5
View File
@@ -299,11 +299,11 @@
onclose(occupant, "exosuit_log")
if (href_list["change_name"])
var/newname = stripped_input(occupant,"Choose new exosuit name","Rename exosuit","", MAX_NAME_LEN)
if(newname && trim(newname))
name = newname
else
alert(occupant, "nope.avi")
var/userinput = stripped_input(occupant,"Choose new exosuit name","Rename exosuit","", MAX_NAME_LEN)
if(!userinput || usr != occupant || usr.incapacitated())
return
name = userinput
return
if (href_list["toggle_id_upload"])
add_req_access = !add_req_access
+1 -1
View File
@@ -128,7 +128,7 @@
if (smooth & SMOOTH_DIAGONAL)
for (var/O in overlays)
var/image/I = O
if (copytext(I.icon_state, 1, 3) == "d-")
if(copytext(I.icon_state, 1, 3) == "d-") //3 == length("d-") + 1
return
var/stuff_on_wall = 0
@@ -10,7 +10,7 @@
/obj/effect/decal/cleanable/blood/gibs/xeno
color = BLOOD_COLOR_XENO
gibs_reagent_id = "liquidxenogibs"
gibs_reagent_id = /datum/reagent/liquidgibs/xeno
gibs_bloodtype = "X*"
/obj/effect/decal/cleanable/blood/gibs/xeno/Initialize(mapload, list/datum/disease/diseases)
@@ -30,13 +30,19 @@
var/list/diseases = list()
SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases)
var/direction = pick(directions)
for(var/i in 0 to pick(0, 200; 1, 150; 2, 50))
sleep(2)
if(i > 0)
var/dist = 0
if(prob(50)) //yes this and the one below are different for a reason.
if(prob(25))
dist = 2
else
dist = 1
if(dist)
for(var/i in 1 to dist)
sleep(2)
var/obj/effect/decal/cleanable/blood/splatter/xeno/splat = new /obj/effect/decal/cleanable/blood/splatter/xeno(loc, diseases)
splat.transfer_blood_dna(blood_DNA, diseases)
if(!step_to(src, get_step(src, direction), 0))
break
if(!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/blood/gibs/xeno/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
@@ -5,9 +5,9 @@
layer = LOW_OBJ_LAYER
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
mergeable_decal = FALSE
bloodiness = 0
bloodiness = 0 //This isn't supposed to be bloody.
var/body_colors = "#e3ba84" //a default color just in case.
var/gibs_reagent_id = "liquidgibs"
var/gibs_reagent_id = /datum/reagent/liquidgibs
var/gibs_bloodtype = "A+"
/obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases)
@@ -20,7 +20,6 @@
add_blood_DNA(list("Non-human DNA" = gibs_bloodtype), diseases)
update_icon()
/obj/effect/decal/cleanable/blood/gibs/update_icon()
add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
cut_overlays()
@@ -45,13 +44,18 @@
var/list/diseases = list()
SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases)
var/direction = pick(directions)
for(var/i in 0 to pick(0, 200; 1, 150; 2, 50))
sleep(2)
if(i > 0)
var/dist = 0
if(prob(50)) //yes this and the one below are different for a reason.
if(prob(25))
dist = 2
else
dist = 1
if(dist)
for(var/i in 1 to dist)
var/obj/effect/decal/cleanable/blood/splatter/splat = new /obj/effect/decal/cleanable/blood/splatter(loc, diseases)
splat.transfer_blood_dna(blood_DNA, diseases)
if(!step_to(src, get_step(src, direction), 0))
break
if(!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/blood/gibs/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
@@ -121,7 +125,6 @@
//Lizards
/obj/effect/decal/cleanable/blood/gibs/human/lizard
body_colors = "117720"
gibs_reagent_id = "liquidgibs"
gibs_bloodtype = "L"
/obj/effect/decal/cleanable/blood/gibs/human/lizard/Initialize(mapload, list/datum/disease/diseases)
@@ -149,7 +152,7 @@
// Slime Gibs
/obj/effect/decal/cleanable/blood/gibs/slime
desc = "They look gooey and gruesome."
gibs_reagent_id = "liquidslimegibs"
gibs_reagent_id = /datum/reagent/liquidgibs/slime
gibs_bloodtype = "GEL"
/obj/effect/decal/cleanable/blood/gibs/slime/Initialize(mapload, list/datum/disease/diseases)
@@ -188,7 +191,7 @@
/obj/effect/decal/cleanable/blood/gibs/synth
desc = "They look sludgy and disgusting."
gibs_reagent_id = "liquidsyntheticgibs"
gibs_reagent_id = /datum/reagent/liquidgibs/synth
gibs_bloodtype = "SY"
/obj/effect/decal/cleanable/blood/gibs/synth/Initialize(mapload, list/datum/disease/diseases)
@@ -199,7 +202,7 @@
/obj/effect/decal/cleanable/blood/gibs/ipc
desc = "They look sharp yet oozing."
body_colors = "00ff00"
gibs_reagent_id = "liquidoilgibs"
gibs_reagent_id = /datum/reagent/liquidgibs/oil
gibs_bloodtype = "HF"
/obj/effect/decal/cleanable/blood/gibs/ipc/Initialize(mapload, list/datum/disease/diseases)
+255 -257
View File
@@ -1,257 +1,255 @@
/obj/effect/decal/cleanable/generic
name = "clutter"
desc = "Someone should clean that up."
icon = 'icons/obj/objects.dmi'
icon_state = "shards"
/obj/effect/decal/cleanable/ash
name = "ashes"
desc = "Ashes to ashes, dust to dust, and into space."
icon = 'icons/obj/objects.dmi'
icon_state = "ash"
mergeable_decal = FALSE
/obj/effect/decal/cleanable/ash/Initialize()
. = ..()
reagents.add_reagent("ash", 30)
pixel_x = rand(-5, 5)
pixel_y = rand(-5, 5)
/obj/effect/decal/cleanable/ash/crematorium
//crematoriums need their own ash cause default ash deletes itself if created in an obj
turf_loc_check = FALSE
/obj/effect/decal/cleanable/ash/large
name = "large pile of ashes"
icon_state = "big_ash"
/obj/effect/decal/cleanable/ash/large/Initialize()
. = ..()
reagents.add_reagent("ash", 30) //double the amount of ash.
/obj/effect/decal/cleanable/glass
name = "tiny shards"
desc = "Back to sand."
icon = 'icons/obj/shards.dmi'
icon_state = "tiny"
/obj/effect/decal/cleanable/glass/Initialize()
. = ..()
setDir(pick(GLOB.cardinals))
/obj/effect/decal/cleanable/glass/ex_act()
qdel(src)
/obj/effect/decal/cleanable/dirt
name = "dirt"
desc = "Someone should clean that up."
icon_state = "dirt"
canSmoothWith = list(/obj/effect/decal/cleanable/dirt, /turf/closed/wall, /obj/structure/falsewall)
smooth = SMOOTH_FALSE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/effect/decal/cleanable/dirt/Initialize()
. = ..()
var/turf/T = get_turf(src)
if(T.tiled_dirt)
smooth = SMOOTH_MORE
icon = 'icons/effects/dirt.dmi'
icon_state = ""
queue_smooth(src)
queue_smooth_neighbors(src)
/obj/effect/decal/cleanable/dirt/Destroy()
queue_smooth_neighbors(src)
return ..()
/obj/effect/decal/cleanable/flour
name = "flour"
desc = "It's still good. Four second rule!"
icon_state = "flour"
/obj/effect/decal/cleanable/greenglow/ecto
name = "ectoplasmic puddle"
desc = "You know who to call."
light_power = 2
/obj/effect/decal/cleanable/greenglow
name = "glowing goo"
desc = "Jeez. I hope that's not for lunch."
light_color = LIGHT_COLOR_GREEN
icon_state = "greenglow"
/obj/effect/decal/cleanable/greenglow/Initialize(mapload)
. = ..()
set_light(2, 0.8, "#22FFAA")
/obj/effect/decal/cleanable/greenglow/radioactive
name = "radioactive hazard"
desc = "You should really clean this up..."
var/rad_pulse_strength = 5
var/last_event = 0
var/active = null
/obj/effect/decal/cleanable/greenglow/radioactive/Crossed(atom/movable/O)
. = ..()
if(ismob(O))
radiate()
/obj/effect/decal/cleanable/greenglow/radioactive/proc/radiate()
if(!active)
if(world.time > last_event+15)
active = 1
radiation_pulse(src, rad_pulse_strength)
for(var/obj/effect/decal/cleanable/greenglow/radioactive/T in orange(1,src))
T.radiate()
last_event = world.time
active = 0
return
/obj/effect/decal/cleanable/greenglow/ex_act()
return
/obj/effect/decal/cleanable/cobweb
name = "cobweb"
desc = "Somebody should remove that."
gender = NEUTER
layer = WALL_OBJ_LAYER
icon_state = "cobweb1"
resistance_flags = FLAMMABLE
/obj/effect/decal/cleanable/cobweb/cobweb2
icon_state = "cobweb2"
/obj/effect/decal/cleanable/molten_object
name = "gooey grey mass"
desc = "It looks like a melted... something."
gender = NEUTER
icon = 'icons/effects/effects.dmi'
icon_state = "molten"
mergeable_decal = FALSE
/obj/effect/decal/cleanable/molten_object/large
name = "big gooey grey mass"
icon_state = "big_molten"
//Vomit (sorry)
/obj/effect/decal/cleanable/vomit
name = "vomit"
desc = "Gosh, how unpleasant."
icon = 'icons/effects/blood.dmi'
icon_state = "vomit_1"
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
/obj/effect/decal/cleanable/vomit/attack_hand(mob/user)
. = ..()
if(.)
return
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(isflyperson(H))
playsound(get_turf(src), 'sound/items/drink.ogg', 50, 1) //slurp
H.visible_message("<span class='alert'>[H] extends a small proboscis into the vomit pool, sucking it with a slurping sound.</span>")
if(reagents)
for(var/datum/reagent/R in reagents.reagent_list)
if (istype(R, /datum/reagent/consumable))
var/datum/reagent/consumable/nutri_check = R
if(nutri_check.nutriment_factor >0)
H.nutrition += nutri_check.nutriment_factor * nutri_check.volume
reagents.remove_reagent(nutri_check.id,nutri_check.volume)
reagents.trans_to(H, reagents.total_volume)
qdel(src)
/obj/effect/decal/cleanable/vomit/old
name = "crusty dried vomit"
desc = "You try not to look at the chunks, and fail."
/obj/effect/decal/cleanable/vomit/old/Initialize(mapload, list/datum/disease/diseases)
. = ..()
icon_state += "-old"
/obj/effect/decal/cleanable/tomato_smudge
name = "tomato smudge"
desc = "It's red."
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3")
/obj/effect/decal/cleanable/plant_smudge
name = "plant smudge"
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_plant")
/obj/effect/decal/cleanable/egg_smudge
name = "smashed egg"
desc = "Seems like this one won't hatch."
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_egg1", "smashed_egg2", "smashed_egg3")
/obj/effect/decal/cleanable/pie_smudge //honk
name = "smashed pie"
desc = "It's pie cream from a cream pie."
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_pie")
/obj/effect/decal/cleanable/chem_pile
name = "chemical pile"
desc = "A pile of chemicals. You can't quite tell what's inside it."
gender = NEUTER
icon = 'icons/obj/objects.dmi'
icon_state = "ash"
/obj/effect/decal/cleanable/shreds
name = "shreds"
desc = "The shredded remains of what appears to be clothing."
icon_state = "shreds"
gender = PLURAL
mergeable_decal = FALSE
/obj/effect/decal/cleanable/shreds/ex_act(severity, target)
if(severity == 1) //so shreds created during an explosion aren't deleted by the explosion.
qdel(src)
/obj/effect/decal/cleanable/shreds/Initialize()
pixel_x = rand(-10, 10)
pixel_y = rand(-10, 10)
. = ..()
/obj/effect/decal/cleanable/salt
name = "salt pile"
desc = "A sizable pile of table salt. Someone must be upset."
icon = 'icons/effects/tomatodecal.dmi'
icon_state = "salt_pile"
gender = NEUTER
/obj/effect/decal/cleanable/glitter
name = "generic glitter pile"
desc = "The herpes of arts and crafts."
icon = 'icons/effects/atmospherics.dmi'
gender = NEUTER
/obj/effect/decal/cleanable/glitter/pink
name = "pink glitter"
icon_state = "plasma_old"
/obj/effect/decal/cleanable/glitter/white
name = "white glitter"
icon_state = "nitrous_oxide_old"
/obj/effect/decal/cleanable/glitter/blue
name = "blue glitter"
icon_state = "freon_old"
/obj/effect/decal/cleanable/plasma
name = "stabilized plasma"
desc = "A puddle of stabilized plasma."
icon_state = "flour"
color = "#9e0089"
/obj/effect/decal/cleanable/insectguts
name = "insect guts"
desc = "One bug squashed. Four more will rise in its place."
icon = 'icons/effects/blood.dmi'
icon_state = "xfloor1"
random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7")
/obj/effect/decal/cleanable/generic
name = "clutter"
desc = "Someone should clean that up."
icon = 'icons/obj/objects.dmi'
icon_state = "shards"
/obj/effect/decal/cleanable/ash
name = "ashes"
desc = "Ashes to ashes, dust to dust, and into space."
icon = 'icons/obj/objects.dmi'
icon_state = "ash"
mergeable_decal = FALSE
/obj/effect/decal/cleanable/ash/Initialize()
. = ..()
reagents.add_reagent(/datum/reagent/ash, 30)
pixel_x = rand(-5, 5)
pixel_y = rand(-5, 5)
/obj/effect/decal/cleanable/ash/crematorium
//crematoriums need their own ash cause default ash deletes itself if created in an obj
turf_loc_check = FALSE
/obj/effect/decal/cleanable/ash/large
name = "large pile of ashes"
icon_state = "big_ash"
/obj/effect/decal/cleanable/ash/large/Initialize()
. = ..()
reagents.add_reagent(/datum/reagent/ash, 30) //double the amount of ash.
/obj/effect/decal/cleanable/glass
name = "tiny shards"
desc = "Back to sand."
icon = 'icons/obj/shards.dmi'
icon_state = "tiny"
/obj/effect/decal/cleanable/glass/Initialize()
. = ..()
setDir(pick(GLOB.cardinals))
/obj/effect/decal/cleanable/glass/ex_act()
qdel(src)
/obj/effect/decal/cleanable/dirt
name = "dirt"
desc = "Someone should clean that up."
icon_state = "dirt"
canSmoothWith = list(/obj/effect/decal/cleanable/dirt, /turf/closed/wall, /obj/structure/falsewall)
smooth = SMOOTH_FALSE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/effect/decal/cleanable/dirt/Initialize()
. = ..()
var/turf/T = get_turf(src)
if(T.tiled_dirt)
smooth = SMOOTH_MORE
icon = 'icons/effects/dirt.dmi'
icon_state = ""
queue_smooth(src)
queue_smooth_neighbors(src)
/obj/effect/decal/cleanable/dirt/Destroy()
queue_smooth_neighbors(src)
return ..()
/obj/effect/decal/cleanable/flour
name = "flour"
desc = "It's still good. Four second rule!"
icon_state = "flour"
/obj/effect/decal/cleanable/greenglow/ecto
name = "ectoplasmic puddle"
desc = "You know who to call."
light_power = 2
/obj/effect/decal/cleanable/greenglow
name = "glowing goo"
desc = "Jeez. I hope that's not for lunch."
light_color = LIGHT_COLOR_GREEN
icon_state = "greenglow"
/obj/effect/decal/cleanable/greenglow/Initialize(mapload)
. = ..()
set_light(2, 0.8, "#22FFAA")
/obj/effect/decal/cleanable/greenglow/radioactive
name = "radioactive hazard"
desc = "You should really clean this up..."
var/rad_pulse_strength = 5
var/last_event = 0
var/active = null
/obj/effect/decal/cleanable/greenglow/radioactive/Crossed(atom/movable/O)
. = ..()
if(ismob(O))
radiate()
/obj/effect/decal/cleanable/greenglow/radioactive/proc/radiate()
if(!active)
if(world.time > last_event+15)
active = 1
radiation_pulse(src, rad_pulse_strength)
for(var/obj/effect/decal/cleanable/greenglow/radioactive/T in orange(1,src))
T.radiate()
last_event = world.time
active = 0
return
/obj/effect/decal/cleanable/greenglow/ex_act()
return
/obj/effect/decal/cleanable/cobweb
name = "cobweb"
desc = "Somebody should remove that."
gender = NEUTER
layer = WALL_OBJ_LAYER
icon_state = "cobweb1"
resistance_flags = FLAMMABLE
/obj/effect/decal/cleanable/cobweb/cobweb2
icon_state = "cobweb2"
/obj/effect/decal/cleanable/molten_object
name = "gooey grey mass"
desc = "It looks like a melted... something."
gender = NEUTER
icon = 'icons/effects/effects.dmi'
icon_state = "molten"
mergeable_decal = FALSE
/obj/effect/decal/cleanable/molten_object/large
name = "big gooey grey mass"
icon_state = "big_molten"
//Vomit (sorry)
/obj/effect/decal/cleanable/vomit
name = "vomit"
desc = "Gosh, how unpleasant."
icon = 'icons/effects/blood.dmi'
icon_state = "vomit_1"
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
/obj/effect/decal/cleanable/vomit/attack_hand(mob/user)
. = ..()
if(.)
return
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(isflyperson(H))
playsound(get_turf(src), 'sound/items/drink.ogg', 50, 1) //slurp
H.visible_message("<span class='alert'>[H] extends a small proboscis into the vomit pool, sucking it with a slurping sound.</span>")
if(reagents)
for(var/datum/reagent/consumable/R in reagents.reagent_list)
if(R.nutriment_factor > 0)
H.nutrition += R.nutriment_factor * R.volume
reagents.del_reagent(R.type)
reagents.trans_to(H, reagents.total_volume)
qdel(src)
/obj/effect/decal/cleanable/vomit/old
name = "crusty dried vomit"
desc = "You try not to look at the chunks, and fail."
/obj/effect/decal/cleanable/vomit/old/Initialize(mapload, list/datum/disease/diseases)
. = ..()
icon_state += "-old"
/obj/effect/decal/cleanable/tomato_smudge
name = "tomato smudge"
desc = "It's red."
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3")
/obj/effect/decal/cleanable/plant_smudge
name = "plant smudge"
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_plant")
/obj/effect/decal/cleanable/egg_smudge
name = "smashed egg"
desc = "Seems like this one won't hatch."
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_egg1", "smashed_egg2", "smashed_egg3")
/obj/effect/decal/cleanable/pie_smudge //honk
name = "smashed pie"
desc = "It's pie cream from a cream pie."
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_pie")
/obj/effect/decal/cleanable/chem_pile
name = "chemical pile"
desc = "A pile of chemicals. You can't quite tell what's inside it."
gender = NEUTER
icon = 'icons/obj/objects.dmi'
icon_state = "ash"
/obj/effect/decal/cleanable/shreds
name = "shreds"
desc = "The shredded remains of what appears to be clothing."
icon_state = "shreds"
gender = PLURAL
mergeable_decal = FALSE
/obj/effect/decal/cleanable/shreds/ex_act(severity, target)
if(severity == 1) //so shreds created during an explosion aren't deleted by the explosion.
qdel(src)
/obj/effect/decal/cleanable/shreds/Initialize()
pixel_x = rand(-10, 10)
pixel_y = rand(-10, 10)
. = ..()
/obj/effect/decal/cleanable/salt
name = "salt pile"
desc = "A sizable pile of table salt. Someone must be upset."
icon = 'icons/effects/tomatodecal.dmi'
icon_state = "salt_pile"
gender = NEUTER
/obj/effect/decal/cleanable/glitter
name = "generic glitter pile"
desc = "The herpes of arts and crafts."
icon = 'icons/effects/atmospherics.dmi'
gender = NEUTER
/obj/effect/decal/cleanable/glitter/pink
name = "pink glitter"
icon_state = "plasma_old"
/obj/effect/decal/cleanable/glitter/white
name = "white glitter"
icon_state = "nitrous_oxide_old"
/obj/effect/decal/cleanable/glitter/blue
name = "blue glitter"
icon_state = "freon_old"
/obj/effect/decal/cleanable/plasma
name = "stabilized plasma"
desc = "A puddle of stabilized plasma."
icon_state = "flour"
color = "#9e0089"
/obj/effect/decal/cleanable/insectguts
name = "insect guts"
desc = "One bug squashed. Four more will rise in its place."
icon = 'icons/effects/blood.dmi'
icon_state = "xfloor1"
random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7")
@@ -1,65 +1,65 @@
// Note: BYOND is object oriented. There is no reason for this to be copy/pasted blood code.
/obj/effect/decal/cleanable/robot_debris
name = "robot debris"
desc = "It's a useless heap of junk... <i>or is it?</i>"
icon = 'icons/mob/robots.dmi'
icon_state = "gib1"
layer = LOW_OBJ_LAYER
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7")
blood_state = BLOOD_STATE_OIL
bloodiness = BLOOD_AMOUNT_PER_DECAL
mergeable_decal = FALSE
/obj/effect/decal/cleanable/robot_debris/Initialize(mapload, list/datum/disease/diseases)
. = ..()
reagents.add_reagent("liquidoilgibs", 5)
/obj/effect/decal/cleanable/robot_debris/proc/streak(list/directions)
set waitfor = 0
var/direction = pick(directions)
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
sleep(2)
if (i > 0)
if (prob(40))
new /obj/effect/decal/cleanable/oil/streak(src.loc)
else if (prob(10))
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, src)
s.start()
if (!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/robot_debris/ex_act()
return
/obj/effect/decal/cleanable/robot_debris/limb
random_icon_states = list("gibarm", "gibleg")
/obj/effect/decal/cleanable/robot_debris/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibup1","gibup1")
/obj/effect/decal/cleanable/robot_debris/down
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibdown1","gibdown1")
/obj/effect/decal/cleanable/oil
name = "motor oil"
desc = "It's black and greasy. Looks like Beepsky made another mess."
icon = 'icons/mob/robots.dmi'
icon_state = "floor1"
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
blood_state = BLOOD_STATE_OIL
bloodiness = BLOOD_AMOUNT_PER_DECAL
/obj/effect/decal/cleanable/oil/Initialize()
. = ..()
reagents.add_reagent("oil", 30)
reagents.add_reagent("liquidoilgibs", 5)
/obj/effect/decal/cleanable/oil/streak
random_icon_states = list("streak1", "streak2", "streak3", "streak4", "streak5")
/obj/effect/decal/cleanable/oil/slippery
/obj/effect/decal/cleanable/oil/slippery/Initialize()
AddComponent(/datum/component/slippery, 80, (NO_SLIP_WHEN_WALKING | SLIDE))
// Note: BYOND is object oriented. There is no reason for this to be copy/pasted blood code.
/obj/effect/decal/cleanable/robot_debris
name = "robot debris"
desc = "It's a useless heap of junk... <i>or is it?</i>"
icon = 'icons/mob/robots.dmi'
icon_state = "gib1"
layer = LOW_OBJ_LAYER
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7")
blood_state = BLOOD_STATE_OIL
bloodiness = BLOOD_AMOUNT_PER_DECAL
mergeable_decal = FALSE
/obj/effect/decal/cleanable/robot_debris/Initialize(mapload, list/datum/disease/diseases)
. = ..()
reagents.add_reagent(/datum/reagent/liquidgibs, 5)
/obj/effect/decal/cleanable/robot_debris/proc/streak(list/directions)
set waitfor = 0
var/direction = pick(directions)
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
sleep(2)
if (i > 0)
if (prob(40))
new /obj/effect/decal/cleanable/oil/streak(src.loc)
else if (prob(10))
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, src)
s.start()
if (!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/robot_debris/ex_act()
return
/obj/effect/decal/cleanable/robot_debris/limb
random_icon_states = list("gibarm", "gibleg")
/obj/effect/decal/cleanable/robot_debris/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibup1","gibup1")
/obj/effect/decal/cleanable/robot_debris/down
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibdown1","gibdown1")
/obj/effect/decal/cleanable/oil
name = "motor oil"
desc = "It's black and greasy. Looks like Beepsky made another mess."
icon = 'icons/mob/robots.dmi'
icon_state = "floor1"
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
blood_state = BLOOD_STATE_OIL
bloodiness = BLOOD_AMOUNT_PER_DECAL
/obj/effect/decal/cleanable/oil/Initialize()
. = ..()
reagents.add_reagent(/datum/reagent/oil, 30)
reagents.add_reagent(/datum/reagent/liquidgibs/oil, 5)
/obj/effect/decal/cleanable/oil/streak
random_icon_states = list("streak1", "streak2", "streak3", "streak4", "streak5")
/obj/effect/decal/cleanable/oil/slippery
/obj/effect/decal/cleanable/oil/slippery/Initialize()
AddComponent(/datum/component/slippery, 80, (NO_SLIP_WHEN_WALKING | SLIDE))
@@ -1,347 +1,347 @@
// Foam
// Similar to smoke, but slower and mobs absorb its reagent through their exposed skin.
#define ALUMINUM_FOAM 1
#define IRON_FOAM 2
#define RESIN_FOAM 3
/obj/effect/particle_effect/foam
name = "foam"
icon_state = "foam"
opacity = 0
anchored = TRUE
density = FALSE
layer = EDGED_TURF_LAYER
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/amount = 3
animate_movement = 0
var/metal = 0
var/lifetime = 40
var/reagent_divisor = 7
var/static/list/blacklisted_turfs = typecacheof(list(
/turf/open/space/transit,
/turf/open/chasm,
/turf/open/lava))
/obj/effect/particle_effect/foam/firefighting
name = "firefighting foam"
lifetime = 20 //doesn't last as long as normal foam
amount = 0 //no spread
var/absorbed_plasma = 0
/obj/effect/particle_effect/foam/firefighting/MakeSlippery()
return
/obj/effect/particle_effect/foam/firefighting/process()
..()
var/turf/open/T = get_turf(src)
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
if(hotspot && istype(T) && T.air)
qdel(hotspot)
var/datum/gas_mixture/G = T.air
var/plas_amt = min(30,G.gases[/datum/gas/plasma]) //Absorb some plasma
G.gases[/datum/gas/plasma] -= plas_amt
absorbed_plasma += plas_amt
if(G.temperature > T20C)
G.temperature = max(G.temperature/2,T20C)
GAS_GARBAGE_COLLECT(G.gases)
T.air_update_turf()
/obj/effect/particle_effect/foam/firefighting/kill_foam()
STOP_PROCESSING(SSfastprocess, src)
if(absorbed_plasma)
var/obj/effect/decal/cleanable/plasma/P = (locate(/obj/effect/decal/cleanable/plasma) in get_turf(src))
if(!P)
P = new(loc)
P.reagents.add_reagent("stable_plasma", absorbed_plasma)
flick("[icon_state]-disolve", src)
QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/firefighting/foam_mob(mob/living/L)
if(!istype(L))
return
L.adjust_fire_stacks(-2)
L.ExtinguishMob()
/obj/effect/particle_effect/foam/firefighting/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
/obj/effect/particle_effect/foam/metal
name = "aluminium foam"
metal = ALUMINUM_FOAM
icon_state = "mfoam"
/obj/effect/particle_effect/foam/metal/MakeSlippery()
return
/obj/effect/particle_effect/foam/metal/smart
name = "smart foam"
/obj/effect/particle_effect/foam/metal/iron
name = "iron foam"
metal = IRON_FOAM
/obj/effect/particle_effect/foam/metal/resin
name = "resin foam"
metal = RESIN_FOAM
/obj/effect/particle_effect/foam/long_life
lifetime = 150
/obj/effect/particle_effect/foam/Initialize()
. = ..()
MakeSlippery()
create_reagents(1000) //limited by the size of the reagent holder anyway.
START_PROCESSING(SSfastprocess, src)
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
/obj/effect/particle_effect/foam/proc/MakeSlippery()
AddComponent(/datum/component/slippery, 100)
/obj/effect/particle_effect/foam/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()
/obj/effect/particle_effect/foam/proc/kill_foam()
STOP_PROCESSING(SSfastprocess, src)
switch(metal)
if(ALUMINUM_FOAM)
new /obj/structure/foamedmetal(get_turf(src))
if(IRON_FOAM)
new /obj/structure/foamedmetal/iron(get_turf(src))
if(RESIN_FOAM)
new /obj/structure/foamedmetal/resin(get_turf(src))
flick("[icon_state]-disolve", src)
QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/smart/kill_foam() //Smart foam adheres to area borders for walls
STOP_PROCESSING(SSfastprocess, src)
if(metal)
var/turf/T = get_turf(src)
if(isspaceturf(T)) //Block up any exposed space
T.PlaceOnTop(/turf/open/floor/plating/foam)
for(var/direction in GLOB.cardinals)
var/turf/cardinal_turf = get_step(T, direction)
if(get_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf!
new/obj/structure/foamedmetal(T)
break
flick("[icon_state]-disolve", src)
QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/process()
lifetime--
if(lifetime < 1)
kill_foam()
return
var/fraction = 1/initial(reagent_divisor)
for(var/obj/O in range(0,src))
if(O.type == src.type)
continue
if(isturf(O.loc))
var/turf/T = O.loc
if(T.intact && O.level == 1) //hidden under the floor
continue
if(lifetime % reagent_divisor)
reagents.reaction(O, VAPOR, fraction)
var/hit = 0
for(var/mob/living/L in range(0,src))
hit += foam_mob(L)
if(hit)
lifetime++ //this is so the decrease from mobs hit and the natural decrease don't cumulate.
var/T = get_turf(src)
if(lifetime % reagent_divisor)
reagents.reaction(T, VAPOR, fraction)
if(--amount < 0)
return
spread_foam()
/obj/effect/particle_effect/foam/proc/foam_mob(mob/living/L)
if(lifetime<1)
return 0
if(!istype(L))
return 0
var/fraction = 1/initial(reagent_divisor)
if(lifetime % reagent_divisor)
reagents.reaction(L, VAPOR, fraction)
lifetime--
return 1
/obj/effect/particle_effect/foam/proc/spread_foam()
var/turf/t_loc = get_turf(src)
for(var/turf/T in t_loc.GetAtmosAdjacentTurfs())
var/obj/effect/particle_effect/foam/foundfoam = locate() in T //Don't spread foam where there's already foam!
if(foundfoam)
continue
if(is_type_in_typecache(T, blacklisted_turfs))
continue
for(var/mob/living/L in T)
foam_mob(L)
var/obj/effect/particle_effect/foam/F = new src.type(T)
F.amount = amount
reagents.copy_to(F, (reagents.total_volume))
F.add_atom_colour(color, FIXED_COLOUR_PRIORITY)
F.metal = metal
/obj/effect/particle_effect/foam/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(prob(max(0, exposed_temperature - 475))) //foam dissolves when heated
kill_foam()
/obj/effect/particle_effect/foam/metal/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
///////////////////////////////////////////////
//FOAM EFFECT DATUM
/datum/effect_system/foam_spread
var/amount = 10 // the size of the foam spread.
var/obj/chemholder
effect_type = /obj/effect/particle_effect/foam
var/metal = 0
/datum/effect_system/foam_spread/metal
effect_type = /obj/effect/particle_effect/foam/metal
/datum/effect_system/foam_spread/metal/smart
effect_type = /obj/effect/particle_effect/foam/smart
/datum/effect_system/foam_spread/long
effect_type = /obj/effect/particle_effect/foam/long_life
/datum/effect_system/foam_spread/New()
..()
chemholder = new /obj()
var/datum/reagents/R = new/datum/reagents(1000)
chemholder.reagents = R
R.my_atom = chemholder
/datum/effect_system/foam_spread/Destroy()
qdel(chemholder)
chemholder = null
return ..()
/datum/effect_system/foam_spread/set_up(amt=5, loca, datum/reagents/carry = null)
if(isturf(loca))
location = loca
else
location = get_turf(loca)
amount = round(sqrt(amt / 2), 1)
carry.copy_to(chemholder, carry.total_volume)
/datum/effect_system/foam_spread/metal/set_up(amt=5, loca, datum/reagents/carry = null, metaltype)
..()
metal = metaltype
/datum/effect_system/foam_spread/start()
var/obj/effect/particle_effect/foam/F = new effect_type(location)
var/foamcolor = mix_color_from_reagents(chemholder.reagents.reagent_list)
chemholder.reagents.copy_to(F, chemholder.reagents.total_volume/amount)
F.add_atom_colour(foamcolor, FIXED_COLOUR_PRIORITY)
F.amount = amount
F.metal = metal
//////////////////////////////////////////////////////////
// FOAM STRUCTURE. Formed by metal foams. Dense and opaque, but easy to break
/obj/structure/foamedmetal
icon = 'icons/effects/effects.dmi'
icon_state = "metalfoam"
density = TRUE
opacity = 1 // changed in New()
anchored = TRUE
layer = EDGED_TURF_LAYER
resistance_flags = FIRE_PROOF | ACID_PROOF
name = "foamed metal"
desc = "A lightweight foamed metal wall."
gender = PLURAL
max_integrity = 20
CanAtmosPass = ATMOS_PASS_DENSITY
/obj/structure/foamedmetal/Initialize()
. = ..()
air_update_turf(1)
/obj/structure/foamedmetal/Move()
var/turf/T = loc
. = ..()
move_update_air(T)
/obj/structure/foamedmetal/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/attack_hand(mob/user)
. = ..()
if(.)
return
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
to_chat(user, "<span class='warning'>You hit [src] but bounce off it!</span>")
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target)
return !density
/obj/structure/foamedmetal/iron
max_integrity = 50
icon_state = "ironfoam"
//Atmos Backpack Resin, transparent, prevents atmos and filters the air
/obj/structure/foamedmetal/resin
name = "\improper ATMOS Resin"
desc = "A lightweight, transparent resin used to suffocate fires, scrub the air of toxins, and restore the air to a safe temperature."
opacity = FALSE
icon_state = "atmos_resin"
alpha = 120
max_integrity = 10
/obj/structure/foamedmetal/resin/Initialize()
. = ..()
if(isopenturf(loc))
var/turf/open/O = loc
O.ClearWet()
if(O.air)
var/datum/gas_mixture/G = O.air
G.temperature = 293.15
for(var/obj/effect/hotspot/H in O)
qdel(H)
var/list/G_gases = G.gases
for(var/I in G_gases)
if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen)
continue
G_gases[I] = 0
GAS_GARBAGE_COLLECT(G.gases)
O.air_update_turf()
for(var/obj/machinery/atmospherics/components/unary/U in O)
if(!U.welded)
U.welded = TRUE
U.update_icon()
U.visible_message("<span class='danger'>[U] sealed shut!</span>")
for(var/mob/living/L in O)
L.ExtinguishMob()
for(var/obj/item/Item in O)
Item.extinguish()
/obj/structure/foamedmetal/resin/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return TRUE
. = ..()
#undef ALUMINUM_FOAM
#undef IRON_FOAM
#undef RESIN_FOAM
// Foam
// Similar to smoke, but slower and mobs absorb its reagent through their exposed skin.
#define ALUMINUM_FOAM 1
#define IRON_FOAM 2
#define RESIN_FOAM 3
/obj/effect/particle_effect/foam
name = "foam"
icon_state = "foam"
opacity = 0
anchored = TRUE
density = FALSE
layer = EDGED_TURF_LAYER
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/amount = 3
animate_movement = 0
var/metal = 0
var/lifetime = 40
var/reagent_divisor = 7
var/static/list/blacklisted_turfs = typecacheof(list(
/turf/open/space/transit,
/turf/open/chasm,
/turf/open/lava))
/obj/effect/particle_effect/foam/firefighting
name = "firefighting foam"
lifetime = 20 //doesn't last as long as normal foam
amount = 0 //no spread
var/absorbed_plasma = 0
/obj/effect/particle_effect/foam/firefighting/MakeSlippery()
return
/obj/effect/particle_effect/foam/firefighting/process()
..()
var/turf/open/T = get_turf(src)
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
if(hotspot && istype(T) && T.air)
qdel(hotspot)
var/datum/gas_mixture/G = T.air
var/plas_amt = min(30,G.gases[/datum/gas/plasma]) //Absorb some plasma
G.gases[/datum/gas/plasma] -= plas_amt
absorbed_plasma += plas_amt
if(G.temperature > T20C)
G.temperature = max(G.temperature/2,T20C)
GAS_GARBAGE_COLLECT(G.gases)
T.air_update_turf()
/obj/effect/particle_effect/foam/firefighting/kill_foam()
STOP_PROCESSING(SSfastprocess, src)
if(absorbed_plasma)
var/obj/effect/decal/cleanable/plasma/P = (locate(/obj/effect/decal/cleanable/plasma) in get_turf(src))
if(!P)
P = new(loc)
P.reagents.add_reagent(/datum/reagent/stable_plasma, absorbed_plasma)
flick("[icon_state]-disolve", src)
QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/firefighting/foam_mob(mob/living/L)
if(!istype(L))
return
L.adjust_fire_stacks(-2)
L.ExtinguishMob()
/obj/effect/particle_effect/foam/firefighting/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
/obj/effect/particle_effect/foam/metal
name = "aluminium foam"
metal = ALUMINUM_FOAM
icon_state = "mfoam"
/obj/effect/particle_effect/foam/metal/MakeSlippery()
return
/obj/effect/particle_effect/foam/metal/smart
name = "smart foam"
/obj/effect/particle_effect/foam/metal/iron
name = "iron foam"
metal = IRON_FOAM
/obj/effect/particle_effect/foam/metal/resin
name = "resin foam"
metal = RESIN_FOAM
/obj/effect/particle_effect/foam/long_life
lifetime = 150
/obj/effect/particle_effect/foam/Initialize()
. = ..()
MakeSlippery()
create_reagents(1000) //limited by the size of the reagent holder anyway.
START_PROCESSING(SSfastprocess, src)
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
/obj/effect/particle_effect/foam/proc/MakeSlippery()
AddComponent(/datum/component/slippery, 100)
/obj/effect/particle_effect/foam/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()
/obj/effect/particle_effect/foam/proc/kill_foam()
STOP_PROCESSING(SSfastprocess, src)
switch(metal)
if(ALUMINUM_FOAM)
new /obj/structure/foamedmetal(get_turf(src))
if(IRON_FOAM)
new /obj/structure/foamedmetal/iron(get_turf(src))
if(RESIN_FOAM)
new /obj/structure/foamedmetal/resin(get_turf(src))
flick("[icon_state]-disolve", src)
QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/smart/kill_foam() //Smart foam adheres to area borders for walls
STOP_PROCESSING(SSfastprocess, src)
if(metal)
var/turf/T = get_turf(src)
if(isspaceturf(T)) //Block up any exposed space
T.PlaceOnTop(/turf/open/floor/plating/foam)
for(var/direction in GLOB.cardinals)
var/turf/cardinal_turf = get_step(T, direction)
if(get_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf!
new/obj/structure/foamedmetal(T)
break
flick("[icon_state]-disolve", src)
QDEL_IN(src, 5)
/obj/effect/particle_effect/foam/process()
lifetime--
if(lifetime < 1)
kill_foam()
return
var/fraction = 1/initial(reagent_divisor)
for(var/obj/O in range(0,src))
if(O.type == src.type)
continue
if(isturf(O.loc))
var/turf/T = O.loc
if(T.intact && O.level == 1) //hidden under the floor
continue
if(lifetime % reagent_divisor)
reagents.reaction(O, VAPOR, fraction)
var/hit = 0
for(var/mob/living/L in range(0,src))
hit += foam_mob(L)
if(hit)
lifetime++ //this is so the decrease from mobs hit and the natural decrease don't cumulate.
var/T = get_turf(src)
if(lifetime % reagent_divisor)
reagents.reaction(T, VAPOR, fraction)
if(--amount < 0)
return
spread_foam()
/obj/effect/particle_effect/foam/proc/foam_mob(mob/living/L)
if(lifetime<1)
return 0
if(!istype(L))
return 0
var/fraction = 1/initial(reagent_divisor)
if(lifetime % reagent_divisor)
reagents.reaction(L, VAPOR, fraction)
lifetime--
return 1
/obj/effect/particle_effect/foam/proc/spread_foam()
var/turf/t_loc = get_turf(src)
for(var/turf/T in t_loc.GetAtmosAdjacentTurfs())
var/obj/effect/particle_effect/foam/foundfoam = locate() in T //Don't spread foam where there's already foam!
if(foundfoam)
continue
if(is_type_in_typecache(T, blacklisted_turfs))
continue
for(var/mob/living/L in T)
foam_mob(L)
var/obj/effect/particle_effect/foam/F = new src.type(T)
F.amount = amount
reagents.copy_to(F, (reagents.total_volume))
F.add_atom_colour(color, FIXED_COLOUR_PRIORITY)
F.metal = metal
/obj/effect/particle_effect/foam/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(prob(max(0, exposed_temperature - 475))) //foam dissolves when heated
kill_foam()
/obj/effect/particle_effect/foam/metal/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
///////////////////////////////////////////////
//FOAM EFFECT DATUM
/datum/effect_system/foam_spread
var/amount = 10 // the size of the foam spread.
var/obj/chemholder
effect_type = /obj/effect/particle_effect/foam
var/metal = 0
/datum/effect_system/foam_spread/metal
effect_type = /obj/effect/particle_effect/foam/metal
/datum/effect_system/foam_spread/metal/smart
effect_type = /obj/effect/particle_effect/foam/smart
/datum/effect_system/foam_spread/long
effect_type = /obj/effect/particle_effect/foam/long_life
/datum/effect_system/foam_spread/New()
..()
chemholder = new /obj()
var/datum/reagents/R = new/datum/reagents(1000)
chemholder.reagents = R
R.my_atom = chemholder
/datum/effect_system/foam_spread/Destroy()
qdel(chemholder)
chemholder = null
return ..()
/datum/effect_system/foam_spread/set_up(amt=5, loca, datum/reagents/carry = null)
if(isturf(loca))
location = loca
else
location = get_turf(loca)
amount = round(sqrt(amt / 2), 1)
carry.copy_to(chemholder, carry.total_volume)
/datum/effect_system/foam_spread/metal/set_up(amt=5, loca, datum/reagents/carry = null, metaltype)
..()
metal = metaltype
/datum/effect_system/foam_spread/start()
var/obj/effect/particle_effect/foam/F = new effect_type(location)
var/foamcolor = mix_color_from_reagents(chemholder.reagents.reagent_list)
chemholder.reagents.copy_to(F, chemholder.reagents.total_volume/amount)
F.add_atom_colour(foamcolor, FIXED_COLOUR_PRIORITY)
F.amount = amount
F.metal = metal
//////////////////////////////////////////////////////////
// FOAM STRUCTURE. Formed by metal foams. Dense and opaque, but easy to break
/obj/structure/foamedmetal
icon = 'icons/effects/effects.dmi'
icon_state = "metalfoam"
density = TRUE
opacity = 1 // changed in New()
anchored = TRUE
layer = EDGED_TURF_LAYER
resistance_flags = FIRE_PROOF | ACID_PROOF
name = "foamed metal"
desc = "A lightweight foamed metal wall."
gender = PLURAL
max_integrity = 20
CanAtmosPass = ATMOS_PASS_DENSITY
/obj/structure/foamedmetal/Initialize()
. = ..()
air_update_turf(1)
/obj/structure/foamedmetal/Move()
var/turf/T = loc
. = ..()
move_update_air(T)
/obj/structure/foamedmetal/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/attack_hand(mob/user)
. = ..()
if(.)
return
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
to_chat(user, "<span class='warning'>You hit [src] but bounce off it!</span>")
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target)
return !density
/obj/structure/foamedmetal/iron
max_integrity = 50
icon_state = "ironfoam"
//Atmos Backpack Resin, transparent, prevents atmos and filters the air
/obj/structure/foamedmetal/resin
name = "\improper ATMOS Resin"
desc = "A lightweight, transparent resin used to suffocate fires, scrub the air of toxins, and restore the air to a safe temperature."
opacity = FALSE
icon_state = "atmos_resin"
alpha = 120
max_integrity = 10
/obj/structure/foamedmetal/resin/Initialize()
. = ..()
if(isopenturf(loc))
var/turf/open/O = loc
O.ClearWet()
if(O.air)
var/datum/gas_mixture/G = O.air
G.temperature = 293.15
for(var/obj/effect/hotspot/H in O)
qdel(H)
var/list/G_gases = G.gases
for(var/I in G_gases)
if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen)
continue
G_gases[I] = 0
GAS_GARBAGE_COLLECT(G.gases)
O.air_update_turf()
for(var/obj/machinery/atmospherics/components/unary/U in O)
if(!U.welded)
U.welded = TRUE
U.update_icon()
U.visible_message("<span class='danger'>[U] sealed shut!</span>")
for(var/mob/living/L in O)
L.ExtinguishMob()
for(var/obj/item/Item in O)
Item.extinguish()
/obj/structure/foamedmetal/resin/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return TRUE
. = ..()
#undef ALUMINUM_FOAM
#undef IRON_FOAM
#undef RESIN_FOAM
+176 -176
View File
@@ -1,176 +1,176 @@
/obj/effect/mine
name = "dummy mine"
desc = "Better stay away from that thing."
density = FALSE
anchored = TRUE
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "uglymine"
var/triggered = 0
/obj/effect/mine/proc/mineEffect(mob/victim)
to_chat(victim, "<span class='danger'>*click*</span>")
/obj/effect/mine/Crossed(AM as mob|obj)
if(isturf(loc))
if(ismob(AM))
var/mob/MM = AM
if(!(MM.movement_type & FLYING))
triggermine(AM)
else
triggermine(AM)
/obj/effect/mine/proc/triggermine(mob/victim)
if(triggered)
return
visible_message("<span class='danger'>[victim] sets off [icon2html(src, viewers(src))] [src]!</span>")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, src)
s.start()
mineEffect(victim)
triggered = 1
qdel(src)
/obj/effect/mine/explosive
name = "explosive mine"
var/range_devastation = 0
var/range_heavy = 1
var/range_light = 2
var/range_flash = 3
/obj/effect/mine/explosive/mineEffect(mob/victim)
explosion(loc, range_devastation, range_heavy, range_light, range_flash)
/obj/effect/mine/stun
name = "stun mine"
var/stun_time = 80
/obj/effect/mine/stun/mineEffect(mob/living/victim)
if(isliving(victim))
victim.Knockdown(stun_time)
/obj/effect/mine/kickmine
name = "kick mine"
/obj/effect/mine/kickmine/mineEffect(mob/victim)
if(isliving(victim) && victim.client)
to_chat(victim, "<span class='userdanger'>You have been kicked FOR NO REISIN!</span>")
qdel(victim.client)
/obj/effect/mine/gas
name = "oxygen mine"
var/gas_amount = 360
var/gas_type = "o2"
/obj/effect/mine/gas/mineEffect(mob/victim)
atmos_spawn_air("[gas_type]=[gas_amount]")
/obj/effect/mine/gas/plasma
name = "plasma mine"
gas_type = "plasma"
/obj/effect/mine/gas/n2o
name = "\improper N2O mine"
gas_type = "n2o"
/obj/effect/mine/sound
name = "honkblaster 1000"
var/sound = 'sound/items/bikehorn.ogg'
/obj/effect/mine/sound/mineEffect(mob/victim)
playsound(loc, sound, 100, 1)
/obj/effect/mine/sound/bwoink
name = "bwoink mine"
sound = 'sound/effects/adminhelp.ogg'
/obj/effect/mine/pickup
name = "pickup"
desc = "pick me up"
icon = 'icons/effects/effects.dmi'
icon_state = "electricity2"
density = FALSE
var/duration = 0
/obj/effect/mine/pickup/Initialize()
. = ..()
animate(src, pixel_y = 4, time = 20, loop = -1)
/obj/effect/mine/pickup/triggermine(mob/victim)
if(triggered)
return
triggered = 1
invisibility = INVISIBILITY_ABSTRACT
mineEffect(victim)
qdel(src)
/obj/effect/mine/pickup/bloodbath
name = "Red Orb"
desc = "You feel angry just looking at it."
duration = 1200 //2min
color = "#FF0000"
/obj/effect/mine/pickup/bloodbath/mineEffect(mob/living/carbon/victim)
if(!victim.client || !istype(victim))
return
to_chat(victim, "<span class='reallybig redtext'>RIP AND TEAR</span>")
var/old_color = victim.client.color
var/static/list/red_splash = list(1,0,0,0.8,0.2,0, 0.8,0,0.2,0.1,0,0)
var/static/list/pure_red = list(0,0,0,0,0,0,0,0,0,1,0,0)
spawn(0)
new /datum/hallucination/delusion(victim, TRUE, "demon",duration,0)
var/obj/item/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc)
victim.log_message("entered a blood frenzy", LOG_ATTACK)
ADD_TRAIT(chainsaw, TRAIT_NODROP, CHAINSAW_FRENZY_TRAIT)
victim.drop_all_held_items()
victim.put_in_hands(chainsaw, forced = TRUE)
chainsaw.attack_self(victim)
chainsaw.wield(victim)
victim.reagents.add_reagent("adminordrazine",25)
to_chat(victim, "<span class='warning'>KILL, KILL, KILL! YOU HAVE NO ALLIES ANYMORE, KILL THEM ALL!</span>")
victim.client.color = pure_red
animate(victim.client,color = red_splash, time = 10, easing = SINE_EASING|EASE_OUT)
sleep(10)
animate(victim.client,color = old_color, time = duration)//, easing = SINE_EASING|EASE_OUT)
sleep(duration)
to_chat(victim, "<span class='notice'>Your bloodlust seeps back into the bog of your subconscious and you regain self control.</span>")
qdel(chainsaw)
victim.log_message("exited a blood frenzy", LOG_ATTACK)
qdel(src)
/obj/effect/mine/pickup/healing
name = "Blue Orb"
desc = "You feel better just looking at it."
color = "#0000FF"
/obj/effect/mine/pickup/healing/mineEffect(mob/living/carbon/victim)
if(!victim.client || !istype(victim))
return
to_chat(victim, "<span class='notice'>You feel great!</span>")
victim.revive(full_heal = 1, admin_revive = 1)
/obj/effect/mine/pickup/speed
name = "Yellow Orb"
desc = "You feel faster just looking at it."
color = "#FFFF00"
duration = 300
/obj/effect/mine/pickup/speed/mineEffect(mob/living/carbon/victim)
if(!victim.client || !istype(victim))
return
to_chat(victim, "<span class='notice'>You feel fast!</span>")
ADD_TRAIT(victim, TRAIT_GOTTAGOREALLYFAST, "yellow_orb")
sleep(duration)
REMOVE_TRAIT(victim, TRAIT_GOTTAGOREALLYFAST, "yellow_orb")
to_chat(victim, "<span class='notice'>You slow down.</span>")
/obj/effect/mine
name = "dummy mine"
desc = "Better stay away from that thing."
density = FALSE
anchored = TRUE
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "uglymine"
var/triggered = 0
/obj/effect/mine/proc/mineEffect(mob/victim)
to_chat(victim, "<span class='danger'>*click*</span>")
/obj/effect/mine/Crossed(AM as mob|obj)
if(isturf(loc))
if(ismob(AM))
var/mob/MM = AM
if(!(MM.movement_type & FLYING))
triggermine(AM)
else
triggermine(AM)
/obj/effect/mine/proc/triggermine(mob/victim)
if(triggered)
return
visible_message("<span class='danger'>[victim] sets off [icon2html(src, viewers(src))] [src]!</span>")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, src)
s.start()
mineEffect(victim)
triggered = 1
qdel(src)
/obj/effect/mine/explosive
name = "explosive mine"
var/range_devastation = 0
var/range_heavy = 1
var/range_light = 2
var/range_flash = 3
/obj/effect/mine/explosive/mineEffect(mob/victim)
explosion(loc, range_devastation, range_heavy, range_light, range_flash)
/obj/effect/mine/stun
name = "stun mine"
var/stun_time = 80
/obj/effect/mine/stun/mineEffect(mob/living/victim)
if(isliving(victim))
victim.Knockdown(stun_time)
/obj/effect/mine/kickmine
name = "kick mine"
/obj/effect/mine/kickmine/mineEffect(mob/victim)
if(isliving(victim) && victim.client)
to_chat(victim, "<span class='userdanger'>You have been kicked FOR NO REISIN!</span>")
qdel(victim.client)
/obj/effect/mine/gas
name = "oxygen mine"
var/gas_amount = 360
var/gas_type = "o2"
/obj/effect/mine/gas/mineEffect(mob/victim)
atmos_spawn_air("[gas_type]=[gas_amount]")
/obj/effect/mine/gas/plasma
name = "plasma mine"
gas_type = "plasma"
/obj/effect/mine/gas/n2o
name = "\improper N2O mine"
gas_type = "n2o"
/obj/effect/mine/sound
name = "honkblaster 1000"
var/sound = 'sound/items/bikehorn.ogg'
/obj/effect/mine/sound/mineEffect(mob/victim)
playsound(loc, sound, 100, 1)
/obj/effect/mine/sound/bwoink
name = "bwoink mine"
sound = 'sound/effects/adminhelp.ogg'
/obj/effect/mine/pickup
name = "pickup"
desc = "pick me up"
icon = 'icons/effects/effects.dmi'
icon_state = "electricity2"
density = FALSE
var/duration = 0
/obj/effect/mine/pickup/Initialize()
. = ..()
animate(src, pixel_y = 4, time = 20, loop = -1)
/obj/effect/mine/pickup/triggermine(mob/victim)
if(triggered)
return
triggered = 1
invisibility = INVISIBILITY_ABSTRACT
mineEffect(victim)
qdel(src)
/obj/effect/mine/pickup/bloodbath
name = "Red Orb"
desc = "You feel angry just looking at it."
duration = 1200 //2min
color = "#FF0000"
/obj/effect/mine/pickup/bloodbath/mineEffect(mob/living/carbon/victim)
if(!victim.client || !istype(victim))
return
to_chat(victim, "<span class='reallybig redtext'>RIP AND TEAR</span>")
var/old_color = victim.client.color
var/static/list/red_splash = list(1,0,0,0.8,0.2,0, 0.8,0,0.2,0.1,0,0)
var/static/list/pure_red = list(0,0,0,0,0,0,0,0,0,1,0,0)
spawn(0)
new /datum/hallucination/delusion(victim, TRUE, "demon",duration,0)
var/obj/item/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc)
victim.log_message("entered a blood frenzy", LOG_ATTACK)
ADD_TRAIT(chainsaw, TRAIT_NODROP, CHAINSAW_FRENZY_TRAIT)
victim.drop_all_held_items()
victim.put_in_hands(chainsaw, forced = TRUE)
chainsaw.attack_self(victim)
chainsaw.wield(victim)
victim.reagents.add_reagent(/datum/reagent/medicine/adminordrazine,25)
to_chat(victim, "<span class='warning'>KILL, KILL, KILL! YOU HAVE NO ALLIES ANYMORE, KILL THEM ALL!</span>")
victim.client.color = pure_red
animate(victim.client,color = red_splash, time = 10, easing = SINE_EASING|EASE_OUT)
sleep(10)
animate(victim.client,color = old_color, time = duration)//, easing = SINE_EASING|EASE_OUT)
sleep(duration)
to_chat(victim, "<span class='notice'>Your bloodlust seeps back into the bog of your subconscious and you regain self control.</span>")
qdel(chainsaw)
victim.log_message("exited a blood frenzy", LOG_ATTACK)
qdel(src)
/obj/effect/mine/pickup/healing
name = "Blue Orb"
desc = "You feel better just looking at it."
color = "#0000FF"
/obj/effect/mine/pickup/healing/mineEffect(mob/living/carbon/victim)
if(!victim.client || !istype(victim))
return
to_chat(victim, "<span class='notice'>You feel great!</span>")
victim.revive(full_heal = 1, admin_revive = 1)
/obj/effect/mine/pickup/speed
name = "Yellow Orb"
desc = "You feel faster just looking at it."
color = "#FFFF00"
duration = 300
/obj/effect/mine/pickup/speed/mineEffect(mob/living/carbon/victim)
if(!victim.client || !istype(victim))
return
to_chat(victim, "<span class='notice'>You feel fast!</span>")
ADD_TRAIT(victim, TRAIT_GOTTAGOREALLYFAST, "yellow_orb")
sleep(duration)
REMOVE_TRAIT(victim, TRAIT_GOTTAGOREALLYFAST, "yellow_orb")
to_chat(victim, "<span class='notice'>You slow down.</span>")
@@ -315,6 +315,11 @@
randomdir = 0
duration = 6
/obj/effect/temp_visual/desynchronizer
name = "desynchronizer field"
icon_state = "chronofield"
duration = 3
/obj/effect/temp_visual/impact_effect
icon_state = "impact_bullet"
duration = 5
@@ -438,6 +443,13 @@
else
return INITIALIZE_HINT_QDEL
/obj/effect/temp_visual/slugboom
icon = 'icons/effects/96x96.dmi'
icon_state = "slugboom"
randomdir = FALSE
duration = 30
pixel_x = -24
/obj/effect/constructing_effect
icon = 'icons/effects/effects_rcd.dmi'
icon_state = ""
@@ -477,4 +489,4 @@
addtimer(CALLBACK(src, .proc/end), 15)
/obj/effect/constructing_effect/proc/end()
qdel(src)
qdel(src)
+3 -1
View File
@@ -213,7 +213,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/list/boostable_nodes = techweb_item_boost_check(src)
if (boostable_nodes)
for(var/id in boostable_nodes)
var/datum/techweb_node/node = SSresearch.techweb_nodes[id]
var/datum/techweb_node/node = SSresearch.techweb_node_by_id(id)
if(!node)
continue
research_msg += sep
research_msg += node.display_name
sep = ", "
+2 -2
View File
@@ -47,9 +47,9 @@ RLD
/obj/item/construction/examine(mob/user)
. = ..()
. += "\A [src]. It currently holds [matter]/[max_matter] matter-units."
. += "It currently holds [matter]/[max_matter] matter-units."
if(upgrade & RCD_UPGRADE_FRAMES)
. += "It contains the design for machine frames, computer frames and deconstruction."
. += "It contains the design for machine frames, computer frames and deconstruction."
if(upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)
. += "It contains the design for firelock, air alarm, fire alarm, apc circuits and crap power cells."
+3 -4
View File
@@ -249,7 +249,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/pipes)
assets.send(user)
ui = new(user, src, ui_key, "rpd", name, 425, 515, master_ui, state)
ui = new(user, src, ui_key, "rpd", name, 425, 472, master_ui, state)
ui.open()
/obj/item/pipe_dispenser/ui_data(mob/user)
@@ -316,9 +316,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
playeffect = FALSE
if("mode")
var/n = text2num(params["mode"])
if(n == 2 && !(mode&1) && !(mode&2))
mode |= 3
else if(mode&n)
if(mode & n)
mode &= ~n
else
mode |= n
@@ -327,6 +325,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
spark_system.start()
effectcooldown = world.time + 100
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
return TRUE
/obj/item/pipe_dispenser/pre_attack(atom/A, mob/user)
if(!user.IsAdvancedToolUser() || istype(A, /turf/open/space/transit))
+1 -1
View File
@@ -180,7 +180,7 @@ RSF
to_chat(user, "Fabricating Cookie..")
var/obj/item/reagent_containers/food/snacks/cookie/S = new /obj/item/reagent_containers/food/snacks/cookie(T)
if(toxin)
S.reagents.add_reagent("chloralhydratedelayed", 10)
S.reagents.add_reagent(/datum/reagent/toxin/chloralhydrate, 10)
if (iscyborg(user))
var/mob/living/silicon/robot/R = user
R.cell.charge -= 100
+126 -126
View File
@@ -1,126 +1,126 @@
/obj/item/airlock_painter
name = "airlock painter"
desc = "An advanced autopainter preprogrammed with several paintjobs for airlocks. Use it on an airlock during or after construction to change the paintjob."
icon = 'icons/obj/objects.dmi'
icon_state = "paint sprayer"
item_state = "paint sprayer"
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=50, MAT_GLASS=50)
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
slot_flags = ITEM_SLOT_BELT
usesound = 'sound/effects/spray2.ogg'
var/obj/item/toner/ink = null
/obj/item/airlock_painter/Initialize()
. = ..()
ink = new /obj/item/toner(src)
//This proc doesn't just check if the painter can be used, but also uses it.
//Only call this if you are certain that the painter will be used right after this check!
/obj/item/airlock_painter/proc/use_paint(mob/user)
if(can_use(user))
ink.charges--
playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1)
return 1
else
return 0
//This proc only checks if the painter can be used.
//Call this if you don't want the painter to be used right after this check, for example
//because you're expecting user input.
/obj/item/airlock_painter/proc/can_use(mob/user)
if(!ink)
to_chat(user, "<span class='notice'>There is no toner cartridge installed in [src]!</span>")
return 0
else if(ink.charges < 1)
to_chat(user, "<span class='notice'>[src] is out of ink!</span>")
return 0
else
return 1
/obj/item/airlock_painter/suicide_act(mob/user)
var/obj/item/organ/lungs/L = user.getorganslot(ORGAN_SLOT_LUNGS)
if(can_use(user) && L)
user.visible_message("<span class='suicide'>[user] is inhaling toner from [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
use(user)
// Once you've inhaled the toner, you throw up your lungs
// and then die.
// Find out if there is an open turf in front of us,
// and if not, pick the turf we are standing on.
var/turf/T = get_step(get_turf(src), user.dir)
if(!isopenturf(T))
T = get_turf(src)
// they managed to lose their lungs between then and
// now. Good job.
if(!L)
return OXYLOSS
L.Remove(user)
// make some colorful reagent, and apply it to the lungs
L.create_reagents(10)
L.reagents.add_reagent("colorful_reagent", 10)
L.reagents.reaction(L, TOUCH, 1)
// TODO maybe add some colorful vomit?
user.visible_message("<span class='suicide'>[user] vomits out [user.p_their()] [L]!</span>")
playsound(user.loc, 'sound/effects/splat.ogg', 50, 1)
L.forceMove(T)
return (TOXLOSS|OXYLOSS)
else if(can_use(user) && !L)
user.visible_message("<span class='suicide'>[user] is spraying toner on [user.p_them()]self from [src]! It looks like [user.p_theyre()] trying to commit suicide.</span>")
user.reagents.add_reagent("colorful_reagent", 1)
user.reagents.reaction(user, TOUCH, 1)
return TOXLOSS
else
user.visible_message("<span class='suicide'>[user] is trying to inhale toner from [src]! It might be a suicide attempt if [src] had any toner.</span>")
return SHAME
/obj/item/airlock_painter/examine(mob/user)
. = ..()
if(!ink)
. += "<span class='notice'>It doesn't have a toner cartridge installed.</span>"
return
var/ink_level = "high"
if(ink.charges < 1)
ink_level = "empty"
else if((ink.charges/ink.max_charges) <= 0.25) //25%
ink_level = "low"
else if((ink.charges/ink.max_charges) > 1) //Over 100% (admin var edit)
ink_level = "dangerously high"
. += "<span class='notice'>Its ink levels look [ink_level].</span>"
/obj/item/airlock_painter/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/toner))
if(ink)
to_chat(user, "<span class='notice'>[src] already contains \a [ink].</span>")
return
if(!user.transferItemToLoc(W, src))
return
to_chat(user, "<span class='notice'>You install [W] into [src].</span>")
ink = W
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
else
return ..()
/obj/item/airlock_painter/attack_self(mob/user)
if(ink)
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
ink.forceMove(user.drop_location())
user.put_in_hands(ink)
to_chat(user, "<span class='notice'>You remove [ink] from [src].</span>")
ink = null
/obj/item/airlock_painter
name = "airlock painter"
desc = "An advanced autopainter preprogrammed with several paintjobs for airlocks. Use it on an airlock during or after construction to change the paintjob."
icon = 'icons/obj/objects.dmi'
icon_state = "paint sprayer"
item_state = "paint sprayer"
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=50, MAT_GLASS=50)
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
slot_flags = ITEM_SLOT_BELT
usesound = 'sound/effects/spray2.ogg'
var/obj/item/toner/ink = null
/obj/item/airlock_painter/Initialize()
. = ..()
ink = new /obj/item/toner(src)
//This proc doesn't just check if the painter can be used, but also uses it.
//Only call this if you are certain that the painter will be used right after this check!
/obj/item/airlock_painter/proc/use_paint(mob/user)
if(can_use(user))
ink.charges--
playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1)
return 1
else
return 0
//This proc only checks if the painter can be used.
//Call this if you don't want the painter to be used right after this check, for example
//because you're expecting user input.
/obj/item/airlock_painter/proc/can_use(mob/user)
if(!ink)
to_chat(user, "<span class='notice'>There is no toner cartridge installed in [src]!</span>")
return 0
else if(ink.charges < 1)
to_chat(user, "<span class='notice'>[src] is out of ink!</span>")
return 0
else
return 1
/obj/item/airlock_painter/suicide_act(mob/user)
var/obj/item/organ/lungs/L = user.getorganslot(ORGAN_SLOT_LUNGS)
if(can_use(user) && L)
user.visible_message("<span class='suicide'>[user] is inhaling toner from [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
use(user)
// Once you've inhaled the toner, you throw up your lungs
// and then die.
// Find out if there is an open turf in front of us,
// and if not, pick the turf we are standing on.
var/turf/T = get_step(get_turf(src), user.dir)
if(!isopenturf(T))
T = get_turf(src)
// they managed to lose their lungs between then and
// now. Good job.
if(!L)
return OXYLOSS
L.Remove(user)
// make some colorful reagent, and apply it to the lungs
L.create_reagents(10)
L.reagents.add_reagent(/datum/reagent/colorful_reagent, 10)
L.reagents.reaction(L, TOUCH, 1)
// TODO maybe add some colorful vomit?
user.visible_message("<span class='suicide'>[user] vomits out [user.p_their()] [L]!</span>")
playsound(user.loc, 'sound/effects/splat.ogg', 50, 1)
L.forceMove(T)
return (TOXLOSS|OXYLOSS)
else if(can_use(user) && !L)
user.visible_message("<span class='suicide'>[user] is spraying toner on [user.p_them()]self from [src]! It looks like [user.p_theyre()] trying to commit suicide.</span>")
user.reagents.add_reagent(/datum/reagent/colorful_reagent, 1)
user.reagents.reaction(user, TOUCH, 1)
return TOXLOSS
else
user.visible_message("<span class='suicide'>[user] is trying to inhale toner from [src]! It might be a suicide attempt if [src] had any toner.</span>")
return SHAME
/obj/item/airlock_painter/examine(mob/user)
. = ..()
if(!ink)
. += "<span class='notice'>It doesn't have a toner cartridge installed.</span>"
return
var/ink_level = "high"
if(ink.charges < 1)
ink_level = "empty"
else if((ink.charges/ink.max_charges) <= 0.25) //25%
ink_level = "low"
else if((ink.charges/ink.max_charges) > 1) //Over 100% (admin var edit)
ink_level = "dangerously high"
. += "<span class='notice'>Its ink levels look [ink_level].</span>"
/obj/item/airlock_painter/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/toner))
if(ink)
to_chat(user, "<span class='notice'>[src] already contains \a [ink].</span>")
return
if(!user.transferItemToLoc(W, src))
return
to_chat(user, "<span class='notice'>You install [W] into [src].</span>")
ink = W
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
else
return ..()
/obj/item/airlock_painter/attack_self(mob/user)
if(ink)
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
ink.forceMove(user.drop_location())
user.put_in_hands(ink)
to_chat(user, "<span class='notice'>You remove [ink] from [src].</span>")
ink = null
+1 -1
View File
@@ -120,4 +120,4 @@
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=50, MAT_GLASS=50)
grind_results = list("iron" = 10, "silicon" = 10)
grind_results = list(/datum/reagent/iron = 10, /datum/reagent/silicon = 10)
+20 -14
View File
@@ -217,9 +217,11 @@ update_label("John Doe", "Clowny")
/obj/item/card/id/proc/update_label(newname, newjob)
if(newname || newjob)
name = "[(!newname) ? "identification card" : "[newname]'s ID Card"][(!newjob) ? "" : " ([newjob])"]"
update_icon()
return
name = "[(!registered_name) ? "identification card" : "[registered_name]'s ID Card"][(!assignment) ? "" : " ([assignment])"]"
update_icon()
/obj/item/card/id/silver
name = "silver identification card"
@@ -269,18 +271,21 @@ update_label("John Doe", "Clowny")
if(isliving(user) && user.mind)
if(user.mind.special_role || anyone)
if(alert(user, "Action", "Agent ID", "Show", "Forge") == "Forge")
var/t = copytext(sanitize(input(user, "What name would you like to put on this card?", "Agent card name", registered_name ? registered_name : (ishuman(user) ? user.real_name : user.name))as text | null),1,26)
if(!t || t == "Unknown" || t == "floor" || t == "wall" || t == "r-wall") //Same as mob/dead/new_player/prefrences.dm
if (t)
alert("Invalid name.")
var/input_name = stripped_input(user, "What name would you like to put on this card? Leave blank to randomise.", "Agent card name", registered_name ? registered_name : (ishuman(user) ? user.real_name : user.name), MAX_NAME_LEN)
input_name = reject_bad_name(input_name, TRUE)
if(!input_name)
// Invalid/blank names give a randomly generated one.
if(user.gender == MALE)
input_name = "[pick(GLOB.first_names_male)] [pick(GLOB.last_names)]"
else if(user.gender == FEMALE)
input_name = "[pick(GLOB.first_names_female)] [pick(GLOB.last_names)]"
else
input_name = "[pick(GLOB.first_names_male)] [pick(GLOB.last_names)]"
var/target_occupation = stripped_input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", assignment ? assignment : "Assistant", MAX_MESSAGE_LEN)
if(!target_occupation)
return
registered_name = t
var/u = copytext(sanitize(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Assistant")as text | null),1,MAX_MESSAGE_LEN)
if(!u)
registered_name = ""
return
assignment = u
registered_name = input_name
assignment = target_occupation
update_label()
to_chat(user, "<span class='notice'>You successfully forge the ID card.</span>")
return
@@ -517,16 +522,17 @@ update_label("John Doe", "Clowny")
return
if(user.incapacitated() || !istype(user))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
return TRUE
if(alert("Are you sure you want to recolor your id?", "Confirm Repaint", "Yes", "No") == "Yes")
var/energy_color_input = input(usr,"","Choose Energy Color",id_color) as color|null
if(!in_range(src, user) || !energy_color_input)
return
return TRUE
if(user.incapacitated() || !istype(user))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
return TRUE
id_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
update_icon()
return TRUE
/obj/item/card/id/knight/Initialize()
. = ..()
+1 -1
View File
@@ -119,7 +119,7 @@
minor_announce("[ureal_name] has designated the planet as [station_name()]", "Captain's Banner", 0)
log_game("[ukey] has renamed the planet as [station_name()].")
name = "banner of [station_name()]"
desc = "The banner bears the official coat of arms of Nanotrasen, signifying that [station_name()] has been claimed by Captain [uname] in the name of the company."
desc = "The banner bears the official coat of arms of Kinaris, signifying that [station_name()] has been claimed by Captain [uname] in the name of the company."
SSblackbox.record_feedback("text", "station_renames", 1, "[station_name()]")
if(!unlimited_uses)
used = TRUE
File diff suppressed because it is too large Load Diff
@@ -12,7 +12,7 @@
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
materials = list(MAT_GLASS=1000)
w_class = WEIGHT_CLASS_SMALL
grind_results = list("silicon" = 20)
grind_results = list(/datum/reagent/silicon = 20)
var/build_path = null
/obj/item/circuitboard/proc/apply_default_parts(obj/machinery/M)
@@ -247,7 +247,7 @@
build_path = /obj/machinery/computer/cargo/request
/obj/item/circuitboard/computer/bounty
name = "Nanotrasen Bounty Console (Computer Board)"
name = "Kinaris Bounty Console (Computer Board)"
build_path = /obj/machinery/computer/bounty
/obj/item/circuitboard/computer/operating
@@ -974,10 +974,12 @@
to_chat(user, "<span class='notice'>You [suction ? "enable" : "disable"] the board's suction function.</span>")
/obj/item/circuitboard/machine/dish_drive/AltClick(mob/living/user)
. = ..()
if(!user.Adjacent(src))
return
transmit = !transmit
to_chat(user, "<span class='notice'>You [transmit ? "enable" : "disable"] the board's automatic disposal transmission.</span>")
return TRUE
/obj/item/circuitboard/machine/stacking_unit_console
name = "Stacking Machine Console (Machine Board)"
+172 -171
View File
@@ -1,171 +1,172 @@
/* Clown Items
* Contains:
* Soap
* Bike Horns
* Air Horns
* Canned Laughter
*/
/*
* Soap
*/
/obj/item/soap
name = "soap"
desc = "A cheap bar of soap. Doesn't smell."
gender = PLURAL
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "soap"
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
item_flags = NOBLUDGEON
throwforce = 0
throw_speed = 3
throw_range = 7
grind_results = list("lye" = 10)
var/cleanspeed = 50 //slower than mop
force_string = "robust... against germs"
/obj/item/soap/Initialize()
. = ..()
AddComponent(/datum/component/slippery, 80)
/obj/item/soap/nanotrasen
desc = "A Kinaris.Co brand bar of soap. Smells of plasma."
icon_state = "soapnt"
/obj/item/soap/homemade
desc = "A homemade bar of soap. Smells of... well...."
icon_state = "soapgibs"
cleanspeed = 45 // a little faster to reward chemists for going to the effort
/obj/item/soap/deluxe
desc = "A deluxe Waffle Co. brand bar of soap. Smells of high-class luxury."
icon_state = "soapdeluxe"
cleanspeed = 40 //same speed as mop because deluxe -- captain gets one of these
/obj/item/soap/syndie
desc = "An untrustworthy bar of soap made of strong chemical agents that dissolve blood faster."
icon_state = "soapsyndie"
cleanspeed = 10 //much faster than mop so it is useful for traitors who want to clean crime scenes
/obj/item/soap/suicide_act(mob/user)
user.say(";FFFFFFFFFFFFFFFFUUUUUUUDGE!!", forced="soap suicide")
user.visible_message("<span class='suicide'>[user] lifts [src] to [user.p_their()] mouth and gnaws on it furiously, producing a thick froth! [user.p_they(TRUE)]'ll never get that BB gun now!</span>")
new /obj/effect/particle_effect/foam(loc)
return (TOXLOSS)
/obj/item/soap/afterattack(atom/target, mob/user, proximity)
. = ..()
if(!proximity || !check_allowed_items(target))
return
//I couldn't feasibly fix the overlay bugs caused by cleaning items we are wearing.
//So this is a workaround. This also makes more sense from an IC standpoint. ~Carn
if(user.client && ((target in user.client.screen) && !user.is_holding(target)))
to_chat(user, "<span class='warning'>You need to take that [target.name] off before cleaning it!</span>")
else if(istype(target, /obj/effect/decal/cleanable))
user.visible_message("[user] begins to scrub \the [target.name] out with [src].", "<span class='warning'>You begin to scrub \the [target.name] out with [src]...</span>")
if(do_after(user, src.cleanspeed, target = target))
to_chat(user, "<span class='notice'>You scrub \the [target.name] out.</span>")
qdel(target)
else if(ishuman(target) && user.zone_selected == BODY_ZONE_PRECISE_MOUTH)
var/mob/living/carbon/human/H = user
user.visible_message("<span class='warning'>\the [user] washes \the [target]'s mouth out with [src.name]!</span>", "<span class='notice'>You wash \the [target]'s mouth out with [src.name]!</span>") //washes mouth out with soap sounds better than 'the soap' here
H.lip_style = null //removes lipstick
H.update_body()
return
else if(istype(target, /obj/structure/window))
user.visible_message("[user] begins to clean \the [target.name] with [src]...", "<span class='notice'>You begin to clean \the [target.name] with [src]...</span>")
if(do_after(user, src.cleanspeed, target = target))
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
target.set_opacity(initial(target.opacity))
else
user.visible_message("[user] begins to clean \the [target.name] with [src]...", "<span class='notice'>You begin to clean \the [target.name] with [src]...</span>")
if(do_after(user, src.cleanspeed, target = target))
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
var/obj/effect/decal/cleanable/C = locate() in target
qdel(C)
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
target.wash_cream()
return
/*
* Bike Horns
*/
/obj/item/bikehorn
name = "bike horn"
desc = "A horn off of a bicycle."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "bike_horn"
item_state = "bike_horn"
lefthand_file = 'icons/mob/inhands/equipment/horns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/horns_righthand.dmi'
throwforce = 0
hitsound = null //To prevent tap.ogg playing, as the item lacks of force
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
attack_verb = list("HONKED")
/obj/item/bikehorn/Initialize()
. = ..()
AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50)
/obj/item/bikehorn/attack(mob/living/carbon/M, mob/living/carbon/user)
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "honk", /datum/mood_event/honk)
return ..()
/obj/item/bikehorn/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] solemnly points the horn at [user.p_their()] temple! It looks like [user.p_theyre()] trying to commit suicide!</span>")
playsound(src, 'sound/items/bikehorn.ogg', 50, 1)
return (BRUTELOSS)
//air horn
/obj/item/bikehorn/airhorn
name = "air horn"
desc = "Damn son, where'd you find this?"
icon_state = "air_horn"
/obj/item/bikehorn/airhorn/Initialize()
. = ..()
AddComponent(/datum/component/squeak, list('sound/items/airhorn2.ogg'=1), 50)
//golden bikehorn
/obj/item/bikehorn/golden
name = "golden bike horn"
desc = "Golden? Clearly, it's made with bananium! Honk!"
icon_state = "gold_horn"
item_state = "gold_horn"
var/flip_cooldown = 0
/obj/item/bikehorn/golden/attack()
if(flip_cooldown < world.time)
flip_mobs()
return ..()
/obj/item/bikehorn/golden/attack_self(mob/user)
if(flip_cooldown < world.time)
flip_mobs()
..()
/obj/item/bikehorn/golden/proc/flip_mobs(mob/living/carbon/M, mob/user)
var/turf/T = get_turf(src)
for(M in ohearers(7, T))
if(ishuman(M) && M.can_hear())
var/mob/living/carbon/human/H = M
if(istype(H.ears, /obj/item/clothing/ears/earmuffs))
continue
M.emote("flip")
flip_cooldown = world.time + 7
//canned laughter
/obj/item/reagent_containers/food/drinks/soda_cans/canned_laughter
name = "Canned Laughter"
desc = "Just looking at this makes you want to giggle."
icon_state = "laughter"
list_reagents = list("laughter" = 50)
/* Clown Items
* Contains:
* Soap
* Bike Horns
* Air Horns
* Canned Laughter
*/
/*
* Soap
*/
/obj/item/soap
name = "soap"
desc = "A cheap bar of soap. Doesn't smell."
gender = PLURAL
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "soap"
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
item_flags = NOBLUDGEON
throwforce = 0
throw_speed = 3
throw_range = 7
grind_results = list(/datum/reagent/lye = 10)
var/cleanspeed = 50 //slower than mop
force_string = "robust... against germs"
/obj/item/soap/Initialize()
. = ..()
AddComponent(/datum/component/slippery, 80)
/obj/item/soap/nanotrasen
desc = "A Kinaris.Co brand bar of soap. Smells of plasma."
icon_state = "soapnt"
/obj/item/soap/homemade
desc = "A homemade bar of soap. Smells of... well...."
icon_state = "soapgibs"
cleanspeed = 45 // a little faster to reward chemists for going to the effort
/obj/item/soap/deluxe
desc = "A deluxe Waffle Co. brand bar of soap. Smells of high-class luxury."
icon_state = "soapdeluxe"
cleanspeed = 40 //same speed as mop because deluxe -- captain gets one of these
/obj/item/soap/syndie
desc = "An untrustworthy bar of soap made of strong chemical agents that dissolve blood faster."
icon_state = "soapsyndie"
cleanspeed = 10 //much faster than mop so it is useful for traitors who want to clean crime scenes
/obj/item/soap/suicide_act(mob/user)
user.say(";FFFFFFFFFFFFFFFFUUUUUUUDGE!!", forced="soap suicide")
user.visible_message("<span class='suicide'>[user] lifts [src] to [user.p_their()] mouth and gnaws on it furiously, producing a thick froth! [user.p_they(TRUE)]'ll never get that BB gun now!</span>")
new /obj/effect/particle_effect/foam(loc)
return (TOXLOSS)
/obj/item/soap/afterattack(atom/target, mob/user, proximity)
. = ..()
if(!proximity || !check_allowed_items(target))
return
//I couldn't feasibly fix the overlay bugs caused by cleaning items we are wearing.
//So this is a workaround. This also makes more sense from an IC standpoint. ~Carn
if(user.client && ((target in user.client.screen) && !user.is_holding(target)))
to_chat(user, "<span class='warning'>You need to take that [target.name] off before cleaning it!</span>")
else if(istype(target, /obj/effect/decal/cleanable))
user.visible_message("[user] begins to scrub \the [target.name] out with [src].", "<span class='warning'>You begin to scrub \the [target.name] out with [src]...</span>")
if(do_after(user, src.cleanspeed, target = target))
to_chat(user, "<span class='notice'>You scrub \the [target.name] out.</span>")
qdel(target)
else if(ishuman(target) && user.zone_selected == BODY_ZONE_PRECISE_MOUTH)
var/mob/living/carbon/human/H = user
user.visible_message("<span class='warning'>\the [user] washes \the [target]'s mouth out with [src.name]!</span>", "<span class='notice'>You wash \the [target]'s mouth out with [src.name]!</span>") //washes mouth out with soap sounds better than 'the soap' here
H.lip_style = null //removes lipstick
H.update_body()
return
else if(istype(target, /obj/structure/window))
user.visible_message("[user] begins to clean \the [target.name] with [src]...", "<span class='notice'>You begin to clean \the [target.name] with [src]...</span>")
if(do_after(user, src.cleanspeed, target = target))
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
target.set_opacity(initial(target.opacity))
else
user.visible_message("[user] begins to clean \the [target.name] with [src]...", "<span class='notice'>You begin to clean \the [target.name] with [src]...</span>")
if(do_after(user, src.cleanspeed, target = target))
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
var/obj/effect/decal/cleanable/C = locate() in target
qdel(C)
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
target.wash_cream()
target.wash_cum()
return
/*
* Bike Horns
*/
/obj/item/bikehorn
name = "bike horn"
desc = "A horn off of a bicycle."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "bike_horn"
item_state = "bike_horn"
lefthand_file = 'icons/mob/inhands/equipment/horns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/horns_righthand.dmi'
throwforce = 0
hitsound = null //To prevent tap.ogg playing, as the item lacks of force
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
attack_verb = list("HONKED")
/obj/item/bikehorn/Initialize()
. = ..()
AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50)
/obj/item/bikehorn/attack(mob/living/carbon/M, mob/living/carbon/user)
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "honk", /datum/mood_event/honk)
return ..()
/obj/item/bikehorn/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] solemnly points the horn at [user.p_their()] temple! It looks like [user.p_theyre()] trying to commit suicide!</span>")
playsound(src, 'sound/items/bikehorn.ogg', 50, 1)
return (BRUTELOSS)
//air horn
/obj/item/bikehorn/airhorn
name = "air horn"
desc = "Damn son, where'd you find this?"
icon_state = "air_horn"
/obj/item/bikehorn/airhorn/Initialize()
. = ..()
AddComponent(/datum/component/squeak, list('sound/items/airhorn2.ogg'=1), 50)
//golden bikehorn
/obj/item/bikehorn/golden
name = "golden bike horn"
desc = "Golden? Clearly, it's made with bananium! Honk!"
icon_state = "gold_horn"
item_state = "gold_horn"
var/flip_cooldown = 0
/obj/item/bikehorn/golden/attack()
if(flip_cooldown < world.time)
flip_mobs()
return ..()
/obj/item/bikehorn/golden/attack_self(mob/user)
if(flip_cooldown < world.time)
flip_mobs()
..()
/obj/item/bikehorn/golden/proc/flip_mobs(mob/living/carbon/M, mob/user)
var/turf/T = get_turf(src)
for(M in ohearers(7, T))
if(ishuman(M) && M.can_hear())
var/mob/living/carbon/human/H = M
if(istype(H.ears, /obj/item/clothing/ears/earmuffs))
continue
M.emote("flip")
flip_cooldown = world.time + 7
//canned laughter
/obj/item/reagent_containers/food/drinks/soda_cans/canned_laughter
name = "Canned Laughter"
desc = "Just looking at this makes you want to giggle."
icon_state = "laughter"
list_reagents = list(/datum/reagent/consumable/laughter = 50)

Some files were not shown because too many files have changed in this diff Show More