Merge branch 'master' into kk-climbs

This commit is contained in:
Killian
2024-11-10 22:03:41 +00:00
committed by GitHub
438 changed files with 7104 additions and 4442 deletions
+1
View File
@@ -19,6 +19,7 @@ cfg/
#Ignore everything in datafolder and subdirectories
/data/**/*
/tmp/**/*
/cache/**/*
#Visual studio stuff
*.vscode/*
+2 -2
View File
@@ -17,7 +17,7 @@
/client/proc/atmos_toggle_debug(var/obj/machinery/atmospherics/M in view())
set name = "Toggle Debug Messages"
set category = "Debug"
set category = "Debug.Misc"
M.debug = !M.debug
to_chat(usr, "[M]: Debug messages toggled [M.debug? "on" : "off"].")
@@ -439,7 +439,7 @@
var/sink_heat_capacity = sink.heat_capacity()
var/transfer_heat_capacity = source.heat_capacity()*estimate_moles/source_total_moles
air_temperature = (sink.temperature*sink_heat_capacity + source.temperature*transfer_heat_capacity) / (sink_heat_capacity + transfer_heat_capacity)
//get the number of moles that would have to be transfered to bring sink to the target pressure
return pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION)
+4 -4
View File
@@ -1,5 +1,5 @@
/client/proc/ZoneTick()
set category = "Debug"
set category = "Debug.Misc"
set name = "Process Atmos"
set desc = "Manually run a single tick of the air subsystem"
@@ -17,7 +17,7 @@
*/
/client/proc/Zone_Info(turf/T as null|turf)
set category = "Debug"
set category = "Debug.Misc"
if(T)
if(istype(T,/turf/simulated) && T:zone)
T:zone:dbg_data(src)
@@ -36,7 +36,7 @@
/client/var/list/zone_debug_images
/client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
set category = "Debug"
set category = "Debug.Misc"
if(!istype(T))
return
@@ -95,6 +95,6 @@
to_chat(mob, "both turfs can merge.")
/client/proc/ZASSettings()
set category = "Debug"
set category = "Debug.Dangerous"
vsc.SetDefault(mob)
+30
View File
@@ -0,0 +1,30 @@
#define VIRUS_SYMPTOM_LIMIT 6
//Visibility Flags
#define HIDDEN_SCANNER (1<<0)
#define HIDDEN_PANDEMIC (1<<1)
//Disease Flags
#define CURABLE (1<<0)
#define CAN_CARRY (1<<1)
#define CAN_RESIST (1<<2)
//Spread Flags
#define SPECIAL (1<<0)
#define NON_CONTAGIOUS (1<<1)
#define BLOOD (1<<2)
#define CONTACT_FEET (1<<3)
#define CONTACT_HANDS (1<<4)
#define CONTACT_GENERAL (1<<5)
#define AIRBORNE (1<<6)
//Severity Defines
#define NONTHREAT "No threat"
#define MINOR "Minor"
#define MEDIUM "Medium"
#define HARMFUL "Harmful"
#define DANGEROUS "Dangerous!"
#define BIOHAZARD "BIOHAZARD THREAT!"
#define SYMPTOM_ACTIVATION_PROB 3
+6
View File
@@ -220,3 +220,9 @@
#define ROUNDUPTOPOWEROFTWO(x) (2 ** -round(-log(2,x)))
#define DEFAULT(a, b) (a? a : b)
// sqrt, but if you give it a negative number, you get 0 instead of a runtime
/proc/sqrtor0(num)
if(num < 0)
return 0
return sqrt(num)
+2 -1
View File
@@ -116,7 +116,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
// Subsystem init_order, from highest priority to lowest priority
// Subsystems shutdown in the reverse of the order they initialize in
// The numbers just define the ordering, they are meaningless otherwise.
#define INIT_ORDER_SERVER_MAINT 93
#define INIT_ORDER_WEBHOOKS 50
#define INIT_ORDER_SQLITE 40
#define INIT_ORDER_GARBAGE 39
@@ -169,6 +169,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define FIRE_PRIORITY_VOTE 8
#define FIRE_PRIORITY_INSTRUMENTS 9
#define FIRE_PRIORITY_PING 10
#define FIRE_PRIORITY_SERVER_MAINT 10
#define FIRE_PRIORITY_AI 10
#define FIRE_PRIORITY_GARBAGE 15
#define FIRE_PRIORITY_ASSETS 20
+7
View File
@@ -209,6 +209,13 @@
result = first - second
return result
/**
* Removes any null entries from the list
* Returns TRUE if the list had nulls, FALSE otherwise
**/
/proc/list_clear_nulls(list/list_to_clear)
return (list_to_clear.RemoveAll(null) > 0)
/*
Two lists may be different (A!=B) even if they have the same elements.
This actually tests if they have the same entries and values.
+3 -2
View File
@@ -52,8 +52,9 @@ GLOBAL_LIST_INIT(custom_species_bases, new) // Species that can be used for a Cu
//Underwear
var/datum/category_collection/underwear/global_underwear = new()
//Backpacks
var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt", "Messenger Bag", "Sports Bag", "Strapless Satchel") //VOREStation edit
//Customizables
GLOBAL_LIST_INIT(headsetlist, list("Standard","Bowman","Earbud"))
var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt", "Messenger Bag", "Sports Bag", "Strapless Satchel")
var/global/list/pdachoicelist = list("Default", "Slim", "Old", "Rugged", "Holographic", "Wrist-Bound","Slider", "Vintage")
var/global/list/exclude_jobs = list(/datum/job/ai,/datum/job/cyborg)
+1 -1
View File
@@ -396,7 +396,7 @@
HUD.inventory_shown = 0
/mob/living/carbon/human/verb/toggle_hotkey_verbs()
set category = "OOC"
set category = "OOC.Client Settings"
set name = "Toggle hotkey buttons"
set desc = "This disables or enables the user interface buttons which can be used with hotkeys."
+1 -1
View File
@@ -2,7 +2,7 @@
/mob/observer/dead/verb/toggle_inquisition() // warning: unexpected inquisition
set name = "Toggle Inquisitiveness"
set desc = "Sets whether your ghost examines everything on click by default"
set category = "Ghost"
set category = "Ghost.Settings"
if(!client) return
client.inquisitive_ghost = !client.inquisitive_ghost
if(client.inquisitive_ghost)
+1 -1
View File
@@ -10,7 +10,7 @@
/client/verb/toggle_hardsuit_mode()
set name = "Toggle Hardsuit Activation Mode"
set desc = "Switch between hardsuit activation modes."
set category = "OOC"
set category = "OOC.Game Settings"
hardsuit_click_mode++
if(hardsuit_click_mode > MAX_HARDSUIT_CLICK_MODE)
@@ -12,10 +12,12 @@
/datum/config_entry/flag/limbs_can_break
/datum/config_entry/number/organ_health_multiplier
default = 1
integer = FALSE
default = 1.0
/datum/config_entry/number/organ_regeneration_multiplier
default = 1
integer = FALSE
default = 1.0
// FIXME: Unused
///datum/config_entry/flag/revival_pod_plants
@@ -549,13 +549,12 @@
/datum/config_entry/flag/persistence_ignore_mapload
/datum/config_entry/flag/allow_byond_links
default = TRUE //CHOMP Edit turned this on
default = TRUE
/datum/config_entry/flag/allow_discord_links
default = TRUE //CHOMP Edit turned this on
default = TRUE
/datum/config_entry/flag/allow_url_links
default = TRUE // honestly if I were you i'd leave this one off, only use in dire situations //CHOMP Edit: pussy.
default = TRUE // honestly if I were you i'd leave this one off, only use in dire situations
/datum/config_entry/flag/starlight // Whether space turfs have ambient light or not
+1 -1
View File
@@ -147,7 +147,7 @@ SUBSYSTEM_DEF(plants)
// Debug for testing seed genes.
/client/proc/show_plant_genes()
set category = "Debug"
set category = "Debug.Investigate"
set name = "Show Plant Genes"
set desc = "Prints the round's plant gene masks."
+115
View File
@@ -0,0 +1,115 @@
#define PING_BUFFER_TIME 25
SUBSYSTEM_DEF(server_maint)
name = "Server Tasks"
wait = 6
flags = SS_POST_FIRE_TIMING
priority = FIRE_PRIORITY_SERVER_MAINT
init_order = INIT_ORDER_SERVER_MAINT
//init_stage = INITSTAGE_EARLY
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
var/list/currentrun
///Associated list of list names to lists to clear of nulls
var/list/lists_to_clear
///Delay between list clearings in ticks
var/delay = 5
var/cleanup_ticker = 0
/*/datum/controller/subsystem/server_maint/PreInit()
world.hub_password = "" *///quickly! before the hubbies see us.
/datum/controller/subsystem/server_maint/New()
if (fexists("tmp/"))
fdel("tmp/")
//if (CONFIG_GET(flag/hub))
//world.update_hub_visibility(TRUE)
//Keep in mind, because of how delay works adding a list here makes each list take wait * delay more time to clear
//Do it for stuff that's properly important, and shouldn't have null checks inside its other uses
lists_to_clear = list(
"player_list" = global.player_list,
"mob_list" = global.mob_list,
"living_mob_list" = global.living_mob_list,
"dead_mob_list" = global.dead_mob_list,
"observer_mob_list" = global.observer_mob_list,
"listening_objects" = global.listening_objects,
"human_mob_list" = global.human_mob_list,
"silicon_mob_list" = global.silicon_mob_list,
"ai_list" = global.ai_list,
//"keyloop_list" = global.keyloop_list, //A null here will cause new clients to be unable to move. totally unacceptable
)
/*var/datum/tgs_version/tgsversion = world.TgsVersion()
if(tgsversion)
SSblackbox.record_feedback("text", "server_tools", 1, tgsversion.raw_parameter)*/
return SS_INIT_SUCCESS
/datum/controller/subsystem/server_maint/fire(resumed = FALSE)
if(!resumed)
if(list_clear_nulls(GLOB.clients))
log_world("Found a null in clients list!")
src.currentrun = GLOB.clients.Copy()
var/position_in_loop = (cleanup_ticker / delay) + 1 //Index at 1, thanks byond
if(!(position_in_loop % 1)) //If it's a whole number
var/listname = lists_to_clear[position_in_loop]
if(list_clear_nulls(lists_to_clear[listname]))
log_world("Found a null in [listname]!")
cleanup_ticker++
var/amount_to_work = length(lists_to_clear)
if(cleanup_ticker >= amount_to_work * delay) //If we've already done a loop, reset
cleanup_ticker = 0
var/list/currentrun = src.currentrun
//var/round_started = SSticker.HasRoundStarted()
//var/kick_inactive = CONFIG_GET(flag/kick_inactive)
//var/afk_period
//if(kick_inactive)
//afk_period = CONFIG_GET(number/afk_period)
for(var/I in currentrun)
var/client/C = I
//handle kicking inactive players
/*if(round_started && kick_inactive && !C.holder && C.is_afk(afk_period))
var/cmob = C.mob
if (!isnewplayer(cmob) || !SSticker.queued_players.Find(cmob))
log_access("AFK: [key_name(C)]")
to_chat(C, span_userdanger("You have been inactive for more than [DisplayTimeText(afk_period)] and have been disconnected.") + "<br>" + span_danger("You may reconnect via the button in the file menu or by " + span_bold(span_underline("<a href='byond://winset?command=.reconnect'>clicking here to reconnect</a>")" + "."))
QDEL_IN(C, 1) //to ensure they get our message before getting disconnected
continue*/
if (!(!C || world.time - C.connection_time < PING_BUFFER_TIME || C.inactivity >= (wait-1)))
winset(C, null, "command=.update_ping+[num2text(world.time+world.tick_lag*TICK_USAGE_REAL/100, 32)]")
if (MC_TICK_CHECK) //one day, when ss13 has 1000 people per server, you guys are gonna be glad I added this tick check
return
/datum/controller/subsystem/server_maint/Shutdown()
if (fexists("tmp/"))
fdel("tmp/")
//kick_clients_in_lobby(span_boldannounce("The round came to an end with you in the lobby."), TRUE) //second parameter ensures only afk clients are kicked
var/server = CONFIG_GET(string/server)
for(var/thing in GLOB.clients)
if(!thing)
continue
var/client/C = thing
C?.tgui_panel?.send_roundrestart()
if(server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
C << link("byond://[server]")
/*
/datum/controller/subsystem/server_maint/proc/UpdateHubStatus()
if(!CONFIG_GET(flag/hub) || !CONFIG_GET(number/max_hub_pop))
return FALSE //no point, hub / auto hub controls are disabled
var/max_pop = CONFIG_GET(number/max_hub_pop)
if(GLOB.clients.len > max_pop)
world.update_hub_visibility(FALSE)
else
world.update_hub_visibility(TRUE)
*/
#undef PING_BUFFER_TIME
+4 -2
View File
@@ -136,7 +136,7 @@ SUBSYSTEM_DEF(statpanels)
target.stat_panel.send_message("update_stat", list(
global_data = global_data,
ping_str = "Ping: -- Not Available --", // [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)",
ping_str = "Ping: [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)",
other_str = target.mob?.get_status_tab_items(),
))
@@ -173,7 +173,9 @@ SUBSYSTEM_DEF(statpanels)
target.stat_panel.send_message("update_examine", examine_update)
/datum/controller/subsystem/statpanels/proc/set_tickets_tab(client/target)
var/list/tickets = GLOB.ahelp_tickets.stat_entry(target)
var/list/tickets = list()
if(check_rights(R_ADMIN|R_SERVER|R_MOD,FALSE,target)) //Prevents non-staff from opening the list of ahelp tickets
tickets += GLOB.ahelp_tickets.stat_entry(target)
tickets += GLOB.mhelp_tickets.stat_entry(target)
target.stat_panel.send_message("update_tickets", tickets)
+1 -1
View File
@@ -392,7 +392,7 @@ SUBSYSTEM_DEF(vote)
usr.client.vote()
/client/verb/vote()
set category = "OOC"
set category = "OOC.Game"
set name = "Vote"
if(SSvote)
+3 -3
View File
@@ -38,7 +38,7 @@
// Debug verbs.
/client/proc/restart_controller(controller in list("Master", "Failsafe"))
set category = "Debug"
set category = "Debug.Dangerous"
set name = "Restart Controller"
set desc = "Restart one of the various periodic loop controllers for the game (be careful!)"
@@ -55,7 +55,7 @@
message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.")
/client/proc/debug_antagonist_template(antag_type in all_antag_types)
set category = "Debug"
set category = "Debug.Investigate"
set name = "Debug Antagonist"
set desc = "Debug an antagonist template."
@@ -65,7 +65,7 @@
message_admins("Admin [key_name_admin(usr)] is debugging the [antag.role_text] template.")
/client/proc/debug_controller()
set category = "Debug"
set category = "Debug.Investigate"
set name = "Debug Controller"
set desc = "Debug the various subsystems/controllers for the game (be careful!)"
+2 -1
View File
@@ -94,6 +94,7 @@ var/list/runechat_image_cache = list()
* * lifespan - The lifespan of the message in deciseconds
*/
/datum/chatmessage/proc/generate_image(text, atom/target, mob/owner, list/extra_classes, lifespan)
set waitfor = FALSE
if(!target || !owner)
qdel(src)
@@ -231,7 +232,7 @@ var/list/runechat_image_cache = list()
return
ending_life = TRUE
animate(message, alpha = 0, time = fadetime, flags = ANIMATION_PARALLEL)
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), src), fadetime, TIMER_DELETE_ME, TIMER_UNIQUE)
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), src), fadetime, TIMER_DELETE_ME)
/**
* Creates a message overlay at a defined location for a given speaker
+195
View File
@@ -0,0 +1,195 @@
/mob/proc/HasDisease(datum/disease/D)
for(var/thing in GetViruses())
var/datum/disease/DD = thing
if(DD.IsSame(D))
return TRUE
return FALSE
/mob/proc/CanContractDisease(datum/disease/D)
if(stat == DEAD && !D.allow_dead)
return FALSE
if(D.GetDiseaseID() in GetResistances())
return FALSE
if(HasDisease(D))
return FALSE
if(istype(D, /datum/disease/advance) && count_by_type(GetViruses(), /datum/disease/advance) > 0)
return FALSE
if(!(type in D.viable_mobtypes))
return -1
if(isSynthetic())
if(D.infect_synthetics)
return TRUE
return FALSE
return TRUE
/mob/proc/ContractDisease(datum/disease/D)
if(!CanContractDisease(D))
return 0
AddDisease(D)
return TRUE
/mob/proc/AddDisease(datum/disease/D, respect_carrier = FALSE)
var/datum/disease/DD = new D.type(1, D, 0)
viruses += DD
DD.affected_mob = src
active_diseases += DD
var/list/skipped = list("affected_mob", "holder", "carrier", "stage", "type", "parent_type", "vars", "transformed")
if(respect_carrier)
skipped -= "carrier"
for(var/V in DD.vars)
if(V in skipped)
continue
if(istype(DD.vars[V],/list))
var/list/L = D.vars[V]
DD.vars[V] = L.Copy()
else
DD.vars[V] = D.vars[V]
log_admin("[key_name(usr)] has contracted the virus \"[DD]\"")
/mob/living/carbon/ContractDisease(datum/disease/D)
if(!CanContractDisease(D))
return 0
var/obj/item/clothing/Cl = null
var/passed = 1
var/head_ch = 100
var/body_ch = 100
var/hands_ch = 25
var/feet_ch = 25
if(D.spread_flags & CONTACT_HANDS)
head_ch = 0
body_ch = 0
hands_ch = 100
feet_ch = 0
if(D.spread_flags & CONTACT_FEET)
head_ch = 0
body_ch = 0
hands_ch = 0
feet_ch = 100
if(prob(15/D.permeability_mod))
return
if(nutrition > 300 && prob(nutrition/10))
return
var/list/zone_weights = list(
1 = head_ch,
2 = body_ch,
3 = hands_ch,
4 = feet_ch
)
var/target_zone = pick(zone_weights)
if(ishuman(src))
var/mob/living/carbon/human/H = src
switch(target_zone)
if(1)
if(isobj(H.head) && !istype(H.head, /obj/item/paper))
Cl = H.head
passed = prob((Cl.permeability_coefficient*100) - 1)
if(passed && isobj(H.wear_mask))
Cl = H.wear_mask
passed = prob((Cl.permeability_coefficient*100) - 1)
if(2)
if(isobj(H.wear_suit))
Cl = H.wear_suit
passed = prob((Cl.permeability_coefficient*100) - 1)
if(passed && isobj(H.w_uniform))
Cl = H.w_uniform
passed = prob((Cl.permeability_coefficient*100) - 1)
if(3)
if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered & HANDS)
Cl = H.wear_suit
passed = prob((Cl.permeability_coefficient*100) - 1)
if(passed && isobj(H.gloves))
Cl = H.gloves
passed = prob((Cl.permeability_coefficient*100) - 1)
if(4)
if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered & FEET)
Cl = H.wear_suit
passed = prob((Cl.permeability_coefficient*100) - 1)
if(passed && isobj(H.shoes))
Cl = H.shoes
passed = prob((Cl.permeability_coefficient*100) - 1)
if(!passed && (D.spread_flags & AIRBORNE) && !internal)
passed = (prob((50*D.permeability_mod) -1))
if(passed)
AddDisease(D)
return passed
/mob/proc/ForceContractDisease(datum/disease/D, respect_carrier)
if(!CanContractDisease(D))
return FALSE
AddDisease(D, respect_carrier)
return TRUE
/mob/living/carbon/human/CanContractDisease(datum/disease/D)
if(species.virus_immune && !D.bypasses_immunity)
return FALSE
for(var/organ in D.required_organs)
if(locate(organ) in internal_organs)
continue
if(locate(organ) in organs)
continue
return FALSE
return ..()
/mob/living/carbon/human/monkey/CanContractDisease(datum/disease/D)
. = ..()
if(. == -1)
if(D.viable_mobtypes.Find(/mob/living/carbon/human))
return 1
/mob/living/proc/handle_diseases()
return
/mob/proc/GetViruses()
LAZYINITLIST(viruses)
return viruses
/mob/proc/GetResistances()
LAZYINITLIST(resistances)
return resistances
/client/proc/ReleaseVirus()
set category = "Fun.Event Kit"
set name = "Release Virus"
set desc = "Release a pre-set virus."
if(!is_admin())
return FALSE
var/datum/disease/D = tgui_input_list(usr, "Choose virus", "Viruses", subtypesof(/datum/disease), subtypesof(/datum/disease))
var/mob/living/carbon/human/H = null
if(isnull(D))
return FALSE
for(var/thing in shuffle(human_mob_list))
H = thing
if(H.stat == DEAD)
continue
if(!H.HasDisease(D))
H.ForceContractDisease(D)
break
message_admins("[key_name_admin(usr)] has triggered a virus outbreak of [D.name]! Affected mob: [key_name_admin(H)]")
log_admin("[key_name_admin(usr)] infected [key_name_admin(H)] with [D.name]")
+167
View File
@@ -0,0 +1,167 @@
GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
/datum/disease
//Flags
var/visibility_flags = 0
var/disease_flags = CURABLE|CAN_CARRY|CAN_RESIST
var/spread_flags = AIRBORNE
//Fluff
/// Used for identification of viruses in the Medical Records Virus Database
var/medical_name
var/form = "Virus"
var/name = "No disease"
var/desc = ""
var/agent = "some microbes"
var/spread_text = ""
var/cure_text = ""
//Stages
var/stage = 1
var/max_stages = 0
var/stage_prob = 4
/// The fraction of stages the virus must at least be at to show up on medical HUDs. Rounded up.
var/discovery_threshold = 0.5
/// If TRUE, this virus will show up on medical HUDs. Automatically set when it reaches mid-stage.
var/discovered = FALSE
// Other
var/list/viable_mobtypes = list()
var/mob/living/carbon/affected_mob
var/list/cures = list()
var/infectivity = 65
var/cure_chance = 8
var/carrier = FALSE
var/bypasses_immunity = FALSE
var/virus_heal_resistant = FALSE
var/permeability_mod = 1
var/severity = NONTHREAT
var/list/required_organs = list()
var/needs_all_cures = TRUE
var/list/strain_data = list()
var/allow_dead = FALSE
var/infect_synthetics = FALSE
var/processing = FALSE
/datum/disease/Destroy()
affected_mob = null
active_diseases.Remove(src)
if(processing)
End()
return ..()
/datum/disease/proc/stage_act()
if(!affected_mob)
return FALSE
var/cure = has_cure()
if(carrier && !cure)
return FALSE
if(!processing)
processing = TRUE
Start()
stage = min(stage, max_stages)
handle_stage_advance(cure)
return handle_cure_testing(cure)
/datum/disease/proc/handle_stage_advance(has_cure = FALSE)
if(!has_cure && prob(stage_prob))
stage = min(stage + 1, max_stages)
if(!discovered && stage >= CEILING(max_stages * discovery_threshold, 1))
discovered = TRUE
BITSET(affected_mob.hud_updateflag, STATUS_HUD)
/datum/disease/proc/handle_cure_testing(has_cure = FALSE)
if(has_cure && prob(cure_chance))
stage = max(stage -1, 1)
if(disease_flags & CURABLE)
if(has_cure && prob(cure_chance))
cure()
return FALSE
return TRUE
/datum/disease/proc/has_cure()
if(!(disease_flags & CURABLE))
return 0
var/cures_found = 0
for(var/C_id in cures)
if(affected_mob.reagents.has_reagent(C_id))
cures_found++
if(needs_all_cures && cures_found < length(cures))
return FALSE
return cures_found
/datum/disease/proc/spread(force_spread = 0)
if(!affected_mob)
return
if((spread_flags & SPECIAL || spread_flags & NON_CONTAGIOUS || spread_flags & BLOOD) && !force_spread)
return
if(affected_mob.reagents.has_reagent("spaceacilin") || (affected_mob.nutrition > 300 && prob(affected_mob.nutrition/10)))
return
var/spread_range = 1
if(force_spread)
spread_range = force_spread
if(spread_flags & AIRBORNE)
spread_range++
var/turf/target = affected_mob.loc
if(istype(target))
for(var/mob/living/carbon/C in oview(spread_range, affected_mob))
var/turf/current = get_turf(C)
if(current)
while(TRUE)
if(current == target)
C.ContractDisease(src)
break
var/direction = get_dir(current, target)
var/turf/next = get_step(current, direction)
current = next
/datum/disease/proc/cure()
if(affected_mob)
if(disease_flags & CAN_RESIST)
if(!(type in affected_mob.GetResistances()))
affected_mob.resistances += type
remove_virus()
qdel(src)
/datum/disease/proc/IsSame(datum/disease/D)
if(ispath(D))
return istype(src, D)
return istype(src, D.type)
/datum/disease/proc/Copy()
var/datum/disease/D = new type()
D.strain_data = strain_data.Copy()
return D
/datum/disease/proc/GetDiseaseID()
return type
/datum/disease/proc/IsSpreadByTouch()
if(spread_flags & CONTACT_FEET || spread_flags & CONTACT_HANDS || spread_flags & CONTACT_GENERAL)
return 1
return 0
/datum/disease/proc/remove_virus()
affected_mob.viruses -= src
BITSET(affected_mob.hud_updateflag, STATUS_HUD)
/datum/disease/proc/Start()
return
/datum/disease/proc/End()
return
+404
View File
@@ -0,0 +1,404 @@
GLOBAL_LIST_EMPTY(archive_diseases)
GLOBAL_LIST_INIT(advance_cures, list(
"sodiumchloride", "sugar", "orangejuice",
"spaceacilin", "glucose", "ethanol",
"dyloteane", "impedrezene", "hepanephrodaxon",
"gold", "silver"
))
/datum/disease/advance
name = "Unknown"
desc = "An engineered disease which can contain a multitude of symptoms."
form = "Advance Disease"
agent = "advance microbes"
max_stages = 5
spread_text = "Unknown"
viable_mobtypes = list(/mob/living/carbon/human)
var/list/symptoms = list()
var/id = ""
/datum/disease/advance/New(process = 1, datum/disease/advance/D)
if(!istype(D))
D = null
if(!symptoms || !length(symptoms))
if(!D || !D.symptoms || !length(D.symptoms))
symptoms = GenerateSymptoms(0, 2)
else
for(var/datum/symptom/S in D.symptoms)
symptoms += new S.type
Refresh()
..(process, D)
return
/datum/disease/advance/Destroy()
if(processing)
for(var/datum/symptom/S in symptoms)
S.End(src)
return ..()
/datum/disease/advance/stage_act()
if(!..())
return FALSE
if(symptoms && length(symptoms))
if(!processing)
processing = TRUE
for(var/datum/symptom/S in symptoms)
S.Start(src)
for(var/datum/symptom/S in symptoms)
S.Activate(src)
else
CRASH("We do not have any symptoms during stage_act()!")
return TRUE
/datum/disease/advance/IsSame(datum/disease/advance/D)
if(ispath(D))
return FALSE
if(!istype(D, /datum/disease/advance))
return FALSE
if(GetDiseaseID() != D.GetDiseaseID())
return FALSE
return TRUE
/datum/disease/advance/cure(resistance=1)
if(affected_mob)
var/id = "[GetDiseaseID()]"
if(resistance && !(id in affected_mob.GetResistances()))
affected_mob.GetResistances()[id] = id
remove_virus()
qdel(src)
/datum/disease/advance/Copy(process = 0)
return new /datum/disease/advance(process, src, 1)
/datum/disease/advance/proc/Mix(datum/disease/advance/D)
if(!(IsSame(D)))
var/list/possible_symptoms = shuffle(D.symptoms)
for(var/datum/symptom/S in possible_symptoms)
AddSymptom(new S.type)
/datum/disease/advance/proc/HasSymptom(datum/symptom/S)
for(var/datum/symptom/symp in symptoms)
if(symp.id == S.id)
return 1
return 0
/datum/disease/advance/proc/GenerateSymptomsBySeverity(sev_min, sev_max, amount = 1)
var/list/generated = list()
var/list/possible_symptoms = list()
for(var/symp in GLOB.list_symptoms)
var/datum/symptom/S = new symp
if(S.severity >= sev_min && S.severity <= sev_max)
if(!HasSymptom(S))
possible_symptoms += S
if(!length(possible_symptoms))
return generated
for(var/i = 1 to amount)
generated += pick_n_take(possible_symptoms)
return generated
/datum/disease/advance/proc/GenerateSymptoms(level_min, level_max, amount_get = 0)
var/list/generated = list()
// Generate symptoms. By default, we only choose non-deadly symptoms.
var/list/possible_symptoms = list()
for(var/symp in GLOB.list_symptoms)
var/datum/symptom/S = new symp
if(S.level >= level_min && S.level <= level_max)
if(!HasSymptom(S))
possible_symptoms += S
if(!length(possible_symptoms))
return generated
// Random chance to get more than one symptom
var/number_of = amount_get
if(!amount_get)
number_of = 1
while(prob(20))
number_of += 1
for(var/i = 1; number_of >= i && length(possible_symptoms); i++)
generated += pick_n_take(possible_symptoms)
return generated
/datum/disease/advance/proc/Refresh(new_name = FALSE, archive = FALSE)
var/list/properties = GenerateProperties()
AssignProperties(properties)
id = null
if(!GLOB.archive_diseases[GetDiseaseID()])
if(new_name)
AssignName()
GLOB.archive_diseases[GetDiseaseID()] = src // So we don't infinite loop
GLOB.archive_diseases[GetDiseaseID()] = new /datum/disease/advance(0, src, 1)
var/datum/disease/advance/A = GLOB.archive_diseases[GetDiseaseID()]
AssignName(A.name)
/datum/disease/advance/proc/GenerateProperties()
if(!symptoms || !length(symptoms))
CRASH("We did not have any symptoms before generating properties.")
var/list/properties = list("resistance" = 1, "stealth" = 0, "stage rate" = 1, "transmittable" = 1, "severity" = 0)
for(var/datum/symptom/S in symptoms)
properties["resistance"] += S.resistance
properties["stealth"] += S.stealth
properties["stage rate"] += S.stage_speed
properties["transmittable"] += S.transmittable
properties["severity"] = max(properties["severity"], S.severity) // severity is based on the highest severity symptom
return properties
/datum/disease/advance/proc/AssignProperties(list/properties = list())
if(properties && length(properties))
switch(properties["stealth"])
if(2)
visibility_flags = HIDDEN_SCANNER
if(3 to INFINITY)
visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC
// The more symptoms we have, the less transmittable it is but some symptoms can make up for it.
SetSpread(clamp(2 ** (properties["transmittable"] - length(symptoms)), BLOOD, AIRBORNE))
permeability_mod = max(CEILING(0.4 * properties["transmittable"], 1), 1)
cure_chance = 15 - clamp(properties["resistance"], -5, 5) // can be between 10 and 20
stage_prob = max(properties["stage rate"], 2)
SetSeverity(properties["severity"])
GenerateCure(properties)
else
CRASH("Our properties were empty or null!")
/datum/disease/advance/proc/SetSpread(spread_id)
switch(spread_id)
if(NON_CONTAGIOUS, SPECIAL)
spread_text = "Non-contagious"
if(CONTACT_GENERAL, CONTACT_HANDS, CONTACT_FEET)
spread_text = "On contact"
if(AIRBORNE)
spread_text = "Airborne"
if(BLOOD)
spread_text = "Blood"
spread_flags = spread_id
/datum/disease/advance/proc/SetSeverity(level_sev)
switch(level_sev)
if(-INFINITY to 0)
severity = NONTHREAT
if(1)
severity = MINOR
if(2)
severity = MEDIUM
if(3)
severity = HARMFUL
if(4)
severity = DANGEROUS
if(5 to INFINITY)
severity = BIOHAZARD
else
severity = "Unknown"
/datum/disease/advance/proc/GenerateCure(list/properties = list())
if(properties && length(properties))
var/res = clamp(properties["resistance"] - (length(symptoms) / 2), 1, length(GLOB.advance_cures))
cures = list(GLOB.advance_cures[res])
cure_text = cures[1]
return
// Randomly generate a symptom, has a chance to lose or gain a symptom.
/datum/disease/advance/proc/Evolve(min_level, max_level)
var/s = safepick(GenerateSymptoms(min_level, max_level, 1))
if(s)
AddSymptom(s)
Refresh(1)
return
// Randomly remove a symptom.
/datum/disease/advance/proc/Devolve()
if(length(symptoms) > 1)
var/s = safepick(symptoms)
if(s)
RemoveSymptom(s)
Refresh(1)
return
// Name the disease.
/datum/disease/advance/proc/AssignName(name = "Unknown")
src.name = name
return
// Return a unique ID of the disease.
/datum/disease/advance/GetDiseaseID()
if(!id)
var/list/L = list()
for(var/datum/symptom/S in symptoms)
L += S.id
L = sortList(L) // Sort the list so it doesn't matter which order the symptoms are in.
var/result = jointext(L, ":")
id = result
return id
// Add a symptom, if it is over the limit (with a small chance to be able to go over)
// we take a random symptom away and add the new one.
/datum/disease/advance/proc/AddSymptom(datum/symptom/S)
if(HasSymptom(S))
return
if(length(symptoms) < (VIRUS_SYMPTOM_LIMIT - 1) + rand(-1, 1))
symptoms += S
else
RemoveSymptom(pick(symptoms))
symptoms += S
return
// Simply removes the symptom.
/datum/disease/advance/proc/RemoveSymptom(datum/symptom/S)
symptoms -= S
return
// Mix a list of advance diseases and return the mixed result.
/proc/Advance_Mix(list/D_list)
var/list/diseases = list()
for(var/datum/disease/advance/A in D_list)
diseases += A.Copy()
if(!length(diseases))
return null
if(length(diseases) <= 1)
return pick(diseases) // Just return the only entry.
var/i = 0
// Mix our diseases until we are left with only one result.
while(i < 20 && length(diseases) > 1)
i++
var/datum/disease/advance/D1 = pick(diseases)
diseases -= D1
var/datum/disease/advance/D2 = pick(diseases)
D2.Mix(D1)
// Should be only 1 entry left, but if not let's only return a single entry
var/datum/disease/advance/to_return = pick(diseases)
to_return.Refresh(1)
return to_return
/proc/SetViruses(datum/reagent/R, list/data)
if(data)
var/list/preserve = list()
if(istype(data) && data["viruses"])
for(var/datum/disease/A in data["viruses"])
preserve += A.Copy()
R.data = data.Copy()
if(length(preserve))
R.data["viruses"] = preserve
/client/proc/AdminCreateVirus()
set category = "Fun.Event Kit"
set name = "Create Advanced Virus"
set desc = "Create an advanced virus and release it."
if(!is_admin())
return FALSE
var/i = VIRUS_SYMPTOM_LIMIT
var/mob/living/carbon/human/H = null
var/datum/disease/advance/D = new(0, null)
D.symptoms = list()
var/list/symptoms = list()
symptoms += "Done"
symptoms += GLOB.list_symptoms.Copy()
do
if(usr)
var/symptom = tgui_input_list(usr, "Choose a symptom to add ([i] remaining)", "Choose a Symptom", symptoms)
if(isnull(symptom))
return
else if(istext(symptom))
i = 0
else if(ispath(symptom))
var/datum/symptom/S = new symptom
if(!D.HasSymptom(S))
D.symptoms += S
i -= 1
while(i > 0)
if(length(D.symptoms) > 0)
var/new_name = tgui_input_text(usr, "Name your new disease.", "New Name")
if(!new_name)
return
D.AssignName(new_name)
D.Refresh()
for(var/datum/disease/advance/AD in active_diseases)
AD.Refresh()
for(var/thing in shuffle(human_mob_list))
H = thing
if(H.stat == DEAD)
continue
if(!H.HasDisease(D))
H.ForceContractDisease(D)
break
var/list/name_symptoms = list()
for(var/datum/symptom/S in D.symptoms)
name_symptoms += S.name
message_admins("[key_name_admin(usr)] has triggered a custom virus outbreak of [D.name]! It has these symptoms: [english_list(name_symptoms)]")
log_admin("[key_name_admin(usr)] infected [key_name_admin(H)] with [D.name]. It has these symptoms: [english_list(name_symptoms)]")
/datum/disease/advance/proc/totalStageSpeed()
var/total_stage_speed = 0
for(var/i in symptoms)
var/datum/symptom/S = i
total_stage_speed += S.stage_speed
return total_stage_speed
/datum/disease/advance/proc/totalStealth()
var/total_stealth = 0
for(var/i in symptoms)
var/datum/symptom/S = i
total_stealth += S.stealth
return total_stealth
/datum/disease/advance/proc/totalResistance()
var/total_resistance = 0
for(var/i in symptoms)
var/datum/symptom/S = i
total_resistance += S.resistance
return total_resistance
/datum/disease/advance/proc/totalTransmittable()
var/total_transmittable = 0
for(var/i in symptoms)
var/datum/symptom/S = i
total_transmittable += S.transmittable
return total_transmittable
@@ -0,0 +1,16 @@
// Cold
/datum/disease/advance/cold/New(process = 1, datum/disease/advance/D, copy = 0)
if(!D)
name = "Cold"
symptoms = list(new /datum/symptom/sneeze)
..(process, D, copy)
// Flu
/datum/disease/advance/flu/New(process = 1, datum/disease/advance/D, copy = 0)
if(!D)
name = "Flu"
symptoms = list(new /datum/symptom/cough)
..(process, D, copy)
@@ -0,0 +1,52 @@
/*
//////////////////////////////////////
Choking
Very very noticable.
Lowers resistance.
Decreases stage speed.
Decreases transmittablity tremendously.
Moderate Level.
Bonus
Inflicts spikes of oxyloss
//////////////////////////////////////
*/
/datum/symptom/choking
name = "Choking"
stealth = -3
resistance = -2
stage_speed = -2
transmittable = -4
level = 3
severity = 3
/datum/symptom/choking/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2)
to_chat(M, span_warning(pick("You're having difficulty breathing.", "Your breathing becomes heavy.")))
if(3, 4)
to_chat(M, span_boldwarning(pick("Your windpipe feels like a straw.", "Your breathing becomes tremendously difficult.")))
Choke_stage_3_4(M, A)
M.emote("gasp")
else
to_chat(M, span_userdanger(pick("You're choking!", "You can't breathe!")))
Choke(M, A)
M.emote("gasp")
return
/datum/symptom/choking/proc/Choke_stage_3_4(mob/living/M, datum/disease/advance/A)
var/get_damage = sqrtor0(21+A.totalStageSpeed()*0.5)+sqrtor0(16+A.totalStealth())
M.adjustOxyLoss(get_damage)
return 1
/datum/symptom/choking/proc/Choke(mob/living/M, datum/disease/advance/A)
var/get_damage = sqrtor0(21+A.totalStageSpeed()*0.5)+sqrtor0(16+A.totalStealth()*5)
M.adjustOxyLoss(get_damage)
return 1
@@ -0,0 +1,40 @@
/*
//////////////////////////////////////
Confusion
Little bit hidden.
Lowers resistance.
Decreases stage speed.
Not very transmittable.
Intense Level.
Bonus
Makes the affected mob be confused for short periods of time.
//////////////////////////////////////
*/
/datum/symptom/confusion
name = "Confusion"
stealth = 1
resistance = -1
stage_speed = -3
transmittable = 0
level = 4
severity = 2
/datum/symptom/confusion/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
to_chat(M, span_warning(pick("Your head hurts.", "Your mind blanks for a moment.")))
else
to_chat(M, span_userdanger("You can't think straight!"))
M.AdjustConfused(rand(16, 200))
return
@@ -0,0 +1,39 @@
/*
//////////////////////////////////////
Coughing
Noticable.
Little Resistance.
Doesn't increase stage speed much.
Transmittable.
Low Level.
BONUS
Will force the affected mob to drop small items!
//////////////////////////////////////
*/
/datum/symptom/cough
name = "Cough"
stealth = -1
resistance = 3
stage_speed = 1
transmittable = 2
level = 1
severity = 1
/datum/symptom/cough/Activate(var/datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3)
to_chat(M, span_warning(pick("You swallow excess mucus", "You lightly cough.")))
else
M.emote("cough")
var/obj/item/I = M.get_active_hand()
if(I && I.w_class == ITEMSIZE_SMALL)
M.drop_item()
return
@@ -0,0 +1,59 @@
/*
//////////////////////////////////////
Damage Converter
Little bit hidden.
Lowers resistance tremendously.
Decreases stage speed tremendously.
Reduced transmittablity
Intense Level.
Bonus
Slowly converts brute/fire damage to toxin.
//////////////////////////////////////
*/
/datum/symptom/damage_converter
name = "Toxic Compensation"
stealth = 1
resistance = -4
stage_speed = -4
transmittable = -2
level = 4
/datum/symptom/damage_converter/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 10))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
Convert(M)
return
/datum/symptom/damage_converter/proc/Convert(mob/living/M)
var/get_damage = rand(1, 2)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/list/parts = H.get_damaged_organs(TRUE, TRUE)
if(!length(parts))
return
var/healed = 0
for(var/obj/item/organ/external/E in parts)
healed += min(E.brute_dam, get_damage) + min(E.burn_dam, get_damage)
E.heal_damage(get_damage, get_damage, 0, 0)
M.adjustToxLoss(healed)
else
if(M.getFireLoss() > 0 || M.getBruteLoss() > 0)
M.adjustFireLoss(-get_damage)
M.adjustBruteLoss(-get_damage)
M.adjustToxLoss(get_damage)
else
return
return TRUE
@@ -0,0 +1,38 @@
/*
//////////////////////////////////////
Dizziness
Hidden.
Lowers resistance considerably.
Decreases stage speed.
Reduced transmittability
Intense Level.
Bonus
Shakes the affected mob's screen for short periods.
//////////////////////////////////////
*/
/// Not the egg
/datum/symptom/dizzy
name = "Dizziness"
stealth = 2
resistance = -2
stage_speed = -3
transmittable = -1
level = 4
severity = 2
/datum/symptom/dizzy/Activate(var/datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
to_chat(M, span_warning(pick("You feel dizzy.", "Your head spins.")))
else
to_chat(M, span_userdanger("A wave of dizziness washes over you!"))
M.make_dizzy(10)
return
@@ -0,0 +1,40 @@
/*
//////////////////////////////////////
Fever
No change to hidden.
Increases resistance.
Increases stage speed.
Little transmittable.
Low level.
Bonus
Heats up your body.
//////////////////////////////////////
*/
/datum/symptom/fever
name = "Fever"
stealth = 0
resistance = 3
stage_speed = 3
transmittable = 2
level = 2
severity = 2
/datum/symptom/fever/Activate(var/datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/M = A.affected_mob
to_chat(M, span_warning(pick("You feel hot.", "You feel like you're burning.")))
if(M.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT)
Heat(M, A)
return
/datum/symptom/fever/proc/Heat(var/mob/living/M, var/datum/disease/advance/A)
var/get_heat = (sqrt(21+A.totalTransmittable()*2))+(sqrt(20+A.totalStageSpeed()*3))
M.bodytemperature = min(M.bodytemperature + (get_heat * A.stage), BODYTEMP_HEAT_DAMAGE_LIMIT - 1)
return TRUE
@@ -0,0 +1,56 @@
/*
//////////////////////////////////////
Spontaneous Combustion
Slightly hidden.
Lowers resistance tremendously.
Decreases stage tremendously.
Decreases transmittablity tremendously.
Fatal Level.
Bonus
Ignites infected mob.
//////////////////////////////////////
*/
/datum/symptom/fire
name = "Spontaneous Combustion"
stealth = 1
resistance = -4
stage_speed = -4
transmittable = -4
level = 6
severity = 5
/datum/symptom/fire/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(3)
to_chat(M, span_warning(pick("You feel hot.", "You hear a crackling noise.", "You smell smoke.")))
if(4)
Firestacks_stage_4(M, A)
M.IgniteMob()
to_chat(M, span_userdanger("Your skin bursts into flames!"))
M.emote("scream")
if(5)
Firestacks_stage_5(M, A)
M.IgniteMob()
to_chat(M, span_userdanger("Your skin erupts into an inferno!"))
M.emote("scream")
return
/datum/symptom/fire/proc/Firestacks_stage_4(mob/living/M, datum/disease/advance/A)
var/get_stacks = max((sqrtor0(20 + A.totalStageSpeed() * 2)) - (sqrtor0(16 + A.totalStealth())), 1)
M.adjust_fire_stacks(get_stacks)
M.adjustFireLoss(get_stacks * 0.5)
return 1
/datum/symptom/fire/proc/Firestacks_stage_5(mob/living/M, datum/disease/advance/A)
var/get_stacks = max((sqrtor0(20 + A.totalStageSpeed() * 3))-(sqrtor0(16 + A.totalStealth())), 1)
M.adjust_fire_stacks(get_stacks)
M.adjustFireLoss(get_stacks)
return 1
@@ -0,0 +1,42 @@
/*
//////////////////////////////////////
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"
stealth = -3
resistance = -4
stage_speed = 0
transmittable = -4
level = 6
severity = 5
/datum/symptom/flesh_eating/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2,3)
to_chat(M, span_warning(pick("You feel a sudden pain across your body.", "Drops of blood appear suddenly on your skin.")))
if(4,5)
to_chat(M, span_userdanger(pick("You cringe as a violent pain takes over your body.", "It feels like your body is eating itself inside out.", "IT HURTS.")))
Flesheat(M, A)
return
/datum/symptom/flesh_eating/proc/Flesheat(mob/living/M, datum/disease/advance/A)
var/get_damage = ((sqrt(16-A.totalStealth()))*5)
M.adjustBruteLoss(get_damage)
return 1
@@ -0,0 +1,40 @@
/*
//////////////////////////////////////
Hallucigen
Very noticable.
Lowers resistance considerably.
Decreases stage speed.
Reduced transmittable.
Critical Level.
Bonus
Makes the affected mob be hallucinated for short periods of time.
//////////////////////////////////////
*/
/datum/symptom/hallucigen
name = "Hallucigen"
stealth = -2
resistance = -3
stage_speed = -3
transmittable = -1
level = 5
severity = 3
/datum/symptom/hallucigen/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/M = A.affected_mob
switch(A.stage)
if(1, 2)
to_chat(M, span_warning(pick("Something appears in your peripheral vision, then winks out.", "You hear a faint whisper with no source.", "Your head aches.")))
if(3, 4)
to_chat(M, span_boldwarning(pick("Something is following you.", "You are being watched.", "You hear a whisper in your ear.", "Thumping footsteps slam toward you from nowhere.")))
else
to_chat(M, span_userdanger(pick("Oh, your head...", "Your head pounds.", "They're everywhere! Run!", "Something in the shadows...")))
M.hallucination = rand(5, 10)
return
@@ -0,0 +1,33 @@
/*
//////////////////////////////////////
Headache
Noticable.
Highly resistant.
Increases stage speed.
Not transmittable.
Low Level.
BONUS
Displays an annoying message!
Should be used for buffing your disease.
//////////////////////////////////////
*/
/datum/symptom/headache
name = "Headache"
stealth = -1
resistance = 4
stage_speed = 2
transmittable = 0
level = 1
severity = 1
/datum/symptom/headache/Activate(var/datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
to_chat(M, span_warning(pick("Your head hurts.", "Your head starts pounding.")))
return
@@ -0,0 +1,150 @@
/*
//////////////////////////////////////
Healing
Little bit hidden.
Lowers resistance tremendously.
Decreases stage speed tremendously.
Decreases transmittablity temrendously.
Fatal Level.
Bonus
Heals toxins in the affected mob's blood stream.
//////////////////////////////////////
*/
/datum/symptom/heal
name = "Toxic Filter"
stealth = 1
resistance = -4
stage_speed = -4
transmittable = -4
level = 6
/datum/symptom/heal/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 10))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
Heal(M, A)
return
/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A)
var/get_damage = (sqrt(20+A.totalStageSpeed())*(1+rand()))
M.adjustToxLoss(-get_damage)
return TRUE
/*
//////////////////////////////////////
Metabolism
Little bit hidden.
Lowers resistance.
Decreases stage speed.
Decreases transmittablity temrendously.
High Level.
Bonus
Cures all diseases (except itself) and creates anti-bodies for them until the symptom dies.
//////////////////////////////////////
*/
/datum/symptom/heal/metabolism
name = "Anti-Bodies Metabolism"
stealth = -1
resistance = -1
stage_speed = -1
transmittable = -4
level = 3
var/list/cured_diseases = list()
/datum/symptom/heal/metabolism/Heal(mob/living/M, datum/disease/advance/A)
var/cured = 0
for(var/thing in M.GetViruses())
var/datum/disease/D = thing
if(D.virus_heal_resistant)
continue
if(D != A)
cured = TRUE
cured_diseases += D.GetDiseaseID()
D.cure()
if(cured)
to_chat(M, span_notice("You feel much better."))
/datum/symptom/heal/metabolism/End(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
if(istype(M))
if(length(cured_diseases))
for(var/res in M.GetResistances())
M.resistances -= res
to_chat(M, span_warning("You feel weaker."))
/*
//////////////////////////////////////
Longevity
Medium hidden boost.
Large resistance boost.
Large stage speed boost.
Large transmittablity boost.
High Level.
Bonus
After a certain amount of time the symptom will cure itself.
//////////////////////////////////////
*/
/datum/symptom/heal/longevity
name = "Longevity"
stealth = 3
resistance = 4
stage_speed = 4
transmittable = 4
level = 3
var/longevity = 30
/datum/symptom/heal/longevity/Heal(mob/living/M, datum/disease/advance/A)
longevity -= 1
if(!longevity)
A.cure()
/datum/symptom/heal/longevity/Start(datum/disease/advance/A)
longevity = rand(initial(longevity) - 5, initial(longevity) + 5)
/*
//////////////////////////////////////
DNA Restoration
Not well hidden.
Lowers resistance minorly.
Does not affect stage speed.
Decreases transmittablity greatly.
Very high level.
Bonus
Heals brain damage, treats radiation.
//////////////////////////////////////
*/
/datum/symptom/heal/dna
name = "Deoxyribonucleic Acid Restoration"
stealth = -1
resistance = -1
stage_speed = 0
transmittable = -3
level = 5
/datum/symptom/heal/dna/Heal(var/mob/living/carbon/M, var/datum/disease/advance/A)
var/amt_healed = (sqrt(20+A.totalStageSpeed()*(3+rand())))-(sqrt(16+A.totalStealth()*rand()))
M.adjustBrainLoss(-amt_healed)
M.radiation = max(M.radiation - 3, 0)
return TRUE
@@ -0,0 +1,33 @@
/*
//////////////////////////////////////
Itching
Not noticable or unnoticable.
Resistant.
Increases stage speed.
Little transmittable.
Low Level.
BONUS
Displays an annoying message!
Should be used for buffing your disease.
//////////////////////////////////////
*/
/datum/symptom/itching
name = "Itching"
stealth = 0
resistance = 3
stage_speed = 3
transmittable = 1
level = 1
severity = 1
/datum/symptom/itching/Activate(var/datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
to_chat(M, span_warning("Your [pick("back", "arm", "leg", "elbow", "head")] itches."))
return
@@ -0,0 +1,31 @@
/*
//////////////////////////////////////
Lingual Disocation
Improves stealth.
Increases resistance.
Decreases stage speed.
Slightly decreases transmissibility.
Moderate Level.
Bonus
Forces the affected mob to vomit
//////////////////////////////////////
*/
/datum/symptom/language
name = "Lingual Disocation"
stealth = 3
resistance = 2
stage_speed = -2
transmittable = -1
level = 3
/datum/symptom/language/Activate(var/datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/human/H = A.affected_mob
H.apply_default_language(pick(H.languages))
return
@@ -0,0 +1,73 @@
/*
//////////////////////////////////////
Macrophages
Very noticeable.
Lowers resistance slightly.
Decreases stage speed.
Increases transmittablity
Fatal leve.
BONUS
The virus grows and ceases to be microscopic.
//////////////////////////////////////
*/
/datum/symptom/macrophage
name = "Macrophage"
stealth = -4
resistance = -1
stage_speed = -2
transmittable = 2
level = 6
severity = 2
var/gigagerms = FALSE
var/netspeed = 0
var/phagecounter = 10
/datum/symptom/macrophage/Start(datum/disease/advance/A)
netspeed = max(1, A.stage)
if(A.severity >= HARMFUL)
gigagerms = TRUE
/datum/symptom/macrophage/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3)
to_chat(M, span_notice("Your skin crawls."))
if(4)
M.visible_message(span_danger("Lumps form on [M]'s skin!"), span_userdanger("You cringe in pain as lumps form and move around on your skin!"))
if(5)
phagecounter -= max(2, A.totalStageSpeed())
if(gigagerms && phagecounter <= 0)
Burst(A, M, TRUE)
phagecounter += 10
while(phagecounter <= 0)
phagecounter += 5
Burst(A, M)
/datum/symptom/macrophage/proc/Burst(datum/disease/advance/A, var/mob/living/M, var/gigagerms = FALSE)
var/mob/living/simple_mob/vore/aggressive/macrophage/phage
phage = new(M.loc)
M.apply_damage(rand(1, 7))
phage.viruses = A.Copy()
phage.health += A.totalResistance()
phage.maxHealth += A.totalResistance()
phage.infections += A
phage.base_disease = A
if(A.spread_flags & CONTACT_GENERAL)
for(var/datum/disease/D in M.GetViruses())
if((D.spread_flags & SPECIAL) || (D.spread_flags & NON_CONTAGIOUS))
continue
if(D == A)
continue
phage.viruses += D
M.visible_message(span_danger("A strange crearure bursts out of [M]!"), span_userdanger("A slimy creature bursts forth from your flesh!"))
addtimer(CALLBACK(phage, TYPE_PROC_REF(/mob/living/simple_mob/vore/aggressive/macrophage, dust)), 3000)
@@ -0,0 +1,33 @@
/*
//////////////////////////////////////
Mlemingtong
Not noticable or unnoticable.
Resistant.
Increases stage speed.
Little transmittable.
Low Level.
BONUS
Mlem. Mlem. Mlem.
Should be used for buffing your disease.
//////////////////////////////////////
*/
/datum/symptom/mlem
name = "Mlemington"
stealth = 0
resistance = 3
stage_speed = 3
transmittable = 1
level = 1
severity = 1
/datum/symptom/itching/Activate(var/datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
M.emote("mlem")
return
@@ -0,0 +1,31 @@
/*
//////////////////////////////////////
Necrotic Agent
Very Noticable.
Lowers resistance resistance considerably.
Decreases stage speed.
Reduced transmittable.
Critical Level.
Bonus
Makes the disease work on corpses
//////////////////////////////////////
*/
/datum/symptom/necrotic_agent
name = "Necrotic Agent"
stealth = -2
resistance = -3
stage_speed = -3
transmittable = 0
level = 6
severity = 3
/datum/symptom/necrotic_agent/Start(datum/disease/advance/A)
A.allow_dead = TRUE
/datum/symptom/necrotic_agent/End(datum/disease/advance/A)
A.allow_dead = FALSE
@@ -0,0 +1,37 @@
/*
//////////////////////////////////////
Self-Respiration
Slightly hidden.
Lowers resistance significantly.
Decreases stage speed significantly.
Decreases transmittablity tremendously.
Fatal Level.
Bonus
The body generates dexalin.
//////////////////////////////////////
*/
/datum/symptom/oxygen
name = "Self-Respiration"
stealth = 1
resistance = -3
stage_speed = -3
transmittable = -4
level = 6
/datum/symptom/oxygen/Activate(var/datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
if(M.reagents.get_reagent_amount("dexalin") < 10)
M.reagents.add_reagent("dexalin", 10)
else
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
to_chat(M, span_notice(pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")))
return
@@ -0,0 +1,63 @@
/*
//////////////////////////////////////
Sensory-Restoration
Very very very very noticable.
Lowers resistance tremendously.
Decreases stage speed tremendously.
Decreases transmittablity tremendously.
Fatal.
Bonus
The body generates Sensory restorational chemicals.
imidazoline for eyes
removes alcohol
removes hallucinogens
alkysine to kickstart the mind
//////////////////////////////////////
*/
/datum/symptom/mind_restoration
name = "Mind Restoration"
stealth = -3
resistance = -4
stage_speed = -4
transmittable = -3
level = 5
severity = 0
/datum/symptom/mind_restoration/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 3))
var/mob/living/M = A.affected_mob
if(A.stage >= 3)
M.slurring = min(0, M.slurring-4)
M.druggy = min(0, M.druggy-4)
M.reagents.remove_reagent("ethanol", 3)
if(A.stage >= 4)
M.drowsyness = min(0, M.drowsyness-4)
if(M.reagents.has_reagent("bliss"))
M.reagents.del_reagent("bliss")
M.hallucination = min(0, M.hallucination-4)
if(A.stage >= 5)
if(M.reagents.get_reagent_amount("alkysine") < 10)
M.reagents.add_reagent("alkysine", 5)
/datum/symptom/sensory_restoration
name = "Sensory Restoration"
stealth = -1
resistance = -3
stage_speed = -2
transmittable = -4
level = 4
/datum/symptom/sensory_restoration/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
if(M.reagents.get_reagent_amount("imidazoline") < 10)
M.reagents.add_reagent("imidazoline", 5)
else
if(prob(SYMPTOM_ACTIVATION_PROB))
to_chat(M, span_notice(pick("Your eyes feel great.","You feel like your eyes can focus more clearly.", "You don't feel the need to blink.")))
@@ -0,0 +1,39 @@
/*
//////////////////////////////////////
Shivering
No change to hidden.
Increases resistance.
Increases stage speed.
Little transmittable.
Low level.
Bonus
Cools down your body.
//////////////////////////////////////
*/
/datum/symptom/shivering
name = "Shivering"
stealth = 0
resistance = 2
stage_speed = 2
transmittable = 2
level = 2
severity = 2
/datum/symptom/shivering/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/M = A.affected_mob
to_chat(M, span_warning(pick("You feel cold.", "You start shivering.")))
if(M.bodytemperature > BODYTEMP_COLD_DAMAGE_LIMIT)
Chill(M, A)
return
/datum/symptom/shivering/proc/Chill(mob/living/M, datum/disease/advance/A)
var/get_cold = (sqrt(16+A.totalStealth()*2))+(sqrt(21+A.totalResistance()*2))
M.bodytemperature = max(M.bodytemperature - (get_cold * A.stage), BODYTEMP_COLD_DAMAGE_LIMIT + 1)
return 1
@@ -0,0 +1,42 @@
/*
//////////////////////////////////////
Sneezing
Very Noticable.
Increases resistance.
Doesn't increase stage speed.
Very transmittable.
Low Level.
Bonus
Forces a spread type of AIRBORNE
with extra range!
//////////////////////////////////////
*/
/datum/symptom/sneeze
name = "Sneezing"
stealth = -2
resistance = 3
stage_speed = 0
transmittable = 4
level = 1
severity = 1
/datum/symptom/sneeze/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3)
M.emote("sniff")
else
M.emote("sneeze")
A.spread(5)
if(prob(30))
var/obj/effect/decal/cleanable/mucus/icky = new(get_turf(M))
icky.viruses |= A.Copy()
return
@@ -0,0 +1,40 @@
/*
//////////////////////////////////////
Spyndrome
Slightly hidden.
No change to resistance.
Increases stage speed.
Little transmittable.
Low Level.
BONUS
Makes the host spin.
Should be used for buffing your disease.
//////////////////////////////////////
*/
/datum/symptom/mlem
name = "Spyndrome"
stealth = 2
resistance = 0
stage_speed = 3
transmittable = 1
level = 1
severity = 1
var/list/directions = list(2,4,1,8,2,4,1,8,2,4,1,8,2,4,1,8,2,4,1,8)
/datum/symptom/mlem/Activate(var/datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
if(A.affected_mob.buckled())
to_chat(viewers(A.affected_mob), span_warning("[A.affected_mob.name] struggles violently against their restraints!"))
else
to_chat(viewers(A.affected_mob), span_warning("[A.affected_mob.name] spins around violently!"))
for(var/D in directions)
A.affected_mob.dir = D
A.affected_mob.dir = pick(2,4,1,8)
return
@@ -0,0 +1,36 @@
// Symptoms are the effects that engineered advanced diseases do.
GLOBAL_LIST_INIT(list_symptoms, subtypesof(/datum/symptom))
/datum/symptom
// Buffs/Debuffs the symptom has to the overall engineered disease.
var/name = ""
var/stealth = 0
var/resistance = 0
var/stage_speed = 0
var/transmittable = 0
// The type level of the symptom. Higher is harder to generate.
var/level = 0
// The severity level of the symptom. Higher is more dangerous.
var/severity = 0
// The hash tag for our diseases, we will add it up with our other symptoms to get a unique id! ID MUST BE UNIQUE!!!
var/id = ""
/datum/symptom/New()
var/list/S = GLOB.list_symptoms
for(var/i = 1; i <= length(S); i++)
if(type == S[i])
id = "[i]"
return
CRASH("We couldn't assign an ID!")
// Called when processing of the advance disease, which holds this symptom, starts.
/datum/symptom/proc/Start(datum/disease/advance/A)
return
// Called when the advance disease is going to be deleted or when the advance disease stops processing.
/datum/symptom/proc/End(datum/disease/advance/A)
return
/datum/symptom/proc/Activate(datum/disease/advance/A)
return
@@ -0,0 +1,32 @@
/*
//////////////////////////////////////
Sneezing
Slightly hidden.
Increases resistance.
Doesn't increase stage speed.
Slightly transmittable.
High Level.
Bonus
Allows the disease to infect synthetics
//////////////////////////////////////
*/
/datum/symptom/infect_synthetics
name = "Synthetic Infection"
stealth = 1
resistance = 2
stage_speed = 0
transmittable = 1
level = 5
severity = 3
id = "synthetic_infection"
/datum/symptom/infect_synthetics/Start(datum/disease/advance/A)
A.infect_synthetics = TRUE
/datum/symptom/infect_synthetics/End(datum/disease/advance/A)
A.infect_synthetics = FALSE
@@ -0,0 +1,36 @@
/*
//////////////////////////////////////
Telepathy
Hidden.
Decreases resistance.
Decreases stage speed significantly.
Decreases transmittablity tremendously.
Critical Level.
Bonus
The user gains telepathy.
//////////////////////////////////////
*/
/datum/symptom/telepathy
name = "Pineal Gland Decalcification"
stealth = 2
resistance = -2
stage_speed = -3
transmittable = -4
level = 5
/datum/symptom/telepathy/Start(datum/disease/advance/A)
var/mob/living/carbon/human/H = A.affected_mob
H.dna.SetSEState(REMOTETALKBLOCK, 1)
domutcheck(H, null, TRUE)
to_chat(H, span_notice("Your mind expands..."))
/datum/symptom/telepathy/End(datum/disease/advance/A)
var/mob/living/carbon/human/H = A.affected_mob
H.dna.SetSEState(REMOTETALKBLOCK, 0)
domutcheck(H, null, TRUE)
to_chat(H, span_notice("Everything feels... Normal."))
@@ -0,0 +1,65 @@
/*
//////////////////////////////////////
Viral adaptation
Moderate stealth boost.
Major Increases to resistance.
Reduces stage speed.
No change to transmission
Critical Level.
BONUS
Extremely useful for buffing viruses
//////////////////////////////////////
*/
/datum/symptom/viraladaptation
name = "Viral self-adaptation"
stealth = 3
resistance = 5
stage_speed = -3
transmittable = 0
level = 3
/datum/symptom/viraladaptation/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1)
to_chat(M, span_notice("You feel off, but no different from before."))
if(5)
to_chat(M, span_notice("You feel better, but nothing interesting happens."))
/*
//////////////////////////////////////
Viral evolution
Moderate stealth reductopn.
Major decreases to resistance.
increases stage speed.
increase to transmission
Critical Level.
BONUS
Extremely useful for buffing viruses
//////////////////////////////////////
*/
/datum/symptom/viralevolution
name = "Viral evolutionary acceleration"
stealth = -2
resistance = -3
stage_speed = 5
transmittable = 3
level = 3
/datum/symptom/viralevolution/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1)
to_chat(M, span_notice("You feel better, but no different from before."))
if(5)
to_chat(M,span_notice("You feel off, but nothing interesting happens."))
@@ -0,0 +1,50 @@
/*
//////////////////////////////////////
Hyphema (Eye bleeding)
Slightly noticable.
Lowers resistance tremendously.
Decreases stage speed tremendously.
Decreases transmittablity.
Critical Level.
Bonus
Causes blindness.
//////////////////////////////////////
*/
/datum/symptom/visionloss
name = "Hyphema"
stealth = -1
resistance = -4
stage_speed = -4
transmittable = -3
level = 5
severity = 4
/datum/symptom/visionloss/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/M = A.affected_mob
var/obj/item/organ/internal/eyes/eyes = M.internal_organs_by_name[O_EYES]
if(!eyes)
return
switch(A.stage)
if(1, 2)
to_chat(M, span_warning("Your eyes itch."))
if(3, 4)
to_chat(M, span_boldwarning("Your eyes burn!"))
M.eye_blurry = 20
eyes.take_damage(1)
else
to_chat(M, span_userdanger("Your eyes burn horrificly!"))
M.eye_blurry = 40
eyes.take_damage(5)
if(eyes.damage >= 10)
M.disabilities |= NEARSIGHTED
if(prob(eyes.damage - 10 + 1))
if(!M.eye_blind)
to_chat(M, span_userdanger("You go blind!"))
M.Blind(20)
@@ -0,0 +1,34 @@
/*
//////////////////////////////////////
Vomiting
Noticeable.
No change to resistance.
Slightly increases stage speed.
Increases transmissibility.
Medium Level.
Bonus
Forces the affected mob to vomit
//////////////////////////////////////
*/
/datum/symptom/vomit
name = "Vomiting"
stealth = -2
resistance = 0
stage_speed = 1
transmittable = 2
level = 3
severity = 1
/datum/symptom/vomit/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
if(prob(2))
to_chat(M, span_warning(pick("you feel nauseated.", "You feel like you're going to throw up!")))
if(prob(SYMPTOM_ACTIVATION_PROB))
M.vomit()
@@ -0,0 +1,43 @@
/*
//////////////////////////////////////
Weakness
Slightly noticeable.
Lowers resistance slightly.
Decreases stage speed moderately.
Decreases transmittablity moderately.
Moderate Level.
Bonus
Weakens the host
//////////////////////////////////////
*/
/datum/symptom/weakness
name = "Weakness"
stealth = -1
resistance = -1
stage_speed = -2
transmittable = -2
level = 3
severity = 3
/datum/symptom/weakness/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2)
to_chat(M, span_warning(pick("You feel weak.", "You feel lazy.")))
if(3, 4)
to_chat(M, span_boldwarning(pick("You feel very frail.", "You think you might faint.")))
M.Weaken(10)
else
to_chat(M, span_userdanger(pick("You feel tremendously weak!", "Your body trembles as exhaustion creeps over you.")))
M.Weaken(20)
if(M.weakened > 60 && !M.stat)
M.visible_message(span_warning("[M] faints!"), span_userdanger("You swoon and faint..."))
M.AdjustSleeping(10)
return
@@ -0,0 +1,37 @@
/*
//////////////////////////////////////
Weight Loss
Very Very Noticable.
Decreases resistance.
Decreases stage speed.
Reduced Transmittable.
High level.
Bonus
Decreases the weight of the mob,
forcing it to be skinny.
//////////////////////////////////////
*/
/datum/symptom/weight_loss
name = "Weight Loss"
stealth = -3
resistance = -2
stage_speed = -2
transmittable = -2
level = 3
severity = 1
/datum/symptom/weight_loss/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
to_chat(M, span_warning(pick("You feel hungry.", "You crave for food.")))
else
to_chat(M, span_warning(pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")))
M.adjust_nutrition(-20)
+53
View File
@@ -0,0 +1,53 @@
/datum/disease/anxiety
name = "Severe Anxiety"
form = "Infection"
max_stages = 4
spread_text = "On contact"
spread_flags = CONTACT_GENERAL
cure_text = "Ethanol"
cures = list("ethanol")
agent = "Excess Lepdopticides"
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/human/monkey)
desc = "If left untreated subject will regurgitate butterflies."
severity = MINOR
/datum/disease/anxiety/stage_act()
if(!..())
return FALSE
switch(stage)
if(2)
if(prob(15))
to_chat(affected_mob, span_notice("You feel anxious."))
if(3)
if(prob(10))
to_chat(affected_mob, span_notice("Your stomach flutters."))
if(prob(5))
to_chat(affected_mob, span_notice("You feel panicky."))
if(prob(2))
to_chat(affected_mob, span_danger("You're overtaken with panic!"))
affected_mob.AdjustConfused(rand(4, 6))
if(4)
if(prob(10))
to_chat(affected_mob, span_danger("You feel butterflies in your stomach."))
if(prob(5))
affected_mob.visible_message(
span_danger("[affected_mob] stumbles around in a panic"),
span_userdanger("You have a panic attack!")
)
affected_mob.AdjustConfused(rand(12, 16))
affected_mob.jitteriness = rand(12, 16)
if(prob(2))
affected_mob.visible_message(
span_danger("[affected_mob] coughs up butterflies!"),
span_userdanger("You cough up butterflies!")
)
affected_mob.emote("cough")
for(var/i in 1 to 2)
var/mob/living/simple_mob/animal/sif/glitterfly/B = new(affected_mob.loc)
addtimer(CALLBACK(B, TYPE_PROC_REF(/mob/living/simple_mob/animal/sif/glitterfly, decompose)), rand(5, 25) SECONDS)
/mob/living/simple_mob/animal/sif/glitterfly/proc/decompose()
visible_message(
span_notice("[src] decomposes due to being outside of its original habitat for too long!"),
span_userdanger("You decompose for being too long out of your habitat!"))
dust()
+36
View File
@@ -0,0 +1,36 @@
/datum/disease/beesease
name = "Beesease"
form = "Infection"
max_stages = 4
spread_text = "On contact"
spread_flags = CONTACT_GENERAL
cure_text = "Sugar"
cures = list("sugar")
agent = "Apidae Infection"
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/human/monkey)
desc = "If left untreated, subject will regurgitate bees."
severity = BIOHAZARD
/datum/disease/beesease/stage_act()
if(!..())
return FALSE
switch(stage)
if(2)
if(prob(2))
to_chat(affected_mob, span_notice("You tastey hone in your mouth."))
if(3)
if(prob(10))
to_chat(affected_mob, span_notice("Your stomach rumbles"))
if(prob(2))
to_chat(affected_mob, span_notice("Your stomach stings painfully."))
if(prob(20))
affected_mob.adjustToxLoss(2)
if(4)
if(prob(10))
affected_mob.visible_message(span_danger("[affected_mob] buzzles loudly"), span_userdanger("Your stomach buzzles violently!"))
if(prob(5))
to_chat(affected_mob, span_danger("You feel something moving in your throat."))
if(prob(1))
affected_mob.visible_message(span_danger("[affected_mob] coughs up a swarm of bees!"), span_userdanger("You cough up a swarm of bees!"))
new /mob/living/simple_mob/vore/bee(affected_mob.loc)
return
+43
View File
@@ -0,0 +1,43 @@
/datum/disease/brainrot
name = "Brainrot"
max_stages = 4
spread_text = "On contact"
spread_flags = CONTACT_GENERAL
cure_text = "Alkysine"
cures = list("alkysine")
agent = "Cryptococcus Cosmosis"
viable_mobtypes = list(/mob/living/carbon/human)
cure_chance = 15
desc = "This disease destroys the braincells, causing brain fever, brain necrosis and general intoxication."
required_organs = list(/obj/item/organ/internal/brain)
severity = HARMFUL
/datum/disease/brainrot/stage_act()
if(!..())
return FALSE
switch(stage)
if(2)
if(prob(2))
affected_mob.say("*blink")
if(prob(2))
affected_mob.say("*yawn")
if(prob(2))
to_chat(affected_mob, span_danger("You don't feel like yourself."))
if(prob(5))
affected_mob.adjustBrainLoss(1)
if(3)
if(prob(2))
affected_mob.say("*stare")
if(prob(3))
affected_mob.say("*drool")
if(prob(10) && affected_mob.getBrainLoss() < 100)
affected_mob.adjustBrainLoss(3)
if(prob(2))
to_chat(affected_mob, span_danger("Strange buzzing fills your head, removing all thoughts."))
if(prob(3))
to_chat(affected_mob, span_danger("You lose consciousness..."))
affected_mob.Sleeping(rand(5, 10))
if(prob(1))
affected_mob.emote("snore")
if(prob(15))
affected_mob.apply_effect(5, STUTTER)
+38
View File
@@ -0,0 +1,38 @@
/datum/disease/choreomania
name = "Choreomania"
max_stages = 3
spread_text = "Airborne"
cure_text = "Adranol"
cures = list("adranol")
cure_chance = 10
agent = "TAP-DAnC3"
viable_mobtypes = list(/mob/living/carbon/human)
permeability_mod = 0.75
desc = "If left untreated the subject... Won't stop dancing!"
severity = MINOR
var/list/dance = list(2,4,8,2,4,8,2,4,8,2,4,8,1,4,1,4,1,4,2,4,8,2)
/datum/disease/choreomania/stage_act()
if(!..())
return FALSE
switch(stage)
if(2)
if(prob(1))
to_chat(affected_mob, span_notice("You feel like dancing like a maniac, maniac..."))
if(prob(1))
affected_mob.emote("whistle")
if(3)
if(prob(1))
to_chat(affected_mob, span_notice("You feel like dancing like a maniac, maniac..."))
if(prob(1))
to_chat(affected_mob, span_notice("You really want to start a conga line!"))
if(prob(2))
for(var/D in dance)
affected_mob.dir = D
animate(affected_mob, pixel_x = 5, time = 5)
sleep(3)
animate(affected_mob, pixel_x = -5, time = 5)
animate(pixel_x = affected_mob.default_pixel_x, pixel_y = affected_mob.default_pixel_x, time = 2)
sleep(3)
return
+64
View File
@@ -0,0 +1,64 @@
/datum/disease/cold
name = "The Cold"
max_stages = 3
spread_text = "Airborne"
spread_flags = AIRBORNE
cure_text = "Rest & Spaceacilin"
cures = list("spaceacilin")
agent = "XY-rhinovirus"
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/human/monkey)
permeability_mod = 0.5
desc = "If left untreated the subject will contract the flu."
severity = MINOR
/datum/disease/cold/stage_act()
if(!..())
return FALSE
switch(stage)
if(2)
if(affected_mob.stat == UNCONSCIOUS && prob(40))
to_chat(affected_mob, span_notice("You feel better."))
cure()
return
if(affected_mob.lying && prob(10))
to_chat(affected_mob, span_notice("You feel better."))
cure()
return
if(prob(1) && prob(5))
to_chat(affected_mob, span_notice("You feel better."))
cure()
return
if(prob(1))
affected_mob.emote("sneeze")
if(prob(1))
affected_mob.emote("cough")
if(prob(1))
to_chat(affected_mob, span_notice("Your throat feels sore."))
if(prob(1))
to_chat(affected_mob, span_notice("Mucous runs down the back of your throat."))
if(3)
if(affected_mob.stat == UNCONSCIOUS && prob(25))
to_chat(affected_mob, span_notice("You feel better."))
cure()
return
if(affected_mob.lying && prob(5))
to_chat(affected_mob, span_notice("You feel better."))
cure()
return
if(prob(1) && prob(1))
to_chat(affected_mob, span_notice("You feel better."))
cure()
return
if(prob(1))
affected_mob.emote("sneeze")
if(prob(1))
affected_mob.emote("cough")
if(prob(1))
to_chat(affected_mob, span_notice("Your throat feels sore."))
if(prob(1))
to_chat(affected_mob, span_notice("Mucous runs down the back of your throat."))
if(prob(1) && prob(50))
if(!affected_mob.resistances.Find(/datum/disease/flu))
var/datum/disease/Flu = new /datum/disease/flu(0)
affected_mob.ContractDisease(Flu)
cure()
+30
View File
@@ -0,0 +1,30 @@
/datum/disease/cold9
name = "The Cold"
medical_name = "ICE9 Cold"
max_stages = 3
spread_text = "On contact"
spread_flags = CONTACT_GENERAL
cure_text = "Spaceacillin"
cures = list("spaceacillin")
agent = "ICE9-rhinovirus"
viable_mobtypes = list(/mob/living/carbon/human)
desc = "If left untreated the subject will slow, as if partly frozen."
severity = HARMFUL
/datum/disease/cold9/stage_act()
if(!..())
return FALSE
if(stage < 2)
return
var/stage_factor = stage - 1
affected_mob.bodytemperature -= 7.5 * stage_factor
if(prob(2 * stage_factor))
affected_mob.say("*sneeze")
if(prob(2 * stage_factor))
affected_mob.say("*cough")
if(prob(3 * stage_factor))
to_chat(affected_mob, span_danger("Your throat feels sore."))
if(prob(5 * stage_factor))
to_chat(affected_mob, span_danger("You feel stiff."))
affected_mob.adjustFireLoss(1)
+10
View File
@@ -0,0 +1,10 @@
/datum/disease/darkness
name = "Dark Exposure"
form = "Bluespace Micro-fissures"
max_stages = 4
spread = NON_CONTAGIOUS
cure_text = "Exposure to light and the real world"
agent = "Bluespace Exposure"
viable_mobtypes = list(/mob/living/carbon/human)
desc = "If left untreated, subject will lose grip on reality."
severity = HARMFUL
+50
View File
@@ -0,0 +1,50 @@
/datum/disease/flu
name = "The Flu"
max_stages = 3
spread_text = "Airborne"
cure_text = "Spaceacilin"
cures = list("spaceacilin")
cure_chance = 10
agent = "H13N1 flu virion"
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/human/monkey)
permeability_mod = 0.75
desc = "If left untreated the subject will feel quite unwell."
severity = MINOR
/datum/disease/flu/stage_act()
if(!..())
return FALSE
switch(stage)
if(2)
if(affected_mob.lying && prob(20))
to_chat(affected_mob, span_notice("You feel better."))
stage--
return
if(prob(1))
affected_mob.emote("sneeze")
if(prob(1))
affected_mob.emote("cough")
if(prob(1))
to_chat(affected_mob, span_danger("Your muscles ache."))
if(prob(20))
affected_mob.apply_damage(1)
if(prob(1))
to_chat(affected_mob, span_danger("Your stomach hurts."))
affected_mob.adjustToxLoss(1)
if(3)
if(affected_mob.lying && prob(15))
to_chat(affected_mob, span_notice("You feel better."))
stage--
return
if(prob(1))
affected_mob.emote("sneeze")
if(prob(1))
affected_mob.emote("cough")
if(prob(1))
to_chat(affected_mob, span_danger("Your muscles ache."))
if(prob(20))
affected_mob.apply_damage(1)
if(prob(1))
to_chat(affected_mob, span_danger("Your stomach hurts."))
affected_mob.adjustToxLoss(1)
return
+67
View File
@@ -0,0 +1,67 @@
/datum/disease/food_poisoning
name = "Food Poisoning"
max_stages = 3
stage_prob = 5
spread_text = "Non-Contagious"
spread_flags = NON_CONTAGIOUS
cure_text = "Sleep"
agent = "Salmonella"
cures = list("chicken_soup")
cure_chance = 10
viable_mobtypes = list(/mob/living/carbon/human)
desc = "Nausea, sickness, and vomitting."
severity = MINOR
disease_flags = CURABLE
virus_heal_resistant = TRUE
/datum/disease/food_poisoning/stage_act()
if(!..())
return FALSE
if(affected_mob.stat == UNCONSCIOUS && prob(33))
to_chat(affected_mob, span_notice("You feel better."))
cure()
return
switch(stage)
if(1)
if(prob(5))
to_chat(affected_mob, span_danger("Your stomach feels weird."))
if(prob(5))
to_chat(affected_mob, span_danger("You feel queasy."))
if(2)
if(affected_mob.stat == UNCONSCIOUS && prob(40))
to_chat(affected_mob, span_notice("You feel better."))
cure()
return
if(prob(1) && prob(10))
to_chat(affected_mob, span_notice("You feel better."))
if(prob(10))
affected_mob.emote("groan")
if(prob(5))
to_chat(affected_mob, span_danger("Your stomach aches."))
if(prob(5))
to_chat(affected_mob, span_danger("You feel nauseous"))
if(3)
if(affected_mob.stat == UNCONSCIOUS && prob(25))
to_chat(affected_mob, span_notice("You feel better."))
cure()
return
if(prob(1) && prob(10))
to_chat(affected_mob, span_notice("You feel better."))
cure()
return
if(prob(10))
affected_mob.emote("moan")
if(prob(10))
affected_mob.emote("groan")
if(prob(1))
to_chat(affected_mob, span_danger("Your stomach hurts."))
if(prob(1))
to_chat(affected_mob, span_danger("You feel sick."))
if(prob(5))
if(affected_mob.nutrition > 10)
affected_mob.emote("vomit")
else
to_chat(affected_mob, span_danger("Your stomach lurches painfully"))
affected_mob.visible_message(span_danger("[affected_mob] gags and retches!"))
affected_mob.Stun(rand(4, 8))
affected_mob.Weaken(rand(4, 8))
+64
View File
@@ -0,0 +1,64 @@
/datum/disease/lycan
name = "Lycancoughy"
form = "Infection"
max_stages = 4
spread_text = "On contact"
spread_flags = CONTACT_GENERAL
cure_text = "Ethanol"
cures = list("ethanol")
agent = "Excess Snuggles"
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/human/monkey)
desc = "If left untreated subject will regurgitate... puppies."
severity = HARMFUL
var/barklimit
var/list/puppy_types = list(/mob/living/simple_mob/animal/passive/dog/corgi/puppy)
var/list/plush_types = list(/obj/item/toy/plushie/orange_fox, /obj/item/toy/plushie/corgi, /obj/item/toy/plushie/robo_corgi, /obj/item/toy/plushie/pink_fox)
/datum/disease/lycan/stage_act()
if(!..())
return FALSE
var/mob/living/carbon/human/H = affected_mob
switch(stage)
if(2)
if(prob(2))
H.emote("cough")
if(prob(3))
to_chat(H, span_notice("You itch."))
H.adjustBruteLoss(rand(4, 6))
if(3)
var/obj/item/organ/external/stomach = H.organs_by_name[pick("torso", "groin")]
if(prob(3))
H.emote("cough")
stomach.take_damage(BRUTE, rand(0, 5))
if(prob(3))
to_chat(H, span_notice("You hear a faint barking."))
stomach.take_damage(BRUTE, rand(4, 6))
if(prob(2))
to_chat(H, span_notice("You crave meat."))
if(prob(3))
to_chat(H, span_danger("Your stomach growls!"))
stomach.take_damage(BRUTE, rand(5, 10))
if(4)
var/obj/item/organ/external/stomach = H.organs_by_name[pick("torso", "groin")]
if(prob(5))
H.emote("cough")
stomach.take_damage(BRUTE, rand(0, 5))
if(prob(5))
H.emote("awoo2")
H.Confuse(rand(12, 16))
stomach.take_damage(rand(0, 5))
if(prob(5))
if(!barklimit)
to_chat(H, span_danger("Your stomach growls!"))
stomach.take_damage(BRUTE, rand(5, 10))
else
var/atom/hairball = pick(prob(50) ? puppy_types : plush_types)
H.visible_message(span_danger("[H] coughs up \a [initial(hairball.name)]!"), span_userdanger("You cough up \a [initial(hairball.name)]?!"))
H.emote("cough")
new hairball(H.loc)
barklimit--
stomach.take_damage(BRUTE, rand(10, 15))
+63
View File
@@ -0,0 +1,63 @@
/datum/disease/magnitis
name = "Magnitis"
max_stages = 4
spread_text = "Airbone"
cure_text = "Iron"
cures = list("iron")
agent = "Fukkos Miracos"
viable_mobtypes = list(/mob/living/carbon/human)
permeability_mod = 0.75
desc = "This disease disrupts the magnetic field of your body, making it act as if a powerful magnet. Injections of iron help stabilize the field."
severity = MINOR
/datum/disease/magnitis/stage_act()
if(!..())
return FALSE
switch(stage)
if(2)
if(prob(2))
to_chat(affected_mob, span_danger("You feel a slight shock course through your body."))
if(prob(2))
for(var/obj/M in orange(2, affected_mob))
if(!M.anchored && prob(5))
INVOKE_ASYNC(M, TYPE_PROC_REF(/atom/movable, throw_at), affected_mob, rand(3, 10), rand(1, 3), src)
for(var/mob/living/silicon/S in orange(2, affected_mob))
if(isAI(S)) continue
INVOKE_ASYNC(S, TYPE_PROC_REF(/atom/movable, throw_at), affected_mob, rand(3, 10), rand(1, 3), src)
if(3)
if(prob(2))
to_chat(affected_mob, span_danger("You feel a strong shock course through your body."))
if(prob(2))
to_chat(affected_mob, span_danger("You feel like clowning aound."))
if(prob(4))
for(var/obj/M in orange(4, affected_mob))
if(!M.anchored && prob(5))
var/i
var/iter = rand(1,2)
for(i=0,i<iter,i++)
INVOKE_ASYNC(M, TYPE_PROC_REF(/atom/movable, throw_at), affected_mob, rand(3, 10), rand(1, 3), src)
for(var/mob/living/silicon/S in orange(4, affected_mob))
if(isAI(S)) continue
var/i
var/iter = rand(1,2)
for(i=0,i<iter,i++)
INVOKE_ASYNC(S, TYPE_PROC_REF(/atom/movable, throw_at), affected_mob, rand(3, 10), rand(1, 3), src)
if(4)
if(prob(2))
to_chat(affected_mob, span_danger("You feel a powerful shock course through your body."))
if(prob(2))
to_chat(affected_mob, span_danger("You query upon the nature of miracles"))
if(prob(8))
for(var/obj/M in orange(6, affected_mob))
if(!M.anchored && prob(5))
var/i
var/iter = rand(1,3)
for(i=0,i<iter,i++)
INVOKE_ASYNC(M, TYPE_PROC_REF(/atom/movable, throw_at), affected_mob, rand(3, 10), rand(1, 3), src)
for(var/mob/living/silicon/S in orange(6, affected_mob))
if(isAI(S)) continue
var/i
var/iter = rand(1,3)
for(i=0,i<iter,i++)
INVOKE_ASYNC(S, TYPE_PROC_REF(/atom/movable, throw_at), affected_mob, rand(3, 10), rand(1, 3), src)
return
+90
View File
@@ -0,0 +1,90 @@
/datum/disease/roanoake
name = "Roanoake Syndrome"
max_stages = 6
stage_prob = 2
spread_text = "Blood and close contact"
spread_flags = BLOOD
cure_text = "Spaceacilin"
agent = "Chimera cells"
cures = list("spaceacilin")
cure_chance = 10
viable_mobtypes = list(/mob/living/carbon/human)
desc = "If left untreated, subject will become a xenochimera upon perishing."
severity = BIOHAZARD
disease_flags = CURABLE
virus_heal_resistant = TRUE
allow_dead = TRUE
var/list/obj/item/organ/organ_list = list()
var/obj/item/organ/O
/datum/disease/roanoake/Start
var/mob/living/carbon/human/M = affected_mob
organ_list += M.organs
organ_list += M.internal_organs
/datum/disease/roanoake/stage_act()
if(!..())
return FALSE
var/mob/living/carbon/human/M = affected_mob
switch(stage)
if(2)
if(prob(1))
to_chat(M, span_notice("You feel a slight shiver through your spine..."))
if(prob(1))
to_chat(M, span_warning(pick("You feel hot.", "You feel like you're burning.")))
if(M.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT)
if(3)
if(prob(1))
to_chat(M, span_notice("You shiver a bit."))
if(prob(1))
to_chat(M, span_warning(pick("You feel hot.", "You feel like you're burning.")))
if(M.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT)
fever(M)
if(prob(1))
O = pick(organ_list)
O.adjust_germ_level(rand(5, 10))
if(4)
if(prob(1))
to_chat(M, span_warning(pick("You feel hot.", "You feel like you're burning.")))
if(M.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT)
fever(M)
if(prob(2))
O = pick(organ_list)
O.adjust_germ_level(rand(5, 10))
if(5)
if(prob(1))
to_chat(M, span_warning(pick("You feel hot.", "You feel like you're burning.")))
if(M.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT)
fever(M)
if(prob(2))
O = pick(organ_list)
O.adjust_germ_level(rand(5, 10))
if(prob(1))
O.take_damage(rand(1, 3))
if(6)
if(prob(1))
to_chat(M, span_warning(pick("You feel hot.", "You feel like you're burning.")))
if(M.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT)
fever(M)
if(prob(2))
O = pick(organ_list)
O.adjust_germ_level(rand(5, 10))
if(prob(2))
O.take_damage(rand(1, 3))
if(prob(1) && prob(10))
var/datum/wound/W = new /datum/wound/internal_bleeding(5)
O.wounds += W
if(M.stat == DEAD)
M.species = /datum/species/xenochimera
cure()
return
/datum/disease/roanoake/proc/fever(var/mob/living/M, var/datum/disease/D)
M.bodytemperature = min(M.bodytemperature + (2 * stage), BODYTEMP_HEAT_DAMAGE_LIMIT - 1)
return TRUE
+1 -1
View File
@@ -51,7 +51,7 @@
. += "<a href=\"[CONFIG_GET(string/githuburl)]/pull/[tm.number]\">#[tm.number][details]</a>"
/client/verb/showrevinfo()
set category = "OOC"
set category = "OOC.Game"
set name = "Show Server Revision"
set desc = "Check the current server code revision"
@@ -2,7 +2,7 @@
var/datum/managed_browser/feedback_viewer/feedback_viewer = null
/datum/admins/proc/view_feedback()
set category = "Admin"
set category = "Admin.Misc"
set name = "View Feedback"
set desc = "Open the Feedback Viewer"
+1 -1
View File
@@ -4,7 +4,7 @@
// Mutable appearances are children of images, just so you know.
/image/mutable_appearance/New(copy_from, ...)
/mutable_appearance/New(copy_from, ...)
..()
if(!copy_from)
plane = FLOAT_PLANE // No clue why this is 0 by default yet images are on FLOAT_PLANE
+12 -3
View File
@@ -1,17 +1,23 @@
/decl/hierarchy/outfit/job/cargo
l_ear = /obj/item/radio/headset/headset_cargo
hierarchy_type = /decl/hierarchy/outfit/job/cargo
headset = /obj/item/radio/headset/cargo
headset_alt = /obj/item/radio/headset/alt/cargo
headset_earbud = /obj/item/radio/headset/earbud/cargo
/decl/hierarchy/outfit/job/cargo/qm
name = OUTFIT_JOB_NAME("Cargo")
uniform = /obj/item/clothing/under/rank/cargo
l_ear = /obj/item/radio/headset/headset_qm //VOREStation Add
shoes = /obj/item/clothing/shoes/brown
glasses = /obj/item/clothing/glasses/sunglasses
l_hand = /obj/item/clipboard
id_type = /obj/item/card/id/cargo/head
pda_type = /obj/item/pda/quartermaster
headset = /obj/item/radio/headset/qm
headset_alt = /obj/item/radio/headset/alt/qm
headset_earbud = /obj/item/radio/headset/earbud/qm
/decl/hierarchy/outfit/job/cargo/cargo_tech
name = OUTFIT_JOB_NAME("Cargo technician")
uniform = /obj/item/clothing/under/rank/cargotech
@@ -21,10 +27,13 @@
/decl/hierarchy/outfit/job/cargo/mining
name = OUTFIT_JOB_NAME("Shaft miner")
uniform = /obj/item/clothing/under/rank/miner
l_ear = /obj/item/radio/headset/headset_mine
backpack = /obj/item/storage/backpack/industrial
satchel_one = /obj/item/storage/backpack/satchel/eng
id_type = /obj/item/card/id/cargo/miner
pda_type = /obj/item/pda/shaftminer
backpack_contents = list(/obj/item/tool/crowbar = 1, /obj/item/storage/bag/ore = 1)
flags = OUTFIT_HAS_BACKPACK|OUTFIT_EXTENDED_SURVIVAL
headset = /obj/item/radio/headset/miner
headset_alt = /obj/item/radio/headset/miner
headset_earbud = /obj/item/radio/headset/miner
+12 -3
View File
@@ -19,9 +19,12 @@
uniform = /obj/item/clothing/under/color/white
/decl/hierarchy/outfit/job/service
l_ear = /obj/item/radio/headset/headset_service
hierarchy_type = /decl/hierarchy/outfit/job/service
headset = /obj/item/radio/headset/service
headset_alt = /obj/item/radio/headset/alt/service
headset_earbud = /obj/item/radio/headset/earbud/service
/decl/hierarchy/outfit/job/service/bartender
name = OUTFIT_JOB_NAME(JOB_BARTENDER)
uniform = /obj/item/clothing/under/rank/bartender
@@ -91,7 +94,6 @@
/decl/hierarchy/outfit/job/internal_affairs_agent
name = OUTFIT_JOB_NAME("Internal affairs agent")
l_ear = /obj/item/radio/headset/ia
uniform = /obj/item/clothing/under/rank/internalaffairs
suit = /obj/item/clothing/suit/storage/toggle/internalaffairs
shoes = /obj/item/clothing/shoes/brown
@@ -100,6 +102,10 @@
id_type = /obj/item/card/id/civilian/internal_affairs
pda_type = /obj/item/pda/lawyer
headset = /obj/item/radio/headset/ia
headset_alt = /obj/item/radio/headset/alt/ia
headset_earbud = /obj/item/radio/headset/earbud/ia
/decl/hierarchy/outfit/job/chaplain
name = OUTFIT_JOB_NAME(JOB_CHAPLAIN)
uniform = /obj/item/clothing/under/rank/chaplain
@@ -114,10 +120,13 @@
mask = /obj/item/clothing/mask/gas/explorer
suit = /obj/item/clothing/suit/storage/hooded/explorer
gloves = /obj/item/clothing/gloves/black
l_ear = /obj/item/radio/headset
id_slot = slot_wear_id
id_type = /obj/item/card/id/exploration //VOREStation Edit
pda_slot = slot_belt
pda_type = /obj/item/pda/cargo // Brown looks more rugged
r_pocket = /obj/item/gps/explorer
id_pda_assignment = JOB_EXPLORER
headset = /obj/item/radio/headset
headset_alt = /obj/item/radio/headset/alt
headset_earbud = /obj/item/radio/headset/earbud
+13 -3
View File
@@ -2,7 +2,7 @@
name = OUTFIT_JOB_NAME(JOB_ALT_CAPTAIN) // Keep Captain for now, not JOB_SITE_MANAGER
glasses = /obj/item/clothing/glasses/sunglasses
uniform = /obj/item/clothing/under/rank/captain
l_ear = /obj/item/radio/headset/heads/captain
shoes = /obj/item/clothing/shoes/brown
backpack = /obj/item/storage/backpack/captain
satchel_one = /obj/item/storage/backpack/satchel/cap
@@ -10,6 +10,10 @@
id_type = /obj/item/card/id/gold
pda_type = /obj/item/pda/captain
headset = /obj/item/radio/headset/heads/captain
headset_alt = /obj/item/radio/headset/alt/heads/captain
headset_earbud = /obj/item/radio/headset/earbud/heads/captain
/decl/hierarchy/outfit/job/captain/post_equip(var/mob/living/carbon/human/H)
..()
if(H.age>49)
@@ -26,19 +30,25 @@
/decl/hierarchy/outfit/job/hop
name = OUTFIT_JOB_NAME(JOB_HEAD_OF_PERSONNEL)
uniform = /obj/item/clothing/under/rank/head_of_personnel
l_ear = /obj/item/radio/headset/heads/hop
shoes = /obj/item/clothing/shoes/brown
id_type = /obj/item/card/id/silver/hop
pda_type = /obj/item/pda/heads/hop
headset = /obj/item/radio/headset/heads/hop
headset_alt = /obj/item/radio/headset/alt/heads/hop
headset_earbud = /obj/item/radio/headset/earbud/heads/hop
/decl/hierarchy/outfit/job/secretary
name = OUTFIT_JOB_NAME(JOB_COMMAND_SECRETARY)
l_ear = /obj/item/radio/headset/headset_com
shoes = /obj/item/clothing/shoes/brown
id_type = /obj/item/card/id/silver/secretary
pda_type = /obj/item/pda/heads
r_hand = /obj/item/clipboard
headset = /obj/item/radio/headset/headset_com
headset_alt = /obj/item/radio/headset/alt/headset_com
headset_earbud = /obj/item/radio/headset/earbud/headset_com
/decl/hierarchy/outfit/job/secretary/pre_equip(mob/living/carbon/human/H)
..()
if(H.gender == FEMALE)
+9 -2
View File
@@ -1,7 +1,6 @@
/decl/hierarchy/outfit/job/engineering
hierarchy_type = /decl/hierarchy/outfit/job/engineering
belt = /obj/item/storage/belt/utility/full/multitool
l_ear = /obj/item/radio/headset/headset_eng
shoes = /obj/item/clothing/shoes/boots/workboots
r_pocket = /obj/item/t_scanner
backpack = /obj/item/storage/backpack/industrial
@@ -10,15 +9,23 @@
pda_slot = slot_l_store
flags = OUTFIT_HAS_BACKPACK|OUTFIT_EXTENDED_SURVIVAL
headset = /obj/item/radio/headset/headset_eng
headset_alt = /obj/item/radio/headset/alt/headset_eng
headset_earbud = /obj/item/radio/headset/earbud/headset_eng
/decl/hierarchy/outfit/job/engineering/chief_engineer
name = OUTFIT_JOB_NAME(JOB_CHIEF_ENGINEER)
head = /obj/item/clothing/head/hardhat/white
uniform = /obj/item/clothing/under/rank/chief_engineer
l_ear = /obj/item/radio/headset/heads/ce
gloves = /obj/item/clothing/gloves/black
id_type = /obj/item/card/id/engineering/head
pda_type = /obj/item/pda/heads/ce
headset = /obj/item/radio/headset/heads/ce
headset_alt = /obj/item/radio/headset/alt/heads/ce
headset_earbud = /obj/item/radio/headset/earbud/heads/ce
/decl/hierarchy/outfit/job/engineering/engineer
name = OUTFIT_JOB_NAME(JOB_ENGINEER)
head = /obj/item/clothing/head/hardhat
+4 -1
View File
@@ -3,7 +3,6 @@
hierarchy_type = /decl/hierarchy/outfit/job
uniform = /obj/item/clothing/under/color/grey
l_ear = /obj/item/radio/headset
shoes = /obj/item/clothing/shoes/black
id_slot = slot_wear_id
@@ -13,6 +12,10 @@
flags = OUTFIT_HAS_BACKPACK
headset = /obj/item/radio/headset
headset_alt = /obj/item/radio/headset/alt
headset_earbud = /obj/item/radio/headset/earbud
/decl/hierarchy/outfit/job/equip_id(mob/living/carbon/human/H, rank, assignment)
var/obj/item/card/id/C = ..()
var/datum/job/J = job_master.GetJob(rank)
+9 -2
View File
@@ -1,16 +1,19 @@
/decl/hierarchy/outfit/job/medical
hierarchy_type = /decl/hierarchy/outfit/job/medical
l_ear = /obj/item/radio/headset/headset_med
shoes = /obj/item/clothing/shoes/white
pda_type = /obj/item/pda/medical
pda_slot = slot_l_store
backpack = /obj/item/storage/backpack/medic
satchel_one = /obj/item/storage/backpack/satchel/med
messenger_bag = /obj/item/storage/backpack/messenger/med
headset = /obj/item/radio/headset/headset_med
headset_alt = /obj/item/radio/headset/alt/headset_med
headset_earbud = /obj/item/radio/headset/earbud/headset_med
/decl/hierarchy/outfit/job/medical/cmo
name = OUTFIT_JOB_NAME(JOB_CHIEF_MEDICAL_OFFICER)
l_ear =/obj/item/radio/headset/heads/cmo
uniform = /obj/item/clothing/under/rank/chief_medical_officer
suit = /obj/item/clothing/suit/storage/toggle/labcoat/cmo
shoes = /obj/item/clothing/shoes/brown
@@ -19,6 +22,10 @@
id_type = /obj/item/card/id/medical/head
pda_type = /obj/item/pda/heads/cmo
headset = /obj/item/radio/headset/heads/cmo
headset_alt = /obj/item/radio/headset/alt/heads/cmo
headset_earbud = /obj/item/radio/headset/earbud/heads/cmo
/decl/hierarchy/outfit/job/medical/doctor
name = OUTFIT_JOB_NAME(JOB_MEDICAL_DOCTOR)
uniform = /obj/item/clothing/under/rank/medical
+9 -2
View File
@@ -1,23 +1,30 @@
/decl/hierarchy/outfit/job/science
hierarchy_type = /decl/hierarchy/outfit/job/science
l_ear = /obj/item/radio/headset/headset_sci
suit = /obj/item/clothing/suit/storage/toggle/labcoat
shoes = /obj/item/clothing/shoes/white
pda_type = /obj/item/pda/science
backpack = /obj/item/storage/backpack/toxins
satchel_one = /obj/item/storage/backpack/satchel/tox
messenger_bag = /obj/item/storage/backpack/messenger/tox
sports_bag = /obj/item/storage/backpack/sport/tox
headset = /obj/item/radio/headset/headset_sci
headset_alt = /obj/item/radio/headset/alt/headset_sci
headset_earbud = /obj/item/radio/headset/earbud/headset_sci
/decl/hierarchy/outfit/job/science/rd
name = OUTFIT_JOB_NAME("Research Director")
l_ear = /obj/item/radio/headset/heads/rd
uniform = /obj/item/clothing/under/rank/research_director
shoes = /obj/item/clothing/shoes/brown
l_hand = /obj/item/clipboard
id_type = /obj/item/card/id/science/head
pda_type = /obj/item/pda/heads/rd
headset = /obj/item/radio/headset/heads/rd
headset_alt = /obj/item/radio/headset/alt/heads/rd
headset_earbud = /obj/item/radio/headset/earbud/heads/rd
/decl/hierarchy/outfit/job/science/scientist
name = OUTFIT_JOB_NAME(JOB_SCIENTIST)
uniform = /obj/item/clothing/under/rank/scientist
+9 -2
View File
@@ -1,22 +1,29 @@
/decl/hierarchy/outfit/job/security
hierarchy_type = /decl/hierarchy/outfit/job/security
glasses = /obj/item/clothing/glasses/sunglasses/sechud
l_ear = /obj/item/radio/headset/headset_sec
gloves = /obj/item/clothing/gloves/black
shoes = /obj/item/clothing/shoes/boots/jackboots
backpack = /obj/item/storage/backpack/security
satchel_one = /obj/item/storage/backpack/satchel/sec
backpack_contents = list(/obj/item/handcuffs = 1)
messenger_bag = /obj/item/storage/backpack/messenger/sec
sports_bag = /obj/item/storage/backpack/sport/sec
headset = /obj/item/radio/headset/headset_sec
headset_alt = /obj/item/radio/headset/alt/headset_sec
headset_earbud = /obj/item/radio/headset/earbud/headset_sec
/decl/hierarchy/outfit/job/security/hos
name = OUTFIT_JOB_NAME(JOB_HEAD_OF_SECURITY)
l_ear = /obj/item/radio/headset/heads/hos
uniform = /obj/item/clothing/under/rank/head_of_security
id_type = /obj/item/card/id/security/head
pda_type = /obj/item/pda/heads/hos
headset = /obj/item/radio/headset/heads/hos
headset_alt = /obj/item/radio/headset/alt/heads/hos
headset_earbud = /obj/item/radio/headset/earbud/heads/hos
/decl/hierarchy/outfit/job/security/warden
name = OUTFIT_JOB_NAME(JOB_WARDEN)
uniform = /obj/item/clothing/under/rank/warden
+9 -1
View File
@@ -52,6 +52,10 @@ var/list/outfits_decls_by_type_
var/id_pda_assignment
var/headset = /obj/item/radio/headset
var/headset_alt = /obj/item/radio/headset/alt
var/headset_earbud = /obj/item/radio/headset/earbud
var/backpack = /obj/item/storage/backpack
var/satchel_one = /obj/item/storage/backpack/satchel/norm
var/satchel_two = /obj/item/storage/backpack/satchel
@@ -72,7 +76,11 @@ var/list/outfits_decls_by_type_
dd_insertObjectList(outfits_decls_, src)
/decl/hierarchy/outfit/proc/pre_equip(mob/living/carbon/human/H)
if(flags & OUTFIT_HAS_BACKPACK)
switch(H.headset)
if(1) l_ear = headset
if(2) l_ear = headset_alt
if(3) l_ear = headset_earbud
if(flags && OUTFIT_HAS_BACKPACK)
switch(H.backbag)
if(2) back = backpack
if(3) back = satchel_one
+16 -4
View File
@@ -112,7 +112,6 @@ Keep outfits simple. Spawn with basic uniforms and minimal gear. Gear instead go
name = OUTFIT_JOB_NAME(JOB_EXPLORER)
shoes = /obj/item/clothing/shoes/boots/winter/explorer
uniform = /obj/item/clothing/under/explorer
l_ear = /obj/item/radio/headset/explorer
id_slot = slot_wear_id
pda_slot = slot_l_store
pda_type = /obj/item/pda/explorer
@@ -123,6 +122,10 @@ Keep outfits simple. Spawn with basic uniforms and minimal gear. Gear instead go
messenger_bag = /obj/item/storage/backpack/messenger/explorer
flags = OUTFIT_HAS_BACKPACK|OUTFIT_COMPREHENSIVE_SURVIVAL
headset = /obj/item/radio/headset/explorer
headset_alt = /obj/item/radio/headset/alt/explorer
headset_earbud = /obj/item/radio/headset/explorer
/decl/hierarchy/outfit/job/pilot
name = OUTFIT_JOB_NAME(JOB_PILOT)
shoes = /obj/item/clothing/shoes/black
@@ -130,7 +133,6 @@ Keep outfits simple. Spawn with basic uniforms and minimal gear. Gear instead go
suit = /obj/item/clothing/suit/storage/toggle/bomber/pilot
gloves = /obj/item/clothing/gloves/fingerless
glasses = /obj/item/clothing/glasses/fakesunglasses/aviator
l_ear = /obj/item/radio/headset/pilot/alt
uniform_accessories = list(/obj/item/clothing/accessory/storage/webbing/pilot1 = 1)
id_slot = slot_wear_id
pda_slot = slot_belt
@@ -139,12 +141,15 @@ Keep outfits simple. Spawn with basic uniforms and minimal gear. Gear instead go
id_pda_assignment = JOB_PILOT
flags = OUTFIT_HAS_BACKPACK|OUTFIT_COMPREHENSIVE_SURVIVAL
headset = /obj/item/radio/headset/pilot
headset_alt = /obj/item/radio/headset/alt/pilot
headset_earbud = /obj/item/radio/headset/alt/pilot
/decl/hierarchy/outfit/job/medical/sar
name = OUTFIT_JOB_NAME(JOB_FIELD_MEDIC)
uniform = /obj/item/clothing/under/utility/blue
//suit = /obj/item/clothing/suit/storage/hooded/wintercoat/medical/sar
shoes = /obj/item/clothing/shoes/boots/winter/explorer
l_ear = /obj/item/radio/headset/sar
l_hand = /obj/item/storage/firstaid/regular
belt = /obj/item/storage/belt/medical/emt
pda_slot = slot_l_store
@@ -156,11 +161,14 @@ Keep outfits simple. Spawn with basic uniforms and minimal gear. Gear instead go
messenger_bag = /obj/item/storage/backpack/messenger/explorer
flags = OUTFIT_HAS_BACKPACK|OUTFIT_EXTENDED_SURVIVAL|OUTFIT_COMPREHENSIVE_SURVIVAL
headset = /obj/item/radio/headset/sar
headset_alt = /obj/item/radio/headset/alt/sar
headset_earbud = /obj/item/radio/headset/sar
/decl/hierarchy/outfit/job/pathfinder
name = OUTFIT_JOB_NAME(JOB_PATHFINDER)
shoes = /obj/item/clothing/shoes/boots/winter/explorer
uniform = /obj/item/clothing/under/explorer //TODO: Uniforms.
l_ear = /obj/item/radio/headset/pathfinder
id_slot = slot_wear_id
pda_slot = slot_l_store
pda_type = /obj/item/pda/pathfinder
@@ -168,6 +176,10 @@ Keep outfits simple. Spawn with basic uniforms and minimal gear. Gear instead go
id_pda_assignment = JOB_PATHFINDER
flags = OUTFIT_HAS_BACKPACK|OUTFIT_EXTENDED_SURVIVAL|OUTFIT_COMPREHENSIVE_SURVIVAL
headset = /obj/item/radio/headset/pathfinder
headset_alt = /obj/item/radio/headset/alt/pathfinder
headset_earbud = /obj/item/radio/headset/pathfinder
/decl/hierarchy/outfit/job/assistant/explorer
id_type = /obj/item/card/id/exploration
flags = OUTFIT_HAS_BACKPACK|OUTFIT_COMPREHENSIVE_SURVIVAL
+1 -1
View File
@@ -97,7 +97,7 @@
/obj/item/clothing/glasses/thermal/syndi,
/obj/item/ammo_magazine/m45/ap,
/obj/item/material/knife/tacknife/combatknife,
/obj/item/multitool/hacktool
/obj/item/multitool/hacktool/modified
),
list( //the professional,
/obj/item/gun/projectile/silenced,
+7 -7
View File
@@ -112,7 +112,7 @@
contains = list(
/obj/item/storage/belt/medical = 3,
/obj/item/clothing/glasses/hud/health = 3,
/obj/item/radio/headset/headset_med/alt = 3,
/obj/item/radio/headset/alt/headset_med = 3,
/obj/item/clothing/suit/storage/hooded/wintercoat/medical = 3
)
cost = 10
@@ -329,11 +329,11 @@
access = access_medical_equip
/datum/supply_pack/med/virus
name = "Virus sample crate"
contains = list(/obj/item/virusdish/random = 4)
name = "Virus culture crate"
contains = list(/obj/item/reagent_containers/glass/bottle/culture/cold = 1, /obj/item/reagent_containers/glass/bottle/culture/flu = 1)
cost = 25
containertype = /obj/structure/closet/crate/secure/zenghu
containername = "Virus sample crate"
containername = "Virus culture crate"
access = access_cmo
/datum/supply_pack/med/defib
@@ -410,11 +410,11 @@
access = access_medical_equip
/datum/supply_pack/med/virus
name = "Virus sample crate"
contains = list(/obj/item/virusdish/random = 4)
name = "Virus culture crate"
contains = list(/obj/item/reagent_containers/glass/bottle/culture/cold = 1, /obj/item/reagent_containers/glass/bottle/culture/flu = 1)
cost = 25
containertype = /obj/structure/closet/crate/secure
containername = "Virus sample crate"
containername = "Virus culture crate"
access = access_medical_equip
+1 -1
View File
@@ -444,7 +444,7 @@
contains = list(
/obj/item/storage/belt/security = 3,
/obj/item/clothing/glasses/sunglasses/sechud = 3,
/obj/item/radio/headset/headset_sec/alt = 3,
/obj/item/radio/headset/alt/headset_sec = 3,
/obj/item/clothing/suit/storage/hooded/wintercoat/security = 3,
/obj/item/clothing/glasses/sunglasses/sechud/tactical_sec_vis = 3
)
+2 -2
View File
@@ -118,7 +118,7 @@
/obj/item/storage/backpack/industrial,
/obj/item/storage/backpack/satchel/eng,
/obj/item/clothing/suit/storage/hooded/wintercoat/miner,
/obj/item/radio/headset/headset_cargo,
/obj/item/radio/headset/miner,
/obj/item/clothing/under/rank/miner,
/obj/item/clothing/gloves/black,
/obj/item/clothing/shoes/black,
@@ -187,7 +187,7 @@
contains = list (
/obj/item/storage/backpack/parachute,
/obj/item/radio/headset/pilot,
/obj/item/radio/headset/pilot/alt,
/obj/item/radio/headset/alt/pilot,
/obj/item/clothing/mask/gas/half,
/obj/item/flashlight/glowstick,
/obj/item/stack/marker_beacon/thirty,
+2 -2
View File
@@ -1,6 +1,6 @@
/mob/living/proc/convert_to_rev(mob/M as mob in oview(src))
set name = "Convert Bourgeoise"
set category = "Abilities"
set category = "Abilities.Antag"
if(!M.mind)
return
convert_to_faction(M.mind, revs)
@@ -44,7 +44,7 @@
/mob/living/proc/convert_to_loyalist(mob/M as mob in oview(src))
set name = "Convert Recidivist"
set category = "Abilities"
set category = "Abilities.Antag"
if(!M.mind)
return
convert_to_faction(M.mind, loyalists)
@@ -32,7 +32,7 @@
/mob/living/proc/write_ambition()
set name = "Set Ambition"
set category = "IC"
set category = "IC.Antag"
set src = usr
if(!mind)
+3 -1
View File
@@ -478,7 +478,9 @@
/atom/proc/add_vomit_floor(mob/living/carbon/M as mob, var/toxvomit = 0)
if( istype(src, /turf/simulated) )
var/obj/effect/decal/cleanable/vomit/this = new /obj/effect/decal/cleanable/vomit(src)
this.virus2 = virus_copylist(M.virus2)
for(var/datum/disease/D in M.GetViruses())
this.viruses |= D.Copy()
// Make toxins vomit look different
if(toxvomit)
+1 -1
View File
@@ -6,7 +6,7 @@ var/global/list/engwords = list("travel", "blood", "join", "hell", "destroy", "t
var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","mgar","balaq", "karazet", "geeri")
/client/proc/check_words() // -- Urist
set category = "Special Verbs"
set category = "Admin.Secrets"
set name = "Check Rune Words"
set desc = "Check the rune-word meaning"
if(!cultwords["travel"])
@@ -239,7 +239,7 @@ var/global/list/Holiday = list() //Holidays are lists now, so we can have more t
//Allows GA and GM to set the Holiday variable
/client/proc/Set_Holiday()
set name = "Set Holiday"
set category = "Fun"
set category = "Fun.Event Kit"
set desc = "Force-set the Holiday variable to make the game think it's a certain day."
if(!check_rights(R_SERVER)) return
+1 -1
View File
@@ -546,7 +546,7 @@ var/global/list/additional_antag_types = list()
/mob/verb/check_round_info()
set name = "Check Round Info"
set category = "OOC"
set category = "OOC.Game"
if(!ticker || !ticker.mode)
to_chat(usr, span_warning("Something is terribly wrong; there is no gametype."))
+7 -3
View File
@@ -189,7 +189,7 @@
occupantData["health"] = H.health
occupantData["maxHealth"] = H.getMaxHealth()
occupantData["hasVirus"] = H.virus2.len
occupantData["hasVirus"] = H.viruses.len
occupantData["bruteLoss"] = H.getBruteLoss()
occupantData["oxyLoss"] = H.getOxyLoss()
@@ -379,8 +379,12 @@
dat += (occupant.health > (occupant.getMaxHealth() / 2) ? span_blue(health_text) : span_red(health_text))
dat += "<br>"
if(occupant.virus2.len)
dat += span_red("Viral pathogen detected in blood stream.") + "<BR>"
if(occupant.viruses.len)
for(var/datum/disease/D in occupant.GetViruses())
if(D.visibility_flags & HIDDEN_SCANNER)
continue
else
dat += span_red("Viral pathogen detected in blood stream.") + "<BR>"
var/damage_string = null
damage_string = "\t-Brute Damage %: [occupant.getBruteLoss()]"
+2 -2
View File
@@ -254,19 +254,19 @@
if (!(src.status))
if(user)
visible_message(span_notice(" [user] has deactivated [src]!"))
add_hiddenprint(user)
else
visible_message(span_notice(" [src] clicks and shuts down. "))
playsound(src, 'sound/items/Wirecutter.ogg', 100, 1)
icon_state = "[initial(icon_state)]1"
add_hiddenprint(user)
else
if(user)
visible_message(span_notice(" [user] has reactivated [src]!"))
add_hiddenprint(user)
else
visible_message(span_notice(" [src] clicks and reactivates itself. "))
playsound(src, 'sound/items/Wirecutter.ogg', 100, 1)
icon_state = initial(icon_state)
add_hiddenprint(user)
/obj/machinery/camera/take_damage(var/force, var/message)
//prob(25) gives an average of 3-4 hits
+5 -5
View File
@@ -26,7 +26,7 @@
/mob/living/silicon/ai/proc/ai_camera_list(var/camera in get_camera_list())
set category = "AI Commands"
set category = "AI.Camera Control"
set name = "Show Camera List"
if(check_unable())
@@ -41,7 +41,7 @@
return
/mob/living/silicon/ai/proc/ai_store_location(loc as text)
set category = "AI Commands"
set category = "AI.Camera Control"
set name = "Store Camera Location"
set desc = "Stores your current camera location by the given name"
@@ -70,7 +70,7 @@
return sortList(stored_locations)
/mob/living/silicon/ai/proc/ai_goto_location(loc in sorted_stored_locations())
set category = "AI Commands"
set category = "AI.Camera Control"
set name = "Goto Camera Location"
set desc = "Returns to the selected camera location"
@@ -82,7 +82,7 @@
src.eyeobj.setLoc(L)
/mob/living/silicon/ai/proc/ai_remove_location(loc in sorted_stored_locations())
set category = "AI Commands"
set category = "AI.Camera Control"
set name = "Delete Camera Location"
set desc = "Deletes the selected camera location"
@@ -129,7 +129,7 @@
return targets
/mob/living/silicon/ai/proc/ai_camera_track(var/target_name in trackable_mobs())
set category = "AI Commands"
set category = "AI.Camera Control"
set name = "Follow With Camera"
set desc = "Select who you would like to track."
+1 -1
View File
@@ -262,7 +262,7 @@ GLOBAL_LIST_BOILERPLATE(all_deactivated_AI_cores, /obj/structure/AIcore/deactiva
/client/proc/empty_ai_core_toggle_latejoin()
set name = "Toggle AI Core Latejoin"
set category = "Admin"
set category = "Admin.Silicon"
var/list/cores = list()
for(var/obj/structure/AIcore/deactivated/D in all_deactivated_AI_cores)
+4 -2
View File
@@ -172,8 +172,10 @@
medical["empty"] = 1
if(MED_DATA_V_DATA)
data["virus"] = list()
for(var/ID in virusDB)
var/datum/data/record/v = virusDB[ID]
for(var/datum/disease/D in active_diseases)
if(!D.discovered)
continue
var/datum/data/record/v = active_diseases[D]
data["virus"] += list(list("name" = v.fields["name"], "D" = "\ref[v]"))
if(MED_DATA_MEDBOT)
data["medbots"] = list()
+67
View File
@@ -0,0 +1,67 @@
/obj/machinery/contraband_scanner
name = "contraband scanner"
gender = PLURAL
icon = 'icons/obj/atm_fieldgen.dmi'
icon_state = "arfg_off"
desc = "A simple scanner that analyzes those who pass over it, and sounds an alarm if it detects any items that are programmed into its contraband list."
anchored = TRUE
opacity = FALSE
density = FALSE
power_channel = EQUIP
use_power = USE_POWER_IDLE
idle_power_usage = 10
active_power_usage = 250
var/deep_scan = TRUE //check more than just their hands/pockets?
var/contraband_count = 0 //how many items have we detected? only one actually needs to be found to set off the alarm
var/area_lockdown = TRUE //do we set off the fire alarm for our area when triggered?
var/close_blastdoors = TRUE //close all blast doors in the area when triggered?
var/power_fields = TRUE //do we activate all ARFs when triggered? use w/ impassable fieldgens. requires area_lockdown = TRUE to do anything.
var/last_trigger //when were we last triggered? combined with the cooldown below for sanity reasons
var/cooldown = 15 SECONDS //minimum time between retriggers, so people can't spam trigger the scanner to be obnoxious
var/auto_cancel = TRUE //automatically cancel alarm states after a delay? same duration as the cooldown for sanity
var/trigger_message = "The contraband scanner has been tripped!"
var/trigger_sound = 'sound/machines/airalarm.ogg' //sound that plays when we're set off
var/list/contraband = list(/obj/item/melee,/obj/item/gun,/obj/item/material)
/obj/machinery/contraband_scanner/Crossed(mob/living/M as mob)
if(M.is_incorporeal())
return
if(isliving(M))
var/area/A = src.loc.loc
if(last_trigger > world.time - cooldown)
return
for(var/obj/O in M.contents)
if(is_type_in_list(O,contraband))
contraband_count++
if(deep_scan)
for(var/obj/O2 in O.contents) //one layer deep is fine for now I think
if(is_type_in_list(O2,contraband))
contraband_count++
if(contraband_count && last_trigger < world.time - cooldown)
visible_message(span_danger(trigger_message))
playsound(src, trigger_sound, 25, 0, 4, volume_channel = VOLUME_CHANNEL_ALARMS)
for(var/obj/machinery/contraband_scanner/CS in A)
CS.last_trigger = world.time //set everyone's trigger time at once, to cut down on spam
CS.contraband_count = 0 //clear all our contraband counts too
if(area_lockdown)
if(close_blastdoors)
for(var/obj/machinery/door/blast/B in A)
if(!B.density)
spawn(0)
B.close()
if(power_fields)
A.arfgs_activate()
if(auto_cancel)
spawn(cooldown)
if(close_blastdoors)
for(var/obj/machinery/door/blast/B in A)
if(B.density)
spawn(0)
B.open()
if(power_fields)
A.arfgs_deactivate()
..()
+20
View File
@@ -221,3 +221,23 @@
spawn(0)
if(SG?.anchored)
SG.toggle()
/obj/machinery/button/remote/airlock/release
icon = 'icons/obj/door_release.dmi'
name = "emergency door release"
desc = "Forces the opening of doors in an emergency, regardless of whether they're powered."
use_power = USE_POWER_OFF
idle_power_usage = 0
active_power_usage = 0
/obj/machinery/button/remote/airlock/release/trigger()
for(var/obj/machinery/door/airlock/D in machines)
if(D.id_tag == id)
if(D.locked)
D.unlock(1)
if(D.density)
D.open(1)
/obj/machinery/button/remote/airlock/release/powered()
return 1 //Is always able to be used
+377
View File
@@ -0,0 +1,377 @@
/obj/machinery/computer/pandemic
name = "PanD.E.M.I.C 2200"
desc = "Used to work with viruses."
density = TRUE
anchored = TRUE
icon = 'icons/obj/pandemic.dmi'
icon_state = "pandemic0"
var/temp_html = ""
var/printing = null
var/wait = null
var/selected_strain_index = 1
var/obj/item/reagent_containers/beaker = null
/obj/machinery/computer/pandemic/Initialize(mapload)
. = ..()
update_icon()
/obj/machinery/computer/pandemic/set_broken()
stat |= BROKEN
update_icon()
/obj/machinery/computer/pandemic/proc/GetViruses()
if(beaker && beaker.reagents)
if(length(beaker.reagents.reagent_list))
var/datum/reagent/blood/BL = locate() in beaker.reagents.reagent_list
if(BL)
if(BL.data && BL.data["viruses"])
var/list/viruses = BL.data["viruses"]
return viruses
/obj/machinery/computer/pandemic/proc/GetVirusByIndex(index)
var/list/viruses = GetViruses()
if(viruses && index > 0 && index <= length(viruses))
return viruses[index]
/obj/machinery/computer/pandemic/proc/GetResistances()
if(beaker && beaker.reagents)
if(length(beaker.reagents.reagent_list))
var/datum/reagent/blood/BL = locate() in beaker.reagents.reagent_list
if(BL)
if(BL.data && BL.data["resistances"])
var/list/resistances = BL.data["resistances"]
return resistances
/obj/machinery/computer/pandemic/proc/GetResistancesByIndex(index)
var/list/resistances = GetResistances()
if(resistances && index > 0 && index <= length(resistances))
return resistances[index]
/obj/machinery/computer/pandemic/proc/GetVirusTypeByIndex(index)
var/datum/disease/D = GetVirusByIndex(index)
if(D)
return D.GetDiseaseID()
/obj/machinery/computer/pandemic/proc/replicator_cooldown(waittime)
wait = 1
update_icon()
spawn(waittime)
wait = null
update_icon()
playsound(loc, 'sound/machines/ping.ogg', 30, 1)
/obj/machinery/computer/pandemic/update_icon()
if(stat & BROKEN)
icon_state = (beaker ? "pandemic1_b" : "pandemic0_b")
return
icon_state = "pandemic[(beaker)?"1":"0"][!(stat & NOPOWER) ? "" : "_nopower"]"
/obj/machinery/computer/pandemic/proc/create_culture(name, bottle_type = "culture", cooldown = 50)
var/obj/item/reagent_containers/glass/bottle/B = new/obj/item/reagent_containers/glass/bottle(loc)
B.icon_state = "bottle10"
B.pixel_x = rand(-3, 3)
B.pixel_y = rand(-3, 3)
replicator_cooldown(cooldown)
B.name = "[name] [bottle_type] bottle"
return B
/obj/machinery/computer/pandemic/tgui_act(action, params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return
if(inoperable())
return
. = TRUE
switch(action)
if("clone_strain")
if(wait)
atom_say("The replicator is not ready yet.")
return
var/strain_index = text2num(params["strain_index"])
if(isnull(strain_index))
atom_say("Unable to respond to command.")
return
var/datum/disease/virus = GetVirusByIndex(strain_index)
var/datum/disease/D = null
if(!virus)
atom_say("Unable to find requested strain.")
return
var/type = virus.GetDiseaseID()
if(!ispath(type))
var/datum/disease/advance/A = GLOB.archive_diseases[type]
if(A)
D = new A.type(0, A)
else if(type)
if(type in GLOB.diseases) // Make sure this is a disease
D = new type(0, null)
if(!D)
atom_say("Unable to synthesize requested strain.")
return
var/default_name = ""
if(D.name == "Unknown" || D.name == "")
default_name = replacetext(beaker.name, new/regex(" culture bottle\\Z", "g"), "")
else
default_name = D.name
var/name = tgui_input_text(usr, "Name:", "Name the culture", default_name, MAX_NAME_LEN)
if(name == null || wait)
return
var/obj/item/reagent_containers/glass/bottle/B = create_culture(name)
B.desc = "A small bottle. Contains [D.agent] culture in synthblood medium."
B.reagents.add_reagent("blood", 20, list("viruses" = list(D)))
if("clone_vaccine")
if(wait)
atom_say("The replicator is not ready yet.")
return
var/resistance_index = text2num(params["resistance_index"])
if(isnull(resistance_index))
atom_say("Unable to find requested antibody.")
return
var/vaccine_type = GetResistancesByIndex(resistance_index)
var/vaccine_name = "Unknown"
if(!ispath(vaccine_type))
if(GLOB.archive_diseases[vaccine_type])
var/datum/disease/D = GLOB.archive_diseases[vaccine_type]
if(D)
vaccine_name = D.name
else if(vaccine_type)
var/datum/disease/D = new vaccine_type(0, null)
if(D)
vaccine_name = D.name
if(!vaccine_type)
atom_say("Unable to synthesize requested antibody.")
return
var/obj/item/reagent_containers/glass/bottle/B = create_culture(vaccine_name, "vaccine", 200)
B.reagents.add_reagent("vaccine", 15, list(vaccine_type))
if("eject_beaker")
eject_beaker()
update_tgui_static_data(ui.user)
if("destroy_eject_beaker")
beaker.reagents.clear_reagents()
eject_beaker()
update_tgui_static_data(ui.user)
if("print_release_forms")
var/strain_index = text2num(params["strain_index"])
if(isnull(strain_index))
atom_say("Unable to respond to command.")
return
var/type = GetVirusTypeByIndex(strain_index)
if(!type)
atom_say("Unable to find requested strain.")
return
var/datum/disease/advance/A = GLOB.archive_diseases[type]
if(!A)
atom_say("Unable to find requested strain.")
return
print_form(A, usr)
if("name_strain")
var/strain_index = text2num(params["strain_index"])
if(isnull(strain_index))
atom_say("Unable to respond to command.")
return
var/type = GetVirusTypeByIndex(strain_index)
if(!type)
atom_say("Unable to find requested strain.")
return
var/datum/disease/advance/A = GLOB.archive_diseases[type]
if(!A)
atom_say("Unable to find requested strain.")
return
if(A.name != "Unknown")
atom_say("Request rejected. Strain already has a name.")
return
var/new_name = tgui_input_text(usr, "Name the Strain", "New Name", max_length = MAX_NAME_LEN)
if(!new_name)
return
A.AssignName(new_name)
for(var/datum/disease/advance/AD in active_diseases)
AD.Refresh()
update_tgui_static_data(ui.user)
if("switch_strain")
var/strain_index = text2num(params["strain_index"])
if(isnull(strain_index) || strain_index < 1)
atom_say("Unable to respond to command.")
return
var/list/viruses = GetViruses()
if(strain_index > length(viruses))
atom_say("Unable to find requested strain.")
return
selected_strain_index = strain_index;
else
return FALSE
/obj/machinery/computer/pandemic/tgui_state(mob/user)
return GLOB.tgui_default_state
/obj/machinery/computer/pandemic/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "PanDEMIC", name)
ui.open()
/obj/machinery/computer/pandemic/tgui_data(mob/user)
var/datum/reagent/blood/Blood = null
if(beaker)
var/datum/reagents/R = beaker.reagents
for(var/datum/reagent/blood/B in R.reagent_list)
if(B)
Blood = B
break
var/list/data = list(
"synthesisCooldown" = wait ? TRUE : FALSE,
"beakerLoaded" = beaker ? TRUE : FALSE,
"beakerContainsBlood" = Blood ? TRUE : FALSE,
"beakerContainsVirus" = length(Blood?.data["viruses"]) != 0,
"selectedStrainIndex" = selected_strain_index,
)
return data
/obj/machinery/computer/pandemic/tgui_static_data(mob/user)
var/list/data = list()
. = data
var/datum/reagent/blood/Blood = null
if(beaker)
var/datum/reagents/R = beaker.reagents
for(var/datum/reagent/blood/B in R.reagent_list)
if(B)
Blood = B
break
var/list/strains = list()
for(var/datum/disease/D in GetViruses())
if(D.visibility_flags & HIDDEN_PANDEMIC)
continue
var/list/symptoms = list()
if(istype(D, /datum/disease/advance))
var/datum/disease/advance/A = D
D = GLOB.archive_diseases[A.GetDiseaseID()]
if(!D)
CRASH("We weren't able to get the advance disease from the archive.")
for(var/datum/symptom/S in A.symptoms)
symptoms += list(list(
"name" = S.name,
"stealth" = S.stealth,
"resistance" = S.resistance,
"stageSpeed" = S.stage_speed,
"transmissibility" = S.transmittable,
"complexity" = S.level,
))
strains += list(list(
"commonName" = D.name,
"description" = D.desc,
"bloodDNA" = Blood.data["blood_DNA"],
"bloodType" = Blood.data["blood_type"],
"diseaseAgent" = D.agent,
"possibleTreatments" = D.cure_text,
"transmissionRoute" = D.spread_text,
"symptoms" = symptoms,
"isAdvanced" = istype(D, /datum/disease/advance),
))
data["strains"] = strains
var/list/resistances = list()
for(var/resistance in GetResistances())
if(!ispath(resistance))
var/datum/disease/D = GLOB.archive_diseases[resistance]
if(D)
resistances += list(D.name)
else if(resistance)
var/datum/disease/D = new resistance(0, null)
if(D)
resistances += list(D.name)
data["resistances"] = resistances
/obj/machinery/computer/pandemic/proc/eject_beaker()
set name = "Eject Beaker"
set category = "Object"
set src in oview(1)
if(usr.stat != 0)
return
beaker.forceMove(loc)
beaker = null
icon_state = "pandemic0"
selected_strain_index = 1
/obj/machinery/computer/pandemic/proc/print_form(datum/disease/advance/D, mob/living/user)
D = GLOB.archive_diseases[D.GetDiseaseID()]
if(!(printing) && D)
var/reason = tgui_input_text(user,"Enter a reason for the release", "Write", multiline = TRUE)
if(!reason)
return
reason += "<span class=\"paper_field\"></span>"
var/english_symptoms = list()
for(var/I in D.symptoms)
var/datum/symptom/S = I
english_symptoms += S.name
var/symtoms = english_list(english_symptoms)
var/signature
if(tgui_alert(user, "Would you like to add your signature?", "Signature", list("Yes","No")) == "Yes")
signature = "<font face=\"Times New Roman\"><i>[user ? user.real_name : "Anonymous"]</i></font>"
else
signature = "<span class=\"paper_field\"></span>"
printing = 1
var/obj/item/paper/P = new /obj/item/paper(loc)
visible_message(span_notice("[src] rattles and prints out a sheet of paper."))
// playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1)
P.info = "<U><font size=\"4\"><B><center> Releasing Virus </B></center></font></U>"
P.info += "<HR>"
P.info += "<U>Name of the Virus:</U> [D.name] <BR>"
P.info += "<U>Symptoms:</U> [symtoms]<BR>"
P.info += "<U>Spreads by:</U> [D.spread_text]<BR>"
P.info += "<U>Cured by:</U> [D.cure_text]<BR>"
P.info += "<BR>"
P.info += "<U>Reason for releasing:</U> [reason]"
P.info += "<HR>"
P.info += "The Virologist is responsible for any biohazards caused by the virus released.<BR>"
P.info += "<U>Virologist's sign:</U> [signature]<BR>"
P.info += "If approved, stamp below with the Chief Medical Officer's stamp, and/or the Captain's stamp if required:"
P.updateinfolinks()
P.name = "Releasing Virus - [D.name]"
printing = null
/obj/machinery/computer/pandemic/attack_ai(mob/user)
return attack_hand(user)
/obj/machinery/computer/pandemic/attack_hand(mob/user)
if(..())
return
tgui_interact(user)
/obj/machinery/computer/pandemic/attack_ghost(mob/user)
tgui_interact(user)
/obj/machinery/computer/pandemic/attackby(obj/item/I, mob/user, params)
if(default_unfasten_wrench(user, I, 4 SECONDS))
return
if(I.has_tool_quality(TOOL_SCREWDRIVER))
eject_beaker()
return
if(istype(I, /obj/item/reagent_containers/glass) && I.is_open_container())
if(stat & (NOPOWER|BROKEN))
return
if(beaker)
to_chat(user, span_warning("A beaker is already loaded into the machine!"))
return
user.drop_item()
beaker = I
beaker.loc = src
to_chat(user, span_notice("You add the beaker to the machine."))
update_tgui_static_data(user)
icon_state = "pandemic1"
else
return ..()
+3 -2
View File
@@ -174,8 +174,9 @@
return
/obj/machinery/partslathe/proc/removeFromQueue(var/index)
queue.Cut(index, index + 1)
return
if(queue.len >= index)
queue.Cut(index, index + 1)
return
/obj/machinery/partslathe/proc/canBuild(var/datum/category_item/partslathe/D)
for(var/M in D.resources)
+1 -1
View File
@@ -34,7 +34,7 @@ var/global/datum/book_manager/book_mgr = new()
/client/proc/delbook()
set name = "Delete Book"
set desc = "Permamently deletes a book from the database."
set category = "Admin"
set category = "Admin.Moderation"
if(!src.holder)
to_chat(src, "Only administrators may use this command.")
return
@@ -252,7 +252,7 @@
if(3)
if(diff==FORWARD)
user.visible_message("[user] installs external reinforced armor layer to [holder].", "You install external reinforced armor layer to [holder].")
qdel(used_atom)//CHOMPedit upstream port. Fixes polecat not useing it's armor plates up.
qdel(used_atom)// upstream port. Fixes polecat not useing it's armor plates up.
holder.icon_state = "polecat18"
else
user.visible_message("[user] cuts internal armor layer from [holder].", "You cut the internal armor layer from [holder].")
@@ -19,7 +19,7 @@ var/global/list/image/splatter_cache=list()
blood_DNA = list()
var/basecolor="#A10808" // Color when wet.
var/synthblood = 0
var/list/datum/disease2/disease/virus2 = list()
var/list/datum/disease/viruses = list()
var/amount = 5
generic_filth = TRUE
persistent = FALSE
@@ -112,6 +112,10 @@ var/global/list/image/splatter_cache=list()
var/obj/structure/bed/chair/wheelchair/W = perp.buckled
W.bloodiness = 4
if(viruses)
for(var/datum/disease/D in viruses)
perp.ContractDisease(D)
amount--
/obj/effect/decal/cleanable/blood/proc/dry()
@@ -124,6 +128,11 @@ var/global/list/image/splatter_cache=list()
..()
if (amount && istype(user))
add_fingerprint(user)
if(viruses)
for(var/datum/disease/D in viruses)
user.ContractDisease(D)
if (user.gloves)
return
var/taken = rand(1,amount)
@@ -242,7 +251,7 @@ var/global/list/image/splatter_cache=list()
icon_state = "mucus"
random_icon_states = list("mucus")
var/list/datum/disease2/disease/virus2 = list()
var/list/datum/disease/viruses = list()
var/dry = 0 // Keeps the lag down
/obj/effect/decal/cleanable/mucus/Initialize()
@@ -252,11 +261,20 @@ var/global/list/image/splatter_cache=list()
//This version should be used for admin spawns and pre-mapped virus vectors (e.g. in PoIs), this version does not dry
/obj/effect/decal/cleanable/mucus/mapped/Initialize()
. = ..()
virus2 |= new /datum/disease2/disease
virus2[1].makerandom()
viruses |= new /datum/disease/advance
/obj/effect/decal/cleanable/mucus/mapped/Destroy()
virus2.Cut()
viruses.Cut()
return ..()
/obj/effect/decal/cleanable/mucus/Crossed(mob/living/carbon/human/perp)
if(viruses)
for(var/datum/disease/D in viruses)
perp.ContractDisease(D)
/obj/effect/decal/cleanable/vomit/Crossed(mob/living/carbon/human/perp)
if(viruses)
for(var/datum/disease/D in viruses)
perp.ContractDisease(D)
#undef DRYING_TIME
@@ -113,7 +113,7 @@
icon = 'icons/effects/blood.dmi'
icon_state = "vomit_1"
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
var/list/datum/disease2/disease/virus2 = list()
var/list/datum/disease/viruses = list()
/obj/effect/decal/cleanable/tomato_smudge
name = "tomato smudge"

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