Progress on DMDocs. PRing progress so far so there's not one mega PR
later with 1500 affected files.

I want my goddamn highlight text on what all these goddamn procs goddamn
do goddamnit. >:(

No actual code change anywhere in this PR, only comments.

---------

Signed-off-by: Batrachophreno <Batrochophreno@gmail.com>
This commit is contained in:
Batrachophreno
2025-08-09 12:22:56 +00:00
committed by GitHub
parent a840bd1cb1
commit c2f054fd81
88 changed files with 1574 additions and 879 deletions
+47 -22
View File
@@ -1,12 +1,19 @@
#define ALARM_RESET_DELAY 100 // How long will the alarm/trigger remain active once origin/source has been found to be gone?
/// How long will the alarm/trigger remain active once origin/source has been found to be gone?
#define ALARM_RESET_DELAY 100
/datum/alarm_source
var/source = null // The source trigger
var/source_name = "" // The name of the source should it be lost (for example a destroyed camera)
var/duration = 0 // How long this source will be alarming, 0 for indefinetely.
var/severity = 1 // How severe the alarm from this source is.
var/start_time = 0 // When this source began alarming.
var/end_time = 0 // Use to set when this trigger should clear, in case the source is lost.
//// The source trigger
var/source = null
/// The name of the source should it be lost (for example a destroyed camera)
var/source_name = ""
/// How long this source will be alarming, 0 for indefinitely.
var/duration = 0
/// How severe the alarm from this source is.
var/severity = 1
/// When this source began alarming.
var/start_time = 0
/// Use to set when this trigger should clear, in case the source is lost.
var/end_time = 0
/datum/alarm_source/New(var/atom/source)
src.source = source
@@ -14,20 +21,29 @@
source_name = source.get_source_name()
/datum/alarm
var/atom/origin //Used to identify the alarm area.
var/list/sources = new() //List of sources triggering the alarm. Used to determine when the alarm should be cleared.
var/list/sources_assoc = new() //Associative list of source triggers. Used to efficiently acquire the alarm source.
var/list/cameras //List of cameras that can be switched to, if the player has that capability.
var/cache_id //ID for camera cache, changed by invalidateCameraCache().
var/area/last_area //The last acquired area, used should origin be lost (for example a destroyed borg containing an alarming camera).
var/area/last_name //The last acquired name, used should origin be lost
var/area/last_camera_area //The last area in which cameras where fetched, used to see if the camera list should be updated.
var/end_time //Used to set when this alarm should clear, in case the origin is lost.
/// Used to identify the alarm area.
var/atom/origin
/// List of sources triggering the alarm. Used to determine when the alarm should be cleared.
var/list/sources = new()
/// Associative list of source triggers. Used to efficiently acquire the alarm source.
var/list/sources_assoc = new()
/// List of cameras that can be switched to, if the player has that capability.
var/list/cameras
/// ID for camera cache, changed by invalidateCameraCache().
var/cache_id
/// The last acquired area, used should origin be lost (for example a destroyed borg containing an alarming camera).
var/area/last_area
/// The last acquired name, used should origin be lost.
var/area/last_name
/// The last area in which cameras where fetched, used to see if the camera list should be updated.
var/area/last_camera_area
/// Used to set when this alarm should clear, in case the origin is lost.
var/end_time
/datum/alarm/New(var/atom/origin, var/atom/source, var/duration, var/severity)
src.origin = origin
cameras() // Sets up both cameras and last alarm area.
// Sets up both cameras and last alarm area.
cameras()
set_source_data(source, duration, severity)
/datum/alarm/process()
@@ -38,8 +54,8 @@
// Has the alarm passed its best before date?
if((AS.end_time && world.time > AS.end_time) || (AS.duration && world.time > (AS.start_time + AS.duration)))
sources -= AS
// Has the source gone missing? Then reset the normal duration and set end_time
if(!AS.source && !AS.end_time) // end_time is used instead of duration to ensure the reset doesn't remain in the future indefinetely.
// Has the source gone missing? Then reset the normal duration and set end_time.
if(!AS.source && !AS.end_time) // end_time is used instead of duration to ensure the reset doesn't remain in the future indefinitely.
AS.duration = 0
AS.end_time = world.time + ALARM_RESET_DELAY
@@ -49,7 +65,7 @@
AS = new/datum/alarm_source(source)
sources += AS
sources_assoc[source] = AS
// Currently only non-0 durations can be altered (normal alarms VS EMP blasts)
// Currently only non-0 durations can be altered (normal alarms VS EMP blasts).
if(AS.duration)
duration = SecondsToTicks(duration)
AS.duration = duration
@@ -74,8 +90,11 @@
last_name = origin.get_alarm_name()
return last_name
/**
* Resets the alarm's camera cache and tries to repopulate it (sometimes cameras move/leave, like borgs etc.).
*/
/datum/alarm/proc/cameras()
// reset camera cache
// Reset camera cache.
if(GLOB.camera_repository.camera_cache_id != cache_id)
cameras = null
cache_id = GLOB.camera_repository.camera_cache_id
@@ -100,12 +119,18 @@
/******************
* Assisting procs *
******************/
/**
* Returns the src's area.
*/
/atom/proc/get_alarm_area()
return get_area(src)
/area/get_alarm_area()
return src
/**
* Wrapper for get_area_display_name (no args).
*/
/atom/proc/get_alarm_name()
var/area/A = get_area(src)
var/display_name = get_area_display_name(A)
+6 -3
View File
@@ -3,9 +3,12 @@
/datum/alarm_handler
var/category = ""
var/list/datum/alarm/alarms = new // All alarms, to handle cases when an origin has been deleted with one or more active alarms
var/list/datum/alarm/alarms_assoc = new // Associative list of alarms, to efficiently acquire them based on origin.
var/list/listeners = new // A list of all objects interested in alarm changes.
// All alarms, to handle cases when an origin has been deleted with one or more active alarms
var/list/datum/alarm/alarms = new
// Associative list of alarms, to efficiently acquire them based on origin.
var/list/datum/alarm/alarms_assoc = new
// A list of all objects interested in alarm changes.
var/list/listeners = new
/datum/alarm_handler/process()
for(var/datum/alarm/A in alarms)
+6 -6
View File
@@ -1,11 +1,11 @@
/*
* Contents:
* Welding mask
* Cakehat
* Ushanka
* Pumpkin head
* Chicken mask
* Warning cone
* * Welding mask
* * Cakehat
* * Ushanka
* * Pumpkin head
* * Chicken mask
* * Warning cone
*/
/*
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Contains:
* Costume
* Misc
* * Costume
* * Misc
*/
/*
+3 -3
View File
@@ -1,8 +1,8 @@
/*
* Contains:
* Fire protection
* Bomb protection
* Radiation protection
* * Fire protection
* * Bomb protection
* * Radiation protection
*/
/*
+3 -3
View File
@@ -1,8 +1,8 @@
/*
* Contains:
* Security
* Detective
* Head of Security
* * Security
* * Detective
* * Head of Security
*/
/*
+3 -3
View File
@@ -1,9 +1,9 @@
/* Library Items
*
* Contains:
* Bookcase
* Book
* Barcode Scanner
* * Bookcase
* * Book
* * Barcode Scanner
*/
+5 -5
View File
@@ -1,11 +1,11 @@
/* Library Machines
*
* Contains:
* Borrowbook datum
* Library Public Computer
* Library Computer
* Library Scanner
* Book Binder
* * Borrowbook datum
* * Library Public Computer
* * Library Computer
* * Library Scanner
* * Book Binder
*/
/*
+1 -1
View File
@@ -41,7 +41,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new)
* WORKING :
*
* 1) Makes an associative mapping of model_keys with model
* e.g aa = /turf/unsimulated/wall{icon_state = "rock"}
* e.g aa = /turf/unsimulated/wall{icon_state = "rock"}
* 2) Read the map line by line, parsing the result (using parse_grid)
*
*/
+1 -1
View File
@@ -33,7 +33,7 @@
icon_state = "coinpress0"
/**
* If a compatible item is fed into the machine, begin conversion. Only allow one at a time.
* If a compatible item is fed into the machine, begin conversion. Only allow one at a time.
*/
/obj/machinery/mineral/rigpress/attackby(obj/item/attacking_item, mob/user)
if(!pressing)
@@ -1,11 +1,11 @@
/* Parrots!
* Contains
* Defines
* Inventory (headset stuff)
* Attack responces
* AI
* Procs / Verbs (usable by players)
* Sub-types
* * Defines
* * Inventory (headset stuff)
* * Attack responces
* * AI
* * Procs / Verbs (usable by players)
* * Sub-types
*/
/*
+36 -17
View File
@@ -1,5 +1,8 @@
// fun if you want to typecast humans/monkeys/etc without writing long path-filled lines.
/**
* Returns mob_size <= MOB_SMALL if used on a /mob/living.
*/
/proc/issmall(A)
if(A && istype(A, /mob/living))
var/mob/living/L = A
@@ -39,7 +42,6 @@
/mob/living/carbon/human/isMonkey()
return istype(species, /datum/species/monkey)
/proc/ishuman_species(A)
if(istype(A, /mob/living/carbon/human))
var/mob/living/carbon/human/H = A
@@ -148,7 +150,10 @@
/mob/living/carbon/alien/diona/is_diona()
return DIONA_NYMPH
/proc/is_mob_special(A) // determines special mobs. has restrictions on certain things, like welderbombing
/**
* Determines special mobs; places restrictions on certain things, like welderbombing.
*/
/proc/is_mob_special(A)
if(isrevenant(A))
return TRUE
if(iszombie(A))
@@ -288,7 +293,9 @@ GLOBAL_LIST_INIT(organ_rel_size, list(
BP_R_FOOT = 10
))
///Find the mob at the bottom of a buckle chain
/**
* Find the mob at the bottom of a buckle chain.
*/
/mob/proc/lowest_buckled_mob()
. = src
//buckled -> buckled_to from TG
@@ -321,9 +328,11 @@ GLOBAL_LIST_INIT(organ_rel_size, list(
zone = pick_weight(weighted_list ? weighted_list : GLOB.organ_rel_size) //Slightly different from TG, we have a list with organ sizes
return zone
/// Emulates targetting a specific body part, and miss chances
/// May return null if missed
/// miss_chance_mod may be negative.
/**
* Emulates targetting a specific body part, and miss chances.
* May return null if missed.
* miss_chance_mod can be negative.
*/
/proc/get_zone_with_miss_chance(zone, var/mob/target, var/miss_chance_mod = 0, var/ranged_attack=0, var/point_blank = FALSE)
zone = check_zone(zone)
@@ -351,7 +360,9 @@ GLOBAL_LIST_INIT(organ_rel_size, list(
return pick(GLOB.base_miss_chance)
return zone
// never a chance to miss, but you might not hit what you want to hit
/**
* No a chance to miss, but you might not hit what you want to hit.
*/
/mob/living/heavy_vehicle/calculate_zone_with_miss_chance(zone, miss_chance_mod)
var/miss_chance = 10
if(zone in GLOB.base_miss_chance)
@@ -380,6 +391,9 @@ GLOBAL_LIST_INIT(organ_rel_size, list(
chars[i] = "*"
return sanitize(jointext(chars, ""))
/**
* The speech impediment, not the other thing.
*/
/proc/slur(phrase, strength = 100)
phrase = html_decode(phrase)
var/leng = length_char(phrase)
@@ -408,13 +422,18 @@ GLOBAL_LIST_INIT(organ_rel_size, list(
if (7)
newletter += "'"
else
. = null // For dreamchecker, does nothing
. = null // For dreamchecker, does nothing.
newphrase += "[newletter]"
counter -= 1
return newphrase
/proc/Gibberish(t, p)//t is the inputted message, and any value higher than 70 for p will cause letters to be replaced instead of added
/* Turn text into complete gibberish! */
/**
* Turns text into complete gibberish.
*
* * t - inputted message
* * p - higher than 70 cause letters to be replaced instead of added
*/
/proc/Gibberish(t, p)
var/returntext = ""
for(var/i = 1, i <= length(t), i++)
@@ -430,13 +449,14 @@ GLOBAL_LIST_INIT(organ_rel_size, list(
return returntext
/**
* Stuttering. Is this even used anywhere???
*
* The difference with stutter is that this proc can stutter more than 1 letter
* The issue here is that anything that does not have a space is treated as one word (in many instances). For instance, "LOOKING," is a word, including the comma.
* It's fairly easy to fix if dealing with single letters but not so much with compounds of letters.
*/
/proc/ninjaspeak(n)
/*
The difference with stutter is that this proc can stutter more than 1 letter
The issue here is that anything that does not have a space is treated as one word (in many instances). For instance, "LOOKING," is a word, including the comma.
It's fairly easy to fix if dealing with single letters but not so much with compounds of letters./N
*/
var/te = html_decode(n)
var/t = ""
n = length(n)
@@ -459,7 +479,6 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
p=p+n_mod
return sanitize(t)
#define TICKS_PER_RECOIL_ANIM 2
#define PIXELS_PER_STRENGTH_VAL 16
@@ -58,7 +58,7 @@
/**
* Returns number of stored files and storage usage/capacity.
* Returns number of stored files and storage usage/capacity.
*/
/obj/item/computer_hardware/hard_drive/diagnostics(var/mob/user)
..()
@@ -67,7 +67,7 @@
to_chat(user, SPAN_NOTICE("Storage capacity: [used_capacity]/[max_capacity]GQ"))
/**
* Use this proc to add file to the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks.
* Use this proc to add file to the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks.
*/
/obj/item/computer_hardware/hard_drive/proc/store_file(var/datum/computer_file/F)
if(!F || !istype(F))
@@ -89,7 +89,7 @@
return TRUE
/**
* Use this proc to add all basic functionality software to the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks.
* Use this proc to add all basic functionality software to the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks.
*/
/obj/item/computer_hardware/hard_drive/proc/install_default_programs()
if(parent_computer)
@@ -98,7 +98,7 @@
store_file(new /datum/computer_file/program/pai_access_lock(parent_computer)) // pAI access control, to stop pesky pAI from messing with computers
/**
* Use this proc to remove files to the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks.
* Use this proc to remove files to the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks.
*/
/obj/item/computer_hardware/hard_drive/proc/remove_file(var/datum/computer_file/F)
if(!F || !istype(F))
@@ -115,7 +115,7 @@
return FALSE
/**
* Loops through all stored files and recalculates used_capacity of this drive
* Loops through all stored files and recalculates used_capacity of this drive
*/
/obj/item/computer_hardware/hard_drive/proc/recalculate_size()
var/total_size = 0
@@ -124,7 +124,7 @@
used_capacity = total_size
/**
* Checks whether file can be stored on the hard drive.
* Checks whether file can be stored on the hard drive.
*/
/obj/item/computer_hardware/hard_drive/proc/can_store_file(var/size = TRUE)
// In the unlikely event someone manages to create that many files.
@@ -139,7 +139,7 @@
return TRUE
/**
* Checks whether we can store the file. We can only store unique files, so this checks whether we wouldn't get a duplicity by adding a file.
* Checks whether we can store the file. We can only store unique files, so this checks whether we wouldn't get a duplicity by adding a file.
*/
/obj/item/computer_hardware/hard_drive/proc/try_store_file(var/datum/computer_file/F)
if(!F || !istype(F))
@@ -151,7 +151,7 @@
return can_store_file(F.size)
/**
* Tries to find the file by filename. Returns null on failure.
* Tries to find the file by filename. Returns null on failure.
*/
/obj/item/computer_hardware/hard_drive/proc/find_file_by_name(var/filename)
if(!check_functionality())
@@ -23,19 +23,19 @@
var/malfunction_probability = 10
/**
* Default handling of hardware enable/disable. Override for specific functionality.
* Default handling of hardware enable/disable. Override for specific functionality.
*/
/obj/item/computer_hardware/proc/enable()
. = enabled = TRUE
/**
* Default handling of hardware enable/disable. Override for specific functionality.
* Default handling of hardware enable/disable. Override for specific functionality.
*/
/obj/item/computer_hardware/proc/disable()
. = enabled = FALSE
/**
* Default handling of hardware enable/disable. Override for specific functionality.
* Default handling of hardware enable/disable. Override for specific functionality.
*/
/obj/item/computer_hardware/proc/toggle()
if(enabled)
@@ -71,7 +71,7 @@
return ..()
/**
* Called on multitool click, prints diagnostic information to the user.
* Called on multitool click, prints diagnostic information to the user.
*/
/obj/item/computer_hardware/proc/diagnostics(var/mob/user)
to_chat(user, SPAN_NOTICE("Hardware Integrity Test... (Physical Damage: [damage]/[max_damage]) [damage > damage_failure ? "FAIL" : damage > damage_malfunction ? "WARN" : "PASS"]"))
@@ -88,7 +88,7 @@
return ..()
/**
* Handles damage checks
* Handles damage checks
*/
/obj/item/computer_hardware/proc/check_functionality()
/// Turned off
@@ -114,7 +114,7 @@
. += SPAN_WARNING("It seems to be slightly damaged.")
/**
* Damages the component. Contains necessary checks. Negative damage "heals" the component.
* Damages the component. Contains necessary checks. Negative damage "heals" the component.
*/
/obj/item/computer_hardware/proc/take_damage(var/amount)
damage += round(amount) /// We want nice rounded numbers here.
+3 -3
View File
@@ -1,8 +1,8 @@
/* Filing cabinets!
* Contains:
* Filing Cabinets
* Security Record Cabinets
* Medical Record Cabinets
* * Filing Cabinets
* * Security Record Cabinets
* * Medical Record Cabinets
*/
+6 -6
View File
@@ -1,11 +1,11 @@
/* Pens!
* Contains:
* Pens
* PDA Pens
* Sleepy Pens
* Coloured Pens
* Parapens
* Fountain Pens
* * Pens
* * PDA Pens
* * Sleepy Pens
* * Coloured Pens
* * Parapens
* * Fountain Pens
*/
+5 -5
View File
@@ -1,9 +1,9 @@
/* Photography!
* Contains:
* Camera
* Camera Film
* Photos
* Photo Albums
* Contains:
* * Camera
* * Camera Film
* * Photos
* * Photo Albums
*/
/*******
+16 -8
View File
@@ -84,20 +84,24 @@ ABSTRACT_TYPE(/obj/machinery/power/apc)
var/area/area
var/areastring = null
var/obj/item/cell/cell
var/chargelevel = 0.0005 // Cap for how fast APC cells charge, as a percentage-per-tick (0.01 means cellcharge is capped to 1% per second)
/// Cap for how fast APC cells charge, as a percentage-per-tick (0.01 means cellcharge is capped to 1% per second)
var/chargelevel = 0.0005
var/cellused = 0
var/start_charge = 90 // initial cell charge %
/// Initial cell charge %
var/start_charge = 90
var/cell_type = /obj/item/cell/apc
var/opened = COVER_CLOSED
var/shorted = FALSE
var/night_mode = FALSE// Determines if the light level is set to dimmed or not
/// Determines if the light level is set to dimmed or not
var/night_mode = FALSE
var/lighting = CHANNEL_ON_AUTO
var/equipment = CHANNEL_ON_AUTO
var/environ = CHANNEL_ON_AUTO
var/infected = FALSE
var/operating = TRUE
var/charging = CHARGING_OFF
var/chargemode = TRUE // whether we're trying to charge
// Whether we're trying to charge
var/chargemode = TRUE
var/chargecount = 0
var/locked = TRUE
var/coverlocked = TRUE
@@ -110,11 +114,14 @@ ABSTRACT_TYPE(/obj/machinery/power/apc)
var/lastused_charging = 0
var/lastused_total = 0
var/main_status = 0
var/mob/living/silicon/ai/hacker = null // Malfunction var. If set AI hacked the APC and has full control.
powernet = 0 // set so that APCs aren't found as powernet nodes //Hackish, Horrible, was like this before I changed it :c
/// Malfunction var. If set AI hacked the APC and has full control.
var/mob/living/silicon/ai/hacker = null
/// Set so that APCs aren't found as powernet nodes. Hackish, Horrible, was like this before I changed it :c
powernet = 0
var/autoflag = AUTOFLAG_OFF
var/has_electronics = HAS_ELECTRONICS_NONE
var/beenhit = 0 // used for counting how many times it has been hit, used for Aliens at the moment
/// Used for counting how many times it has been hit, used for Aliens at the moment
var/beenhit = 0
var/longtermpower = 10
var/datum/wires/apc/wires = null
var/update_state = -1
@@ -133,7 +140,8 @@ ABSTRACT_TYPE(/obj/machinery/power/apc)
var/emergency_lights = FALSE
var/time = 0
var/charge_mode = CHARGE_MODE_CHARGE // if we're actually able to charge
/// If we're actually able to charge
var/charge_mode = CHARGE_MODE_CHARGE
var/last_time = 1
/obj/machinery/power/apc/mechanics_hints(mob/user, distance, is_adjacent)
+11 -1
View File
@@ -10,7 +10,8 @@
density = TRUE
use_power = POWER_USE_IDLE
idle_power_usage = 50
active_power_usage = 500 //multiplied by field strength
/// Gets multiplied by field strength
active_power_usage = 500
anchored = FALSE
var/obj/effect/fusion_em_field/owned_field
@@ -25,11 +26,17 @@
connect_to_network()
AddComponent(/datum/component/local_network_member, initial_id_tag)
/**
* If there's no powernet or no owned field, shutdown() in those cases too.
*/
/obj/machinery/power/fusion_core/process()
. = ..()
if(stat & BROKEN || !powernet || !owned_field)
Shutdown()
/**
* Create a new owned_field of appropriate strength and update power usage.
*/
/obj/machinery/power/fusion_core/proc/Startup()
if(owned_field)
return
@@ -39,6 +46,9 @@
update_use_power(POWER_USE_ACTIVE)
. = 1
/**
* If we're too hot, there's going to be an explosion, EMP, etc. Bad time.
*/
/obj/machinery/power/fusion_core/proc/Shutdown(force_rupture)
if(owned_field)
icon_state = "core0"
+79 -12
View File
@@ -12,12 +12,15 @@
light_color = COLOR_RED
mouse_opacity = MOUSE_OPACITY_ICON
var/size = 1
var/energy = 0
var/plasma_temperature = 0
var/radiation = 0
/// The currently configured Field Strength (0.01 = 1 Tesla).
var/field_strength = 0.01
/// Radius of the EM field. Scales with Field Strength.
var/size = 1
var/tick_instability = 0
/// Ranges from 0-1. At or over 1, boom.
var/percent_unstable = 0
var/percent_unstable_archive = 0
@@ -88,7 +91,7 @@
particles.spawning = 0 //Turn off particles until something calls for it
//create the gimmicky things to handle field collisions
// Create the gimmicky things to handle field collisions
var/obj/effect/fusion_particle_catcher/catcher
catcher = new (locate(src.x,src.y,src.z))
@@ -124,6 +127,9 @@
addtimer(CALLBACK(src, PROC_REF(update_light_colors)), 10 SECONDS, TIMER_LOOP)
radio = new /obj/item/device/radio{channels=list("Engineering")}(src)
/**
* Not blackbody radiation- with these colors, is some sort of space magic?
*/
/obj/effect/fusion_em_field/proc/update_light_colors()
var/use_range
var/use_power = 0
@@ -164,6 +170,16 @@
UNLINT(var/dm_filter/bloom = filters[3])
UNLINT(bloom.alpha = alpha)
/**
* What are we doing every tick? A lot.
* * Grab some gas from the env and convert it to reactants for the pool.
* * Run react(), which updates a ton of vars for us to respond to here.
* * Based on our updated heat values, dump power into the power net.
* * Calculate what sort of entropy tax we're going to pay.
* * Run check_instability() and decide how sad/angry we are.
* * If we're sad/angry, try to send a warning.
* * Run radiate(). This is us paying the entropy tax.
*/
/obj/effect/fusion_em_field/process()
//make sure the field generator is still intact
if(QDELETED(owned_core))
@@ -184,19 +200,19 @@
if(added_particles)
uptake_gas.update_values()
//let the particles inside the field react
// Let the particles inside the field react.
React()
// Dump power to our powernet.
owned_core.add_avail(FUSION_ENERGY_PER_K * plasma_temperature)
// Energy decay.
// Energy decay (entropy tax).
if(plasma_temperature >= 1)
var/lost = plasma_temperature*0.01
radiation += lost
plasma_temperature -= lost
//handle some reactants formatting
// Handle some reactants formatting.
for(var/reactant in reactants)
var/amount = reactants[reactant]
if(amount < 1)
@@ -217,6 +233,19 @@
SSradiation.radiate(src, round(radiation*0.001))
return 1
/**
* Handles checks for instability, does bad things if unstable. Instability
* ranges from 0 to 1.
*
* Possible consequences:
* * Field wobbles/ripples (visual only)
* * Fuel loss (rad spikes)
* * Flares (bigger rad spikes, bigger wobbles/ripples)
* * Rupture (you're fucked, we done)
*
* If instability hits 1, boom. Otherwise, this code looks fucked up, best
* document details later.
*/
/obj/effect/fusion_em_field/proc/check_instability()
if(tick_instability > 0)
percent_unstable_archive = percent_unstable
@@ -245,6 +274,7 @@
var/flare
var/fuel_loss
var/rupture
// Why the fuck are these less thans???
if(percent_unstable < 0.7)
visible_message(SPAN_DANGER("\The [src] ripples uneasily, like a disturbed pond."))
fuel_loss = prob(5)
@@ -323,6 +353,9 @@
radio.autosay(alert_msg, "INDRA Reactor Monitor")
public_alert = FALSE
/**
* Handles visual animation.
*/
/obj/effect/fusion_em_field/proc/Ripple(_size, _radius)
if(!animating_ripple)
UNLINT(var/dm_filter/ripple = filters[1])
@@ -338,6 +371,9 @@
/obj/effect/fusion_em_field/proc/is_shutdown_safe()
return plasma_temperature < 1000
/**
* EMP, rads, and a big fuckoff explosion.
*/
/obj/effect/fusion_em_field/proc/Rupture()
visible_message(SPAN_DANGER("\The [src] shudders like a dying animal before flaring to eye-searing brightness and rupturing!"))
set_light(1, 0.1, 15, 2, "#ccccff")
@@ -347,6 +383,10 @@
explosion(get_turf(owned_core), 8, 8)
return
/**
* Sets field strength in Tesla, and corresponding field size.
* This currently does nothing mechanically, and the UI locks us to 100 max strength anyway.
*/
/obj/effect/fusion_em_field/proc/ChangeFieldStrength(new_strength)
var/calc_size = 1
if(new_strength <= 50)
@@ -384,9 +424,10 @@
reactants[name] = quantity
UpdateVisuals()
/**
* Create our plasma field and dump it into our environment.
*/
/obj/effect/fusion_em_field/proc/RadiateAll(ratio_lost = 1)
// Create our plasma field and dump it into our environment.
var/turf/T = get_turf(src)
if(istype(T))
var/datum/gas_mixture/plasma
@@ -395,7 +436,8 @@
continue
if(!plasma)
plasma = new
plasma.adjust_gas(reactant, max(1,round(reactants[reactant]*0.1)), 0) // *0.1 to compensate for *10 when uptaking gas.
// *0.1 to compensate for *10 when uptaking gas.
plasma.adjust_gas(reactant, max(1,round(reactants[reactant]*0.1)), 0)
if(!plasma)
return
plasma.temperature = (plasma_temperature/2)
@@ -414,6 +456,22 @@
SSradiation.radiate(src, round(radiation*0.001))
Radiate()
/**
* Called as part of our regular Process()
*
* First, it checks if our current size is intersecting with any
* offending objects. If it is... Well, it won't be for long, since it'll
* probably blow up the entire reactor in about 5 seconds.
*
* After that, it'll return the air it stole this tick, just heated up.
* The max temperature is capped so it can't be used for TEGs or shit.
*
* I don't know why radiation is set to 0 after that, because it means
* that the INDRA is COMPLETELY radiation-free short of exploding it.
*
* Probably need to delete radiation = 0 after testing it doesn't generate
* unreasonable amounts of rads with current values.
*/
/obj/effect/fusion_em_field/proc/Radiate()
if(istype(loc, /turf))
for(var/atom/movable/AM in range(max(1,FLOOR(size/2, 1)), loc))
@@ -435,7 +493,8 @@
if(owned_core && owned_core.loc)
var/datum/gas_mixture/environment = owned_core.loc.return_air()
if(environment && environment.temperature < (T0C+1000)) // Putting an upper bound on it to stop it being used in a TEG.
// Putting an upper bound on it to stop it being used in a TEG.
if(environment && environment.temperature < (T0C+1000))
environment.add_thermal_energy(plasma_temperature*20000)
radiation = 0
@@ -450,13 +509,21 @@
catcher.UpdateSize()
return changed
//the !!fun!! part
/**
* The !!fun!! part.
*
* Read through the whole code for actual details please, but TLDR:
* * Maximum of 10000 reactants present in the pool at a given time.
* * A random number of reactants are chosen to react in a given cycle.
* * Reactions follow a priority list- IE deut+trit before deut+deut.
* *
*/
/obj/effect/fusion_em_field/proc/React()
//loop through the reactants in random order
// Loop through the reactants in random order
var/list/react_pool = reactants.Copy()
last_reactants = 0
//cant have any reactions if there aren't any reactants present
// Can't have any reactions if there aren't any reactants present
if(length(react_pool))
//determine a random amount to actually react this cycle, and remove it from the standard pool
//this is a hack, and quite nonrealistic :(
+27 -10
View File
@@ -1,12 +1,18 @@
// Describes a point source of radiation. Created either in response to a pulse of radiation, or over an irradiated atom.
// Sources will decay over time, unless something is renewing their power!
/datum/radiation_source
var/turf/source_turf // Location of the radiation source.
var/rad_power // Strength of the radiation being emitted.
var/decay = TRUE // True for automatic decay. False if owner promises to handle it (i.e. supermatter)
var/respect_maint = FALSE // True for not affecting AREA_FLAG_RAD_SHIELDED areas.
var/flat = FALSE // True for power falloff with distance.
var/range // Cached maximum range, used for quick checks against mobs.
/// Location of the radiation source.
var/turf/source_turf
/// Strength of the radiation being emitted.
var/rad_power
/// True for automatic decay. False if owner promises to handle it (i.e. Supermatter, INDRA, etc.)
var/decay = TRUE
/// True for not affecting AREA_FLAG_RAD_SHIELDED areas.
var/respect_rad_shielding = FALSE
/// True for power falloff with distance.
var/flat = FALSE
/// Cached maximum range, used for quick checks against mobs.
var/range
/datum/radiation_source/New(source_turf, rad_power, decay = TRUE)
src.source_turf = source_turf
@@ -20,6 +26,9 @@
src.source_turf = null
. = ..()
/**
* Initialization handling decaying sources. Decrease by RADIATION_DECAY_RATE per SSradiation.fire() in latter cases.
*/
/datum/radiation_source/proc/update_rad_power(new_power = null)
if(new_power == null || new_power == rad_power)
return // No change
@@ -28,7 +37,8 @@
else
rad_power = new_power
if(!flat)
range = min(round(sqrt(rad_power / RADIATION_LOWER_LIMIT)), 31) // R = rad_power / dist**2 - Solve for dist
// R = rad_power / dist**2 - Solve for dist
range = min(round(sqrt(rad_power / RADIATION_LOWER_LIMIT)), 31)
/turf/var/cached_rad_resistance = 0
@@ -47,7 +57,8 @@
cached_rad_resistance = (density ? material.weight / RADIATION_MATERIAL_RESISTANCE_DIVISOR : 0)
/obj
var/rad_resistance_modifier = 1 // Allow overriding rad resistance
/// Allow overriding rad resistance.
var/rad_resistance_modifier = 1
/**
* Retrieves the atom's current radiation level. By default, this will return `loc.get_rads()`.
@@ -65,14 +76,20 @@
/**
* Called when radiation affects the atom.
*
* **Parameters**:
* - `severity` - The amount of radiation being applied. Also see `RAD_LEVEL_*`.
* * severity - The amount of radiation being applied. Also see RAD_LEVEL_*.
*
* Returns boolean
*/
/atom/proc/rad_act(severity)
return 1
/**
* Called when radiation affects a /mob/living.
*
* * severity - The amount of radiation being applied. Anything over RAD_LEVEL_LOW will deal [severity] dispersed damage and run rad_act to everything in it.
*
* Returns boolean
*/
/mob/living/rad_act(severity)
if(severity > RAD_LEVEL_LOW)
apply_damage(severity, DAMAGE_RADIATION, damage_flags = DAMAGE_FLAG_DISPERSED)
@@ -1200,19 +1200,19 @@
var/list/goodmessage_species
/**
* We leave goodmessage_species null so no unnecessary checks are performed for most reagents. However, if we want a given reagent to have unique
* messages for consumers of a given species, its value can be set as below within the singleton/reagent/mental:
* We leave goodmessage_species null so no unnecessary checks are performed for most reagents. However, if we want a given reagent to have unique
* messages for consumers of a given species, its value can be set as below within the singleton/reagent/mental:
*
* goodmessage_species = list(
* SPECIES_HUMAN = list("Damn you're high.","You're totally zooted!"),
* SPECIES_HUMAN_OFFWORLD = list("Damn you're WAY higher than normal humans. Like, you might even say outside the gravity well high.", "Zooted bo booted boyyy."),
* SPECIES_UNATHI = list("You feel like shit and want to die.","Why the fuck did you smoke that shitty human stuff."),
* SPECIES_SKRELL = list("Aaaaaaaaaaaa!","Aaaauuuuaaaa!","Waaaoouuuuaaaaahhh!"),
* SPECIES_SKRELL_AXIORI = list("If you weren't axiori you'd probably be having a bad time but you're pretty zooted.")
* )
* goodmessage_species = list(
* SPECIES_HUMAN = list("Damn you're high.","You're totally zooted!"),
* SPECIES_HUMAN_OFFWORLD = list("Damn you're WAY higher than normal humans. Like, you might even say outside the gravity well high.", "Zooted bo booted boyyy."),
* SPECIES_UNATHI = list("You feel like shit and want to die.","Why the fuck did you smoke that shitty human stuff."),
* SPECIES_SKRELL = list("Aaaaaaaaaaaa!","Aaaauuuuaaaa!","Waaaoouuuuaaaaahhh!"),
* SPECIES_SKRELL_AXIORI = list("If you weren't axiori you'd probably be having a bad time but you're pretty zooted.")
* )
*
* No, there's not support right now for things like ALL_DIONA_SPECIES. Once somebody wants to make Vaurca-only drugs, they will probably
* implement support for it out of sheer annoyance though.
* No, there's not support right now for things like ALL_DIONA_SPECIES. Once somebody wants to make Vaurca-only drugs, they will probably
* implement support for it out of sheer annoyance though.
*/
fallback_specific_heat = 1.5
@@ -1239,8 +1239,8 @@
/**
* Holds logic for returning feedback message strings based on race.
* 'goodmessage' is your generic catch-all list of message strings.
* 'goodmessage_species', if set, will override the 'goodmessage' list only for that species.
* 'goodmessage' is your generic catch-all list of message strings.
* 'goodmessage_species', if set, will override the 'goodmessage' list only for that species.
*/
/singleton/reagent/mental/proc/feedback_message(var/mob/living/carbon/human/mob)
var/mob_species = mob.get_species()
+67 -67
View File
@@ -1,11 +1,11 @@
/**
* Disposal bin
* Holds items for disposal into pipe system
* Draws air from turf, gradually charges internal reservoir
* Once full (~1 atm), uses air resv to flush items into the pipes
* Automatically recharges air (unless off), will flush when ready if pre-set
* Can hold items and human size things, no other draggables
* Toilets are a type of disposal bin for small objects only and work on magic. By magic, I mean torque rotation
* Disposal bin
* Holds items for disposal into pipe system
* Draws air from turf, gradually charges internal reservoir
* Once full (~1 atm), uses air resv to flush items into the pipes
* Automatically recharges air (unless off), will flush when ready if pre-set
* Can hold items and human size things, no other draggables
* Toilets are a type of disposal bin for small objects only and work on magic. By magic, I mean torque rotation
*/
/// kPa - assume the inside of a dispoal pipe is 1 atm, so that needs to be added.
@@ -104,8 +104,8 @@
return TRUE
/**
* Create a new disposal:
* Find the attached trunk (if present), and initialize gas reservoir.
* Create a new disposal:
* Find the attached trunk (if present), and initialize gas reservoir.
*/
/obj/machinery/disposal/Initialize()
. = ..()
@@ -138,7 +138,7 @@
return things
/**
* Attack by an item places it into the disposal.
* Attack by an item places it into the disposal.
*/
/obj/machinery/disposal/attackby(obj/item/attacking_item, mob/user)
if(stat & BROKEN || !attacking_item || !user)
@@ -261,7 +261,7 @@
update()
/**
* Handles mouse-dropping another mob or self onto disposal.
* Handles mouse-dropping another mob or self onto disposal.
*/
/obj/machinery/disposal/mouse_drop_receive(atom/dropped, mob/user, params)
var/mob/target = dropped
@@ -329,7 +329,7 @@
return 1
/**
* Attempt to move while inside.
* Attempt to move while inside.
*/
/obj/machinery/disposal/relaymove(mob/living/user, direction)
. = ..()
@@ -341,7 +341,7 @@
return
/**
* Leave the disposal.
* Leave the disposal.
*/
/obj/machinery/disposal/proc/go_out(mob/user)
@@ -353,7 +353,7 @@
return
/**
* AI: as human but can't flush.
* AI: as human but can't flush.
*/
/obj/machinery/disposal/attack_ai(mob/user as mob)
if(!ai_can_interact(user))
@@ -362,7 +362,7 @@
interact(user, !inside_bin)
/**
* Human interacts with machine.
* Human interacts with machine.
*/
/obj/machinery/disposal/attack_hand(mob/user as mob)
if(stat & BROKEN)
@@ -424,7 +424,7 @@
. = TRUE
/**
* Eject the contents of the disposal unit.
* Eject the contents of the disposal unit.
*/
/obj/machinery/disposal/proc/eject()
for(var/atom/movable/AM in src)
@@ -433,7 +433,7 @@
update()
/**
* Update the icon & overlays to reflect mode & status
* Update the icon & overlays to reflect mode & status
*/
/obj/machinery/disposal/proc/update()
ClearOverlays()
@@ -462,7 +462,7 @@
AddOverlays("[icon_state]-ready")
/**
* Timed process. Charge the gas reservoir and perform flush if ready.
* Timed process. Charge the gas reservoir and perform flush if ready.
*/
/obj/machinery/disposal/process()
if((stat & BROKEN) || !is_on)
@@ -502,7 +502,7 @@
return
/**
* If powered and working, transfer gas from local env to internal reservoir and use the required power to do so.
* If powered and working, transfer gas from local env to internal reservoir and use the required power to do so.
*/
/obj/machinery/disposal/proc/pressurize()
// Don't pressurize if there's no power.
@@ -528,7 +528,7 @@
mode = MODE_READY
/**
* Attempt to flush. If able, create a virtual holder object containing disposal bin & gas reservoir contents to ship through disposals network
* Attempt to flush. If able, create a virtual holder object containing disposal bin & gas reservoir contents to ship through disposals network
*/
/obj/machinery/disposal/proc/flush()
set waitfor = FALSE
@@ -583,7 +583,7 @@
return
/**
* Called when area power changes.
* Called when area power changes.
*/
/obj/machinery/disposal/power_change()
// do default setting/reset of stat NOPOWER bit
@@ -593,7 +593,7 @@
return
/**
* Called when holder is expelled from a disposal- should usually only occur if the pipe network is modified
* Called when holder is expelled from a disposal- should usually only occur if the pipe network is modified
*/
/obj/machinery/disposal/proc/expel(var/obj/disposalholder/H)
@@ -637,10 +637,10 @@
/**
* Virtual disposal object
* Travels through pipes in lieu of actual items
* Contents will be items flushed by the disposal
* This allows the gas flushed to be tracked
* Virtual disposal object
* Travels through pipes in lieu of actual items
* Contents will be items flushed by the disposal
* This allows the gas flushed to be tracked
*/
/obj/disposalholder
invisibility = 101
@@ -662,7 +662,7 @@
var/tmp/obj/structure/disposalpipe/tick_last
/**
* Initialize a holder from the contents of a disposal unit.
* Initialize a holder from the contents of a disposal unit.
*/
/obj/disposalholder/proc/init(var/obj/machinery/disposal/D, var/datum/gas_mixture/flush_gas)
gas = flush_gas// transfer gas resv. into holder object -- let's be explicit about the data this proc consumes, please.
@@ -702,8 +702,8 @@
/**
* Start the movement process
* Argument is the disposal unit the holder started in
* Start the movement process
* Argument is the disposal unit the holder started in
*/
/obj/disposalholder/proc/start(var/obj/machinery/disposal/D)
// No trunk connected, so expel immediately
@@ -716,7 +716,7 @@
START_PROCESSING(SSdisposals, src)
/**
* For the new SSdisposals-based movement.
* For the new SSdisposals-based movement.
*/
/obj/disposalholder/process()
if (hasmob && prob(3))
@@ -751,13 +751,13 @@
tick_last = null
/**
* Find the turf which should contain the next pipe
* Find the turf which should contain the next pipe
*/
/obj/disposalholder/proc/nextloc()
return get_step(loc,dir)
/**
* Find a matching pipe on a turf
* Find a matching pipe on a turf
*/
/obj/disposalholder/proc/findpipe(var/turf/T)
if(!T)
@@ -773,7 +773,7 @@
return null
/**
* Merge two holder objects. Used when a a holder meets a stuck holder.
* Merge two holder objects. Used when a a holder meets a stuck holder.
*/
/obj/disposalholder/proc/merge(obj/disposalholder/other)
for(var/atom/movable/AM in other)
@@ -798,7 +798,7 @@
partialTag = new_tag
/**
* Called when player tries to move while in a pipe.
* Called when player tries to move while in a pipe.
*/
/obj/disposalholder/relaymove(mob/living/user, direction)
. = ..()
@@ -820,7 +820,7 @@
playsound(src.loc, 'sound/effects/clang.ogg', 50, 0, 0)
/**
* Called to vent all gas in holder to a location
* Called to vent all gas in holder to a location
*/
/obj/disposalholder/proc/vent_gas(atom/location)
location.assume_air(gas) // vent all gas to turf
@@ -859,7 +859,7 @@
LAZYADD(T.blueprints, I)
/**
* Pipe is deleted. Ensure if holder is present, it is expelled.
* Pipe is deleted. Ensure if holder is present, it is expelled.
*/
/obj/structure/disposalpipe/Destroy()
var/obj/disposalholder/H = locate() in src
@@ -884,15 +884,15 @@
return ..()
/**
* Returns the direction of the next pipe object, given the entrance dir
* By default, returns the bitmask of remaining directions
* Returns the direction of the next pipe object, given the entrance dir
* By default, returns the bitmask of remaining directions
*/
/obj/structure/disposalpipe/proc/nextdir(var/fromdir)
return dpdir & (~turn(fromdir, 180))
/**
* Transfer the holder through this pipe segment
* Overriden for special behaviour
* Transfer the holder through this pipe segment
* Overriden for special behaviour
*/
/obj/structure/disposalpipe/proc/transfer(var/obj/disposalholder/H)
var/nextdir = nextdir(H.dir)
@@ -914,22 +914,22 @@
return P
/**
* Update the icon_state to reflect hidden status
* Update the icon_state to reflect hidden status
*/
/obj/structure/disposalpipe/proc/update()
var/turf/T = src.loc
hide(!T.is_plating() && !istype(T,/turf/space)) // space never hides pipes
/**
* Hide called by levelupdate if turf intact status changes
* Change visibility status and force update of icon
* Hide called by levelupdate if turf intact status changes
* Change visibility status and force update of icon
*/
/obj/structure/disposalpipe/hide(var/intact)
set_invisibility(intact ? 101: 0) // hide if floor is intact
/**
* Expel the held objects into a turf
* Called when there is a break in the pipe
* Expel the held objects into a turf
* Called when there is a break in the pipe
*/
/obj/structure/disposalpipe/proc/expel(var/obj/disposalholder/H, var/turf/T, var/direction)
if(!istype(H) || !istype(T))
@@ -981,8 +981,8 @@
/**
* Call to break the pipe: will expel any holder inside at the time then delete the pipe
* remains: Set to leave broken pipe pieces in place.
* Call to break the pipe: will expel any holder inside at the time then delete the pipe
* remains: Set to leave broken pipe pieces in place.
*/
/obj/structure/disposalpipe/proc/broken(var/remains = 0)
if(remains)
@@ -1015,7 +1015,7 @@
/**
* Pipe is affected by an explosion
* Pipe is affected by an explosion
*/
/obj/structure/disposalpipe/ex_act(severity)
switch(severity)
@@ -1033,7 +1033,7 @@
/**
* Test pipe's health. Am I broken?
* Test pipe's health. Am I broken?
*/
/obj/structure/disposalpipe/proc/healthcheck()
if(health < -2)
@@ -1042,8 +1042,8 @@
broken(1)
/**
* Attack by item
* Welding tool: Unfasten and convert to obj/disposalconstruct
* Attack by item
* Welding tool: Unfasten and convert to obj/disposalconstruct
*/
/obj/structure/disposalpipe/attackby(obj/item/attacking_item, mob/user)
var/turf/T = src.loc
@@ -1066,7 +1066,7 @@
to_chat(user, "You need more welding fuel to cut the pipe.")
/**
* Called when pipe is cut by a welder.
* Called when pipe is cut by a welder.
*/
/obj/structure/disposalpipe/proc/welded()
var/obj/structure/disposalconstruct/C = new (src.loc)
@@ -1249,9 +1249,9 @@
update()
/*
* Next direction to move:
* If coming in from secondary dirs, then next is primary dir.
* If coming in from primary dir, then next is equal chance of other dirs.
* Next direction to move:
* If coming in from secondary dirs, then next is primary dir.
* If coming in from primary dir, then next is equal chance of other dirs.
*/
/obj/structure/disposalpipe/junction/nextdir(var/fromdir)
var/flipdir = turn(fromdir, 180)
@@ -1394,10 +1394,10 @@
return sortType == checkTag
/**
* Next direction to move:
* If coming in from negdir, then next is primary dir or sortdir.
* If coming in from posdir, then flip around and go back to posdir.
* If coming in from sortdir, go to posdir.
* Next direction to move:
* If coming in from negdir, then next is primary dir or sortdir.
* If coming in from posdir, then flip around and go back to posdir.
* If coming in from sortdir, go to posdir.
*/
/obj/structure/disposalpipe/sortjunction/nextdir(var/fromdir, var/sortTag)
if(fromdir != sortdir) // probably came from the negdir
@@ -1483,7 +1483,7 @@
update()
/**
* Override attackby so we disallow trunkremoval when somethings ontop
* Override attackby so we disallow trunkremoval when somethings ontop
*/
/obj/structure/disposalpipe/trunk/attackby(obj/item/attacking_item, mob/user)
@@ -1525,8 +1525,8 @@
to_chat(user, "You need more welding fuel to cut the pipe.")
/*
* Would transfer to next pipe segment, but we are in a trunk.
* If not entering from disposal bin, transfer to linked object (outlet or bin)
* Would transfer to next pipe segment, but we are in a trunk.
* If not entering from disposal bin, transfer to linked object (outlet or bin)
*/
/obj/structure/disposalpipe/trunk/transfer(var/obj/disposalholder/H)
@@ -1570,8 +1570,8 @@
update()
/**
* Called when welded
* For broken pipe, remove and turn into scrap
* Called when welded
* For broken pipe, remove and turn into scrap
*/
/obj/structure/disposalpipe/broken/welded()
// var/obj/item/scrap/S = new(src.loc)
@@ -1698,14 +1698,14 @@
return
/**
* Called when movable is expelled from a disposal pipe or outlet
* By default does nothing, override for special behaviour
* Called when movable is expelled from a disposal pipe or outlet
* By default does nothing, override for special behaviour
*/
/atom/movable/proc/pipe_eject(var/direction)
return
/**
* Check if mob has client, if so restore client view on eject
* Check if mob has client, if so restore client view on eject
*/
/mob/pipe_eject(var/direction)
if (src.client)