mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-20 10:37:45 +01:00
Merge branch 'master' into Arokha/machinerybreak
This commit is contained in:
@@ -44,10 +44,10 @@
|
||||
// TODO - Make these in actual icon states so its not silly like this
|
||||
var/image/I = image(icon = icon, icon_state = "algae-pipe-overlay", dir = dir)
|
||||
I.color = PIPE_COLOR_BLUE
|
||||
overlays += I
|
||||
add_overlay(I)
|
||||
I = image(icon = icon, icon_state = "algae-pipe-overlay", dir = reverse_dir[dir])
|
||||
I.color = PIPE_COLOR_BLACK
|
||||
overlays += I
|
||||
add_overlay(I)
|
||||
|
||||
/obj/machinery/atmospherics/binary/algae_farm/Destroy()
|
||||
. = ..()
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
if(!check_icon_cache())
|
||||
return
|
||||
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
|
||||
var/vent_icon = "vent"
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
else
|
||||
vent_icon += "[use_power ? "[pump_direction ? "out" : "in"]" : "off"]"
|
||||
|
||||
overlays += icon_manager.get_atmos_icon("device", , , vent_icon)
|
||||
add_overlay(icon_manager.get_atmos_icon("device", , , vent_icon))
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/update_underlays()
|
||||
if(..())
|
||||
|
||||
@@ -73,15 +73,15 @@
|
||||
network2.update = 1
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/update_icon()
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
if (dP > 10)
|
||||
overlays += image('icons/obj/pipeturbine.dmi', "moto-turb")
|
||||
add_overlay(image('icons/obj/pipeturbine.dmi', "moto-turb"))
|
||||
if (kin_energy > 100000)
|
||||
overlays += image('icons/obj/pipeturbine.dmi', "low-turb")
|
||||
add_overlay(image('icons/obj/pipeturbine.dmi', "low-turb"))
|
||||
if (kin_energy > 500000)
|
||||
overlays += image('icons/obj/pipeturbine.dmi', "med-turb")
|
||||
add_overlay(image('icons/obj/pipeturbine.dmi', "med-turb"))
|
||||
if (kin_energy > 1000000)
|
||||
overlays += image('icons/obj/pipeturbine.dmi', "hi-turb")
|
||||
add_overlay(image('icons/obj/pipeturbine.dmi', "hi-turb"))
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(W.is_wrench())
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
power_rating = 30000 //7500 W ~ 10 HP //VOREStation Edit - 30000 W
|
||||
|
||||
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY //connects to regular and supply pipes
|
||||
blocks_emissive = FALSE
|
||||
|
||||
var/area/initial_loc
|
||||
level = 1
|
||||
@@ -141,7 +142,7 @@
|
||||
if(!check_icon_cache())
|
||||
return
|
||||
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
|
||||
var/vent_icon = "vent"
|
||||
|
||||
@@ -159,7 +160,7 @@
|
||||
else
|
||||
vent_icon += "[pump_direction ? "out" : "in"]"
|
||||
|
||||
overlays += icon_manager.get_atmos_icon("device", , , vent_icon)
|
||||
add_overlay(icon_manager.get_atmos_icon("device", , , vent_icon))
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/update_underlays()
|
||||
if(..())
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
if(!check_icon_cache())
|
||||
return
|
||||
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
|
||||
var/scrubber_icon = "scrubber"
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
else
|
||||
scrubber_icon += "[use_power ? "[scrubbing ? "on" : "in"]" : "off"]"
|
||||
|
||||
overlays += icon_manager.get_atmos_icon("device", , , scrubber_icon)
|
||||
add_overlay(icon_manager.get_atmos_icon("device", , , scrubber_icon))
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/update_underlays()
|
||||
if(..())
|
||||
|
||||
@@ -53,9 +53,9 @@
|
||||
|
||||
alpha = 255
|
||||
|
||||
overlays.Cut()
|
||||
overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "cap[icon_connect_type]")
|
||||
|
||||
cut_overlays()
|
||||
add_overlay(icon_manager.get_atmos_icon("pipe", , pipe_color, "cap[icon_connect_type]"))
|
||||
|
||||
/obj/machinery/atmospherics/pipe/cap/atmos_init()
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src, dir))
|
||||
if (can_be_node(target, 1))
|
||||
|
||||
@@ -102,9 +102,9 @@
|
||||
|
||||
alpha = 255
|
||||
|
||||
overlays.Cut()
|
||||
overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type)
|
||||
overlays += icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type)
|
||||
cut_overlays()
|
||||
add_overlay(icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type))
|
||||
add_overlay(icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type))
|
||||
underlays.Cut()
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
@@ -102,9 +102,9 @@
|
||||
|
||||
alpha = 255
|
||||
|
||||
overlays.Cut()
|
||||
overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type)
|
||||
overlays += icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type)
|
||||
cut_overlays()
|
||||
add_overlay(icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type))
|
||||
add_overlay(icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type))
|
||||
underlays.Cut()
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
@@ -117,12 +117,12 @@
|
||||
|
||||
alpha = 255
|
||||
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
|
||||
if(node1 && node2)
|
||||
overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]intact[icon_connect_type]")
|
||||
add_overlay(icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]intact[icon_connect_type]"))
|
||||
else
|
||||
overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]exposed[node1?1:0][node2?1:0][icon_connect_type]")
|
||||
add_overlay(icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]exposed[node1?1:0][node2?1:0][icon_connect_type]"))
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/update_underlays()
|
||||
return
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
alpha = 255
|
||||
|
||||
overlays.Cut()
|
||||
overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal")
|
||||
cut_overlays()
|
||||
add_overlay(icon_manager.get_atmos_icon("pipe", , pipe_color, "universal"))
|
||||
underlays.Cut()
|
||||
|
||||
if (node1)
|
||||
@@ -54,8 +54,8 @@
|
||||
|
||||
alpha = 255
|
||||
|
||||
overlays.Cut()
|
||||
overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal")
|
||||
cut_overlays()
|
||||
add_overlay(icon_manager.get_atmos_icon("pipe", , pipe_color, "universal"))
|
||||
underlays.Cut()
|
||||
|
||||
if (node1)
|
||||
|
||||
+13
-11
@@ -57,14 +57,12 @@ Class Procs:
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/connection_edge/var/zone/A
|
||||
|
||||
/connection_edge/var/list/connecting_turfs = list()
|
||||
/connection_edge/var/direct = 0
|
||||
/connection_edge/var/sleeping = 1
|
||||
|
||||
/connection_edge/var/coefficient = 0
|
||||
/connection_edge
|
||||
var/zone/A
|
||||
var/list/connecting_turfs = list()
|
||||
var/direct = 0
|
||||
var/sleeping = 1
|
||||
var/coefficient = 0
|
||||
|
||||
/connection_edge/New()
|
||||
CRASH("Cannot make connection edge without specifications.")
|
||||
@@ -119,7 +117,8 @@ Class Procs:
|
||||
|
||||
|
||||
|
||||
/connection_edge/zone/var/zone/B
|
||||
/connection_edge/zone
|
||||
var/zone/B
|
||||
|
||||
/connection_edge/zone/New(zone/A, zone/B)
|
||||
|
||||
@@ -189,8 +188,11 @@ Class Procs:
|
||||
if(A == from) return B
|
||||
else return A
|
||||
|
||||
/connection_edge/unsimulated/var/turf/B
|
||||
/connection_edge/unsimulated/var/datum/gas_mixture/air
|
||||
/connection_edge/unsimulated
|
||||
var/turf/B
|
||||
|
||||
/connection_edge/unsimulated
|
||||
var/datum/gas_mixture/air
|
||||
|
||||
/connection_edge/unsimulated/New(zone/A, turf/B)
|
||||
src.A = A
|
||||
|
||||
@@ -170,7 +170,7 @@ Class Procs:
|
||||
if(T.needs_air_update) return
|
||||
tiles_to_update |= T
|
||||
#ifdef ZASDBG
|
||||
T.overlays += mark
|
||||
T.add_overlay(mark)
|
||||
#endif
|
||||
T.needs_air_update = 1
|
||||
|
||||
|
||||
+2
-2
@@ -12,8 +12,8 @@ var/image/mark = image('icons/Testing/Zone.dmi', icon_state = "mark")
|
||||
/turf/var/tmp/dbg_img
|
||||
/turf/proc/dbg(image/img, d = 0)
|
||||
if(d > 0) img.dir = d
|
||||
overlays -= dbg_img
|
||||
overlays += img
|
||||
cut_overlay(dbg_img)
|
||||
add_overlay(img)
|
||||
dbg_img = img
|
||||
|
||||
proc/soft_assert(thing,fail)
|
||||
|
||||
+2
-2
@@ -63,11 +63,11 @@ obj/var/contaminated = 0
|
||||
else
|
||||
if(!contaminated)
|
||||
contaminated = 1
|
||||
overlays += contamination_overlay
|
||||
add_overlay(contamination_overlay)
|
||||
|
||||
/obj/item/proc/decontaminate()
|
||||
contaminated = 0
|
||||
overlays -= contamination_overlay
|
||||
cut_overlay(contamination_overlay)
|
||||
|
||||
/mob/proc/contaminate()
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#define LAZYACCESSASSOC(L, I, K) L ? L[I] ? L[I][K] ? L[I][K] : null : null : null
|
||||
|
||||
// Null-safe L.Cut()
|
||||
#define LAZYCLEARLIST(L) if(L) L.Cut()
|
||||
#define LAZYCLEARLIST(L) if(L) { L.Cut(); L = null; }
|
||||
|
||||
// Reads L or an empty list if L is not a list. Note: Does NOT assign, L may be an expression.
|
||||
#define SANITIZE_LIST(L) ( islist(L) ? L : list() )
|
||||
|
||||
@@ -50,10 +50,10 @@ What is the naming convention for planes or layers?
|
||||
#define PLANE_LOOKINGGLASS_IMG -77 // For the Looking Glass holodecks
|
||||
|
||||
// OPENSPACE_PLANE reserves all planes between OPENSPACE_PLANE_START and OPENSPACE_PLANE_END inclusive
|
||||
#define OPENSPACE_PLANE -75 // /turf/simulated/open will use OPENSPACE_PLANE + z (Valid z's being 2 thru 17)
|
||||
#define OPENSPACE_PLANE -75 // /turf/simulated/open will use OPENSPACE_PLANE + z (Valid z's being 2 thru 27) //VOREStation Edit
|
||||
#define OPENSPACE_PLANE_START -73
|
||||
#define OPENSPACE_PLANE_END -58
|
||||
#define OVER_OPENSPACE_PLANE -57
|
||||
#define OPENSPACE_PLANE_END -48 //VOREStation Edit
|
||||
#define OVER_OPENSPACE_PLANE -47 //VOREStation Edit
|
||||
|
||||
// Turf Planes
|
||||
#define PLATING_PLANE -44 // Plating
|
||||
@@ -122,9 +122,21 @@ What is the naming convention for planes or layers?
|
||||
|
||||
#define PLANE_ADMIN1 3 //Purely for shenanigans (below lighting)
|
||||
#define PLANE_PLANETLIGHTING 4 //Lighting on planets
|
||||
|
||||
#define PLANE_LIGHTING 5 //Where the lighting (and darkness) lives
|
||||
#define PLANE_LIGHTING_ABOVE 6 //For glowy eyes etc. that shouldn't be affected by darkness
|
||||
#define PLANE_RUNECHAT 7
|
||||
#define LIGHTING_RENDER_TARGET "LIGHT_PLANE"
|
||||
|
||||
#define PLANE_O_LIGHTING_VISUAL 6 //For masking the lighting plane
|
||||
#define O_LIGHTING_VISUAL_RENDER_TARGET "O_LIGHT_VISUAL_PLANE"
|
||||
|
||||
#define PLANE_LIGHTING_ABOVE 7 //For glowy eyes etc. that shouldn't be affected by darkness
|
||||
#define LIGHTING_ABOVE_RENDER_TARGET "LIGHTING_ABOVE_PLANE"
|
||||
|
||||
#define PLANE_EMISSIVE 8 //Glowing lights in otherwise dark areas using overlays/sprites
|
||||
#define EMISSIVE_RENDER_TARGET "*EMISSIVE_PLANE"
|
||||
#define EMISSIVE_LAYER_UNBLOCKABLE 9999
|
||||
|
||||
#define PLANE_RUNECHAT 9
|
||||
|
||||
#define PLANE_GHOSTS 10 //Spooooooooky ghooooooosts
|
||||
#define PLANE_AI_EYE 11 //The AI eye lives here
|
||||
|
||||
+38
-1
@@ -92,6 +92,7 @@
|
||||
#define COLOR_LIGHT_VIOLET "#e7bfff"
|
||||
#define COLOR_SAN_MARINO_BLUE "#4b75ab"
|
||||
#define COLOR_OLIVE "#52613b" //VOREStation Addition
|
||||
#define COLOR_HALF_TRANSPARENT_BLACK "#0000007A"
|
||||
|
||||
#define PIPE_COLOR_GREY "#808080"
|
||||
#define PIPE_COLOR_RED "#ff0000"
|
||||
@@ -171,4 +172,40 @@
|
||||
#define COLOR_WEBHOOK_DEFAULT 0x8bbbd5 // "#8bbbd5"
|
||||
#define COLOR_WEBHOOK_GOOD 0x2ECC71 // "#2ECC71"
|
||||
#define COLOR_WEBHOOK_POOR 0xE67E22 // "#E67E22"
|
||||
#define COLOR_WEBHOOK_BAD 0xE74C3C // "#E74C3C"
|
||||
#define COLOR_WEBHOOK_BAD 0xE74C3C // "#E74C3C"
|
||||
|
||||
//Some defines to generalise colours used in lighting.
|
||||
//Important note on colors. Colors can end up significantly different from the basic html picture, especially when saturated
|
||||
#define LIGHT_COLOR_RED "#FA8282" //Warm but extremely diluted red. rgb(250, 130, 130)
|
||||
#define LIGHT_COLOR_GREEN "#64C864" //Bright but quickly dissipating neon green. rgb(100, 200, 100)
|
||||
#define LIGHT_COLOR_BLUE "#6496FA" //Cold, diluted blue. rgb(100, 150, 250)
|
||||
|
||||
#define LIGHT_COLOR_BLUEGREEN "#7DE1AF" //Light blueish green. rgb(125, 225, 175)
|
||||
#define LIGHT_COLOR_CYAN "#7DE1E1" //Diluted cyan. rgb(125, 225, 225)
|
||||
#define LIGHT_COLOR_LIGHT_CYAN "#40CEFF" //More-saturated cyan. rgb(64, 206, 255)
|
||||
#define LIGHT_COLOR_DARK_BLUE "#6496FA" //Saturated blue. rgb(51, 117, 248)
|
||||
#define LIGHT_COLOR_PINK "#E17DE1" //Diluted, mid-warmth pink. rgb(225, 125, 225)
|
||||
#define LIGHT_COLOR_YELLOW "#E1E17D" //Dimmed yellow, leaning kaki. rgb(225, 225, 125)
|
||||
#define LIGHT_COLOR_BROWN "#966432" //Clear brown, mostly dim. rgb(150, 100, 50)
|
||||
#define LIGHT_COLOR_ORANGE "#FA9632" //Mostly pure orange. rgb(250, 150, 50)
|
||||
#define LIGHT_COLOR_PURPLE "#952CF4" //Light Purple. rgb(149, 44, 244)
|
||||
#define LIGHT_COLOR_LAVENDER "#9B51FF" //Less-saturated light purple. rgb(155, 81, 255)
|
||||
|
||||
//These ones aren't a direct colour like the ones above, because nothing would fit
|
||||
#define LIGHT_COLOR_FIRE "#FAA019" //Warm orange color, leaning strongly towards yellow. rgb(250, 160, 25)
|
||||
#define LIGHT_COLOR_LAVA "#C48A18" //Very warm yellow, leaning slightly towards orange. rgb(196, 138, 24)
|
||||
#define LIGHT_COLOR_FLARE "#FA644B" //Bright, non-saturated red. Leaning slightly towards pink for visibility. rgb(250, 100, 75)
|
||||
#define LIGHT_COLOR_SLIME_LAMP "#AFC84B" //Weird color, between yellow and green, very slimy. rgb(175, 200, 75)
|
||||
#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" //Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175)
|
||||
#define LIGHT_COLOR_HALOGEN "#F0FAFA" //Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250)
|
||||
|
||||
//Lighting values used by the station lights
|
||||
#define LIGHT_COLOR_FLUORESCENT_TUBE "#E0EFFF"
|
||||
#define LIGHT_COLOR_FLUORESCENT_FLASHLIGHT "#CDDDFF"
|
||||
#define LIGHT_COLOR_INCANDESCENT_TUBE "#fffed9"
|
||||
#define LIGHT_COLOR_INCANDESCENT_BULB "#ffe7ce"
|
||||
#define LIGHT_COLOR_INCANDESCENT_FLASHLIGHT "#FFCC66"
|
||||
#define LIGHT_COLOR_NIGHTSHIFT "#EFCC86"
|
||||
|
||||
//Fake ambient occlusion filter
|
||||
#define AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, offset=3, color="#04080F80")
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
* Only elements created with the same arguments given after `id_arg_index` share an element instance
|
||||
* The arguments are the same when the text and number values are the same and all other values have the same ref
|
||||
*/
|
||||
#define ELEMENT_BESPOKE (1 << 1)
|
||||
#define ELEMENT_BESPOKE (1 << 1)
|
||||
/// Causes all detach arguments to be passed to detach instead of only being used to identify the element
|
||||
/// When this is used your Detach proc should have the same signature as your Attach proc
|
||||
#define ELEMENT_COMPLEX_DETACH (1 << 2)
|
||||
|
||||
// How multiple components of the exact same type are handled in the same datum
|
||||
/// old component is deleted (default)
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
#define COMSIG_PARENT_QDELETING "parent_qdeleting"
|
||||
/// generic topic handler (usr, href_list)
|
||||
#define COMSIG_TOPIC "handle_topic"
|
||||
/// from datum ui_act (usr, action)
|
||||
#define COMSIG_UI_ACT "COMSIG_UI_ACT"
|
||||
|
||||
|
||||
/// fires on the target datum when an element is attached to it (/datum/element)
|
||||
#define COMSIG_ELEMENT_ATTACH "element_attach"
|
||||
@@ -162,6 +165,8 @@
|
||||
#define COMSIG_ATOM_ORBIT_BEGIN "atom_orbit_begin"
|
||||
///called when an atom stops orbiting another atom: (atom)
|
||||
#define COMSIG_ATOM_ORBIT_STOP "atom_orbit_stop"
|
||||
///from base of atom/set_opacity(): (new_opacity)
|
||||
#define COMSIG_ATOM_SET_OPACITY "atom_set_opacity"
|
||||
/////////////////
|
||||
///from base of atom/attack_ghost(): (mob/dead/observer/ghost)
|
||||
#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost"
|
||||
@@ -737,4 +742,40 @@
|
||||
#define COMSIG_TRIGGERED_ALARM "ssalarm_triggered"
|
||||
#define COMSIG_CANCELLED_ALARM "ssalarm_cancelled"
|
||||
|
||||
#define COMSIG_REAGENTS_CRAFTING_PING "reagents_crafting_ping"
|
||||
#define COMSIG_REAGENTS_CRAFTING_PING "reagents_crafting_ping"
|
||||
|
||||
// Lighting:
|
||||
///from base of [atom/proc/set_light]: (l_range, l_power, l_color, l_on)
|
||||
#define COMSIG_ATOM_SET_LIGHT "atom_set_light"
|
||||
/// Blocks [/atom/proc/set_light], [/atom/proc/set_light_power], [/atom/proc/set_light_range], [/atom/proc/set_light_color], [/atom/proc/set_light_on], and [/atom/proc/set_light_flags].
|
||||
#define COMPONENT_BLOCK_LIGHT_UPDATE (1<<0)
|
||||
///Called right before the atom changes the value of light_power to a different one, from base [atom/proc/set_light_power]: (new_power)
|
||||
#define COMSIG_ATOM_SET_LIGHT_POWER "atom_set_light_power"
|
||||
///Called right after the atom changes the value of light_power to a different one, from base of [/atom/proc/set_light_power]: (old_power)
|
||||
#define COMSIG_ATOM_UPDATE_LIGHT_POWER "atom_update_light_power"
|
||||
///Called right before the atom changes the value of light_range to a different one, from base [atom/proc/set_light_range]: (new_range)
|
||||
#define COMSIG_ATOM_SET_LIGHT_RANGE "atom_set_light_range"
|
||||
///Called right after the atom changes the value of light_range to a different one, from base of [/atom/proc/set_light_range]: (old_range)
|
||||
#define COMSIG_ATOM_UPDATE_LIGHT_RANGE "atom_update_light_range"
|
||||
///Called right before the atom changes the value of light_color to a different one, from base [atom/proc/set_light_color]: (new_color)
|
||||
#define COMSIG_ATOM_SET_LIGHT_COLOR "atom_set_light_color"
|
||||
///Called right after the atom changes the value of light_color to a different one, from base of [/atom/proc/set_light_color]: (old_color)
|
||||
#define COMSIG_ATOM_UPDATE_LIGHT_COLOR "atom_update_light_color"
|
||||
///Called right before the atom changes the value of light_on to a different one, from base [atom/proc/set_light_on]: (new_value)
|
||||
#define COMSIG_ATOM_SET_LIGHT_ON "atom_set_light_on"
|
||||
///Called right after the atom changes the value of light_on to a different one, from base of [/atom/proc/set_light_on]: (old_value)
|
||||
#define COMSIG_ATOM_UPDATE_LIGHT_ON "atom_update_light_on"
|
||||
///Called right before the atom changes the value of light_flags to a different one, from base [atom/proc/set_light_flags]: (new_flags)
|
||||
#define COMSIG_ATOM_SET_LIGHT_FLAGS "atom_set_light_flags"
|
||||
///Called right after the atom changes the value of light_flags to a different one, from base of [/atom/proc/set_light_flags]: (old_flags)
|
||||
#define COMSIG_ATOM_UPDATE_LIGHT_FLAGS "atom_update_light_flags"
|
||||
|
||||
// /datum/element/light_eater
|
||||
///from base of [/datum/element/light_eater/proc/table_buffet]: (list/light_queue, datum/light_eater)
|
||||
#define COMSIG_LIGHT_EATER_QUEUE "light_eater_queue"
|
||||
///from base of [/datum/element/light_eater/proc/devour]: (datum/light_eater)
|
||||
#define COMSIG_LIGHT_EATER_ACT "light_eater_act"
|
||||
///Prevents the default light eater behavior from running in case of immunity or custom behavior
|
||||
#define COMPONENT_BLOCK_LIGHT_EATER (1<<0)
|
||||
///from base of [/datum/element/light_eater/proc/devour]: (atom/eaten_light)
|
||||
#define COMSIG_LIGHT_EATER_DEVOUR "light_eater_devour"
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
|
||||
GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768))
|
||||
|
||||
/* Directions */
|
||||
///All the cardinal direction bitflags.
|
||||
#define ALL_CARDINALS (NORTH|SOUTH|EAST|WEST)
|
||||
|
||||
// datum_flags
|
||||
#define DF_VAR_EDITED (1<<0)
|
||||
#define DF_ISPROCESSING (1<<1)
|
||||
|
||||
+101
-70
@@ -1,88 +1,119 @@
|
||||
#define FOR_DVIEW(type, range, center, invis_flags) \
|
||||
dview_mob.loc = center; \
|
||||
dview_mob.see_invisible = invis_flags; \
|
||||
for(type in view(range, dview_mob))
|
||||
///Object doesn't use any of the light systems. Should be changed to add a light source to the object.
|
||||
#define NO_LIGHT_SUPPORT 0
|
||||
///Light made with the lighting datums, applying a matrix.
|
||||
#define STATIC_LIGHT 1
|
||||
///Light made by masking the lighting darkness plane.
|
||||
#define MOVABLE_LIGHT 2
|
||||
///Light made by masking the lighting darkness plane, and is directional.
|
||||
#define MOVABLE_LIGHT_DIRECTIONAL 3
|
||||
|
||||
#define END_FOR_DVIEW dview_mob.loc = null
|
||||
///Is a movable light source attached to another movable (its loc), meaning that the lighting component should go one level deeper.
|
||||
#define LIGHT_ATTACHED (1<<0)
|
||||
|
||||
#define LIGHTING_FALLOFF 1 // type of falloff to use for lighting; 1 for circular, 2 for square
|
||||
#define LIGHTING_LAMBERTIAN 0 // use lambertian shading for light sources
|
||||
#define LIGHTING_HEIGHT 1 // height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone
|
||||
//Bay lighting engine shit, not in /code/modules/lighting because BYOND is being shit about it
|
||||
/// frequency, in 1/10ths of a second, of the lighting process
|
||||
#define LIGHTING_INTERVAL 5
|
||||
|
||||
#define LIGHTING_ICON 'icons/effects/lighting_overlay.dmi' // icon used for lighting shading effects
|
||||
#define LIGHTING_ICON_STATE_DARK "soft_dark" // Change between "soft_dark" and "dark" to swap soft darkvision
|
||||
#define MINIMUM_USEFUL_LIGHT_RANGE 1.4
|
||||
|
||||
#define LIGHTING_ROUND_VALUE (1 / 64) // Value used to round lumcounts, values smaller than 1/69 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY.
|
||||
/// type of falloff to use for lighting; 1 for circular, 2 for square
|
||||
#define LIGHTING_FALLOFF 1
|
||||
/// use lambertian shading for light sources
|
||||
#define LIGHTING_LAMBERTIAN 0
|
||||
/// height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone
|
||||
#define LIGHTING_HEIGHT 1
|
||||
/// Value used to round lumcounts, values smaller than 1/129 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY.
|
||||
#define LIGHTING_ROUND_VALUE (1 / 64)
|
||||
|
||||
#define LIGHTING_SOFT_THRESHOLD 0.05 // If the max of the lighting lumcounts of each spectrum drops below this, disable luminosity on the lighting overlays. This also should be the transparancy of the "soft_dark" icon state.
|
||||
/// icon used for lighting shading effects
|
||||
#define LIGHTING_ICON 'icons/effects/lighting_object.dmi'
|
||||
|
||||
#define LIGHTING_MULT_FACTOR 0.5
|
||||
/// If the max of the lighting lumcounts of each spectrum drops below this, disable luminosity on the lighting objects.
|
||||
/// Set to zero to disable soft lighting. Luminosity changes then work if it's lit at all.
|
||||
#define LIGHTING_SOFT_THRESHOLD 0
|
||||
|
||||
// If I were you I'd leave this alone.
|
||||
/// If I were you I'd leave this alone.
|
||||
#define LIGHTING_BASE_MATRIX \
|
||||
list \
|
||||
( \
|
||||
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
|
||||
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
|
||||
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
|
||||
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
|
||||
1, 1, 1, 0, \
|
||||
1, 1, 1, 0, \
|
||||
1, 1, 1, 0, \
|
||||
1, 1, 1, 0, \
|
||||
0, 0, 0, 1 \
|
||||
) \
|
||||
|
||||
// Helpers so we can (more easily) control the colour matrices.
|
||||
#define CL_MATRIX_RR 1
|
||||
#define CL_MATRIX_RG 2
|
||||
#define CL_MATRIX_RB 3
|
||||
#define CL_MATRIX_RA 4
|
||||
#define CL_MATRIX_GR 5
|
||||
#define CL_MATRIX_GG 6
|
||||
#define CL_MATRIX_GB 7
|
||||
#define CL_MATRIX_GA 8
|
||||
#define CL_MATRIX_BR 9
|
||||
#define CL_MATRIX_BG 10
|
||||
#define CL_MATRIX_BB 11
|
||||
#define CL_MATRIX_BA 12
|
||||
#define CL_MATRIX_AR 13
|
||||
#define CL_MATRIX_AG 14
|
||||
#define CL_MATRIX_AB 15
|
||||
#define CL_MATRIX_AA 16
|
||||
#define CL_MATRIX_CR 17
|
||||
#define CL_MATRIX_CG 18
|
||||
#define CL_MATRIX_CB 19
|
||||
#define CL_MATRIX_CA 20
|
||||
///How many tiles standard fires glow.
|
||||
#define LIGHT_RANGE_FIRE 3
|
||||
|
||||
//Some defines to generalise colours used in lighting.
|
||||
//Important note on colors. Colors can end up significantly different from the basic html picture, especially when saturated
|
||||
#define LIGHT_COLOR_RED "#FA8282" //Warm but extremely diluted red. rgb(250, 130, 130)
|
||||
#define LIGHT_COLOR_GREEN "#64C864" //Bright but quickly dissipating neon green. rgb(100, 200, 100)
|
||||
#define LIGHT_COLOR_BLUE "#6496FA" //Cold, diluted blue. rgb(100, 150, 250)
|
||||
#define LIGHTING_PLANE_ALPHA_VISIBLE 255
|
||||
#define LIGHTING_PLANE_ALPHA_NV_TRAIT 245
|
||||
#define LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE 192
|
||||
/// For lighting alpha, small amounts lead to big changes. even at 128 its hard to figure out what is dark and what is light, at 64 you almost can't even tell.
|
||||
#define LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE 128
|
||||
#define LIGHTING_PLANE_ALPHA_INVISIBLE 0
|
||||
|
||||
#define LIGHT_COLOR_BLUEGREEN "#7DE1AF" //Light blueish green. rgb(125, 225, 175)
|
||||
#define LIGHT_COLOR_CYAN "#7DE1E1" //Diluted cyan. rgb(125, 225, 225)
|
||||
#define LIGHT_COLOR_LIGHT_CYAN "#40CEFF" //More-saturated cyan. rgb(64, 206, 255)
|
||||
#define LIGHT_COLOR_DARK_BLUE "#6496FA" //Saturated blue. rgb(51, 117, 248)
|
||||
#define LIGHT_COLOR_PINK "#E17DE1" //Diluted, mid-warmth pink. rgb(225, 125, 225)
|
||||
#define LIGHT_COLOR_YELLOW "#E1E17D" //Dimmed yellow, leaning kaki. rgb(225, 225, 125)
|
||||
#define LIGHT_COLOR_BROWN "#966432" //Clear brown, mostly dim. rgb(150, 100, 50)
|
||||
#define LIGHT_COLOR_ORANGE "#FA9632" //Mostly pure orange. rgb(250, 150, 50)
|
||||
#define LIGHT_COLOR_PURPLE "#952CF4" //Light Purple. rgb(149, 44, 244)
|
||||
#define LIGHT_COLOR_LAVENDER "#9B51FF" //Less-saturated light purple. rgb(155, 81, 255)
|
||||
//lighting area defines
|
||||
/// dynamic lighting disabled (area stays at full brightness)
|
||||
#define DYNAMIC_LIGHTING_DISABLED 0
|
||||
/// dynamic lighting enabled
|
||||
#define DYNAMIC_LIGHTING_ENABLED 1
|
||||
/// dynamic lighting enabled even if the area doesn't require power
|
||||
#define DYNAMIC_LIGHTING_FORCED 2
|
||||
/// dynamic lighting enabled only if starlight is.
|
||||
#define DYNAMIC_LIGHTING_IFSTARLIGHT 3
|
||||
#define IS_DYNAMIC_LIGHTING(A) A.dynamic_lighting
|
||||
|
||||
//These ones aren't a direct colour like the ones above, because nothing would fit
|
||||
#define LIGHT_COLOR_FIRE "#FAA019" //Warm orange color, leaning strongly towards yellow. rgb(250, 160, 25)
|
||||
#define LIGHT_COLOR_LAVA "#C48A18" //Very warm yellow, leaning slightly towards orange. rgb(196, 138, 24)
|
||||
#define LIGHT_COLOR_FLARE "#FA644B" //Bright, non-saturated red. Leaning slightly towards pink for visibility. rgb(250, 100, 75)
|
||||
#define LIGHT_COLOR_SLIME_LAMP "#AFC84B" //Weird color, between yellow and green, very slimy. rgb(175, 200, 75)
|
||||
#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" //Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175)
|
||||
#define LIGHT_COLOR_HALOGEN "#F0FAFA" //Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250)
|
||||
|
||||
//Lighting values used by the station lights
|
||||
#define LIGHT_COLOR_FLUORESCENT_TUBE "#E0EFFF"
|
||||
#define LIGHT_COLOR_FLUORESCENT_FLASHLIGHT "#CDDDFF"
|
||||
#define LIGHT_COLOR_INCANDESCENT_TUBE "#FFFEB8"
|
||||
#define LIGHT_COLOR_INCANDESCENT_BULB "#FFDDBB"
|
||||
#define LIGHT_COLOR_INCANDESCENT_FLASHLIGHT "#FFCC66"
|
||||
#define LIGHT_COLOR_NIGHTSHIFT "#EFCC86"
|
||||
//code assumes higher numbers override lower numbers.
|
||||
#define LIGHTING_NO_UPDATE 0
|
||||
#define LIGHTING_VIS_UPDATE 1
|
||||
#define LIGHTING_CHECK_UPDATE 2
|
||||
#define LIGHTING_FORCE_UPDATE 3
|
||||
|
||||
//Fake ambient occlusion filter
|
||||
#define AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-1, size=2, offset=2, color="#04080F55") //VOREStation Edit for prettier visuals.
|
||||
#define FLASH_LIGHT_DURATION 2
|
||||
#define FLASH_LIGHT_POWER 3
|
||||
#define FLASH_LIGHT_RANGE 3.8
|
||||
|
||||
// Emissive blocking.
|
||||
/// Uses vis_overlays to leverage caching so that very few new items need to be made for the overlay. For anything that doesn't change outline or opaque area much or at all.
|
||||
#define EMISSIVE_BLOCK_GENERIC 1
|
||||
/// Uses a dedicated render_target object to copy the entire appearance in real time to the blocking layer. For things that can change in appearance a lot from the base state, like humans.
|
||||
#define EMISSIVE_BLOCK_UNIQUE 2
|
||||
|
||||
/// The color matrix applied to all emissive overlays. Should be solely dependent on alpha and not have RGB overlap with [EM_BLOCK_COLOR].
|
||||
#define EMISSIVE_COLOR list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 1,1,1,0)
|
||||
/// A globaly cached version of [EMISSIVE_COLOR] for quick access.
|
||||
GLOBAL_LIST_INIT(emissive_color, EMISSIVE_COLOR)
|
||||
/// The color matrix applied to all emissive blockers. Should be solely dependent on alpha and not have RGB overlap with [EMISSIVE_COLOR].
|
||||
#define EM_BLOCK_COLOR list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0)
|
||||
/// A globaly cached version of [EM_BLOCK_COLOR] for quick access.
|
||||
GLOBAL_LIST_INIT(em_block_color, EM_BLOCK_COLOR)
|
||||
/// The color matrix used to mask out emissive blockers on the emissive plane. Alpha should default to zero, be solely dependent on the RGB value of [EMISSIVE_COLOR], and be independant of the RGB value of [EM_BLOCK_COLOR].
|
||||
#define EM_MASK_MATRIX list(0,0,0,1/3, 0,0,0,1/3, 0,0,0,1/3, 0,0,0,0, 1,1,1,0)
|
||||
/// A globaly cached version of [EM_MASK_MATRIX] for quick access.
|
||||
GLOBAL_LIST_INIT(em_mask_matrix, EM_MASK_MATRIX)
|
||||
|
||||
/// Returns the red part of a #RRGGBB hex sequence as number
|
||||
#define GETREDPART(hexa) hex2num(copytext(hexa, 2, 4))
|
||||
|
||||
/// Returns the green part of a #RRGGBB hex sequence as number
|
||||
#define GETGREENPART(hexa) hex2num(copytext(hexa, 4, 6))
|
||||
|
||||
/// Returns the blue part of a #RRGGBB hex sequence as number
|
||||
#define GETBLUEPART(hexa) hex2num(copytext(hexa, 6, 8))
|
||||
|
||||
/// Parse the hexadecimal color into lumcounts of each perspective.
|
||||
#define PARSE_LIGHT_COLOR(source) \
|
||||
do { \
|
||||
if (source.light_color != COLOR_WHITE) { \
|
||||
var/__light_color = source.light_color; \
|
||||
source.lum_r = GETREDPART(__light_color) / 255; \
|
||||
source.lum_g = GETGREENPART(__light_color) / 255; \
|
||||
source.lum_b = GETBLUEPART(__light_color) / 255; \
|
||||
} else { \
|
||||
source.lum_r = 1; \
|
||||
source.lum_g = 1; \
|
||||
source.lum_b = 1; \
|
||||
}; \
|
||||
} while (FALSE)
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
#define LIGHT_COLOR_INCANDESCENT_TUBE "#E0EFF0"
|
||||
#define LIGHT_COLOR_INCANDESCENT_BULB "#FFFEB8"
|
||||
#define LIGHT_COLOR_INCANDESCENT_BULB "#FFFEB8"
|
||||
//Fake ambient occlusion filter
|
||||
#define AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-1, size=2, offset=2, color="#04080F55") //VOREStation Edit for prettier visuals.
|
||||
@@ -8,7 +8,7 @@
|
||||
#define MAP_LEVEL_CONSOLES 0x040 // Z-levels available to various consoles, such as the crew monitor (when that gets coded in). Defaults to station_levels if unset.
|
||||
#define MAP_LEVEL_XENOARCH_EXEMPT 0x080 // Z-levels exempt from xenoarch digsite generation.
|
||||
#define MAP_LEVEL_PERSIST 0x100 // Z-levels where SSpersistence should persist between rounds
|
||||
#define MAP_LEVEL_MAPPABLE 0x200 // Z-levels where SSpersistence should persist between rounds
|
||||
#define MAP_LEVEL_MAPPABLE 0x200 // Z-levels where mapping units will work fully
|
||||
|
||||
// Misc map defines.
|
||||
#define SUBMAP_MAP_EDGE_PAD 8 // Automatically created submaps are forbidden from being this close to the main map's edge. //VOREStation Edit
|
||||
#define SUBMAP_MAP_EDGE_PAD 8 // Automatically created submaps are forbidden from being this close to the main map's edge. //VOREStation Edit
|
||||
|
||||
@@ -61,3 +61,15 @@
|
||||
#define DEFAULT_WALL_MATERIAL "steel"
|
||||
|
||||
#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass)
|
||||
|
||||
//Material Container Flags.
|
||||
///If the container shows the amount of contained materials on examine.
|
||||
#define MATCONTAINER_EXAMINE (1<<0)
|
||||
///If the container cannot have materials inserted through attackby().
|
||||
#define MATCONTAINER_NO_INSERT (1<<1)
|
||||
///if the user can insert mats into the container despite the intent.
|
||||
#define MATCONTAINER_ANY_INTENT (1<<2)
|
||||
///if the user won't receive a warning when attacking the container with an unallowed item.
|
||||
#define MATCONTAINER_SILENT (1<<3)
|
||||
|
||||
#define GET_MATERIAL_REF(arguments...) _GetMaterialRef(list(##arguments))
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#define SEE_INVISIBLE_MINIMUM 5
|
||||
#define INVISIBILITY_MAXIMUM 100
|
||||
#define INVISIBILITY_ABSTRACT 101 //only used for abstract objects, things that are not really there.
|
||||
|
||||
// Pseudo-Invis, like Ninja, Ling, Etc.
|
||||
#define EFFECTIVE_INVIS 50 // Below this, can't be examined, may as well be invisible to the game
|
||||
|
||||
+26
-23
@@ -377,37 +377,40 @@
|
||||
//Vision flags, for dealing with plane visibility
|
||||
#define VIS_FULLBRIGHT 1
|
||||
#define VIS_LIGHTING 2
|
||||
#define VIS_GHOSTS 3
|
||||
#define VIS_AI_EYE 4
|
||||
#define VIS_O_LIGHT 3
|
||||
#define VIS_EMISSIVE 4
|
||||
|
||||
#define VIS_CH_STATUS 5
|
||||
#define VIS_CH_HEALTH 6
|
||||
#define VIS_CH_LIFE 7
|
||||
#define VIS_CH_ID 8
|
||||
#define VIS_CH_WANTED 9
|
||||
#define VIS_CH_IMPLOYAL 10
|
||||
#define VIS_CH_IMPTRACK 11
|
||||
#define VIS_CH_IMPCHEM 12
|
||||
#define VIS_CH_SPECIAL 13
|
||||
#define VIS_CH_STATUS_OOC 14
|
||||
#define VIS_GHOSTS 5
|
||||
#define VIS_AI_EYE 6
|
||||
|
||||
#define VIS_ADMIN1 15
|
||||
#define VIS_ADMIN2 16
|
||||
#define VIS_ADMIN3 17
|
||||
#define VIS_CH_STATUS 7
|
||||
#define VIS_CH_HEALTH 8
|
||||
#define VIS_CH_LIFE 9
|
||||
#define VIS_CH_ID 10
|
||||
#define VIS_CH_WANTED 11
|
||||
#define VIS_CH_IMPLOYAL 12
|
||||
#define VIS_CH_IMPTRACK 13
|
||||
#define VIS_CH_IMPCHEM 14
|
||||
#define VIS_CH_SPECIAL 15
|
||||
#define VIS_CH_STATUS_OOC 16
|
||||
|
||||
#define VIS_MESONS 18
|
||||
#define VIS_ADMIN1 17
|
||||
#define VIS_ADMIN2 18
|
||||
#define VIS_ADMIN3 19
|
||||
|
||||
#define VIS_TURFS 19
|
||||
#define VIS_OBJS 20
|
||||
#define VIS_MOBS 21
|
||||
#define VIS_MESONS 20
|
||||
|
||||
#define VIS_BUILDMODE 22
|
||||
#define VIS_TURFS 21
|
||||
#define VIS_OBJS 22
|
||||
#define VIS_MOBS 23
|
||||
|
||||
#define VIS_CLOAKED 23
|
||||
#define VIS_BUILDMODE 24
|
||||
|
||||
#define VIS_STATUS 24
|
||||
#define VIS_CLOAKED 25
|
||||
|
||||
#define VIS_COUNT 24 //Must be highest number from above.
|
||||
#define VIS_STATUS 26
|
||||
|
||||
#define VIS_COUNT 26 //Must be highest number from above.
|
||||
|
||||
//Some mob icon layering defines
|
||||
#define BODY_LAYER -100
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#undef VIS_COUNT
|
||||
|
||||
#define VIS_CH_STATUS_R 24
|
||||
#define VIS_CH_HEALTH_VR 25
|
||||
#define VIS_CH_BACKUP 26
|
||||
#define VIS_CH_VANTAG 27
|
||||
#define VIS_CH_STATUS_R 27
|
||||
#define VIS_CH_HEALTH_VR 28
|
||||
#define VIS_CH_BACKUP 29
|
||||
#define VIS_CH_VANTAG 30
|
||||
|
||||
#define VIS_AUGMENTED 28
|
||||
#define VIS_AUGMENTED 31
|
||||
|
||||
#define VIS_COUNT 28
|
||||
#define VIS_COUNT 31
|
||||
|
||||
//Protean organs
|
||||
#define O_ORCH "orchestrator"
|
||||
|
||||
@@ -56,6 +56,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
||||
#define INIT_ORDER_SQLITE 40
|
||||
#define INIT_ORDER_MEDIA_TRACKS 38 // Gotta get that lobby music up, yo
|
||||
#define INIT_ORDER_CHEMISTRY 35
|
||||
#define INIT_ORDER_VIS 32
|
||||
#define INIT_ORDER_SKYBOX 30
|
||||
#define INIT_ORDER_MAPPING 25
|
||||
#define INIT_ORDER_SOUNDS 23
|
||||
@@ -94,6 +95,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
||||
#define FIRE_PRIORITY_SUPPLY 5
|
||||
#define FIRE_PRIORITY_NIGHTSHIFT 5
|
||||
#define FIRE_PRIORITY_PLANTS 5
|
||||
#define FIRE_PRIORITY_VIS 5
|
||||
#define FIRE_PRIORITY_ORBIT 7
|
||||
#define FIRE_PRIORITY_VOTE 8
|
||||
#define FIRE_PRIORITY_INSTRUMENTS 9
|
||||
|
||||
@@ -18,6 +18,14 @@
|
||||
/// Get a pool index of the provided window id
|
||||
#define TGUI_WINDOW_INDEX(window_id) text2num(copytext(window_id, 13))
|
||||
|
||||
/// Creates a message packet for sending via output()
|
||||
// This is {"type":type,"payload":payload}, but pre-encoded. This is much faster
|
||||
// than doing it the normal way.
|
||||
// To ensure this is correct, this is unit tested in tgui_create_message.
|
||||
#define TGUI_CREATE_MESSAGE(type, payload) ( \
|
||||
"%7b%22type%22%3a%22[type]%22%2c%22payload%22%3a[url_encode(json_encode(payload))]%7d" \
|
||||
)
|
||||
|
||||
/// Max length for Modal Input
|
||||
#define TGUI_MODAL_INPUT_MAX_LENGTH 1024
|
||||
/// Max length for Modal Input for names
|
||||
|
||||
@@ -17,4 +17,6 @@
|
||||
#define SMOOTH_GREYLIST 4 // Use a whitelist and a blacklist at the same time. atom smoothing only
|
||||
|
||||
#define isCardinal(x) (x == NORTH || x == SOUTH || x == EAST || x == WEST)
|
||||
#define isDiagonal(x) (x == NORTHEAST || x == SOUTHEAST || x == NORTHWEST || x == SOUTHWEST)
|
||||
#define isDiagonal(x) (x == NORTHEAST || x == SOUTHEAST || x == NORTHWEST || x == SOUTHWEST)
|
||||
|
||||
#define IS_OPAQUE_TURF(turf) (turf.directional_opacity == ALL_CARDINALS)
|
||||
|
||||
@@ -2,6 +2,38 @@ GLOBAL_LIST_INIT(bitfields, list(
|
||||
"datum_flags" = list(
|
||||
"DF_VAR_EDITED" = DF_VAR_EDITED,
|
||||
"DF_ISPROCESSING" = DF_ISPROCESSING
|
||||
)
|
||||
|
||||
),
|
||||
"appearance_flags" = list(
|
||||
"KEEP_APART" = KEEP_APART,
|
||||
"KEEP_TOGETHER" = KEEP_TOGETHER,
|
||||
"LONG_GLIDE" = LONG_GLIDE,
|
||||
"NO_CLIENT_COLOR" = NO_CLIENT_COLOR,
|
||||
"PIXEL_SCALE" = PIXEL_SCALE,
|
||||
"PLANE_MASTER" = PLANE_MASTER,
|
||||
"RESET_ALPHA" = RESET_ALPHA,
|
||||
"RESET_COLOR" = RESET_COLOR,
|
||||
"RESET_TRANSFORM" = RESET_TRANSFORM,
|
||||
"TILE_BOUND" = TILE_BOUND,
|
||||
),
|
||||
"vis_flags" = list(
|
||||
"VIS_HIDE" = VIS_HIDE,
|
||||
"VIS_INHERIT_DIR" = VIS_INHERIT_DIR,
|
||||
"VIS_INHERIT_ICON" = VIS_INHERIT_ICON,
|
||||
"VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE,
|
||||
"VIS_INHERIT_ID" = VIS_INHERIT_ID,
|
||||
"VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER,
|
||||
"VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE,
|
||||
"VIS_UNDERLAY" = VIS_UNDERLAY,
|
||||
),
|
||||
"sight" = list(
|
||||
"BLIND" = BLIND,
|
||||
"SEE_BLACKNESS" = SEE_BLACKNESS,
|
||||
"SEE_INFRA" = SEE_INFRA,
|
||||
"SEE_MOBS" = SEE_MOBS,
|
||||
"SEE_OBJS" = SEE_OBJS,
|
||||
"SEE_PIXELS" = SEE_PIXELS,
|
||||
"SEE_SELF" = SEE_SELF,
|
||||
"SEE_THRU" = SEE_THRU,
|
||||
"SEE_TURFS" = SEE_TURFS,
|
||||
),
|
||||
))
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
//please store common type caches here.
|
||||
//type caches should only be stored here if used in mutiple places or likely to be used in mutiple places.
|
||||
|
||||
//Note: typecache can only replace istype if you know for sure the thing is at least a datum.
|
||||
|
||||
GLOBAL_LIST_INIT(typecache_stack, typecacheof(/obj/item/stack))
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
//Find coordinates
|
||||
var/turf/T = get_turf(AM) //use AM's turfs, as it's coords are the same as AM's AND AM's coords are lost if it is inside another atom
|
||||
if(!T)
|
||||
return null
|
||||
var/final_x = T.x + rough_x
|
||||
var/final_y = T.y + rough_y
|
||||
|
||||
|
||||
@@ -26,13 +26,6 @@ var/list/mannequins_
|
||||
// Times that players are allowed to respawn ("ckey" = world.time)
|
||||
GLOBAL_LIST_EMPTY(respawn_timers)
|
||||
|
||||
// Closets have magic appearances
|
||||
GLOBAL_LIST_EMPTY(closet_appearances)
|
||||
|
||||
// Posters
|
||||
var/global/list/poster_designs = list()
|
||||
var/global/list/NT_poster_designs = list()
|
||||
|
||||
// Holomaps
|
||||
var/global/list/holomap_markers = list()
|
||||
var/global/list/mapping_units = list()
|
||||
@@ -213,18 +206,6 @@ GLOBAL_LIST_EMPTY(mannequins)
|
||||
if(S.spawn_flags & SPECIES_IS_WHITELISTED)
|
||||
GLOB.whitelisted_species += S.name
|
||||
|
||||
//Posters
|
||||
paths = typesof(/datum/poster) - /datum/poster
|
||||
paths -= typesof(/datum/poster/nanotrasen)
|
||||
for(var/T in paths)
|
||||
var/datum/poster/P = new T
|
||||
poster_designs += P
|
||||
|
||||
paths = typesof(/datum/poster/nanotrasen)
|
||||
for(var/T in paths)
|
||||
var/datum/poster/P = new T
|
||||
NT_poster_designs += P
|
||||
|
||||
//Ores
|
||||
paths = typesof(/ore)-/ore
|
||||
for(var/oretype in paths)
|
||||
@@ -236,10 +217,7 @@ GLOBAL_LIST_EMPTY(mannequins)
|
||||
GLOB.alloy_data += new alloytype()
|
||||
|
||||
//Closet appearances
|
||||
paths = typesof(/decl/closet_appearance)
|
||||
for(var/T in paths)
|
||||
var/decl/closet_appearance/app = new T()
|
||||
GLOB.closet_appearances[T] = app
|
||||
GLOB.closet_appearances = decls_repository.get_decls_of_type(/decl/closet_appearance)
|
||||
|
||||
paths = typesof(/datum/sprite_accessory/ears) - /datum/sprite_accessory/ears
|
||||
for(var/path in paths)
|
||||
|
||||
@@ -13,6 +13,9 @@ var/global/list/active_ghost_pods = list()
|
||||
|
||||
var/global/list/sensorpreflist = list("Off", "Binary", "Vitals", "Tracking", "No Preference")
|
||||
|
||||
// Closets have magic appearances
|
||||
GLOBAL_LIST_EMPTY(closet_appearances)
|
||||
|
||||
//stores numeric player size options indexed by name
|
||||
var/global/list/player_sizes_list = list(
|
||||
"Macro" = RESIZE_HUGE,
|
||||
@@ -232,6 +235,7 @@ var/global/list/contamination_flavors = list(
|
||||
"Dirty" = contamination_flavors_dirty,
|
||||
"Musky" = contamination_flavors_musky,
|
||||
"Smelly" = contamination_flavors_smelly,
|
||||
"Slimy" = contamination_flavors_slimy,
|
||||
"Wet" = contamination_flavors_wet)
|
||||
|
||||
var/global/list/contamination_flavors_generic = list("acrid",
|
||||
@@ -435,6 +439,21 @@ var/global/list/contamination_flavors_musky = list("drenched",
|
||||
"sticky",
|
||||
"tainted")
|
||||
|
||||
var/global/list/contamination_flavors_slimy = list("slimy",
|
||||
"sloppy",
|
||||
"drippy",
|
||||
"glistening",
|
||||
"dripping",
|
||||
"gunky",
|
||||
"slimed",
|
||||
"mucky",
|
||||
"viscous",
|
||||
"dank",
|
||||
"glutinous",
|
||||
"syrupy",
|
||||
"slippery",
|
||||
"gelatinous")
|
||||
|
||||
var/global/list/contamination_colors = list("green",
|
||||
"white",
|
||||
"black",
|
||||
@@ -522,4 +541,4 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
|
||||
return 1 // Hooks must return 1
|
||||
|
||||
var/global/list/weavable_structures = list()
|
||||
var/global/list/weavable_items = list()
|
||||
var/global/list/weavable_items = list()
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EMISSIVE_COLOR].
|
||||
/proc/emissive_appearance(icon, icon_state = "", layer = FLOAT_LAYER, alpha = 255, appearance_flags = NONE)
|
||||
var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, PLANE_EMISSIVE, alpha, appearance_flags)
|
||||
appearance.color = GLOB.emissive_color
|
||||
return appearance
|
||||
|
||||
/proc/em_block_image_generic(var/image/I)
|
||||
var/mutable_appearance/em_overlay = mutable_appearance(I.icon, I.icon_state, plane = PLANE_EMISSIVE, alpha = I.alpha, appearance_flags = KEEP_APART)
|
||||
em_overlay.color = GLOB.em_block_color
|
||||
return em_overlay
|
||||
@@ -57,12 +57,6 @@
|
||||
if (!.)
|
||||
. = B[STAT_ENTRY_COUNT] - A[STAT_ENTRY_COUNT]
|
||||
|
||||
// Compares complexity of recipes for use in cooking, etc. This is for telling which recipe to make, not for showing things to the player.
|
||||
/proc/cmp_recipe_complexity_dsc(datum/recipe/A, datum/recipe/B)
|
||||
var/a_score = LAZYLEN(A.items) + LAZYLEN(A.reagents) + LAZYLEN(A.fruit)
|
||||
var/b_score = LAZYLEN(B.items) + LAZYLEN(B.reagents) + LAZYLEN(B.fruit)
|
||||
return b_score - a_score
|
||||
|
||||
/proc/cmp_typepaths_asc(A, B)
|
||||
return sorttext("[B]","[A]")
|
||||
|
||||
@@ -88,3 +82,6 @@
|
||||
/proc/cmp_media_track_asc(datum/track/A, datum/track/B)
|
||||
var/genre_sort = sorttext(B.genre || "Uncategorized", A.genre || "Uncategorized")
|
||||
return genre_sort || sorttext(B.title, A.title)
|
||||
|
||||
/proc/cmp_filter_data_priority(list/A, list/B)
|
||||
return A["priority"] - B["priority"]
|
||||
|
||||
@@ -1621,6 +1621,9 @@ GLOBAL_REAL_VAR(list/stack_trace_storage)
|
||||
// 'Utility' planes
|
||||
. += new /obj/screen/plane_master/fullbright //Lighting system (lighting_overlay objects)
|
||||
. += new /obj/screen/plane_master/lighting //Lighting system (but different!)
|
||||
. += new /obj/screen/plane_master/o_light_visual //Object lighting (using masks)
|
||||
. += new /obj/screen/plane_master/emissive //Emissive overlays
|
||||
|
||||
. += new /obj/screen/plane_master/ghosts //Ghosts!
|
||||
. += new /obj/screen/plane_master{plane = PLANE_AI_EYE} //AI Eye!
|
||||
|
||||
|
||||
+367
-19
@@ -1,20 +1,306 @@
|
||||
// These involve BYOND's built in filters that do visual effects, and not stuff that distinguishes between things.
|
||||
#define ICON_NOT_SET "Not Set"
|
||||
//This is stored as a nested list instead of datums or whatever because it json encodes nicely for usage in tgui
|
||||
GLOBAL_LIST_INIT(master_filter_info, list(
|
||||
"alpha" = list(
|
||||
"defaults" = list(
|
||||
"x" = 0,
|
||||
"y" = 0,
|
||||
"icon" = ICON_NOT_SET,
|
||||
"render_source" = "",
|
||||
"flags" = 0
|
||||
),
|
||||
"flags" = list(
|
||||
"MASK_INVERSE" = MASK_INVERSE,
|
||||
"MASK_SWAP" = MASK_SWAP
|
||||
)
|
||||
),
|
||||
"angular_blur" = list(
|
||||
"defaults" = list(
|
||||
"x" = 0,
|
||||
"y" = 0,
|
||||
"size" = 1
|
||||
)
|
||||
),
|
||||
/* Not supported because making a proper matrix editor on the frontend would be a huge dick pain.
|
||||
Uncomment if you ever implement it
|
||||
"color" = list(
|
||||
"defaults" = list(
|
||||
"color" = matrix(),
|
||||
"space" = FILTER_COLOR_RGB
|
||||
)
|
||||
),
|
||||
*/
|
||||
"displace" = list(
|
||||
"defaults" = list(
|
||||
"x" = 0,
|
||||
"y" = 0,
|
||||
"size" = null,
|
||||
"icon" = ICON_NOT_SET,
|
||||
"render_source" = ""
|
||||
)
|
||||
),
|
||||
"drop_shadow" = list(
|
||||
"defaults" = list(
|
||||
"x" = 1,
|
||||
"y" = -1,
|
||||
"size" = 1,
|
||||
"offset" = 0,
|
||||
"color" = COLOR_HALF_TRANSPARENT_BLACK
|
||||
)
|
||||
),
|
||||
"blur" = list(
|
||||
"defaults" = list(
|
||||
"size" = 1
|
||||
)
|
||||
),
|
||||
"layer" = list(
|
||||
"defaults" = list(
|
||||
"x" = 0,
|
||||
"y" = 0,
|
||||
"icon" = ICON_NOT_SET,
|
||||
"render_source" = "",
|
||||
"flags" = FILTER_OVERLAY,
|
||||
"color" = "",
|
||||
"transform" = null,
|
||||
"blend_mode" = BLEND_DEFAULT
|
||||
)
|
||||
),
|
||||
"motion_blur" = list(
|
||||
"defaults" = list(
|
||||
"x" = 0,
|
||||
"y" = 0
|
||||
)
|
||||
),
|
||||
"outline" = list(
|
||||
"defaults" = list(
|
||||
"size" = 0,
|
||||
"color" = COLOR_BLACK,
|
||||
"flags" = NONE
|
||||
),
|
||||
"flags" = list(
|
||||
"OUTLINE_SHARP" = OUTLINE_SHARP,
|
||||
"OUTLINE_SQUARE" = OUTLINE_SQUARE
|
||||
)
|
||||
),
|
||||
"radial_blur" = list(
|
||||
"defaults" = list(
|
||||
"x" = 0,
|
||||
"y" = 0,
|
||||
"size" = 0.01
|
||||
)
|
||||
),
|
||||
"rays" = list(
|
||||
"defaults" = list(
|
||||
"x" = 0,
|
||||
"y" = 0,
|
||||
"size" = 16,
|
||||
"color" = COLOR_WHITE,
|
||||
"offset" = 0,
|
||||
"density" = 10,
|
||||
"threshold" = 0.5,
|
||||
"factor" = 0,
|
||||
"flags" = FILTER_OVERLAY | FILTER_UNDERLAY
|
||||
),
|
||||
"flags" = list(
|
||||
"FILTER_OVERLAY" = FILTER_OVERLAY,
|
||||
"FILTER_UNDERLAY" = FILTER_UNDERLAY
|
||||
)
|
||||
),
|
||||
"ripple" = list(
|
||||
"defaults" = list(
|
||||
"x" = 0,
|
||||
"y" = 0,
|
||||
"size" = 1,
|
||||
"repeat" = 2,
|
||||
"radius" = 0,
|
||||
"falloff" = 1,
|
||||
"flags" = NONE
|
||||
),
|
||||
"flags" = list(
|
||||
"WAVE_BOUNDED" = WAVE_BOUNDED
|
||||
)
|
||||
),
|
||||
"wave" = list(
|
||||
"defaults" = list(
|
||||
"x" = 0,
|
||||
"y" = 0,
|
||||
"size" = 1,
|
||||
"offset" = 0,
|
||||
"flags" = NONE
|
||||
),
|
||||
"flags" = list(
|
||||
"WAVE_SIDEWAYS" = WAVE_SIDEWAYS,
|
||||
"WAVE_BOUNDED" = WAVE_BOUNDED
|
||||
)
|
||||
)
|
||||
))
|
||||
|
||||
// All of this ported from TG.
|
||||
/atom/movable
|
||||
var/list/filter_data // For handling persistent filters
|
||||
#undef ICON_NOT_SET
|
||||
|
||||
/proc/cmp_filter_data_priority(list/A, list/B)
|
||||
return A["priority"] - B["priority"]
|
||||
//Helpers to generate lists for filter helpers
|
||||
//This is the only practical way of writing these that actually produces sane lists
|
||||
/proc/alpha_mask_filter(x, y, icon/icon, render_source, flags)
|
||||
. = list("type" = "alpha")
|
||||
if(!isnull(x))
|
||||
.["x"] = x
|
||||
if(!isnull(y))
|
||||
.["y"] = y
|
||||
if(!isnull(icon))
|
||||
.["icon"] = icon
|
||||
if(!isnull(render_source))
|
||||
.["render_source"] = render_source
|
||||
if(!isnull(flags))
|
||||
.["flags"] = flags
|
||||
|
||||
/atom/movable/proc/add_filter(filter_name, priority, list/params)
|
||||
/proc/angular_blur_filter(x, y, size)
|
||||
. = list("type" = "angular_blur")
|
||||
if(!isnull(x))
|
||||
.["x"] = x
|
||||
if(!isnull(y))
|
||||
.["y"] = y
|
||||
if(!isnull(size))
|
||||
.["size"] = size
|
||||
|
||||
/proc/color_matrix_filter(matrix/in_matrix, space)
|
||||
. = list("type" = "color")
|
||||
.["color"] = in_matrix
|
||||
if(!isnull(space))
|
||||
.["space"] = space
|
||||
|
||||
/proc/displacement_map_filter(icon, render_source, x, y, size = 32)
|
||||
. = list("type" = "displace")
|
||||
if(!isnull(icon))
|
||||
.["icon"] = icon
|
||||
if(!isnull(render_source))
|
||||
.["render_source"] = render_source
|
||||
if(!isnull(x))
|
||||
.["x"] = x
|
||||
if(!isnull(y))
|
||||
.["y"] = y
|
||||
if(!isnull(size))
|
||||
.["size"] = size
|
||||
|
||||
/proc/drop_shadow_filter(x, y, size, offset, color)
|
||||
. = list("type" = "drop_shadow")
|
||||
if(!isnull(x))
|
||||
.["x"] = x
|
||||
if(!isnull(y))
|
||||
.["y"] = y
|
||||
if(!isnull(size))
|
||||
.["size"] = size
|
||||
if(!isnull(offset))
|
||||
.["offset"] = offset
|
||||
if(!isnull(color))
|
||||
.["color"] = color
|
||||
|
||||
/proc/gauss_blur_filter(size)
|
||||
. = list("type" = "blur")
|
||||
if(!isnull(size))
|
||||
.["size"] = size
|
||||
|
||||
/proc/layering_filter(icon, render_source, x, y, flags, color, transform, blend_mode)
|
||||
. = list("type" = "layer")
|
||||
if(!isnull(icon))
|
||||
.["icon"] = icon
|
||||
if(!isnull(render_source))
|
||||
.["render_source"] = render_source
|
||||
if(!isnull(x))
|
||||
.["x"] = x
|
||||
if(!isnull(y))
|
||||
.["y"] = y
|
||||
if(!isnull(color))
|
||||
.["color"] = color
|
||||
if(!isnull(flags))
|
||||
.["flags"] = flags
|
||||
if(!isnull(transform))
|
||||
.["transform"] = transform
|
||||
if(!isnull(blend_mode))
|
||||
.["blend_mode"] = blend_mode
|
||||
|
||||
/proc/motion_blur_filter(x, y)
|
||||
. = list("type" = "motion_blur")
|
||||
if(!isnull(x))
|
||||
.["x"] = x
|
||||
if(!isnull(y))
|
||||
.["y"] = y
|
||||
|
||||
/proc/outline_filter(size, color, flags)
|
||||
. = list("type" = "outline")
|
||||
if(!isnull(size))
|
||||
.["size"] = size
|
||||
if(!isnull(color))
|
||||
.["color"] = color
|
||||
if(!isnull(flags))
|
||||
.["flags"] = flags
|
||||
|
||||
/proc/radial_blur_filter(size, x, y)
|
||||
. = list("type" = "radial_blur")
|
||||
if(!isnull(size))
|
||||
.["size"] = size
|
||||
if(!isnull(x))
|
||||
.["x"] = x
|
||||
if(!isnull(y))
|
||||
.["y"] = y
|
||||
|
||||
/proc/rays_filter(size, color, offset, density, threshold, factor, x, y, flags)
|
||||
. = list("type" = "rays")
|
||||
if(!isnull(size))
|
||||
.["size"] = size
|
||||
if(!isnull(color))
|
||||
.["color"] = color
|
||||
if(!isnull(offset))
|
||||
.["offset"] = offset
|
||||
if(!isnull(density))
|
||||
.["density"] = density
|
||||
if(!isnull(threshold))
|
||||
.["threshold"] = threshold
|
||||
if(!isnull(factor))
|
||||
.["factor"] = factor
|
||||
if(!isnull(x))
|
||||
.["x"] = x
|
||||
if(!isnull(y))
|
||||
.["y"] = y
|
||||
if(!isnull(flags))
|
||||
.["flags"] = flags
|
||||
|
||||
/proc/ripple_filter(radius, size, falloff, repeat, x, y, flags)
|
||||
. = list("type" = "ripple")
|
||||
if(!isnull(radius))
|
||||
.["radius"] = radius
|
||||
if(!isnull(size))
|
||||
.["size"] = size
|
||||
if(!isnull(falloff))
|
||||
.["falloff"] = falloff
|
||||
if(!isnull(repeat))
|
||||
.["repeat"] = repeat
|
||||
if(!isnull(flags))
|
||||
.["flags"] = flags
|
||||
if(!isnull(x))
|
||||
.["x"] = x
|
||||
if(!isnull(y))
|
||||
.["y"] = y
|
||||
|
||||
/proc/wave_filter(x, y, size, offset, flags)
|
||||
. = list("type" = "wave")
|
||||
if(!isnull(size))
|
||||
.["size"] = size
|
||||
if(!isnull(x))
|
||||
.["x"] = x
|
||||
if(!isnull(y))
|
||||
.["y"] = y
|
||||
if(!isnull(offset))
|
||||
.["offset"] = offset
|
||||
if(!isnull(flags))
|
||||
.["flags"] = flags
|
||||
|
||||
/atom/proc/add_filter(name,priority,list/params)
|
||||
LAZYINITLIST(filter_data)
|
||||
var/list/p = params.Copy()
|
||||
p["priority"] = priority
|
||||
filter_data[filter_name] = p
|
||||
filter_data[name] = p
|
||||
update_filters()
|
||||
|
||||
/atom/movable/proc/update_filters()
|
||||
/atom/proc/update_filters()
|
||||
filters = null
|
||||
filter_data = sortTim(filter_data, /proc/cmp_filter_data_priority, TRUE)
|
||||
for(var/f in filter_data)
|
||||
@@ -22,15 +308,77 @@
|
||||
var/list/arguments = data.Copy()
|
||||
arguments -= "priority"
|
||||
filters += filter(arglist(arguments))
|
||||
UNSETEMPTY(filter_data)
|
||||
|
||||
/atom/movable/proc/get_filter(filter_name)
|
||||
if(filter_data && filter_data[filter_name])
|
||||
return filters[filter_data.Find(filter_name)]
|
||||
/atom/proc/transition_filter(name, time, list/new_params, easing, loop)
|
||||
var/filter = get_filter(name)
|
||||
if(!filter)
|
||||
return
|
||||
|
||||
// Polaris Extensions
|
||||
/atom/movable/proc/remove_filter(filter_name)
|
||||
var/thing = get_filter(filter_name)
|
||||
if(thing)
|
||||
LAZYREMOVE(filter_data, filter_name)
|
||||
filters -= thing
|
||||
update_filters()
|
||||
var/list/old_filter_data = filter_data[name]
|
||||
|
||||
var/list/params = old_filter_data.Copy()
|
||||
for(var/thing in new_params)
|
||||
params[thing] = new_params[thing]
|
||||
|
||||
animate(filter, new_params, time = time, easing = easing, loop = loop)
|
||||
for(var/param in params)
|
||||
filter_data[name][param] = params[param]
|
||||
|
||||
/atom/proc/change_filter_priority(name, new_priority)
|
||||
if(!filter_data || !filter_data[name])
|
||||
return
|
||||
|
||||
filter_data[name]["priority"] = new_priority
|
||||
update_filters()
|
||||
|
||||
/obj/item/update_filters()
|
||||
. = ..()
|
||||
/* Will port this from TG
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
*/
|
||||
|
||||
/atom/proc/get_filter(name)
|
||||
if(filter_data && filter_data[name])
|
||||
return filters[filter_data.Find(name)]
|
||||
|
||||
/atom/proc/remove_filter(name_or_names)
|
||||
if(!filter_data)
|
||||
return
|
||||
|
||||
var/list/names = islist(name_or_names) ? name_or_names : list(name_or_names)
|
||||
|
||||
for(var/name in names)
|
||||
if(filter_data[name])
|
||||
filter_data -= name
|
||||
update_filters()
|
||||
|
||||
/atom/proc/clear_filters()
|
||||
filter_data = null
|
||||
filters = null
|
||||
|
||||
/proc/apply_wibbly_filters(atom/in_atom, length)
|
||||
for(var/i in 1 to 7)
|
||||
//This is a very baffling and strange way of doing this but I am just preserving old functionality
|
||||
var/X
|
||||
var/Y
|
||||
var/rsq
|
||||
do
|
||||
X = 60*rand() - 30
|
||||
Y = 60*rand() - 30
|
||||
rsq = X*X + Y*Y
|
||||
while(rsq<100 || rsq>900) // Yeah let's just loop infinitely due to bad luck what's the worst that could happen?
|
||||
var/random_roll = rand()
|
||||
in_atom.add_filter("wibbly-[i]", 5, wave_filter(x = X, y = Y, size = rand() * 2.5 + 0.5, offset = random_roll))
|
||||
var/filter = in_atom.get_filter("wibbly-[i]")
|
||||
animate(filter, offset = random_roll, time = 0, loop = -1, flags = ANIMATION_PARALLEL)
|
||||
animate(offset = random_roll - 1, time = rand() * 20 + 10)
|
||||
|
||||
/proc/remove_wibbly_filters(atom/in_atom)
|
||||
var/filter
|
||||
for(var/i in 1 to 7)
|
||||
filter = in_atom.get_filter("wibbly-[i]")
|
||||
animate(filter)
|
||||
in_atom.remove_filter("wibbly-[i]")
|
||||
|
||||
@@ -355,7 +355,7 @@
|
||||
facedir(direction)
|
||||
|
||||
/obj/screen/click_catcher
|
||||
name = "Darkness"
|
||||
name = "" // Empty string names don't show up in context menu clicks
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "click_catcher"
|
||||
plane = CLICKCATCHER_PLANE
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
// if((last_charge == spell.charge_counter || !handle_icon_updates) && !forced_update)
|
||||
// return //nothing to see here
|
||||
|
||||
// overlays -= spell.hud_state
|
||||
// cut_overlay(spell.hud_state)
|
||||
|
||||
// if(spell.charge_type == Sp_RECHARGE || spell.charge_type == Sp_CHARGES)
|
||||
// if(spell.charge_counter < spell.charge_max)
|
||||
@@ -228,27 +228,27 @@
|
||||
// partial_charge.Crop(1, 1, partial_charge.Width(), round(partial_charge.Height() * spell.charge_counter / spell.charge_max))
|
||||
// overlays += partial_charge
|
||||
// if(last_charged_icon)
|
||||
// overlays -= last_charged_icon
|
||||
// cut_overlay(last_charged_icon)
|
||||
// last_charged_icon = partial_charge
|
||||
// else if(last_charged_icon)
|
||||
// overlays -= last_charged_icon
|
||||
// cut_overlay(last_charged_icon)
|
||||
// last_charged_icon = null
|
||||
// else
|
||||
// icon_state = "[spell_base]_spell_ready"
|
||||
// if(last_charged_icon)
|
||||
// overlays -= last_charged_icon
|
||||
// cut_overlay(last_charged_icon)
|
||||
// else
|
||||
// icon_state = "[spell_base]_spell_ready"
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
icon_state = "[background_base_state]_spell_base"
|
||||
|
||||
overlays += ability_icon_state
|
||||
|
||||
// last_charge = spell.charge_counter
|
||||
|
||||
// overlays -= "silence"
|
||||
// cut_overlay("silence")
|
||||
// if(spell.silenced)
|
||||
// overlays += "silence"
|
||||
// add_overlay("silence")
|
||||
|
||||
/obj/screen/ability/Click()
|
||||
if(!usr)
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
icon = owner.button_icon
|
||||
icon_state = owner.background_icon_state
|
||||
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
var/image/img
|
||||
if(owner.action_type == AB_ITEM && owner.target)
|
||||
var/obj/item/I = owner.target
|
||||
@@ -143,7 +143,7 @@
|
||||
img = image(owner.button_icon,src,owner.button_icon_state)
|
||||
img.pixel_x = 0
|
||||
img.pixel_y = 0
|
||||
overlays += img
|
||||
add_overlay(img)
|
||||
|
||||
if(!owner.IsAvailable())
|
||||
color = rgb(128,0,0,128)
|
||||
@@ -178,9 +178,9 @@
|
||||
return
|
||||
|
||||
/obj/screen/movable/action_button/hide_toggle/UpdateIcon()
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
var/image/img = image(icon,src,hidden?"show":"hide")
|
||||
overlays += img
|
||||
add_overlay(img)
|
||||
return
|
||||
|
||||
//This is the proc used to update all the action buttons. Properly defined in /mob/living/
|
||||
|
||||
@@ -5,25 +5,22 @@
|
||||
condition ? overlay_fullscreen(screen_name, screen_type, arg) : clear_fullscreen(screen_name)
|
||||
|
||||
/mob/proc/overlay_fullscreen(category, type, severity)
|
||||
var/obj/screen/fullscreen/screen = screens[category]
|
||||
var/obj/screen/fullscreen/screen = screens[category]
|
||||
if (!screen || screen.type != type)
|
||||
// needs to be recreated
|
||||
clear_fullscreen(category, FALSE)
|
||||
screens[category] = screen = new type()
|
||||
else if ((!severity || severity == screen.severity) && (!client || screen.screen_loc != "CENTER-7,CENTER-7" || screen.view == client.view))
|
||||
// doesn't need to be updated
|
||||
return screen
|
||||
|
||||
if(screen)
|
||||
if(screen.type != type)
|
||||
clear_fullscreen(category, FALSE)
|
||||
screen = null
|
||||
else if(!severity || severity == screen.severity)
|
||||
return screen
|
||||
screen.icon_state = "[initial(screen.icon_state)][severity]"
|
||||
screen.severity = severity
|
||||
if (client && screen.should_show_to(src))
|
||||
screen.update_for_view(client.view)
|
||||
client.screen += screen
|
||||
|
||||
if(!screen)
|
||||
screen = new type()
|
||||
|
||||
screen.icon_state = "[initial(screen.icon_state)][severity]"
|
||||
screen.severity = severity
|
||||
|
||||
screens[category] = screen
|
||||
if(client && stat != DEAD)
|
||||
client.screen += screen
|
||||
return screen
|
||||
return screen
|
||||
|
||||
/mob/proc/clear_fullscreen(category, animated = 10)
|
||||
var/obj/screen/fullscreen/screen = screens[category]
|
||||
@@ -64,13 +61,26 @@
|
||||
screen_loc = "CENTER-7,CENTER-7"
|
||||
layer = FULLSCREEN_LAYER
|
||||
plane = PLANE_FULLSCREEN
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
var/view = 7
|
||||
var/severity = 0
|
||||
var/show_when_dead = FALSE
|
||||
|
||||
/obj/screen/fullscreen/Destroy()
|
||||
severity = 0
|
||||
return ..()
|
||||
|
||||
/obj/screen/fullscreen/proc/update_for_view(client_view)
|
||||
if (screen_loc == "CENTER-7,CENTER-7" && view != client_view)
|
||||
var/list/actualview = getviewsize(client_view)
|
||||
view = client_view
|
||||
transform = matrix(actualview[1]/15, 0, 0, 0, actualview[2]/15, 0)
|
||||
|
||||
/obj/screen/fullscreen/proc/should_show_to(mob/mymob)
|
||||
if(!show_when_dead && mymob.stat == DEAD)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/screen/fullscreen/brute
|
||||
icon_state = "brutedamageoverlay"
|
||||
layer = DAMAGE_LAYER
|
||||
@@ -123,3 +133,21 @@
|
||||
|
||||
/obj/screen/fullscreen/fishbed
|
||||
icon_state = "fishbed"
|
||||
|
||||
/obj/screen/fullscreen/lighting_backdrop
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "flash"
|
||||
transform = matrix(200, 0, 0, 0, 200, 0)
|
||||
plane = PLANE_LIGHTING
|
||||
blend_mode = BLEND_OVERLAY
|
||||
show_when_dead = TRUE
|
||||
|
||||
//Provides darkness to the back of the lighting plane
|
||||
/obj/screen/fullscreen/lighting_backdrop/lit
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
layer = BACKGROUND_LAYER+21
|
||||
color = "#000"
|
||||
|
||||
//Provides whiteness in case you don't see lights so everything is still visible
|
||||
/obj/screen/fullscreen/lighting_backdrop/unlit
|
||||
layer = BACKGROUND_LAYER+20
|
||||
|
||||
@@ -291,8 +291,8 @@
|
||||
zone_sel.icon = HUD.ui_style
|
||||
zone_sel.color = HUD.ui_color
|
||||
zone_sel.alpha = HUD.ui_alpha
|
||||
zone_sel.overlays.Cut()
|
||||
zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[zone_sel.selecting]")
|
||||
zone_sel.cut_overlays()
|
||||
zone_sel.add_overlay(image('icons/mob/zone_sel.dmi', "[zone_sel.selecting]"))
|
||||
hud_elements |= zone_sel
|
||||
|
||||
//Handle the gun settings buttons
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
|
||||
y_off = -height * world.icon_size - 16
|
||||
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
add_background()
|
||||
add_buttons()
|
||||
if(do_refresh)
|
||||
|
||||
@@ -141,8 +141,8 @@ var/obj/screen/robot_inventory
|
||||
zone_sel = new /obj/screen/zone_sel()
|
||||
zone_sel.icon = HUD.ui_style
|
||||
zone_sel.alpha = HUD.ui_alpha
|
||||
zone_sel.overlays.Cut()
|
||||
zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[zone_sel.selecting]")
|
||||
zone_sel.cut_overlays()
|
||||
zone_sel.add_overlay(image('icons/mob/zone_sel.dmi', "[zone_sel.selecting]"))
|
||||
|
||||
//Handle the gun settings buttons
|
||||
gun_setting_icon = new /obj/screen/gun/mode(null)
|
||||
|
||||
@@ -602,11 +602,11 @@
|
||||
if(!handcuff_overlay)
|
||||
var/state = (hud.l_hand_hud_object == src) ? "l_hand_hud_handcuffs" : "r_hand_hud_handcuffs"
|
||||
handcuff_overlay = image("icon"='icons/mob/screen_gen.dmi', "icon_state"=state)
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
if(hud.mymob && iscarbon(hud.mymob))
|
||||
var/mob/living/carbon/C = hud.mymob
|
||||
if(C.handcuffed)
|
||||
overlays |= handcuff_overlay
|
||||
add_overlay(handcuff_overlay)
|
||||
|
||||
// PIP stuff
|
||||
/obj/screen/component_button
|
||||
@@ -630,6 +630,13 @@
|
||||
return ..()
|
||||
|
||||
// Background 'floor'
|
||||
/obj/screen/setup_preview/pm_helper
|
||||
icon = null
|
||||
icon_state = null
|
||||
appearance_flags = PLANE_MASTER
|
||||
plane = PLANE_EMISSIVE
|
||||
alpha = 0
|
||||
|
||||
/obj/screen/setup_preview/bg
|
||||
mouse_over_pointer = MOUSE_HAND_POINTER
|
||||
|
||||
@@ -711,7 +718,7 @@
|
||||
var/obj/item/device/mapping_unit/owner
|
||||
var/obj/screen/mapper/extras_holder/extras_holder
|
||||
|
||||
/obj/screen/movable/mapper_holder/New(newloc, newowner)
|
||||
/obj/screen/movable/mapper_holder/Initialize(mapload, newowner)
|
||||
owner = newowner
|
||||
|
||||
mask_full = new(src) // Full white square mask
|
||||
@@ -849,15 +856,15 @@
|
||||
|
||||
/obj/screen/mapper/powbutton/Click()
|
||||
if(!usr.checkClickCooldown())
|
||||
return 1
|
||||
return TRUE
|
||||
if(usr.stat || usr.paralysis || usr.stunned || usr.weakened)
|
||||
return 1
|
||||
return TRUE
|
||||
if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
return 1
|
||||
return TRUE
|
||||
parent.powerClick()
|
||||
flick("powClick",src)
|
||||
usr << get_sfx("button")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/screen/mapper/mapbutton
|
||||
icon = 'icons/effects/gpshud.dmi'
|
||||
@@ -867,15 +874,15 @@
|
||||
|
||||
/obj/screen/mapper/mapbutton/Click()
|
||||
if(!usr.checkClickCooldown())
|
||||
return 1
|
||||
return TRUE
|
||||
if(usr.stat || usr.paralysis || usr.stunned || usr.weakened)
|
||||
return 1
|
||||
return TRUE
|
||||
if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
return 1
|
||||
return TRUE
|
||||
parent.mapClick()
|
||||
flick("mapClick",src)
|
||||
usr << get_sfx("button")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
// Markers are 16x16, people have apparently settled on centering them on the 8,8 pixel
|
||||
/obj/screen/mapper/marker
|
||||
|
||||
@@ -181,7 +181,7 @@
|
||||
if((last_charge == spell.charge_counter || !handle_icon_updates) && !forced_update)
|
||||
return //nothing to see here
|
||||
|
||||
overlays -= spell.hud_state
|
||||
cut_overlay(spell.hud_state)
|
||||
|
||||
if(spell.charge_type == Sp_RECHARGE || spell.charge_type == Sp_CHARGES)
|
||||
if(spell.charge_counter < spell.charge_max)
|
||||
@@ -191,23 +191,23 @@
|
||||
partial_charge.Crop(1, 1, partial_charge.Width(), round(partial_charge.Height() * spell.charge_counter / spell.charge_max))
|
||||
overlays += partial_charge
|
||||
if(last_charged_icon)
|
||||
overlays -= last_charged_icon
|
||||
cut_overlay(last_charged_icon)
|
||||
last_charged_icon = partial_charge
|
||||
else if(last_charged_icon)
|
||||
overlays -= last_charged_icon
|
||||
cut_overlay(last_charged_icon)
|
||||
last_charged_icon = null
|
||||
else
|
||||
icon_state = "[spell_base]_spell_ready"
|
||||
if(last_charged_icon)
|
||||
overlays -= last_charged_icon
|
||||
cut_overlay(last_charged_icon)
|
||||
else
|
||||
icon_state = "[spell_base]_spell_ready"
|
||||
|
||||
overlays += spell.hud_state
|
||||
add_overlay(spell.hud_state)
|
||||
|
||||
last_charge = spell.charge_counter
|
||||
|
||||
overlays -= "silence"
|
||||
cut_overlay("silence")
|
||||
if(spell.silenced)
|
||||
overlays += "silence"
|
||||
|
||||
|
||||
@@ -41,11 +41,6 @@ avoid code duplication. This includes items that may sometimes act as a standard
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/atom/movable/attackby(obj/item/W, mob/user, var/attack_modifier, var/click_parameters)
|
||||
. = ..()
|
||||
if(!. && !(W.flags & NOBLUDGEON))
|
||||
visible_message("<span class='danger'>[src] has been hit by [user] with [W].</span>")
|
||||
|
||||
/mob/living/attackby(obj/item/I, mob/user, var/attack_modifier, var/click_parameters)
|
||||
if(!ismob(user))
|
||||
return 0
|
||||
|
||||
@@ -163,7 +163,7 @@ var/const/tk_maxrange = 15
|
||||
return
|
||||
|
||||
/obj/item/tk_grab/update_icon()
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
if(focus && focus.icon && focus.icon_state)
|
||||
overlays += icon(focus.icon,focus.icon_state)
|
||||
add_overlay(icon(focus.icon, focus.icon_state))
|
||||
return
|
||||
|
||||
@@ -57,23 +57,23 @@ var/datum/controller/failsafe/Failsafe
|
||||
if(4,5)
|
||||
--defcon
|
||||
if(3)
|
||||
to_chat(GLOB.admins, "<span class='adminnotice'>Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks.</span>")
|
||||
log_and_message_admins("<span class='adminnotice'>SSfailsafe Notice: DEFCON [defcon_pretty()]. The Master Controller (\ref[Master]) has not fired in the last [(5-defcon) * processing_interval] ticks.</span>")
|
||||
--defcon
|
||||
if(2)
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</span>")
|
||||
log_and_message_admins("<span class='boldannounce'>SSfailsafe Warning: DEFCON [defcon_pretty()]. The Master Controller (\ref[Master]) has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</span>")
|
||||
--defcon
|
||||
if(1)
|
||||
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...</span>")
|
||||
log_and_message_admins("<span class='boldannounce'>SSfailsafe Warning: DEFCON [defcon_pretty()]. The Master Controller (\ref[Master]) has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...</span>")
|
||||
--defcon
|
||||
var/rtn = Recreate_MC()
|
||||
if(rtn > 0)
|
||||
defcon = 4
|
||||
master_iteration = 0
|
||||
to_chat(GLOB.admins, "<span class='adminnotice'>MC restarted successfully</span>")
|
||||
log_and_message_admins("<span class='adminnotice'>SSfailsafe Notice: MC (New:\ref[Master]) restarted successfully</span>")
|
||||
else if(rtn < 0)
|
||||
log_world("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0")
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.</span>")
|
||||
log_game("SSfailsafe Notice: Could not restart MC (\ref[Master]), runtime encountered. Entering defcon 0")
|
||||
log_and_message_admins("<span class='boldannounce'>SSFAILSAFE ERROR: DEFCON [defcon_pretty()]. Could not restart MC (\ref[Master]), runtime encountered. I will silently keep retrying.</span>")
|
||||
//if the return number was 0, it just means the mc was restarted too recently, and it just needs some time before we try again
|
||||
//no need to handle that specially when defcon 0 can handle it
|
||||
if(0) //DEFCON 0! (mc failed to restart)
|
||||
@@ -81,7 +81,7 @@ var/datum/controller/failsafe/Failsafe
|
||||
if(rtn > 0)
|
||||
defcon = 4
|
||||
master_iteration = 0
|
||||
to_chat(GLOB.admins, "<span class='adminnotice'>MC restarted successfully</span>")
|
||||
log_and_message_admins("<span class='adminnotice'>SSfailsafe Notice: MC (New:\ref[Master]) restarted successfully</span>")
|
||||
else
|
||||
defcon = min(defcon + 1,5)
|
||||
master_iteration = Master.iteration
|
||||
|
||||
+15
-13
@@ -132,11 +132,11 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
LAZYINITLIST(BadBoy.failure_strikes)
|
||||
switch(++BadBoy.failure_strikes[BadBoy.type])
|
||||
if(2)
|
||||
msg = "The [BadBoy.name] subsystem was the last to fire for 2 controller restarts. It will be recovered now and disabled if it happens again."
|
||||
msg = "MC Notice: The [BadBoy.name] subsystem was the last to fire for 2 controller restarts. It will be recovered now and disabled if it happens again."
|
||||
FireHim = TRUE
|
||||
BadBoy.fail()
|
||||
if(3)
|
||||
msg = "The [BadBoy.name] subsystem seems to be destabilizing the MC and will be offlined."
|
||||
msg = "MC Notice: The [BadBoy.name] subsystem seems to be destabilizing the MC and will be offlined."
|
||||
BadBoy.flags |= SS_NO_FIRE
|
||||
BadBoy.critfail()
|
||||
if(msg)
|
||||
@@ -152,7 +152,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
current_runlevel = Master.current_runlevel
|
||||
StartProcessing(10)
|
||||
else
|
||||
to_chat(world, "<span class='boldannounce'>The Master Controller is having some issues, we will need to re-initialize EVERYTHING</span>")
|
||||
to_world("<span class='boldannounce'>The Master Controller is having some issues, we will need to re-initialize EVERYTHING</span>")
|
||||
Initialize(20, TRUE)
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
if(init_sss)
|
||||
init_subtypes(/datum/controller/subsystem, subsystems)
|
||||
|
||||
to_chat(world, "<span class='boldannounce'>Initializing subsystems...</span>")
|
||||
to_chat(world, "<span class='boldannounce'>MC: Initializing subsystems...</span>")
|
||||
|
||||
// Sort subsystems by init_order, so they initialize in the correct order.
|
||||
sortTim(subsystems, /proc/cmp_subsystem_init)
|
||||
@@ -186,7 +186,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
current_ticklimit = TICK_LIMIT_RUNNING
|
||||
var/time = (REALTIMEOFDAY - start_timeofday) / 10
|
||||
|
||||
var/msg = "Initializations complete within [time] second[time == 1 ? "" : "s"]!"
|
||||
var/msg = "MC: Initializations complete within [time] second[time == 1 ? "" : "s"]!"
|
||||
to_chat(world, "<span class='boldannounce'>[msg]</span>")
|
||||
log_world(msg)
|
||||
|
||||
@@ -226,15 +226,17 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
if (rtn > 0 || processing < 0)
|
||||
return //this was suppose to happen.
|
||||
//loop ended, restart the mc
|
||||
log_game("MC crashed or runtimed, restarting")
|
||||
message_admins("MC crashed or runtimed, restarting")
|
||||
log_world("MC crashed or runtimed, restarting")
|
||||
log_and_message_admins("MC Notice: MC crashed or runtimed, self-restarting (\ref[src])")
|
||||
var/rtn2 = Recreate_MC()
|
||||
if (rtn2 <= 0)
|
||||
log_game("Failed to recreate MC (Error code: [rtn2]), it's up to the failsafe now")
|
||||
message_admins("Failed to recreate MC (Error code: [rtn2]), it's up to the failsafe now")
|
||||
log_world("Failed to recreate MC (Error code: [rtn2]), it's up to the failsafe now")
|
||||
Failsafe.defcon = 2
|
||||
switch(rtn2)
|
||||
if(-1)
|
||||
log_and_message_admins("MC Warning: Failed to self-recreate MC (Return code: [rtn2]), it's up to the failsafe now (\ref[src])")
|
||||
Failsafe.defcon = 2
|
||||
if(0)
|
||||
log_and_message_admins("MC Warning: Too soon for MC self-restart (Return code: [rtn2]), going to let failsafe handle it (\ref[src])")
|
||||
Failsafe.defcon = 2
|
||||
if(1)
|
||||
log_and_message_admins("MC Notice: MC self-recreated, old MC departing (Return code: [rtn2]) (\ref[src])")
|
||||
|
||||
// Main loop.
|
||||
/datum/controller/master/proc/Loop()
|
||||
|
||||
@@ -57,9 +57,44 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
if(active_edges.len)
|
||||
var/list/edge_log = list()
|
||||
for(var/connection_edge/E in active_edges)
|
||||
|
||||
var/a_temp = E.A.air.temperature
|
||||
var/a_moles = E.A.air.total_moles
|
||||
var/a_vol = E.A.air.volume
|
||||
var/a_gas = ""
|
||||
for(var/gas in E.A.air.gas)
|
||||
a_gas += "[gas]=[E.A.air.gas[gas]]"
|
||||
|
||||
var/b_temp
|
||||
var/b_moles
|
||||
var/b_vol
|
||||
var/b_gas = ""
|
||||
|
||||
// Two zones mixing
|
||||
if(istype(E, /connection_edge/zone))
|
||||
var/connection_edge/zone/Z = E
|
||||
b_temp = Z.B.air.temperature
|
||||
b_moles = Z.B.air.total_moles
|
||||
b_vol = Z.B.air.volume
|
||||
for(var/gas in Z.B.air.gas)
|
||||
b_gas += "[gas]=[Z.B.air.gas[gas]]"
|
||||
|
||||
// Zone and unsimulated turfs mixing
|
||||
if(istype(E, /connection_edge/unsimulated))
|
||||
var/connection_edge/unsimulated/U = E
|
||||
b_temp = U.B.temperature
|
||||
b_moles = "Unsim"
|
||||
b_vol = "Unsim"
|
||||
for(var/gas in U.air.gas)
|
||||
b_gas += "[gas]=[U.air.gas[gas]]"
|
||||
|
||||
edge_log += "Active Edge [E] ([E.type])"
|
||||
edge_log += "Edge side A: T:[a_temp], Mol:[a_moles], Vol:[a_vol], Gas:[a_gas]"
|
||||
edge_log += "Edge side B: T:[b_temp], Mol:[b_moles], Vol:[b_vol], Gas:[b_gas]"
|
||||
|
||||
for(var/turf/T in E.connecting_turfs)
|
||||
edge_log += "+--- Connecting Turf [T] ([T.type]) @ [T.x], [T.y], [T.z] ([T.loc])"
|
||||
|
||||
log_debug("Active Edges on ZAS Startup\n" + edge_log.Join("\n"))
|
||||
startup_active_edge_log = edge_log.Copy()
|
||||
|
||||
@@ -68,10 +103,14 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
/datum/controller/subsystem/air/fire(resumed = 0)
|
||||
var/timer
|
||||
if(!resumed)
|
||||
ASSERT(LAZYLEN(currentrun) == 0) // Santity checks to make sure we don't somehow have items left over from last cycle
|
||||
ASSERT(current_step == null) // Or somehow didn't finish all the steps from last cycle
|
||||
current_cycle++ // Begin a new air_master cycle!
|
||||
current_step = SSAIR_TURFS // Start with Step 1 of course
|
||||
// Santity checks to make sure we don't somehow have items left over from last cycle
|
||||
// Or somehow didn't finish all the steps from last cycle
|
||||
if(LAZYLEN(currentrun) || current_step)
|
||||
log_and_message_admins("SSair: Was told to start a new run, but the previous run wasn't finished! currentrun.len=[currentrun.len], current_step=[current_step]")
|
||||
resumed = TRUE
|
||||
else
|
||||
current_cycle++ // Begin a new air_master cycle!
|
||||
current_step = SSAIR_TURFS // Start with Step 1 of course
|
||||
|
||||
INTERNAL_PROCESS_STEP(SSAIR_TURFS, TRUE, process_tiles_to_update, cost_turfs, SSAIR_EDGES)
|
||||
INTERNAL_PROCESS_STEP(SSAIR_EDGES, FALSE, process_active_edges, cost_edges, SSAIR_FIREZONES)
|
||||
@@ -80,10 +119,11 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
INTERNAL_PROCESS_STEP(SSAIR_ZONES, FALSE, process_zones_to_update, cost_zones, SSAIR_DONE)
|
||||
|
||||
// Okay, we're done! Woo! Got thru a whole air_master cycle!
|
||||
ASSERT(LAZYLEN(currentrun) == 0) // Sanity checks to make sure there are really none left
|
||||
ASSERT(current_step == SSAIR_DONE) // And that we didn't somehow skip past the last step
|
||||
currentrun = null
|
||||
current_step = null
|
||||
if(LAZYLEN(currentrun) || current_step != SSAIR_DONE)
|
||||
log_and_message_admins("SSair: Was not able to complete a full air cycle despite reaching the end of fire(). This shouldn't happen.")
|
||||
else
|
||||
currentrun = null
|
||||
current_step = null
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_tiles_to_update(resumed = 0)
|
||||
if (!resumed)
|
||||
@@ -119,7 +159,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
T.post_update_air_properties()
|
||||
T.needs_air_update = 0
|
||||
#ifdef ZASDBG
|
||||
T.overlays -= mark
|
||||
T.cut_overlay(mark)
|
||||
#endif
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
@@ -134,7 +174,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
T.post_update_air_properties()
|
||||
T.needs_air_update = 0
|
||||
#ifdef ZASDBG
|
||||
T.overlays -= mark
|
||||
T.cut_overlay(mark)
|
||||
#endif
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
@@ -1,166 +1,91 @@
|
||||
/*
|
||||
** Lighting Subsystem - Process the lighting! Do it!
|
||||
*/
|
||||
|
||||
#define SSLIGHTING_STAGE_LIGHTS 1
|
||||
#define SSLIGHTING_STAGE_CORNERS 2
|
||||
#define SSLIGHTING_STAGE_OVERLAYS 3
|
||||
#define SSLIGHTING_STAGE_DONE 4
|
||||
// This subsystem's fire() method also gets called once during Master.Initialize().
|
||||
// During this fire we need to use CHECK_TICK to sleep and continue, but in all other fires we need to use MC_CHECK_TICK to pause and return.
|
||||
// This leads us to a rather annoying little tidbit of code that I have stuffed into this macro so I don't have to see it.
|
||||
#define DUAL_TICK_CHECK if (init_tick_checks) { CHECK_TICK; } else if (MC_TICK_CHECK) { return; }
|
||||
|
||||
// Globals
|
||||
/var/lighting_overlays_initialised = FALSE
|
||||
/var/list/lighting_update_lights = list() // List of lighting sources queued for update.
|
||||
/var/list/lighting_update_corners = list() // List of lighting corners queued for update.
|
||||
/var/list/lighting_update_overlays = list() // List of lighting overlays queued for update.
|
||||
|
||||
SUBSYSTEM_DEF(lighting)
|
||||
name = "Lighting"
|
||||
wait = 2 // Ticks, not deciseconds
|
||||
wait = 2
|
||||
init_order = INIT_ORDER_LIGHTING
|
||||
flags = SS_TICKER
|
||||
var/static/list/sources_queue = list() // List of lighting sources queued for update.
|
||||
var/static/list/corners_queue = list() // List of lighting corners queued for update.
|
||||
var/static/list/objects_queue = list() // List of lighting objects queued for update.
|
||||
|
||||
var/list/currentrun = list()
|
||||
var/stage = null
|
||||
|
||||
var/cost_lights = 0
|
||||
var/cost_corners = 0
|
||||
var/cost_overlays = 0
|
||||
|
||||
/datum/controller/subsystem/lighting/Initialize(timeofday)
|
||||
if(!lighting_overlays_initialised)
|
||||
// TODO - TG initializes starlight here.
|
||||
create_all_lighting_overlays()
|
||||
lighting_overlays_initialised = TRUE
|
||||
|
||||
// Pre-process lighting once before the round starts.
|
||||
internal_process_lights(FALSE, TRUE)
|
||||
internal_process_corners(FALSE, TRUE)
|
||||
internal_process_overlays(FALSE, TRUE)
|
||||
/datum/controller/subsystem/lighting/stat_entry(msg)
|
||||
msg = "L:[length(sources_queue)]|C:[length(corners_queue)]|O:[length(objects_queue)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/lighting/fire(resumed = FALSE)
|
||||
var/timer
|
||||
if(!resumed)
|
||||
ASSERT(LAZYLEN(currentrun) == 0) // Santity checks to make sure we don't somehow have items left over from last cycle
|
||||
ASSERT(stage == null) // Or somehow didn't finish all the steps from last cycle
|
||||
stage = SSLIGHTING_STAGE_LIGHTS // Start with Step 1 of course
|
||||
|
||||
if(stage == SSLIGHTING_STAGE_LIGHTS)
|
||||
timer = TICK_USAGE
|
||||
internal_process_lights(resumed)
|
||||
cost_lights = MC_AVERAGE(cost_lights, TICK_DELTA_TO_MS(TICK_USAGE - timer))
|
||||
if(state != SS_RUNNING)
|
||||
return
|
||||
resumed = 0
|
||||
stage = SSLIGHTING_STAGE_CORNERS
|
||||
/datum/controller/subsystem/lighting/Initialize(timeofday)
|
||||
if(!subsystem_initialized)
|
||||
if (config.starlight)
|
||||
for(var/area/A in world)
|
||||
if (A.dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT)
|
||||
A.luminosity = 0
|
||||
|
||||
if(stage == SSLIGHTING_STAGE_CORNERS)
|
||||
timer = TICK_USAGE
|
||||
internal_process_corners(resumed)
|
||||
cost_corners = MC_AVERAGE(cost_corners, TICK_DELTA_TO_MS(TICK_USAGE - timer))
|
||||
if(state != SS_RUNNING)
|
||||
return
|
||||
resumed = 0
|
||||
stage = SSLIGHTING_STAGE_OVERLAYS
|
||||
subsystem_initialized = TRUE
|
||||
create_all_lighting_objects()
|
||||
|
||||
if(stage == SSLIGHTING_STAGE_OVERLAYS)
|
||||
timer = TICK_USAGE
|
||||
internal_process_overlays(resumed)
|
||||
cost_overlays = MC_AVERAGE(cost_overlays, TICK_DELTA_TO_MS(TICK_USAGE - timer))
|
||||
if(state != SS_RUNNING)
|
||||
return
|
||||
resumed = 0
|
||||
stage = SSLIGHTING_STAGE_DONE
|
||||
fire(FALSE, TRUE)
|
||||
|
||||
// Okay, we're done! Woo! Got thru a whole air_master cycle!
|
||||
ASSERT(LAZYLEN(currentrun) == 0) // Sanity checks to make sure there are really none left
|
||||
ASSERT(stage == SSLIGHTING_STAGE_DONE) // And that we didn't somehow skip past the last step
|
||||
currentrun = null
|
||||
stage = null
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/lighting/proc/internal_process_lights(resumed = FALSE, init_tick_checks = FALSE)
|
||||
if (!resumed)
|
||||
// We swap out the lists so any additions to the global list during a pause don't make things wierd.
|
||||
src.currentrun = global.lighting_update_lights
|
||||
global.lighting_update_lights = list()
|
||||
/datum/controller/subsystem/lighting/fire(resumed, init_tick_checks)
|
||||
MC_SPLIT_TICK_INIT(3)
|
||||
if(!init_tick_checks)
|
||||
MC_SPLIT_TICK
|
||||
var/list/queue = sources_queue
|
||||
var/i = 0
|
||||
for (i in 1 to length(queue))
|
||||
var/datum/light_source/L = queue[i]
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/datum/light_source/L = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
L.update_corners()
|
||||
|
||||
if(!L) continue
|
||||
if(L.check() || L.destroyed || L.force_update)
|
||||
L.remove_lum()
|
||||
if(!L.destroyed)
|
||||
L.apply_lum()
|
||||
L.needs_update = LIGHTING_NO_UPDATE
|
||||
|
||||
else if(L.vis_update) //We smartly update only tiles that became (in) visible to use.
|
||||
L.smart_vis_update()
|
||||
if(init_tick_checks)
|
||||
CHECK_TICK
|
||||
else if (MC_TICK_CHECK)
|
||||
break
|
||||
if (i)
|
||||
queue.Cut(1, i+1)
|
||||
i = 0
|
||||
|
||||
L.vis_update = FALSE
|
||||
L.force_update = FALSE
|
||||
L.needs_update = FALSE
|
||||
if(!init_tick_checks)
|
||||
MC_SPLIT_TICK
|
||||
|
||||
DUAL_TICK_CHECK
|
||||
queue = corners_queue
|
||||
for (i in 1 to length(queue))
|
||||
var/datum/lighting_corner/C = queue[i]
|
||||
|
||||
/datum/controller/subsystem/lighting/proc/internal_process_corners(resumed = FALSE, init_tick_checks = FALSE)
|
||||
if (!resumed)
|
||||
// We swap out the lists so any additions to the global list during a pause don't make things wierd.
|
||||
src.currentrun = global.lighting_update_corners
|
||||
global.lighting_update_corners = list()
|
||||
C.needs_update = FALSE //update_objects() can call qdel if the corner is storing no data
|
||||
C.update_objects()
|
||||
|
||||
if(init_tick_checks)
|
||||
CHECK_TICK
|
||||
else if (MC_TICK_CHECK)
|
||||
break
|
||||
if (i)
|
||||
queue.Cut(1, i+1)
|
||||
i = 0
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/datum/lighting_corner/C = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
|
||||
if(!C) continue
|
||||
C.update_overlays()
|
||||
C.needs_update = FALSE
|
||||
if(!init_tick_checks)
|
||||
MC_SPLIT_TICK
|
||||
|
||||
DUAL_TICK_CHECK
|
||||
queue = objects_queue
|
||||
for (i in 1 to length(queue))
|
||||
var/datum/lighting_object/O = queue[i]
|
||||
|
||||
/datum/controller/subsystem/lighting/proc/internal_process_overlays(resumed = FALSE, init_tick_checks = FALSE)
|
||||
if (!resumed)
|
||||
// We swap out the lists so any additions to the global list during a pause don't make things wierd.
|
||||
src.currentrun = global.lighting_update_overlays
|
||||
global.lighting_update_overlays = list()
|
||||
if (QDELETED(O))
|
||||
continue
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/atom/movable/lighting_overlay/O = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
|
||||
if(!O) continue
|
||||
O.update_overlay()
|
||||
O.update()
|
||||
O.needs_update = FALSE
|
||||
if(init_tick_checks)
|
||||
CHECK_TICK
|
||||
else if (MC_TICK_CHECK)
|
||||
break
|
||||
if (i)
|
||||
queue.Cut(1, i+1)
|
||||
|
||||
DUAL_TICK_CHECK
|
||||
|
||||
/datum/controller/subsystem/lighting/stat_entry(msg_prefix)
|
||||
var/list/msg = list(msg_prefix)
|
||||
msg += "T:{"
|
||||
msg += "S [total_lighting_sources] | "
|
||||
msg += "C [total_lighting_corners] | "
|
||||
msg += "O [total_lighting_overlays]"
|
||||
msg += "}"
|
||||
msg += "C:{"
|
||||
msg += "S [round(cost_lights, 1)] | "
|
||||
msg += "C [round(cost_corners, 1)] | "
|
||||
msg += "O [round(cost_overlays, 1)]"
|
||||
msg += "}"
|
||||
..(msg.Join())
|
||||
|
||||
#undef DUAL_TICK_CHECK
|
||||
#undef SSLIGHTING_STAGE_LIGHTS
|
||||
#undef SSLIGHTING_STAGE_CORNERS
|
||||
#undef SSLIGHTING_STAGE_OVERLAYS
|
||||
#undef SSLIGHTING_STAGE_STATS
|
||||
/datum/controller/subsystem/lighting/Recover()
|
||||
subsystem_initialized = SSlighting.subsystem_initialized
|
||||
..()
|
||||
|
||||
@@ -102,6 +102,10 @@ SUBSYSTEM_DEF(mapping)
|
||||
return
|
||||
|
||||
for(var/map in picklist)
|
||||
if(islist(map))
|
||||
// TRIPLE NEST. In this situation we pick one at random from the choices in the list.
|
||||
//This allows a sort of a1,a2,a3,b1,b2,b3,c1,c2,c3 setup where it picks one 'a', one 'b', one 'c'
|
||||
map = pick(map)
|
||||
var/datum/map_template/MT = map_templates[map]
|
||||
if(!istype(MT))
|
||||
error("Randompick Z level \"[map]\" is not a valid map!")
|
||||
|
||||
@@ -74,9 +74,43 @@ SUBSYSTEM_DEF(media_tracks)
|
||||
return
|
||||
|
||||
// Required
|
||||
var/url = input(C, "REQUIRED: Provide URL for track", "Track URL") as text|null
|
||||
var/url = input(C, "REQUIRED: Provide URL for track, or paste JSON if you know what you're doing. See code comments.", "Track URL") as message|null
|
||||
if(!url)
|
||||
return
|
||||
|
||||
var/list/json
|
||||
try
|
||||
json = json_decode(url)
|
||||
catch
|
||||
|
||||
/**
|
||||
* Alternatively to using a series of inputs, you can use json and paste it in.
|
||||
* The json base element needs to be an array, even if it's only one song, so wrap it in []
|
||||
* The songs are json object literals inside the base array and use these keys:
|
||||
* "url": the url for the song (REQUIRED) (text)
|
||||
* "title": the title of the song (REQUIRED) (text)
|
||||
* "duration": duration of song in 1/10ths of a second (seconds * 10) (REQUIRED) (number)
|
||||
* "artist": artist of the song (text)
|
||||
* "genre": artist of the song, REALLY try to match an existing one (text)
|
||||
* "secret": only on hacked jukeboxes (true/false)
|
||||
* "lobby": plays in the lobby (true/false)
|
||||
*/
|
||||
|
||||
if(islist(json))
|
||||
for(var/song in json)
|
||||
if(!islist(song))
|
||||
to_chat(C, "<span class='warning'>Song appears to be malformed.</span>")
|
||||
continue
|
||||
var/list/songdata = song
|
||||
if(!songdata["url"] || !songdata["title"] || !songdata["duration"])
|
||||
to_chat(C, "<span class='warning'>URL, Title, or Duration was missing from a song. Skipping.</span>")
|
||||
continue
|
||||
var/datum/track/T = new(songdata["url"], songdata["title"], songdata["duration"], songdata["artist"], songdata["genre"], songdata["secret"], songdata["lobby"])
|
||||
all_tracks += T
|
||||
|
||||
report_progress("New media track added by [C]: [T.title]")
|
||||
sort_tracks()
|
||||
return
|
||||
|
||||
var/title = input(C, "REQUIRED: Provide title for track", "Track Title") as text|null
|
||||
if(!title)
|
||||
|
||||
@@ -224,6 +224,32 @@ var/global/image/appearance_bro = new() // Temporarily super-global because of B
|
||||
else if(cut_old)
|
||||
cut_overlays()
|
||||
|
||||
/**
|
||||
* Returns a list of overlays that the target atom has
|
||||
*
|
||||
* @param priority If true, returns priority overlays as well
|
||||
* @param special If true, returns special overlays like emissives and em_blockers
|
||||
*/
|
||||
/proc/get_overlays(atom/other, priority, special)
|
||||
var/list/including = list()
|
||||
if(!other)
|
||||
return including
|
||||
|
||||
for(var/image/I as anything in other.our_overlays)
|
||||
if(!special && I.plane > 0)
|
||||
continue
|
||||
including += I
|
||||
|
||||
if(!priority)
|
||||
return including
|
||||
|
||||
for(var/image/I as anything in other.priority_overlays)
|
||||
if(!special && I.plane > 0)
|
||||
continue
|
||||
including += I
|
||||
|
||||
return including
|
||||
|
||||
#undef NOT_QUEUED_ALREADY
|
||||
#undef QUEUE_FOR_COMPILE
|
||||
|
||||
|
||||
@@ -44,9 +44,8 @@ SUBSYSTEM_DEF(planets)
|
||||
P.planet_walls += T
|
||||
else if(istype(T, /turf/simulated) && T.outdoors)
|
||||
P.planet_floors += T
|
||||
T.vis_contents |= P.weather_holder.visuals
|
||||
T.vis_contents |= P.weather_holder.special_visuals
|
||||
|
||||
P.weather_holder.apply_to_turf(T)
|
||||
P.sun_holder.apply_to_turf(T)
|
||||
|
||||
/datum/controller/subsystem/planets/proc/removeTurf(var/turf/T,var/is_edge)
|
||||
if(z_to_planet.len >= T.z)
|
||||
@@ -57,8 +56,8 @@ SUBSYSTEM_DEF(planets)
|
||||
P.planet_walls -= T
|
||||
else
|
||||
P.planet_floors -= T
|
||||
T.vis_contents -= P.weather_holder.visuals
|
||||
T.vis_contents -= P.weather_holder.special_visuals
|
||||
P.weather_holder.remove_from_turf(T)
|
||||
P.sun_holder.remove_from_turf(T)
|
||||
|
||||
|
||||
/datum/controller/subsystem/planets/fire(resumed = 0)
|
||||
@@ -72,7 +71,8 @@ SUBSYSTEM_DEF(planets)
|
||||
updateSunlight(P)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
|
||||
#ifndef UNIT_TEST // Don't be updating temperatures and such during unit tests
|
||||
var/list/needs_temp_update = src.needs_temp_update
|
||||
while(needs_temp_update.len)
|
||||
var/datum/planet/P = needs_temp_update[needs_temp_update.len]
|
||||
@@ -80,6 +80,7 @@ SUBSYSTEM_DEF(planets)
|
||||
updateTemp(P)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
#endif
|
||||
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
@@ -102,39 +103,11 @@ SUBSYSTEM_DEF(planets)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/planets/proc/updateSunlight(var/datum/planet/P)
|
||||
// Remove old value from corners
|
||||
var/list/sunlit_corners = P.sunlit_corners
|
||||
var/old_lum_r = -P.sun["lum_r"]
|
||||
var/old_lum_g = -P.sun["lum_g"]
|
||||
var/old_lum_b = -P.sun["lum_b"]
|
||||
if(old_lum_r || old_lum_g || old_lum_b)
|
||||
for(var/C in sunlit_corners)
|
||||
var/datum/lighting_corner/LC = C
|
||||
LC.update_lumcount(old_lum_r, old_lum_g, old_lum_b)
|
||||
CHECK_TICK
|
||||
sunlit_corners.Cut()
|
||||
|
||||
// Calculate new values to apply
|
||||
var/new_brightness = P.sun["brightness"]
|
||||
P.sun_holder.update_brightness(new_brightness)
|
||||
|
||||
var/new_color = P.sun["color"]
|
||||
var/lum_r = new_brightness * GetRedPart (new_color) / 255
|
||||
var/lum_g = new_brightness * GetGreenPart(new_color) / 255
|
||||
var/lum_b = new_brightness * GetBluePart (new_color) / 255
|
||||
var/static/update_gen = -1 // Used to prevent double-processing corners. Otherwise would happen when looping over adjacent turfs.
|
||||
for(var/turf/simulated/T as anything in P.planet_floors)
|
||||
if(!T.lighting_corners_initialised)
|
||||
T.generate_missing_corners()
|
||||
for(var/C in T.get_corners())
|
||||
var/datum/lighting_corner/LC = C
|
||||
if(LC.update_gen != update_gen && LC.active)
|
||||
sunlit_corners += LC
|
||||
LC.update_gen = update_gen
|
||||
LC.update_lumcount(lum_r, lum_g, lum_b)
|
||||
CHECK_TICK
|
||||
update_gen--
|
||||
P.sun["lum_r"] = lum_r
|
||||
P.sun["lum_g"] = lum_g
|
||||
P.sun["lum_b"] = lum_b
|
||||
P.sun_holder.update_color(new_color)
|
||||
|
||||
/datum/controller/subsystem/planets/proc/updateTemp(var/datum/planet/P)
|
||||
//Set new temperatures
|
||||
|
||||
@@ -37,7 +37,8 @@ SUBSYSTEM_DEF(skybox)
|
||||
im.alpha = 128 //80
|
||||
im.blend_mode = BLEND_ADD
|
||||
|
||||
MA.overlays = list(im)
|
||||
MA.cut_overlays()
|
||||
MA.add_overlay(im)
|
||||
|
||||
dust_cache["[i]"] = MA
|
||||
|
||||
@@ -48,7 +49,8 @@ SUBSYSTEM_DEF(skybox)
|
||||
var/image/im = image('icons/turf/space_dust_transit.dmi', "speedspace_ns_[i]")
|
||||
im.plane = DUST_PLANE
|
||||
im.blend_mode = BLEND_ADD
|
||||
MA.overlays = list(im)
|
||||
MA.cut_overlays()
|
||||
MA.add_overlay(im)
|
||||
speedspace_cache["NS_[i]"] = MA
|
||||
// EAST/WEST
|
||||
MA = new(normal_space)
|
||||
@@ -56,7 +58,8 @@ SUBSYSTEM_DEF(skybox)
|
||||
im.plane = DUST_PLANE
|
||||
im.blend_mode = BLEND_ADD
|
||||
|
||||
MA.overlays = list(im)
|
||||
MA.cut_overlays()
|
||||
MA.add_overlay(im)
|
||||
|
||||
speedspace_cache["EW_[i]"] = MA
|
||||
|
||||
|
||||
@@ -205,11 +205,11 @@ SUBSYSTEM_DEF(supply)
|
||||
else if(islist(SP.access) && SP.one_access)
|
||||
var/list/L = SP.access // access var is a plain var, we need a list
|
||||
A.req_one_access = L.Copy()
|
||||
A.req_access = null
|
||||
LAZYCLEARLIST(A.req_access)
|
||||
else if(islist(SP.access) && !SP.one_access)
|
||||
var/list/L = SP.access
|
||||
A.req_access = L.Copy()
|
||||
A.req_one_access = null
|
||||
LAZYCLEARLIST(A.req_one_access)
|
||||
else
|
||||
log_debug("<span class='danger'>Supply pack with invalid access restriction [SP.access] encountered!</span>")
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ SUBSYSTEM_DEF(tgui)
|
||||
var/basehtml
|
||||
|
||||
/datum/controller/subsystem/tgui/PreInit()
|
||||
basehtml = file2text('tgui/packages/tgui/public/tgui.html')
|
||||
basehtml = file2text('tgui/public/tgui.html')
|
||||
|
||||
/datum/controller/subsystem/tgui/Shutdown()
|
||||
close_all_uis()
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
SUBSYSTEM_DEF(vis_overlays)
|
||||
name = "Vis contents overlays"
|
||||
wait = 1 MINUTES
|
||||
priority = FIRE_PRIORITY_VIS
|
||||
init_order = INIT_ORDER_VIS
|
||||
|
||||
var/list/vis_overlay_cache
|
||||
var/list/currentrun
|
||||
|
||||
/datum/controller/subsystem/vis_overlays/Initialize()
|
||||
vis_overlay_cache = list()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/vis_overlays/fire(resumed = FALSE)
|
||||
if(!resumed)
|
||||
currentrun = vis_overlay_cache.Copy()
|
||||
var/list/current_run = currentrun
|
||||
|
||||
while(current_run.len)
|
||||
var/key = current_run[current_run.len]
|
||||
var/obj/effect/overlay/vis/overlay = current_run[key]
|
||||
current_run.len--
|
||||
if(!overlay.unused && !length(overlay.vis_locs))
|
||||
overlay.unused = world.time
|
||||
else if(overlay.unused && overlay.unused + overlay.cache_expiration < world.time)
|
||||
vis_overlay_cache -= key
|
||||
qdel(overlay)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
//the "thing" var can be anything with vis_contents which includes images - in the future someone should totally allow vis overlays to be passed in as an arg instead of all this bullshit
|
||||
/datum/controller/subsystem/vis_overlays/proc/add_vis_overlay(atom/movable/thing, icon, iconstate, layer, plane, dir, alpha = 255, add_appearance_flags = NONE, unique = FALSE)
|
||||
var/obj/effect/overlay/vis/overlay
|
||||
if(!unique)
|
||||
. = "[icon]|[iconstate]|[layer]|[plane]|[dir]|[alpha]|[add_appearance_flags]"
|
||||
overlay = vis_overlay_cache[.]
|
||||
if(!overlay)
|
||||
overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
|
||||
vis_overlay_cache[.] = overlay
|
||||
else
|
||||
overlay.unused = 0
|
||||
else
|
||||
overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
|
||||
overlay.cache_expiration = -1
|
||||
var/cache_id = "\ref[overlay]@{[world.time]}"
|
||||
vis_overlay_cache[cache_id] = overlay
|
||||
. = overlay
|
||||
thing.vis_contents += overlay
|
||||
|
||||
if(!isatom(thing))
|
||||
return overlay
|
||||
|
||||
if(!thing.managed_vis_overlays)
|
||||
thing.managed_vis_overlays = list(overlay)
|
||||
else
|
||||
thing.managed_vis_overlays += overlay
|
||||
return overlay
|
||||
|
||||
/datum/controller/subsystem/vis_overlays/proc/_create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
|
||||
var/obj/effect/overlay/vis/overlay = new
|
||||
overlay.icon = icon
|
||||
overlay.icon_state = iconstate
|
||||
overlay.layer = layer
|
||||
overlay.plane = plane
|
||||
overlay.dir = dir
|
||||
overlay.alpha = alpha
|
||||
overlay.appearance_flags |= add_appearance_flags
|
||||
return overlay
|
||||
|
||||
|
||||
/datum/controller/subsystem/vis_overlays/proc/remove_vis_overlay(atom/movable/thing, list/overlays)
|
||||
thing.vis_contents -= overlays
|
||||
if(!isatom(thing))
|
||||
return
|
||||
thing.managed_vis_overlays -= overlays
|
||||
if(!length(thing.managed_vis_overlays))
|
||||
thing.managed_vis_overlays = null
|
||||
@@ -4,6 +4,7 @@
|
||||
// Clickable stat() button.
|
||||
/obj/effect/statclick
|
||||
name = "Initializing..."
|
||||
blocks_emissive = FALSE
|
||||
var/target
|
||||
|
||||
/obj/effect/statclick/New(loc, text, target) //Don't port this to Initialize it's too critical
|
||||
|
||||
@@ -38,6 +38,28 @@
|
||||
name = "All"
|
||||
category_item_type = /datum/category_item/autolathe
|
||||
|
||||
// Copypasted from materials, they should show in All
|
||||
/datum/category_group/autolathe/all/New()
|
||||
..()
|
||||
|
||||
for(var/Name in name_to_material)
|
||||
var/datum/material/M = name_to_material[Name]
|
||||
|
||||
if(!M.stack_type) // Shouldn't happen, but might. Never know.
|
||||
continue
|
||||
|
||||
if(istype(M, /datum/material/alienalloy))
|
||||
continue
|
||||
|
||||
var/obj/item/stack/material/S = M.stack_type
|
||||
if(initial(S.name) in items_by_name)
|
||||
continue
|
||||
|
||||
var/datum/category_item/autolathe/materials/WorkDat = new(src, M)
|
||||
|
||||
items |= WorkDat
|
||||
items_by_name[WorkDat.name] = WorkDat
|
||||
|
||||
///datum/category_group/autolathe/all/New()
|
||||
|
||||
/datum/category_group/autolathe/arms
|
||||
|
||||
@@ -306,13 +306,9 @@
|
||||
var/output = {"<form><input type="hidden" name="src" value="\ref[src]"><ul class="sparse">"}
|
||||
if (inputtype == "checkbox" || inputtype == "radio")
|
||||
for (var/i in values)
|
||||
var/div_slider = slidecolor
|
||||
if(!i["allowed_edit"])
|
||||
div_slider = "locked"
|
||||
output += {"<li>
|
||||
<label class="switch">
|
||||
<input type="[inputtype]" value="1" name="[i["name"]]"[i["checked"] ? " checked" : ""][i["allowed_edit"] ? "" : " onclick='return false' onkeydown='return false'"]>
|
||||
<div class="slider [div_slider ? "[div_slider]" : ""]"></div>
|
||||
<input type="[inputtype]" value="1" name="[i["name"]]"[i["checked"] ? " checked" : ""][i["allowed_edit"] ? "" : " disabled onclick='return false' onkeydown='return false'"]>
|
||||
<span>[i["name"]]</span>
|
||||
</label>
|
||||
</li>"}
|
||||
|
||||
@@ -196,6 +196,9 @@ var/list/runechat_image_cache = list()
|
||||
message.maptext_y = message_loc.runechat_y_offset(msgwidth, mheight)
|
||||
message.maptext = complete_text
|
||||
|
||||
if(!owner)
|
||||
qdel(src)
|
||||
return
|
||||
if(owner.contains(target)) // Special case, holding an atom speaking (pAI, recorder...)
|
||||
message.plane = PLANE_PLAYER_HUD_ABOVE
|
||||
|
||||
|
||||
@@ -188,7 +188,11 @@
|
||||
var/list/sig_types = islist(sig_type_or_types) ? sig_type_or_types : list(sig_type_or_types)
|
||||
for(var/sig_type in sig_types)
|
||||
if(!override && procs[target][sig_type])
|
||||
stack_trace("[sig_type] overridden. Use override = TRUE to suppress this warning")
|
||||
var/trace_msg = "[sig_type] overridden. Use override = TRUE to suppress this warning."
|
||||
if(isatom(target))
|
||||
var/atom/A = target
|
||||
trace_msg += " [A.x],[A.y],[A.z]"
|
||||
stack_trace(trace_msg)
|
||||
|
||||
procs[target][sig_type] = proctype
|
||||
|
||||
|
||||
@@ -0,0 +1,484 @@
|
||||
/*!
|
||||
This datum should be used for handling mineral contents of machines and whatever else is supposed to hold minerals and make use of them.
|
||||
|
||||
Variables:
|
||||
amount - raw amount of the mineral this container is holding, calculated by the defined value SHEET_MATERIAL_AMOUNT=2000.
|
||||
max_amount - max raw amount of mineral this container can hold.
|
||||
stack_type - type of the mineral sheet the container handles, used for output.
|
||||
parent - object that this container is being used by, used for output.
|
||||
MAX_STACK_SIZE - size of a stack of mineral sheets. Constant.
|
||||
*/
|
||||
|
||||
/datum/component/material_container
|
||||
/// The total amount of materials this material container contains
|
||||
var/total_amount = 0
|
||||
/// The maximum amount of materials this material container can contain
|
||||
var/max_amount
|
||||
/// Map of material ref -> amount
|
||||
var/list/materials //Map of key = material ref | Value = amount
|
||||
/// The list of materials that this material container can accept
|
||||
var/list/allowed_materials
|
||||
/// The typecache of things that this material container can accept
|
||||
var/list/allowed_item_typecache
|
||||
/// The last main material that was inserted into this container
|
||||
var/last_inserted_id
|
||||
/// A callback for checking wheter we can insert a material into this container
|
||||
var/datum/callback/insertion_check
|
||||
/// A callback invoked before materials are inserted into this container
|
||||
var/datum/callback/precondition
|
||||
/// A callback invoked after materials are inserted into this container
|
||||
var/datum/callback/after_insert
|
||||
/// The material container flags. See __DEFINES/materials.dm.
|
||||
var/mat_container_flags
|
||||
|
||||
/// Sets up the proper signals and fills the list of materials with the appropriate references.
|
||||
/datum/component/material_container/Initialize(list/init_mats, max_amt = 0, _mat_container_flags=NONE, list/allowed_mats=init_mats, list/allowed_items, datum/callback/_insertion_check, datum/callback/_precondition, datum/callback/_after_insert)
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
materials = list()
|
||||
max_amount = max(0, max_amt)
|
||||
mat_container_flags = _mat_container_flags
|
||||
|
||||
allowed_materials = allowed_mats || list()
|
||||
if(allowed_items)
|
||||
if(ispath(allowed_items) && allowed_items == /obj/item/stack)
|
||||
allowed_item_typecache = GLOB.typecache_stack
|
||||
else
|
||||
allowed_item_typecache = typecacheof(allowed_items)
|
||||
|
||||
insertion_check = _insertion_check
|
||||
precondition = _precondition
|
||||
after_insert = _after_insert
|
||||
|
||||
for(var/mat in init_mats) //Make the assoc list material reference -> amount
|
||||
var/mat_ref = GET_MATERIAL_REF(mat)
|
||||
if(isnull(mat_ref))
|
||||
continue
|
||||
var/mat_amt = init_mats[mat]
|
||||
if(isnull(mat_amt))
|
||||
mat_amt = 0
|
||||
materials[mat_ref] += mat_amt
|
||||
|
||||
/datum/component/material_container/Destroy(force, silent)
|
||||
materials = null
|
||||
allowed_materials = null
|
||||
if(insertion_check)
|
||||
QDEL_NULL(insertion_check)
|
||||
if(precondition)
|
||||
QDEL_NULL(precondition)
|
||||
if(after_insert)
|
||||
QDEL_NULL(after_insert)
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/component/material_container/RegisterWithParent()
|
||||
. = ..()
|
||||
|
||||
if(!(mat_container_flags & MATCONTAINER_NO_INSERT))
|
||||
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/on_attackby)
|
||||
if(mat_container_flags & MATCONTAINER_EXAMINE)
|
||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine)
|
||||
|
||||
|
||||
/datum/component/material_container/vv_edit_var(var_name, var_value)
|
||||
var/old_flags = mat_container_flags
|
||||
. = ..()
|
||||
if(var_name == NAMEOF(src, mat_container_flags) && parent)
|
||||
if(!(old_flags & MATCONTAINER_EXAMINE) && mat_container_flags & MATCONTAINER_EXAMINE)
|
||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine)
|
||||
else if(old_flags & MATCONTAINER_EXAMINE && !(mat_container_flags & MATCONTAINER_EXAMINE))
|
||||
UnregisterSignal(parent, COMSIG_PARENT_EXAMINE)
|
||||
|
||||
if(old_flags & MATCONTAINER_NO_INSERT && !(mat_container_flags & MATCONTAINER_NO_INSERT))
|
||||
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/on_attackby)
|
||||
else if(!(old_flags & MATCONTAINER_NO_INSERT) && mat_container_flags & MATCONTAINER_NO_INSERT)
|
||||
UnregisterSignal(parent, COMSIG_PARENT_ATTACKBY)
|
||||
|
||||
|
||||
/datum/component/material_container/proc/on_examine(datum/source, mob/user, list/examine_texts)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
for(var/I in materials)
|
||||
var/datum/material/M = I
|
||||
var/amt = materials[I]
|
||||
if(amt)
|
||||
examine_texts += "<span class='notice'>It has [amt] units of [lowertext(M.name)] stored.</span>"
|
||||
|
||||
/// Proc that allows players to fill the parent with mats
|
||||
/datum/component/material_container/proc/on_attackby(datum/source, obj/item/I, mob/living/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/list/tc = allowed_item_typecache
|
||||
if(!(mat_container_flags & MATCONTAINER_ANY_INTENT) && user.a_intent != I_HELP)
|
||||
return
|
||||
if(tc && !is_type_in_typecache(I, tc))
|
||||
if(!(mat_container_flags & MATCONTAINER_SILENT))
|
||||
to_chat(user, "<span class='warning'>[parent] won't accept [I]!</span>")
|
||||
return
|
||||
. = COMPONENT_NO_AFTERATTACK
|
||||
var/datum/callback/pc = precondition
|
||||
if(pc && !pc.Invoke(user))
|
||||
return
|
||||
if(istype(I, /obj/item/stack))
|
||||
var/obj/item/stack/S = I
|
||||
user_insert_stack(S, user, mat_container_flags)
|
||||
return
|
||||
var/material_amount = get_item_material_amount(I, mat_container_flags)
|
||||
if(!material_amount)
|
||||
to_chat(user, "<span class='warning'>[I] does not contain sufficient materials to be accepted by [parent].</span>")
|
||||
return
|
||||
if(!has_space(material_amount))
|
||||
to_chat(user, "<span class='warning'>[parent] is full. Please remove materials from [parent] in order to insert more.</span>")
|
||||
return
|
||||
user_insert(I, user, mat_container_flags)
|
||||
|
||||
/// Proc used for when player inserts a stack
|
||||
/datum/component/material_container/proc/user_insert_stack(obj/item/stack/S, mob/living/user, breakdown_flags = mat_container_flags)
|
||||
var/sheets = S.get_amount()
|
||||
if(sheets < 1)
|
||||
to_chat(user, "<span class='warning'>[S] does not contain sufficient materials to be accepted by [parent].</span>")
|
||||
return
|
||||
|
||||
// Cache this since S may go away after use()
|
||||
var/list/sheet_matter = S.matter
|
||||
|
||||
// Calculate total amount of material for one sheet
|
||||
var/matter_per_sheet = 0
|
||||
for(var/material in sheet_matter)
|
||||
matter_per_sheet += sheet_matter[material]
|
||||
|
||||
// If any part of a sheet can't go in us, the whole sheet is invalid
|
||||
if(!can_hold_material(GET_MATERIAL_REF(material)))
|
||||
to_chat(user, "<span class='warning'>[parent] cannot contain [material].</span>")
|
||||
return
|
||||
|
||||
// If we can't fit the material for one sheet, we're full.
|
||||
if(!has_space(matter_per_sheet))
|
||||
to_chat(user, "<span class='warning'>[parent] is full. Please remove materials from [parent] in order to insert more.</span>")
|
||||
return
|
||||
|
||||
// Calculate the maximum amount of sheets we could possibly accept.
|
||||
var/max_sheets = round((max_amount - total_amount) / matter_per_sheet)
|
||||
if(max_sheets <= 0)
|
||||
to_chat(user, "<span class='warning'>[parent] is full. Please remove materials from [parent] in order to insert more.</span>")
|
||||
return
|
||||
|
||||
// Calculate the amount of sheets we're actually going to use.
|
||||
var/sheets_to_use = min(sheets, max_sheets)
|
||||
|
||||
// It shouldn't be possible to add more matter than our max
|
||||
ASSERT((total_amount + (matter_per_sheet * sheets_to_use)) <= max_amount)
|
||||
|
||||
// Use the amount of sheets from the stack
|
||||
if(!S.use(sheets_to_use))
|
||||
to_chat(user, "<span class='warning'>Something went wrong with your stack. Split it manually and try again.</span>")
|
||||
return
|
||||
|
||||
// We're going to blindly insert all of the materials, our assertion above says it shouldn't be possible to overflow
|
||||
var/inserted = 0
|
||||
for(var/matter in sheet_matter)
|
||||
var/datum/material/MAT = GET_MATERIAL_REF(matter)
|
||||
inserted += insert_amount_mat(sheet_matter[matter] * sheets_to_use, MAT)
|
||||
last_inserted_id = matter
|
||||
|
||||
// Tell the user and wrap up.
|
||||
to_chat(user, "<span class='notice'>You insert a material total of [inserted] into [parent].</span>")
|
||||
if(after_insert)
|
||||
after_insert.Invoke(S, last_inserted_id, inserted)
|
||||
|
||||
/// Proc used for when player inserts materials
|
||||
/datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user, breakdown_flags = mat_container_flags)
|
||||
set waitfor = FALSE
|
||||
var/active_held = user.get_active_hand() // differs from I when using TK
|
||||
if(!user.unEquip(I))
|
||||
to_chat(user, "<span class='warning'>[I] is stuck to you and cannot be placed into [parent].</span>")
|
||||
return
|
||||
var/inserted = insert_item(I, breakdown_flags = mat_container_flags)
|
||||
if(inserted)
|
||||
to_chat(user, "<span class='notice'>You insert a material total of [inserted] into [parent].</span>")
|
||||
qdel(I)
|
||||
if(after_insert)
|
||||
after_insert.Invoke(I, last_inserted_id, inserted)
|
||||
else if(I == active_held)
|
||||
user.put_in_active_hand(I)
|
||||
|
||||
/// Proc specifically for inserting items, returns the amount of materials entered.
|
||||
/datum/component/material_container/proc/insert_item(obj/item/I, multiplier = 1, breakdown_flags = mat_container_flags)
|
||||
if(QDELETED(I))
|
||||
return FALSE
|
||||
|
||||
multiplier = CEILING(multiplier, 0.01)
|
||||
|
||||
var/material_amount = get_item_material_amount(I, breakdown_flags)
|
||||
if(!material_amount || !has_space(material_amount))
|
||||
return FALSE
|
||||
|
||||
last_inserted_id = insert_item_materials(I, multiplier, breakdown_flags)
|
||||
return material_amount
|
||||
|
||||
/**
|
||||
* Inserts the relevant materials from an item into this material container.
|
||||
*
|
||||
* Arguments:
|
||||
* - [source][/obj/item]: The source of the materials we are inserting.
|
||||
* - multiplier: The multiplier for the materials being inserted.
|
||||
* - breakdown_flags: The breakdown bitflags that will be used to retrieve the materials from the source
|
||||
*/
|
||||
/datum/component/material_container/proc/insert_item_materials(obj/item/source, multiplier = 1, breakdown_flags = mat_container_flags)
|
||||
var/primary_mat
|
||||
var/max_mat_value = 0
|
||||
var/list/item_materials = source.get_material_composition(breakdown_flags)
|
||||
for(var/MAT in item_materials)
|
||||
if(!can_hold_material(MAT))
|
||||
continue
|
||||
materials[MAT] += item_materials[MAT] * multiplier
|
||||
total_amount += item_materials[MAT] * multiplier
|
||||
if(item_materials[MAT] > max_mat_value)
|
||||
max_mat_value = item_materials[MAT]
|
||||
primary_mat = MAT
|
||||
|
||||
return primary_mat
|
||||
|
||||
/**
|
||||
* The default check for whether we can add materials to this material container.
|
||||
*
|
||||
* Arguments:
|
||||
* - [mat][/atom/material]: The material we are checking for insertability.
|
||||
*/
|
||||
/datum/component/material_container/proc/can_hold_material(datum/material/mat)
|
||||
if(mat in allowed_materials)
|
||||
return TRUE
|
||||
if(istype(mat) && ((mat.name in allowed_materials) || (mat.type in allowed_materials)))
|
||||
allowed_materials += mat // This could get messy with passing lists by ref... but if you're doing that the list expansion is probably being taken care of elsewhere anyway...
|
||||
return TRUE
|
||||
if(insertion_check?.Invoke(mat))
|
||||
allowed_materials += mat
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/// For inserting an amount of material
|
||||
/datum/component/material_container/proc/insert_amount_mat(amt, datum/material/mat)
|
||||
if(amt <= 0 || !has_space(amt))
|
||||
return 0
|
||||
|
||||
var/total_amount_saved = total_amount
|
||||
if(mat)
|
||||
if(!istype(mat))
|
||||
mat = GET_MATERIAL_REF(mat)
|
||||
materials[mat] += amt
|
||||
total_amount += amt
|
||||
else
|
||||
var/num_materials = length(materials)
|
||||
if(!num_materials)
|
||||
return 0
|
||||
|
||||
amt /= num_materials
|
||||
for(var/i in materials)
|
||||
materials[i] += amt
|
||||
total_amount += amt
|
||||
return (total_amount - total_amount_saved)
|
||||
|
||||
/// Uses an amount of a specific material, effectively removing it.
|
||||
/datum/component/material_container/proc/use_amount_mat(amt, datum/material/mat)
|
||||
if(!istype(mat))
|
||||
mat = GET_MATERIAL_REF(mat)
|
||||
|
||||
if(!mat)
|
||||
return 0
|
||||
var/amount = materials[mat]
|
||||
if(amount < amt)
|
||||
return 0
|
||||
|
||||
materials[mat] -= amt
|
||||
total_amount -= amt
|
||||
return amt
|
||||
|
||||
/// Proc for transfering materials to another container.
|
||||
/datum/component/material_container/proc/transer_amt_to(datum/component/material_container/T, amt, datum/material/mat)
|
||||
if(!istype(mat))
|
||||
mat = GET_MATERIAL_REF(mat)
|
||||
if((amt==0)||(!T)||(!mat))
|
||||
return FALSE
|
||||
if(amt<0)
|
||||
return T.transer_amt_to(src, -amt, mat)
|
||||
var/tr = min(amt, materials[mat], T.can_insert_amount_mat(amt, mat))
|
||||
if(tr)
|
||||
use_amount_mat(tr, mat)
|
||||
T.insert_amount_mat(tr, mat)
|
||||
return tr
|
||||
return FALSE
|
||||
|
||||
/// Proc for checking if there is room in the component, returning the amount or else the amount lacking.
|
||||
/datum/component/material_container/proc/can_insert_amount_mat(amt, datum/material/mat)
|
||||
if(!amt || !mat)
|
||||
return 0
|
||||
|
||||
if((total_amount + amt) <= max_amount)
|
||||
return amt
|
||||
else
|
||||
return (max_amount - total_amount)
|
||||
|
||||
|
||||
/// For consuming a dictionary of materials. mats is the map of materials to use and the corresponding amounts, example: list(M/datum/material/glass =100, datum/material/iron=200)
|
||||
/datum/component/material_container/proc/use_materials(list/mats, multiplier=1)
|
||||
if(!mats || !length(mats))
|
||||
return FALSE
|
||||
|
||||
var/list/mats_to_remove = list() //Assoc list MAT | AMOUNT
|
||||
|
||||
for(var/x in mats) //Loop through all required materials
|
||||
var/datum/material/req_mat = x
|
||||
if(!istype(req_mat))
|
||||
req_mat = GET_MATERIAL_REF(req_mat) //Get the ref if necesary
|
||||
if(!materials[req_mat]) //Do we have the resource?
|
||||
return FALSE //Can't afford it
|
||||
var/amount_required = mats[x] * multiplier
|
||||
if(!(materials[req_mat] >= amount_required)) // do we have enough of the resource?
|
||||
return FALSE //Can't afford it
|
||||
mats_to_remove[req_mat] += amount_required //Add it to the assoc list of things to remove
|
||||
continue
|
||||
|
||||
var/total_amount_save = total_amount
|
||||
|
||||
for(var/i in mats_to_remove)
|
||||
total_amount_save -= use_amount_mat(mats_to_remove[i], i)
|
||||
|
||||
return total_amount_save - total_amount
|
||||
|
||||
/// For spawning mineral sheets at a specific location. Used by machines to output sheets.
|
||||
/datum/component/material_container/proc/retrieve_sheets(sheet_amt, datum/material/M, atom/target = null)
|
||||
if(!M.stack_type)
|
||||
return 0 //Add greyscale sheet handling here later
|
||||
if(sheet_amt <= 0)
|
||||
return 0
|
||||
|
||||
if(!target)
|
||||
var/atom/parent_atom = parent
|
||||
target = parent_atom.drop_location()
|
||||
if(materials[M] < (sheet_amt * SHEET_MATERIAL_AMOUNT))
|
||||
sheet_amt = round(materials[M] / SHEET_MATERIAL_AMOUNT)
|
||||
|
||||
var/obj/item/stack/S = M.stack_type
|
||||
var/max_stack_size = initial(S.max_amount)
|
||||
|
||||
var/count = 0
|
||||
while(sheet_amt > max_stack_size)
|
||||
new M.stack_type(target, max_stack_size, null, list((M) = SHEET_MATERIAL_AMOUNT))
|
||||
count += max_stack_size
|
||||
use_amount_mat(sheet_amt * SHEET_MATERIAL_AMOUNT, M)
|
||||
sheet_amt -= max_stack_size
|
||||
if(sheet_amt >= 1)
|
||||
new M.stack_type(target, sheet_amt, null, list((M) = SHEET_MATERIAL_AMOUNT))
|
||||
count += sheet_amt
|
||||
use_amount_mat(sheet_amt * SHEET_MATERIAL_AMOUNT, M)
|
||||
return count
|
||||
|
||||
|
||||
/// Proc to get all the materials and dump them as sheets
|
||||
/datum/component/material_container/proc/retrieve_all(target = null)
|
||||
var/result = 0
|
||||
for(var/MAT in materials)
|
||||
var/amount = materials[MAT]
|
||||
result += retrieve_sheets(amount2sheet(amount), MAT, target)
|
||||
return result
|
||||
|
||||
/// Proc that returns TRUE if the container has space
|
||||
/datum/component/material_container/proc/has_space(amt = 0)
|
||||
return (total_amount + amt) <= max_amount
|
||||
|
||||
/// Checks if its possible to afford a certain amount of materials. Takes a dictionary of materials.
|
||||
/datum/component/material_container/proc/has_materials(list/mats, multiplier=1)
|
||||
if(!mats || !mats.len)
|
||||
return FALSE
|
||||
|
||||
for(var/x in mats) //Loop through all required materials
|
||||
var/datum/material/req_mat = x
|
||||
if(!istype(req_mat))
|
||||
if(ispath(req_mat) || istext(req_mat)) //Is this an actual material, or is it a category?
|
||||
req_mat = GET_MATERIAL_REF(req_mat) //Get the ref
|
||||
|
||||
// else // Its a category. (For example MAT_CATEGORY_RIGID)
|
||||
// if(!has_enough_of_category(req_mat, mats[x], multiplier)) //Do we have enough of this category?
|
||||
// return FALSE
|
||||
// else
|
||||
// continue
|
||||
|
||||
if(!has_enough_of_material(req_mat, mats[x], multiplier))//Not a category, so just check the normal way
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/// Returns all the categories in a recipe.
|
||||
/datum/component/material_container/proc/get_categories(list/mats)
|
||||
var/list/categories = list()
|
||||
for(var/x in mats) //Loop through all required materials
|
||||
if(!istext(x)) //This means its not a category
|
||||
continue
|
||||
categories += x
|
||||
return categories
|
||||
|
||||
/// Returns TRUE if you have enough of the specified material.
|
||||
/datum/component/material_container/proc/has_enough_of_material(datum/material/req_mat, amount, multiplier=1)
|
||||
if(!materials[req_mat]) //Do we have the resource?
|
||||
return FALSE //Can't afford it
|
||||
var/amount_required = amount * multiplier
|
||||
if(materials[req_mat] >= amount_required) // do we have enough of the resource?
|
||||
return TRUE
|
||||
return FALSE //Can't afford it
|
||||
|
||||
/// Returns TRUE if you have enough of a specified material category (Which could be multiple materials)
|
||||
// /datum/component/material_container/proc/has_enough_of_category(category, amount, multiplier=1)
|
||||
// for(var/i in SSmaterials.materials_by_category[category])
|
||||
// var/datum/material/mat = i
|
||||
// if(materials[mat] >= amount) //we have enough
|
||||
// return TRUE
|
||||
// return FALSE
|
||||
|
||||
/// Turns a material amount into the amount of sheets it should output
|
||||
/datum/component/material_container/proc/amount2sheet(amt)
|
||||
if(amt >= SHEET_MATERIAL_AMOUNT)
|
||||
return round(amt / SHEET_MATERIAL_AMOUNT)
|
||||
return FALSE
|
||||
|
||||
/// Turns an amount of sheets into the amount of material amount it should output
|
||||
/datum/component/material_container/proc/sheet2amount(sheet_amt)
|
||||
if(sheet_amt > 0)
|
||||
return sheet_amt * SHEET_MATERIAL_AMOUNT
|
||||
return FALSE
|
||||
|
||||
|
||||
///returns the amount of material relevant to this container; if this container does not support glass, any glass in 'I' will not be taken into account
|
||||
/datum/component/material_container/proc/get_item_material_amount(obj/item/I, breakdown_flags = mat_container_flags)
|
||||
if(!istype(I) || !I.matter)
|
||||
return 0
|
||||
var/material_amount = 0
|
||||
var/list/item_materials = I.get_material_composition(breakdown_flags)
|
||||
for(var/MAT in item_materials)
|
||||
if(!can_hold_material(MAT))
|
||||
continue
|
||||
material_amount += item_materials[MAT]
|
||||
return material_amount
|
||||
|
||||
/// Returns the amount of a specific material in this container.
|
||||
/datum/component/material_container/proc/get_material_amount(datum/material/mat)
|
||||
if(!istype(mat))
|
||||
mat = GET_MATERIAL_REF(mat)
|
||||
return materials[mat]
|
||||
|
||||
/// List format is list(list(name = ..., amount = ..., ref = ..., etc.), list(...))
|
||||
/datum/component/material_container/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
for(var/datum/material/material as anything in materials)
|
||||
var/amount = materials[material]
|
||||
|
||||
data += list(list(
|
||||
"name" = material.name,
|
||||
"ref" = REF(material),
|
||||
"amount" = amount,
|
||||
"sheets" = round(amount / SHEET_MATERIAL_AMOUNT),
|
||||
"removable" = amount >= SHEET_MATERIAL_AMOUNT,
|
||||
))
|
||||
|
||||
return data
|
||||
@@ -0,0 +1,518 @@
|
||||
///For switchable lights, is it on and currently emitting light?
|
||||
#define LIGHTING_ON (1<<0)
|
||||
///Is the parent attached to something else, its loc? Then we need to keep an eye of this.
|
||||
#define LIGHTING_ATTACHED (1<<1)
|
||||
|
||||
#define GET_PARENT (parent_attached_to || parent)
|
||||
|
||||
#define GET_LIGHT_SOURCE (directional_atom || current_holder)
|
||||
|
||||
#define SHORT_CAST 2
|
||||
|
||||
/**
|
||||
* Movable atom overlay-based lighting component.
|
||||
*
|
||||
* * Component works by applying a visual object to the parent target.
|
||||
*
|
||||
* * The component tracks the parent's loc to determine the current_holder.
|
||||
* * The current_holder is either the parent or its loc, whichever is on a turf. If none, then the current_holder is null and the light is not visible.
|
||||
*
|
||||
* * Lighting works at its base by applying a dark overlay and "cutting" said darkness with light, adding (possibly colored) transparency.
|
||||
* * This component uses the visible_mask visual object to apply said light mask on the darkness.
|
||||
*
|
||||
* * The main limitation of this system is that it uses a limited number of pre-baked geometrical shapes, but for most uses it does the job.
|
||||
*
|
||||
* * Another limitation is for big lights: you only see the light if you see the object emiting it.
|
||||
* * For small objects this is good (you can't see them behind a wall), but for big ones this quickly becomes prety clumsy.
|
||||
*/
|
||||
/datum/component/overlay_lighting
|
||||
///How far the light reaches, float.
|
||||
var/range = 1
|
||||
///Ceiling of range, integer without decimal entries.
|
||||
var/lumcount_range = 0
|
||||
///How much this light affects the dynamic_lumcount of turfs.
|
||||
var/lum_power = 0.5
|
||||
///Transparency value.
|
||||
var/set_alpha = 0
|
||||
///For light sources that can be turned on and off.
|
||||
var/overlay_lighting_flags = NONE
|
||||
|
||||
///Cache of the possible light overlays, according to size.
|
||||
var/static/list/light_overlays = list(
|
||||
"32" = 'icons/effects/light_overlays/light_32.dmi',
|
||||
"64" = 'icons/effects/light_overlays/light_64.dmi',
|
||||
"96" = 'icons/effects/light_overlays/light_96.dmi',
|
||||
"128" = 'icons/effects/light_overlays/light_128.dmi',
|
||||
"160" = 'icons/effects/light_overlays/light_160.dmi',
|
||||
"192" = 'icons/effects/light_overlays/light_192.dmi',
|
||||
"224" = 'icons/effects/light_overlays/light_224.dmi',
|
||||
"256" = 'icons/effects/light_overlays/light_256.dmi',
|
||||
"288" = 'icons/effects/light_overlays/light_288.dmi',
|
||||
"320" = 'icons/effects/light_overlays/light_320.dmi',
|
||||
"352" = 'icons/effects/light_overlays/light_352.dmi',
|
||||
)
|
||||
|
||||
///Overlay effect to cut into the darkness and provide light.
|
||||
var/obj/effect/overlay/light_visible/visible_mask
|
||||
///Lazy list to track the turfs being affected by our light, to determine their visibility.
|
||||
var/list/turf/affected_turfs
|
||||
///Movable atom currently holding the light. Parent might be a flashlight, for example, but that might be held by a mob or something else.
|
||||
var/atom/movable/current_holder
|
||||
///Movable atom the parent is attached to. For example, a flashlight into a helmet or gun. We'll need to track the thing the parent is attached to as if it were the parent itself.
|
||||
var/atom/movable/parent_attached_to
|
||||
///Whether we're a directional light
|
||||
var/directional
|
||||
///Abstractional atom for directional light, we move this around to make the directional effect
|
||||
var/obj/effect/abstract/directional_lighting/directional_atom
|
||||
///A cone overlay for directional light, it's alpha and color are dependant on the light
|
||||
var/obj/effect/overlay/light_cone/cone
|
||||
///Current tracked direction for the directional cast behaviour
|
||||
var/current_direction
|
||||
///Cast range for the directional cast (how far away the atom is moved)
|
||||
var/cast_range = 2
|
||||
///Cone offset X hint from atom, used when facing south, inverted when facing north
|
||||
var/cone_hint_x
|
||||
///Cone offset Y hint from atom, when facing east/west, ignored for north/south (uses 16 in those cases)
|
||||
var/cone_hint_y
|
||||
|
||||
|
||||
/datum/component/overlay_lighting/Initialize(_range, _power, _color, starts_on, is_directional)
|
||||
if(!ismovable(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
var/atom/movable/movable_parent = parent
|
||||
if(movable_parent.light_system != MOVABLE_LIGHT && movable_parent.light_system != MOVABLE_LIGHT_DIRECTIONAL)
|
||||
stack_trace("[type] added to [parent], with [movable_parent.light_system] value for the light_system var. Use [MOVABLE_LIGHT] or [MOVABLE_LIGHT_DIRECTIONAL] instead.")
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
. = ..()
|
||||
|
||||
visible_mask = new()
|
||||
if(is_directional)
|
||||
directional = TRUE
|
||||
directional_atom = new()
|
||||
cone = new()
|
||||
cone_hint_x = movable_parent.light_cone_x_offset
|
||||
cone_hint_y = movable_parent.light_cone_y_offset
|
||||
cone.transform = cone.transform.Translate(-32, -32)
|
||||
set_direction(movable_parent.dir)
|
||||
if(!isnull(_range))
|
||||
movable_parent.set_light_range(_range)
|
||||
set_range(parent, movable_parent.light_range)
|
||||
if(!isnull(_power))
|
||||
movable_parent.set_light_power(_power)
|
||||
set_power(parent, movable_parent.light_power)
|
||||
if(!isnull(_color))
|
||||
movable_parent.set_light_color(_color)
|
||||
set_color(parent, movable_parent.light_color)
|
||||
if(!isnull(starts_on))
|
||||
movable_parent.set_light_on(starts_on)
|
||||
|
||||
|
||||
/datum/component/overlay_lighting/RegisterWithParent()
|
||||
. = ..()
|
||||
if(directional)
|
||||
RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/on_parent_dir_change)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/on_parent_moved)
|
||||
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_RANGE, .proc/set_range)
|
||||
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_POWER, .proc/set_power)
|
||||
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_COLOR, .proc/set_color)
|
||||
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_ON, .proc/on_toggle)
|
||||
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_FLAGS, .proc/on_light_flags_change)
|
||||
RegisterSignal(parent, COMSIG_ATOM_USED_IN_CRAFT, .proc/on_parent_crafted)
|
||||
RegisterSignal(parent, COMSIG_LIGHT_EATER_QUEUE, .proc/on_light_eater)
|
||||
var/atom/movable/movable_parent = parent
|
||||
if(movable_parent.light_flags & LIGHT_ATTACHED)
|
||||
overlay_lighting_flags |= LIGHTING_ATTACHED
|
||||
set_parent_attached_to(ismovable(movable_parent.loc) ? movable_parent.loc : null)
|
||||
check_holder()
|
||||
if(movable_parent.light_on)
|
||||
turn_on()
|
||||
|
||||
|
||||
/datum/component/overlay_lighting/UnregisterFromParent()
|
||||
overlay_lighting_flags &= ~LIGHTING_ATTACHED
|
||||
set_parent_attached_to(null)
|
||||
set_holder(null)
|
||||
clean_old_turfs()
|
||||
UnregisterSignal(parent, list(
|
||||
COMSIG_MOVABLE_MOVED,
|
||||
COMSIG_ATOM_UPDATE_LIGHT_RANGE,
|
||||
COMSIG_ATOM_UPDATE_LIGHT_POWER,
|
||||
COMSIG_ATOM_UPDATE_LIGHT_COLOR,
|
||||
COMSIG_ATOM_UPDATE_LIGHT_ON,
|
||||
COMSIG_ATOM_UPDATE_LIGHT_FLAGS,
|
||||
COMSIG_ATOM_USED_IN_CRAFT,
|
||||
COMSIG_LIGHT_EATER_QUEUE,
|
||||
))
|
||||
if(directional)
|
||||
UnregisterSignal(parent, COMSIG_ATOM_DIR_CHANGE)
|
||||
if(overlay_lighting_flags & LIGHTING_ON)
|
||||
turn_off()
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/component/overlay_lighting/Destroy()
|
||||
set_parent_attached_to(null)
|
||||
set_holder(null)
|
||||
clean_old_turfs()
|
||||
|
||||
qdel(visible_mask, TRUE)
|
||||
visible_mask = null
|
||||
|
||||
if(directional)
|
||||
qdel(directional_atom, TRUE)
|
||||
directional_atom = null
|
||||
|
||||
qdel(cone, TRUE)
|
||||
cone = null
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
///Clears the affected_turfs lazylist, removing from its contents the effects of being near the light.
|
||||
/datum/component/overlay_lighting/proc/clean_old_turfs()
|
||||
for(var/t in affected_turfs)
|
||||
var/turf/lit_turf = t
|
||||
lit_turf.dynamic_lumcount -= lum_power
|
||||
affected_turfs = null
|
||||
|
||||
|
||||
///Populates the affected_turfs lazylist, adding to its contents the effects of being near the light.
|
||||
/datum/component/overlay_lighting/proc/get_new_turfs()
|
||||
if(!current_holder)
|
||||
return
|
||||
var/atom/movable/light_source = GET_LIGHT_SOURCE
|
||||
for(var/turf/lit_turf in view(lumcount_range, get_turf(light_source)))
|
||||
lit_turf.dynamic_lumcount += lum_power
|
||||
LAZYADD(affected_turfs, lit_turf)
|
||||
|
||||
|
||||
///Clears the old affected turfs and populates the new ones.
|
||||
/datum/component/overlay_lighting/proc/make_luminosity_update()
|
||||
clean_old_turfs()
|
||||
if(!isturf(current_holder?.loc))
|
||||
return
|
||||
if(directional)
|
||||
cast_directional_light()
|
||||
get_new_turfs()
|
||||
|
||||
|
||||
///Adds the luminosity and source for the afected movable atoms to keep track of their visibility.
|
||||
/datum/component/overlay_lighting/proc/add_dynamic_lumi()
|
||||
var/atom/movable/light_source = GET_LIGHT_SOURCE
|
||||
LAZYSET(light_source.affected_dynamic_lights, src, lumcount_range + 1)
|
||||
light_source.vis_contents += visible_mask
|
||||
light_source.update_dynamic_luminosity()
|
||||
if(directional)
|
||||
current_holder.vis_contents += cone
|
||||
|
||||
///Removes the luminosity and source for the afected movable atoms to keep track of their visibility.
|
||||
/datum/component/overlay_lighting/proc/remove_dynamic_lumi()
|
||||
var/atom/movable/light_source = GET_LIGHT_SOURCE
|
||||
LAZYREMOVE(light_source.affected_dynamic_lights, src)
|
||||
light_source.vis_contents -= visible_mask
|
||||
light_source.update_dynamic_luminosity()
|
||||
if(directional)
|
||||
current_holder.vis_contents -= cone
|
||||
directional_atom.moveToNullspace()
|
||||
|
||||
///Called to change the value of parent_attached_to.
|
||||
/datum/component/overlay_lighting/proc/set_parent_attached_to(atom/movable/new_parent_attached_to)
|
||||
if(new_parent_attached_to == parent_attached_to)
|
||||
return
|
||||
|
||||
. = parent_attached_to
|
||||
parent_attached_to = new_parent_attached_to
|
||||
if(.)
|
||||
var/atom/movable/old_parent_attached_to = .
|
||||
UnregisterSignal(old_parent_attached_to, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED, COMSIG_LIGHT_EATER_QUEUE))
|
||||
if(old_parent_attached_to == current_holder)
|
||||
RegisterSignal(old_parent_attached_to, COMSIG_PARENT_QDELETING, .proc/on_holder_qdel)
|
||||
RegisterSignal(old_parent_attached_to, COMSIG_MOVABLE_MOVED, .proc/on_holder_moved)
|
||||
RegisterSignal(old_parent_attached_to, COMSIG_LIGHT_EATER_QUEUE, .proc/on_light_eater)
|
||||
if(parent_attached_to)
|
||||
if(parent_attached_to == current_holder)
|
||||
UnregisterSignal(current_holder, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED, COMSIG_LIGHT_EATER_QUEUE))
|
||||
RegisterSignal(parent_attached_to, COMSIG_PARENT_QDELETING, .proc/on_parent_attached_to_qdel)
|
||||
RegisterSignal(parent_attached_to, COMSIG_MOVABLE_MOVED, .proc/on_parent_attached_to_moved)
|
||||
RegisterSignal(parent_attached_to, COMSIG_LIGHT_EATER_QUEUE, .proc/on_light_eater)
|
||||
check_holder()
|
||||
|
||||
|
||||
///Called to change the value of current_holder.
|
||||
/datum/component/overlay_lighting/proc/set_holder(atom/movable/new_holder)
|
||||
if(new_holder == current_holder)
|
||||
return
|
||||
if(current_holder)
|
||||
if(current_holder != parent && current_holder != parent_attached_to)
|
||||
UnregisterSignal(current_holder, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED, COMSIG_LIGHT_EATER_QUEUE))
|
||||
if(directional)
|
||||
UnregisterSignal(current_holder, COMSIG_ATOM_DIR_CHANGE)
|
||||
if(overlay_lighting_flags & LIGHTING_ON)
|
||||
remove_dynamic_lumi()
|
||||
current_holder = new_holder
|
||||
if(new_holder == null)
|
||||
clean_old_turfs()
|
||||
return
|
||||
if(new_holder != parent && new_holder != parent_attached_to)
|
||||
RegisterSignal(new_holder, COMSIG_PARENT_QDELETING, .proc/on_holder_qdel)
|
||||
RegisterSignal(new_holder, COMSIG_MOVABLE_MOVED, .proc/on_holder_moved)
|
||||
RegisterSignal(new_holder, COMSIG_LIGHT_EATER_QUEUE, .proc/on_light_eater)
|
||||
if(directional)
|
||||
RegisterSignal(new_holder, COMSIG_ATOM_DIR_CHANGE, .proc/on_holder_dir_change)
|
||||
if(overlay_lighting_flags & LIGHTING_ON)
|
||||
make_luminosity_update()
|
||||
add_dynamic_lumi()
|
||||
|
||||
|
||||
///Used to determine the new valid current_holder from the parent's loc.
|
||||
/datum/component/overlay_lighting/proc/check_holder()
|
||||
var/atom/movable/movable_parent = GET_PARENT
|
||||
if(isturf(movable_parent.loc))
|
||||
set_holder(movable_parent)
|
||||
return
|
||||
var/atom/inside = movable_parent.loc //Parent's loc
|
||||
if(isnull(inside))
|
||||
set_holder(null)
|
||||
return
|
||||
if(isturf(inside.loc))
|
||||
set_holder(inside)
|
||||
return
|
||||
set_holder(null)
|
||||
|
||||
|
||||
///Called when the current_holder is qdeleted, to remove the light effect.
|
||||
/datum/component/overlay_lighting/proc/on_holder_qdel(atom/movable/source, force)
|
||||
SIGNAL_HANDLER
|
||||
UnregisterSignal(current_holder, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED))
|
||||
if(directional)
|
||||
UnregisterSignal(current_holder, COMSIG_ATOM_DIR_CHANGE)
|
||||
set_holder(null)
|
||||
|
||||
|
||||
///Called when current_holder changes loc.
|
||||
/datum/component/overlay_lighting/proc/on_holder_moved(atom/movable/source, OldLoc, Dir, Forced)
|
||||
SIGNAL_HANDLER
|
||||
if(!(overlay_lighting_flags & LIGHTING_ON))
|
||||
return
|
||||
make_luminosity_update()
|
||||
|
||||
|
||||
///Called when parent changes loc.
|
||||
/datum/component/overlay_lighting/proc/on_parent_moved(atom/movable/source, OldLoc, Dir, Forced)
|
||||
SIGNAL_HANDLER
|
||||
var/atom/movable/movable_parent = parent
|
||||
if(overlay_lighting_flags & LIGHTING_ATTACHED)
|
||||
set_parent_attached_to(ismovable(movable_parent.loc) ? movable_parent.loc : null)
|
||||
check_holder()
|
||||
if(!(overlay_lighting_flags & LIGHTING_ON) || !current_holder)
|
||||
return
|
||||
make_luminosity_update()
|
||||
|
||||
|
||||
///Called when the current_holder is qdeleted, to remove the light effect.
|
||||
/datum/component/overlay_lighting/proc/on_parent_attached_to_qdel(atom/movable/source, force)
|
||||
SIGNAL_HANDLER
|
||||
UnregisterSignal(parent_attached_to, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED))
|
||||
if(directional)
|
||||
UnregisterSignal(parent_attached_to, COMSIG_ATOM_DIR_CHANGE)
|
||||
if(parent_attached_to == current_holder)
|
||||
set_holder(null)
|
||||
set_parent_attached_to(null)
|
||||
|
||||
|
||||
///Called when parent_attached_to changes loc.
|
||||
/datum/component/overlay_lighting/proc/on_parent_attached_to_moved(atom/movable/source, OldLoc, Dir, Forced)
|
||||
SIGNAL_HANDLER
|
||||
check_holder()
|
||||
if(!(overlay_lighting_flags & LIGHTING_ON) || !current_holder)
|
||||
return
|
||||
make_luminosity_update()
|
||||
|
||||
|
||||
///Changes the range which the light reaches. 0 means no light, 6 is the maximum value.
|
||||
/datum/component/overlay_lighting/proc/set_range(atom/source, old_range)
|
||||
SIGNAL_HANDLER
|
||||
var/new_range = source.light_range
|
||||
if(range == new_range)
|
||||
return
|
||||
if(range == 0)
|
||||
turn_off()
|
||||
range = clamp(CEILING(new_range, 0.5), 1, 6)
|
||||
var/pixel_bounds = ((range - 1) * 64) + 32
|
||||
lumcount_range = CEILING(range, 1)
|
||||
visible_mask.icon = light_overlays["[pixel_bounds]"]
|
||||
if(pixel_bounds == 32)
|
||||
visible_mask.transform = null
|
||||
return
|
||||
var/offset = (pixel_bounds - 32) * 0.5
|
||||
var/matrix/transform = new
|
||||
transform.Translate(-offset, -offset)
|
||||
visible_mask.transform = transform
|
||||
if(directional)
|
||||
cast_range = clamp(round(new_range * 0.5), 1, 3)
|
||||
if(overlay_lighting_flags & LIGHTING_ON)
|
||||
make_luminosity_update()
|
||||
|
||||
|
||||
///Changes the intensity/brightness of the light by altering the visual object's alpha.
|
||||
/datum/component/overlay_lighting/proc/set_power(atom/source, old_power)
|
||||
SIGNAL_HANDLER
|
||||
var/new_power = source.light_power
|
||||
set_lum_power(new_power >= 0 ? 0.5 : -0.5)
|
||||
set_alpha = min(230, (abs(new_power) * 120) + 30)
|
||||
visible_mask.alpha = set_alpha
|
||||
if(directional)
|
||||
cone.alpha = min(200, (abs(new_power) * 90)+20)
|
||||
|
||||
|
||||
///Changes the light's color, pretty straightforward.
|
||||
/datum/component/overlay_lighting/proc/set_color(atom/source, old_color)
|
||||
SIGNAL_HANDLER
|
||||
var/new_color = source.light_color
|
||||
visible_mask.color = new_color
|
||||
if(directional)
|
||||
cone.color = new_color
|
||||
|
||||
|
||||
///Toggles the light on and off.
|
||||
/datum/component/overlay_lighting/proc/on_toggle(atom/source, old_value)
|
||||
SIGNAL_HANDLER
|
||||
var/new_value = source.light_on
|
||||
if(new_value) //Truthy value input, turn on.
|
||||
turn_on()
|
||||
return
|
||||
turn_off() //Falsey value, turn off.
|
||||
|
||||
|
||||
///Triggered right after the parent light flags change.
|
||||
/datum/component/overlay_lighting/proc/on_light_flags_change(atom/source, old_flags)
|
||||
SIGNAL_HANDLER
|
||||
var/new_flags = source.light_flags
|
||||
var/atom/movable/movable_parent = parent
|
||||
if(!((new_flags ^ old_flags) & LIGHT_ATTACHED))
|
||||
return
|
||||
|
||||
if(new_flags & LIGHT_ATTACHED) // Gained the [LIGHT_ATTACHED] property
|
||||
overlay_lighting_flags |= LIGHTING_ATTACHED
|
||||
if(ismovable(movable_parent.loc))
|
||||
set_parent_attached_to(movable_parent.loc)
|
||||
else // Lost the [LIGHT_ATTACHED] property
|
||||
overlay_lighting_flags &= ~LIGHTING_ATTACHED
|
||||
set_parent_attached_to(null)
|
||||
|
||||
|
||||
///Toggles the light on.
|
||||
/datum/component/overlay_lighting/proc/turn_on()
|
||||
if(overlay_lighting_flags & LIGHTING_ON)
|
||||
return
|
||||
if(current_holder)
|
||||
if(directional)
|
||||
cast_directional_light()
|
||||
add_dynamic_lumi()
|
||||
overlay_lighting_flags |= LIGHTING_ON
|
||||
get_new_turfs()
|
||||
|
||||
|
||||
///Toggles the light off.
|
||||
/datum/component/overlay_lighting/proc/turn_off()
|
||||
if(!(overlay_lighting_flags & LIGHTING_ON))
|
||||
return
|
||||
if(current_holder)
|
||||
remove_dynamic_lumi()
|
||||
overlay_lighting_flags &= ~LIGHTING_ON
|
||||
clean_old_turfs()
|
||||
|
||||
|
||||
///Here we append the behavior associated to changing lum_power.
|
||||
/datum/component/overlay_lighting/proc/set_lum_power(new_lum_power)
|
||||
if(lum_power == new_lum_power)
|
||||
return
|
||||
. = lum_power
|
||||
lum_power = new_lum_power
|
||||
var/difference = . - lum_power
|
||||
for(var/t in affected_turfs)
|
||||
var/turf/lit_turf = t
|
||||
lit_turf.dynamic_lumcount -= difference
|
||||
|
||||
///Here we append the behavior associated to changing lum_power.
|
||||
/datum/component/overlay_lighting/proc/cast_directional_light()
|
||||
var/final_distance = cast_range
|
||||
//Lower the distance by 1 if we're not looking at a cardinal direction, and we're not a short cast
|
||||
if(final_distance > SHORT_CAST && !(ALL_CARDINALS & current_direction))
|
||||
final_distance -= 1
|
||||
var/turf/scanning = get_turf(current_holder)
|
||||
for(var/i in 1 to final_distance)
|
||||
var/turf/next_turf = get_step(scanning, current_direction)
|
||||
if(isnull(next_turf) || IS_OPAQUE_TURF(next_turf))
|
||||
break
|
||||
scanning = next_turf
|
||||
directional_atom.forceMove(scanning)
|
||||
|
||||
///Called when current_holder changes loc.
|
||||
/datum/component/overlay_lighting/proc/on_holder_dir_change(atom/movable/source, olddir, newdir)
|
||||
SIGNAL_HANDLER
|
||||
set_direction(newdir)
|
||||
|
||||
///Called when parent changes loc.
|
||||
/datum/component/overlay_lighting/proc/on_parent_dir_change(atom/movable/source, olddir, newdir)
|
||||
SIGNAL_HANDLER
|
||||
set_direction(newdir)
|
||||
|
||||
///Sets a new direction for the directional cast, then updates luminosity
|
||||
/datum/component/overlay_lighting/proc/set_direction(newdir)
|
||||
if(!newdir)
|
||||
return
|
||||
if(current_direction == newdir)
|
||||
return
|
||||
current_direction = newdir
|
||||
cone.set_dir(newdir)
|
||||
|
||||
if(newdir & NORTH)
|
||||
cone.pixel_y = 16
|
||||
else if(newdir & SOUTH)
|
||||
cone.pixel_y = -16
|
||||
else
|
||||
if(!isnull(cone_hint_y))
|
||||
cone.pixel_y = cone_hint_y
|
||||
else
|
||||
cone.pixel_y = 0
|
||||
|
||||
if(newdir & EAST)
|
||||
cone.pixel_x = 16
|
||||
else if(newdir & WEST)
|
||||
cone.pixel_x = -16
|
||||
else
|
||||
if(!isnull(cone_hint_x))
|
||||
if(newdir & NORTH)
|
||||
cone.pixel_x = -1*cone_hint_x
|
||||
else
|
||||
cone.pixel_x = cone_hint_x
|
||||
else
|
||||
cone.pixel_x = 0
|
||||
|
||||
if(overlay_lighting_flags & LIGHTING_ON)
|
||||
make_luminosity_update()
|
||||
|
||||
/datum/component/overlay_lighting/proc/on_parent_crafted(datum/source, atom/movable/new_craft)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!istype(new_craft))
|
||||
return
|
||||
|
||||
UnregisterSignal(parent, COMSIG_ATOM_USED_IN_CRAFT)
|
||||
RegisterSignal(new_craft, COMSIG_ATOM_USED_IN_CRAFT, .proc/on_parent_crafted)
|
||||
set_parent_attached_to(new_craft)
|
||||
|
||||
/// Handles putting the source for overlay lights into the light eater queue since we aren't tracked by [/atom/var/light_sources]
|
||||
/datum/component/overlay_lighting/proc/on_light_eater(datum/source, list/light_queue, datum/light_eater)
|
||||
SIGNAL_HANDLER
|
||||
light_queue[parent] = TRUE
|
||||
return NONE
|
||||
|
||||
#undef LIGHTING_ON
|
||||
#undef LIGHTING_ATTACHED
|
||||
#undef GET_PARENT
|
||||
#undef GET_LIGHT_SOURCE
|
||||
#undef SHORT_CAST
|
||||
@@ -1,9 +1,9 @@
|
||||
/**
|
||||
* A holder for simple behaviour that can be attached to many different types
|
||||
*
|
||||
* Only one element of each type is instanced during game init.
|
||||
* Otherwise acts basically like a lightweight component.
|
||||
*/
|
||||
* A holder for simple behaviour that can be attached to many different types
|
||||
*
|
||||
* Only one element of each type is instanced during game init.
|
||||
* Otherwise acts basically like a lightweight component.
|
||||
*/
|
||||
/datum/element
|
||||
/// Option flags for element behaviour
|
||||
var/element_flags = NONE
|
||||
@@ -18,17 +18,23 @@
|
||||
|
||||
/// Activates the functionality defined by the element on the given target datum
|
||||
/datum/element/proc/Attach(datum/target)
|
||||
SHOULD_CALL_PARENT(1)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(type == /datum/element)
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
SEND_SIGNAL(target, COMSIG_ELEMENT_ATTACH, src)
|
||||
if(element_flags & ELEMENT_DETACH)
|
||||
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/Detach, override = TRUE)
|
||||
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/OnTargetDelete, override = TRUE)
|
||||
|
||||
/datum/element/proc/OnTargetDelete(datum/source, force)
|
||||
SIGNAL_HANDLER
|
||||
Detach(source)
|
||||
|
||||
/// Deactivates the functionality defines by the element on the given datum
|
||||
/datum/element/proc/Detach(datum/source, force)
|
||||
/datum/element/proc/Detach(datum/source, ...)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
SEND_SIGNAL(source, COMSIG_ELEMENT_DETACH, src)
|
||||
SHOULD_CALL_PARENT(1)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
UnregisterSignal(source, COMSIG_PARENT_QDELETING)
|
||||
|
||||
/datum/element/Destroy(force)
|
||||
@@ -41,15 +47,21 @@
|
||||
|
||||
/// Finds the singleton for the element type given and attaches it to src
|
||||
/datum/proc/_AddElement(list/arguments)
|
||||
if(QDELING(src))
|
||||
CRASH("We just tried to add an element to a qdeleted datum, something is fucked")
|
||||
var/datum/element/ele = SSdcs.GetElement(arguments)
|
||||
arguments[1] = src
|
||||
if(ele.Attach(arglist(arguments)) == ELEMENT_INCOMPATIBLE)
|
||||
CRASH("Incompatible [arguments[1]] assigned to a [type]! args: [json_encode(args)]")
|
||||
|
||||
/**
|
||||
* Finds the singleton for the element type given and detaches it from src
|
||||
* You only need additional arguments beyond the type if you're using [ELEMENT_BESPOKE]
|
||||
*/
|
||||
* Finds the singleton for the element type given and detaches it from src
|
||||
* You only need additional arguments beyond the type if you're using [ELEMENT_BESPOKE]
|
||||
*/
|
||||
/datum/proc/_RemoveElement(list/arguments)
|
||||
var/datum/element/ele = SSdcs.GetElement(arguments)
|
||||
ele.Detach(src)
|
||||
if(ele.element_flags & ELEMENT_COMPLEX_DETACH)
|
||||
arguments[1] = src
|
||||
ele.Detach(arglist(arguments))
|
||||
else
|
||||
ele.Detach(src)
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Attached to movable atoms with opacity. Listens to them move and updates their old and new turf loc's opacity accordingly.
|
||||
*/
|
||||
/datum/element/light_blocking
|
||||
element_flags = ELEMENT_DETACH
|
||||
|
||||
|
||||
/datum/element/light_blocking/Attach(datum/target)
|
||||
. = ..()
|
||||
if(!ismovable(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/on_target_move)
|
||||
var/atom/movable/movable_target = target
|
||||
if(isturf(movable_target.loc))
|
||||
var/turf/turf_loc = movable_target.loc
|
||||
turf_loc.add_opacity_source(target)
|
||||
|
||||
|
||||
/datum/element/light_blocking/Detach(atom/movable/target)
|
||||
. = ..()
|
||||
UnregisterSignal(target, list(COMSIG_MOVABLE_MOVED))
|
||||
var/atom/movable/movable_target = target
|
||||
if(isturf(movable_target.loc))
|
||||
var/turf/turf_loc = movable_target.loc
|
||||
turf_loc.remove_opacity_source(target)
|
||||
|
||||
|
||||
///Updates old and new turf loc opacities.
|
||||
/datum/element/light_blocking/proc/on_target_move(atom/movable/source, atom/OldLoc, Dir, Forced = FALSE)
|
||||
SIGNAL_HANDLER
|
||||
if(isturf(OldLoc))
|
||||
var/turf/old_turf = OldLoc
|
||||
old_turf.remove_opacity_source(source)
|
||||
if(isturf(source.loc))
|
||||
var/turf/new_turf = source.loc
|
||||
new_turf.add_opacity_source(source)
|
||||
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
DO NOT USE THIS. THIS IS BEING DEPRECATED BY PROCESSING SUBSYSTEMS (controllers/subsystems/processing) AND TIMERS.
|
||||
*/
|
||||
|
||||
/*
|
||||
README:
|
||||
|
||||
The global_iterator datum is supposed to provide a simple and robust way to
|
||||
create some constantly "looping" processes with ability to stop and restart them at will.
|
||||
Generally, the only thing you want to play with (meaning, redefine) is the process() proc.
|
||||
It must contain all the things you want done.
|
||||
|
||||
Control functions:
|
||||
new - used to create datum. First argument (optional) - var list(to use in process() proc) as list,
|
||||
second (optional) - autostart control.
|
||||
If autostart == TRUE, the loop will be started immediately after datum creation.
|
||||
|
||||
start(list/arguments) - starts the loop. Takes arguments(optional) as a list, which is then used
|
||||
by process() proc. Returns null if datum already active, 1 if loop started succesfully and 0 if there's
|
||||
an error in supplied arguments (not list or empty list).
|
||||
|
||||
stop() - stops the loop. Returns null if datum is already inactive and 1 on success.
|
||||
|
||||
set_delay(new_delay) - sets the delay between iterations. Pretty selfexplanatory.
|
||||
Returns 0 on error(new_delay is not numerical), 1 otherwise.
|
||||
|
||||
set_process_args(list/arguments) - passes the supplied arguments to the process() proc.
|
||||
|
||||
active() - Returns 1 if datum is active, 0 otherwise.
|
||||
|
||||
toggle() - toggles datum state. Returns new datum state (see active()).
|
||||
|
||||
Misc functions:
|
||||
|
||||
get_last_exec_time() - Returns the time of last iteration.
|
||||
|
||||
get_last_exec_time_as_text() - Returns the time of last iteration as text
|
||||
|
||||
|
||||
Control vars:
|
||||
|
||||
delay - delay between iterations
|
||||
|
||||
check_for_null - if equals TRUE, on each iteration the supplied arguments will be checked for nulls.
|
||||
If some varible equals null (and null only), the loop is stopped.
|
||||
Usefull, if some var unexpectedly becomes null - due to object deletion, for example.
|
||||
Of course, you can also check the variables inside process() proc to prevent runtime errors.
|
||||
|
||||
Data storage vars:
|
||||
|
||||
result - stores the value returned by process() proc
|
||||
*/
|
||||
|
||||
/datum/global_iterator
|
||||
var/control_switch = 0
|
||||
var/delay = 10
|
||||
var/list/arg_list = new
|
||||
var/last_exec = null
|
||||
var/check_for_null = 1
|
||||
var/forbid_garbage = 0
|
||||
var/result
|
||||
var/state = 0
|
||||
|
||||
New(list/arguments=null,autostart=1)
|
||||
delay = delay>0?(delay):1
|
||||
if(forbid_garbage) //prevents garbage collection with tag != null
|
||||
tag = "\ref[src]"
|
||||
set_process_args(arguments)
|
||||
if(autostart)
|
||||
start()
|
||||
return
|
||||
|
||||
proc/main()
|
||||
state = 1
|
||||
while(src && control_switch)
|
||||
last_exec = world.timeofday
|
||||
if(check_for_null && has_null_args())
|
||||
stop()
|
||||
return 0
|
||||
result = process(arglist(arg_list))
|
||||
for(var/sleep_time=delay;sleep_time>0;sleep_time--) //uhh, this is ugly. But I see no other way to terminate sleeping proc. Such disgrace.
|
||||
if(!control_switch)
|
||||
return 0
|
||||
sleep(1)
|
||||
return 0
|
||||
|
||||
proc/start(list/arguments=null)
|
||||
if(active())
|
||||
return
|
||||
if(arguments)
|
||||
if(!set_process_args(arguments))
|
||||
return 0
|
||||
if(!state_check()) //the main loop is sleeping, wait for it to terminate.
|
||||
return
|
||||
control_switch = 1
|
||||
spawn()
|
||||
state = main()
|
||||
return 1
|
||||
|
||||
proc/stop()
|
||||
if(!active())
|
||||
return
|
||||
control_switch = 0
|
||||
spawn(-1) //report termination error but don't wait for state_check().
|
||||
state_check()
|
||||
return 1
|
||||
|
||||
proc/state_check()
|
||||
var/lag = 0
|
||||
while(state)
|
||||
sleep(1)
|
||||
if(++lag>10)
|
||||
CRASH("The global_iterator loop \ref[src] failed to terminate in designated timeframe. This may be caused by server lagging.")
|
||||
return 1
|
||||
|
||||
proc/active()
|
||||
return control_switch
|
||||
|
||||
proc/has_null_args()
|
||||
if(null in arg_list)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
proc/set_delay(new_delay)
|
||||
if(isnum(new_delay))
|
||||
delay = max(1, round(new_delay))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
proc/get_last_exec_time()
|
||||
return (last_exec||0)
|
||||
|
||||
proc/get_last_exec_time_as_text()
|
||||
return (time2text(last_exec)||"Wasn't executed yet")
|
||||
|
||||
proc/set_process_args(list/arguments)
|
||||
if(arguments && istype(arguments, /list) && arguments.len)
|
||||
arg_list = arguments
|
||||
return 1
|
||||
else
|
||||
// to_world("<span class='danger'>Invalid arguments supplied for [src.type], ref = \ref[src]</span>")
|
||||
return 0
|
||||
|
||||
proc/toggle_null_checks()
|
||||
check_for_null = !check_for_null
|
||||
return check_for_null
|
||||
|
||||
proc/toggle()
|
||||
if(!stop())
|
||||
start()
|
||||
return active()
|
||||
|
||||
/datum/global_iterator/Destroy()
|
||||
tag = null
|
||||
arg_list.Cut()
|
||||
stop()
|
||||
return QDEL_HINT_LETMELIVE
|
||||
//Do not call ..()
|
||||
@@ -10,10 +10,13 @@
|
||||
plane = FLOAT_PLANE // No clue why this is 0 by default yet images are on FLOAT_PLANE
|
||||
// And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var
|
||||
|
||||
// Helper similar to image()
|
||||
/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER)
|
||||
/// Helper similar to image()
|
||||
/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE)
|
||||
var/mutable_appearance/MA = new()
|
||||
MA.icon = icon
|
||||
MA.icon_state = icon_state
|
||||
MA.layer = layer
|
||||
return MA
|
||||
MA.plane = plane
|
||||
MA.alpha = alpha
|
||||
MA.appearance_flags |= appearance_flags
|
||||
return MA
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// III. Thou shalt not write a decl that relies on arguments supplied to New().
|
||||
// IV. Thou shalt not call Initialize() on a /decl.
|
||||
|
||||
var/repository/decls/decls_repository = new()
|
||||
var/repository/decls/decls_repository // Initialiozed in /datum/global_init/New()
|
||||
|
||||
/repository/decls
|
||||
var/list/fetched_decls
|
||||
|
||||
@@ -66,7 +66,8 @@
|
||||
/obj/item/weapon/surgical/bonegel,
|
||||
/obj/item/weapon/surgical/retractor,
|
||||
/obj/item/weapon/surgical/bonesetter,
|
||||
/obj/item/weapon/surgical/circular_saw
|
||||
/obj/item/weapon/surgical/circular_saw,
|
||||
/obj/item/weapon/surgical/bioregen
|
||||
)
|
||||
cost = 25
|
||||
containertype = /obj/structure/closet/crate/secure/veymed
|
||||
|
||||
@@ -7,4 +7,14 @@
|
||||
cost = 35
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "frontier phaser crate"
|
||||
access = access_explorer
|
||||
access = access_explorer
|
||||
|
||||
/datum/supply_pack/munitions/expeditionbows
|
||||
name = "Frontier bows (station-locked) crate"
|
||||
contains = list(
|
||||
/obj/item/weapon/gun/energy/locked/frontier/handbow=2
|
||||
)
|
||||
cost = 20
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "phaser handbow crate"
|
||||
access = access_explorer
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
/obj/item/weapon/reagent_containers/glass/paint/purple,
|
||||
/obj/item/weapon/reagent_containers/glass/paint/black,
|
||||
/obj/item/weapon/reagent_containers/glass/paint/white,
|
||||
/obj/item/weapon/contraband/poster/custom,
|
||||
/obj/item/poster/custom,
|
||||
/obj/item/weapon/wrapping_paper = 3
|
||||
)
|
||||
cost = 10
|
||||
|
||||
@@ -421,7 +421,8 @@
|
||||
/obj/item/clothing/accessory/holster,
|
||||
/obj/item/clothing/accessory/holster/armpit,
|
||||
/obj/item/clothing/accessory/holster/waist,
|
||||
/obj/item/clothing/accessory/holster/hip
|
||||
/obj/item/clothing/accessory/holster/hip,
|
||||
/obj/item/clothing/accessory/holster/leg
|
||||
)
|
||||
cost = 15
|
||||
containertype = /obj/structure/closet/crate/hedberg
|
||||
@@ -667,9 +668,9 @@
|
||||
/datum/supply_pack/security/posters
|
||||
name = "Gear - Morale Posters"
|
||||
contains = list(
|
||||
/obj/item/weapon/contraband/poster/nanotrasen = 6
|
||||
/obj/item/poster/nanotrasen = 6
|
||||
)
|
||||
cost = 20
|
||||
cost = 10
|
||||
containertype = /obj/structure/closet/crate/secure/nanotrasen
|
||||
containername = "Morale Posters"
|
||||
access = access_maint_tunnels
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
A.contents.Add(T)
|
||||
if(old_area)
|
||||
// Handle dynamic lighting update if
|
||||
if(T.dynamic_lighting && old_area.dynamic_lighting != A.dynamic_lighting)
|
||||
if(SSlighting.subsystem_initialized && T.dynamic_lighting && old_area.dynamic_lighting != A.dynamic_lighting)
|
||||
if(A.dynamic_lighting)
|
||||
T.lighting_build_overlay()
|
||||
else
|
||||
|
||||
+16
-2
@@ -26,9 +26,16 @@
|
||||
///Chemistry.
|
||||
|
||||
// Overlays
|
||||
var/list/our_overlays //our local copy of (non-priority) overlays without byond magic. Use procs in SSoverlays to manipulate
|
||||
var/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4.
|
||||
///Our local copy of (non-priority) overlays without byond magic. Use procs in SSoverlays to manipulate
|
||||
var/list/our_overlays
|
||||
///Overlays that should remain on top and not normally removed when using cut_overlay functions, like c4.
|
||||
var/list/priority_overlays
|
||||
///vis overlays managed by SSvis_overlays to automaticaly turn them like other overlays
|
||||
var/list/managed_vis_overlays
|
||||
|
||||
///Our local copy of filter data so we can add/remove it
|
||||
var/list/filter_data
|
||||
|
||||
//Detective Work, used for the duplicate data points kept in the scanners
|
||||
var/list/original_atom
|
||||
// Track if we are already had initialize() called to prevent double-initialization.
|
||||
@@ -82,6 +89,13 @@
|
||||
initialized = TRUE
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
|
||||
/atom/Destroy()
|
||||
if(reagents)
|
||||
QDEL_NULL(reagents)
|
||||
if(light)
|
||||
QDEL_NULL(light)
|
||||
return ..()
|
||||
|
||||
// Called after all object's normal initialize() if initialize() returns INITIALIZE_HINT_LATELOAD
|
||||
/atom/proc/LateInitialize()
|
||||
return
|
||||
|
||||
+35
-23
@@ -30,37 +30,46 @@
|
||||
var/cloaked = FALSE //If we're cloaked or not
|
||||
var/image/cloaked_selfimage //The image we use for our client to let them see where we are
|
||||
|
||||
/atom/movable/Initialize(mapload)
|
||||
. = ..()
|
||||
switch(blocks_emissive)
|
||||
if(EMISSIVE_BLOCK_GENERIC)
|
||||
var/mutable_appearance/gen_emissive_blocker = mutable_appearance(icon, icon_state, plane = PLANE_EMISSIVE, alpha = src.alpha)
|
||||
gen_emissive_blocker.color = GLOB.em_block_color
|
||||
gen_emissive_blocker.dir = dir
|
||||
gen_emissive_blocker.appearance_flags |= appearance_flags
|
||||
add_overlay(list(gen_emissive_blocker), TRUE)
|
||||
if(EMISSIVE_BLOCK_UNIQUE)
|
||||
render_target = ref(src)
|
||||
em_block = new(src, render_target)
|
||||
add_overlay(list(em_block), TRUE)
|
||||
if(opacity)
|
||||
AddElement(/datum/element/light_blocking)
|
||||
switch(light_system)
|
||||
if(STATIC_LIGHT)
|
||||
update_light()
|
||||
if(MOVABLE_LIGHT)
|
||||
AddComponent(/datum/component/overlay_lighting, starts_on = light_on)
|
||||
if(MOVABLE_LIGHT_DIRECTIONAL)
|
||||
AddComponent(/datum/component/overlay_lighting, is_directional = TRUE, starts_on = light_on)
|
||||
|
||||
/atom/movable/Destroy()
|
||||
. = ..()
|
||||
if(reagents)
|
||||
qdel(reagents)
|
||||
reagents = null
|
||||
for(var/atom/movable/AM in contents)
|
||||
qdel(AM)
|
||||
var/turf/un_opaque
|
||||
if(opacity && isturf(loc))
|
||||
un_opaque = loc
|
||||
|
||||
if(opacity)
|
||||
RemoveElement(/datum/element/light_blocking)
|
||||
|
||||
moveToNullspace()
|
||||
if(un_opaque)
|
||||
un_opaque.recalc_atom_opacity()
|
||||
if (pulledby)
|
||||
if (pulledby.pulling == src)
|
||||
pulledby.pulling = null
|
||||
pulledby = null
|
||||
|
||||
if(pulledby)
|
||||
pulledby.stop_pulling()
|
||||
|
||||
if(orbiting)
|
||||
stop_orbit()
|
||||
QDEL_NULL(riding_datum) //VOREStation Add
|
||||
|
||||
|
||||
/atom/movable/vv_get_dropdown()
|
||||
. = ..()
|
||||
VV_DROPDOWN_OPTION("move_atom", "Move To Coordinate")
|
||||
|
||||
/atom/vv_do_topic(list/href_list)
|
||||
. = ..()
|
||||
IF_VV_OPTION("move_atom")
|
||||
usr.client.cmd_admin_move_atom(src)
|
||||
href_list["datumrefresh"] = "\ref[src]"
|
||||
|
||||
/atom/movable/vv_edit_var(var_name, var_value)
|
||||
if(var_name in GLOB.VVpixelmovement) //Pixel movement is not yet implemented, changing this will break everything irreversibly.
|
||||
return FALSE
|
||||
@@ -211,12 +220,15 @@
|
||||
|
||||
//Called after a successful Move(). By this point, we've already moved
|
||||
/atom/movable/proc/Moved(atom/old_loc, direction, forced = FALSE, movetime)
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, old_loc, direction, forced, movetime)
|
||||
// Handle any buckled mobs on this movable
|
||||
if(has_buckled_mobs())
|
||||
handle_buckled_mob_movement(old_loc, direction, movetime)
|
||||
if(riding_datum)
|
||||
riding_datum.handle_vehicle_layer()
|
||||
riding_datum.handle_vehicle_offsets()
|
||||
for (var/datum/light_source/light as anything in light_sources) // Cycle through the light sources on this atom and tell them to update.
|
||||
light.source_atom.update_light()
|
||||
return TRUE
|
||||
|
||||
/atom/movable/set_dir(newdir)
|
||||
|
||||
@@ -1,2 +1,12 @@
|
||||
/atom/movable/proc/Bump_vr(var/atom/A, yes)
|
||||
return
|
||||
|
||||
/atom/movable/vv_get_dropdown()
|
||||
. = ..()
|
||||
VV_DROPDOWN_OPTION("move_atom", "Move To Coordinate")
|
||||
|
||||
/atom/vv_do_topic(list/href_list)
|
||||
. = ..()
|
||||
IF_VV_OPTION("move_atom")
|
||||
usr.client.cmd_admin_move_atom(src)
|
||||
href_list["datumrefresh"] = "\ref[src]"
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
C.transforming = 1
|
||||
C.canmove = 0
|
||||
C.icon = null
|
||||
C.overlays.Cut()
|
||||
C.cut_overlays()
|
||||
C.invisibility = 101
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( C.loc )
|
||||
animation.icon_state = "blank"
|
||||
|
||||
@@ -629,6 +629,7 @@ proc/findNullRod(var/atom/target)
|
||||
light_range = 4
|
||||
light_power = 5
|
||||
light_color = "#FF0000"
|
||||
light_on = TRUE
|
||||
pulses_remaining = 10
|
||||
pulse_delay = 1 SECOND
|
||||
|
||||
@@ -650,6 +651,7 @@ proc/findNullRod(var/atom/target)
|
||||
aspect = ASPECT_UNHOLY
|
||||
light_color = "#FF5C5C"
|
||||
light_power = -2
|
||||
light_on = TRUE
|
||||
|
||||
/obj/item/weapon/spell/construct/mend_occult/on_melee_cast(atom/hit_atom, mob/living/user, def_zone)
|
||||
if(isliving(hit_atom))
|
||||
@@ -666,6 +668,7 @@ proc/findNullRod(var/atom/target)
|
||||
aspect = ASPECT_UNHOLY
|
||||
light_color = "#FF5C5C"
|
||||
light_power = -2
|
||||
light_on = TRUE
|
||||
cooldown = 15
|
||||
|
||||
/obj/item/weapon/spell/construct/slam/on_melee_cast(atom/hit_atom, mob/living/user, def_zone)
|
||||
|
||||
@@ -91,6 +91,8 @@ The access requirements on the Asteroid Shuttles' consoles have now been revoked
|
||||
A.updateicon()
|
||||
|
||||
/datum/universal_state/supermatter_cascade/OverlayAndAmbientSet()
|
||||
return
|
||||
/* TODO
|
||||
spawn(0)
|
||||
for(var/datum/lighting_corner/L in world)
|
||||
if(L.z in using_map.admin_levels)
|
||||
@@ -100,7 +102,7 @@ The access requirements on the Asteroid Shuttles' consoles have now been revoked
|
||||
|
||||
for(var/turf/space/T in world)
|
||||
OnTurfChange(T)
|
||||
|
||||
*/
|
||||
/datum/universal_state/supermatter_cascade/proc/MiscSet()
|
||||
for (var/obj/machinery/firealarm/alm in machines)
|
||||
if (!(alm.stat & BROKEN))
|
||||
|
||||
@@ -90,9 +90,9 @@
|
||||
last_instability_event = world.time
|
||||
spawn(1)
|
||||
var/image/instability_flash = image('icons/obj/spells.dmi',"instability")
|
||||
overlays |= instability_flash
|
||||
add_overlay(instability_flash)
|
||||
sleep(4)
|
||||
overlays.Remove(instability_flash)
|
||||
cut_overlay(instability_flash)
|
||||
qdel(instability_flash)
|
||||
|
||||
/mob/living/silicon/instability_effects()
|
||||
|
||||
@@ -168,9 +168,9 @@
|
||||
/obj/item/weapon/spell/update_icon()
|
||||
if(toggled)
|
||||
var/image/new_overlay = image('icons/obj/spells.dmi',"toggled")
|
||||
overlays |= new_overlay
|
||||
add_overlay(new_overlay)
|
||||
else
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
..()
|
||||
|
||||
// Proc: run_checks()
|
||||
|
||||
@@ -65,11 +65,11 @@
|
||||
|
||||
// Makes a tiny overlay of the thing the player has copied, so they can easily tell what they currently have.
|
||||
/obj/item/weapon/spell/illusion/update_icon()
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
if(copied)
|
||||
var/image/temp_image = image(copied)
|
||||
var/matrix/M = matrix()
|
||||
M.Scale(0.5, 0.5)
|
||||
temp_image.transform = M
|
||||
// temp_image.pixel_y = 8
|
||||
src.overlays.Add(temp_image)
|
||||
add_overlay(temp_image)
|
||||
|
||||
@@ -27,4 +27,5 @@
|
||||
time_to_die = 2 MINUTES
|
||||
invisibility = 101
|
||||
light_range = 6
|
||||
light_power = -20
|
||||
light_power = -20
|
||||
light_on = TRUE
|
||||
@@ -31,6 +31,7 @@
|
||||
light_range = 6
|
||||
light_power = 20
|
||||
light_color = "#C26DDE"
|
||||
light_on = TRUE
|
||||
var/pulses_remaining = 40 // Lasts 20 seconds.
|
||||
var/instability_power = 5
|
||||
var/instability_range = 6
|
||||
|
||||
@@ -28,32 +28,21 @@
|
||||
return has_access(req_access, req_one_access, L)
|
||||
|
||||
/proc/has_access(var/list/req_access, var/list/req_one_access, var/list/accesses)
|
||||
// Doesn't have access lists, always works
|
||||
if(!LAZYLEN(req_access) && !LAZYLEN(req_one_access))
|
||||
return TRUE
|
||||
|
||||
// Didn't pass anything to compare
|
||||
if(!LAZYLEN(accesses))
|
||||
return FALSE
|
||||
|
||||
// req_access list has priority if set
|
||||
// Requires at least every access in list
|
||||
if(LAZYLEN(req_access))
|
||||
for(var/req in req_access)
|
||||
if(!(req in accesses))
|
||||
return FALSE
|
||||
// Wasn't missing any accesses
|
||||
return TRUE
|
||||
for(var/req in req_access)
|
||||
if(!(req in accesses))
|
||||
return FALSE
|
||||
|
||||
// req_one_access is secondary if set
|
||||
// Requires at least one access in list
|
||||
for(var/req in req_one_access)
|
||||
if(req in accesses)
|
||||
// Found at least one
|
||||
return TRUE
|
||||
if(LAZYLEN(req_one_access))
|
||||
for(var/req in req_one_access)
|
||||
if(req in accesses)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
// Didn't find anything that matched
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/proc/get_centcom_access(job)
|
||||
switch(job)
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
/obj/machinery/sleep_console/tgui_act(action, params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(sleeper)
|
||||
return sleeper.tgui_act(action, params, ui, state)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/sleeper
|
||||
name = "sleeper"
|
||||
|
||||
@@ -568,21 +568,22 @@
|
||||
var/list/info = alarm_area.air_scrub_info[id_tag]
|
||||
if(!info)
|
||||
continue
|
||||
var/list/list/filters = list()
|
||||
scrubbers.Add(list(list(
|
||||
scrubbers += list(list(
|
||||
"id_tag" = id_tag,
|
||||
"long_name" = sanitize(long_name),
|
||||
"power" = info["power"],
|
||||
"scrubbing" = info["scrubbing"],
|
||||
"panic" = info["panic"],
|
||||
"filters" = filters
|
||||
)))
|
||||
filters.Add(list(list("name" = "Oxygen", "command" = "o2_scrub", "val" = info["filter_o2"])))
|
||||
filters.Add(list(list("name" = "Nitrogen", "command" = "n2_scrub", "val" = info["filter_n2"])))
|
||||
filters.Add(list(list("name" = "Carbon Dioxide", "command" = "co2_scrub","val" = info["filter_co2"])))
|
||||
filters.Add(list(list("name" = "Toxin" , "command" = "tox_scrub","val" = info["filter_phoron"])))
|
||||
filters.Add(list(list("name" = "Nitrous Oxide", "command" = "n2o_scrub","val" = info["filter_n2o"])))
|
||||
filters.Add(list(list("name" = "Fuel", "command" = "fuel_scrub","val" = info["filter_fuel"])))
|
||||
"filters" = list(
|
||||
list("name" = "Oxygen", "command" = "o2_scrub", "val" = info["filter_o2"]),
|
||||
list("name" = "Nitrogen", "command" = "n2_scrub", "val" = info["filter_n2"]),
|
||||
list("name" = "Carbon Dioxide", "command" = "co2_scrub","val" = info["filter_co2"]),
|
||||
list("name" = "Toxin" , "command" = "tox_scrub","val" = info["filter_phoron"]),
|
||||
list("name" = "Nitrous Oxide", "command" = "n2o_scrub","val" = info["filter_n2o"]),
|
||||
list("name" = "Fuel", "command" = "fuel_scrub","val" = info["filter_fuel"])
|
||||
)
|
||||
))
|
||||
data["scrubbers"] = scrubbers
|
||||
|
||||
data["mode"] = mode
|
||||
|
||||
@@ -798,4 +799,4 @@
|
||||
|
||||
TLV["temperature"] = list(T0C - 40, T0C - 20, T0C + 40, T0C + 66) // K, Lower Temperature for Freezer Air Alarms (This is because TLV is hardcoded to be generated on first_run, and therefore the only way to modify this without changing TLV generation)
|
||||
|
||||
// VOREStation Edit End
|
||||
// VOREStation Edit End
|
||||
|
||||
@@ -109,14 +109,14 @@
|
||||
env.merge(removed)
|
||||
|
||||
/obj/machinery/power/thermoregulator/update_icon()
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
if(on)
|
||||
overlays += "lasergen-on"
|
||||
add_overlay("lasergen-on")
|
||||
switch(mode)
|
||||
if(MODE_HEATING)
|
||||
overlays += "lasergen-heat"
|
||||
add_overlay("lasergen-heat")
|
||||
if(MODE_COOLING)
|
||||
overlays += "lasergen-cool"
|
||||
add_overlay("lasergen-cool")
|
||||
|
||||
/obj/machinery/power/thermoregulator/proc/turn_off()
|
||||
on = 0
|
||||
|
||||
@@ -141,20 +141,20 @@ update_flag
|
||||
if(check_change()) //Returns 1 if no change needed to icons.
|
||||
return
|
||||
|
||||
src.overlays = 0
|
||||
cut_overlays()
|
||||
|
||||
if(update_flag & 1)
|
||||
overlays += "can-open"
|
||||
add_overlay("can-open")
|
||||
if(update_flag & 2)
|
||||
overlays += "can-connector"
|
||||
add_overlay("can-connector")
|
||||
if(update_flag & 4)
|
||||
overlays += "can-o0"
|
||||
add_overlay("can-o0")
|
||||
if(update_flag & 8)
|
||||
overlays += "can-o1"
|
||||
add_overlay("can-o1")
|
||||
else if(update_flag & 16)
|
||||
overlays += "can-o2"
|
||||
add_overlay("can-o2")
|
||||
else if(update_flag & 32)
|
||||
overlays += "can-o3"
|
||||
add_overlay("can-o3")
|
||||
return
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
src.air_contents.adjust_multi("oxygen", air_mix["oxygen"], "nitrogen", air_mix["nitrogen"])
|
||||
|
||||
/obj/machinery/portable_atmospherics/powered/pump/update_icon()
|
||||
src.overlays = 0
|
||||
cut_overlays()
|
||||
|
||||
if(on && cell && cell.charge)
|
||||
icon_state = "psiphon:1"
|
||||
@@ -37,10 +37,10 @@
|
||||
icon_state = "psiphon:0"
|
||||
|
||||
if(holding)
|
||||
overlays += "siphon-open"
|
||||
add_overlay("siphon-open")
|
||||
|
||||
if(connected_port)
|
||||
overlays += "siphon-connector"
|
||||
add_overlay("siphon-connector")
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
to_chat(user, "<span class='notice'>You can't directly interact with this machine. Use the pump control console.</span>")
|
||||
|
||||
/obj/machinery/portable_atmospherics/powered/pump/huge/update_icon()
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
|
||||
if(on && !(stat & (NOPOWER|BROKEN)))
|
||||
icon_state = "siphon:1"
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
..(severity)
|
||||
|
||||
/obj/machinery/portable_atmospherics/powered/scrubber/update_icon()
|
||||
src.overlays = 0
|
||||
cut_overlays()
|
||||
|
||||
if(on && cell && cell.charge)
|
||||
icon_state = "pscrubber:1"
|
||||
@@ -44,10 +44,10 @@
|
||||
icon_state = "pscrubber:0"
|
||||
|
||||
if(holding)
|
||||
overlays += "scrubber-open"
|
||||
add_overlay("scrubber-open")
|
||||
|
||||
if(connected_port)
|
||||
overlays += "scrubber-connector"
|
||||
add_overlay("scrubber-connector")
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
circuit = /obj/item/weapon/circuitboard/autolathe
|
||||
|
||||
var/static/datum/category_collection/autolathe/autolathe_recipes
|
||||
var/list/stored_material = list(DEFAULT_WALL_MATERIAL = 0, MAT_GLASS = 0, MAT_PLASTEEL = 0, MAT_PLASTIC = 0)
|
||||
var/list/storage_capacity = list(DEFAULT_WALL_MATERIAL = 0, MAT_GLASS = 0, MAT_PLASTEEL = 0, MAT_PLASTIC = 0)
|
||||
|
||||
var/hacked = 0
|
||||
var/disabled = 0
|
||||
@@ -32,18 +30,12 @@
|
||||
var/filtertext
|
||||
|
||||
/obj/machinery/autolathe/Initialize()
|
||||
AddComponent(/datum/component/material_container, subtypesof(/datum/material), 0, MATCONTAINER_EXAMINE, _after_insert = CALLBACK(src, .proc/AfterMaterialInsert))
|
||||
. = ..()
|
||||
if(!autolathe_recipes)
|
||||
autolathe_recipes = new()
|
||||
wires = new(src)
|
||||
|
||||
for(var/Name in name_to_material)
|
||||
if(Name in stored_material)
|
||||
continue
|
||||
|
||||
stored_material[Name] = 0
|
||||
storage_capacity[Name] = 0
|
||||
|
||||
default_apply_parts()
|
||||
RefreshParts()
|
||||
|
||||
@@ -82,6 +74,7 @@
|
||||
"requirements" = M.resources,
|
||||
"hidden" = M.hidden,
|
||||
"coeff_applies" = !M.no_scale,
|
||||
"is_stack" = M.is_stack,
|
||||
)))
|
||||
data["recipes"] = recipes
|
||||
data["categories"] = categories
|
||||
@@ -95,19 +88,9 @@
|
||||
|
||||
/obj/machinery/autolathe/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
var/list/material_data = list()
|
||||
for(var/mat_id in stored_material)
|
||||
var/amount = stored_material[mat_id]
|
||||
var/list/material_info = list(
|
||||
"name" = mat_id,
|
||||
"amount" = amount,
|
||||
"sheets" = round(amount / SHEET_MATERIAL_AMOUNT),
|
||||
"removable" = amount >= SHEET_MATERIAL_AMOUNT
|
||||
)
|
||||
material_data += list(material_info)
|
||||
data["busy"] = busy
|
||||
data["materials"] = material_data
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
data["materials"] = materials.tgui_data()
|
||||
data["mat_efficiency"] = mat_efficiency
|
||||
return data
|
||||
|
||||
@@ -146,70 +129,14 @@
|
||||
wires.Interact(user)
|
||||
return
|
||||
|
||||
if(O.loc != user && !(istype(O,/obj/item/stack)))
|
||||
return 0
|
||||
|
||||
if(is_robot_module(O))
|
||||
return 0
|
||||
|
||||
if(istype(O,/obj/item/ammo_magazine/clip) || istype(O,/obj/item/ammo_magazine/s357) || istype(O,/obj/item/ammo_magazine/s38) || istype (O,/obj/item/ammo_magazine/s44)/* VOREstation Edit*/) // Prevents ammo recycling exploit with speedloaders.
|
||||
to_chat(user, "\The [O] is too hazardous to recycle with the autolathe!")
|
||||
return
|
||||
|
||||
//Resources are being loaded.
|
||||
var/obj/item/eating = O
|
||||
if(!eating.matter)
|
||||
to_chat(user, "\The [eating] does not contain significant amounts of useful materials and cannot be accepted.")
|
||||
return
|
||||
|
||||
var/filltype = 0 // Used to determine message.
|
||||
var/total_used = 0 // Amount of material used.
|
||||
var/mass_per_sheet = 0 // Amount of material constituting one sheet.
|
||||
|
||||
for(var/material in eating.matter)
|
||||
|
||||
if(isnull(stored_material[material]) || isnull(storage_capacity[material]))
|
||||
continue
|
||||
|
||||
if(stored_material[material] >= storage_capacity[material])
|
||||
continue
|
||||
|
||||
var/total_material = eating.matter[material]
|
||||
|
||||
//If it's a stack, we eat multiple sheets.
|
||||
if(istype(eating,/obj/item/stack))
|
||||
var/obj/item/stack/stack = eating
|
||||
total_material *= stack.get_amount()
|
||||
|
||||
if(stored_material[material] + total_material > storage_capacity[material])
|
||||
total_material = storage_capacity[material] - stored_material[material]
|
||||
filltype = 1
|
||||
else
|
||||
filltype = 2
|
||||
|
||||
stored_material[material] += total_material
|
||||
total_used += total_material
|
||||
mass_per_sheet += eating.matter[material]
|
||||
|
||||
if(!filltype)
|
||||
to_chat(user, "<span class='notice'>\The [src] is full. Please remove material from the autolathe in order to insert more.</span>")
|
||||
return
|
||||
else if(filltype == 1)
|
||||
to_chat(user, "You fill \the [src] to capacity with \the [eating].")
|
||||
else
|
||||
to_chat(user, "You fill \the [src] with \the [eating].")
|
||||
|
||||
flick("autolathe_loading", src) // Plays metal insertion animation. Work out a good way to work out a fitting animation. ~Z
|
||||
|
||||
if(istype(eating,/obj/item/stack))
|
||||
var/obj/item/stack/stack = eating
|
||||
stack.use(max(1, round(total_used/mass_per_sheet))) // Always use at least 1 to prevent infinite materials.
|
||||
else
|
||||
user.remove_from_mob(O)
|
||||
qdel(O)
|
||||
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/autolathe/attack_hand(mob/user as mob)
|
||||
user.set_machine(src)
|
||||
@@ -233,36 +160,42 @@
|
||||
if(making.hidden && !hacked)
|
||||
return
|
||||
|
||||
var/multiplier = 1
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
|
||||
var/list/materials_used = list()
|
||||
|
||||
var/multiplier = (params["multiplier"] || 1)
|
||||
|
||||
if(making.is_stack)
|
||||
var/max_sheets
|
||||
for(var/material in making.resources)
|
||||
var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient
|
||||
var/sheets = round(stored_material[material]/round(making.resources[material]*coeff))
|
||||
var/sheets = round(materials.get_material_amount(material) / round(making.resources[material] * coeff))
|
||||
if(isnull(max_sheets) || max_sheets > sheets)
|
||||
max_sheets = sheets
|
||||
if(!isnull(stored_material[material]) && stored_material[material] < round(making.resources[material]*coeff))
|
||||
if(!isnull(materials.get_material_amount(material)) && materials.get_material_amount(material) < round(making.resources[material] * coeff))
|
||||
max_sheets = 0
|
||||
//Build list of multipliers for sheets.
|
||||
multiplier = input(usr, "How many do you want to print? (0-[max_sheets])") as num|null
|
||||
if(!multiplier || multiplier <= 0 || multiplier > max_sheets || tgui_status(usr, state) != STATUS_INTERACTIVE)
|
||||
return FALSE
|
||||
|
||||
busy = making.name
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
|
||||
//Check if we still have the materials.
|
||||
var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient
|
||||
for(var/material in making.resources)
|
||||
if(!isnull(stored_material[material]))
|
||||
if(stored_material[material] < round(making.resources[material] * coeff) * multiplier)
|
||||
return
|
||||
|
||||
for(var/MAT in making.resources)
|
||||
var/datum/material/used_material = MAT
|
||||
var/amount_needed = making.resources[MAT] * coeff * multiplier
|
||||
materials_used[used_material] = amount_needed
|
||||
|
||||
//Consume materials.
|
||||
for(var/material in making.resources)
|
||||
if(!isnull(stored_material[material]))
|
||||
stored_material[material] = max(0, stored_material[material] - round(making.resources[material] * coeff) * multiplier)
|
||||
if(LAZYLEN(materials_used))
|
||||
if(!materials.has_materials(materials_used))
|
||||
return
|
||||
|
||||
materials.use_materials(materials_used)
|
||||
|
||||
busy = making.name
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
|
||||
update_icon() // So lid closes
|
||||
|
||||
@@ -308,12 +241,12 @@
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/autolathe/update_icon()
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
if(panel_open)
|
||||
overlays.Add(image(icon, "[icon_state]_panel"))
|
||||
add_overlay("[icon_state]_panel")
|
||||
if(stat & NOPOWER)
|
||||
return
|
||||
if(busy)
|
||||
@@ -329,39 +262,25 @@
|
||||
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
|
||||
man_rating += M.rating
|
||||
|
||||
for(var/mat_name in storage_capacity)
|
||||
storage_capacity[mat_name] = mb_rating * 25000
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
materials.max_amount = mb_rating * 75000
|
||||
|
||||
build_time = 50 / man_rating
|
||||
mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.6. Maximum rating of parts is 5
|
||||
update_tgui_static_data(usr)
|
||||
|
||||
/obj/machinery/autolathe/dismantle()
|
||||
for(var/mat in stored_material)
|
||||
var/datum/material/M = get_material_by_name(mat)
|
||||
if(!istype(M))
|
||||
continue
|
||||
var/obj/item/stack/material/S = new M.stack_type(get_turf(src))
|
||||
if(stored_material[mat] > S.perunit)
|
||||
S.amount = round(stored_material[mat] / S.perunit)
|
||||
else
|
||||
qdel(S)
|
||||
..()
|
||||
return 1
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
materials.retrieve_all()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/autolathe/proc/eject_materials(var/material, var/amount) // 0 amount = 0 means ejecting a full stack; -1 means eject everything
|
||||
var/recursive = amount == -1 ? 1 : 0
|
||||
var/matstring = lowertext(material)
|
||||
var/datum/material/M = get_material_by_name(matstring)
|
||||
/obj/machinery/autolathe/proc/AfterMaterialInsert(obj/item/item_inserted, id_inserted, amount_inserted)
|
||||
flick("autolathe_loading", src)//plays metal insertion animation
|
||||
// use_power(min(1000, amount_inserted / 100))
|
||||
SStgui.update_uis(src)
|
||||
|
||||
var/obj/item/stack/material/S = M.place_sheet(get_turf(src))
|
||||
if(amount <= 0)
|
||||
amount = S.max_amount
|
||||
var/ejected = min(round(stored_material[matstring] / S.perunit), amount)
|
||||
S.amount = min(ejected, amount)
|
||||
if(S.amount <= 0)
|
||||
qdel(S)
|
||||
return
|
||||
stored_material[matstring] -= ejected * S.perunit
|
||||
if(recursive && stored_material[matstring] >= S.perunit)
|
||||
eject_materials(matstring, -1)
|
||||
/obj/machinery/autolathe/examine(mob/user)
|
||||
. = ..()
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
. += "<span class='notice'>The status display reads: Storing up to <b>[materials.max_amount]</b> material units.<br>Material consumption at <b>[mat_efficiency*100]%</b>.</span>"
|
||||
|
||||
@@ -62,11 +62,11 @@
|
||||
simulation_finish()
|
||||
|
||||
/obj/machinery/bomb_tester/update_icon()
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
if(tank1)
|
||||
overlays += image(icon, "[icon_name]-tank1")
|
||||
add_overlay("[icon_name]-tank1")
|
||||
if(tank2)
|
||||
overlays += image(icon, "[icon_name]-tank2")
|
||||
add_overlay("[icon_name]-tank2")
|
||||
if(stat & NOPOWER)
|
||||
icon_state = "[icon_name]-p"
|
||||
else
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user