Merge pull request #10575 from Arturlang/TGUIs_Nexties

[TESTMERGE] Properly working TGUI Next
This commit is contained in:
Ghom
2020-02-02 17:29:56 +01:00
committed by Archie
parent 7ed460e9fe
commit 291dcf9515
378 changed files with 40549 additions and 9150 deletions
+11 -1
View File
@@ -96,12 +96,22 @@
#define NUKESTATE_CORE_EXPOSED 1
#define NUKESTATE_CORE_REMOVED 0
#define NUKEUI_AWAIT_DISK 0
#define NUKEUI_AWAIT_CODE 1
#define NUKEUI_AWAIT_TIMER 2
#define NUKEUI_AWAIT_ARM 3
#define NUKEUI_TIMING 4
#define NUKEUI_EXPLODED 5
#define NUKE_OFF_LOCKED 0
#define NUKE_OFF_UNLOCKED 1
#define NUKE_ON_TIMING 2
#define NUKE_ON_EXPLODING 3
#define MACHINE_NOT_ELECTRIFIED 0
#define MACHINE_ELECTRIFIED_PERMANENT -1
#define MACHINE_DEFAULT_ELECTRIFY_TIME 30
//these flags are used to tell the DNA modifier if a plant gene cannot be extracted or modified.
#define PLANT_GENE_REMOVABLE (1<<0)
#define PLANT_GENE_EXTRACTABLE (1<<1)
+5
View File
@@ -165,6 +165,11 @@
/proc/start_log(log)
WRITE_LOG(log, "Starting up round ID [GLOB.round_id].\n-------------------------")
/* ui logging */
/proc/log_tgui(text)
WRITE_LOG(GLOB.tgui_log, text)
/* Close open log handles. This should be called as late as possible, and no logging should hapen after. */
/proc/shutdown_logging()
rustg_log_close_all()
+1 -1
View File
@@ -1,6 +1,6 @@
// Ensure the frequency is within bounds of what it should be sending/receiving at
/proc/sanitize_frequency(frequency, free = FALSE)
. = round(frequency)
frequency = round(frequency)
if(free)
. = CLAMP(frequency, MIN_FREE_FREQ, MAX_FREE_FREQ)
else
+44
View File
@@ -1576,3 +1576,47 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
return -1
else
return 0
// Converts browser keycodes to BYOND keycodes.
/proc/browser_keycode_to_byond(keycode)
keycode = text2num(keycode)
switch(keycode)
// letters and numbers
if(65 to 90, 48 to 57)
return ascii2text(keycode)
if(17)
return "Ctrl"
if(18)
return "Alt"
if(16)
return "Shift"
if(37)
return "West"
if(38)
return "North"
if(39)
return "East"
if(40)
return "South"
if(45)
return "Insert"
if(46)
return "Delete"
if(36)
return "Northwest"
if(35)
return "Southwest"
if(33)
return "Northeast"
if(34)
return "Southeast"
if(112 to 123)
return "F[keycode-111]"
if(96 to 105)
return "Numpad[keycode-96]"
if(188)
return ","
if(190)
return "."
if(189)
return "-"
+3
View File
@@ -38,6 +38,9 @@ GLOBAL_PROTECT(lastsignalers)
GLOBAL_LIST_EMPTY(lawchanges) //Stores who uploaded laws to which silicon-based lifeform, and what the law was
GLOBAL_PROTECT(lawchanges)
GLOBAL_VAR(tgui_log)
GLOBAL_PROTECT(tgui_log)
GLOBAL_LIST_EMPTY(combatlog)
GLOBAL_PROTECT(combatlog)
GLOBAL_LIST_EMPTY(IClog)
+2 -8
View File
@@ -138,10 +138,7 @@
if(obj_flags & EMAGGED)
return
if(locked)
bolt_raise(usr)
else
bolt_drop(usr)
toggle_bolt(usr)
/obj/machinery/door/airlock/AIAltClick() // Eletrifies doors.
if(obj_flags & EMAGGED)
@@ -162,10 +159,7 @@
if(obj_flags & EMAGGED)
return
if(!emergency)
emergency_on(usr)
else
emergency_off(usr)
toggle_emergency(usr)
/* APC */
/obj/machinery/power/apc/AICtrlClick() // turns off/on APCs.
+1 -1
View File
@@ -11,7 +11,7 @@ SUBSYSTEM_DEF(tgui)
var/basehtml // The HTML base used for all UIs.
/datum/controller/subsystem/tgui/PreInit()
basehtml = file2text('tgui/tgui.html')
basehtml = file2text('tgui-next/packages/tgui/public/tgui-main.html')
/datum/controller/subsystem/tgui/Shutdown()
close_all_uis()
+6 -6
View File
@@ -39,12 +39,12 @@
//title_image = ntitle_image
/datum/browser/proc/add_stylesheet(name, file)
stylesheets["[ckey(name)].css"] = file
register_asset("[ckey(name)].css", file)
/datum/browser/proc/add_script(name, file)
scripts["[ckey(name)].js"] = file
register_asset("[ckey(name)].js", file)
if(istype(name, /datum/asset/spritesheet))
var/datum/asset/spritesheet/sheet = name
stylesheets["spritesheet_[sheet.name].css"] = "data/spritesheets/[sheet.name]"
else
stylesheets["[ckey(name)].css"] = file
register_asset("[ckey(name)].css", file)
/datum/browser/proc/set_content(ncontent)
content = ncontent
+1 -1
View File
@@ -294,4 +294,4 @@ GLOBAL_LIST_EMPTY(uplinks)
if(!T)
return
explosion(T,1,2,3)
qdel(parent) //Alternatively could brick the uplink.
qdel(parent) //Alternatively could brick the uplink.
+149 -145
View File
@@ -1,145 +1,149 @@
/*
//////////////////////////////////////
Choking
Very very noticable.
Lowers resistance.
Decreases stage speed.
Decreases transmittablity tremendously.
Moderate Level.
Bonus
Inflicts spikes of oxyloss
//////////////////////////////////////
*/
/datum/symptom/choking
name = "Choking"
desc = "The virus causes inflammation of the host's air conduits, leading to intermittent choking."
stealth = -3
resistance = -2
stage_speed = -2
transmittable = -4
level = 3
severity = 3
base_message_chance = 15
symptom_delay_min = 10
symptom_delay_max = 30
threshold_desc = "<b>Stage Speed 8:</b> Causes choking more frequently.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/choking/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 8)
symptom_delay_min = 7
symptom_delay_max = 24
if(A.properties["stealth"] >= 4)
suppress_warning = TRUE
/datum/symptom/choking/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>[pick("You're having difficulty breathing.", "Your breathing becomes heavy.")]</span>")
if(3, 4)
if(!suppress_warning)
to_chat(M, "<span class='warning'>[pick("Your windpipe feels like a straw.", "Your breathing becomes tremendously difficult.")]</span>")
else
to_chat(M, "<span class='warning'>You feel very [pick("dizzy","woozy","faint")].</span>") //fake bloodloss messages
Choke_stage_3_4(M, A)
M.emote("gasp")
else
to_chat(M, "<span class='userdanger'>[pick("You're choking!", "You can't breathe!")]</span>")
Choke(M, A)
M.emote("gasp")
/datum/symptom/choking/proc/Choke_stage_3_4(mob/living/M, datum/disease/advance/A)
M.adjustOxyLoss(rand(6,13))
return 1
/datum/symptom/choking/proc/Choke(mob/living/M, datum/disease/advance/A)
M.adjustOxyLoss(rand(10,18))
return 1
/*
//////////////////////////////////////
Asphyxiation
Very very noticable.
Decreases stage speed.
Decreases transmittablity.
Bonus
Inflicts large spikes of oxyloss
Introduces Asphyxiating drugs to the system
Causes cardiac arrest on dying victims.
//////////////////////////////////////
*/
/datum/symptom/asphyxiation
name = "Acute respiratory distress syndrome"
desc = "The virus causes shrinking of the host's lungs, causing severe asphyxiation. May also lead to heart attacks."
stealth = -2
resistance = -0
stage_speed = -1
transmittable = -2
level = 7
severity = 6
base_message_chance = 15
symptom_delay_min = 14
symptom_delay_max = 30
var/paralysis = FALSE
threshold_desc = "<b>Stage Speed 8:</b> Additionally synthesizes pancuronium and sodium thiopental inside the host.<br>\
<b>Transmission 8:</b> Doubles the damage caused by the symptom."
/datum/symptom/asphyxiation/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 8)
paralysis = TRUE
if(A.properties["transmittable"] >= 8)
power = 2
/datum/symptom/asphyxiation/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(3, 4)
to_chat(M, "<span class='warning'><b>[pick("Your windpipe feels thin.", "Your lungs feel small.")]</span>")
Asphyxiate_stage_3_4(M, A)
M.emote("gasp")
if(5)
to_chat(M, "<span class='userdanger'>[pick("Your lungs hurt!", "It hurts to breathe!")]</span>")
Asphyxiate(M, A)
M.emote("gasp")
if(M.getOxyLoss() >= 120)
M.visible_message("<span class='warning'>[M] stops breathing, as if their lungs have totally collapsed!</span>")
Asphyxiate_death(M, A)
return
/datum/symptom/asphyxiation/proc/Asphyxiate_stage_3_4(mob/living/M, datum/disease/advance/A)
var/get_damage = rand(10,15) * power
M.adjustOxyLoss(get_damage)
return 1
/datum/symptom/asphyxiation/proc/Asphyxiate(mob/living/M, datum/disease/advance/A)
var/get_damage = rand(15,21) * power
M.adjustOxyLoss(get_damage)
if(paralysis)
M.reagents.add_reagent_list(list(/datum/reagent/toxin/pancuronium = 3, /datum/reagent/toxin/sodium_thiopental = 3))
return 1
/datum/symptom/asphyxiation/proc/Asphyxiate_death(mob/living/M, datum/disease/advance/A)
var/get_damage = rand(25,35) * power
M.adjustOxyLoss(get_damage)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, get_damage/2)
return 1
/*
//////////////////////////////////////
Choking
Very very noticable.
Lowers resistance.
Decreases stage speed.
Decreases transmittablity tremendously.
Moderate Level.
Bonus
Inflicts spikes of oxyloss
//////////////////////////////////////
*/
/datum/symptom/choking
name = "Choking"
desc = "The virus causes inflammation of the host's air conduits, leading to intermittent choking."
stealth = -3
resistance = -2
stage_speed = -2
transmittable = -4
level = 3
severity = 3
base_message_chance = 15
symptom_delay_min = 10
symptom_delay_max = 30
threshold_desc = list(
"Stage Speed 8" = "Causes choking more frequently.",
"Stealth 4" = "The symptom remains hidden until active."
)
/datum/symptom/choking/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 8)
symptom_delay_min = 7
symptom_delay_max = 24
if(A.properties["stealth"] >= 4)
suppress_warning = TRUE
/datum/symptom/choking/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>[pick("You're having difficulty breathing.", "Your breathing becomes heavy.")]</span>")
if(3, 4)
if(!suppress_warning)
to_chat(M, "<span class='warning'>[pick("Your windpipe feels like a straw.", "Your breathing becomes tremendously difficult.")]</span>")
else
to_chat(M, "<span class='warning'>You feel very [pick("dizzy","woozy","faint")].</span>") //fake bloodloss messages
Choke_stage_3_4(M, A)
M.emote("gasp")
else
to_chat(M, "<span class='userdanger'>[pick("You're choking!", "You can't breathe!")]</span>")
Choke(M, A)
M.emote("gasp")
/datum/symptom/choking/proc/Choke_stage_3_4(mob/living/M, datum/disease/advance/A)
M.adjustOxyLoss(rand(6,13))
return 1
/datum/symptom/choking/proc/Choke(mob/living/M, datum/disease/advance/A)
M.adjustOxyLoss(rand(10,18))
return 1
/*
//////////////////////////////////////
Asphyxiation
Very very noticable.
Decreases stage speed.
Decreases transmittablity.
Bonus
Inflicts large spikes of oxyloss
Introduces Asphyxiating drugs to the system
Causes cardiac arrest on dying victims.
//////////////////////////////////////
*/
/datum/symptom/asphyxiation
name = "Acute respiratory distress syndrome"
desc = "The virus causes shrinking of the host's lungs, causing severe asphyxiation. May also lead to heart attacks."
stealth = -2
resistance = -0
stage_speed = -1
transmittable = -2
level = 7
severity = 6
base_message_chance = 15
symptom_delay_min = 14
symptom_delay_max = 30
var/paralysis = FALSE
threshold_desc = list(
"Stage Speed 8" = "Additionally synthesizes pancuronium and sodium thiopental inside the host.",
"Transmission 8" = "Doubles the damage caused by the symptom."
)
/datum/symptom/asphyxiation/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 8)
paralysis = TRUE
if(A.properties["transmittable"] >= 8)
power = 2
/datum/symptom/asphyxiation/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(3, 4)
to_chat(M, "<span class='warning'><b>[pick("Your windpipe feels thin.", "Your lungs feel small.")]</span>")
Asphyxiate_stage_3_4(M, A)
M.emote("gasp")
if(5)
to_chat(M, "<span class='userdanger'>[pick("Your lungs hurt!", "It hurts to breathe!")]</span>")
Asphyxiate(M, A)
M.emote("gasp")
if(M.getOxyLoss() >= 120)
M.visible_message("<span class='warning'>[M] stops breathing, as if their lungs have totally collapsed!</span>")
Asphyxiate_death(M, A)
return
/datum/symptom/asphyxiation/proc/Asphyxiate_stage_3_4(mob/living/M, datum/disease/advance/A)
var/get_damage = rand(10,15) * power
M.adjustOxyLoss(get_damage)
return 1
/datum/symptom/asphyxiation/proc/Asphyxiate(mob/living/M, datum/disease/advance/A)
var/get_damage = rand(15,21) * power
M.adjustOxyLoss(get_damage)
if(paralysis)
M.reagents.add_reagent_list(list(/datum/reagent/toxin/pancuronium = 3, /datum/reagent/toxin/sodium_thiopental = 3))
return 1
/datum/symptom/asphyxiation/proc/Asphyxiate_death(mob/living/M, datum/disease/advance/A)
var/get_damage = rand(25,35) * power
M.adjustOxyLoss(get_damage)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, get_damage/2)
return 1
@@ -29,9 +29,11 @@ Bonus
symptom_delay_min = 10
symptom_delay_max = 30
var/brain_damage = FALSE
threshold_desc = "<b>Resistance 6:</b> Causes brain damage over time.<br>\
<b>Transmission 6:</b> Increases confusion duration.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
threshold_desc = list(
"Resistance 6" = "Causes brain damage over time.",
"Transmission 6" = "Increases confusion duration and strength.",
"Stealth 4" = "The symptom remains hidden until active.",
)
/datum/symptom/confusion/Start(datum/disease/advance/A)
if(!..())
@@ -29,12 +29,13 @@ BONUS
symptom_delay_min = 2
symptom_delay_max = 15
var/infective = FALSE
threshold_desc = "<b>Resistance 3:</b> Host will drop small items when coughing.<br>\
<b>Resistance 10:</b> Occasionally causes coughing fits that stun the host.<br>\
<b>Stage Speed 6:</b> Increases cough frequency.<br>\
<b>If Airborne:</b> Coughing will infect bystanders.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
threshold_desc = list(
"Resistance 11" = "The host will drop small items when coughing.",
"Resistance 15" = "Occasionally causes coughing fits that stun the host. The extra coughs do not spread the virus.",
"Stage Speed 6" = "Increases cough frequency.",
"Transmission 7" = "Coughing will now infect bystanders up to 2 tiles away.",
"Stealth 4" = "The symptom remains hidden until active.",
)
/datum/symptom/cough/Start(datum/disease/advance/A)
if(!..())
return
@@ -28,8 +28,10 @@ Bonus
base_message_chance = 100
symptom_delay_min = 25
symptom_delay_max = 80
threshold_desc = "<b>Resistance 9:</b> Causes permanent deafness, instead of intermittent.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
threshold_desc = list(
"Resistance 9" = "Causes permanent deafness, instead of intermittent.",
"Stealth 4" = "The symptom remains hidden until active.",
)
/datum/symptom/deafness/Start(datum/disease/advance/A)
if(!..())
@@ -27,8 +27,10 @@ Bonus
base_message_chance = 50
symptom_delay_min = 15
symptom_delay_max = 40
threshold_desc = "<b>Transmission 6:</b> Also causes druggy vision.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
threshold_desc = list(
"Transmission 6" = "Also causes druggy vision.",
"Stealth 4" = "The symptom remains hidden until active.",
)
/datum/symptom/dizzy/Start(datum/disease/advance/A)
if(!..())
@@ -28,9 +28,10 @@ Bonus
symptom_delay_min = 10
symptom_delay_max = 30
var/unsafe = FALSE //over the heat threshold
threshold_desc = "<b>Resistance 5:</b> Increases fever intensity, fever can overheat and harm the host.<br>\
<b>Resistance 10:</b> Further increases fever intensity."
threshold_desc = list(
"Resistance 5" = "Increases fever intensity, fever can overheat and harm the host.",
"Resistance 10" = "Further increases fever intensity.",
)
/datum/symptom/fever/Start(datum/disease/advance/A)
if(!..())
return
@@ -29,11 +29,12 @@ Bonus
symptom_delay_min = 20
symptom_delay_max = 75
var/infective = FALSE
threshold_desc = "<b>Stage Speed 4:</b> Increases the intensity of the flames.<br>\
<b>Stage Speed 8:</b> Further increases flame intensity.<br>\
<b>Transmission 8:</b> Host will spread the virus through skin flakes when bursting into flame.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
threshold_desc = list(
"Stage Speed 4" = "Increases the intensity of the flames.",
"Stage Speed 8" = "Further increases flame intensity.",
"Transmission 8" = "Host will spread the virus through skin flakes when bursting into flame.",
"Stealth 4" = "The symptom remains hidden until active.",
)
/datum/symptom/fire/Start(datum/disease/advance/A)
if(!..())
return
@@ -1,130 +1,136 @@
/*
//////////////////////////////////////
Necrotizing Fasciitis (AKA Flesh-Eating Disease)
Very very noticable.
Lowers resistance tremendously.
No changes to stage speed.
Decreases transmittablity temrendously.
Fatal Level.
Bonus
Deals brute damage over time.
//////////////////////////////////////
*/
/datum/symptom/flesh_eating
name = "Necrotizing Fasciitis"
desc = "The virus aggressively attacks body cells, necrotizing tissues and organs."
stealth = -3
resistance = -4
stage_speed = 0
transmittable = -4
level = 6
severity = 5
base_message_chance = 50
symptom_delay_min = 15
symptom_delay_max = 60
var/bleed = FALSE
var/pain = FALSE
threshold_desc = "<b>Resistance 7:</b> Host will bleed profusely during necrosis.<br>\
<b>Transmission 8:</b> Causes extreme pain to the host, weakening it."
/datum/symptom/flesh_eating/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["resistance"] >= 7) //extra bleeding
bleed = TRUE
if(A.properties["transmittable"] >= 8) //extra stamina damage
pain = TRUE
/datum/symptom/flesh_eating/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2,3)
if(prob(base_message_chance))
to_chat(M, "<span class='warning'>[pick("You feel a sudden pain across your body.", "Drops of blood appear suddenly on your skin.")]</span>")
if(4,5)
to_chat(M, "<span class='userdanger'>[pick("You cringe as a violent pain takes over your body.", "It feels like your body is eating itself inside out.", "IT HURTS.")]</span>")
Flesheat(M, A)
/datum/symptom/flesh_eating/proc/Flesheat(mob/living/M, datum/disease/advance/A)
var/get_damage = rand(15,25) * power
M.adjustBruteLoss(get_damage)
if(pain)
M.adjustStaminaLoss(get_damage)
if(bleed)
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.bleed_rate += 5 * power
return 1
/*
//////////////////////////////////////
Autophagocytosis (AKA Programmed mass cell death)
Very noticable.
Lowers resistance.
Fast stage speed.
Decreases transmittablity.
Fatal Level.
Bonus
Deals brute damage over time.
//////////////////////////////////////
*/
/datum/symptom/flesh_death
name = "Autophagocytosis Necrosis"
desc = "The virus rapidly consumes infected cells, leading to heavy and widespread damage."
stealth = -2
resistance = -2
stage_speed = 1
transmittable = -2
level = 7
severity = 6
base_message_chance = 50
symptom_delay_min = 3
symptom_delay_max = 6
var/chems = FALSE
var/zombie = FALSE
threshold_desc = "<b>Stage Speed 7:</b> Synthesizes Heparin and Lipolicide inside the host, causing increased bleeding and hunger.<br>\
<b>Stealth 5:</b> The symptom remains hidden until active."
/datum/symptom/flesh_death/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stealth"] >= 5)
suppress_warning = TRUE
if(A.properties["stage_rate"] >= 7) //bleeding and hunger
chems = TRUE
/datum/symptom/flesh_death/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2,3)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>[pick("You feel your body break apart.", "Your skin rubs off like dust.")]</span>")
if(4,5)
if(prob(base_message_chance / 2)) //reduce spam
to_chat(M, "<span class='userdanger'>[pick("You feel your muscles weakening.", "Some of your skin detaches itself.", "You feel sandy.")]</span>")
Flesh_death(M, A)
/datum/symptom/flesh_death/proc/Flesh_death(mob/living/M, datum/disease/advance/A)
var/get_damage = rand(6,10)
M.adjustBruteLoss(get_damage)
if(chems)
M.reagents.add_reagent_list(list(/datum/reagent/toxin/heparin = 2, /datum/reagent/toxin/lipolicide = 2))
if(zombie)
M.reagents.add_reagent(/datum/reagent/romerol, 1)
return 1
/*
//////////////////////////////////////
Necrotizing Fasciitis (AKA Flesh-Eating Disease)
Very very noticable.
Lowers resistance tremendously.
No changes to stage speed.
Decreases transmittablity temrendously.
Fatal Level.
Bonus
Deals brute damage over time.
//////////////////////////////////////
*/
/datum/symptom/flesh_eating
name = "Necrotizing Fasciitis"
desc = "The virus aggressively attacks body cells, necrotizing tissues and organs."
stealth = -3
resistance = -4
stage_speed = 0
transmittable = -4
level = 6
severity = 5
base_message_chance = 50
symptom_delay_min = 15
symptom_delay_max = 60
var/bleed = FALSE
var/pain = FALSE
threshold_desc = list(
"Resistance 9" = "Doubles the intensity of the immolation effect, but reduces the frequency of all of this symptom's effects.",
"Stage Speed 8" = "Increases explosion radius and explosion damage to the host when the host is wet.",
"Transmission 8" = "Additionally synthesizes chlorine trifluoride and napalm inside the host. More chemicals are synthesized if the resistance 9 threshold has been met."
)
/datum/symptom/flesh_eating/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["resistance"] >= 7) //extra bleeding
bleed = TRUE
if(A.properties["transmittable"] >= 8) //extra stamina damage
pain = TRUE
/datum/symptom/flesh_eating/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2,3)
if(prob(base_message_chance))
to_chat(M, "<span class='warning'>[pick("You feel a sudden pain across your body.", "Drops of blood appear suddenly on your skin.")]</span>")
if(4,5)
to_chat(M, "<span class='userdanger'>[pick("You cringe as a violent pain takes over your body.", "It feels like your body is eating itself inside out.", "IT HURTS.")]</span>")
Flesheat(M, A)
/datum/symptom/flesh_eating/proc/Flesheat(mob/living/M, datum/disease/advance/A)
var/get_damage = rand(15,25) * power
M.adjustBruteLoss(get_damage)
if(pain)
M.adjustStaminaLoss(get_damage)
if(bleed)
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.bleed_rate += 5 * power
return 1
/*
//////////////////////////////////////
Autophagocytosis (AKA Programmed mass cell death)
Very noticable.
Lowers resistance.
Fast stage speed.
Decreases transmittablity.
Fatal Level.
Bonus
Deals brute damage over time.
//////////////////////////////////////
*/
/datum/symptom/flesh_death
name = "Autophagocytosis Necrosis"
desc = "The virus rapidly consumes infected cells, leading to heavy and widespread damage."
stealth = -2
resistance = -2
stage_speed = 1
transmittable = -2
level = 7
severity = 6
base_message_chance = 50
symptom_delay_min = 3
symptom_delay_max = 6
var/chems = FALSE
var/zombie = FALSE
threshold_desc = list(
"Stage Speed 7" = "Synthesizes Heparin and Lipolicide inside the host, causing increased bleeding and hunger.",
"Stealth 5" = "The symptom remains hidden until active.",
)
/datum/symptom/flesh_death/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stealth"] >= 5)
suppress_warning = TRUE
if(A.properties["stage_rate"] >= 7) //bleeding and hunger
chems = TRUE
/datum/symptom/flesh_death/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2,3)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>[pick("You feel your body break apart.", "Your skin rubs off like dust.")]</span>")
if(4,5)
if(prob(base_message_chance / 2)) //reduce spam
to_chat(M, "<span class='userdanger'>[pick("You feel your muscles weakening.", "Some of your skin detaches itself.", "You feel sandy.")]</span>")
Flesh_death(M, A)
/datum/symptom/flesh_death/proc/Flesh_death(mob/living/M, datum/disease/advance/A)
var/get_damage = rand(6,10)
M.adjustBruteLoss(get_damage)
if(chems)
M.reagents.add_reagent_list(list(/datum/reagent/toxin/heparin = 2, /datum/reagent/toxin/lipolicide = 2))
if(zombie)
M.reagents.add_reagent(/datum/reagent/romerol, 1)
return 1
@@ -0,0 +1,81 @@
/*
//////////////////////////////////////
DNA Saboteur
Very noticable.
Lowers resistance tremendously.
No changes to stage speed.
Decreases transmittablity tremendously.
Fatal Level.
Bonus
Cleans the DNA of a person and then randomly gives them a trait.
//////////////////////////////////////
*/
/datum/symptom/genetic_mutation
name = "Deoxyribonucleic Acid Saboteur"
desc = "The virus bonds with the DNA of the host, causing damaging mutations until removed."
stealth = -2
resistance = -3
stage_speed = 0
transmittable = -3
level = 6
severity = 4
var/list/possible_mutations
var/archived_dna = null
base_message_chance = 50
symptom_delay_min = 60
symptom_delay_max = 120
var/no_reset = FALSE
threshold_desc = list(
"Resistance 8" = "The negative and mildly negative mutations caused by the virus are mutadone-proof (but will still be undone when the virus is cured if the resistance 14 threshold is not met).",
"Resistance 14" = "The host's genetic alterations are not undone when the virus is cured.",
"Stage Speed 10" = "The virus activates dormant mutations at a much faster rate.",
"Stealth 5" = "Only activates negative mutations in hosts."
)
/datum/symptom/genetic_mutation/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/carbon/C = A.affected_mob
if(!C.has_dna())
return
switch(A.stage)
if(4, 5)
to_chat(C, "<span class='warning'>[pick("Your skin feels itchy.", "You feel light headed.")]</span>")
C.dna.remove_mutation_group(possible_mutations)
for(var/i in 1 to power)
C.randmut(possible_mutations)
// Archive their DNA before they were infected.
/datum/symptom/genetic_mutation/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stealth"] >= 5) //don't restore dna after curing
no_reset = TRUE
if(A.properties["stage_rate"] >= 10) //mutate more often
symptom_delay_min = 20
symptom_delay_max = 60
if(A.properties["resistance"] >= 8) //mutate twice
power = 2
possible_mutations = (GLOB.bad_mutations | GLOB.not_good_mutations) - GLOB.mutations_list[RACEMUT]
var/mob/living/carbon/M = A.affected_mob
if(M)
if(!M.has_dna())
return
archived_dna = M.dna.struc_enzymes
// Give them back their old DNA when cured.
/datum/symptom/genetic_mutation/End(datum/disease/advance/A)
if(!..())
return
if(!no_reset)
var/mob/living/carbon/M = A.affected_mob
if(M && archived_dna)
if(!M.has_dna())
return
M.dna.struc_enzymes = archived_dna
M.domutcheck()
@@ -28,8 +28,10 @@ Bonus
symptom_delay_min = 25
symptom_delay_max = 90
var/fake_healthy = FALSE
threshold_desc = "<b>Stage Speed 7:</b> Increases the amount of hallucinations.<br>\
<b>Stealth 4:</b> The virus mimics positive symptoms.."
threshold_desc = list(
"Stage Speed 7" = "Increases the amount of hallucinations.",
"Stealth 4" = "The virus mimics positive symptoms.",
)
/datum/symptom/hallucigen/Start(datum/disease/advance/A)
if(!..())
@@ -29,9 +29,11 @@ BONUS
base_message_chance = 100
symptom_delay_min = 15
symptom_delay_max = 30
threshold_desc = "<b>Stage Speed 6:</b> Headaches will cause severe pain, that weakens the host.<br>\
<b>Stage Speed 9:</b> Headaches become less frequent but far more intense, preventing any action from the host.<br>\
<b>Stealth 4:</b> Reduces headache frequency until later stages."
threshold_desc = list(
"Stage Speed 6" = "Headaches will cause severe pain, that weakens the host.",
"Stage Speed 9" = "Headaches become less frequent but far more intense, preventing any action from the host.",
"Stealth 4" = "Reduces headache frequency until later stages.",
)
/datum/symptom/headache/Start(datum/disease/advance/A)
if(!..())
+503 -491
View File
@@ -1,491 +1,503 @@
/datum/symptom/heal
name = "Basic Healing (does nothing)" //warning for adminspawn viruses
desc = "You should not be seeing this."
stealth = 0
resistance = 0
stage_speed = 0
transmittable = 0
level = 0 //not obtainable
base_message_chance = 20 //here used for the overlays
symptom_delay_min = 1
symptom_delay_max = 1
var/passive_message = "" //random message to infected but not actively healing people
threshold_desc = "<b>Stage Speed 6:</b> Doubles healing speed.<br>\
<b>Stealth 4:</b> Healing will no longer be visible to onlookers."
/datum/symptom/heal/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 6) //stronger healing
power = 2
/datum/symptom/heal/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
var/effectiveness = CanHeal(A)
if(!effectiveness)
if(passive_message && prob(2) && passive_message_condition(M))
to_chat(M, passive_message)
return
else
Heal(M, A, effectiveness)
return
/datum/symptom/heal/proc/CanHeal(datum/disease/advance/A)
return power
/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A, actual_power)
return TRUE
/datum/symptom/heal/proc/passive_message_condition(mob/living/M)
return TRUE
/datum/symptom/heal/starlight
name = "Starlight Condensation"
desc = "The virus reacts to direct starlight, producing regenerative chemicals. Works best against toxin-based damage."
stealth = -1
resistance = -2
stage_speed = 0
transmittable = 1
level = 6
passive_message = "<span class='notice'>You miss the feeling of starlight on your skin.</span>"
var/nearspace_penalty = 0.3
threshold_desc = "<b>Stage Speed 6:</b> Increases healing speed.<br>\
<b>Transmission 6:</b> Removes penalty for only being close to space."
/datum/symptom/heal/starlight/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["transmittable"] >= 6)
nearspace_penalty = 1
if(A.properties["stage_rate"] >= 6)
power = 2
/datum/symptom/heal/starlight/CanHeal(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
if(istype(get_turf(M), /turf/open/space))
return power
else
for(var/turf/T in view(M, 2))
if(istype(T, /turf/open/space))
return power * nearspace_penalty
/datum/symptom/heal/starlight/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = actual_power
if(M.getToxLoss() && prob(5))
to_chat(M, "<span class='notice'>Your skin tingles as the starlight seems to heal you.</span>")
M.adjustToxLoss(-(4 * heal_amt)) //most effective on toxins
var/list/parts = M.get_damaged_bodyparts(1,1)
if(!parts.len)
return
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len))
M.update_damage_overlays()
return 1
/datum/symptom/heal/starlight/passive_message_condition(mob/living/M)
if(M.getBruteLoss() || M.getFireLoss() || M.getToxLoss())
return TRUE
return FALSE
/datum/symptom/heal/chem
name = "Toxolysis"
stealth = 0
resistance = -2
stage_speed = 2
transmittable = -2
level = 7
var/food_conversion = FALSE
desc = "The virus rapidly breaks down any foreign chemicals in the bloodstream."
threshold_desc = "<b>Resistance 7:</b> Increases chem removal speed.<br>\
<b>Stage Speed 6:</b> Consumed chemicals nourish the host."
/datum/symptom/heal/chem/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 6)
food_conversion = TRUE
if(A.properties["resistance"] >= 7)
power = 2
/datum/symptom/heal/chem/Heal(mob/living/M, datum/disease/advance/A, actual_power)
for(var/E in M.reagents.reagent_list) //Not just toxins!
var/datum/reagent/R = E
M.reagents.remove_reagent(R.type, actual_power)
if(food_conversion)
M.nutrition += 0.3
if(prob(2))
to_chat(M, "<span class='notice'>You feel a mild warmth as your blood purifies itself.</span>")
return 1
/datum/symptom/heal/metabolism
name = "Metabolic Boost"
stealth = -1
resistance = -2
stage_speed = 2
transmittable = 1
level = 7
var/triple_metabolism = FALSE
var/reduced_hunger = FALSE
desc = "The virus causes the host's metabolism to accelerate rapidly, making them process chemicals twice as fast,\
but also causing increased hunger."
threshold_desc = "<b>Stealth 3:</b> Reduces hunger rate.<br>\
<b>Stage Speed 10:</b> Chemical metabolization is tripled instead of doubled."
/datum/symptom/heal/metabolism/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 10)
triple_metabolism = TRUE
if(A.properties["stealth"] >= 3)
reduced_hunger = TRUE
/datum/symptom/heal/metabolism/Heal(mob/living/carbon/C, datum/disease/advance/A, actual_power)
if(!istype(C))
return
C.reagents.metabolize(C, can_overdose=TRUE) //this works even without a liver; it's intentional since the virus is metabolizing by itself
if(triple_metabolism)
C.reagents.metabolize(C, can_overdose=TRUE)
C.overeatduration = max(C.overeatduration - 2, 0)
var/lost_nutrition = 9 - (reduced_hunger * 5)
C.nutrition = max(C.nutrition - (lost_nutrition * HUNGER_FACTOR), 0) //Hunger depletes at 10x the normal speed
if(prob(2))
to_chat(C, "<span class='notice'>You feel an odd gurgle in your stomach, as if it was working much faster than normal.</span>")
return 1
/datum/symptom/heal/darkness
name = "Nocturnal Regeneration"
desc = "The virus is able to mend the host's flesh when in conditions of low light, repairing physical damage. More effective against brute damage."
stealth = 2
resistance = -1
stage_speed = -2
transmittable = -1
level = 6
passive_message = "<span class='notice'>You feel tingling on your skin as light passes over it.</span>"
threshold_desc = "<b>Stage Speed 8:</b> Doubles healing speed."
/datum/symptom/heal/darkness/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 8)
power = 2
/datum/symptom/heal/darkness/CanHeal(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
var/light_amount = 0
if(isturf(M.loc)) //else, there's considered to be no light
var/turf/T = M.loc
light_amount = min(1,T.get_lumcount()) - 0.5
if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD)
return power
/datum/symptom/heal/darkness/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = 2 * actual_power
var/list/parts = M.get_damaged_bodyparts(1,1)
if(!parts.len)
return
if(prob(5))
to_chat(M, "<span class='notice'>The darkness soothes and mends your wounds.</span>")
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len * 0.5)) //more effective on brute
M.update_damage_overlays()
return 1
/datum/symptom/heal/darkness/passive_message_condition(mob/living/M)
if(M.getBruteLoss() || M.getFireLoss())
return TRUE
return FALSE
/datum/symptom/heal/coma
name = "Regenerative Coma"
desc = "The virus causes the host to fall into a death-like coma when severely damaged, then rapidly fixes the damage."
stealth = 0
resistance = 2
stage_speed = -3
transmittable = -2
level = 8
passive_message = "<span class='notice'>The pain from your wounds makes you feel oddly sleepy...</span>"
var/deathgasp = FALSE
var/stabilize = FALSE
var/active_coma = FALSE //to prevent multiple coma procs
threshold_desc = "<b>Stealth 2:</b> Host appears to die when falling into a coma.<br>\
<b>Resistance 4:</b> The virus also stabilizes the host while they are in critical condition.<br>\
<b>Stage Speed 7:</b> Increases healing speed."
/datum/symptom/heal/coma/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 7)
power = 1.5
if(A.properties["resistance"] >= 4)
stabilize = TRUE
if(A.properties["stealth"] >= 2)
deathgasp = TRUE
/datum/symptom/heal/coma/on_stage_change(datum/disease/advance/A) //mostly copy+pasted from the code for self-respiration's TRAIT_NOBREATH stuff
if(!..())
return FALSE
if(A.stage >= 4 && stabilize)
ADD_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
else
REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
return TRUE
/datum/symptom/heal/coma/End(datum/disease/advance/A)
if(!..())
return
REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
/datum/symptom/heal/coma/CanHeal(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
if(HAS_TRAIT(M, TRAIT_DEATHCOMA))
return power
else if(M.IsUnconscious() || M.stat == UNCONSCIOUS)
return power * 0.9
else if(M.stat == SOFT_CRIT)
return power * 0.5
else if(M.IsSleeping())
return power * 0.25
else if(M.getBruteLoss() + M.getFireLoss() >= 70 && !active_coma)
to_chat(M, "<span class='warning'>You feel yourself slip into a regenerative coma...</span>")
active_coma = TRUE
addtimer(CALLBACK(src, .proc/coma, M), 60)
/datum/symptom/heal/coma/proc/coma(mob/living/M)
if(deathgasp)
M.emote("deathgasp")
M.fakedeath("regenerative_coma")
M.update_stat()
M.update_canmove()
addtimer(CALLBACK(src, .proc/uncoma, M), 300)
/datum/symptom/heal/coma/proc/uncoma(mob/living/M)
if(!active_coma)
return
active_coma = FALSE
M.cure_fakedeath("regenerative_coma")
M.update_stat()
M.update_canmove()
/datum/symptom/heal/coma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = 4 * actual_power
var/list/parts = M.get_damaged_bodyparts(1,1)
if(!parts.len)
return
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len))
M.update_damage_overlays()
if(active_coma && M.getBruteLoss() + M.getFireLoss() == 0)
uncoma(M)
return 1
/datum/symptom/heal/coma/passive_message_condition(mob/living/M)
if((M.getBruteLoss() + M.getFireLoss()) > 30)
return TRUE
return FALSE
/datum/symptom/heal/water
name = "Tissue Hydration"
desc = "The virus uses excess water inside and outside the body to repair damaged tissue cells. More effective against burns."
stealth = 0
resistance = -1
stage_speed = 0
transmittable = 1
level = 6
passive_message = "<span class='notice'>Your skin feels oddly dry...</span>"
var/absorption_coeff = 1
threshold_desc = "<b>Resistance 5:</b> Water is consumed at a much slower rate.<br>\
<b>Stage Speed 7:</b> Increases healing speed."
/datum/symptom/heal/water/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 7)
power = 2
if(A.properties["stealth"] >= 2)
absorption_coeff = 0.25
/datum/symptom/heal/water/CanHeal(datum/disease/advance/A)
. = 0
var/mob/living/M = A.affected_mob
if(M.fire_stacks < 0)
M.fire_stacks = min(M.fire_stacks + 1 * absorption_coeff, 0)
. += power
if(M.reagents.has_reagent(/datum/reagent/water/holywater))
M.reagents.remove_reagent(/datum/reagent/water/holywater, 0.5 * absorption_coeff)
. += power * 0.75
else if(M.reagents.has_reagent(/datum/reagent/water))
M.reagents.remove_reagent(/datum/reagent/water, 0.5 * absorption_coeff)
. += power * 0.5
/datum/symptom/heal/water/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = 2 * actual_power
var/list/parts = M.get_damaged_bodyparts(1,1) //more effective on burns
if(!parts.len)
return
if(prob(5))
to_chat(M, "<span class='notice'>You feel yourself absorbing the water around you to soothe your damaged skin.</span>")
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len * 0.5, heal_amt/parts.len))
M.update_damage_overlays()
return 1
/datum/symptom/heal/water/passive_message_condition(mob/living/M)
if(M.getBruteLoss() || M.getFireLoss())
return TRUE
return FALSE
/datum/symptom/heal/plasma
name = "Plasma Fixation"
desc = "The virus draws plasma from the atmosphere and from inside the body to heal and stabilize body temperature."
stealth = 0
resistance = 3
stage_speed = -2
transmittable = -2
level = 8
passive_message = "<span class='notice'>You feel an odd attraction to plasma.</span>"
var/temp_rate = 1
threshold_desc = "<b>Transmission 6:</b> Increases temperature adjustment rate.<br>\
<b>Stage Speed 7:</b> Increases healing speed."
/datum/symptom/heal/plasma/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 7)
power = 2
if(A.properties["transmittable"] >= 6)
temp_rate = 4
/datum/symptom/heal/plasma/CanHeal(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
var/datum/gas_mixture/environment
var/plasmamount
. = 0
if(M.loc)
environment = M.loc.return_air()
if(environment)
plasmamount = environment.gases[/datum/gas/plasma]
if(plasmamount && plasmamount > GLOB.meta_gas_visibility[/datum/gas/plasma]) //if there's enough plasma in the air to see
. += power * 0.5
if(M.reagents.has_reagent(/datum/reagent/toxin/plasma))
. += power * 0.75
/datum/symptom/heal/plasma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = 4 * actual_power
if(prob(5))
to_chat(M, "<span class='notice'>You feel yourself absorbing plasma inside and around you...</span>")
if(M.bodytemperature > BODYTEMP_NORMAL)
M.adjust_bodytemperature(-20 * temp_rate * TEMPERATURE_DAMAGE_COEFFICIENT,BODYTEMP_NORMAL)
if(prob(5))
to_chat(M, "<span class='notice'>You feel less hot.</span>")
else if(M.bodytemperature < (BODYTEMP_NORMAL + 1))
M.adjust_bodytemperature(20 * temp_rate * TEMPERATURE_DAMAGE_COEFFICIENT,0,BODYTEMP_NORMAL)
if(prob(5))
to_chat(M, "<span class='notice'>You feel warmer.</span>")
M.adjustToxLoss(-heal_amt)
var/list/parts = M.get_damaged_bodyparts(1,1)
if(!parts.len)
return
if(prob(5))
to_chat(M, "<span class='notice'>The pain from your wounds fades rapidly.</span>")
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len))
M.update_damage_overlays()
return 1
/datum/symptom/heal/radiation
name = "Radioactive Resonance"
desc = "The virus uses radiation to fix damage through dna mutations."
stealth = -1
resistance = -2
stage_speed = 2
transmittable = -3
level = 6
symptom_delay_min = 1
symptom_delay_max = 1
passive_message = "<span class='notice'>Your skin glows faintly for a moment.</span>"
var/cellular_damage = FALSE
threshold_desc = "<b>Transmission 6:</b> Additionally heals cellular damage.<br>\
<b>Resistance 7:</b> Increases healing speed."
/datum/symptom/heal/radiation/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["resistance"] >= 7)
power = 2
if(A.properties["transmittable"] >= 6)
cellular_damage = TRUE
ADD_TRAIT(A.affected_mob, TRAIT_RADRESONANCE, DISEASE_TRAIT)
/datum/symptom/heal/radiation/CanHeal(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
switch(M.radiation)
if(0)
return FALSE
if(1 to RAD_MOB_SAFE)
return 0.25
if(RAD_MOB_SAFE to RAD_BURN_THRESHOLD)
return 0.5
if(RAD_BURN_THRESHOLD to RAD_MOB_MUTATE)
return 0.75
if(RAD_MOB_MUTATE to RAD_MOB_KNOCKDOWN)
return 1
else
return 1.5
/datum/symptom/heal/radiation/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = actual_power
if(cellular_damage)
M.adjustCloneLoss(-heal_amt * 0.5)
M.adjustToxLoss(-(2 * heal_amt))
var/list/parts = M.get_damaged_bodyparts(1,1)
if(!parts.len)
return
if(prob(4))
to_chat(M, "<span class='notice'>Your skin glows faintly, and you feel your wounds mending themselves.</span>")
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len))
M.update_damage_overlays()
return 1
/datum/symptom/heal/radiation/End(datum/disease/advance/A)
if(!..())
return
REMOVE_TRAIT(A.affected_mob, TRAIT_RADRESONANCE, DISEASE_TRAIT)
/datum/symptom/heal
name = "Basic Healing (does nothing)" //warning for adminspawn viruses
desc = "You should not be seeing this."
stealth = 0
resistance = 0
stage_speed = 0
transmittable = 0
level = 0 //not obtainable
base_message_chance = 20 //here used for the overlays
symptom_delay_min = 1
symptom_delay_max = 1
var/passive_message = "" //random message to infected but not actively healing people
threshold_desc = list(
"Stage Speed 6" = "Doubles healing speed.",
"Stealth 4" = "Healing will no longer be visible to onlookers.",
)
/datum/symptom/heal/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 6) //stronger healing
power = 2
/datum/symptom/heal/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
var/effectiveness = CanHeal(A)
if(!effectiveness)
if(passive_message && prob(2) && passive_message_condition(M))
to_chat(M, passive_message)
return
else
Heal(M, A, effectiveness)
return
/datum/symptom/heal/proc/CanHeal(datum/disease/advance/A)
return power
/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A, actual_power)
return TRUE
/datum/symptom/heal/proc/passive_message_condition(mob/living/M)
return TRUE
/datum/symptom/heal/starlight
name = "Starlight Condensation"
desc = "The virus reacts to direct starlight, producing regenerative chemicals. Works best against toxin-based damage."
stealth = -1
resistance = -2
stage_speed = 0
transmittable = 1
level = 6
passive_message = "<span class='notice'>You miss the feeling of starlight on your skin.</span>"
var/nearspace_penalty = 0.3
threshold_desc = list(
"Stage Speed 6" = "Increases healing speed.",
"Transmission 6" = "Removes penalty for only being close to space.",
)
/datum/symptom/heal/starlight/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["transmittable"] >= 6)
nearspace_penalty = 1
if(A.properties["stage_rate"] >= 6)
power = 2
/datum/symptom/heal/starlight/CanHeal(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
if(istype(get_turf(M), /turf/open/space))
return power
else
for(var/turf/T in view(M, 2))
if(istype(T, /turf/open/space))
return power * nearspace_penalty
/datum/symptom/heal/starlight/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = actual_power
if(M.getToxLoss() && prob(5))
to_chat(M, "<span class='notice'>Your skin tingles as the starlight seems to heal you.</span>")
M.adjustToxLoss(-(4 * heal_amt)) //most effective on toxins
var/list/parts = M.get_damaged_bodyparts(1,1)
if(!parts.len)
return
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len))
M.update_damage_overlays()
return 1
/datum/symptom/heal/starlight/passive_message_condition(mob/living/M)
if(M.getBruteLoss() || M.getFireLoss() || M.getToxLoss())
return TRUE
return FALSE
/datum/symptom/heal/chem
name = "Toxolysis"
stealth = 0
resistance = -2
stage_speed = 2
transmittable = -2
level = 7
var/food_conversion = FALSE
desc = "The virus rapidly breaks down any foreign chemicals in the bloodstream."
threshold_desc = list(
"Resistance 7" = "Increases chem removal speed.",
"Stage Speed 6" = "Consumed chemicals nourish the host.",
)
/datum/symptom/heal/chem/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 6)
food_conversion = TRUE
if(A.properties["resistance"] >= 7)
power = 2
/datum/symptom/heal/chem/Heal(mob/living/M, datum/disease/advance/A, actual_power)
for(var/E in M.reagents.reagent_list) //Not just toxins!
var/datum/reagent/R = E
M.reagents.remove_reagent(R.type, actual_power)
if(food_conversion)
M.nutrition += 0.3
if(prob(2))
to_chat(M, "<span class='notice'>You feel a mild warmth as your blood purifies itself.</span>")
return 1
/datum/symptom/heal/metabolism
name = "Metabolic Boost"
stealth = -1
resistance = -2
stage_speed = 2
transmittable = 1
level = 7
var/triple_metabolism = FALSE
var/reduced_hunger = FALSE
desc = "The virus causes the host's metabolism to accelerate rapidly, making them process chemicals twice as fast,\
but also causing increased hunger."
threshold_desc = list(
"Stealth 3" = "Reduces hunger rate.",
"Stage Speed 10" = "Chemical metabolization is tripled instead of doubled.",
)
/datum/symptom/heal/metabolism/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 10)
triple_metabolism = TRUE
if(A.properties["stealth"] >= 3)
reduced_hunger = TRUE
/datum/symptom/heal/metabolism/Heal(mob/living/carbon/C, datum/disease/advance/A, actual_power)
if(!istype(C))
return
C.reagents.metabolize(C, can_overdose=TRUE) //this works even without a liver; it's intentional since the virus is metabolizing by itself
if(triple_metabolism)
C.reagents.metabolize(C, can_overdose=TRUE)
C.overeatduration = max(C.overeatduration - 2, 0)
var/lost_nutrition = 9 - (reduced_hunger * 5)
C.nutrition = max(C.nutrition - (lost_nutrition * HUNGER_FACTOR), 0) //Hunger depletes at 10x the normal speed
if(prob(2))
to_chat(C, "<span class='notice'>You feel an odd gurgle in your stomach, as if it was working much faster than normal.</span>")
return 1
/datum/symptom/heal/darkness
name = "Nocturnal Regeneration"
desc = "The virus is able to mend the host's flesh when in conditions of low light, repairing physical damage. More effective against brute damage."
stealth = 2
resistance = -1
stage_speed = -2
transmittable = -1
level = 6
passive_message = "<span class='notice'>You feel tingling on your skin as light passes over it.</span>"
threshold_desc = list(
"Stage Speed 8" = "Doubles healing speed.",
)
/datum/symptom/heal/darkness/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 8)
power = 2
/datum/symptom/heal/darkness/CanHeal(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
var/light_amount = 0
if(isturf(M.loc)) //else, there's considered to be no light
var/turf/T = M.loc
light_amount = min(1,T.get_lumcount()) - 0.5
if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD)
return power
/datum/symptom/heal/darkness/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = 2 * actual_power
var/list/parts = M.get_damaged_bodyparts(1,1)
if(!parts.len)
return
if(prob(5))
to_chat(M, "<span class='notice'>The darkness soothes and mends your wounds.</span>")
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len * 0.5)) //more effective on brute
M.update_damage_overlays()
return 1
/datum/symptom/heal/darkness/passive_message_condition(mob/living/M)
if(M.getBruteLoss() || M.getFireLoss())
return TRUE
return FALSE
/datum/symptom/heal/coma
name = "Regenerative Coma"
desc = "The virus causes the host to fall into a death-like coma when severely damaged, then rapidly fixes the damage."
stealth = 0
resistance = 2
stage_speed = -3
transmittable = -2
level = 8
passive_message = "<span class='notice'>The pain from your wounds makes you feel oddly sleepy...</span>"
var/deathgasp = FALSE
var/stabilize = FALSE
var/active_coma = FALSE //to prevent multiple coma procs
threshold_desc = list(
"Stealth 2" = "Host appears to die when falling into a coma.",
"Resistance 4" = "The virus also stabilizes the host while they are in critical condition.",
"Stage Speed 7" = "Increases healing speed.",
)
/datum/symptom/heal/coma/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 7)
power = 1.5
if(A.properties["resistance"] >= 4)
stabilize = TRUE
if(A.properties["stealth"] >= 2)
deathgasp = TRUE
/datum/symptom/heal/coma/on_stage_change(datum/disease/advance/A) //mostly copy+pasted from the code for self-respiration's TRAIT_NOBREATH stuff
if(!..())
return FALSE
if(A.stage >= 4 && stabilize)
ADD_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
else
REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
return TRUE
/datum/symptom/heal/coma/End(datum/disease/advance/A)
if(!..())
return
REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
/datum/symptom/heal/coma/CanHeal(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
if(HAS_TRAIT(M, TRAIT_DEATHCOMA))
return power
else if(M.IsUnconscious() || M.stat == UNCONSCIOUS)
return power * 0.9
else if(M.stat == SOFT_CRIT)
return power * 0.5
else if(M.IsSleeping())
return power * 0.25
else if(M.getBruteLoss() + M.getFireLoss() >= 70 && !active_coma)
to_chat(M, "<span class='warning'>You feel yourself slip into a regenerative coma...</span>")
active_coma = TRUE
addtimer(CALLBACK(src, .proc/coma, M), 60)
/datum/symptom/heal/coma/proc/coma(mob/living/M)
if(deathgasp)
M.emote("deathgasp")
M.fakedeath("regenerative_coma")
M.update_stat()
M.update_canmove()
addtimer(CALLBACK(src, .proc/uncoma, M), 300)
/datum/symptom/heal/coma/proc/uncoma(mob/living/M)
if(!active_coma)
return
active_coma = FALSE
M.cure_fakedeath("regenerative_coma")
M.update_stat()
M.update_canmove()
/datum/symptom/heal/coma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = 4 * actual_power
var/list/parts = M.get_damaged_bodyparts(1,1)
if(!parts.len)
return
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len))
M.update_damage_overlays()
if(active_coma && M.getBruteLoss() + M.getFireLoss() == 0)
uncoma(M)
return 1
/datum/symptom/heal/coma/passive_message_condition(mob/living/M)
if((M.getBruteLoss() + M.getFireLoss()) > 30)
return TRUE
return FALSE
/datum/symptom/heal/water
name = "Tissue Hydration"
desc = "The virus uses excess water inside and outside the body to repair damaged tissue cells. More effective against burns."
stealth = 0
resistance = -1
stage_speed = 0
transmittable = 1
level = 6
passive_message = "<span class='notice'>Your skin feels oddly dry...</span>"
var/absorption_coeff = 1
threshold_desc = list(
"Resistance 5" = "Water is consumed at a much slower rate.",
"Stage Speed 7" = "Increases healing speed.",
)
/datum/symptom/heal/water/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 7)
power = 2
if(A.properties["stealth"] >= 2)
absorption_coeff = 0.25
/datum/symptom/heal/water/CanHeal(datum/disease/advance/A)
. = 0
var/mob/living/M = A.affected_mob
if(M.fire_stacks < 0)
M.fire_stacks = min(M.fire_stacks + 1 * absorption_coeff, 0)
. += power
if(M.reagents.has_reagent(/datum/reagent/water/holywater))
M.reagents.remove_reagent(/datum/reagent/water/holywater, 0.5 * absorption_coeff)
. += power * 0.75
else if(M.reagents.has_reagent(/datum/reagent/water))
M.reagents.remove_reagent(/datum/reagent/water, 0.5 * absorption_coeff)
. += power * 0.5
/datum/symptom/heal/water/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = 2 * actual_power
var/list/parts = M.get_damaged_bodyparts(1,1) //more effective on burns
if(!parts.len)
return
if(prob(5))
to_chat(M, "<span class='notice'>You feel yourself absorbing the water around you to soothe your damaged skin.</span>")
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len * 0.5, heal_amt/parts.len))
M.update_damage_overlays()
return 1
/datum/symptom/heal/water/passive_message_condition(mob/living/M)
if(M.getBruteLoss() || M.getFireLoss())
return TRUE
return FALSE
/datum/symptom/heal/plasma
name = "Plasma Fixation"
desc = "The virus draws plasma from the atmosphere and from inside the body to heal and stabilize body temperature."
stealth = 0
resistance = 3
stage_speed = -2
transmittable = -2
level = 8
passive_message = "<span class='notice'>You feel an odd attraction to plasma.</span>"
var/temp_rate = 1
threshold_desc = list(
"Transmission 6" = "Additionally increases temperature adjustment rate and heals those who love toxins",
"Resistance 7" = "Increases healing speed.",
)
/datum/symptom/heal/plasma/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 7)
power = 2
if(A.properties["transmittable"] >= 6)
temp_rate = 4
/datum/symptom/heal/plasma/CanHeal(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
var/datum/gas_mixture/environment
var/plasmamount
. = 0
if(M.loc)
environment = M.loc.return_air()
if(environment)
plasmamount = environment.gases[/datum/gas/plasma]
if(plasmamount && plasmamount > GLOB.meta_gas_visibility[/datum/gas/plasma]) //if there's enough plasma in the air to see
. += power * 0.5
if(M.reagents.has_reagent(/datum/reagent/toxin/plasma))
. += power * 0.75
/datum/symptom/heal/plasma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = 4 * actual_power
if(prob(5))
to_chat(M, "<span class='notice'>You feel yourself absorbing plasma inside and around you...</span>")
if(M.bodytemperature > BODYTEMP_NORMAL)
M.adjust_bodytemperature(-20 * temp_rate * TEMPERATURE_DAMAGE_COEFFICIENT,BODYTEMP_NORMAL)
if(prob(5))
to_chat(M, "<span class='notice'>You feel less hot.</span>")
else if(M.bodytemperature < (BODYTEMP_NORMAL + 1))
M.adjust_bodytemperature(20 * temp_rate * TEMPERATURE_DAMAGE_COEFFICIENT,0,BODYTEMP_NORMAL)
if(prob(5))
to_chat(M, "<span class='notice'>You feel warmer.</span>")
M.adjustToxLoss(-heal_amt)
var/list/parts = M.get_damaged_bodyparts(1,1)
if(!parts.len)
return
if(prob(5))
to_chat(M, "<span class='notice'>The pain from your wounds fades rapidly.</span>")
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len))
M.update_damage_overlays()
return 1
/datum/symptom/heal/radiation
name = "Radioactive Resonance"
desc = "The virus uses radiation to fix damage through dna mutations."
stealth = -1
resistance = -2
stage_speed = 2
transmittable = -3
level = 6
symptom_delay_min = 1
symptom_delay_max = 1
passive_message = "<span class='notice'>Your skin glows faintly for a moment.</span>"
var/cellular_damage = FALSE
threshold_desc = "<b>Transmission 6:</b> Additionally heals cellular damage.<br>\
<b>Resistance 7:</b> Increases healing speed."
/datum/symptom/heal/radiation/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["resistance"] >= 7)
power = 2
if(A.properties["transmittable"] >= 6)
cellular_damage = TRUE
ADD_TRAIT(A.affected_mob, TRAIT_RADRESONANCE, DISEASE_TRAIT)
/datum/symptom/heal/radiation/CanHeal(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
switch(M.radiation)
if(0)
return FALSE
if(1 to RAD_MOB_SAFE)
return 0.25
if(RAD_MOB_SAFE to RAD_BURN_THRESHOLD)
return 0.5
if(RAD_BURN_THRESHOLD to RAD_MOB_MUTATE)
return 0.75
if(RAD_MOB_MUTATE to RAD_MOB_KNOCKDOWN)
return 1
else
return 1.5
/datum/symptom/heal/radiation/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = actual_power
if(cellular_damage)
M.adjustCloneLoss(-heal_amt * 0.5)
M.adjustToxLoss(-(2 * heal_amt))
var/list/parts = M.get_damaged_bodyparts(1,1)
if(!parts.len)
return
if(prob(4))
to_chat(M, "<span class='notice'>Your skin glows faintly, and you feel your wounds mending themselves.</span>")
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len))
M.update_damage_overlays()
return 1
/datum/symptom/heal/radiation/End(datum/disease/advance/A)
if(!..())
return
REMOVE_TRAIT(A.affected_mob, TRAIT_RADRESONANCE, DISEASE_TRAIT)
@@ -29,8 +29,10 @@ BONUS
symptom_delay_min = 5
symptom_delay_max = 25
var/scratch = FALSE
threshold_desc = "<b>Transmission 6:</b> Increases frequency of itching.<br>\
<b>Stage Speed 7:</b> The host will scrath itself when itching, causing superficial damage."
threshold_desc = list(
"Transmission 6" = "Increases frequency of itching.",
"Stage Speed 7" = "The host will scrath itself when itching, causing superficial damage.",
)
/datum/symptom/itching/Start(datum/disease/advance/A)
if(!..())
@@ -10,8 +10,10 @@
symptom_delay_min = 1
symptom_delay_max = 1
var/reverse_boost = FALSE
threshold_desc = "<b>Transmission 5:</b> Increases the virus' growth rate while nanites are present.<br>\
<b>Stage Speed 7:</b> Increases the replication boost."
threshold_desc = list(
"Transmission 5" = "Increases the virus' growth rate while nanites are present.",
"Stage Speed 7" = "Increases the replication boost."
)
/datum/symptom/nano_boost/Start(datum/disease/advance/A)
if(!..())
@@ -42,8 +44,10 @@
symptom_delay_min = 1
symptom_delay_max = 1
var/reverse_boost = FALSE
threshold_desc = "<b>Stage Speed 5:</b> Increases the virus' growth rate while nanites are present.<br>\
<b>Resistance 7:</b> Severely increases the rate at which the nanites are destroyed."
threshold_desc = list(
"Stage Speed 5" = "Increases the virus' growth rate while nanites are present.",
"Resistance 7" = "Severely increases the rate at which the nanites are destroyed."
)
/datum/symptom/nano_destroy/Start(datum/disease/advance/A)
if(!..())
@@ -26,8 +26,10 @@ Bonus
var/sleep_level = 0
var/sleepy_ticks = 0
var/stamina = FALSE
threshold_desc = "<b>Transmission 7:</b> Also relaxes the muscles, weakening and slowing the host.<br>\
<b>Resistance 10:</b> Causes narcolepsy more often, increasing the chance of the host falling asleep."
threshold_desc = list(
"Transmission 4" = "Causes the host to periodically emit a yawn that spreads the virus in a manner similar to that of a sneeze.",
"Stage Speed 10" = "Causes narcolepsy more often, increasing the chance of the host falling asleep.",
)
/datum/symptom/narcolepsy/Start(datum/disease/advance/A)
if(!..())
+69 -67
View File
@@ -1,68 +1,70 @@
/*
//////////////////////////////////////
Self-Respiration
Slightly hidden.
Lowers resistance significantly.
Decreases stage speed significantly.
Decreases transmittablity tremendously.
Fatal Level.
Bonus
The body generates salbutamol.
//////////////////////////////////////
*/
/datum/symptom/oxygen
name = "Self-Respiration"
desc = "The virus rapidly synthesizes oxygen, effectively removing the need for breathing."
stealth = 1
resistance = -3
stage_speed = -3
transmittable = -4
level = 6
base_message_chance = 5
symptom_delay_min = 1
symptom_delay_max = 1
var/regenerate_blood = FALSE
threshold_desc = "<b>Resistance 8:</b>Additionally regenerates lost blood.<br>"
/datum/symptom/oxygen/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["resistance"] >= 8) //blood regeneration
regenerate_blood = TRUE
/datum/symptom/oxygen/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/carbon/M = A.affected_mob
switch(A.stage)
if(4, 5)
M.adjustOxyLoss(-7, 0)
M.losebreath = max(0, M.losebreath - 4)
if(regenerate_blood && M.blood_volume < (BLOOD_VOLUME_NORMAL * M.blood_ratio))
M.blood_volume += 1
else
if(prob(base_message_chance))
to_chat(M, "<span class='notice'>[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]</span>")
return
/datum/symptom/oxygen/on_stage_change(datum/disease/advance/A)
if(!..())
return FALSE
var/mob/living/carbon/M = A.affected_mob
if(A.stage >= 4)
ADD_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT)
else
REMOVE_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT)
return TRUE
/datum/symptom/oxygen/End(datum/disease/advance/A)
if(!..())
return
if(A.stage >= 4)
/*
//////////////////////////////////////
Self-Respiration
Slightly hidden.
Lowers resistance significantly.
Decreases stage speed significantly.
Decreases transmittablity tremendously.
Fatal Level.
Bonus
The body generates salbutamol.
//////////////////////////////////////
*/
/datum/symptom/oxygen
name = "Self-Respiration"
desc = "The virus rapidly synthesizes oxygen, effectively removing the need for breathing."
stealth = 1
resistance = -3
stage_speed = -3
transmittable = -4
level = 6
base_message_chance = 5
symptom_delay_min = 1
symptom_delay_max = 1
var/regenerate_blood = FALSE
threshold_desc = list(
"Resistance 8" = "Additionally regenerates lost blood."
)
/datum/symptom/oxygen/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["resistance"] >= 8) //blood regeneration
regenerate_blood = TRUE
/datum/symptom/oxygen/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/carbon/M = A.affected_mob
switch(A.stage)
if(4, 5)
M.adjustOxyLoss(-7, 0)
M.losebreath = max(0, M.losebreath - 4)
if(regenerate_blood && M.blood_volume < (BLOOD_VOLUME_NORMAL * M.blood_ratio))
M.blood_volume += 1
else
if(prob(base_message_chance))
to_chat(M, "<span class='notice'>[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]</span>")
return
/datum/symptom/oxygen/on_stage_change(datum/disease/advance/A)
if(!..())
return FALSE
var/mob/living/carbon/M = A.affected_mob
if(A.stage >= 4)
ADD_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT)
else
REMOVE_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT)
return TRUE
/datum/symptom/oxygen/End(datum/disease/advance/A)
if(!..())
return
if(A.stage >= 4)
REMOVE_TRAIT(A.affected_mob, TRAIT_NOBREATH, DISEASE_TRAIT)
@@ -11,9 +11,11 @@
var/purge_alcohol = FALSE
var/trauma_heal_mild = FALSE
var/trauma_heal_severe = FALSE
threshold_desc = "<b>Resistance 6:</b> Heals minor brain traumas.<br>\
<b>Resistance 9:</b> Heals severe brain traumas.<br>\
<b>Transmission 8:</b> Purges alcohol in the bloodstream."
threshold_desc = list(
"Resistance 6" = "Heals minor brain traumas.",
"Resistance 9" = "Heals severe brain traumas.",
"Transmission 8" = "Purges alcohol in the bloodstream.",
)
/datum/symptom/mind_restoration/Start(datum/disease/advance/A)
if(!..())
@@ -27,8 +27,10 @@ Bonus
symptom_delay_min = 10
symptom_delay_max = 30
var/unsafe = FALSE //over the cold threshold
threshold_desc = "<b>Stage Speed 5:</b> Increases cooling speed; the host can fall below safe temperature levels.<br>\
<b>Stage Speed 10:</b> Further increases cooling speed."
threshold_desc = list(
"Stage Speed 5" = "Increases cooling speed,; the host can fall below safe temperature levels.",
"Stage Speed 10" = "Further increases cooling speed."
)
/datum/symptom/fever/Start(datum/disease/advance/A)
if(!..())
+53 -51
View File
@@ -1,52 +1,54 @@
/*
//////////////////////////////////////
Sneezing
Very Noticable.
Increases resistance.
Doesn't increase stage speed.
Very transmissible.
Low Level.
Bonus
Forces a spread type of AIRBORNE
with extra range!
//////////////////////////////////////
*/
/datum/symptom/sneeze
name = "Sneezing"
desc = "The virus causes irritation of the nasal cavity, making the host sneeze occasionally."
stealth = -2
resistance = 3
stage_speed = 0
transmittable = 4
level = 1
severity = 1
symptom_delay_min = 5
symptom_delay_max = 35
threshold_desc = "<b>Transmission 9:</b> Increases sneezing range, spreading the virus over a larger area.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/sneeze/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["transmittable"] >= 9) //longer spread range
power = 2
if(A.properties["stealth"] >= 4)
suppress_warning = TRUE
/datum/symptom/sneeze/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3)
if(!suppress_warning)
M.emote("sniff")
else
M.emote("sneeze")
if(M.CanSpreadAirborneDisease()) //don't spread germs if they covered their mouth
/*
//////////////////////////////////////
Sneezing
Very Noticable.
Increases resistance.
Doesn't increase stage speed.
Very transmissible.
Low Level.
Bonus
Forces a spread type of AIRBORNE
with extra range!
//////////////////////////////////////
*/
/datum/symptom/sneeze
name = "Sneezing"
desc = "The virus causes irritation of the nasal cavity, making the host sneeze occasionally."
stealth = -2
resistance = 3
stage_speed = 0
transmittable = 4
level = 1
severity = 1
symptom_delay_min = 5
symptom_delay_max = 35
threshold_desc = list(
"Transmission 9" = "Increases sneezing range, spreading the virus over 6 meter cone instead of over a 4 meter cone.",
"Stealth 4" = "The symptom remains hidden until active.",
)
/datum/symptom/sneeze/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["transmittable"] >= 9) //longer spread range
power = 2
if(A.properties["stealth"] >= 4)
suppress_warning = TRUE
/datum/symptom/sneeze/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3)
if(!suppress_warning)
M.emote("sniff")
else
M.emote("sneeze")
if(M.CanSpreadAirborneDisease()) //don't spread germs if they covered their mouth
A.spread(4 + power)
@@ -29,9 +29,10 @@ Bonus
symptom_delay_min = 25
symptom_delay_max = 80
var/remove_eyes = FALSE
threshold_desc = "<b>Resistance 12:</b> Weakens extraocular muscles, eventually leading to complete detachment of the eyes.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
threshold_desc = list(
"Resistance 12" = "Weakens extraocular muscles, eventually leading to complete detachment of the eyes.",
"Stealth 4" = "The symptom remains hidden until active.",
)
/datum/symptom/visionloss/Start(datum/disease/advance/A)
if(!..())
return
@@ -31,9 +31,11 @@ Bonus
var/scramble_language = FALSE
var/datum/language/current_language
var/datum/language_holder/original_language
threshold_desc = "<b>Transmission 14:</b> The host's language center of the brain is damaged, leading to complete inability to speak or understand any language.<br>\
<b>Stage Speed 7:</b> Changes voice more often.<br>\
<b>Stealth 3:</b> The symptom remains hidden until active."
threshold_desc = list(
"Transmission 14" = "The host's language center of the brain is damaged, leading to complete inability to speak or understand any language.",
"Stage Speed 7" = "Changes voice more often.",
"Stealth 3" = "The symptom remains hidden until active."
)
/datum/symptom/voice_change/Start(datum/disease/advance/A)
if(!..())
@@ -34,9 +34,11 @@ Bonus
symptom_delay_max = 80
var/vomit_blood = FALSE
var/proj_vomit = 0
threshold_desc = "<b>Resistance 7:</b> Host will vomit blood, causing internal damage.<br>\
<b>Transmission 7:</b> Host will projectile vomit, increasing vomiting range.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
threshold_desc = list(
"Resistance 7" = "Host will vomit blood, causing internal damage.",
"Transmission 7" = "Host will projectile vomit, increasing vomiting range.",
"Stealth 4" = "The symptom remains hidden until active."
)
/datum/symptom/vomit/Start(datum/disease/advance/A)
if(!..())
@@ -29,7 +29,9 @@ Bonus
base_message_chance = 100
symptom_delay_min = 15
symptom_delay_max = 45
threshold_desc = "<b>Stealth 2:</b> The symptom is less noticeable."
threshold_desc = list(
"Stealth 4" = "The symptom is less noticeable."
)
/datum/symptom/weight_loss/Start(datum/disease/advance/A)
if(!..())
@@ -48,4 +50,4 @@ Bonus
else
to_chat(M, "<span class='warning'><i>[pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")]</i></span>")
M.overeatduration = max(M.overeatduration - 100, 0)
M.nutrition = max(M.nutrition - 100, 0)
M.nutrition = max(M.nutrition - 100, 0)
+6 -2
View File
@@ -18,14 +18,18 @@
for(var/spawner in GLOB.mob_spawners)
var/list/this = list()
this["name"] = spawner
this["desc"] = ""
this["short_desc"] = ""
this["flavor_text"] = ""
this["important_warning"] = ""
this["refs"] = list()
for(var/spawner_obj in GLOB.mob_spawners[spawner])
this["refs"] += "[REF(spawner_obj)]"
if(!this["desc"])
if(istype(spawner_obj, /obj/effect/mob_spawn))
var/obj/effect/mob_spawn/MS = spawner_obj
this["desc"] = MS.flavour_text
this["short_desc"] = MS.short_desc
this["flavor_text"] = MS.flavour_text
this["important_info"] = MS.important_info
else
var/obj/O = spawner_obj
this["desc"] = O.desc
+2 -2
View File
@@ -215,8 +215,8 @@
/datum/wires/ui_interact(mob/user, ui_key = "wires", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if (!ui)
ui = new(user, src, ui_key, "wires", "[holder.name] wires", 350, 150 + wires.len * 30, master_ui, state)
if(!ui)
ui = new(user, src, ui_key, "wires", "[holder.name] Wires", 350, 150 + wires.len * 30, master_ui, state)
ui.open()
/datum/wires/ui_data(mob/user)
+7
View File
@@ -731,6 +731,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)
+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
+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 -8
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()
@@ -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
+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)
+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
@@ -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()
@@ -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)
+27 -105
View File
@@ -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))
+1 -1
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
+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)
+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)
+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)
+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))
+2 -2
View File
@@ -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,
+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))
+7 -9
View File
@@ -69,8 +69,10 @@ GLOBAL_LIST_EMPTY(GPS_list)
return
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
var/gps_window_height = 300 + GLOB.GPS_list.len * 20 // Variable window height, depending on how many GPS units there are to show
ui = new(user, src, ui_key, "gps", "Global Positioning System", 600, gps_window_height, master_ui, state) //width, height
// Variable window height, depending on how many GPS units there are
// to show, clamped to relatively safe range.
var/gps_window_height = CLAMP(325 + GLOB.GPS_list.len * 14, 325, 700)
ui = new(user, src, ui_key, "gps", "Global Positioning System", 470, gps_window_height, master_ui, state) //width, height
ui.open()
ui.set_autoupdate(state = updating)
@@ -87,6 +89,8 @@ GLOBAL_LIST_EMPTY(GPS_list)
var/turf/curr = get_turf(src)
data["current"] = "[get_area_name(curr, TRUE)] ([curr.x], [curr.y], [curr.z])"
data["currentArea"] = "[get_area_name(curr, TRUE)]"
data["currentCoords"] = "[curr.x], [curr.y], [curr.z]"
var/list/signals = list()
data["signals"] = list()
@@ -100,16 +104,10 @@ GLOBAL_LIST_EMPTY(GPS_list)
continue
var/list/signal = list()
signal["entrytag"] = G.gpstag //Name or 'tag' of the GPS
signal["area"] = get_area_name(G, TRUE)
signal["coord"] = "[pos.x], [pos.y], [pos.z]"
signal["coords"] = "[pos.x], [pos.y], [pos.z]"
if(pos.z == curr.z) //Distance/Direction calculations for same z-level only
signal["dist"] = max(get_dist(curr, pos), 0) //Distance between the src and remote GPS turfs
signal["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision.
var/direction = uppertext(dir2text(get_dir(curr, pos))) //Direction text (East, etc). Not as precise, but still helpful.
if(!direction)
direction = "CENTER"
signal["degrees"] = "N/A"
signal["direction"] = direction
signals += list(signal) //Add this signal to the list of signals
data["signals"] = signals
@@ -111,7 +111,14 @@
. = ..()
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "radio", name, 370, 220 + channels.len * 22, master_ui, state)
var/ui_width = 360
var/ui_height = 106
if(subspace_transmission)
if(channels.len > 0)
ui_height += 6 + channels.len * 21
else
ui_height += 24
ui = new(user, src, ui_key, "radio", name, ui_width, ui_height, master_ui, state)
ui.open()
/obj/item/radio/ui_data(mob/user)
+64 -45
View File
@@ -54,7 +54,7 @@
to_chat(user, "<span class='warning'>[src] was shaken recently, it needs time to settle.</span>")
return
user.visible_message("<span class='notice'>[user] starts shaking [src].</span>", "<span class='notice'>You start shaking [src].</span>", "<span class='italics'>You hear shaking and sloshing.</span>")
user.visible_message("<span class='notice'>[user] starts shaking [src].</span>", "<span class='notice'>You start shaking [src].</span>", "<span class='hear'>You hear shaking and sloshing.</span>")
shaking = TRUE
@@ -95,16 +95,47 @@
// except it actually ASKS THE DEAD (wooooo)
/obj/item/toy/eightball/haunted
shake_time = 150
cooldown_time = 1800
shake_time = 30 SECONDS
cooldown_time = 3 MINUTES
flags_1 = HEAR_1
var/last_message
var/selected_message
var/list/votes
//these kind of store the same thing but one is easier to work with.
var/list/votes = list()
var/list/voted = list()
var/static/list/haunted_answers = list(
"yes" = list(
"It is certain",
"It is decidedly so",
"Without a doubt",
"Yes definitely",
"You may rely on it",
"As I see it, yes",
"Most likely",
"Outlook good",
"Yes",
"Signs point to yes"
),
"maybe" = list(
"Reply hazy try again",
"Ask again later",
"Better not tell you now",
"Cannot predict now",
"Concentrate and ask again"
),
"no" = list(
"Don't count on it",
"My reply is no",
"My sources say no",
"Outlook not so good",
"Very doubtful"
)
)
/obj/item/toy/eightball/haunted/Initialize(mapload)
. = ..()
votes = list()
for (var/answer in haunted_answers)
votes[answer] = 0
GLOB.poi_list |= src
/obj/item/toy/eightball/haunted/Destroy()
@@ -137,38 +168,31 @@
if(isobserver(usr))
interact(usr)
/obj/item/toy/eightball/haunted/proc/get_vote_tallies()
var/list/answers = list()
for(var/ckey in votes)
var/selected = votes[ckey]
if(selected in answers)
answers[selected]++
else
answers[selected] = 1
return answers
/obj/item/toy/eightball/haunted/get_answer()
if(!votes.len)
return pick(possible_answers)
var/top_amount = 0
var/top_vote
var/list/tallied_votes = get_vote_tallies()
for(var/vote in votes)
var/amount_of_votes = length(votes[vote])
if(amount_of_votes > top_amount)
top_vote = vote
top_amount = amount_of_votes
//If one option actually has votes and there's a tie, pick between them 50/50
else if(top_amount && amount_of_votes == top_amount && prob(50))
top_vote = vote
top_amount = amount_of_votes
// I miss python sorting, then I wouldn't have to muck about with
// all this
var/most_popular_answer
var/most_amount = 0
// yes, if there is a tie, there is an arbitary decision
// but we never said the spirit world was fair
for(var/A in tallied_votes)
var/amount = tallied_votes[A]
if(amount > most_amount)
most_popular_answer = A
if(isnull(top_vote))
top_vote = pick(votes)
return most_popular_answer
for(var/vote in votes)
votes[vote] = 0
/obj/item/toy/eightball/haunted/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state = GLOB.observer_state)
voted.Cut()
return top_vote
/obj/item/toy/eightball/haunted/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state = GLOB.always_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
@@ -179,21 +203,13 @@
var/list/data = list()
data["shaking"] = shaking
data["question"] = selected_message
var/list/tallied_votes = get_vote_tallies()
data["answers"] = list()
for(var/pa in possible_answers)
for(var/pa in haunted_answers)
var/list/L = list()
L["answer"] = pa
var/amount = 0
if(pa in tallied_votes)
amount = tallied_votes[pa]
L["amount"] = amount
var/selected = FALSE
if(votes[user.ckey] == pa)
selected = TRUE
L["selected"] = selected
L["amount"] = votes[pa]
L["selected"] = voted[user.ckey]
data["answers"] += list(L)
return data
@@ -206,8 +222,11 @@
switch(action)
if("vote")
var/selected_answer = params["answer"]
if(!selected_answer in possible_answers)
if(!(selected_answer in haunted_answers))
return
if(user.ckey in voted)
return
else
votes[user.ckey] = selected_answer
votes[selected_answer] += 1
voted[user.ckey] = selected_answer
. = TRUE
+1 -1
View File
@@ -156,7 +156,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "tanks", name, 420, 200, master_ui, state)
ui = new(user, src, ui_key, "tanks", name, 400, 120, master_ui, state)
ui.open()
/obj/item/tank/ui_data(mob/user)
@@ -12,9 +12,11 @@
roundstart = FALSE
death = FALSE
mob_species = /datum/species/pod
flavour_text = "<span class='big bold'>You are a sentient ecosystem,</span><b> an example of the mastery over life that your creators possessed. Your masters, benevolent as they were, created uncounted \
seed vaults and spread them across the universe to every planet they could chart. You are in one such seed vault. Your goal is to cultivate and spread life wherever it will go while waiting \
for contact from your creators. Estimated time of last contact: Deployment, 5x10^3 millennia ago.</b>"
short_desc = "You are a sentient ecosystem, an example of the mastery over life that your creators possessed."
flavour_text = "Your masters, benevolent as they were, created uncounted seed vaults and spread them across \
the universe to every planet they could chart. You are in one such seed vault. \
Your goal is to cultivate and spread life wherever it will go while waiting for contact from your creators. \
Estimated time of last contact: Deployment, 5000 millennia ago."
assignedrole = "Lifebringer"
/obj/effect/mob_spawn/human/seed_vault/special(mob/living/new_spawn)
@@ -87,8 +89,9 @@
roundstart = FALSE
death = FALSE
mob_species = /datum/species/shadow
flavour_text = "<span class='big bold'>You are cursed.</span><b> Years ago, you sacrificed the lives of your trusted friends and the humanity of yourself to reach the Wish Granter. Though you \
did so, it has come at a cost: your very body rejects the light, dooming you to wander endlessly in this horrible wasteland.</b>"
short_desc = "You are cursed."
flavour_text = "Years ago, you sacrificed the lives of your trusted friends and the humanity of yourself to reach the Wish Granter. Though you \
did so, it has come at a cost: your very body rejects the light, dooming you to wander endlessly in this horrible wasteland."
assignedrole = "Exile"
/obj/effect/mob_spawn/human/exile/Destroy()
@@ -125,9 +128,10 @@
var/has_owner = FALSE
var/can_transfer = TRUE //if golems can switch bodies to this new shell
var/mob/living/owner = null //golem's owner if it has one
flavour_text = "<span class='big bold'>You are a Free Golem.</span><b> Your family worships <span class='danger'>The Liberator</span>. In his infinite and divine wisdom, he set your clan free to \
short_desc = "You are a Free Golem. Your family worships The Liberator."
flavour_text = "In his infinite and divine wisdom, he set your clan free to \
travel the stars with a single declaration: \"Yeah go do whatever.\" Though you are bound to the one who created you, it is customary in your society to repeat those same words to newborn \
golems, so that no golem may ever be forced to serve again.</b>"
golems, so that no golem may ever be forced to serve again."
/obj/effect/mob_spawn/human/golem/Initialize(mapload, datum/species/golem/species = null, mob/creator = null)
if(species) //spawners list uses object name to register so this goes before ..()
@@ -138,8 +142,9 @@
if(!mapload && A)
notify_ghosts("\A [initial(species.prefix)] golem shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_GOLEM)
if(has_owner && creator)
flavour_text = "<span class='big bold'>You are a Golem.</span><b> You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. \
Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost.</b>"
short_desc = "You are a golem."
flavour_text = "You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools."
important_info = "Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost."
owner = creator
/obj/effect/mob_spawn/human/golem/special(mob/living/new_spawn, name)
@@ -209,8 +214,9 @@
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You've been stranded in this godless prison of a planet for longer than you can remember.</span><b> Each day you barely scrape by, and between the terrible \
conditions of your makeshift shelter, the hostile creatures, and the ash drakes swooping down from the cloudless skies, all you can wish for is the feel of soft grass between your toes and \
short_desc = "You've been stranded in this godless prison of a planet for longer than you can remember."
flavour_text = "Each day you barely scrape by, and between the terrible conditions of your makeshift shelter, \
the hostile creatures, and the ash drakes swooping down from the cloudless skies, all you can wish for is the feel of soft grass between your toes and \
the fresh air of Earth. These thoughts are dispelled by yet another recollection of how you got here... "
assignedrole = "Hermit"
mirrorcanloadappearance = TRUE
@@ -222,20 +228,20 @@
if(1)
flavour_text += "you were a [pick("arms dealer", "shipwright", "docking manager")]'s assistant on a small trading station several sectors from here. Raiders attacked, and there was \
only one pod left when you got to the escape bay. You took it and launched it alone, and the crowd of terrified faces crowding at the airlock door as your pod's engines burst to \
life and sent you to this hell are forever branded into your memory.</b>"
life and sent you to this hell are forever branded into your memory."
outfit.uniform = /obj/item/clothing/under/assistantformal
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
outfit.back = /obj/item/storage/backpack
if(2)
flavour_text += "you're an exile from the Tiger Cooperative. Their technological fanaticism drove you to question the power and beliefs of the Exolitics, and they saw you as a \
heretic and subjected you to hours of horrible torture. You were hours away from execution when a high-ranking friend of yours in the Cooperative managed to secure you a pod, \
scrambled its destination's coordinates, and launched it. You awoke from stasis when you landed and have been surviving - barely - ever since.</b>"
scrambled its destination's coordinates, and launched it. You awoke from stasis when you landed and have been surviving - barely - ever since."
outfit.uniform = /obj/item/clothing/under/rank/prisoner
outfit.shoes = /obj/item/clothing/shoes/sneakers/orange
outfit.back = /obj/item/storage/backpack
if(3)
flavour_text += "you were a doctor on one of Nanotrasen's space stations, but you left behind that damn corporation's tyranny and everything it stood for. From a metaphorical hell \
to a literal one, you find yourself nonetheless missing the recycled air and warm floors of what you left behind... but you'd still rather be here than there.</b>"
to a literal one, you find yourself nonetheless missing the recycled air and warm floors of what you left behind... but you'd still rather be here than there."
outfit.uniform = /obj/item/clothing/under/rank/medical
outfit.suit = /obj/item/clothing/suit/toggle/labcoat
outfit.back = /obj/item/storage/backpack/medic
@@ -243,7 +249,7 @@
if(4)
flavour_text += "you were always joked about by your friends for \"not playing with a full deck\", as they so <i>kindly</i> put it. It seems that they were right when you, on a tour \
at one of Nanotrasen's state-of-the-art research facilities, were in one of the escape pods alone and saw the red button. It was big and shiny, and it caught your eye. You pressed \
it, and after a terrifying and fast ride for days, you landed here. You've had time to wisen up since then, and you think that your old friends wouldn't be laughing now.</b>"
it, and after a terrifying and fast ride for days, you landed here. You've had time to wisen up since then, and you think that your old friends wouldn't be laughing now."
outfit.uniform = /obj/item/clothing/under/color/grey/glorf
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
outfit.back = /obj/item/storage/backpack
@@ -258,9 +264,10 @@
desc = "A small sleeper typically used to instantly restore minor wounds. This one seems broken, and its occupant is comatose."
job_description = "Lavaland Veterinarian"
mob_name = "a translocated vet"
flavour_text = "<span class='big bold'>What...?</span><b> Where are you? Where are the others? This is still the animal hospital - you should know, you've been an intern here for weeks - but \
everyone's gone. One of the cats scratched you just a few minutes ago. That's why you were in the pod - to heal the scratch. The scabs are still fresh; you see them right now. So where is \
everyone? Where did they go? What happened to the hospital? And is that <i>smoke</i> you smell? You need to find someone else. Maybe they can tell you what happened.</b>"
short_desc = "You are a animal doctor who just woke up in lavaland"
flavour_text = "What...? Where are you? Where are the others? This is still the animal hospital - you should know, you've been an intern here for weeks - but \
you see them right now. So where is \
everyone? Where did they go? What happened to the hospital? And is that <i>smoke</i> you smell? You need to find someone else. Maybe they c everyone's gone. One of the cats scratched you just a few minutes ago. That's why you were in the pod - to heal the scratch. The scabs are still fresh; an tell you what happened."
assignedrole = "Translocated Vet"
mirrorcanloadappearance = TRUE
@@ -280,8 +287,9 @@
outfit = /datum/outfit/lavalandprisoner
roundstart = FALSE
death = FALSE
flavour_text = "<b>Good. It seems as though your ship crashed. <span class='big bold'>You're a prisoner,</span> sentenced to hard work in one of Nanotrasen's labor camps, but it seems as \
though fate has other plans for you. You remember that you were convicted of "
short_desc = "You're a prisoner, sentenced to hard work in one of Nanotrasen's labor camps, but it seems as \
though fate has other plans for you."
flavour_text = "Good. It seems as though your ship crashed. You remember that you were convicted of "
assignedrole = "Escaped Prisoner"
/obj/effect/mob_spawn/human/prisoner_transport/special(mob/living/L)
@@ -293,7 +301,7 @@
var/list/crimes = list("murder", "larceny", "embezzlement", "unionization", "dereliction of duty", "kidnapping", "gross incompetence", "grand theft", "collaboration with the Syndicate", \
"worship of a forbidden deity", "interspecies relations", "mutiny")
flavour_text += "[pick(crimes)]. but regardless of that, it seems like your crime doesn't matter now. You don't know where you are, but you know that it's out to kill you, and you're not going \
to lose this opportunity. Find a way to get out of this mess and back to where you rightfully belong - your [pick("house", "apartment", "spaceship", "station")]</b>."
to lose this opportunity. Find a way to get out of this mess and back to where you rightfully belong - your [pick("house", "apartment", "spaceship", "station")]."
/datum/outfit/lavalandprisoner
name = "Lavaland Prisoner"
@@ -320,8 +328,9 @@
roundstart = FALSE
random = TRUE
outfit = /datum/outfit/hotelstaff
flavour_text = "<span class='big bold'>You are a staff member of a top-of-the-line space hotel!</span><b> Cater to guests and <font size=6><b>DON'T</b></font> leave the hotel, lest the manager fire you for\
dereliction of duty!</b>"
short_desc = "You are a staff member of a top-of-the-line space hotel!"
flavour_text = "You are a staff member of a top-of-the-line space hotel! Cater to guests and make sure the manager doesn't fire you."
important_info = "DON'T leave the hotel"
assignedrole = "Hotel Staff"
mirrorcanloadappearance = TRUE
@@ -338,8 +347,10 @@
mob_name = "hotel security member"
job_description = "Hotel Security"
outfit = /datum/outfit/hotelstaff/security
flavour_text = "<span class='big bold'>You are a peacekeeper</span><b> assigned to this hotel to protect the interests of the company while keeping the peace between \
guests and the staff. Do <font size=6>NOT</font> leave the hotel, as that is grounds for contract termination.</b>"
short_desc = "You are a peacekeeper."
flavour_text = "You have been assigned to this hotel to protect the interests of the company while keeping the peace between \
guests and the staff."
important_info = "Do NOT leave the hotel, as that is grounds for contract termination."
objectives = "Do not leave your assigned hotel. Try and keep the peace between staff and guests, non-lethal force heavily advised if possible."
mirrorcanloadappearance = TRUE
@@ -376,7 +387,8 @@
/obj/effect/mob_spawn/human/demonic_friend/Initialize(mapload, datum/mind/owner_mind, obj/effect/proc_holder/spell/targeted/summon_friend/summoning_spell)
. = ..()
owner = owner_mind
flavour_text = "<span class='big bold'>You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil.</span><b> Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell.</b>"
flavour_text = "You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil."
important_info = "Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell."
var/area/A = get_area(src)
if(!mapload && A)
notify_ghosts("\A friendship shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE)
@@ -434,9 +446,9 @@
/obj/effect/mob_spawn/human/syndicate/battlecruiser
name = "Syndicate Battlecruiser Ship Operative"
flavour_text = "<span class='big bold'>You are a crewmember aboard the syndicate flagship: the SBC Starfury.</span><span class='big'> <span class='danger'><b>Your job is to follow your captain's orders, maintain the ship, and keep the engine running.</b></span> If you are not familiar with how the supermatter engine functions: <b>do not attempt to start it.</b><br>\
<br>\
<span class='danger'><b>The armory is not a candy store, and your role is not to assault the station directly, leave that work to the assault operatives.</b></span></font>"
short_desc = "You are a crewmember aboard the syndicate flagship: the SBC Starfury."
flavour_text = "Your job is to follow your captain's orders, maintain the ship, and keep the engine running. If you are not familiar with how the supermatter engine functions: do not attempt to start it."
important_info = "The armory is not a candy store, and your role is not to assault the station directly, leave that work to the assault operatives."
outfit = /datum/outfit/syndicate_empty/SBC
mirrorcanloadappearance = TRUE
@@ -447,10 +459,9 @@
belt = /obj/item/storage/belt/military/assault
/obj/effect/mob_spawn/human/syndicate/battlecruiser/assault
name = "Syndicate Battlecruiser Assault Operative"
flavour_text = "<span class='big bold'>You are an assault operative aboard the syndicate flagship: the SBC Starfury.</span><span class='big'> <span class='danger'><b>Your job is to follow your captain's orders, keep intruders out of the ship, and assault Space Station 13.</b></span> There is an armory, multiple assault ships, and beam cannons to attack the station with.<br>\
<br>\
<span class='danger'><b>Work as a team with your fellow operatives and work out a plan of attack. If you are overwhelmed, escape back to your ship!</b></span></span>"
short_desc = "You are an assault operative aboard the syndicate flagship: the SBC Starfury."
flavour_text = "Your job is to follow your captain's orders, keep intruders out of the ship, and assault Space Station 13. There is an armory, multiple assault ships, and beam cannons to attack the station with."
important_info = "Work as a team with your fellow operatives and work out a plan of attack. If you are overwhelmed, escape back to your ship!"
outfit = /datum/outfit/syndicate_empty/SBC/assault
mirrorcanloadappearance = TRUE
@@ -467,9 +478,9 @@
/obj/effect/mob_spawn/human/syndicate/battlecruiser/captain
name = "Syndicate Battlecruiser Captain"
flavour_text = "<span class='big bold'>You are the captain aboard the syndicate flagship: the SBC Starfury.</span><span class='big'> <span class='danger'><b>Your job is to oversee your crew, defend the ship, and destroy Space Station 13.</b></span> The ship has an armory, multiple ships, beam cannons, and multiple crewmembers to accomplish this goal.<br>\
<br>\
<span class='danger'><b>As the captain, this whole operation falls on your shoulders.</b></span> You do not need to nuke the station, causing sufficient damage and preventing your ship from being destroyed will be enough.</span>"
short_desc = "You are the captain aboard the syndicate flagship: the SBC Starfury."
flavour_text = "Your job is to oversee your crew, defend the ship, and destroy Space Station 13. The ship has an armory, multiple ships, beam cannons, and multiple crewmembers to accomplish this goal."
important_info = "As the captain, this whole operation falls on your shoulders. You do not need to nuke the station, causing sufficient damage and preventing your ship from being destroyed will be enough."
outfit = /datum/outfit/syndicate_empty/SBC/assault/captain
id_access_list = list(150,151)
mirrorcanloadappearance = TRUE
@@ -496,10 +507,11 @@
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You are a security officer working for Nanotrasen,</span><b> stationed onboard a state of the art research station. You vaguely recall rushing into a \
cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \
Work as a team with your fellow survivors and do not abandon them.</b>"
short_desc = "You are a security officer working for Nanotrasen, stationed onboard a state of the art research station."
flavour_text = "You vaguely recall rushing into a cryogenics pod due to an oncoming radiation storm. \
The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod."
important_info = "Work as a team with your fellow survivors and do not abandon them."
uniform = /obj/item/clothing/under/rank/security
shoes = /obj/item/clothing/shoes/jackboots
id = /obj/item/card/id/away/old/sec
@@ -524,10 +536,11 @@
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You are an engineer working for Nanotrasen,</span><b> stationed onboard a state of the art research station. You vaguely recall rushing into a \
cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \
Work as a team with your fellow survivors and do not abandon them.</b>"
short_desc = "You are an engineer working for Nanotrasen, stationed onboard a state of the art research station."
flavour_text = "You vaguely recall rushing into a cryogenics pod due to an oncoming radiation storm. The last thing \
you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod."
important_info = "Work as a team with your fellow survivors and do not abandon them."
uniform = /obj/item/clothing/under/rank/engineer
shoes = /obj/item/clothing/shoes/workboots
id = /obj/item/card/id/away/old/eng
@@ -550,10 +563,11 @@
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You are a scientist working for Nanotrasen,</span><b> stationed onboard a state of the art research station. You vaguely recall rushing into a \
cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \
Work as a team with your fellow survivors and do not abandon them.</b>"
short_desc = "You are a scientist working for Nanotrasen, stationed onboard a state of the art research station."
flavour_text = "You vaguely recall rushing into a cryogenics pod due to an oncoming radiation storm. \
The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod."
important_info = "Work as a team with your fellow survivors and do not abandon them."
uniform = /obj/item/clothing/under/rank/scientist
shoes = /obj/item/clothing/shoes/laceup
id = /obj/item/card/id/away/old/sci
@@ -581,7 +595,8 @@
anchored = TRUE
density = FALSE
show_flavour = FALSE //Flavour only exists for spawners menu
flavour_text = "<span class='big bold'>You are a space pirate.</span><b> The station refused to pay for your protection, protect the ship, siphon the credits from the station and raid it for even more loot.</b>"
short_desc = "You are a space pirate."
flavour_text = "The station refused to pay for your protection, protect the ship, siphon the credits from the station and raid it for even more loot."
assignedrole = "Space Pirate"
var/rank = "Mate"
@@ -71,7 +71,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "tank_dispenser", name, 275, 100, master_ui, state)
ui = new(user, src, ui_key, "tank_dispenser", name, 275, 103, master_ui, state)
ui.open()
/obj/structure/tank_dispenser/ui_data(mob/user)
+3
View File
@@ -118,6 +118,8 @@ GLOBAL_VAR(restart_counter)
GLOB.world_runtime_log = "[GLOB.log_directory]/runtime.log"
GLOB.query_debug_log = "[GLOB.log_directory]/query_debug.log"
GLOB.world_job_debug_log = "[GLOB.log_directory]/job_debug.log"
GLOB.tgui_log = "[GLOB.log_directory]/tgui.log"
#ifdef UNIT_TESTS
GLOB.test_log = file("[GLOB.log_directory]/tests.log")
@@ -132,6 +134,7 @@ GLOBAL_VAR(restart_counter)
start_log(GLOB.world_qdel_log)
start_log(GLOB.world_runtime_log)
start_log(GLOB.world_job_debug_log)
start_log(GLOB.tgui_log)
GLOB.changelog_hash = md5('html/changelog.html') //for telling if the changelog has changed recently
if(fexists(GLOB.config_error_log))
+5
View File
@@ -202,6 +202,11 @@
if(filename == P.filename)
return P
/datum/ntnet/proc/get_chat_channel_by_id(id)
for(var/datum/ntnet_conversation/chan in chat_channels)
if(chan.id == id)
return chan
// Resets the IDS alarm
/datum/ntnet/proc/resetIDS()
intrusion_detection_alarm = FALSE
+7 -2
View File
@@ -9,6 +9,9 @@
icon_state = "bus"
density = TRUE
circuit = /obj/item/circuitboard/machine/ntnet_relay
ui_x = 400
ui_y = 300
var/datum/ntnet/NTNet = null // This is mostly for backwards reference and to allow varedit modifications from ingame.
var/enabled = 1 // Set to 0 if the relay was turned off
var/dos_failure = 0 // Set to 1 if the relay failed due to (D)DoS attack
@@ -66,7 +69,7 @@
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "ntnet_relay", "NTNet Quantum Relay", 500, 300, master_ui, state)
ui = new(user, src, ui_key, "ntnet_relay", "NTNet Quantum Relay", ui_x, ui_y, master_ui, state)
ui.open()
@@ -88,10 +91,12 @@
dos_failure = 0
update_icon()
SSnetworks.station_network.add_log("Quantum relay manually restarted from overload recovery mode to normal operation mode.")
return TRUE
if("toggle")
enabled = !enabled
SSnetworks.station_network.add_log("Quantum relay manually [enabled ? "enabled" : "disabled"].")
update_icon()
return TRUE
/obj/machinery/ntnet_relay/Initialize()
uid = gl_uid++
@@ -113,4 +118,4 @@
D.target = null
D.error = "Connection to quantum relay severed"
return ..()
return ..()
@@ -57,7 +57,7 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
var/short_desc = ""
var/long_desc = ""
var/stat_block = ""
var/threshold_block = ""
var/threshold_block = list()
var/category = ""
var/list/symptoms
@@ -76,7 +76,7 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
resistance += initial(S.resistance)
stage_speed += initial(S.stage_speed)
transmittable += initial(S.transmittable)
threshold_block += "<br><br>[initial(S.threshold_desc)]"
threshold_block += initial(S.threshold_desc)
stat_block = "Resistance: [resistance]<br>Stealth: [stealth]<br>Stage Speed: [stage_speed]<br>Transmissibility: [transmittable]<br><br>"
if(symptoms.len == 1) //lazy boy's dream
name = initial(S.name)
@@ -325,7 +325,11 @@ the new instance inside the host to be updated to the template's stats.
var/list/dat = list()
if(examining_ability)
dat += "<a href='byond://?src=[REF(src)];main_menu=1'>Back</a><br><h1>[examining_ability.name]</h1>[examining_ability.stat_block][examining_ability.long_desc][examining_ability.threshold_block]"
dat += "<a href='byond://?src=[REF(src)];main_menu=1'>Back</a><br>"
dat += "<h1>[examining_ability.name]</h1>"
dat += "[examining_ability.stat_block][examining_ability.long_desc][examining_ability.threshold_block]"
for(var/entry in examining_ability.threshold_block)
dat += "<b>[entry]</b>: [examining_ability.threshold_block[entry]]<br>"
else
dat += "<h1>Disease Statistics</h1><br>\
Resistance: [DT.totalResistance()]<br>\
@@ -11,9 +11,10 @@
var/default_timer_set = 90
var/minimum_timer_set = 90
var/maximum_timer_set = 3600
var/ui_style = "nanotrasen"
ui_style = "nanotrasen"
var/numeric_input = ""
var/ui_mode = NUKEUI_AWAIT_DISK
var/timing = FALSE
var/exploding = FALSE
var/exploded = FALSE
@@ -97,6 +98,8 @@
if(!user.transferItemToLoc(I, src))
return
auth = I
update_ui_mode()
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
add_fingerprint(user)
return
@@ -233,113 +236,159 @@
var/volume = (get_time_left() <= 20 ? 30 : 5)
playsound(loc, 'sound/items/timer.ogg', volume, 0)
/obj/machinery/nuclearbomb/proc/update_ui_mode()
if(exploded)
ui_mode = NUKEUI_EXPLODED
return
if(!auth)
ui_mode = NUKEUI_AWAIT_DISK
return
if(timing)
ui_mode = NUKEUI_TIMING
return
if(!safety)
ui_mode = NUKEUI_AWAIT_ARM
return
if(!yes_code)
ui_mode = NUKEUI_AWAIT_CODE
return
ui_mode = NUKEUI_AWAIT_TIMER
/obj/machinery/nuclearbomb/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, "nuclear_bomb", name, 500, 600, master_ui, state)
ui = new(user, src, ui_key, "nuclear_bomb", name, 350, 442, master_ui, state)
ui.set_style(ui_style)
ui.open()
/obj/machinery/nuclearbomb/ui_data(mob/user)
var/list/data = list()
data["disk_present"] = auth
data["code_approved"] = yes_code
var/first_status
if(auth)
if(yes_code)
first_status = timing ? "Func/Set" : "Functional"
else
first_status = "Auth S2."
var/hidden_code = (ui_mode == NUKEUI_AWAIT_CODE && numeric_input != "ERROR")
var/current_code = ""
if(hidden_code)
while(length(current_code) < length(numeric_input))
current_code = "[current_code]*"
else
if(timing)
first_status = "Set"
else
first_status = "Auth S1."
var/second_status = exploded ? "Warhead triggered, thanks for flying Kinaris" : (safety ? "Safe" : "Engaged")
current_code = numeric_input
while(length(current_code) < 5)
current_code = "[current_code]-"
var/first_status
var/second_status
switch(ui_mode)
if(NUKEUI_AWAIT_DISK)
first_status = "DEVICE LOCKED"
if(timing)
second_status = "TIME: [get_time_left()]"
else
second_status = "AWAIT DISK"
if(NUKEUI_AWAIT_CODE)
first_status = "INPUT CODE"
second_status = "CODE: [current_code]"
if(NUKEUI_AWAIT_TIMER)
first_status = "INPUT TIME"
second_status = "TIME: [current_code]"
if(NUKEUI_AWAIT_ARM)
first_status = "DEVICE READY"
second_status = "TIME: [get_time_left()]"
if(NUKEUI_TIMING)
first_status = "DEVICE ARMED"
second_status = "TIME: [get_time_left()]"
if(NUKEUI_EXPLODED)
first_status = "DEVICE DEPLOYED"
second_status = "THANK YOU"
data["status1"] = first_status
data["status2"] = second_status
data["anchored"] = anchored
data["safety"] = safety
data["timing"] = timing
data["time_left"] = get_time_left()
data["timer_set"] = timer_set
data["timer_is_not_default"] = timer_set != default_timer_set
data["timer_is_not_min"] = timer_set != minimum_timer_set
data["timer_is_not_max"] = timer_set != maximum_timer_set
var/message = "AUTH"
if(auth)
message = "[numeric_input]"
if(yes_code)
message = "*****"
data["message"] = message
return data
/obj/machinery/nuclearbomb/ui_act(action, params)
if(..())
return
playsound(src, "terminal_type", 20, FALSE)
switch(action)
if("eject_disk")
if(auth && auth.loc == src)
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
auth.forceMove(get_turf(src))
auth = null
. = TRUE
if("insert_disk")
if(!auth)
else
var/obj/item/I = usr.is_holding_item_of_type(/obj/item/disk/nuclear)
if(I && disk_check(I) && usr.transferItemToLoc(I, src))
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
auth = I
. = TRUE
update_ui_mode()
if("keypad")
if(auth)
var/digit = params["digit"]
switch(digit)
if("R")
if("C")
if(auth && ui_mode == NUKEUI_AWAIT_ARM)
set_safety()
yes_code = FALSE
playsound(src, 'sound/machines/nuke/confirm_beep.ogg', 50, FALSE)
update_ui_mode()
else
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
numeric_input = ""
yes_code = FALSE
. = TRUE
if("E")
if(numeric_input == r_code)
numeric_input = ""
yes_code = TRUE
. = TRUE
else
numeric_input = "ERROR"
switch(ui_mode)
if(NUKEUI_AWAIT_CODE)
if(numeric_input == r_code)
numeric_input = ""
yes_code = TRUE
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
. = TRUE
else
playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE)
numeric_input = "ERROR"
if(NUKEUI_AWAIT_TIMER)
var/number_value = text2num(numeric_input)
if(number_value)
timer_set = CLAMP(number_value, minimum_timer_set, maximum_timer_set)
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
set_safety()
. = TRUE
else
playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE)
update_ui_mode()
if("0","1","2","3","4","5","6","7","8","9")
if(numeric_input != "ERROR")
numeric_input += digit
if(length(numeric_input) > 5)
numeric_input = "ERROR"
else
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
. = TRUE
if("timer")
if(auth && yes_code)
var/change = params["change"]
if(change == "reset")
timer_set = default_timer_set
else if(change == "decrease")
timer_set = max(minimum_timer_set, timer_set - 10)
else if(change == "increase")
timer_set = min(maximum_timer_set, timer_set + 10)
else if(change == "input")
var/user_input = input(usr, "Set time to detonation.", name) as null|num
if(!user_input)
return
var/N = text2num(user_input)
if(!N)
return
timer_set = CLAMP(N,minimum_timer_set,maximum_timer_set)
. = TRUE
if("safety")
if(auth && yes_code && !exploded)
set_safety()
else
playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE)
if("arm")
if(auth && yes_code && !safety && !exploded)
playsound(src, 'sound/machines/nuke/confirm_beep.ogg', 50, FALSE)
set_active()
update_ui_mode()
else
playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE)
if("anchor")
if(auth && yes_code)
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
set_anchor()
if("toggle_timer")
if(auth && yes_code && !safety && !exploded)
set_active()
else
playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE)
/obj/machinery/nuclearbomb/proc/set_anchor()
@@ -459,8 +508,8 @@
return CINEMATIC_SELFDESTRUCT_MISS
/obj/machinery/nuclearbomb/beer
name = "Kinaris-brand nuclear fission explosive"
desc = "One of the more successful achievements of the Kinaris Corporate Warfare Division, their nuclear fission explosives are renowned for being cheap to produce and devastatingly effective. Signs explain that though this particular device has been decommissioned, every Kinaris station is equipped with an equivalent one, just in case. All Captains carefully guard the disk needed to detonate them - at least, the sign says they do. There seems to be a tap on the back."
name = "Nanotrasen-brand nuclear fission explosive"
desc = "One of the more successful achievements of the Nanotrasen Corporate Warfare Division, their nuclear fission explosives are renowned for being cheap to produce and devastatingly effective. Signs explain that though this particular device has been decommissioned, every Nanotrasen station is equipped with an equivalent one, just in case. All Captains carefully guard the disk needed to detonate them - at least, the sign says they do. There seems to be a tap on the back."
proper_bomb = FALSE
var/obj/structure/reagent_dispensers/beerkeg/keg
@@ -19,6 +19,7 @@
job_description = "Swarmer"
death = FALSE
roundstart = FALSE
short_desc = "You are a swarmer, a weapon of a long dead civilization."
flavour_text = {"
<b>You are a swarmer, a weapon of a long dead civilization. Until further orders from your original masters are received, you must continue to consume and replicate.</b>
<b>Clicking on any object will try to consume it, either deconstructing it into its components, destroying it, or integrating any materials it has into you if successful.</b>
+38 -53
View File
@@ -11,7 +11,6 @@
var/code = DEFAULT_SIGNALER_CODE
var/frequency = FREQ_SIGNALER
var/delay = 0
var/datum/radio_frequency/radio_connection
var/suicider = null
var/hearing_range = 1
@@ -48,64 +47,50 @@
holder.update_icon()
return
/obj/item/assembly/signaler/ui_interact(mob/user, flag1)
. = ..()
if(is_secured(user))
var/t1 = "-------"
var/dat = {"
<TT>
<A href='byond://?src=[REF(src)];send=1'>Send Signal</A><BR>
<B>Frequency/Code</B> for signaler:<BR>
Frequency:
[format_frequency(src.frequency)]
<A href='byond://?src=[REF(src)];set=freq'>Set</A><BR>
Code:
[src.code]
<A href='byond://?src=[REF(src)];set=code'>Set</A><BR>
[t1]
</TT>"}
user << browse(dat, "window=radio")
onclose(user, "radio")
/obj/item/assembly/signaler/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)
if(!is_secured(user))
return
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
var/ui_width = 280
var/ui_height = 132
ui = new(user, src, ui_key, "signaler", name, ui_width, ui_height, master_ui, state)
ui.open()
/obj/item/assembly/signaler/ui_data(mob/user)
var/list/data = list()
data["frequency"] = frequency
data["code"] = code
data["minFrequency"] = MIN_FREE_FREQ
data["maxFrequency"] = MAX_FREE_FREQ
/obj/item/assembly/signaler/Topic(href, href_list)
..()
return data
if(!usr.canUseTopic(src, BE_CLOSE))
usr << browse(null, "window=radio")
onclose(usr, "radio")
/obj/item/assembly/signaler/ui_act(action, params)
if(..())
return
switch(action)
if("signal")
INVOKE_ASYNC(src, .proc/signal)
. = TRUE
if("freq")
frequency = unformat_frequency(params["freq"])
frequency = sanitize_frequency(frequency, TRUE)
set_frequency(frequency)
. = TRUE
if("code")
code = text2num(params["code"])
code = round(code)
. = TRUE
if("reset")
if(params["reset"] == "freq")
frequency = initial(frequency)
else
code = initial(code)
. = TRUE
if (href_list["set"])
if(href_list["set"] == "freq")
var/new_freq = input(usr, "Input a new signalling frequency", "Remote Signaller Frequency", format_frequency(frequency)) as num|null
if(!usr.canUseTopic(src, BE_CLOSE))
return
new_freq = unformat_frequency(new_freq)
new_freq = sanitize_frequency(new_freq, TRUE)
set_frequency(new_freq)
if(href_list["set"] == "code")
var/new_code = input(usr, "Input a new signalling code", "Remote Signaller Code", code) as num|null
if(!usr.canUseTopic(src, BE_CLOSE))
return
new_code = round(new_code)
new_code = CLAMP(new_code, 1, 100)
code = new_code
if(href_list["send"])
spawn( 0 )
signal()
if(usr)
attack_self(usr)
return
update_icon()
/obj/item/assembly/signaler/attackby(obj/item/W, mob/user, params)
if(issignaler(W))
var/obj/item/assembly/signaler/signaler2 = W
@@ -386,9 +386,10 @@
send_signal(device_id, list("checks" = text2num(params["val"])^2), usr)
. = TRUE
if("set_external_pressure", "set_internal_pressure")
var/area/A = get_area(src)
var/target = input("New target pressure:", name, A.air_vent_info[device_id][(action == "set_external_pressure" ? "external" : "internal")]) as num|null
if(!isnull(target) && !..())
var/target = params["value"]
if(!isnull(target))
send_signal(device_id, list("[action]" = target), usr)
. = TRUE
if("reset_external_pressure")
@@ -138,7 +138,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, "atmos_filter", name, 475, 195, master_ui, state)
ui = new(user, src, ui_key, "atmos_filter", name, 475, 185, master_ui, state)
ui.open()
/obj/machinery/atmospherics/components/trinary/filter/ui_data()
@@ -14,21 +14,16 @@
construction_type = /obj/item/pipe/trinary/flippable
pipe_state = "mixer"
ui_x = 370
ui_y = 165
//node 3 is the outlet, nodes 1 & 2 are intakes
/obj/machinery/atmospherics/components/trinary/mixer/examine(mob/user)
. = ..()
. += "<span class='notice'>You can hold <b>Ctrl</b> and click on it to toggle it on and off.</span>"
. += "<span class='notice'>You can hold <b>Alt</b> and click on it to maximize its pressure.</span>"
/obj/machinery/atmospherics/components/trinary/mixer/CtrlClick(mob/user)
var/area/A = get_area(src)
var/turf/T = get_turf(src)
if(user.canUseTopic(src, BE_CLOSE, FALSE,))
if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
on = !on
update_icon()
investigate_log("Mixer, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Mixer, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
return ..()
return ..()
/obj/machinery/atmospherics/components/trinary/mixer/AltClick(mob/user)
var/area/A = get_area(src)
@@ -62,12 +57,6 @@
var/on_state = on && nodes[1] && nodes[2] && nodes[3] && is_operational()
icon_state = "mixer_[on_state ? "on" : "off"][flipped ? "_f" : ""]"
/obj/machinery/atmospherics/components/trinary/mixer/power_change()
var/old_stat = stat
..()
if(stat != old_stat)
update_icon()
/obj/machinery/atmospherics/components/trinary/mixer/New()
..()
var/datum/gas_mixture/air3 = airs[3]
@@ -79,8 +68,13 @@
if(!on || !(nodes[1] && nodes[2] && nodes[3]) && !is_operational())
return
//Get those gases, mah boiiii
var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2]
if(!air1 || !air2)
return
var/datum/gas_mixture/air3 = airs[3]
var/output_starting_pressure = air3.return_pressure()
@@ -90,60 +84,57 @@
return
//Calculate necessary moles to transfer using PV=nRT
var/general_transfer = (target_pressure - output_starting_pressure) * air3.volume / R_IDEAL_GAS_EQUATION
var/pressure_delta = target_pressure - output_starting_pressure
var/transfer_moles1 = 0
var/transfer_moles2 = 0
if(air1.temperature > 0)
transfer_moles1 = (node1_concentration * pressure_delta) * air3.volume / (air1.temperature * R_IDEAL_GAS_EQUATION)
if(air2.temperature > 0)
transfer_moles2 = (node2_concentration * pressure_delta) * air3.volume / (air2.temperature * R_IDEAL_GAS_EQUATION)
var/transfer_moles1 = air1.temperature ? node1_concentration * general_transfer / air1.temperature : 0
var/transfer_moles2 = air2.temperature ? node2_concentration * general_transfer / air2.temperature : 0
var/air1_moles = air1.total_moles()
var/air2_moles = air2.total_moles()
if((air1_moles < transfer_moles1) || (air2_moles < transfer_moles2))
var/ratio = 0
if((transfer_moles1 > 0 ) && (transfer_moles2 > 0))
if(!node2_concentration)
if(air1.temperature <= 0)
return
transfer_moles1 = min(transfer_moles1, air1_moles)
transfer_moles2 = 0
else if(!node1_concentration)
if(air2.temperature <= 0)
return
transfer_moles2 = min(transfer_moles2, air2_moles)
transfer_moles1 = 0
else
if(air1.temperature <= 0 || air2.temperature <= 0)
return
if((transfer_moles2 <= 0) || (transfer_moles1 <= 0))
return
if((air1_moles < transfer_moles1) || (air2_moles < transfer_moles2))
var/ratio = 0
ratio = min(air1_moles / transfer_moles1, air2_moles / transfer_moles2)
if((transfer_moles2 == 0 ) && ( transfer_moles1 > 0))
ratio = air1_moles / transfer_moles1
if((transfer_moles1 == 0 ) && ( transfer_moles2 > 0))
ratio = air2_moles / transfer_moles2
transfer_moles1 *= ratio
transfer_moles2 *= ratio
transfer_moles1 *= ratio
transfer_moles2 *= ratio
//Actually transfer the gas
if(transfer_moles1 > 0)
if(transfer_moles1)
var/datum/gas_mixture/removed1 = air1.remove(transfer_moles1)
air3.merge(removed1)
if(transfer_moles2 > 0)
var/datum/gas_mixture/removed2 = air2.remove(transfer_moles2)
air3.merge(removed2)
if(transfer_moles1)
var/datum/pipeline/parent1 = parents[1]
parent1.update = TRUE
if(transfer_moles2)
var/datum/gas_mixture/removed2 = air2.remove(transfer_moles2)
air3.merge(removed2)
var/datum/pipeline/parent2 = parents[2]
parent2.update = TRUE
var/datum/pipeline/parent3 = parents[3]
parent3.update = TRUE
return
/obj/machinery/atmospherics/components/trinary/mixer/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, "atmos_mixer", name, 370, 165, master_ui, state)
ui = new(user, src, ui_key, "atmos_mixer", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/atmospherics/components/trinary/mixer/ui_data()
@@ -151,8 +142,8 @@
data["on"] = on
data["set_pressure"] = round(target_pressure)
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
data["node1_concentration"] = round(node1_concentration*100)
data["node2_concentration"] = round(node2_concentration*100)
data["node1_concentration"] = round(node1_concentration*100, 1)
data["node2_concentration"] = round(node2_concentration*100, 1)
return data
/obj/machinery/atmospherics/components/trinary/mixer/ui_act(action, params)
@@ -180,18 +171,19 @@
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS)
if("node1")
var/value = text2num(params["concentration"])
node1_concentration = max(0, min(1, node1_concentration + value))
node2_concentration = max(0, min(1, node2_concentration - value))
adjust_node1_value(value)
investigate_log("was set to [node1_concentration] % on node 1 by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE
if("node2")
var/value = text2num(params["concentration"])
node2_concentration = max(0, min(1, node2_concentration + value))
node1_concentration = max(0, min(1, node1_concentration - value))
adjust_node1_value(100 - value)
investigate_log("was set to [node2_concentration] % on node 2 by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE
update_icon()
/obj/machinery/atmospherics/components/trinary/mixer/proc/adjust_node1_value(newValue)
node1_concentration = newValue / 100
node2_concentration = 1 - node1_concentration
/obj/machinery/atmospherics/components/trinary/mixer/can_unwrench(mob/user)
. = ..()
@@ -259,4 +251,4 @@
/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped/inverse
node1_concentration = O2STANDARD
node2_concentration = N2STANDARD
node2_concentration = N2STANDARD
@@ -10,6 +10,8 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 30)
layer = OBJ_LAYER
circuit = /obj/item/circuitboard/machine/thermomachine
ui_x = 300
ui_y = 230
pipe_flags = PIPING_ONE_PER_TURF
@@ -126,7 +128,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, "thermomachine", name, 400, 240, master_ui, state)
ui = new(user, src, ui_key, "thermomachine", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/atmospherics/components/unary/thermomachine/ui_data(mob/user)
@@ -84,14 +84,14 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "portable_pump", name, 420, 415, master_ui, state)
ui = new(user, src, ui_key, "portable_pump", name, 300, 315, master_ui, state)
ui.open()
/obj/machinery/portable_atmospherics/pump/ui_data()
var/data = list()
data["on"] = on
data["direction"] = direction
data["connected"] = connected_port ? 1 : 0
data["direction"] = direction == PUMP_IN ? TRUE : FALSE
data["connected"] = connected_port ? TRUE : FALSE
data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
data["target_pressure"] = round(pump.target_pressure ? pump.target_pressure : 0)
data["default_pressure"] = round(PUMP_DEFAULT_PRESSURE)
@@ -102,6 +102,8 @@
data["holding"] = list()
data["holding"]["name"] = holding.name
data["holding"]["pressure"] = round(holding.air_contents.return_pressure())
else
data["holding"] = null
return data
/obj/machinery/portable_atmospherics/pump/ui_act(action, params)
@@ -67,7 +67,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "portable_scrubber", name, 420, 435, master_ui, state)
ui = new(user, src, ui_key, "portable_scrubber", name, 320, 335, master_ui, state)
ui.open()
/obj/machinery/portable_atmospherics/scrubber/ui_data()
@@ -85,6 +85,8 @@
data["holding"] = list()
data["holding"]["name"] = holding.name
data["holding"]["pressure"] = round(holding.air_contents.return_pressure())
else
data["holding"] = null
return data
/obj/machinery/portable_atmospherics/scrubber/ui_act(action, params)
+21 -9
View File
@@ -13,7 +13,9 @@
var/death = TRUE //Kill the mob
var/roundstart = TRUE //fires on initialize
var/instant = FALSE //fires on New
var/flavour_text = "The mapper forgot to set this!"
var/short_desc = "The mapper forgot to set this!"
var/flavour_text = ""
var/important_info = ""
var/faction = null
var/permanent = FALSE //If true, the spawner will not disappear upon running out of uses.
var/random = FALSE //Don't set a name or gender, just go random
@@ -118,7 +120,12 @@
if(ckey)
M.ckey = ckey
if(show_flavour)
to_chat(M, "[flavour_text]")
var/output_message = "<span class='big bold'>[short_desc]</span>"
if(flavour_text != "")
output_message += "\n<span class='bold'>[flavour_text]</span>"
if(important_info != "")
output_message += "\n<span class='userdanger'>[important_info]</span>"
to_chat(M, output_message)
var/datum/mind/MM = M.mind
if(objectives)
for(var/objective in objectives)
@@ -345,7 +352,7 @@
name = "sleeper"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
flavour_text = "<span class='big bold'>You are a space doctor!</span>"
short_desc = "You are a space doctor!"
assignedrole = "Space Doctor"
job_description = "Off-station Doctor"
@@ -402,7 +409,8 @@
name = "bartender sleeper"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
flavour_text = "<span class='big bold'>You are a space bartender!</span><b> Time to mix drinks and change lives. Smoking space drugs makes it easier to understand your patrons' odd dialect.</b>"
short_desc = "You are a space bartender!"
flavour_text = "Time to mix drinks and change lives. Smoking space drugs makes it easier to understand your patrons' odd dialect."
assignedrole = "Space Bartender"
id_job = "Bartender"
mirrorcanloadappearance = TRUE
@@ -429,7 +437,8 @@
name = "beach bum sleeper"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
flavour_text = "<span class='big bold'>You're, like, totally a dudebro, bruh.</span><b> Ch'yea. You came here, like, on spring break, hopin' to pick up some bangin' hot chicks, y'knaw?</b>"
short_desc = "You're a spunky lifeguard!"
flavour_text = "It's up to you to make sure nobody drowns or gets eaten by sharks and stuff."
assignedrole = "Beach Bum"
/obj/effect/mob_spawn/human/beach/alive/lifeguard
@@ -518,7 +527,7 @@
name = "sleeper"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
flavour_text = "<span class='big bold'>You are a Nanotrasen Commander!</span>"
short_desc = "You are a Nanotrasen Commander!"
/obj/effect/mob_spawn/human/nanotrasensoldier/alive
death = FALSE
@@ -529,7 +538,7 @@
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
faction = "nanotrasenprivate"
flavour_text = "<span class='big bold'>You are a Nanotrasen Private Security Officer!</span>"
short_desc = "You are a Nanotrasen Private Security Officer!"
/////////////////Spooky Undead//////////////////////
@@ -546,7 +555,8 @@
job_description = "Skeleton"
icon = 'icons/effects/blood.dmi'
icon_state = "remains"
flavour_text = "<span class='big bold'>By unknown powers, your skeletal remains have been reanimated!</span><b> Walk this mortal plain and terrorize all living adventurers who dare cross your path.</b>"
short_desc = "By unknown powers, your skeletal remains have been reanimated!"
flavour_text = "Walk this mortal plain and terrorize all living adventurers who dare cross your path."
assignedrole = "Skeleton"
/obj/effect/mob_spawn/human/zombie
@@ -561,7 +571,9 @@
job_description = "Zombie"
icon = 'icons/effects/blood.dmi'
icon_state = "remains"
flavour_text = "<span class='big bold'>By unknown powers, your rotting remains have been resurrected!</span><b> Walk this mortal plain and terrorize all living adventurers who dare cross your path.</b>"
short_desc = "By unknown powers, your rotting remains have been resurrected!"
flavour_text = "Walk this mortal plain and terrorize all living adventurers who dare cross your path."
/obj/effect/mob_spawn/human/abductor
@@ -596,8 +596,9 @@
job_description = "Syndicate Snow Operative"
faction = ROLE_SYNDICATE
outfit = /datum/outfit/snowsyndie
flavour_text = "<span class='big bold'>You are a syndicate operative recently awoken from cryostasis in an underground outpost. Monitor Nanotrasen communications and record information. All intruders should be \
disposed of swiftly to assure no gathered information is stolen or lost. Try not to wander too far from the outpost as the caves can be a deadly place even for a trained operative such as yourself.</span>"
short_desc = "You are a syndicate operative recently awoken from cryostasis in an underground outpost."
flavour_text = "You are a syndicate operative recently awoken from cryostasis in an underground outpost. Monitor Nanotrasen communications and record information. All intruders should be \
disposed of swiftly to assure no gathered information is stolen or lost. Try not to wander too far from the outpost as the caves can be a deadly place even for a trained operative such as yourself."
/datum/outfit/snowsyndie
name = "Syndicate Snow Operative"
+45 -35
View File
@@ -3,13 +3,20 @@
desc = "Used to order supplies, approve requests, and control the shuttle."
icon_screen = "supply"
circuit = /obj/item/circuitboard/computer/cargo
req_access = list(ACCESS_CARGO)
ui_x = 780
ui_y = 750
var/requestonly = FALSE
var/contraband = FALSE
var/self_paid = FALSE
var/safety_warning = "For safety reasons, the automated supply shuttle \
cannot transport live organisms, human remains, classified nuclear weaponry \
or homing beacons."
cannot transport live organisms, human remains, classified nuclear weaponry, \
homing beacons or machinery housing any form of artificial intelligence."
var/blockade_warning = "Bluespace instability detected. Shuttle movement impossible."
/// radio used by the console to send messages on supply channel
var/obj/item/radio/headset/radio
/// var that tracks message cooldown
var/message_cooldown
light_color = "#E2853D"//orange
@@ -18,11 +25,11 @@
desc = "Used to request supplies from cargo."
icon_screen = "request"
circuit = /obj/item/circuitboard/computer/cargo/request
req_access = list()
requestonly = TRUE
/obj/machinery/computer/cargo/Initialize()
. = ..()
radio = new /obj/item/radio/headset/headset_cargo(src)
var/obj/item/circuitboard/computer/cargo/board = circuit
contraband = board.contraband
if (board.obj_flags & EMAGGED)
@@ -30,6 +37,10 @@
else
obj_flags &= ~EMAGGED
/obj/machinery/computer/cargo/Destroy()
QDEL_NULL(radio)
..()
/obj/machinery/computer/cargo/proc/get_export_categories()
. = EXPORT_CARGO
if(contraband)
@@ -38,11 +49,11 @@
. |= EXPORT_EMAG
/obj/machinery/computer/cargo/emag_act(mob/user)
. = ..()
if(obj_flags & EMAGGED)
return
user.visible_message("<span class='warning'>[user] swipes a suspicious card through [src]!</span>",
"<span class='notice'>You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.</span>")
if(user)
user.visible_message("<span class='warning'>[user] swipes a suspicious card through [src]!</span>",
"<span class='notice'>You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.</span>")
obj_flags |= EMAGGED
contraband = TRUE
@@ -51,23 +62,21 @@
var/obj/item/circuitboard/computer/cargo/board = circuit
board.contraband = TRUE
board.obj_flags |= EMAGGED
req_access = list()
return TRUE
update_static_data(user)
/obj/machinery/computer/cargo/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, "cargo", name, 1000, 800, master_ui, state)
ui = new(user, src, ui_key, "cargo", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/cargo/ui_data()
var/list/data = list()
data["requestonly"] = requestonly
data["location"] = SSshuttle.supply.getStatusText()
data["points"] = SSshuttle.points
data["away"] = SSshuttle.supply.getDockedId() == "supply_away"
data["docked"] = SSshuttle.supply.mode == SHUTTLE_IDLE
data["points"] = SSshuttle.points
data["loan"] = !!SSshuttle.shuttle_loan
data["loan_dispatched"] = SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched
var/message = "Remember to stamp and send back the supply manifests."
@@ -76,29 +85,13 @@
if(SSshuttle.supplyBlocked)
message = blockade_warning
data["message"] = message
data["supplies"] = list()
for(var/pack in SSshuttle.supply_packs)
var/datum/supply_pack/P = SSshuttle.supply_packs[pack]
if(!data["supplies"][P.group])
data["supplies"][P.group] = list(
"name" = P.group,
"packs" = list()
)
if((P.hidden && !(obj_flags & EMAGGED)) || (P.contraband && !contraband) || (P.special && !P.special_enabled) || P.DropPodOnly)
continue
data["supplies"][P.group]["packs"] += list(list(
"name" = P.name,
"cost" = P.cost,
"id" = pack,
"desc" = P.desc || P.name // If there is a description, use it. Otherwise use the pack's name.
))
data["cart"] = list()
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
data["cart"] += list(list(
"object" = SO.pack.name,
"cost" = SO.pack.cost,
"id" = SO.id
"id" = SO.id,
"orderer" = SO.orderer,
))
data["requests"] = list()
@@ -113,14 +106,31 @@
return data
/obj/machinery/computer/cargo/ui_static_data(mob/user)
var/list/data = list()
data["requestonly"] = requestonly
data["supplies"] = list()
for(var/pack in SSshuttle.supply_packs)
var/datum/supply_pack/P = SSshuttle.supply_packs[pack]
if(!data["supplies"][P.group])
data["supplies"][P.group] = list(
"name" = P.group,
"packs" = list()
)
if((P.hidden && !(obj_flags & EMAGGED)) || (P.contraband && !contraband) || (P.special && !P.special_enabled) || P.DropPodOnly)
continue
data["supplies"][P.group]["packs"] += list(list(
"name" = P.name,
"cost" = P.cost,
"id" = pack,
"desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name.
"access" = P.access
))
return data
/obj/machinery/computer/cargo/ui_act(action, params, datum/tgui/ui)
if(..())
return
if(!allowed(usr))
to_chat(usr, "<span class='notice'>Access denied.</span>")
return
if(action != "add" && requestonly)
return
switch(action)
if("send")
if(!SSshuttle.supply.canMove())
+1 -1
View File
@@ -90,7 +90,7 @@
/obj/machinery/computer/cargo/express/ui_interact(mob/living/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state.
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "cargo_express", name, 1000, 800, master_ui, state)
ui = new(user, src, ui_key, "cargo_express", name, 600, 700, master_ui, state)
ui.open()
/obj/machinery/computer/cargo/express/ui_data(mob/user)
+45 -22
View File
@@ -28,7 +28,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the
//This proc sends the asset to the client, but only if it needs it.
//This proc blocks(sleeps) unless verify is set to false
/proc/send_asset(var/client/client, var/asset_name, var/verify = TRUE)
/proc/send_asset(client/client, asset_name, verify = TRUE)
if(!istype(client))
if(ismob(client))
var/mob/M = client
@@ -72,7 +72,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the
return 1
//This proc blocks(sleeps) unless verify is set to false
/proc/send_asset_list(var/client/client, var/list/asset_list, var/verify = TRUE)
/proc/send_asset_list(client/client, list/asset_list, verify = TRUE)
if(!istype(client))
if(ismob(client))
var/mob/M = client
@@ -122,7 +122,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the
//This proc will download the files without clogging up the browse() queue, used for passively sending files on connection start.
//The proc calls procs that sleep for long times.
/proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE)
/proc/getFilesSlow(client/client, list/files, register_asset = TRUE)
var/concurrent_tracker = 1
for(var/file in files)
if (!client)
@@ -140,13 +140,13 @@ You can set verify to TRUE if you want send() to sleep until the client has the
//This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up.
//if it's an icon or something be careful, you'll have to copy it before further use.
/proc/register_asset(var/asset_name, var/asset)
/proc/register_asset(asset_name, asset)
SSassets.cache[asset_name] = asset
//Generated names do not include file extention.
//Used mainly for code that deals with assets in a generic way
//The same asset will always lead to the same asset name
/proc/generate_asset_name(var/file)
/proc/generate_asset_name(file)
return "asset.[md5(fcopy_rsc(file))]"
@@ -156,7 +156,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the
GLOBAL_LIST_EMPTY(asset_datums)
//get an assetdatum or make a new one
/proc/get_asset_datum(var/type)
/proc/get_asset_datum(type)
return GLOB.asset_datums[type] || new type()
/datum/asset
@@ -323,6 +323,13 @@ GLOBAL_LIST_EMPTY(asset_datums)
var/size_id = sprite[SPR_SIZE]
return {"<span class="[name][size_id] [sprite_name]"></span>"}
/datum/asset/spritesheet/proc/icon_class_name(sprite_name)
var/sprite = sprites[sprite_name]
if (!sprite)
return null
var/size_id = sprite[SPR_SIZE]
return {"[name][size_id] [sprite_name]"}
#undef SPR_SIZE
#undef SPR_IDX
#undef SPRSZ_COUNT
@@ -379,14 +386,24 @@ GLOBAL_LIST_EMPTY(asset_datums)
/datum/asset/simple/tgui
assets = list(
"tgui.css" = 'tgui/assets/tgui.css',
"tgui.js" = 'tgui/assets/tgui.js',
"font-awesome.min.css" = 'tgui/assets/font-awesome.min.css',
"fontawesome-webfont.eot" = 'tgui/assets/fonts/fontawesome-webfont.eot',
"fontawesome-webfont.woff2" = 'tgui/assets/fonts/fontawesome-webfont.woff2',
"fontawesome-webfont.woff" = 'tgui/assets/fonts/fontawesome-webfont.woff',
"fontawesome-webfont.ttf" = 'tgui/assets/fonts/fontawesome-webfont.ttf',
"fontawesome-webfont.svg" = 'tgui/assets/fonts/fontawesome-webfont.svg'
// tgui
"tgui.css" = 'tgui/assets/tgui.css',
"tgui.js" = 'tgui/assets/tgui.js',
// tgui-next
"tgui-main.html" = 'tgui-next/packages/tgui/public/tgui-main.html',
"tgui-fallback.html" = 'tgui-next/packages/tgui/public/tgui-fallback.html',
"tgui.bundle.js" = 'tgui-next/packages/tgui/public/tgui.bundle.js',
"tgui.bundle.css" = 'tgui-next/packages/tgui/public/tgui.bundle.css',
"shim-html5shiv.js" = 'tgui-next/packages/tgui/public/shim-html5shiv.js',
"shim-ie8.js" = 'tgui-next/packages/tgui/public/shim-ie8.js',
"shim-dom4.js" = 'tgui-next/packages/tgui/public/shim-dom4.js',
"shim-css-om.js" = 'tgui-next/packages/tgui/public/shim-css-om.js',
)
/datum/asset/group/tgui
children = list(
/datum/asset/simple/tgui,
/datum/asset/simple/fontawesome
)
/datum/asset/simple/headers
@@ -511,7 +528,7 @@ GLOBAL_LIST_EMPTY(asset_datums)
"pill21" = 'icons/UI_Icons/Pills/pill21.png',
"pill22" = 'icons/UI_Icons/Pills/pill22.png',
)
/datum/asset/simple/IRV
assets = list(
"jquery-ui.custom-core-widgit-mouse-sortable-min.js" = 'html/IRV/jquery-ui.custom-core-widgit-mouse-sortable-min.js',
@@ -550,7 +567,8 @@ GLOBAL_LIST_EMPTY(asset_datums)
children = list(
/datum/asset/simple/jquery,
/datum/asset/simple/goonchat,
/datum/asset/spritesheet/goonchat
/datum/asset/spritesheet/goonchat,
/datum/asset/simple/fontawesome
)
/datum/asset/simple/jquery
@@ -563,18 +581,23 @@ GLOBAL_LIST_EMPTY(asset_datums)
verify = FALSE
assets = list(
"json2.min.js" = 'code/modules/goonchat/browserassets/js/json2.min.js',
"errorHandler.js" = 'code/modules/goonchat/browserassets/js/errorHandler.js',
"browserOutput.js" = 'code/modules/goonchat/browserassets/js/browserOutput.js',
"fontawesome-webfont.eot" = 'tgui/assets/fonts/fontawesome-webfont.eot',
"fontawesome-webfont.svg" = 'tgui/assets/fonts/fontawesome-webfont.svg',
"fontawesome-webfont.ttf" = 'tgui/assets/fonts/fontawesome-webfont.ttf',
"fontawesome-webfont.woff" = 'tgui/assets/fonts/fontawesome-webfont.woff',
"font-awesome.css" = 'code/modules/goonchat/browserassets/css/font-awesome.css',
"browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css',
"browserOutput_dark.css" = 'code/modules/goonchat/browserassets/css/browserOutput_dark.css',
"browserOutput_light.css" = 'code/modules/goonchat/browserassets/css/browserOutput_light.css'
)
/datum/asset/simple/fontawesome
verify = FALSE
assets = list(
"fa-regular-400.eot" = 'html/font-awesome/webfonts/fa-regular-400.eot',
"fa-regular-400.woff" = 'html/font-awesome/webfonts/fa-regular-400.woff',
"fa-solid-900.eot" = 'html/font-awesome/webfonts/fa-solid-900.eot',
"fa-solid-900.woff" = 'html/font-awesome/webfonts/fa-solid-900.woff',
"font-awesome.css" = 'html/font-awesome/css/all.min.css',
"v4shim.css" = 'html/font-awesome/css/v4-shims.min.css'
)
/datum/asset/spritesheet/goonchat
name = "chat"
+12
View File
@@ -47,6 +47,18 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
else if (job in completed_asset_jobs) //byond bug ID:2256651
to_chat(src, "<span class='danger'>An error has been detected in how your client is receiving resources. Attempting to correct.... (If you keep seeing these messages you might want to close byond and reconnect)</span>")
src << browse("...", "window=asset_cache_browser")
// Keypress passthrough
if(href_list["__keydown"])
var/keycode = browser_keycode_to_byond(href_list["__keydown"])
if(keycode)
keyDown(keycode)
return
if(href_list["__keyup"])
var/keycode = browser_keycode_to_byond(href_list["__keyup"])
if(keycode)
keyUp(keycode)
return
var/mtl = CONFIG_GET(number/minute_topic_limit)
if (!holder && mtl)
@@ -678,6 +678,8 @@ datum/crafting_recipe/food/donut/meat
/obj/item/reagent_containers/food/snacks/grown/oat = 1
)
result = /obj/item/reagent_containers/food/snacks/oatmealcookie
subcategory = CAT_PASTRY
/datum/crafting_recipe/food/raisincookie
name = "Raisin cookie"
@@ -101,7 +101,7 @@ a.popt {text-decoration: none;}
#ping {
position: fixed;
top: 0;
right: 115px;
right: 135px;
width: 45px;
background: #d0d0d0;
height: 30px;
@@ -131,13 +131,13 @@ a.popt {text-decoration: none;}
}
#userBar .subCell:hover {background: #ccc;}
#userBar .toggle {
width: 40px;
width: 45px;
background: #ccc;
border-top: 0;
float: right;
text-align: center;
}
#userBar .sub {clear: both; display: none; width: 160px;}
#userBar .sub {clear: both; display: none; width: 180px;}
#userBar .sub.scroll {overflow-y: scroll;}
#userBar .sub.subCell {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;}
#userBar .sub span {
-788
View File
@@ -1,788 +0,0 @@
@font-face{font-family:'FontAwesome';src:url('fontawesome-webfont.eot');src:url('fontawesome-webfont.eot') format('embedded-opentype'),url('fontawesome-webfont.woff') format('woff'),url('fontawesome-webfont.ttf') format('truetype'),url('fontawesome-webfont.svg') format('svg');font-weight:normal;font-style:normal;}[class^="icon-"],[class*=" icon-"]{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;}
[class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none;}
.icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em;}
a [class^="icon-"],a [class*=" icon-"]{display:inline;}
[class^="icon-"].icon-fixed-width,[class*=" icon-"].icon-fixed-width{display:inline-block;width:1.1428571428571428em;text-align:right;padding-right:0.2857142857142857em;}[class^="icon-"].icon-fixed-width.icon-large,[class*=" icon-"].icon-fixed-width.icon-large{width:1.4285714285714286em;}
.icons-ul{margin-left:2.142857142857143em;list-style-type:none;}.icons-ul>li{position:relative;}
.icons-ul .icon-li{position:absolute;left:-2.142857142857143em;width:2.142857142857143em;text-align:center;line-height:inherit;}
[class^="icon-"].hide,[class*=" icon-"].hide{display:none;}
.icon-muted{color:#eeeeee;}
.icon-light{color:#ffffff;}
.icon-dark{color:#333333;}
.icon-border{border:solid 1px #eeeeee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
.icon-2x{font-size:2em;}.icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
.icon-3x{font-size:3em;}.icon-3x.icon-border{border-width:3px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}
.icon-4x{font-size:4em;}.icon-4x.icon-border{border-width:4px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
.icon-5x{font-size:5em;}.icon-5x.icon-border{border-width:5px;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px;}
.pull-right{float:right;}
.pull-left{float:left;}
[class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em;}
[class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em;}
[class^="icon-"],[class*=" icon-"]{display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0% 0%;background-repeat:repeat;margin-top:0;}
.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none;}
.btn [class^="icon-"].icon-large,.nav [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em;}
.btn [class^="icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block;}
.nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:.9em;}
.btn [class^="icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em;}
.btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em;}
.btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em;}
.btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0;}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em;}
.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em;}
.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em;}
.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{line-height:inherit;}
.icon-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:-35%;}.icon-stack [class^="icon-"],.icon-stack [class*=" icon-"]{display:block;text-align:center;position:absolute;width:100%;height:100%;font-size:1em;line-height:inherit;*line-height:2em;}
.icon-stack .icon-stack-base{font-size:2em;*line-height:1em;}
.icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;}
a .icon-stack,a .icon-spin{display:inline-block;text-decoration:none;}
@-moz-keyframes spin{0%{-moz-transform:rotate(0deg);} 100%{-moz-transform:rotate(359deg);}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg);} 100%{-webkit-transform:rotate(359deg);}}@-o-keyframes spin{0%{-o-transform:rotate(0deg);} 100%{-o-transform:rotate(359deg);}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg);} 100%{-ms-transform:rotate(359deg);}}@keyframes spin{0%{transform:rotate(0deg);} 100%{transform:rotate(359deg);}}.icon-rotate-90:before{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);}
.icon-rotate-180:before{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);}
.icon-rotate-270:before{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);}
.icon-flip-horizontal:before{-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1);}
.icon-flip-vertical:before{-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1);}
a .icon-rotate-90:before,a .icon-rotate-180:before,a .icon-rotate-270:before,a .icon-flip-horizontal:before,a .icon-flip-vertical:before{display:inline-block;}
.icon-glass:before{content:"\f000";}
.icon-music:before{content:"\f001";}
.icon-search:before{content:"\f002";}
.icon-envelope-alt:before{content:"\f003";}
.icon-heart:before{content:"\f004";}
.icon-star:before{content:"\f005";}
.icon-star-empty:before{content:"\f006";}
.icon-user:before{content:"\f007";}
.icon-film:before{content:"\f008";}
.icon-th-large:before{content:"\f009";}
.icon-th:before{content:"\f00a";}
.icon-th-list:before{content:"\f00b";}
.icon-ok:before{content:"\f00c";}
.icon-remove:before{content:"\f00d";}
.icon-zoom-in:before{content:"\f00e";}
.icon-zoom-out:before{content:"\f010";}
.icon-power-off:before,.icon-off:before{content:"\f011";}
.icon-signal:before{content:"\f012";}
.icon-gear:before,.icon-cog:before{content:"\f013";}
.icon-trash:before{content:"\f014";}
.icon-home:before{content:"\f015";}
.icon-file-alt:before{content:"\f016";}
.icon-time:before{content:"\f017";}
.icon-road:before{content:"\f018";}
.icon-download-alt:before{content:"\f019";}
.icon-download:before{content:"\f01a";}
.icon-upload:before{content:"\f01b";}
.icon-inbox:before{content:"\f01c";}
.icon-play-circle:before{content:"\f01d";}
.icon-rotate-right:before,.icon-repeat:before{content:"\f01e";}
.icon-refresh:before{content:"\f021";}
.icon-list-alt:before{content:"\f022";}
.icon-lock:before{content:"\f023";}
.icon-flag:before{content:"\f024";}
.icon-headphones:before{content:"\f025";}
.icon-volume-off:before{content:"\f026";}
.icon-volume-down:before{content:"\f027";}
.icon-volume-up:before{content:"\f028";}
.icon-qrcode:before{content:"\f029";}
.icon-barcode:before{content:"\f02a";}
.icon-tag:before{content:"\f02b";}
.icon-tags:before{content:"\f02c";}
.icon-book:before{content:"\f02d";}
.icon-bookmark:before{content:"\f02e";}
.icon-print:before{content:"\f02f";}
.icon-camera:before{content:"\f030";}
.icon-font:before{content:"\f031";}
.icon-bold:before{content:"\f032";}
.icon-italic:before{content:"\f033";}
.icon-text-height:before{content:"\f034";}
.icon-text-width:before{content:"\f035";}
.icon-align-left:before{content:"\f036";}
.icon-align-center:before{content:"\f037";}
.icon-align-right:before{content:"\f038";}
.icon-align-justify:before{content:"\f039";}
.icon-list:before{content:"\f03a";}
.icon-indent-left:before{content:"\f03b";}
.icon-indent-right:before{content:"\f03c";}
.icon-facetime-video:before{content:"\f03d";}
.icon-picture:before{content:"\f03e";}
.icon-pencil:before{content:"\f040";}
.icon-map-marker:before{content:"\f041";}
.icon-adjust:before{content:"\f042";}
.icon-tint:before{content:"\f043";}
.icon-edit:before{content:"\f044";}
.icon-share:before{content:"\f045";}
.icon-check:before{content:"\f046";}
.icon-move:before{content:"\f047";}
.icon-step-backward:before{content:"\f048";}
.icon-fast-backward:before{content:"\f049";}
.icon-backward:before{content:"\f04a";}
.icon-play:before{content:"\f04b";}
.icon-pause:before{content:"\f04c";}
.icon-stop:before{content:"\f04d";}
.icon-forward:before{content:"\f04e";}
.icon-fast-forward:before{content:"\f050";}
.icon-step-forward:before{content:"\f051";}
.icon-eject:before{content:"\f052";}
.icon-chevron-left:before{content:"\f053";}
.icon-chevron-right:before{content:"\f054";}
.icon-plus-sign:before{content:"\f055";}
.icon-minus-sign:before{content:"\f056";}
.icon-remove-sign:before{content:"\f057";}
.icon-ok-sign:before{content:"\f058";}
.icon-question-sign:before{content:"\f059";}
.icon-info-sign:before{content:"\f05a";}
.icon-screenshot:before{content:"\f05b";}
.icon-remove-circle:before{content:"\f05c";}
.icon-ok-circle:before{content:"\f05d";}
.icon-ban-circle:before{content:"\f05e";}
.icon-arrow-left:before{content:"\f060";}
.icon-arrow-right:before{content:"\f061";}
.icon-arrow-up:before{content:"\f062";}
.icon-arrow-down:before{content:"\f063";}
.icon-mail-forward:before,.icon-share-alt:before{content:"\f064";}
.icon-resize-full:before{content:"\f065";}
.icon-resize-small:before{content:"\f066";}
.icon-plus:before{content:"\f067";}
.icon-minus:before{content:"\f068";}
.icon-asterisk:before{content:"\f069";}
.icon-exclamation-sign:before{content:"\f06a";}
.icon-gift:before{content:"\f06b";}
.icon-leaf:before{content:"\f06c";}
.icon-fire:before{content:"\f06d";}
.icon-eye-open:before{content:"\f06e";}
.icon-eye-close:before{content:"\f070";}
.icon-warning-sign:before{content:"\f071";}
.icon-plane:before{content:"\f072";}
.icon-calendar:before{content:"\f073";}
.icon-random:before{content:"\f074";}
.icon-comment:before{content:"\f075";}
.icon-magnet:before{content:"\f076";}
.icon-chevron-up:before{content:"\f077";}
.icon-chevron-down:before{content:"\f078";}
.icon-retweet:before{content:"\f079";}
.icon-shopping-cart:before{content:"\f07a";}
.icon-folder-close:before{content:"\f07b";}
.icon-folder-open:before{content:"\f07c";}
.icon-resize-vertical:before{content:"\f07d";}
.icon-resize-horizontal:before{content:"\f07e";}
.icon-bar-chart:before{content:"\f080";}
.icon-twitter-sign:before{content:"\f081";}
.icon-facebook-sign:before{content:"\f082";}
.icon-camera-retro:before{content:"\f083";}
.icon-key:before{content:"\f084";}
.icon-gears:before,.icon-cogs:before{content:"\f085";}
.icon-comments:before{content:"\f086";}
.icon-thumbs-up-alt:before{content:"\f087";}
.icon-thumbs-down-alt:before{content:"\f088";}
.icon-star-half:before{content:"\f089";}
.icon-heart-empty:before{content:"\f08a";}
.icon-signout:before{content:"\f08b";}
.icon-linkedin-sign:before{content:"\f08c";}
.icon-pushpin:before{content:"\f08d";}
.icon-external-link:before{content:"\f08e";}
.icon-signin:before{content:"\f090";}
.icon-trophy:before{content:"\f091";}
.icon-github-sign:before{content:"\f092";}
.icon-upload-alt:before{content:"\f093";}
.icon-lemon:before{content:"\f094";}
.icon-phone:before{content:"\f095";}
.icon-unchecked:before,.icon-check-empty:before{content:"\f096";}
.icon-bookmark-empty:before{content:"\f097";}
.icon-phone-sign:before{content:"\f098";}
.icon-twitter:before{content:"\f099";}
.icon-facebook:before{content:"\f09a";}
.icon-github:before{content:"\f09b";}
.icon-unlock:before{content:"\f09c";}
.icon-credit-card:before{content:"\f09d";}
.icon-rss:before{content:"\f09e";}
.icon-hdd:before{content:"\f0a0";}
.icon-bullhorn:before{content:"\f0a1";}
.icon-bell:before{content:"\f0a2";}
.icon-certificate:before{content:"\f0a3";}
.icon-hand-right:before{content:"\f0a4";}
.icon-hand-left:before{content:"\f0a5";}
.icon-hand-up:before{content:"\f0a6";}
.icon-hand-down:before{content:"\f0a7";}
.icon-circle-arrow-left:before{content:"\f0a8";}
.icon-circle-arrow-right:before{content:"\f0a9";}
.icon-circle-arrow-up:before{content:"\f0aa";}
.icon-circle-arrow-down:before{content:"\f0ab";}
.icon-globe:before{content:"\f0ac";}
.icon-wrench:before{content:"\f0ad";}
.icon-tasks:before{content:"\f0ae";}
.icon-filter:before{content:"\f0b0";}
.icon-briefcase:before{content:"\f0b1";}
.icon-fullscreen:before{content:"\f0b2";}
.icon-group:before{content:"\f0c0";}
.icon-link:before{content:"\f0c1";}
.icon-cloud:before{content:"\f0c2";}
.icon-beaker:before{content:"\f0c3";}
.icon-cut:before{content:"\f0c4";}
.icon-copy:before{content:"\f0c5";}
.icon-paperclip:before,.icon-paper-clip:before{content:"\f0c6";}
.icon-save:before{content:"\f0c7";}
.icon-sign-blank:before{content:"\f0c8";}
.icon-reorder:before{content:"\f0c9";}
.icon-list-ul:before{content:"\f0ca";}
.icon-list-ol:before{content:"\f0cb";}
.icon-strikethrough:before{content:"\f0cc";}
.icon-underline:before{content:"\f0cd";}
.icon-table:before{content:"\f0ce";}
.icon-magic:before{content:"\f0d0";}
.icon-truck:before{content:"\f0d1";}
.icon-pinterest:before{content:"\f0d2";}
.icon-pinterest-sign:before{content:"\f0d3";}
.icon-google-plus-sign:before{content:"\f0d4";}
.icon-google-plus:before{content:"\f0d5";}
.icon-money:before{content:"\f0d6";}
.icon-caret-down:before{content:"\f0d7";}
.icon-caret-up:before{content:"\f0d8";}
.icon-caret-left:before{content:"\f0d9";}
.icon-caret-right:before{content:"\f0da";}
.icon-columns:before{content:"\f0db";}
.icon-sort:before{content:"\f0dc";}
.icon-sort-down:before{content:"\f0dd";}
.icon-sort-up:before{content:"\f0de";}
.icon-envelope:before{content:"\f0e0";}
.icon-linkedin:before{content:"\f0e1";}
.icon-rotate-left:before,.icon-undo:before{content:"\f0e2";}
.icon-legal:before{content:"\f0e3";}
.icon-dashboard:before{content:"\f0e4";}
.icon-comment-alt:before{content:"\f0e5";}
.icon-comments-alt:before{content:"\f0e6";}
.icon-bolt:before{content:"\f0e7";}
.icon-sitemap:before{content:"\f0e8";}
.icon-umbrella:before{content:"\f0e9";}
.icon-paste:before{content:"\f0ea";}
.icon-lightbulb:before{content:"\f0eb";}
.icon-exchange:before{content:"\f0ec";}
.icon-cloud-download:before{content:"\f0ed";}
.icon-cloud-upload:before{content:"\f0ee";}
.icon-user-md:before{content:"\f0f0";}
.icon-stethoscope:before{content:"\f0f1";}
.icon-suitcase:before{content:"\f0f2";}
.icon-bell-alt:before{content:"\f0f3";}
.icon-coffee:before{content:"\f0f4";}
.icon-food:before{content:"\f0f5";}
.icon-file-text-alt:before{content:"\f0f6";}
.icon-building:before{content:"\f0f7";}
.icon-hospital:before{content:"\f0f8";}
.icon-ambulance:before{content:"\f0f9";}
.icon-medkit:before{content:"\f0fa";}
.icon-fighter-jet:before{content:"\f0fb";}
.icon-beer:before{content:"\f0fc";}
.icon-h-sign:before{content:"\f0fd";}
.icon-plus-sign-alt:before{content:"\f0fe";}
.icon-double-angle-left:before{content:"\f100";}
.icon-double-angle-right:before{content:"\f101";}
.icon-double-angle-up:before{content:"\f102";}
.icon-double-angle-down:before{content:"\f103";}
.icon-angle-left:before{content:"\f104";}
.icon-angle-right:before{content:"\f105";}
.icon-angle-up:before{content:"\f106";}
.icon-angle-down:before{content:"\f107";}
.icon-desktop:before{content:"\f108";}
.icon-laptop:before{content:"\f109";}
.icon-tablet:before{content:"\f10a";}
.icon-mobile-phone:before{content:"\f10b";}
.icon-circle-blank:before{content:"\f10c";}
.icon-quote-left:before{content:"\f10d";}
.icon-quote-right:before{content:"\f10e";}
.icon-spinner:before{content:"\f110";}
.icon-circle:before{content:"\f111";}
.icon-mail-reply:before,.icon-reply:before{content:"\f112";}
.icon-github-alt:before{content:"\f113";}
.icon-folder-close-alt:before{content:"\f114";}
.icon-folder-open-alt:before{content:"\f115";}
.icon-expand-alt:before{content:"\f116";}
.icon-collapse-alt:before{content:"\f117";}
.icon-smile:before{content:"\f118";}
.icon-frown:before{content:"\f119";}
.icon-meh:before{content:"\f11a";}
.icon-gamepad:before{content:"\f11b";}
.icon-keyboard:before{content:"\f11c";}
.icon-flag-alt:before{content:"\f11d";}
.icon-flag-checkered:before{content:"\f11e";}
.icon-terminal:before{content:"\f120";}
.icon-code:before{content:"\f121";}
.icon-reply-all:before{content:"\f122";}
.icon-mail-reply-all:before{content:"\f122";}
.icon-star-half-full:before,.icon-star-half-empty:before{content:"\f123";}
.icon-location-arrow:before{content:"\f124";}
.icon-crop:before{content:"\f125";}
.icon-code-fork:before{content:"\f126";}
.icon-unlink:before{content:"\f127";}
.icon-question:before{content:"\f128";}
.icon-info:before{content:"\f129";}
.icon-exclamation:before{content:"\f12a";}
.icon-superscript:before{content:"\f12b";}
.icon-subscript:before{content:"\f12c";}
.icon-eraser:before{content:"\f12d";}
.icon-puzzle-piece:before{content:"\f12e";}
.icon-microphone:before{content:"\f130";}
.icon-microphone-off:before{content:"\f131";}
.icon-shield:before{content:"\f132";}
.icon-calendar-empty:before{content:"\f133";}
.icon-fire-extinguisher:before{content:"\f134";}
.icon-rocket:before{content:"\f135";}
.icon-maxcdn:before{content:"\f136";}
.icon-chevron-sign-left:before{content:"\f137";}
.icon-chevron-sign-right:before{content:"\f138";}
.icon-chevron-sign-up:before{content:"\f139";}
.icon-chevron-sign-down:before{content:"\f13a";}
.icon-html5:before{content:"\f13b";}
.icon-css3:before{content:"\f13c";}
.icon-anchor:before{content:"\f13d";}
.icon-unlock-alt:before{content:"\f13e";}
.icon-bullseye:before{content:"\f140";}
.icon-ellipsis-horizontal:before{content:"\f141";}
.icon-ellipsis-vertical:before{content:"\f142";}
.icon-rss-sign:before{content:"\f143";}
.icon-play-sign:before{content:"\f144";}
.icon-ticket:before{content:"\f145";}
.icon-minus-sign-alt:before{content:"\f146";}
.icon-check-minus:before{content:"\f147";}
.icon-level-up:before{content:"\f148";}
.icon-level-down:before{content:"\f149";}
.icon-check-sign:before{content:"\f14a";}
.icon-edit-sign:before{content:"\f14b";}
.icon-external-link-sign:before{content:"\f14c";}
.icon-share-sign:before{content:"\f14d";}
.icon-compass:before{content:"\f14e";}
.icon-collapse:before{content:"\f150";}
.icon-collapse-top:before{content:"\f151";}
.icon-expand:before{content:"\f152";}
.icon-euro:before,.icon-eur:before{content:"\f153";}
.icon-gbp:before{content:"\f154";}
.icon-dollar:before,.icon-usd:before{content:"\f155";}
.icon-rupee:before,.icon-inr:before{content:"\f156";}
.icon-yen:before,.icon-jpy:before{content:"\f157";}
.icon-renminbi:before,.icon-cny:before{content:"\f158";}
.icon-won:before,.icon-krw:before{content:"\f159";}
.icon-bitcoin:before,.icon-btc:before{content:"\f15a";}
.icon-file:before{content:"\f15b";}
.icon-file-text:before{content:"\f15c";}
.icon-sort-by-alphabet:before{content:"\f15d";}
.icon-sort-by-alphabet-alt:before{content:"\f15e";}
.icon-sort-by-attributes:before{content:"\f160";}
.icon-sort-by-attributes-alt:before{content:"\f161";}
.icon-sort-by-order:before{content:"\f162";}
.icon-sort-by-order-alt:before{content:"\f163";}
.icon-thumbs-up:before{content:"\f164";}
.icon-thumbs-down:before{content:"\f165";}
.icon-youtube-sign:before{content:"\f166";}
.icon-youtube:before{content:"\f167";}
.icon-xing:before{content:"\f168";}
.icon-xing-sign:before{content:"\f169";}
.icon-youtube-play:before{content:"\f16a";}
.icon-dropbox:before{content:"\f16b";}
.icon-stackexchange:before{content:"\f16c";}
.icon-instagram:before{content:"\f16d";}
.icon-flickr:before{content:"\f16e";}
.icon-adn:before{content:"\f170";}
.icon-bitbucket:before{content:"\f171";}
.icon-bitbucket-sign:before{content:"\f172";}
.icon-tumblr:before{content:"\f173";}
.icon-tumblr-sign:before{content:"\f174";}
.icon-long-arrow-down:before{content:"\f175";}
.icon-long-arrow-up:before{content:"\f176";}
.icon-long-arrow-left:before{content:"\f177";}
.icon-long-arrow-right:before{content:"\f178";}
.icon-apple:before{content:"\f179";}
.icon-windows:before{content:"\f17a";}
.icon-android:before{content:"\f17b";}
.icon-linux:before{content:"\f17c";}
.icon-dribbble:before{content:"\f17d";}
.icon-skype:before{content:"\f17e";}
.icon-foursquare:before{content:"\f180";}
.icon-trello:before{content:"\f181";}
.icon-female:before{content:"\f182";}
.icon-male:before{content:"\f183";}
.icon-gittip:before{content:"\f184";}
.icon-sun:before{content:"\f185";}
.icon-moon:before{content:"\f186";}
.icon-archive:before{content:"\f187";}
.icon-bug:before{content:"\f188";}
.icon-vk:before{content:"\f189";}
.icon-weibo:before{content:"\f18a";}
.icon-renren:before{content:"\f18b";}
.icon-large{font-size:1.3333333333333333em;margin-top:-4px;padding-top:3px;margin-bottom:-4px;padding-bottom:3px;vertical-align:middle;}
.nav [class^="icon-"],.nav [class*=" icon-"]{vertical-align:inherit;margin-top:-4px;padding-top:3px;margin-bottom:-4px;padding-bottom:3px;}.nav [class^="icon-"].icon-large,.nav [class*=" icon-"].icon-large{vertical-align:-25%;}
.nav-pills [class^="icon-"].icon-large,.nav-tabs [class^="icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large{line-height:.75em;margin-top:-7px;padding-top:5px;margin-bottom:-5px;padding-bottom:4px;}
.btn [class^="icon-"].pull-left,.btn [class*=" icon-"].pull-left,.btn [class^="icon-"].pull-right,.btn [class*=" icon-"].pull-right{vertical-align:inherit;}
.btn [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large{margin-top:-0.5em;}
a [class^="icon-"],a [class*=" icon-"]{cursor:pointer;}
.icon-glass{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf000;');}
.icon-music{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf001;');}
.icon-search{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf002;');}
.icon-envelope-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf003;');}
.icon-heart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf004;');}
.icon-star{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf005;');}
.icon-star-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf006;');}
.icon-user{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf007;');}
.icon-film{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf008;');}
.icon-th-large{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf009;');}
.icon-th{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf00a;');}
.icon-th-list{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf00b;');}
.icon-ok{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf00c;');}
.icon-remove{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf00d;');}
.icon-zoom-in{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf00e;');}
.icon-zoom-out{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf010;');}
.icon-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf011;');}
.icon-power-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf011;');}
.icon-signal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf012;');}
.icon-cog{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf013;');}
.icon-gear{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf013;');}
.icon-trash{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf014;');}
.icon-home{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf015;');}
.icon-file-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf016;');}
.icon-time{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf017;');}
.icon-road{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf018;');}
.icon-download-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf019;');}
.icon-download{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf01a;');}
.icon-upload{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf01b;');}
.icon-inbox{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf01c;');}
.icon-play-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf01d;');}
.icon-repeat{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf01e;');}
.icon-rotate-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf01e;');}
.icon-refresh{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf021;');}
.icon-list-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf022;');}
.icon-lock{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf023;');}
.icon-flag{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf024;');}
.icon-headphones{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf025;');}
.icon-volume-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf026;');}
.icon-volume-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf027;');}
.icon-volume-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf028;');}
.icon-qrcode{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf029;');}
.icon-barcode{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf02a;');}
.icon-tag{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf02b;');}
.icon-tags{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf02c;');}
.icon-book{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf02d;');}
.icon-bookmark{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf02e;');}
.icon-print{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf02f;');}
.icon-camera{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf030;');}
.icon-font{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf031;');}
.icon-bold{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf032;');}
.icon-italic{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf033;');}
.icon-text-height{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf034;');}
.icon-text-width{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf035;');}
.icon-align-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf036;');}
.icon-align-center{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf037;');}
.icon-align-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf038;');}
.icon-align-justify{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf039;');}
.icon-list{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf03a;');}
.icon-indent-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf03b;');}
.icon-indent-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf03c;');}
.icon-facetime-video{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf03d;');}
.icon-picture{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf03e;');}
.icon-pencil{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf040;');}
.icon-map-marker{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf041;');}
.icon-adjust{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf042;');}
.icon-tint{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf043;');}
.icon-edit{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf044;');}
.icon-share{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf045;');}
.icon-check{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf046;');}
.icon-move{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf047;');}
.icon-step-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf048;');}
.icon-fast-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf049;');}
.icon-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf04a;');}
.icon-play{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf04b;');}
.icon-pause{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf04c;');}
.icon-stop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf04d;');}
.icon-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf04e;');}
.icon-fast-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf050;');}
.icon-step-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf051;');}
.icon-eject{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf052;');}
.icon-chevron-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf053;');}
.icon-chevron-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf054;');}
.icon-plus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf055;');}
.icon-minus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf056;');}
.icon-remove-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf057;');}
.icon-ok-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf058;');}
.icon-question-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf059;');}
.icon-info-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf05a;');}
.icon-screenshot{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf05b;');}
.icon-remove-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf05c;');}
.icon-ok-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf05d;');}
.icon-ban-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf05e;');}
.icon-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf060;');}
.icon-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf061;');}
.icon-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf062;');}
.icon-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf063;');}
.icon-share-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf064;');}
.icon-mail-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf064;');}
.icon-resize-full{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf065;');}
.icon-resize-small{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf066;');}
.icon-plus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf067;');}
.icon-minus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf068;');}
.icon-asterisk{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf069;');}
.icon-exclamation-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf06a;');}
.icon-gift{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf06b;');}
.icon-leaf{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf06c;');}
.icon-fire{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf06d;');}
.icon-eye-open{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf06e;');}
.icon-eye-close{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf070;');}
.icon-warning-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf071;');}
.icon-plane{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf072;');}
.icon-calendar{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf073;');}
.icon-random{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf074;');}
.icon-comment{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf075;');}
.icon-magnet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf076;');}
.icon-chevron-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf077;');}
.icon-chevron-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf078;');}
.icon-retweet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf079;');}
.icon-shopping-cart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf07a;');}
.icon-folder-close{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf07b;');}
.icon-folder-open{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf07c;');}
.icon-resize-vertical{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf07d;');}
.icon-resize-horizontal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf07e;');}
.icon-bar-chart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf080;');}
.icon-twitter-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf081;');}
.icon-facebook-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf082;');}
.icon-camera-retro{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf083;');}
.icon-key{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf084;');}
.icon-cogs{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf085;');}
.icon-gears{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf085;');}
.icon-comments{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf086;');}
.icon-thumbs-up-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf087;');}
.icon-thumbs-down-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf088;');}
.icon-star-half{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf089;');}
.icon-heart-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf08a;');}
.icon-signout{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf08b;');}
.icon-linkedin-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf08c;');}
.icon-pushpin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf08d;');}
.icon-external-link{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf08e;');}
.icon-signin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf090;');}
.icon-trophy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf091;');}
.icon-github-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf092;');}
.icon-upload-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf093;');}
.icon-lemon{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf094;');}
.icon-phone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf095;');}
.icon-check-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf096;');}
.icon-unchecked{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf096;');}
.icon-bookmark-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf097;');}
.icon-phone-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf098;');}
.icon-twitter{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf099;');}
.icon-facebook{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf09a;');}
.icon-github{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf09b;');}
.icon-unlock{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf09c;');}
.icon-credit-card{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf09d;');}
.icon-rss{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf09e;');}
.icon-hdd{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0a0;');}
.icon-bullhorn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0a1;');}
.icon-bell{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0a2;');}
.icon-certificate{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0a3;');}
.icon-hand-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0a4;');}
.icon-hand-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0a5;');}
.icon-hand-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0a6;');}
.icon-hand-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0a7;');}
.icon-circle-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0a8;');}
.icon-circle-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0a9;');}
.icon-circle-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0aa;');}
.icon-circle-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0ab;');}
.icon-globe{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0ac;');}
.icon-wrench{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0ad;');}
.icon-tasks{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0ae;');}
.icon-filter{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0b0;');}
.icon-briefcase{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0b1;');}
.icon-fullscreen{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0b2;');}
.icon-group{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0c0;');}
.icon-link{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0c1;');}
.icon-cloud{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0c2;');}
.icon-beaker{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0c3;');}
.icon-cut{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0c4;');}
.icon-copy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0c5;');}
.icon-paper-clip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0c6;');}
.icon-paperclip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0c6;');}
.icon-save{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0c7;');}
.icon-sign-blank{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0c8;');}
.icon-reorder{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0c9;');}
.icon-list-ul{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0ca;');}
.icon-list-ol{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0cb;');}
.icon-strikethrough{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0cc;');}
.icon-underline{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0cd;');}
.icon-table{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0ce;');}
.icon-magic{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0d0;');}
.icon-truck{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0d1;');}
.icon-pinterest{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0d2;');}
.icon-pinterest-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0d3;');}
.icon-google-plus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0d4;');}
.icon-google-plus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0d5;');}
.icon-money{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0d6;');}
.icon-caret-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0d7;');}
.icon-caret-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0d8;');}
.icon-caret-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0d9;');}
.icon-caret-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0da;');}
.icon-columns{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0db;');}
.icon-sort{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0dc;');}
.icon-sort-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0dd;');}
.icon-sort-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0de;');}
.icon-envelope{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e0;');}
.icon-linkedin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e1;');}
.icon-undo{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e2;');}
.icon-rotate-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e2;');}
.icon-legal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e3;');}
.icon-dashboard{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e4;');}
.icon-comment-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e5;');}
.icon-comments-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e6;');}
.icon-bolt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e7;');}
.icon-sitemap{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e8;');}
.icon-umbrella{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e9;');}
.icon-paste{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0ea;');}
.icon-lightbulb{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0eb;');}
.icon-exchange{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0ec;');}
.icon-cloud-download{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0ed;');}
.icon-cloud-upload{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0ee;');}
.icon-user-md{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0f0;');}
.icon-stethoscope{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0f1;');}
.icon-suitcase{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0f2;');}
.icon-bell-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0f3;');}
.icon-coffee{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0f4;');}
.icon-food{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0f5;');}
.icon-file-text-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0f6;');}
.icon-building{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0f7;');}
.icon-hospital{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0f8;');}
.icon-ambulance{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0f9;');}
.icon-medkit{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0fa;');}
.icon-fighter-jet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0fb;');}
.icon-beer{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0fc;');}
.icon-h-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0fd;');}
.icon-plus-sign-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0fe;');}
.icon-double-angle-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf100;');}
.icon-double-angle-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf101;');}
.icon-double-angle-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf102;');}
.icon-double-angle-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf103;');}
.icon-angle-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf104;');}
.icon-angle-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf105;');}
.icon-angle-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf106;');}
.icon-angle-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf107;');}
.icon-desktop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf108;');}
.icon-laptop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf109;');}
.icon-tablet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf10a;');}
.icon-mobile-phone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf10b;');}
.icon-circle-blank{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf10c;');}
.icon-quote-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf10d;');}
.icon-quote-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf10e;');}
.icon-spinner{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf110;');}
.icon-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf111;');}
.icon-reply{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf112;');}
.icon-mail-reply{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf112;');}
.icon-github-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf113;');}
.icon-folder-close-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf114;');}
.icon-folder-open-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf115;');}
.icon-expand-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf116;');}
.icon-collapse-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf117;');}
.icon-smile{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf118;');}
.icon-frown{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf119;');}
.icon-meh{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf11a;');}
.icon-gamepad{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf11b;');}
.icon-keyboard{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf11c;');}
.icon-flag-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf11d;');}
.icon-flag-checkered{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf11e;');}
.icon-terminal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf120;');}
.icon-code{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf121;');}
.icon-reply-all{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf122;');}
.icon-mail-reply-all{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf122;');}
.icon-star-half-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf123;');}
.icon-star-half-full{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf123;');}
.icon-location-arrow{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf124;');}
.icon-crop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf125;');}
.icon-code-fork{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf126;');}
.icon-unlink{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf127;');}
.icon-question{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf128;');}
.icon-info{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf129;');}
.icon-exclamation{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf12a;');}
.icon-superscript{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf12b;');}
.icon-subscript{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf12c;');}
.icon-eraser{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf12d;');}
.icon-puzzle-piece{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf12e;');}
.icon-microphone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf130;');}
.icon-microphone-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf131;');}
.icon-shield{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf132;');}
.icon-calendar-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf133;');}
.icon-fire-extinguisher{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf134;');}
.icon-rocket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf135;');}
.icon-maxcdn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf136;');}
.icon-chevron-sign-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf137;');}
.icon-chevron-sign-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf138;');}
.icon-chevron-sign-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf139;');}
.icon-chevron-sign-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf13a;');}
.icon-html5{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf13b;');}
.icon-css3{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf13c;');}
.icon-anchor{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf13d;');}
.icon-unlock-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf13e;');}
.icon-bullseye{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf140;');}
.icon-ellipsis-horizontal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf141;');}
.icon-ellipsis-vertical{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf142;');}
.icon-rss-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf143;');}
.icon-play-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf144;');}
.icon-ticket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf145;');}
.icon-minus-sign-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf146;');}
.icon-check-minus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf147;');}
.icon-level-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf148;');}
.icon-level-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf149;');}
.icon-check-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf14a;');}
.icon-edit-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf14b;');}
.icon-external-link-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf14c;');}
.icon-share-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf14d;');}
.icon-compass{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf14e;');}
.icon-collapse{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf150;');}
.icon-collapse-top{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf151;');}
.icon-expand{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf152;');}
.icon-eur{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf153;');}
.icon-euro{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf153;');}
.icon-gbp{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf154;');}
.icon-usd{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf155;');}
.icon-dollar{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf155;');}
.icon-inr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf156;');}
.icon-rupee{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf156;');}
.icon-jpy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf157;');}
.icon-yen{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf157;');}
.icon-cny{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf158;');}
.icon-renminbi{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf158;');}
.icon-krw{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf159;');}
.icon-won{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf159;');}
.icon-btc{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf15a;');}
.icon-bitcoin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf15a;');}
.icon-file{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf15b;');}
.icon-file-text{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf15c;');}
.icon-sort-by-alphabet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf15d;');}
.icon-sort-by-alphabet-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf15e;');}
.icon-sort-by-attributes{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf160;');}
.icon-sort-by-attributes-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf161;');}
.icon-sort-by-order{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf162;');}
.icon-sort-by-order-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf163;');}
.icon-thumbs-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf164;');}
.icon-thumbs-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf165;');}
.icon-youtube-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf166;');}
.icon-youtube{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf167;');}
.icon-xing{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf168;');}
.icon-xing-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf169;');}
.icon-youtube-play{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf16a;');}
.icon-dropbox{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf16b;');}
.icon-stackexchange{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf16c;');}
.icon-instagram{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf16d;');}
.icon-flickr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf16e;');}
.icon-adn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf170;');}
.icon-bitbucket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf171;');}
.icon-bitbucket-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf172;');}
.icon-tumblr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf173;');}
.icon-tumblr-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf174;');}
.icon-long-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf175;');}
.icon-long-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf176;');}
.icon-long-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf177;');}
.icon-long-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf178;');}
.icon-apple{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf179;');}
.icon-windows{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf17a;');}
.icon-android{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf17b;');}
.icon-linux{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf17c;');}
.icon-dribbble{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf17d;');}
.icon-skype{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf17e;');}
.icon-foursquare{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf180;');}
.icon-trello{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf181;');}
.icon-female{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf182;');}
.icon-male{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf183;');}
.icon-gittip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf184;');}
.icon-sun{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf185;');}
.icon-moon{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf186;');}
.icon-archive{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf187;');}
.icon-bug{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf188;');}
.icon-vk{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf189;');}
.icon-weibo{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf18a;');}
.icon-renren{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf18b;');}
@@ -8,13 +8,12 @@
<link rel="stylesheet" type="text/css" href="browserOutput.css" />
<link rel="stylesheet" type="text/css" href="spritesheet_chat.css" />
<link rel="stylesheet" type="text/css" id="colorPresetLink"/>
<script type="text/javascript" src="errorHandler.js"></script>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="json2.min.js"></script>
</head>
<body>
<div id="loading">
<i class="icon-spinner icon-2x"></i>
<i class="fas fa-spinner fa-2x"></i>
<div>
Loading...<br><br>
If this takes longer than 30 seconds, it will automatically reload a maximum of 5 times.<br>
@@ -26,34 +25,34 @@
</div>
<div id="userBar" style="display: none;">
<div id="ping">
<i class="icon-circle" id="pingDot"></i>
<i class="fas fa-circle" id="pingDot"></i>
<span class="ms" id="pingMs">--ms</span>
</div>
<div id="darkmodething">
<a href="#" class="subCell toggle" id="changeColorPreset" title="Change color preset"><i class="icon-eye-open"></i></a>
<a href="#" class="subCell toggle" id="changeColorPreset" title="Change color preset"><i class="fas fa-eye-open"></i></a>
</div>
<div id="audio">
<a href="#" class="subCell toggle" id="toggleAudio" title="Audio"><i class="icon-volume-up"></i></a>
<a href="#" class="subCell toggle" id="toggleAudio" title="Audio"><i class="fas fa-volume-up"></i></a>
</div>
<div id="options">
<a href="#" class="subCell toggle" id="toggleOptions" title="Options"><i class="icon-cog"></i></a>
<a href="#" class="subCell toggle" id="toggleOptions" title="Options"><i class="fas fa-cog"></i></a>
</div>
<div class="sub" id="subOptions">
<a href="#" class="subCell decreaseFont topCell" id="decreaseFont"><span>Decrease font size</span> <i class="icon-font">-</i></a>
<a href="#" class="subCell increaseFont" id="increaseFont"><span>Increase font size</span> <i class="icon-font">+</i></a>
<a href="#" class="subCell decreaseLineHeight" id="decreaseLineHeight"><span>Decrease line height</span> <i class="icon-text-height">-</i></a>
<a href="#" class="subCell increaseLineHeight" id="increaseLineHeight"><span>Increase line height</span> <i class="icon-text-height">+</i></a>
<a href="#" class="subCell togglePing" id="togglePing"><span>Toggle ping display</span> <i class="icon-circle"></i></a>
<a href="#" class="subCell highlightTerm" id="highlightTerm"><span>Highlight string</span> <i class="icon-tag"></i></a>
<a href="#" class="subCell saveLog" id="saveLog"><span>Save chat log</span> <i class="icon-save"></i></a>
<a href="#" class="subCell toggleCombine" id="toggleCombine"><span>Toggle line combining</span> <i class="icon-filter"></i></a>
<a href="#" class="subCell clearMessages" id="clearMessages"><span>Clear all messages</span> <i class="icon-eraser"></i></a>
<a href="#" class="subCell decreaseFont topCell" id="decreaseFont"><span>Decrease font size</span> <i class="fas fa-font">-</i></a>
<a href="#" class="subCell increaseFont" id="increaseFont"><span>Increase font size</span> <i class="fas fa-font">+</i></a>
<a href="#" class="subCell decreaseLineHeight" id="decreaseLineHeight"><span>Decrease line height</span> <i class="fas fa-text-height">-</i></a>
<a href="#" class="subCell increaseLineHeight" id="increaseLineHeight"><span>Increase line height</span> <i class="fas fa-text-height">+</i></a>
<a href="#" class="subCell togglePing" id="togglePing"><span>Toggle ping display</span> <i class="fas fa-circle"></i></a>
<a href="#" class="subCell highlightTerm" id="highlightTerm"><span>Highlight string</span> <i class="fas fa-tag"></i></a>
<a href="#" class="subCell saveLog" id="saveLog"><span>Save chat log</span> <i class="fas fa-save"></i></a>
<a href="#" class="subCell toggleCombine" id="toggleCombine"><span>Toggle line combining</span> <i class="fas fa-filter"></i></a>
<a href="#" class="subCell clearMessages" id="clearMessages"><span>Clear all messages</span> <i class="fas fa-eraser"></i></a>
</div>
<div class="sub" id="subAudio">
<span class="subCell topCell" id="musicVolumeSpan"><input type="range" class="hidden" id="musicVolume"><span id="musicVolumeText">Admin music volume</span><i class="icon-music"></i></span>
<span class="subCell topCell" id="musicVolumeSpan"><input type="range" class="hidden" id="musicVolume"><span id="musicVolumeText">Admin music volume</span><i class="fas fa-music"></i></span>
</div>
</div>
<audio class="hidden" id="adminMusic" autoplay></audio>
<script type="text/javascript" src="browserOutput.js"></script>
</body>
</html>
</html>
@@ -6,7 +6,6 @@
******************************************/
//DEBUG STUFF
var triggerError = attachErrorHandler('chatDebug', true);
var escaper = encodeURIComponent || escape;
var decoder = decodeURIComponent || unescape;
window.onerror = function(msg, url, line, col, error) {
@@ -1,34 +0,0 @@
(function(window, navigator) {
var escaper = encodeURIComponent || escape;
var triggerError = function(msg, url, line, col, error) {
window.onerror(msg, url, line, col, error);
};
/**
* Directs JS errors to a byond proc for logging
*
* @param string file Name of the logfile to dump errors in, do not prepend with data/
* @param boolean overrideDefault True to prevent default JS errors (an big honking error prompt thing)
* @return boolean
*/
var attach = function(file, overrideDefault) {
overrideDefault = typeof overrideDefault === 'undefined' ? false : overrideDefault;
file = escaper(file);
window.onerror = function(msg, url, line, col, error) {
var extra = !col ? '' : ' | column: ' + col;
extra += !error ? '' : ' | error: ' + error;
extra += !navigator.userAgent ? '' : ' | user agent: ' + navigator.userAgent;
var debugLine = 'Error: ' + msg + ' | url: ' + url + ' | line: ' + line + extra;
window.location = '?action=debugFileOutput&file=' + file + '&message=' + escaper(debugLine);
return overrideDefault;
};
return triggerError;
};
window.attachErrorHandler = attach;
}(window, window.navigator));
-102
View File
@@ -1,102 +0,0 @@
/**
* This is a generic handler for logging your dumb JS errors generated by html popups
*
* 1. Add your logfile to the validFiles list
* 2. Include the "browserassets/js/errorHandler.js" file in your html file (if using chui, skip this step) (look at browserOutput.html for an example)
* 3. Call attachErrorHandler('yourLogFile'); at the top of your JS (again see browserOutput.js for an example)
*/
/datum/debugFileOutput
var/directory = "data/popupErrors" //where to shove all the logfiles
var/ext = "log" //file extension
var/logFileLimit = 52428800 //50mb, so yeah pretty permissive
//Add your dumb file here. This is so some schmuck can't just shit out a bunch of spam logfiles and use all the diskspace. Relative to src.directory
var/list/validFiles = list(
"chatDebug",
"tooltipDebug",
"chemDispenser",
"banPanel",
"stationNamer"
)
/datum/debugFileOutput/proc/error(fileName, message, client/C)
if (!fileName || !message)
return 0
if (!(fileName in src.validFiles))
throw EXCEPTION("Debug log file '[fileName].[src.ext]' is not a valid path.")
var/logFile = file("[src.directory]/[fileName].[src.ext]")
var/fileSize = length(logFile)
if (fileSize >= src.logFileLimit)
CRASH("Debug Error Handling encountered an error! This is highly ironic! File: '[fileName]' has exceeded the filesize limit of: [src.logFileLimit] bytes")
message = "\[[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]\] Client: \[[C && C.key ? C.key : "Unknown Client"]\] triggered: [message]"
WRITE_FILE(logFile, message)
return 1
/datum/debugFileOutput/proc/clear(fileName)
if (!fileName)
return 0
if (!fexists("[src.directory]/[fileName].[src.ext]"))
throw EXCEPTION("Debug log file '[fileName].[src.ext]' does not exist.")
if (!(fileName in src.validFiles))
throw EXCEPTION("Debug log file '[fileName].[src.ext]' is not a valid path.")
fdel("[src.directory]/[fileName].[src.ext]")
return 1
/datum/debugFileOutput/proc/clearAll()
var/list/deleted = new()
for (var/fileName in src.validFiles)
if (fexists("[src.directory]/[fileName].[src.ext]"))
fdel("[src.directory]/[fileName].[src.ext]")
deleted += fileName
return deleted
GLOBAL_DATUM_INIT(debugFileOutput, /datum/debugFileOutput, new)
/client/Topic(href, href_list)
..()
if (href_list["action"] && href_list["action"] == "debugFileOutput" && href_list["file"] && href_list["message"])
var/file = href_list["file"]
var/message = href_list["message"]
GLOB.debugFileOutput.error(file, message, src)
/client/proc/deleteJsLogFile(fileName as text)
set category = "Debug"
set name = "Delete JS Logfile"
set desc = "Delete a logfile for JS error reporting. Be sure you want to do this!"
set popup_menu = 0
if(!holder)
return
if (!fileName)
return
GLOB.debugFileOutput.clear(fileName)
log_admin("[key_name(usr)] deleted the '[fileName]' JS logfile")
message_admins("[key_name_admin(usr)] deleted the '[fileName]' JS logfile")
/client/proc/deleteAllJsLogFiles()
set category = null
set name = "Delete All JS Logfiles"
set desc = "Delete all logfiles for JS error reporting. Be extra sure you want to do this!"
if(!holder)
return
if (alert("Are you really sure you want to delete every single JS logfile?", "No", "Yes") == "No")
return
var/list/summary = GLOB.debugFileOutput.clearAll()
var/friendlySummary = summary.Join(", ")
log_admin("[key_name(usr)] deleted every JS logfile! ([friendlySummary])")
message_admins("[key_name_admin(usr)] deleted every JS logfile! ([friendlySummary])")
+1 -1
View File
@@ -11,7 +11,7 @@
/datum/language_menu/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.language_menu_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "language_menu", "Language Menu", 700, 800, master_ui, state)
ui = new(user, src, ui_key, "language_menu", "Language Menu", 700, 600, master_ui, state)
ui.open()
/datum/language_menu/ui_data(mob/user)
+12 -8
View File
@@ -36,7 +36,7 @@ GLOBAL_LIST(labor_sheet_values)
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, "labor_claim_console", name, 450, 475, master_ui, state)
ui = new(user, src, ui_key, "labor_claim_console", name, 315, 430, master_ui, state)
ui.open()
/obj/machinery/mineral/labor_claim_console/ui_data(mob/user)
@@ -46,8 +46,6 @@ GLOBAL_LIST(labor_sheet_values)
data["emagged"] = (obj_flags & EMAGGED) ? 1 : 0
if(obj_flags & EMAGGED)
can_go_home = TRUE
data["status_info"] = "No Prisoner ID detected."
var/obj/item/card/id/I = user.get_idcard(TRUE)
if(istype(I, /obj/item/card/id/prisoner))
var/obj/item/card/id/prisoner/P = I
@@ -57,6 +55,9 @@ GLOBAL_LIST(labor_sheet_values)
data["status_info"] = "Goal met!"
else
data["status_info"] = "You are [(P.goal - P.points)] points away."
else
data["status_info"] = "No Prisoner ID detected."
data["id_points"] = 0
if(stacking_machine)
data["unclaimed_points"] = stacking_machine.points
@@ -78,24 +79,27 @@ GLOBAL_LIST(labor_sheet_values)
P.points += stacking_machine.points
stacking_machine.points = 0
to_chat(usr, "<span class='notice'>Points transferred.</span>")
. = TRUE
else
to_chat(usr, "<span class='notice'>No valid id for point transfer detected.</span>")
to_chat(usr, "<span class='alert'>No valid id for point transfer detected.</span>")
if("move_shuttle")
if(!alone_in_area(get_area(src), usr))
to_chat(usr, "<span class='warning'>Prisoners are only allowed to be released while alone.</span>")
to_chat(usr, "<span class='alert'>Prisoners are only allowed to be released while alone.</span>")
else
switch(SSshuttle.moveShuttle("laborcamp", "laborcamp_home", TRUE))
if(1)
to_chat(usr, "<span class='notice'>Shuttle not found.</span>")
to_chat(usr, "<span class='alert'>Shuttle not found.</span>")
if(2)
to_chat(usr, "<span class='notice'>Shuttle already at station.</span>")
to_chat(usr, "<span class='alert'>Shuttle already at station.</span>")
if(3)
to_chat(usr, "<span class='notice'>No permission to dock could be granted.</span>")
to_chat(usr, "<span class='alert'>No permission to dock could be granted.</span>")
else
if(!(obj_flags & EMAGGED))
Radio.set_frequency(FREQ_SECURITY)
Radio.talk_into(src, "A prisoner has returned to the station. Minerals and Prisoner ID card ready for retrieval.", FREQ_SECURITY)
to_chat(usr, "<span class='notice'>Shuttle received message and will be sent shortly.</span>")
. = TRUE
/obj/machinery/mineral/labor_claim_console/proc/locate_stacking_machine()
stacking_machine = locate(/obj/machinery/mineral/stacking_machine, get_step(src, machinedir))
@@ -220,6 +220,7 @@
data["disconnected"] = "mineral withdrawal is on hold"
data["diskDesigns"] = list()
data["hasDisk"] = FALSE
if(inserted_disk)
data["hasDisk"] = TRUE
if(inserted_disk.blueprints.len)
+30 -21
View File
@@ -28,7 +28,7 @@
/obj/structure/ore_box/examine(mob/living/user)
if(Adjacent(user) && istype(user))
show_contents(user)
ui_interact(user)
return ..()
/obj/structure/ore_box/attack_hand(mob/user)
@@ -36,22 +36,11 @@
if(.)
return
if(Adjacent(user))
show_contents(user)
ui_interact(user)
/obj/structure/ore_box/attack_robot(mob/user)
if(Adjacent(user))
show_contents(user)
/obj/structure/ore_box/proc/show_contents(mob/user)
var/dat = text("<b>The contents of the ore box reveal...</b><br>")
var/list/assembled = list()
for(var/obj/item/stack/ore/O in src)
assembled[O.type] += O.amount
for(var/type in assembled)
var/obj/item/stack/ore/O = type
dat += "[initial(O.name)] - [assembled[type]]<br>"
dat += text("<br><br><A href='?src=[REF(src)];removeall=1'>Empty box</A>")
user << browse(dat, "window=orebox")
ui_interact(user)
/obj/structure/ore_box/proc/dump_box_contents()
var/drop = drop_location()
@@ -65,18 +54,38 @@
stoplag()
drop = drop_location()
/obj/structure/ore_box/Topic(href, href_list)
/obj/structure/ore_box/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, "ore_box", name, 335, 415, master_ui, state)
ui.open()
/obj/structure/ore_box/ui_data()
var/contents = list()
for(var/obj/item/stack/ore/O in src)
contents[O.type] += O.amount
var/data = list()
data["materials"] = list()
for(var/type in contents)
var/obj/item/stack/ore/O = type
var/name = initial(O.name)
data["materials"] += list(list("name" = name, "amount" = contents[type], "id" = type))
return data
/obj/structure/ore_box/ui_act(action, params)
if(..())
return
if(!Adjacent(usr))
return
usr.set_machine(src)
add_fingerprint(usr)
if(href_list["removeall"])
dump_box_contents()
to_chat(usr, "<span class='notice'>You open the release hatch on the box..</span>")
updateUsrDialog()
usr.set_machine(src)
switch(action)
if("removeall")
dump_box_contents()
to_chat(usr, "<span class='notice'>You open the release hatch on the box..</span>")
/obj/structure/ore_box/deconstruct(disassembled = TRUE, mob/user)
var/obj/item/stack/sheet/mineral/wood/WD = new (loc, 4)
@@ -24,7 +24,7 @@
/datum/notificationpanel/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.observer_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "notificationpanel", "Notification Preferences", 700, 700, master_ui, state)
ui = new(user, src, ui_key, "notificationpanel", "Notification Preferences", 270, 360, master_ui, state)
ui.open()
/datum/notificationpanel/ui_data(mob/user)
@@ -14,7 +14,7 @@
icon_state = "mulebot0"
density = TRUE
move_resist = MOVE_FORCE_STRONG
animate_movement = 1
animate_movement = FORWARD_STEPS
health = 50
maxHealth = 50
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
@@ -29,10 +29,14 @@
model = "MULE"
bot_core_type = /obj/machinery/bot_core/mulebot
var/ui_x = 350
var/ui_y = 425
var/id
path_image_color = "#7F5200"
var/base_icon = "mulebot"
var/atom/movable/load = null
var/mob/living/passenger = null
var/turf/target // this is turf to navigate to (location of beacon)
@@ -74,16 +78,16 @@
/mob/living/simple_animal/bot/mulebot/proc/set_id(new_id)
id = new_id
if(paicard)
bot_name = "\improper MULEbot ([new_id])"
bot_name = "[initial(name)] ([new_id])"
else
name = "\improper MULEbot ([new_id])"
name = "[initial(name)] ([new_id])"
/mob/living/simple_animal/bot/mulebot/bot_reset()
..()
reached_target = 0
/mob/living/simple_animal/bot/mulebot/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/screwdriver))
if(I.tool_behaviour == TOOL_SCREWDRIVER)
..()
if(open)
on = FALSE
@@ -91,13 +95,13 @@
if(!user.transferItemToLoc(I, src))
return
cell = I
visible_message("[user] inserts a cell into [src].",
visible_message("<span class='notice'>[user] inserts a cell into [src].</span>",
"<span class='notice'>You insert the new cell into [src].</span>")
else if(istype(I, /obj/item/crowbar) && open && cell)
else if(I.tool_behaviour == TOOL_CROWBAR && open && cell)
cell.add_fingerprint(usr)
cell.forceMove(loc)
cell = null
visible_message("[user] crowbars out the power cell from [src].",
visible_message("<span class='notice'>[user] crowbars out the power cell from [src].</span>",
"<span class='notice'>You pry the powercell out of [src].</span>")
else if(is_wire_tool(I) && open)
return attack_hand(user)
@@ -121,13 +125,13 @@
locked = !locked
to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] [src]'s controls!</span>")
flick("mulebot-emagged", src)
playsound(src, "sparks", 100, 0)
playsound(src, "sparks", 100, FALSE)
/mob/living/simple_animal/bot/mulebot/update_icon()
if(open)
icon_state="mulebot-hatch"
icon_state="[base_icon]-hatch"
else
icon_state = "mulebot[wires.is_cut(WIRE_AVOIDANCE)]"
icon_state = "[base_icon][wires.is_cut(WIRE_AVOIDANCE)]"
cut_overlays()
if(load && !ismob(load))//buckling handles the mob offsets
load.pixel_y = initial(load.pixel_y) + 9
@@ -149,7 +153,8 @@
return
/mob/living/simple_animal/bot/mulebot/bullet_act(obj/item/projectile/Proj)
if(..())
. = ..()
if(. && !QDELETED(src)) //Got hit and not blown up yet.
if(prob(50) && !isnull(load))
unload(0)
if(prob(25))
@@ -168,7 +173,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, "mulebot", name, 600, 375, master_ui, state)
ui = new(user, src, ui_key, "mulebot", name, ui_x, ui_y, master_ui, state)
ui.open()
/mob/living/simple_animal/bot/mulebot/ui_data(mob/user)
@@ -188,12 +193,15 @@
else
data["load"] = load ? load.name : null
data["destination"] = destination ? destination : null
data["home"] = home_destination
data["destinations"] = GLOB.deliverybeacontags
data["cell"] = cell ? TRUE : FALSE
data["cellPercent"] = cell ? cell.percent() : null
data["autoReturn"] = auto_return
data["autoPickup"] = auto_pickup
data["reportDelivery"] = report_delivery
data["haspai"] = paicard ? TRUE : FALSE
data["id"] = id
return data
/mob/living/simple_animal/bot/mulebot/ui_act(action, params)
@@ -213,10 +221,10 @@
return
. = TRUE
else
bot_control(action, usr) // Kill this later.
bot_control(action, usr, params) // Kill this later.
. = TRUE
/mob/living/simple_animal/bot/mulebot/bot_control(command, mob/user, pda = 0)
/mob/living/simple_animal/bot/mulebot/bot_control(command, mob/user, list/params = list(), pda = FALSE)
if(pda && wires.is_cut(WIRE_RX)) // MULE wireless is controlled by wires.
return
@@ -231,15 +239,27 @@
if(mode == BOT_IDLE || mode == BOT_DELIVER)
start_home()
if("destination")
var/new_dest = input(user, "Enter Destination:", name, destination) as null|anything in GLOB.deliverybeacontags
var/new_dest
if(pda)
new_dest = input(user, "Enter Destination:", name, destination) as null|anything in GLOB.deliverybeacontags
else
new_dest = params["value"]
if(new_dest)
set_destination(new_dest)
if("setid")
var/new_id = stripped_input(user, "Enter ID:", name, id, MAX_NAME_LEN)
var/new_id
if(pda)
new_id = stripped_input(user, "Enter ID:", name, id, MAX_NAME_LEN)
else
new_id = params["value"]
if(new_id)
set_id(new_id)
if("sethome")
var/new_home = input(user, "Enter Home:", name, home_destination) as null|anything in GLOB.deliverybeacontags
var/new_home
if(pda)
new_home = input(user, "Enter Home:", name, home_destination) as null|anything in GLOB.deliverybeacontags
else
new_home = params["value"]
if(new_home)
home_destination = new_home
if("unload")
@@ -314,26 +334,28 @@
/mob/living/simple_animal/bot/mulebot/proc/buzz(type)
switch(type)
if(SIGH)
audible_message("[src] makes a sighing buzz.", "<span class='italics'>You hear an electronic buzzing sound.</span>")
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
audible_message("<span class='hear'>[src] makes a sighing buzz.</span>")
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, FALSE)
if(ANNOYED)
audible_message("[src] makes an annoyed buzzing sound.", "<span class='italics'>You hear an electronic buzzing sound.</span>")
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
audible_message("<span class='hear'>[src] makes an annoyed buzzing sound.</span>")
playsound(loc, 'sound/machines/buzz-two.ogg', 50, FALSE)
if(DELIGHT)
audible_message("[src] makes a delighted ping!", "<span class='italics'>You hear a ping.</span>")
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
audible_message("<span class='hear'>[src] makes a delighted ping!</span>")
playsound(loc, 'sound/machines/ping.ogg', 50, FALSE)
// mousedrop a crate to load the bot
// can load anything if hacked
/mob/living/simple_animal/bot/mulebot/MouseDrop_T(atom/movable/AM, mob/user)
if(user.incapacitated() || user.lying)
return
if(!istype(AM))
return
if(!istype(AM) || isdead(AM) || iscameramob(AM) || istype(AM, /obj/effect/dummy/phased_mob))
return
load(AM)
// called to load a crate
@@ -446,10 +468,8 @@
process_bot()
num_steps--
if(mode != BOT_IDLE)
spawn(0)
for(var/i=num_steps,i>0,i--)
sleep(2)
process_bot()
var/process_timer = addtimer(CALLBACK(src, .proc/process_bot), 2, TIMER_LOOP|TIMER_STOPPABLE)
addtimer(CALLBACK(GLOBAL_PROC, /proc/deltimer, process_timer), (num_steps*2) + 1)
/mob/living/simple_animal/bot/mulebot/proc/process_bot()
if(!on || client)
@@ -488,6 +508,7 @@
B.setDir(newdir)
bloodiness--
var/oldloc = loc
var/moved = step_towards(src, next) // attempt to move
if(cell)
@@ -513,11 +534,7 @@
buzz(SIGH)
mode = BOT_WAIT_FOR_NAV
blockcount = 0
spawn(20)
calc_path(avoid=next)
if(path.len > 0)
buzz(DELIGHT)
mode = BOT_BLOCKED
addtimer(CALLBACK(src, .proc/process_blocked, next), 2 SECONDS)
return
return
else
@@ -530,18 +547,26 @@
if(BOT_NAV) // calculate new path
mode = BOT_WAIT_FOR_NAV
spawn(0)
calc_path()
INVOKE_ASYNC(src, .proc/process_nav)
if(path.len > 0)
blockcount = 0
mode = BOT_BLOCKED
buzz(DELIGHT)
/mob/living/simple_animal/bot/mulebot/proc/process_blocked(turf/next)
calc_path(avoid=next)
if(path.len > 0)
buzz(DELIGHT)
mode = BOT_BLOCKED
else
buzz(SIGH)
/mob/living/simple_animal/bot/mulebot/proc/process_nav()
calc_path()
mode = BOT_NO_ROUTE
if(path.len > 0)
blockcount = 0
mode = BOT_BLOCKED
buzz(DELIGHT)
else
buzz(SIGH)
mode = BOT_NO_ROUTE
// calculates a path to the current destination
// given an optional turf to avoid
@@ -571,26 +596,28 @@
/mob/living/simple_animal/bot/mulebot/proc/start_home()
if(!on)
return
spawn(0)
set_destination(home_destination)
mode = BOT_BLOCKED
INVOKE_ASYNC(src, .proc/do_start_home)
update_icon()
/mob/living/simple_animal/bot/mulebot/proc/do_start_home()
set_destination(home_destination)
mode = BOT_BLOCKED
// called when bot reaches current target
/mob/living/simple_animal/bot/mulebot/proc/at_target()
if(!reached_target)
radio_channel = "Supply" //Supply channel
audible_message("[src] makes a chiming sound!", "<span class='italics'>You hear a chime.</span>")
playsound(loc, 'sound/machines/chime.ogg', 50, 0)
radio_channel = RADIO_CHANNEL_SUPPLY //Supply channel
audible_message("<span class='hear'>[src] makes a chiming sound!</span>")
playsound(loc, 'sound/machines/chime.ogg', 50, FALSE)
reached_target = 1
if(pathset) //The AI called us here, so notify it of our arrival.
loaddir = dir //The MULE will attempt to load a crate in whatever direction the MULE is "facing".
if(calling_ai)
to_chat(calling_ai, "<span class='notice'>[icon2html(src, calling_ai)] [src] wirelessly plays a chiming sound!</span>")
playsound(calling_ai, 'sound/machines/chime.ogg',40, 0)
playsound(calling_ai, 'sound/machines/chime.ogg',40, FALSE)
calling_ai = null
radio_channel = "AI Private" //Report on AI Private instead if the AI is controlling us.
radio_channel = RADIO_CHANNEL_AI_PRIVATE //Report on AI Private instead if the AI is controlling us.
if(load) // if loaded, unload at target
if(report_delivery)
@@ -642,7 +669,7 @@
log_combat(src, H, "run over", null, "(DAMTYPE: [uppertext(BRUTE)])")
H.visible_message("<span class='danger'>[src] drives over [H]!</span>", \
"<span class='userdanger'>[src] drives over you!</span>")
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
playsound(loc, 'sound/effects/splat.ogg', 50, TRUE)
var/damage = rand(5,15)
H.apply_damage(2*damage, BRUTE, BODY_ZONE_HEAD, run_armor_check(BODY_ZONE_HEAD, "melee"))
@@ -731,7 +758,7 @@
/mob/living/simple_animal/bot/mulebot/insertpai(mob/user, obj/item/paicard/card)
if(..())
visible_message("[src] safeties are locked on.")
visible_message("<span class='notice'>[src] safeties are locked on.</span>")
#undef SIGH
#undef ANNOYED
@@ -739,3 +766,4 @@
/obj/machinery/bot_core/mulebot
req_access = list(ACCESS_CARGO)
@@ -1,3 +1,5 @@
#define MAX_CHANNELS 1000
/datum/ntnet_conversation
var/id = null
var/title = "Untitled Conversation"
@@ -8,7 +10,11 @@
var/static/ntnrc_uid = 0
/datum/ntnet_conversation/New()
id = ntnrc_uid++
id = ntnrc_uid + 1
if(id > MAX_CHANNELS)
qdel(src)
return
ntnrc_uid = id
if(SSnetworks.station_network)
SSnetworks.station_network.chat_channels.Add(src)
..()
@@ -66,3 +72,5 @@
add_status_message("[client.username] has changed channel title from [title] to [newtitle]")
title = newtitle
#undef MAX_CHANNELS
@@ -316,7 +316,7 @@
data["PC_batteryicon"] = "batt_20.gif"
else
data["PC_batteryicon"] = "batt_5.gif"
data["PC_batterypercent"] = "[round(battery_module.battery.percent())] %"
data["PC_batterypercent"] = "[round(battery_module.battery.percent())]%"
data["PC_showbatteryicon"] = 1
else
data["PC_batteryicon"] = "batt_5.gif"
@@ -38,7 +38,8 @@
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers)
assets.send(user)
ui = new(user, src, ui_key, "ntos_main", "NTOS Main menu", 400, 500, master_ui, state)
ui = new(user, src, ui_key, "ntos_main", "NtOS Main menu", 400, 500, master_ui, state)
ui.set_style("ntos")
ui.open()
ui.set_autoupdate(state = 1)
@@ -68,10 +69,10 @@
switch(action)
if("PC_exit")
kill_program()
return 1
return TRUE
if("PC_shutdown")
shutdown_computer()
return 1
return TRUE
if("PC_minimize")
var/mob/user = usr
if(!active_program || !all_components[MC_CPU])
@@ -156,6 +157,7 @@
comp_light_color = new_color
light_color = new_color
update_light()
return TRUE
else
return
@@ -16,9 +16,9 @@
var/network_destination = null // Optional string that describes what NTNet server/system this program connects to. Used in default logging.
var/available_on_ntnet = 1 // Whether the program can be downloaded from NTNet. Set to 0 to disable.
var/available_on_syndinet = 0 // Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to 1 to enable.
var/tgui_id // ID of TG UI interface
var/ui_style // ID of custom TG UI style (optional)
var/ui_x = 575 // Default size of TG UI window, in pixels
var/tgui_id // ID of TGUI interface
var/ui_style // ID of custom TGUI style (optional)
var/ui_x = 575 // Default size of TGUI window, in pixels
var/ui_y = 700
var/ui_header = null // Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /icons/program_icons. Be careful not to use too large images!
@@ -71,7 +71,7 @@
// Check if the user can run program. Only humans can operate computer. Automatically called in run_program()
// User has to wear their ID for ID Scan to work.
// Can also be called manually, with optional parameter being access_to_check to scan the user's ID
/datum/computer_file/program/proc/can_run(mob/user, loud = 0, access_to_check, transfer = 0)
/datum/computer_file/program/proc/can_run(mob/user, loud = FALSE, access_to_check, transfer = FALSE)
// Defaults to required_access
if(!access_to_check)
if(transfer && transfer_access)
@@ -79,16 +79,16 @@
else
access_to_check = required_access
if(!access_to_check) // No required_access, allow it.
return 1
return TRUE
if(!transfer && computer && (computer.obj_flags & EMAGGED)) //emags can bypass the execution locks but not the download ones.
return 1
return TRUE
if(IsAdminGhost(user))
return 1
return TRUE
if(issilicon(user))
return 1
return TRUE
if(ishuman(user))
var/obj/item/card/id/D
@@ -101,17 +101,17 @@
if(!I && !D)
if(loud)
to_chat(user, "<span class='danger'>\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.</span>")
return 0
return FALSE
if(I)
if(access_to_check in I.GetAccess())
return 1
return TRUE
else if(D)
if(access_to_check in D.GetAccess())
return 1
return TRUE
if(loud)
to_chat(user, "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>")
return 0
return FALSE
// This attempts to retrieve header data for UIs. If implementing completely new device of different type than existing ones
// always include the device here in this proc. This proc basically relays the request to whatever is running the program.
@@ -127,15 +127,15 @@
if(requires_ntnet && network_destination)
generate_network_log("Connection opened to [network_destination].")
program_state = PROGRAM_STATE_ACTIVE
return 1
return 0
return TRUE
return FALSE
// Use this proc to kill the program. Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client.
/datum/computer_file/program/proc/kill_program(forced = FALSE)
program_state = PROGRAM_STATE_KILLED
if(network_destination)
generate_network_log("Connection to [network_destination] closed.")
return 1
return TRUE
/datum/computer_file/program/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)
@@ -158,17 +158,17 @@
// ALWAYS INCLUDE PARENT CALL ..() OR DIE IN FIRE.
/datum/computer_file/program/ui_act(action,params,datum/tgui/ui)
if(..())
return 1
return TRUE
if(computer)
switch(action)
if("PC_exit")
computer.kill_program()
ui.close()
return 1
return TRUE
if("PC_shutdown")
computer.shutdown_computer()
ui.close()
return 1
return TRUE
if("PC_minimize")
var/mob/user = usr
if(!computer.active_program || !computer.all_components[MC_CPU])
@@ -10,6 +10,8 @@
unsendable = 1
undeletable = 1
size = 4
ui_x = 420
ui_y = 630
available_on_ntnet = 0
requires_ntnet = 0
tgui_id = "ntos_configuration"
@@ -10,215 +10,225 @@
ui_header = "ntnrc_idle.gif"
available_on_ntnet = 1
tgui_id = "ntos_net_chat"
ui_x = 900
ui_y = 675
var/last_message = null // Used to generate the toolbar icon
var/last_message // Used to generate the toolbar icon
var/username
var/datum/ntnet_conversation/channel = null
var/operator_mode = 0 // Channel operator mode
var/netadmin_mode = 0 // Administrator mode (invisible to other users + bypasses passwords)
var/active_channel
var/list/channel_history = list()
var/operator_mode = FALSE // Channel operator mode
var/netadmin_mode = FALSE // Administrator mode (invisible to other users + bypasses passwords)
/datum/computer_file/program/chatclient/New()
username = "DefaultUser[rand(100, 999)]"
/datum/computer_file/program/chatclient/ui_act(action, params)
if(..())
return 1
return
var/datum/ntnet_conversation/channel = SSnetworks.station_network.get_chat_channel_by_id(active_channel)
var/authed = FALSE
if(channel && ((channel.operator == src) || netadmin_mode))
authed = TRUE
switch(action)
if("PRG_speak")
. = 1
if(!channel)
return 1
var/mob/living/user = usr
var/message = reject_bad_text(input(user, "Enter message or leave blank to cancel: "))
if(!message || !channel)
if(!channel || isnull(active_channel))
return
var/message = reject_bad_text(params["message"])
if(!message)
return
if(channel.password && !(src in channel.clients))
if(channel.password == message)
channel.add_client(src)
return TRUE
channel.add_message(message, username)
var/mob/living/user = usr
user.log_talk(message, LOG_CHAT, tag="as [username] to channel [channel.title]")
return TRUE
if("PRG_joinchannel")
. = 1
var/datum/ntnet_conversation/C
for(var/datum/ntnet_conversation/chan in SSnetworks.station_network.chat_channels)
if(chan.id == text2num(params["id"]))
C = chan
break
if(!C)
return 1
var/new_target = text2num(params["id"])
if(isnull(new_target) || new_target == active_channel)
return
if(netadmin_mode)
channel = C // Bypasses normal leave/join and passwords. Technically makes the user invisible to others.
return 1
active_channel = new_target // Bypasses normal leave/join and passwords. Technically makes the user invisible to others.
return TRUE
if(C.password)
var/mob/living/user = usr
var/password = reject_bad_text(input(user,"Access Denied. Enter password:"))
if(C && (password == C.password))
C.add_client(src)
channel = C
return 1
C.add_client(src)
channel = C
active_channel = new_target
channel = SSnetworks.station_network.get_chat_channel_by_id(new_target)
if(!(src in channel.clients) && !channel.password)
channel.add_client(src)
return TRUE
if("PRG_leavechannel")
. = 1
if(channel)
channel.remove_client(src)
channel = null
active_channel = null
return TRUE
if("PRG_newchannel")
. = 1
var/mob/living/user = usr
var/channel_title = reject_bad_text(input(user,"Enter channel name or leave blank to cancel:"))
var/channel_title = reject_bad_text(params["new_channel_name"])
if(!channel_title)
return
var/datum/ntnet_conversation/C = new/datum/ntnet_conversation()
var/datum/ntnet_conversation/C = new /datum/ntnet_conversation()
C.add_client(src)
C.operator = src
channel = C
C.title = channel_title
active_channel = C.id
return TRUE
if("PRG_toggleadmin")
. = 1
if(netadmin_mode)
netadmin_mode = 0
netadmin_mode = FALSE
if(channel)
channel.remove_client(src) // We shouldn't be in channel's user list, but just in case...
channel = null
return 1
return TRUE
var/mob/living/user = usr
if(can_run(usr, 1, ACCESS_NETWORK))
if(channel)
var/response = alert(user, "Really engage admin-mode? You will be disconnected from your current channel!", "NTNRC Admin mode", "Yes", "No")
if(response == "Yes")
if(channel)
channel.remove_client(src)
channel = null
else
return
netadmin_mode = 1
if(can_run(user, TRUE, ACCESS_NETWORK))
for(var/C in SSnetworks.station_network.chat_channels)
var/datum/ntnet_conversation/chan = C
chan.remove_client(src)
netadmin_mode = TRUE
return TRUE
if("PRG_changename")
. = 1
var/mob/living/user = usr
var/newname = sanitize(input(user,"Enter new nickname or leave blank to cancel:"))
var/newname = sanitize(params["new_name"])
if(!newname)
return 1
if(channel)
channel.add_status_message("[username] is now known as [newname].")
return
for(var/C in SSnetworks.station_network.chat_channels)
var/datum/ntnet_conversation/chan = C
if(src in chan.clients)
chan.add_status_message("[username] is now known as [newname].")
username = newname
return TRUE
if("PRG_savelog")
. = 1
if(!channel)
return
var/mob/living/user = usr
var/logname = stripped_input(user,"Enter desired logfile name (.log) or leave blank to cancel:")
if(!logname || !channel)
return 1
var/datum/computer_file/data/logfile = new/datum/computer_file/data/logfile()
var/logname = stripped_input(params["log_name"])
if(!logname)
return
var/datum/computer_file/data/logfile = new /datum/computer_file/data/logfile()
// Now we will generate HTML-compliant file that can actually be viewed/printed.
logfile.filename = logname
logfile.stored_data = "\[b\]Logfile dump from NTNRC channel [channel.title]\[/b\]\[BR\]"
for(var/logstring in channel.messages)
logfile.stored_data += "[logstring]\[BR\]"
logfile.stored_data += "\[b\]Logfile dump completed.\[/b\]"
logfile.stored_data = "[logfile.stored_data][logstring]\[BR\]"
logfile.stored_data = "[logfile.stored_data]\[b\]Logfile dump completed.\[/b\]"
logfile.calculate_size()
var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
if(!computer || !hard_drive || !hard_drive.store_file(logfile))
if(!computer)
// This program shouldn't even be runnable without computer.
CRASH("Var computer is null!")
return 1
if(!hard_drive)
computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive connection error\" warning.")
computer.visible_message("<span class='warning'>\The [computer] shows an \"I/O Error - Hard drive connection error\" warning.</span>")
else // In 99.9% cases this will mean our HDD is full
computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning.")
computer.visible_message("<span class='warning'>\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning.</span>")
return TRUE
if("PRG_renamechannel")
. = 1
if(!operator_mode || !channel)
return 1
var/mob/living/user = usr
var/newname = reject_bad_text(input(user, "Enter new channel name or leave blank to cancel:"))
if(!authed)
return
var/newname = reject_bad_text(params["new_name"])
if(!newname || !channel)
return
channel.add_status_message("Channel renamed from [channel.title] to [newname] by operator.")
channel.title = newname
return TRUE
if("PRG_deletechannel")
. = 1
if(channel && ((channel.operator == src) || netadmin_mode))
if(authed)
qdel(channel)
channel = null
active_channel = null
return TRUE
if("PRG_setpassword")
. = 1
if(!channel || ((channel.operator != src) && !netadmin_mode))
return 1
if(!authed)
return
var/mob/living/user = usr
var/newpassword = sanitize(input(user, "Enter new password for this channel. Leave blank to cancel, enter 'nopassword' to remove password completely:"))
if(!channel || !newpassword || ((channel.operator != src) && !netadmin_mode))
return 1
var/new_password = sanitize(params["new_password"])
if(!authed)
return
if(newpassword == "nopassword")
channel.password = ""
else
channel.password = newpassword
channel.password = new_password
return TRUE
/datum/computer_file/program/chatclient/process_tick()
..()
. = ..()
var/datum/ntnet_conversation/channel = SSnetworks.station_network.get_chat_channel_by_id(active_channel)
if(program_state != PROGRAM_STATE_KILLED)
ui_header = "ntnrc_idle.gif"
if(channel)
// Remember the last message. If there is no message in the channel remember null.
last_message = channel.messages.len ? channel.messages[channel.messages.len - 1] : null
last_message = length(channel.messages) ? channel.messages[length(channel.messages)] : null
else
last_message = null
return 1
if(channel && channel.messages && channel.messages.len)
ui_header = last_message == channel.messages[channel.messages.len - 1] ? "ntnrc_idle.gif" : "ntnrc_new.gif"
return TRUE
if(channel?.messages?.len)
ui_header = last_message == channel.messages[length(channel.messages)] ? "ntnrc_idle.gif" : "ntnrc_new.gif"
else
ui_header = "ntnrc_idle.gif"
/datum/computer_file/program/chatclient/kill_program(forced = FALSE)
if(channel)
for(var/C in SSnetworks.station_network.chat_channels)
var/datum/ntnet_conversation/channel = C
channel.remove_client(src)
channel = null
..()
/datum/computer_file/program/chatclient/ui_static_data(mob/user)
var/list/data = list()
data["can_admin"] = can_run(user, FALSE, ACCESS_NETWORK)
return data
/datum/computer_file/program/chatclient/ui_data(mob/user)
if(!SSnetworks.station_network || !SSnetworks.station_network.chat_channels)
return
return list()
var/list/data = list()
data = get_header_data()
var/list/all_channels = list()
for(var/C in SSnetworks.station_network.chat_channels)
var/datum/ntnet_conversation/conv = C
if(conv && conv.title)
all_channels.Add(list(list(
"chan" = conv.title,
"id" = conv.id
)))
data["all_channels"] = all_channels
data["active_channel"] = active_channel
data["username"] = username
data["adminmode"] = netadmin_mode
var/datum/ntnet_conversation/channel = SSnetworks.station_network.get_chat_channel_by_id(active_channel)
if(channel)
data["title"] = channel.title
var/list/messages[0]
for(var/M in channel.messages)
messages.Add(list(list(
"msg" = M
)))
data["messages"] = messages
var/list/clients[0]
var/authed = FALSE
if(!channel.password)
authed = TRUE
if(netadmin_mode)
authed = TRUE
var/list/clients = list()
for(var/C in channel.clients)
if(C == src)
authed = TRUE
var/datum/computer_file/program/chatclient/cl = C
clients.Add(list(list(
"name" = cl.username
)))
data["clients"] = clients
operator_mode = (channel.operator == src) ? 1 : 0
data["is_operator"] = operator_mode || netadmin_mode
else // Channel selection screen
var/list/all_channels[0]
for(var/C in SSnetworks.station_network.chat_channels)
var/datum/ntnet_conversation/conv = C
if(conv && conv.title)
all_channels.Add(list(list(
"chan" = conv.title,
"id" = conv.id
data["authed"] = authed
//no fishing for ui data allowed
if(authed)
data["clients"] = clients
var/list/messages = list()
for(var/M in channel.messages)
messages.Add(list(list(
"msg" = M
)))
data["all_channels"] = all_channels
data["messages"] = messages
data["is_operator"] = (channel.operator == src) || netadmin_mode
else
data["clients"] = list()
data["messages"] = list()
else
data["clients"] = list()
data["authed"] = FALSE
data["messages"] = list()
return data
return data
@@ -12,8 +12,9 @@
network_destination = "power monitoring system"
size = 9
tgui_id = "ntos_power_monitor"
ui_x = 1200
ui_y = 1000
ui_style = "ntos"
ui_x = 550
ui_y = 700
var/has_alert = 0
var/obj/structure/cable/attached_wire
@@ -9,8 +9,9 @@
network_destination = "supermatter monitoring system"
size = 5
tgui_id = "ntos_supermatter_monitor"
ui_style = "ntos"
ui_x = 600
ui_y = 400
ui_y = 350
var/last_status = SUPERMATTER_INACTIVE
var/list/supermatters
var/obj/machinery/power/supermatter_crystal/active // Currently selected supermatter crystal.
+56 -36
View File
@@ -27,6 +27,9 @@
var/dev_printer = 0 // 0: None, 1: Standard
var/dev_card = 0 // 0: None, 1: Standard
ui_x = 500
ui_y = 400
// Removes all traces of old order and allows you to begin configuration from scratch.
/obj/machinery/lapvend/proc/reset_order()
state = 0
@@ -46,7 +49,7 @@
dev_card = 0
// Recalculates the price and optionally even fabricates the device.
/obj/machinery/lapvend/proc/fabricate_and_recalc_price(fabricate = 0)
/obj/machinery/lapvend/proc/fabricate_and_recalc_price(fabricate = FALSE)
total_price = 0
if(devtype == 1) // Laptop, generally cheaper to make it accessible for most station roles
var/obj/item/computer_hardware/battery/battery_module = null
@@ -160,7 +163,7 @@
if(fabricate)
fabricated_tablet.install_component(new/obj/item/computer_hardware/card_slot)
return total_price
return 0
return FALSE
@@ -168,90 +171,106 @@
/obj/machinery/lapvend/ui_act(action, params)
if(..())
return 1
return TRUE
switch(action)
if("pick_device")
if(state) // We've already picked a device type
return 0
return FALSE
devtype = text2num(params["pick"])
state = 1
fabricate_and_recalc_price(0)
return 1
fabricate_and_recalc_price(FALSE)
return TRUE
if("clean_order")
reset_order()
return 1
return TRUE
if("purchase")
try_purchase()
return 1
return TRUE
if((state != 1) && devtype) // Following IFs should only be usable when in the Select Loadout mode
return 0
return FALSE
switch(action)
if("confirm_order")
state = 2 // Wait for ID swipe for payment processing
fabricate_and_recalc_price(0)
return 1
fabricate_and_recalc_price(FALSE)
return TRUE
if("hw_cpu")
dev_cpu = text2num(params["cpu"])
fabricate_and_recalc_price(0)
return 1
fabricate_and_recalc_price(FALSE)
return TRUE
if("hw_battery")
dev_battery = text2num(params["battery"])
fabricate_and_recalc_price(0)
return 1
fabricate_and_recalc_price(FALSE)
return TRUE
if("hw_disk")
dev_disk = text2num(params["disk"])
fabricate_and_recalc_price(0)
return 1
fabricate_and_recalc_price(FALSE)
return TRUE
if("hw_netcard")
dev_netcard = text2num(params["netcard"])
fabricate_and_recalc_price(0)
return 1
fabricate_and_recalc_price(FALSE)
return TRUE
if("hw_tesla")
dev_apc_recharger = text2num(params["tesla"])
fabricate_and_recalc_price(0)
return 1
fabricate_and_recalc_price(FALSE)
return TRUE
if("hw_nanoprint")
dev_printer = text2num(params["print"])
fabricate_and_recalc_price(0)
return 1
fabricate_and_recalc_price(FALSE)
return TRUE
if("hw_card")
dev_card = text2num(params["card"])
fabricate_and_recalc_price(0)
return 1
return 0
fabricate_and_recalc_price(FALSE)
return TRUE
return FALSE
/obj/machinery/lapvend/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)
if(stat & (BROKEN | NOPOWER | MAINT))
if(ui)
ui.close()
return 0
return FALSE
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if (!ui)
ui = new(user, src, ui_key, "computer_fabricator", "Personal Computer Vendor", 500, 400, state = state)
ui = new(user, src, ui_key, "computer_fabricator", "Personal Computer Vendor", ui_x, ui_y, state = state)
ui.open()
ui.set_autoupdate(state = 1)
/obj/machinery/lapvend/attackby(obj/item/I as obj, mob/user as mob)
/obj/machinery/lapvend/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/stack/spacecash))
var/obj/item/stack/spacecash/c = I
if(!user.temporarilyRemoveItemFromInventory(c))
return
credits += c.value
visible_message("<span class='info'><span class='name'>[usr]</span> inserts [c.value] credits into [src].</span>")
visible_message("<span class='info'><span class='name'>[user]</span> inserts [c.value] credits into [src].</span>")
qdel(c)
return
/*else if(istype(I, /obj/item/holochip))
var/obj/item/holochip/HC = I
credits += HC.credits
visible_message("<span class='info'>[user] inserts a $[HC.credits] holocredit chip into [src].</span>")
qdel(HC)
return
else if(istype(I, /obj/item/card/id))
if(state != 2)
return
var/obj/item/card/id/ID = I
var/datum/bank_account/account = ID.registered_account
var/target_credits = total_price - credits
if(!account.adjust_money(-target_credits))
say("Insufficient money on card to purchase!")
return
credits += target_credits
say("$[target_credits] has been desposited from your account.")
return */ //Goonconomy when
return ..()
// Simplified payment processing, returns 1 on success.
/obj/machinery/lapvend/proc/process_payment()
if(total_price > credits)
say("Insufficient credits.")
return 0
return FALSE
else
return 1
return TRUE
/obj/machinery/lapvend/ui_data(mob/user)
@@ -287,5 +306,6 @@
credits -= total_price
say("Enjoy your new product!")
state = 3
return 1
return 0
addtimer(CALLBACK(src, .proc/reset_order), 100)
return TRUE
return FALSE

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