From d38246bb69f84d49334dadf99131792506278134 Mon Sep 17 00:00:00 2001 From: Letter N <24603524+LetterN@users.noreply.github.com> Date: Mon, 4 Nov 2024 02:06:10 +0800 Subject: [PATCH] Init-&-co (#6833) ## About The Pull Request update init code, LateInitialize now complains if it doesnt have anything in it ## Why It's Good For The Game ## Changelog :cl: code: update how init does things code: update matrix helpers /:cl: --- citadel.dme | 7 +- code/__DEFINES/_atoms.dm | 12 + code/__DEFINES/_core.dm | 4 + code/__DEFINES/controllers/_subsystems.dm | 5 +- code/__DEFINES/matrices.dm | 27 ++ code/__DEFINES/vv.dm | 2 + code/__HELPERS/matrices/color_matrix.dm | 302 +++++++----------- code/__HELPERS/matrices/transform_matrix.dm | 76 +++-- code/__HELPERS/sorts/comparators.dm | 3 + code/__HELPERS/type2type/color.dm | 4 +- code/__HELPERS/vfx/appearance_cloning.dm | 2 +- code/controllers/subsystem/atoms.dm | 234 ++++++++------ code/datums/holograms/hologram.dm | 4 +- code/game/atoms/{atom.dm => _atom.dm} | 149 ++------- code/game/atoms/{vv.dm => atom_vv.dm} | 268 +++++++++------- .../atoms/atoms_initializing_EXPENSIVE.dm | 159 +++++++++ code/game/atoms/movement.dm | 3 +- code/game/dna/dna_modifier.dm | 1 - code/game/landmarks/landmarks.dm | 43 ++- code/game/machinery/Sleeper.dm | 1 - code/game/machinery/adv_med.dm | 1 - code/game/machinery/computer/message.dm | 1 - code/game/machinery/doors/door_timer.dm | 1 - code/game/machinery/doors/firedoor.dm | 1 - code/game/machinery/holopad.dm | 4 +- code/game/machinery/lightswitch.dm | 8 +- code/game/machinery/newscaster.dm | 1 - code/game/machinery/telecomms/_telecomms.dm | 1 - code/game/machinery/teleporter/pad.dm | 1 - code/game/machinery/teleporter/projector.dm | 1 - code/game/objects/items/stacks/sandbag.dm | 1 - .../structures/crates_lockers/__closet.dm | 1 - .../structures/crates_lockers/largecrate.dm | 1 - .../structures/stool_bed_chair_nest/chairs.dm | 1 - code/game/objects/structures/tables/table.dm | 1 - code/game/objects/structures/transit_tubes.dm | 1 - .../game/turfs/simulated/floor_types/glass.dm | 1 - code/game/turfs/space/space.dm | 28 +- code/game/turfs/turf.dm | 7 +- .../view_variables/color_matrix_editor.dm | 2 +- code/modules/assembly/signaler.dm | 1 - .../portable/portable_atmospherics.dm | 1 - .../industry/disposals/disposal/chute.dm | 1 - .../industry/disposals/disposal_pipe/trunk.dm | 2 +- code/modules/mapping/dmm_suite/dmm_parsed.dm | 16 +- .../planet_station_turfs/_lythios43c.dm | 9 +- code/modules/mob/freelook/ai/eye.dm | 1 - .../mob/living/bot/medibot_construction.dm | 1 - code/modules/mob/living/carbon/human/human.dm | 1 - code/modules/mob/living/silicon/ai/ai.dm | 5 +- .../modules/organs/external/external_icons.dm | 2 +- .../overmap/legacy/ships/computers/helm.dm | 1 - .../overmap/legacy/ships/computers/sensors.dm | 1 - code/modules/power/breaker_box.dm | 1 - code/modules/power/geothermal_power.dm | 1 - code/modules/power/gravitygenerator.dm | 3 +- code/modules/power/smes/smes.dm | 1 - tools/read_init_times.py | 9 +- 58 files changed, 771 insertions(+), 656 deletions(-) create mode 100644 code/__DEFINES/_atoms.dm create mode 100644 code/__DEFINES/matrices.dm rename code/game/atoms/{atom.dm => _atom.dm} (88%) rename code/game/atoms/{vv.dm => atom_vv.dm} (71%) create mode 100644 code/game/atoms/atoms_initializing_EXPENSIVE.dm diff --git a/citadel.dme b/citadel.dme index df14c808d5e6..d3fee73206d0 100644 --- a/citadel.dme +++ b/citadel.dme @@ -19,6 +19,7 @@ #include "code\__global_init.dm" #include "code\_macros.dm" #include "code\global.dm" +#include "code\__DEFINES\_atoms.dm" #include "code\__DEFINES\_bitfields.dm" #include "code\__DEFINES\_cooldowns.dm" #include "code\__DEFINES\_core.dm" @@ -62,6 +63,7 @@ #include "code\__DEFINES\machinery.dm" #include "code\__DEFINES\maps.dm" #include "code\__DEFINES\math.dm" +#include "code\__DEFINES\matrices.dm" #include "code\__DEFINES\MC.dm" #include "code\__DEFINES\misc.dm" #include "code\__DEFINES\move_force.dm" @@ -1034,18 +1036,19 @@ #include "code\game\area\Tether_areas.dm" #include "code\game\area\station\exporation.dm" #include "code\game\area\station\security_areas.dm" +#include "code\game\atoms\_atom.dm" #include "code\game\atoms\action_feedback.dm" #include "code\game\atoms\appearance.dm" #include "code\game\atoms\atom-construction.dm" #include "code\game\atoms\atom-damage.dm" #include "code\game\atoms\atom-defense.dm" -#include "code\game\atoms\atom.dm" +#include "code\game\atoms\atom_vv.dm" +#include "code\game\atoms\atoms_initializing_EXPENSIVE.dm" #include "code\game\atoms\buckling.dm" #include "code\game\atoms\defense_old.dm" #include "code\game\atoms\materials.dm" #include "code\game\atoms\movement.dm" #include "code\game\atoms\say.dm" -#include "code\game\atoms\vv.dm" #include "code\game\atoms\movable\movable-movement.dm" #include "code\game\atoms\movable\movable-throw.dm" #include "code\game\atoms\movable\movable.dm" diff --git a/code/__DEFINES/_atoms.dm b/code/__DEFINES/_atoms.dm new file mode 100644 index 000000000000..abc4d805170c --- /dev/null +++ b/code/__DEFINES/_atoms.dm @@ -0,0 +1,12 @@ +#define BAD_INIT_QDEL_BEFORE 1 +#define BAD_INIT_DIDNT_INIT 2 +#define BAD_INIT_SLEPT 4 +#define BAD_INIT_NO_HINT 8 + +#ifdef PROFILE_MAPLOAD_INIT_ATOM +#define PROFILE_INIT_ATOM_BEGIN(...) var/__profile_stat_time = TICK_USAGE +#define PROFILE_INIT_ATOM_END(atom) mapload_init_times[##atom.type] += TICK_USAGE_TO_MS(__profile_stat_time) +#else +#define PROFILE_INIT_ATOM_BEGIN(...) +#define PROFILE_INIT_ATOM_END(...) +#endif diff --git a/code/__DEFINES/_core.dm b/code/__DEFINES/_core.dm index 2a6a70722d89..086fb81f6281 100644 --- a/code/__DEFINES/_core.dm +++ b/code/__DEFINES/_core.dm @@ -17,3 +17,7 @@ /// byond bug https://secure.byond.com/forum/?post=2072419 #define BLOCK_BYOND_BUG_2072419 + +/// A null statement to guard against EmptyBlock lint without necessitating the use of pass() +/// Used to avoid proc-call overhead. But use sparingly. Probably pointless in most places. +#define EMPTY_BLOCK_GUARD ; diff --git a/code/__DEFINES/controllers/_subsystems.dm b/code/__DEFINES/controllers/_subsystems.dm index 80abb3939ab0..61115e157901 100644 --- a/code/__DEFINES/controllers/_subsystems.dm +++ b/code/__DEFINES/controllers/_subsystems.dm @@ -34,8 +34,11 @@ #define INITIALIZE_IMMEDIATE(X) ##X/New(loc, ...){\ ..();\ if(!(atom_flags & ATOM_INITIALIZED)) {\ + var/previous_initialized_value = SSatoms.initialized;\ + SSatoms.initialized = INITIALIZATION_INNEW_MAPLOAD;\ args[1] = TRUE;\ - SSatoms.InitAtom(src, args);\ + SSatoms.InitAtom(src, FALSE, args);\ + SSatoms.initialized = previous_initialized_value;\ }\ } diff --git a/code/__DEFINES/matrices.dm b/code/__DEFINES/matrices.dm new file mode 100644 index 000000000000..26ff5a7232a2 --- /dev/null +++ b/code/__DEFINES/matrices.dm @@ -0,0 +1,27 @@ +/// Helper macro for creating a matrix at the given offsets. +/// Works at compile time. +#define TRANSLATE_MATRIX(offset_x, offset_y) matrix(1, 0, (offset_x), 0, 1, (offset_y)) +/// The color matrix of an image which colors haven't been altered. Does nothing. +#define COLOR_MATRIX_IDENTITY list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0) +/// Color inversion +#define COLOR_MATRIX_INVERT list(-1,0,0,0, 0,-1,0,0, 0,0,-1,0, 0,0,0,1, 1,1,1,0) +///Sepiatone +#define COLOR_MATRIX_SEPIATONE list(0.393,0.349,0.272,0, 0.769,0.686,0.534,0, 0.189,0.168,0.131,0, 0,0,0,1, 0,0,0,0) +///Grayscale +#define COLOR_MATRIX_GRAYSCALE list(0.33,0.33,0.33,0, 0.59,0.59,0.59,0, 0.11,0.11,0.11,0, 0,0,0,1, 0,0,0,0) +///Polaroid colors +#define COLOR_MATRIX_POLAROID list(1.438,-0.062,-0.062,0, -0.122,1.378,-0.122,0, -0.016,-0.016,1.483,0, 0,0,0,1, 0,0,0,0) +/// Converts reds to blue, green to red and blue to green. +#define COLOR_MATRIX_BRG list(0,0,1,0, 0,1,0,0, 1,0,0,0, 0,0,0,1, 0,0,0,0) +/// Black & White +#define COLOR_MATRIX_BLACK_WHITE list(1.5,1.5,1.5,0, 1.5,1.5,1.5,0, 1.5,1.5,1.5,0, 0,0,0,1, -1,-1,-1,0) +/** + * Adds/subtracts overall lightness + * 0 is identity, 1 makes everything white, -1 makes everything black + */ +#define COLOR_MATRIX_LIGHTNESS(power) list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, power,power,power,0) +/** + * Changes distance colors have from rgb(127,127,127) grey + * 1 is identity. 0 makes everything grey >1 blows out colors and greys + */ +#define COLOR_MATRIX_CONTRAST(val) list(val,0,0,0, 0,val,0,0, 0,0,val,0, 0,0,0,1, (1-val)*0.5,(1-val)*0.5,(1-val)*0.5,0) diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index c58f5cb50db4..0ba4477f7b8b 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -89,6 +89,8 @@ // /atom #define VV_HK_MODIFY_TRANSFORM "atom_transform" +#define VV_HK_SPIN_ANIMATION "atom_spin" +#define VV_HK_STOP_ALL_ANIMATIONS "stop_animations" #define VV_HK_ADD_REAGENT "addreagent" #define VV_HK_TRIGGER_EMP "empulse" #define VV_HK_TRIGGER_EXPLOSION "explode" diff --git a/code/__HELPERS/matrices/color_matrix.dm b/code/__HELPERS/matrices/color_matrix.dm index 0a4763076937..73ba29b2284d 100644 --- a/code/__HELPERS/matrices/color_matrix.dm +++ b/code/__HELPERS/matrices/color_matrix.dm @@ -2,7 +2,7 @@ // COLOUR MATRICES // ///////////////////// -/* Documenting a couple of potentially useful color matrices here to inspire ideas. +/* Documenting a couple of potentially useful color matrices here to inspire ideas // Greyscale - indentical to saturation @ 0 list(LUMA_R,LUMA_R,LUMA_R,0, LUMA_G,LUMA_G,LUMA_G,0, LUMA_B,LUMA_B,LUMA_B,0, 0,0,0,1, 0,0,0,0) @@ -13,21 +13,8 @@ list(-1,0,0,0, 0,-1,0,0, 0,0,-1,0, 0,0,0,1, 1,1,1,0) list(0.393,0.349,0.272,0, 0.769,0.686,0.534,0, 0.189,0.168,0.131,0, 0,0,0,1, 0,0,0,0) */ -/// Does nothing. -/proc/color_matrix_identity() - return list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0) - -/** - * Adds/subtracts overall lightness. - * 0 is identity, 1 makes everything white, -1 makes everything black. - */ -/proc/color_matrix_lightness(power) - return list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, power,power,power,0) - -/** - * Changes distance hues have from grey while maintaining the overall lightness. Greys are unaffected. - * 1 is identity, 0 is greyscale, >1 oversaturates colors. - */ +//Changes distance hues have from grey while maintaining the overall lightness. Greys are unaffected. +//1 is identity, 0 is greyscale, >1 oversaturates colors /proc/color_matrix_saturation(value) var/inv = 1 - value var/R = round(LUMA_R * inv, 0.001) @@ -36,164 +23,115 @@ list(0.393,0.349,0.272,0, 0.769,0.686,0.534,0, 0.189,0.168,0.131,0, 0,0,0,1, 0,0 return list(R + value,R,R,0, G,G + value,G,0, B,B,B + value,0, 0,0,0,1, 0,0,0,0) -/** - * Exxagerates or removes colors. - */ -/proc/color_matrix_saturation_percent(percent) - if(percent == 0) - return color_matrix_identity() - percent = clamp(percent, -100, 100) - if(percent > 0) - percent *= 3 - var/x = 1 + percent / 100 - var/inv = 1 - x - var/R = LUMA_R * inv - var/G = LUMA_G * inv - var/B = LUMA_B * inv - - return list(R + x,R,R, G,G + x,G, B,B,B + x) - -/** - * Greyscale matrix. - */ -/proc/color_matrix_greyscale() - return list(LUMA_R, LUMA_R, LUMA_R, LUMA_G, LUMA_G, LUMA_G, LUMA_B, LUMA_B, LUMA_B) - -/** - * Changes distance colors have from rgb(127,127,127) grey. - * 1 is identity. 0 makes everything grey >1 blows out colors and greys. - */ -/proc/color_matrix_contrast(value) - var/add = (1 - value) / 2 - return list(value,0,0,0, 0,value,0,0, 0,0,value,0, 0,0,0,1, add,add,add,0) - -/** - * Exxagerates or removes brightness. - */ -/proc/color_matrix_contrast_percent(percent) - var/static/list/delta_index = list( - 0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11, - 0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.20, 0.21, 0.22, 0.24, - 0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42, - 0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, - 0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98, - 1.0, 1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54, - 1.60, 1.66, 1.72, 1.78, 1.84, 1.90, 1.96, 2.0, 2.12, 2.25, - 2.37, 2.50, 2.62, 2.75, 2.87, 3.0, 3.2, 3.4, 3.6, 3.8, - 4.0, 4.3, 4.7, 4.9, 5.0, 5.5, 6.0, 6.5, 6.8, 7.0, - 7.3, 7.5, 7.8, 8.0, 8.4, 8.7, 9.0, 9.4, 9.6, 9.8, - 10.0) - percent = clamp(percent, -100, 100) - if(percent == 0) - return color_matrix_identity() - - var/x = 0 - if (percent < 0) - x = 127 + percent / 100 * 127; - else - x = percent % 1 - if(x == 0) - x = delta_index[percent] - else - x = delta_index[percent] * (1-x) + delta_index[percent+1] * x//use linear interpolation for more granularity. - x = x * 127 + 127 - - var/mult = x / 127 - var/add = 0.5 * (127-x) / 255 - return list(mult,0,0, 0,mult,0, 0,0,mult, add,add,add) - -/** - * Moves all colors angle degrees around the color wheel while maintaining intensity of the color and not affecting greys. - * 0 is identity, 120 moves reds to greens, 240 moves reds to blues. - */ -// -// +//Moves all colors angle degrees around the color wheel while maintaining intensity of the color and not affecting greys +//0 is identity, 120 moves reds to greens, 240 moves reds to blues /proc/color_matrix_rotate_hue(angle) var/sin = sin(angle) var/cos = cos(angle) var/cos_inv_third = 0.333*(1-cos) var/sqrt3_sin = sqrt(3)*sin return list( - round(cos+cos_inv_third, 0.001), round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), 0, - round(cos_inv_third-sqrt3_sin, 0.001), round(cos+cos_inv_third, 0.001), round(cos_inv_third+sqrt3_sin, 0.001), 0, - round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), round(cos+cos_inv_third, 0.001), 0, - 0,0,0,1, - 0,0,0,0, - ) - -/** - * Moves all colors angle degrees around the color wheel while maintaining intensity of the color and not affecting whites. - * TODO: Need a version that only affects one color (ie shift red to blue but leave greens and blues alone) - */ -/proc/color_matrix_rotation(angle) - if(angle == 0) - return color_matrix_identity() - angle = clamp(angle, -180, 180) - var/cos = cos(angle) - var/sin = sin(angle) - - var/constA = 0.143 - var/constB = 0.140 - var/constC = -0.283 - return list( - LUMA_R + cos * (1-LUMA_R) + sin * -LUMA_R, LUMA_R + cos * -LUMA_R + sin * constA, LUMA_R + cos * -LUMA_R + sin * -(1-LUMA_R), - LUMA_G + cos * -LUMA_G + sin * -LUMA_G, LUMA_G + cos * (1-LUMA_G) + sin * constB, LUMA_G + cos * -LUMA_G + sin * LUMA_G, - LUMA_B + cos * -LUMA_B + sin * (1-LUMA_B), LUMA_B + cos * -LUMA_B + sin * constC, LUMA_B + cos * (1-LUMA_B) + sin * LUMA_B - ) - -/** - * These next three rotate values about one axis only. - * x is the red axis, y is the green axis, z is the blue axis. - */ +round(cos+cos_inv_third, 0.001), round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), 0, +round(cos_inv_third-sqrt3_sin, 0.001), round(cos+cos_inv_third, 0.001), round(cos_inv_third+sqrt3_sin, 0.001), 0, +round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), round(cos+cos_inv_third, 0.001), 0, +0,0,0,1, +0,0,0,0) + +//These next three rotate values about one axis only +//x is the red axis, y is the green axis, z is the blue axis. /proc/color_matrix_rotate_x(angle) - var/sinval = round(sin(angle), 0.001) - var/cosval = round(cos(angle), 0.001) + var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001) return list(1,0,0,0, 0,cosval,sinval,0, 0,-sinval,cosval,0, 0,0,0,1, 0,0,0,0) /proc/color_matrix_rotate_y(angle) - var/sinval = round(sin(angle), 0.001) - var/cosval = round(cos(angle), 0.001) + var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001) return list(cosval,0,-sinval,0, 0,1,0,0, sinval,0,cosval,0, 0,0,0,1, 0,0,0,0) /proc/color_matrix_rotate_z(angle) - var/sinval = round(sin(angle), 0.001) - var/cosval = round(cos(angle), 0.001) + var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001) return list(cosval,sinval,0,0, -sinval,cosval,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0) -/** - * Builds a color matrix that transforms the hue, saturation, and value, all in one operation. - */ -/proc/color_matrix_hsv(hue, saturation, value) - hue = clamp(360 - hue, 0, 360) - - // This is very much a rough approximation of hueshifting. This carries some artifacting, such as negative values that simply shouldn't exist, but it does get the job done, and that's what matters. - var/cos_a = cos(hue) // These have to be inverted from 360, otherwise the hue's inverted - var/sin_a = sin(hue) - var/rot_x = cos_a + (1 - cos_a) / 3 - var/rot_y = (1 - cos_a) / 3 - 0.5774 * sin_a // 0.5774 is sqrt(1/3) - var/rot_z = (1 - cos_a) / 3 + 0.5774 * sin_a - - return list( - round((((1-saturation) * LUMA_R) + (rot_x * saturation)) * value, 0.01), round((((1-saturation) * LUMA_R) + (rot_y * saturation)) * value, 0.01), round((((1-saturation) * LUMA_R) + (rot_z * saturation)) * value, 0.01), - round((((1-saturation) * LUMA_G) + (rot_z * saturation)) * value, 0.01), round((((1-saturation) * LUMA_G) + (rot_x * saturation)) * value, 0.01), round((((1-saturation) * LUMA_G) + (rot_y * saturation)) * value, 0.01), - round((((1-saturation) * LUMA_B) + (rot_y * saturation)) * value, 0.01), round((((1-saturation) * LUMA_B) + (rot_z * saturation)) * value, 0.01), round((((1-saturation) * LUMA_B) + (rot_x * saturation)) * value, 0.01), - 0, 0, 0 - ) -/** - * Returns a matrix addition of A with B. - */ +//Returns a matrix addition of A with B /proc/color_matrix_add(list/A, list/B) if(!istype(A) || !istype(B)) - return color_matrix_identity() + return COLOR_MATRIX_IDENTITY if(A.len != 20 || B.len != 20) - return color_matrix_identity() + return COLOR_MATRIX_IDENTITY var/list/output = list() output.len = 20 for(var/value in 1 to 20) output[value] = A[value] + B[value] return output +//Returns a matrix multiplication of A with B +/proc/color_matrix_multiply(list/A, list/B) + if(!istype(A) || !istype(B)) + return COLOR_MATRIX_IDENTITY + if(A.len != 20 || B.len != 20) + return COLOR_MATRIX_IDENTITY + var/list/output = list() + output.len = 20 + var/x = 1 + var/y = 1 + var/offset = 0 + for(y in 1 to 5) + offset = (y-1)*4 + for(x in 1 to 4) + output[offset+x] = round(A[offset+1]*B[x] + A[offset+2]*B[x+4] + A[offset+3]*B[x+8] + A[offset+4]*B[x+12]+(y == 5?B[x+16]:0), 0.001) + return output + +/** + * Converts RGB shorthands into RGBA matrices complete of constants rows (ergo a 20 keys list in byond). + * if return_identity_on_fail is true, stack_trace is called instead of CRASH, and an identity is returned. + */ +/proc/color_to_full_rgba_matrix(color, return_identity_on_fail = TRUE) + if(!color) + return COLOR_MATRIX_IDENTITY + if(istext(color)) + var/list/L = rgb2num(color) + if(!L) + var/message = "Invalid/unsupported color ([color]) argument in color_to_full_rgba_matrix()" + if(return_identity_on_fail) + stack_trace(message) + return COLOR_MATRIX_IDENTITY + CRASH(message) + return list(L[1]/255,0,0,0, 0,L[2]/255,0,0, 0,0,L[3]/255,0, 0,0,0,L.len>3?L[4]/255:1, 0,0,0,0) + if(!islist(color)) //invalid format + CRASH("Invalid/unsupported color ([color]) argument in color_to_full_rgba_matrix()") + var/list/L = color + switch(L.len) + if(3 to 5) // row-by-row hexadecimals + . = list() + for(var/a in 1 to L.len) + var/list/rgb = rgb2num(L[a]) + for(var/b in rgb) + . += b/255 + if(length(rgb) % 4) // RGB has no alpha instruction + . += a != 4 ? 0 : 1 + if(L.len < 4) //missing both alphas and constants rows + . += list(0,0,0,1, 0,0,0,0) + else if(L.len < 5) //missing constants row + . += list(0,0,0,0) + if(9 to 12) //RGB + . = list(L[1],L[2],L[3],0, L[4],L[5],L[6],0, L[7],L[8],L[9],0, 0,0,0,1) + for(var/b in 1 to 3) //missing constants row + . += L.len < 9+b ? 0 : L[9+b] + . += 0 + if(16 to 20) // RGBA + . = L.Copy() + if(L.len < 20) //missing constants row + for(var/b in 1 to 20-L.len) + . += 0 + else + var/message = "Invalid/unsupported color (list of length [L.len]) argument in color_to_full_rgba_matrix()" + if(return_identity_on_fail) + stack_trace(message) + return COLOR_MATRIX_IDENTITY + CRASH(message) + +//! legacy + /** * Force a matrix to be a full 20 value rgba matrix. */ @@ -217,37 +155,28 @@ list(0.393,0.349,0.272,0, 0.769,0.686,0.534,0, 0.189,0.168,0.131,0, 0,0,0,1, 0,0 if(16) // rgba without constant expanding.Insert(17, 0, 0, 0, 0) // inject cr to ca else - . = color_matrix_identity() + . = COLOR_MATRIX_IDENTITY CRASH("what?") /** - * Returns a matrix multiplication of A with B. - * - * todo: support rgb instead of rgba. + * Builds a color matrix that transforms the hue, saturation, and value, all in one operation. */ -/proc/color_matrix_multiply(list/A, list/B) - if(!istype(A) || !istype(B)) - return color_matrix_identity() - if(A.len < 20) - A = color_matrix_expand(A) - if(B.len < 20) - B = color_matrix_expand(B) - var/list/output = list() - output.len = 20 - var/x = 1 - var/y = 1 - var/offset = 0 - for(y in 1 to 5) - offset = (y-1)*4 - for(x in 1 to 4) - output[offset+x] = round(A[offset+1]*B[x] + A[offset+2]*B[x+4] + A[offset+3]*B[x+8] + A[offset+4]*B[x+12]+(y==5?B[x+16]:0), 0.001) - return output +/proc/color_matrix_hsv(hue, saturation, value) + hue = clamp(360 - hue, 0, 360) -/** - * Assembles a color matrix, defaulting to identity. - */ -/proc/construct_rgb_color_matrix(rr = 1, rg = 0, rb = 0, gr = 0, gg = 1, gb = 0, br = 0, bg = 0, bb = 1, cr = 0, cg = 0, cb = 0) - return list(rr, rg, rb, gr, gg, gb, br, bg, bb, cr, cg, cb) + // This is very much a rough approximation of hueshifting. This carries some artifacting, such as negative values that simply shouldn't exist, but it does get the job done, and that's what matters. + var/cos_a = cos(hue) // These have to be inverted from 360, otherwise the hue's inverted + var/sin_a = sin(hue) + var/rot_x = cos_a + (1 - cos_a) / 3 + var/rot_y = (1 - cos_a) / 3 - 0.5774 * sin_a // 0.5774 is sqrt(1/3) + var/rot_z = (1 - cos_a) / 3 + 0.5774 * sin_a + + return list( + round((((1-saturation) * LUMA_R) + (rot_x * saturation)) * value, 0.01), round((((1-saturation) * LUMA_R) + (rot_y * saturation)) * value, 0.01), round((((1-saturation) * LUMA_R) + (rot_z * saturation)) * value, 0.01), + round((((1-saturation) * LUMA_G) + (rot_z * saturation)) * value, 0.01), round((((1-saturation) * LUMA_G) + (rot_x * saturation)) * value, 0.01), round((((1-saturation) * LUMA_G) + (rot_y * saturation)) * value, 0.01), + round((((1-saturation) * LUMA_B) + (rot_y * saturation)) * value, 0.01), round((((1-saturation) * LUMA_B) + (rot_z * saturation)) * value, 0.01), round((((1-saturation) * LUMA_B) + (rot_x * saturation)) * value, 0.01), + 0, 0, 0 + ) /** * Assembles a color matrix, defaulting to identity. @@ -256,23 +185,10 @@ list(0.393,0.349,0.272,0, 0.769,0.686,0.534,0, 0.189,0.168,0.131,0, 0,0,0,1, 0,0 return list(rr, rg, rb, ra, gr, gg, gb, ga, br, bg, bb, ba, ar, ag, ab, aa, cr, cg, cb, ca) /** - * Assemble a color matrix from a rgb(a) string. + * Assembles a color matrix, defaulting to identity. */ -/proc/color_matrix_from_rgb(color) - var/list/L1 = ReadRGB(color) - if(length(L1) == 3) // rgb - return construct_rgb_color_matrix( - rr = L1[1] / 255, - gg = L1[2] / 255, - bb = L1[3] / 255, - ) - else // rgba - return construct_rgba_color_matrix( - rr = L1[1] / 255, - gg = L1[2] / 255, - bb = L1[3] / 255, - aa = L1[4] / 255, - ) +/proc/construct_rgb_color_matrix(rr = 1, rg = 0, rb = 0, gr = 0, gg = 1, gb = 0, br = 0, bg = 0, bb = 1, cr = 0, cg = 0, cb = 0) + return list(rr, rg, rb, gr, gg, gb, br, bg, bb, cr, cg, cb) /** * Constructs a colored greyscale matrix. @@ -280,6 +196,6 @@ list(0.393,0.349,0.272,0, 0.769,0.686,0.534,0, 0.189,0.168,0.131,0, 0,0,0,1, 0,0 */ /proc/rgba_auto_greyscale_matrix(rgba_string) return color_matrix_multiply( - color_matrix_greyscale(), - color_matrix_from_rgb(rgba_string) + COLOR_MATRIX_GRAYSCALE, + color_to_full_rgba_matrix(rgba_string) ) diff --git a/code/__HELPERS/matrices/transform_matrix.dm b/code/__HELPERS/matrices/transform_matrix.dm index b36b94a7d7e9..51288a51b7de 100644 --- a/code/__HELPERS/matrices/transform_matrix.dm +++ b/code/__HELPERS/matrices/transform_matrix.dm @@ -1,8 +1,51 @@ +/// Datum which stores information about a matrix decomposed with decompose(). +/datum/decompose_matrix + ///? + var/scale_x = 1 + ///? + var/scale_y = 1 + ///? + var/rotation = 0 + ///? + var/shift_x = 0 + ///? + var/shift_y = 0 + +/// Decomposes a matrix into scale, shift and rotation. +/// +/// If other operations were applied on the matrix, such as shearing, the result +/// will not be precise. +/// +/// Negative scales are now supported. =) +/matrix/proc/decompose() + var/datum/decompose_matrix/decompose_matrix = new + . = decompose_matrix + var/flip_sign = (a*e - b*d < 0)? -1 : 1 // Det < 0 => only 1 axis is flipped - start doing some sign flipping + // If both axis are flipped, nothing bad happens and Det >= 0, it just treats it like a 180° rotation + // If only 1 axis is flipped, we need to flip one direction - in this case X, so we flip a, b and the x scaling + decompose_matrix.scale_x = sqrt(a * a + d * d) * flip_sign + decompose_matrix.scale_y = sqrt(b * b + e * e) + decompose_matrix.shift_x = c + decompose_matrix.shift_y = f + if(!decompose_matrix.scale_x || !decompose_matrix.scale_y) + return + // If only translated, scaled and rotated, a/xs == e/ys and -d/xs == b/xy + var/cossine = (a/decompose_matrix.scale_x + e/decompose_matrix.scale_y) / 2 + var/sine = (b/decompose_matrix.scale_y - d/decompose_matrix.scale_x) / 2 * flip_sign + decompose_matrix.rotation = arctan(cossine, sine) * flip_sign + /matrix/proc/TurnTo(old_angle, new_angle) - . = new_angle - old_angle - Turn(.) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT + return Turn(new_angle - old_angle) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT -/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3, parallel = TRUE) +/** + * Shear the transform on either or both axes. + * * x - X axis shearing + * * y - Y axis shearing + */ +/matrix/proc/Shear(x, y) + return Multiply(matrix(1, x, 0, y, 1, 0)) + +/atom/proc/SpinAnimation(speed = 1 SECONDS, loops = -1, clockwise = 1, segments = 3, parallel = TRUE) if(!segments) return var/segment = 360/segments @@ -28,9 +71,8 @@ //doesn't have an object argument because this is "Stacking" with the animate call above //3 billion% intentional -/** - * Dumps the matrix data in format a-f. - */ + +//Dumps the matrix data in format a-f /matrix/proc/tolist() . = list() . += a @@ -40,13 +82,12 @@ . += e . += f -/** - * Dumps the matrix data in a matrix-grid format. - * - * a d 0 - * b e 0 - * c f 1 - */ +//Dumps the matrix data in a matrix-grid format +/* +a d 0 +b e 0 +c f 1 +*/ /matrix/proc/togrid() . = list() . += a @@ -59,15 +100,12 @@ . += f . += 1 -/** - * The X pixel offset of this matrix. - */ + +///The X pixel offset of this matrix /matrix/proc/get_x_shift() . = c -/** - * The Y pixel offset of this matrix. - */ +///The Y pixel offset of this matrix /matrix/proc/get_y_shift() . = f diff --git a/code/__HELPERS/sorts/comparators.dm b/code/__HELPERS/sorts/comparators.dm index 0214226acb59..ace8dd066988 100644 --- a/code/__HELPERS/sorts/comparators.dm +++ b/code/__HELPERS/sorts/comparators.dm @@ -210,3 +210,6 @@ GLOBAL_VAR_INIT(cmp_field, "name") /proc/cmp_planelayer(atom/A, atom/B) return (B.plane - A.plane) || (B.layer - A.layer) + +/proc/cmp_typepaths_asc(A, B) + return sorttext("[B]","[A]") diff --git a/code/__HELPERS/type2type/color.dm b/code/__HELPERS/type2type/color.dm index eb3d3e315048..71a4644b0e4e 100644 --- a/code/__HELPERS/type2type/color.dm +++ b/code/__HELPERS/type2type/color.dm @@ -142,7 +142,7 @@ /proc/color_hex2color_matrix(string) var/length = length(string) if((length != 7 && length != 9) || length != length_char(string)) - return color_matrix_identity() + return COLOR_MATRIX_IDENTITY var/r = hex2num(copytext(string, 2, 4)) / 255 var/g = hex2num(copytext(string, 4, 6)) / 255 var/b = hex2num(copytext(string, 6, 8)) / 255 @@ -150,7 +150,7 @@ if(length == 9) a = hex2num(copytext(string, 8, 10)) / 255 if(!isnum(r) || !isnum(g) || !isnum(b) || !isnum(a)) - return color_matrix_identity() + return COLOR_MATRIX_IDENTITY return list( r,0,0,0,0, g,0,0,0,0, diff --git a/code/__HELPERS/vfx/appearance_cloning.dm b/code/__HELPERS/vfx/appearance_cloning.dm index 1d437be29f32..fc9f8148759f 100644 --- a/code/__HELPERS/vfx/appearance_cloning.dm +++ b/code/__HELPERS/vfx/appearance_cloning.dm @@ -25,7 +25,7 @@ * clones us as a high-resolution greyscale */ /atom/proc/vfx_clone_as_greyscale(alpha = 127) - var/static/list/static_greyscale_matrix = color_matrix_greyscale() + var/static/list/static_greyscale_matrix = COLOR_MATRIX_GRAYSCALE var/mutable_appearance/MA = new MA.appearance = src MA.color = static_greyscale_matrix diff --git a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm index dec55fa76c4a..74ebf6cd6021 100644 --- a/code/controllers/subsystem/atoms.dm +++ b/code/controllers/subsystem/atoms.dm @@ -1,97 +1,126 @@ -#define BAD_INIT_QDEL_BEFORE 1 -#define BAD_INIT_DIDNT_INIT 2 -#define BAD_INIT_SLEPT 4 -#define BAD_INIT_NO_HINT 8 - SUBSYSTEM_DEF(atoms) name = "Atoms" init_order = INIT_ORDER_ATOMS subsystem_flags = SS_NO_FIRE - var/old_subsystem_initialized + /// A stack of list(source, desired initialized state) + /// We read the source of init changes from the last entry, and assert that all changes will come with a reset + var/list/initialized_state = list() + var/base_initialized var/list/late_loaders = list() var/list/BadInitializeCalls = list() + ///initAtom() adds the atom its creating to this list iff InitializeAtoms() has been given a list to populate as an argument + var/list/created_atoms + + /// Atoms that will be deleted once the subsystem is initialized + var/list/queued_deletions = list() + + var/init_start_time + + #ifdef PROFILE_MAPLOAD_INIT_ATOM + var/list/mapload_init_times = list() + #endif + + initialized = INITIALIZATION_INSSATOMS + /datum/controller/subsystem/atoms/Initialize(timeofday) - //GLOB.fire_overlay.appearance_flags = RESET_COLOR - //setupGenetics() //to set the mutations' sequence + init_start_time = world.time + initialized = INITIALIZATION_INNEW_MAPLOAD InitializeAtoms() + initialized = INITIALIZATION_INNEW_REGULAR + return ..() -/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms) +/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms, list/atoms_to_return) if(initialized == INITIALIZATION_INSSATOMS) return - initialized = INITIALIZATION_INNEW_MAPLOAD - - LAZYINITLIST(late_loaders) + // Generate a unique mapload source for this run of InitializeAtoms + var/static/uid = 0 + uid = (uid + 1) % (SHORT_REAL_LIMIT - 1) + var/source = "subsystem init [uid]" + set_tracked_initalized(INITIALIZATION_INNEW_MAPLOAD, source) - var/count - var/list/mapload_arg = list(TRUE) - if(atoms) - count = atoms.len - for(var/I in atoms) - var/atom/A = I - if(!(A.atom_flags & ATOM_INITIALIZED)) - InitAtom(I, mapload_arg) - CHECK_TICK - else - count = 0 - for(var/atom/A in world) - if(!(A.atom_flags & ATOM_INITIALIZED)) - InitAtom(A, mapload_arg) - ++count - CHECK_TICK - - testing("Initialized [count] atoms") - pass(count) - - initialized = INITIALIZATION_INNEW_REGULAR + // This may look a bit odd, but if the actual atom creation runtimes for some reason, we absolutely need to set initialized BACK + CreateAtoms(atoms, atoms_to_return, source) + clear_tracked_initalize(source) if(late_loaders.len) - for(var/I in late_loaders) - var/atom/A = I + for(var/I in 1 to late_loaders.len) + var/atom/A = late_loaders[I] + //I hate that we need this + if(QDELETED(A)) + continue A.LateInitialize() testing("Late initialized [late_loaders.len] atoms") late_loaders.Cut() -/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments) - var/the_type = A.type - if(QDELING(A)) - BadInitializeCalls[the_type] |= BAD_INIT_QDEL_BEFORE - return TRUE + if (created_atoms) + atoms_to_return += created_atoms + created_atoms = null + + for (var/queued_deletion in queued_deletions) + qdel(queued_deletion) - var/start_tick = world.time + testing("[queued_deletions.len] atoms were queued for deletion.") + queued_deletions.Cut() - var/result = A.Initialize(arglist(arguments)) + #ifdef PROFILE_MAPLOAD_INIT_ATOM + rustg_file_write(json_encode(mapload_init_times), "[GLOB.log_directory]/init_times.json") + #endif - if(start_tick != world.time) - BadInitializeCalls[the_type] |= BAD_INIT_SLEPT +/// Actually creates the list of atoms. Exists solely so a runtime in the creation logic doesn't cause initialized to totally break +/datum/controller/subsystem/atoms/proc/CreateAtoms(list/atoms, list/atoms_to_return = null, mapload_source = null) + if (atoms_to_return) + LAZYINITLIST(created_atoms) - var/qdeleted = FALSE + #ifdef TESTING + var/count + #endif + + var/list/mapload_arg = list(TRUE) - if(result != INITIALIZE_HINT_NORMAL) - switch(result) - if(INITIALIZE_HINT_LATELOAD) - if(arguments[1]) //mapload - late_loaders += A - else - A.LateInitialize() - if(INITIALIZE_HINT_QDEL) - qdel(A) - qdeleted = TRUE - else - BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT + if(atoms) + #ifdef TESTING + count = atoms.len + #endif + + for(var/I in 1 to atoms.len) + var/atom/A = atoms[I] + if(!(A.atom_flags & ATOM_INITIALIZED)) + // Unrolled CHECK_TICK setup to let us enable/disable mapload based off source + if(TICK_CHECK) + clear_tracked_initalize(mapload_source) + stoplag() + if(mapload_source) + set_tracked_initalized(INITIALIZATION_INNEW_MAPLOAD, mapload_source) + PROFILE_INIT_ATOM_BEGIN() + InitAtom(A, TRUE, mapload_arg) + PROFILE_INIT_ATOM_END(A) + else + #ifdef TESTING + count = 0 + #endif - if(!A) //possible harddel - qdeleted = TRUE - else if(!(A.atom_flags & ATOM_INITIALIZED)) - BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT + for(var/atom/A as anything in world) + if(!(A.atom_flags & ATOM_INITIALIZED)) + PROFILE_INIT_ATOM_BEGIN() + InitAtom(A, FALSE, mapload_arg) + PROFILE_INIT_ATOM_END(A) + #ifdef TESTING + ++count + #endif + if(TICK_CHECK) + clear_tracked_initalize(mapload_source) + stoplag() + if(mapload_source) + set_tracked_initalized(INITIALIZATION_INNEW_MAPLOAD, mapload_source) - return qdeleted || QDELING(A) + testing("Initialized [count] atoms") /** * immediately creates and inits an atom @@ -109,12 +138,44 @@ SUBSYSTEM_DEF(atoms) initialized = old_initialized return created -/datum/controller/subsystem/atoms/proc/map_loader_begin() - old_subsystem_initialized = initialized - initialized = INITIALIZATION_INSSATOMS +/datum/controller/subsystem/atoms/proc/map_loader_begin(source) + set_tracked_initalized(INITIALIZATION_INSSATOMS, source) + +/datum/controller/subsystem/atoms/proc/map_loader_stop(source) + clear_tracked_initalize(source) + +/// Returns the source currently modifying SSatom's init behavior +/datum/controller/subsystem/atoms/proc/get_initialized_source() + var/state_length = length(initialized_state) + if(!state_length) + return null + return initialized_state[state_length][1] + +/// Use this to set initialized to prevent error states where the old initialized is overridden, and we end up losing all context +/// Accepts a state and a source, the most recent state is used, sources exist to prevent overriding old values accidentally +/datum/controller/subsystem/atoms/proc/set_tracked_initalized(state, source) + if(!length(initialized_state)) + base_initialized = initialized + initialized_state += list(list(source, state)) + initialized = state + +/datum/controller/subsystem/atoms/proc/clear_tracked_initalize(source) + if(!length(initialized_state)) + return + for(var/i in length(initialized_state) to 1 step -1) + if(initialized_state[i][1] == source) + initialized_state.Cut(i, i+1) + break + + if(!length(initialized_state)) + initialized = base_initialized + base_initialized = INITIALIZATION_INNEW_REGULAR + return + initialized = initialized_state[length(initialized_state)][2] -/datum/controller/subsystem/atoms/proc/map_loader_stop() - initialized = old_subsystem_initialized +/// Returns TRUE if anything is currently being initialized +/datum/controller/subsystem/atoms/proc/initializing_something() + return length(initialized_state) > 1 /datum/controller/subsystem/atoms/proc/init_map_bounds(list/bounds) if (initialized == INITIALIZATION_INSSATOMS) @@ -165,51 +226,36 @@ SUBSYSTEM_DEF(atoms) admin_notice("Submap initializations finished.", R_DEBUG) + /datum/controller/subsystem/atoms/Recover() initialized = SSatoms.initialized if(initialized == INITIALIZATION_INNEW_MAPLOAD) InitializeAtoms() - old_subsystem_initialized = SSatoms.old_subsystem_initialized + initialized_state = SSatoms.initialized_state BadInitializeCalls = SSatoms.BadInitializeCalls -/* -/datum/controller/subsystem/atoms/proc/setupGenetics() - var/list/mutations = subtypesof(/datum/mutation/human) - shuffle_inplace(mutations) - for(var/A in subtypesof(/datum/generecipe)) - var/datum/generecipe/GR = A - GLOB.mutation_recipes[initial(GR.required)] = initial(GR.result) - for(var/i in 1 to LAZYLEN(mutations)) - var/path = mutations[i] //byond gets pissy when we do it in one line - var/datum/mutation/human/B = new path () - B.alias = "Mutation #[i]" - GLOB.all_mutations[B.type] = B - GLOB.full_sequences[B.type] = generate_gene_sequence(B.blocks) - if(B.locked) - continue - if(B.quality == POSITIVE) - GLOB.good_mutations |= B - else if(B.quality == NEGATIVE) - GLOB.bad_mutations |= B - else if(B.quality == MINOR_NEGATIVE) - GLOB.not_good_mutations |= B - CHECK_TICK -*/ - /datum/controller/subsystem/atoms/proc/InitLog() . = "" for(var/path in BadInitializeCalls) . += "Path : [path] \n" var/fails = BadInitializeCalls[path] if(fails & BAD_INIT_DIDNT_INIT) - . += "- Didn't call atom/Initialize()\n" + . += "- Didn't call atom/Initialize(mapload)\n" if(fails & BAD_INIT_NO_HINT) . += "- Didn't return an Initialize hint\n" if(fails & BAD_INIT_QDEL_BEFORE) - . += "- Qdel'd in New()\n" + . += "- Qdel'd before Initialize proc ran\n" if(fails & BAD_INIT_SLEPT) . += "- Slept during Initialize()\n" +/// Prepares an atom to be deleted once the atoms SS is initialized. +/datum/controller/subsystem/atoms/proc/prepare_deletion(atom/target) + if (initialized == INITIALIZATION_INNEW_REGULAR) + // Atoms SS has already completed, just kill it now. + qdel(target) + else + queued_deletions += WEAKREF(target) + /datum/controller/subsystem/atoms/Shutdown() var/initlog = InitLog() if(initlog) diff --git a/code/datums/holograms/hologram.dm b/code/datums/holograms/hologram.dm index eeeef5374ad5..536f0b17a6f4 100644 --- a/code/datums/holograms/hologram.dm +++ b/code/datums/holograms/hologram.dm @@ -57,10 +57,10 @@ GLOBAL_LIST_INIT(holograms, __init_holograms()) /datum/hologram/proc/render_greyscale(cheap, alpha = 140 / 255) if(cheap) var/mutable_appearance/rendering = make_hologram_appearance(image(icon = icon, icon_state = icon_state), alpha) - rendering.color = color_matrix_greyscale() + rendering.color = COLOR_MATRIX_GRAYSCALE return rendering else var/icon/rendering = render_hologram_icon(image(icon = icon, icon_state = icon_state), alpha) - rendering.MapColors(arglist(color_matrix_greyscale())) + rendering.MapColors(arglist(COLOR_MATRIX_GRAYSCALE)) return rendering diff --git a/code/game/atoms/atom.dm b/code/game/atoms/_atom.dm similarity index 88% rename from code/game/atoms/atom.dm rename to code/game/atoms/_atom.dm index d01dc169e376..0bdec7cb8c73 100644 --- a/code/game/atoms/atom.dm +++ b/code/game/atoms/_atom.dm @@ -205,128 +205,6 @@ /// Default sound played on a burn type impact. This is usually null for default. var/hit_sound_burn -/proc/lint__check_atom_new_doesnt_sleep() - SHOULD_NOT_SLEEP(TRUE) - var/atom/target - target.New() - -/** - * Called when an atom is created in byond (built in engine proc) - * - * Not a lot happens here in SS13 code, as we offload most of the work to the - * [Intialization][/atom/proc/Initialize] proc, mostly we run the preloader - * if the preloader is being used and then call [InitAtom][/datum/controller/subsystem/atoms/proc/InitAtom] of which the ultimate - * result is that the Intialize proc is called. - * - * We also generate a tag here if the DF_USE_TAG flag is set on the atom - */ -/atom/New(loc, ...) - // atom creation method that preloads variables at creation - // todo: we shouldn't need a type check here. - if(global.dmm_preloader_active && global.dmm_preloader_target == type) - world.preloader_load(src) - - if(datum_flags & DF_USE_TAG) - generate_tag() - - var/do_initialize = SSatoms.initialized - if(do_initialize != INITIALIZATION_INSSATOMS) - args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD - if(SSatoms.InitAtom(src, args)) - //we were deleted - return - -/** - * Called by the maploader if a dmm_context is set - */ -/atom/proc/preloading_instance(datum/dmm_context/context) - return - -/** - * hook for abstract direction sets from the maploader - * - * return FALSE to override maploader automatic rotation - */ -/atom/proc/preloading_dir(datum/dmm_context/context) - return TRUE - -/** - * The primary method that objects are setup in SS13 with - * - * we don't use New as we have better control over when this is called and we can choose - * to delay calls or hook other logic in and so forth - * - * During roundstart map parsing, atoms are queued for intialization in the base atom/New(), - * After the map has loaded, then Initalize is called on all atoms one by one. NB: this - * is also true for loading map templates as well, so they don't Initalize until all objects - * in the map file are parsed and present in the world - * - * If you're creating an object at any point after SSInit has run then this proc will be - * immediately be called from New. - * - * mapload: This parameter is true if the atom being loaded is either being intialized during - * the Atom subsystem intialization, or if the atom is being loaded from the map template. - * If the item is being created at runtime any time after the Atom subsystem is intialized then - * it's false. - * - * The mapload argument occupies the same position as loc when Initialize() is called by New(). - * loc will no longer be needed after it passed New(), and thus it is being overwritten - * with mapload at the end of atom/New() before this proc (atom/Initialize()) is called. - * - * You must always call the parent of this proc, otherwise failures will occur as the item - * will not be seen as initalized (this can lead to all sorts of strange behaviour, like - * the item being completely unclickable) - * - * !Note: Ignore the note below until the first two lines of the proc are uncommented. -Zandario - * You must not sleep in this proc, or any subprocs - * - * Any parameters from new are passed through (excluding loc), naturally if you're loading from a map - * there are no other arguments - * - * Must return an [initialization hint][INITIALIZE_HINT_NORMAL] or a runtime will occur. - * - * !Note: the following functions don't call the base for optimization and must copypasta handling: - * * [/turf/proc/Initialize] - */ -/atom/proc/Initialize(mapload, ...) - SHOULD_NOT_SLEEP(TRUE) - SHOULD_CALL_PARENT(TRUE) - if(atom_flags & ATOM_INITIALIZED) - stack_trace("Warning: [src]([type]) initialized multiple times!") - atom_flags |= ATOM_INITIALIZED - - if (is_datum_abstract()) - log_debug("Abstract atom [type] created!") - return INITIALIZE_HINT_QDEL - - if(loc) - SEND_SIGNAL(loc, COMSIG_ATOM_INITIALIZED_ON, src) /// Sends a signal that the new atom `src`, has been created at `loc` - - if(light_power && light_range) - update_light() - - SETUP_SMOOTHING() - - if(opacity && isturf(loc)) - var/turf/T = loc - T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guranteed to be on afterwards anyways. - - return INITIALIZE_HINT_NORMAL - -/** - * Late Intialization, for code that should run after all atoms have run Intialization - * - * To have your LateIntialize proc be called, your atoms [Initalization][/atom/proc/Initialize] - * proc must return the hint - * [INITIALIZE_HINT_LATELOAD] otherwise you will never be called. - * - * useful for doing things like finding other machines on GLOB.machines because you can guarantee - * that all atoms will actually exist in the "WORLD" at this time and that all their Intialization - * code has been run - */ -/atom/proc/LateInitialize() - set waitfor = FALSE - /** * Top level of the destroy chain for most atoms * @@ -357,6 +235,20 @@ return ..() +/** + * Called by the maploader if a dmm_context is set + */ +/atom/proc/preloading_instance(datum/dmm_context/context) + return + +/** + * hook for abstract direction sets from the maploader + * + * return FALSE to override maploader automatic rotation + */ +/atom/proc/preloading_dir(datum/dmm_context/context) + return TRUE + /atom/proc/reveal_blood() return @@ -531,12 +423,13 @@ /atom/proc/relaymove_from_contents(mob/user, direction) return relaymove(user, direction) -// Called to set the atom's density and used to add behavior to density changes. -/atom/proc/set_density(var/new_density) - if(density == new_density) - return FALSE - density = !!new_density // Sanitize to be strictly 0 or 1 - return TRUE +///Setter for the `density` variable to append behavior related to its changing. +/atom/proc/set_density(new_value) + SHOULD_CALL_PARENT(TRUE) + if(density == new_value) + return + . = density + density = new_value // Called to set the atom's invisibility and usd to add behavior to invisibility changes. /atom/proc/set_invisibility(var/new_invisibility) diff --git a/code/game/atoms/vv.dm b/code/game/atoms/atom_vv.dm similarity index 71% rename from code/game/atoms/vv.dm rename to code/game/atoms/atom_vv.dm index f36655a135e7..4937bb3e97c2 100644 --- a/code/game/atoms/vv.dm +++ b/code/game/atoms/atom_vv.dm @@ -1,97 +1,8 @@ /** - * call back when a var is edited on this atom - * - * Can be used to implement special handling of vars - * - * At the atom level, if you edit a var named "color" it will add the atom colour with - * admin level priority to the atom colours list - * - * Also, if GLOB.Debug2 is FALSE, it sets the ADMIN_SPAWNED_1 flag on flags_1, which signifies - * the object has been admin edited - */ -/atom/vv_edit_var(var_name, var_value, mass_edit, raw_edit) - if(raw_edit) - return ..() - - switch(var_name) - if(NAMEOF(src, smoothing_junction)) - set_smoothed_icon_state(var_value) - . = TRUE - if(NAMEOF(src, opacity)) - set_opacity(var_value) - . = TRUE - if(NAMEOF(src, base_pixel_x)) - set_base_pixel_x(var_value) - . = TRUE - if(NAMEOF(src, base_pixel_y)) - set_base_pixel_y(var_value) - . = TRUE - if(NAMEOF(src, integrity)) - if(!isnum(var_value)) - return FALSE - if(var_value > integrity_max) - integrity_max = var_value - var_value = max(0, var_value) - if(integrity_enabled) - set_integrity(var_value) - . = TRUE - if(NAMEOF(src, integrity_failure)) - if(!isnum(var_value) || var_value < 0) - return FALSE - if(NAMEOF(src, integrity_max)) - if(!isnum(var_value)) - return FALSE - var_value = max(0, var_value) - if(NAMEOF(src, contents)) - var/list/O = contents - var/list/N = var_value - for(var/atom/movable/AM in O - N) - // these go away - AM.moveToNullspace() - for(var/atom/movable/AM in N - O) - // these go in - AM.forceMove(src) - - if(!isnull(.)) - datum_flags |= DF_VAR_EDITED - return - - . = ..() - if(!.) - return - - switch(var_name) - if(NAMEOF(src, color)) - add_atom_colour(color, ADMIN_COLOUR_PRIORITY) - if(NAMEOF(src, base_layer), NAMEOF(src, layer)) - set_base_layer(var_value) - if(NAMEOF(src, relative_layer)) - set_relative_layer(var_value) - if(NAMEOF(src, integrity_max)) - integrity = min(integrity_max, integrity) - if(NAMEOF(src, integrity_failure)) - if(integrity_enabled) - var/was_failing = integrity_failure >= integrity - var/now_failing = var_value >= integrity - if(!was_failing && now_failing) - atom_break() - else if(was_failing && !now_failing) - atom_fix() - -/atom/vv_get_var(var_name, resolve) - switch(var_name) - if(NAMEOF(src, base_layer)) - if(isnull(base_layer)) - return debug_variable(NAMEOF(src, base_layer), layer, 0, src) - else - return debug_variable(NAMEOF(src, base_layer), base_layer, 0, src) - return ..() - -/** - * Return the markup to for the dropdown list for the VV panel for this atom - * - * Override in subtypes to add custom VV handling in the VV panel - */ + * Return the markup to for the dropdown list for the VV panel for this atom + * + * Override in subtypes to add custom VV handling in the VV panel + */ /atom/vv_get_dropdown() . = ..() VV_DROPDOWN_OPTION("", "---------") @@ -99,22 +10,30 @@ var/turf/curturf = get_turf(src) if(curturf) . += "" + VV_DROPDOWN_OPTION(VV_HK_MODIFY_TRANSFORM, "Modify Transform") + VV_DROPDOWN_OPTION(VV_HK_SPIN_ANIMATION, "SpinAnimation") + VV_DROPDOWN_OPTION(VV_HK_STOP_ALL_ANIMATIONS, "Stop All Animations") + // VV_DROPDOWN_OPTION(VV_HK_SHOW_HIDDENPRINTS, "Show Hiddenprint log") VV_DROPDOWN_OPTION(VV_HK_ADD_REAGENT, "Add Reagent") - VV_DROPDOWN_OPTION(VV_HK_EDIT_ARMOR, "Edit Armor") + VV_DROPDOWN_OPTION(VV_HK_TRIGGER_EMP, "EMP Pulse") + VV_DROPDOWN_OPTION(VV_HK_TRIGGER_EXPLOSION, "Explosion") VV_DROPDOWN_OPTION(VV_HK_EDIT_FILTERS, "Edit Filters") VV_DROPDOWN_OPTION(VV_HK_EDIT_COLOR_MATRIX, "Edit Color as Matrix") - VV_DROPDOWN_OPTION(VV_HK_MODIFY_TRANSFORM, "Modify Transform") - VV_DROPDOWN_OPTION(VV_HK_TRIGGER_EXPLOSION, "Explosion") - VV_DROPDOWN_OPTION(VV_HK_TRIGGER_EMP, "EMP Pulse") + // VV_DROPDOWN_OPTION(VV_HK_TEST_MATRIXES, "Test Matrices") + // VV_DROPDOWN_OPTION(VV_HK_ADD_AI, "Add AI controller") + VV_DROPDOWN_OPTION(VV_HK_EDIT_ARMOR, "Edit Armor") /atom/vv_do_topic(list/href_list) . = ..() + + if(!.) + return + if(href_list[VV_HK_ADD_REAGENT] && check_rights(R_VAREDIT)) if(!reagents) var/amount = input(usr, "Specify the reagent size of [src]", "Set Reagent Size", 50) as num|null if(amount) create_reagents(amount) - if(reagents) var/chosen_id switch(alert(usr, "Choose a method.", "Add Reagents", "Search", "Choose from a list", "I'm feeling lucky")) @@ -133,7 +52,7 @@ if(!valid_id) to_chat(usr, "A reagent with that ID doesn't exist!") if("Choose from a list") - chosen_id = input(usr, "Choose a reagent to add.", "Choose a reagent.") as null|anything in subtypesof(/datum/reagent) + chosen_id = input(usr, "Choose a reagent to add.", "Choose a reagent.") as null|anything in sortList(subtypesof(/datum/reagent), GLOBAL_PROC_REF(cmp_typepaths_asc)) if("I'm feeling lucky") chosen_id = pick(subtypesof(/datum/reagent)) if(chosen_id) @@ -141,35 +60,84 @@ if(amount) reagents.add_reagent(chosen_id, amount) log_admin("[key_name(usr)] has added [amount] units of [chosen_id] to [src]") - message_admins("[key_name(usr)] has added [amount] units of [chosen_id] to [src]") + message_admins(SPAN_NOTICE("[key_name(usr)] has added [amount] units of [chosen_id] to [src]")) + if(href_list[VV_HK_TRIGGER_EXPLOSION] && check_rights(R_FUN)) usr.client.cmd_admin_explosion(src) + if(href_list[VV_HK_TRIGGER_EMP] && check_rights(R_FUN)) usr.client.cmd_admin_emp(src) + if(href_list[VV_HK_MODIFY_TRANSFORM] && check_rights(R_VAREDIT)) - var/result = input(usr, "Choose the transformation to apply","Transform Mod") as null|anything in list("Scale","Translate","Rotate") + var/result = input(usr, "Choose the transformation to apply","Transform Mod") as null|anything in list("Scale","Translate","Rotate","Shear") var/matrix/M = transform + if(!result) + return switch(result) if("Scale") var/x = input(usr, "Choose x mod","Transform Mod") as null|num var/y = input(usr, "Choose y mod","Transform Mod") as null|num - if(!isnull(x) && !isnull(y)) - transform = M.Scale(x,y) + if(isnull(x) || isnull(y)) + return + transform = M.Scale(x,y) if("Translate") + var/x = input(usr, "Choose x mod (negative = left, positive = right)","Transform Mod") as null|num + var/y = input(usr, "Choose y mod (negative = down, positive = up)","Transform Mod") as null|num + if(isnull(x) || isnull(y)) + return + transform = M.Translate(x,y) + if("Shear") var/x = input(usr, "Choose x mod","Transform Mod") as null|num var/y = input(usr, "Choose y mod","Transform Mod") as null|num - if(!isnull(x) && !isnull(y)) - transform = M.Translate(x,y) + if(isnull(x) || isnull(y)) + return + transform = M.Shear(x,y) if("Rotate") var/angle = input(usr, "Choose angle to rotate","Transform Mod") as null|num - if(!isnull(angle)) - transform = M.Turn(angle) + if(isnull(angle)) + return + transform = M.Turn(angle) + // SEND_SIGNAL(src, COMSIG_ATOM_VV_MODIFY_TRANSFORM) + + if(href_list[VV_HK_SPIN_ANIMATION]) + if(!check_rights(R_VAREDIT)) + return + var/num_spins = input(usr, "Do you want infinite spins?", "Spin Animation") in list("Yes", "No") + if(num_spins == "No") + num_spins = input(usr, "How many spins?", "Spin Animation") as null|num + else + num_spins = -1 + if(!num_spins) + return + var/spin_speed = input(usr, "How fast?", "Spin Animation") as null|num + if(!spin_speed) + return + var/direction = input(usr, "Which direction?", "Spin Animation") in list("Clockwise", "Counter-clockwise") + switch(direction) + if("Clockwise") + direction = 1 + if("Counter-clockwise") + direction = 0 + else + return + SpinAnimation(spin_speed, num_spins, direction) + + if(href_list[VV_HK_STOP_ALL_ANIMATIONS]) + if(!check_rights(R_VAREDIT)) + return + var/result = input(usr, "Are you sure?", "Stop Animating") in list("Yes", "No") + if(result == "Yes") + animate(src, transform = null, flags = ANIMATION_END_NOW) // Literally just fucking stop animating entirely because admin said so + return + if(href_list[VV_HK_EDIT_FILTERS] && check_rights(R_VAREDIT)) var/client/C = usr.client C?.open_filter_editor(src) + if(href_list[VV_HK_EDIT_COLOR_MATRIX] && check_rights(R_VAREDIT)) var/client/C = usr.client C?.open_color_matrix_editor(src) + if(href_list[VV_HK_EDIT_ARMOR] && check_rights(R_VAREDIT)) // todo: tgui armor editor? var/list/pickerlist = list() @@ -193,3 +161,89 @@ var/refid = REF(src) . += "[VV_HREF_TARGETREF_1V(refid, VV_HK_BASIC_EDIT, "[src]", NAMEOF(src, name))]" . += "
<< [dir2text(dir) || dir] >>" + +/** + * call back when a var is edited on this atom + * + * Can be used to implement special handling of vars + * + * At the atom level, if you edit a var named "color" it will add the atom colour with + * admin level priority to the atom colours list + */ +/atom/vv_edit_var(var_name, var_value, mass_edit, raw_edit) + if(raw_edit) + return ..() + + switch(var_name) + if(NAMEOF(src, smoothing_junction)) + set_smoothed_icon_state(var_value) + . = TRUE + if(NAMEOF(src, opacity)) + set_opacity(var_value) + . = TRUE + if(NAMEOF(src, base_pixel_x)) + set_base_pixel_x(var_value) + . = TRUE + if(NAMEOF(src, base_pixel_y)) + set_base_pixel_y(var_value) + . = TRUE + if(NAMEOF(src, integrity)) + if(!isnum(var_value)) + return FALSE + if(var_value > integrity_max) + integrity_max = var_value + var_value = max(0, var_value) + if(integrity_enabled) + set_integrity(var_value) + . = TRUE + if(NAMEOF(src, integrity_failure)) + if(!isnum(var_value) || var_value < 0) + return FALSE + if(NAMEOF(src, integrity_max)) + if(!isnum(var_value)) + return FALSE + var_value = max(0, var_value) + if(NAMEOF(src, contents)) + var/list/O = contents + var/list/N = var_value + for(var/atom/movable/AM in O - N) + // these go away + AM.moveToNullspace() + for(var/atom/movable/AM in N - O) + // these go in + AM.forceMove(src) + + if(!isnull(.)) + datum_flags |= DF_VAR_EDITED + return + + . = ..() + if(!.) + return + + switch(var_name) + if(NAMEOF(src, color)) + add_atom_colour(color, ADMIN_COLOUR_PRIORITY) + if(NAMEOF(src, base_layer), NAMEOF(src, layer)) + set_base_layer(var_value) + if(NAMEOF(src, relative_layer)) + set_relative_layer(var_value) + if(NAMEOF(src, integrity_max)) + integrity = min(integrity_max, integrity) + if(NAMEOF(src, integrity_failure)) + if(integrity_enabled) + var/was_failing = integrity_failure >= integrity + var/now_failing = var_value >= integrity + if(!was_failing && now_failing) + atom_break() + else if(was_failing && !now_failing) + atom_fix() + +/atom/vv_get_var(var_name, resolve) + switch(var_name) + if(NAMEOF(src, base_layer)) + if(isnull(base_layer)) + return debug_variable(NAMEOF(src, base_layer), layer, 0, src) + else + return debug_variable(NAMEOF(src, base_layer), base_layer, 0, src) + return ..() diff --git a/code/game/atoms/atoms_initializing_EXPENSIVE.dm b/code/game/atoms/atoms_initializing_EXPENSIVE.dm new file mode 100644 index 000000000000..3c1dbacb0149 --- /dev/null +++ b/code/game/atoms/atoms_initializing_EXPENSIVE.dm @@ -0,0 +1,159 @@ +/// Init this specific atom +/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, from_template = FALSE, list/arguments) + + var/the_type = A.type + + if(QDELING(A)) + // Check init_start_time to not worry about atoms created before the atoms SS that are cleaned up before this + if (A.gc_destroyed > init_start_time) + BadInitializeCalls[the_type] |= BAD_INIT_QDEL_BEFORE + return TRUE + + // This is handled and battle tested by dreamchecker. Limit to UNIT_TESTS just in case that ever fails. + #ifdef UNIT_TESTS + var/start_tick = world.time + #endif + + var/result = A.Initialize(arglist(arguments)) + + #ifdef UNIT_TESTS + if(start_tick != world.time) + BadInitializeCalls[the_type] |= BAD_INIT_SLEPT + #endif + + var/qdeleted = FALSE + + switch(result) + if (INITIALIZE_HINT_NORMAL) + EMPTY_BLOCK_GUARD // Pass + if(INITIALIZE_HINT_LATELOAD) + if(arguments[1]) //mapload + late_loaders += A + else + A.LateInitialize() + if(INITIALIZE_HINT_QDEL) + qdel(A) + qdeleted = TRUE + else + BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT + + if(!A) //possible harddel + qdeleted = TRUE + else if(!(A.atom_flags & ATOM_INITIALIZED)) + BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT + else + SEND_SIGNAL(A, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE) + // SEND_GLOBAL_SIGNAL(COMSIG_GLOB_ATOM_AFTER_POST_INIT, A) + var/atom/location = A.loc + if(location) + /// Sends a signal that the new atom `src`, has been created at `loc` + SEND_SIGNAL(location, COMSIG_ATOM_INITIALIZED_ON, A, arguments[1]) + if(created_atoms && from_template && ispath(the_type, /atom/movable))//we only want to populate the list with movables + created_atoms += A.get_all_contents() + + return qdeleted || QDELING(A) + +/** + * Called when an atom is created in byond (built in engine proc) + * + * Not a lot happens here in SS13 code, as we offload most of the work to the + * [Initialization][/atom/proc/Initialize] proc, mostly we run the preloader + * if the preloader is being used and then call [InitAtom][/datum/controller/subsystem/atoms/proc/InitAtom] of which the ultimate + * result is that the Initialize proc is called. + * + */ +/atom/New(loc, ...) + //atom creation method that preloads variables at creation + if(global.dmm_preloader_active && global.dmm_preloader_target == type)//in case the instantiated atom is creating other atoms in New() + world.preloader_load(src) + + if(datum_flags & DF_USE_TAG) + generate_tag() + + var/do_initialize = SSatoms.initialized + if(do_initialize != INITIALIZATION_INSSATOMS) + args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD + if(SSatoms.InitAtom(src, FALSE, args)) + //we were deleted + return + +/** + * The primary method that objects are setup in SS13 with + * + * we don't use New as we have better control over when this is called and we can choose + * to delay calls or hook other logic in and so forth + * + * During roundstart map parsing, atoms are queued for initialization in the base atom/New(), + * After the map has loaded, then Initialize is called on all atoms one by one. NB: this + * is also true for loading map templates as well, so they don't Initialize until all objects + * in the map file are parsed and present in the world + * + * If you're creating an object at any point after SSInit has run then this proc will be + * immediately be called from New. + * + * mapload: This parameter is true if the atom being loaded is either being initialized during + * the Atom subsystem initialization, or if the atom is being loaded from the map template. + * If the item is being created at runtime any time after the Atom subsystem is initialized then + * it's false. + * + * The mapload argument occupies the same position as loc when Initialize() is called by New(). + * loc will no longer be needed after it passed New(), and thus it is being overwritten + * with mapload at the end of atom/New() before this proc (atom/Initialize()) is called. + * + * You must always call the parent of this proc, otherwise failures will occur as the item + * will not be seen as initialized (this can lead to all sorts of strange behaviour, like + * the item being completely unclickable) + * + * You must not sleep in this proc, or any subprocs + * + * Any parameters from new are passed through (excluding loc), naturally if you're loading from a map + * there are no other arguments + * + * Must return an [initialization hint][INITIALIZE_HINT_NORMAL] or a runtime will occur. + * + * Note: the following functions don't call the base for optimization and must copypasta handling: + * * [/turf/proc/Initialize] + * * [/turf/open/space/proc/Initialize] + */ +/atom/proc/Initialize(mapload, ...) + SHOULD_NOT_SLEEP(TRUE) + SHOULD_CALL_PARENT(TRUE) + + if(atom_flags & ATOM_INITIALIZED) + stack_trace("Warning: [src]([type]) initialized multiple times!") + atom_flags |= ATOM_INITIALIZED + + if (is_datum_abstract()) + log_debug("Abstract atom [type] created!") + return INITIALIZE_HINT_QDEL + + //atom color stuff + if(color) + add_atom_colour(color, FIXED_COLOUR_PRIORITY) + + if(light_power && light_range) + update_light() + + SETUP_SMOOTHING() + + if(opacity && isturf(loc)) + var/turf/T = loc + T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guranteed to be on afterwards anyways. + + return INITIALIZE_HINT_NORMAL + +/** + * Late Initialization, for code that should run after all atoms have run Initialization + * + * To have your LateIntialize proc be called, your atoms [Initialization][/atom/proc/Initialize] + * proc must return the hint + * [INITIALIZE_HINT_LATELOAD] otherwise it will never be called. + * + * useful for doing things like finding other machines on GLOB.machines because you can guarantee + * that all atoms will actually exist in the "WORLD" at this time and that all their Initialization + * code has been run + */ +/atom/proc/LateInitialize() + set waitfor = FALSE + SHOULD_CALL_PARENT(FALSE) + stack_trace("[src] ([type]) called LateInitialize but has nothing on it!") diff --git a/code/game/atoms/movement.dm b/code/game/atoms/movement.dm index 4910477e5325..4eaa8a24b887 100644 --- a/code/game/atoms/movement.dm +++ b/code/game/atoms/movement.dm @@ -33,9 +33,8 @@ ///Can the mover object pass this atom, while heading for the target turf /atom/proc/CanPass(atom/movable/mover, turf/target) - // SHOULD_NOT_OVERRIDE(TRUE) - // SHOULD_BE_PURE(TRUE) // SHOULD_CALL_PARENT(TRUE) + // SHOULD_BE_PURE(TRUE) if(mover.movement_type & MOVEMENT_UNSTOPPABLE) return TRUE . = CanAllowThrough(mover, target) diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 7fd8de7c9530..f3dfb5f75fad 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -256,7 +256,6 @@ return INITIALIZE_HINT_LATELOAD /obj/machinery/computer/scan_consolenew/LateInitialize() - . = ..() scan_for_scanner() addtimer(CALLBACK(src, PROC_REF(recharge_injector)), 25 SECONDS) diff --git a/code/game/landmarks/landmarks.dm b/code/game/landmarks/landmarks.dm index d00ae3343d8f..d17eddaade7d 100644 --- a/code/game/landmarks/landmarks.dm +++ b/code/game/landmarks/landmarks.dm @@ -36,29 +36,10 @@ INITIALIZE_IMMEDIATE(/obj/landmark) else GLOB.landmarks_keyed[landmark_key] += src -/obj/landmark/Destroy() - GLOB.landmarks_list -= src - if(landmark_key && GLOB.landmarks_keyed[landmark_key]) - GLOB.landmarks_keyed[landmark_key] -= src - if(!length(GLOB.landmarks_keyed[landmark_key])) - GLOB.landmarks_keyed -= landmark_key - return ..() - -/** - * Called when the round is finished setting up directly from SSticker - */ -/obj/landmark/proc/OnRoundstart() - if(QDELETED(src)) - CRASH("already deleted") - if(delete_on_roundstart) - qdel(src) - -// everything below here are subtypes -// no no no, ftfy: everything below here needs to be nuked from orbit ~silicons -/obj/landmark/Initialize(mapload) - . = ..() + // everything below here are subtypes + // no no no, ftfy: everything below here needs to be nuked from orbit ~silicons tag = "landmark*[name]" - invisibility = 101 + invisibility = INVISIBILITY_ABSTRACT switch(name) //some of these are probably obsolete if("monkey") @@ -111,7 +92,23 @@ INITIALIZE_IMMEDIATE(/obj/landmark) lavaland_exit += loc delete_on_roundstart = 1 return - return 1 + +/obj/landmark/Destroy() + GLOB.landmarks_list -= src + if(landmark_key && GLOB.landmarks_keyed[landmark_key]) + GLOB.landmarks_keyed[landmark_key] -= src + if(!length(GLOB.landmarks_keyed[landmark_key])) + GLOB.landmarks_keyed -= landmark_key + return ..() + +/** + * Called when the round is finished setting up directly from SSticker + */ +/obj/landmark/proc/OnRoundstart() + if(QDELETED(src)) + CRASH("already deleted") + if(delete_on_roundstart) + qdel(src) /obj/landmark/observer_spawn name = "observer start" diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 88b51467ac46..080b7d55293b 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -16,7 +16,6 @@ return INITIALIZE_HINT_LATELOAD /obj/machinery/sleep_console/LateInitialize() - . = ..() findsleeper() /obj/machinery/sleep_console/Destroy() diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index f5780aa48c7d..ae3898fc44ea 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -177,7 +177,6 @@ return INITIALIZE_HINT_LATELOAD /obj/machinery/body_scanconsole/LateInitialize() - . = ..() findscanner() /obj/machinery/body_scanconsole/Destroy() diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index b14ff4229d32..1d660d6d83f2 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -513,7 +513,6 @@ return INITIALIZE_HINT_LATELOAD /obj/item/paper/monitorkey/LateInitialize() - . = ..() if(message_servers) for(var/obj/machinery/message_server/server in message_servers) if(!isnull(server)) diff --git a/code/game/machinery/doors/door_timer.dm b/code/game/machinery/doors/door_timer.dm index cd5690419e7b..e1f1dfba8c79 100644 --- a/code/game/machinery/doors/door_timer.dm +++ b/code/game/machinery/doors/door_timer.dm @@ -48,7 +48,6 @@ return INITIALIZE_HINT_LATELOAD /obj/machinery/door_timer/LateInitialize() - . = ..() if(id != null) for(var/obj/machinery/door/window/brigdoor/M in urange(20, src)) if (M.id == id) diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index ebe353bb3e0d..423e176d4d09 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -85,7 +85,6 @@ GLOBAL_LIST_INIT(firelock_align_types, typecacheof(list( return INITIALIZE_HINT_LATELOAD /obj/machinery/door/firedoor/LateInitialize() - . = ..() if(autoset_dir) for (var/cardinal in GLOB.cardinal) var/turf/step_turf = get_step(src, cardinal) diff --git a/code/game/machinery/holopad.dm b/code/game/machinery/holopad.dm index ab12b2c4607b..43d4ec6d8773 100644 --- a/code/game/machinery/holopad.dm +++ b/code/game/machinery/holopad.dm @@ -1,7 +1,7 @@ GLOBAL_LIST_EMPTY(holopad_lookup) -#define HOLO_NORMAL_COLOR color_matrix_from_rgb("#ccccff") -#define HOLO_VORE_COLOR color_matrix_from_rgb("#d97de0") +#define HOLO_NORMAL_COLOR color_to_full_rgba_matrix("#ccccff") +#define HOLO_VORE_COLOR color_to_full_rgba_matrix("#d97de0") #define HOLO_NORMAL_ALPHA 140 #define HOLO_VORE_ALPHA 210 diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 4a44849248b9..1b2cb611e5fb 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -18,19 +18,15 @@ var/image/overlay /obj/machinery/light_switch/Initialize(mapload, newdir) - . = ..() - return INITIALIZE_HINT_LATELOAD - -/obj/machinery/light_switch/LateInitialize() . = ..() area = get_area(src) - if(otherarea) area = locate(text2path("/area/[otherarea]")) - if(!name) name = "light switch ([area.name])" + return INITIALIZE_HINT_LATELOAD +/obj/machinery/light_switch/LateInitialize() on = area.lightswitch updateicon() diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index d3b48657543d..44386e2dcd30 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -189,7 +189,6 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co return INITIALIZE_HINT_LATELOAD /obj/machinery/newscaster/LateInitialize() - . = ..() node = get_exonet_node() /obj/machinery/newscaster/Destroy() diff --git a/code/game/machinery/telecomms/_telecomms.dm b/code/game/machinery/telecomms/_telecomms.dm index 65a6994ea967..55cb28f8a702 100644 --- a/code/game/machinery/telecomms/_telecomms.dm +++ b/code/game/machinery/telecomms/_telecomms.dm @@ -141,7 +141,6 @@ else for(var/obj/machinery/telecomms/T in GLOB.telecomms_list) add_link(T) - return ..() /obj/machinery/telecomms/Destroy() GLOB.telecomms_list -= src diff --git a/code/game/machinery/teleporter/pad.dm b/code/game/machinery/teleporter/pad.dm index c87279c0206f..07aaac186824 100644 --- a/code/game/machinery/teleporter/pad.dm +++ b/code/game/machinery/teleporter/pad.dm @@ -17,7 +17,6 @@ return INITIALIZE_HINT_LATELOAD /obj/machinery/tele_pad/LateInitialize() - . = ..() update_icon() /obj/machinery/tele_pad/update_icon() diff --git a/code/game/machinery/teleporter/projector.dm b/code/game/machinery/teleporter/projector.dm index 5d2922237cc6..594bf591400f 100644 --- a/code/game/machinery/teleporter/projector.dm +++ b/code/game/machinery/teleporter/projector.dm @@ -58,7 +58,6 @@ /obj/machinery/tele_projector/LateInitialize() - . = ..() for(var/target_dir in GLOB.cardinal) var/obj/machinery/tele_pad/found_pad = locate() in get_step(src, target_dir) if(found_pad) diff --git a/code/game/objects/items/stacks/sandbag.dm b/code/game/objects/items/stacks/sandbag.dm index 06915faf9048..b7d9b67d49ab 100644 --- a/code/game/objects/items/stacks/sandbag.dm +++ b/code/game/objects/items/stacks/sandbag.dm @@ -128,7 +128,6 @@ update_icon() /obj/structure/sandbag/LateInitialize() - . = ..() //update_connections(FALSE) update_icon() diff --git a/code/game/objects/structures/crates_lockers/__closet.dm b/code/game/objects/structures/crates_lockers/__closet.dm index d1c3e2fcb82b..d3597b1c215e 100644 --- a/code/game/objects/structures/crates_lockers/__closet.dm +++ b/code/game/objects/structures/crates_lockers/__closet.dm @@ -70,7 +70,6 @@ return INITIALIZE_HINT_LATELOAD /obj/structure/closet/LateInitialize() - . = ..() if(starts_with) create_objects_in_loc(src, starts_with) starts_with = null diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm index 678e7fb73aa3..55812aecb098 100644 --- a/code/game/objects/structures/crates_lockers/largecrate.dm +++ b/code/game/objects/structures/crates_lockers/largecrate.dm @@ -20,7 +20,6 @@ return INITIALIZE_HINT_LATELOAD /obj/structure/largecrate/LateInitialize() - . = ..() if(starts_with) create_objects_in_loc(src, starts_with) starts_with = null diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index 6810f3fe6fa1..53e1acc87f96 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -18,7 +18,6 @@ return INITIALIZE_HINT_LATELOAD /obj/structure/bed/chair/LateInitialize() - . = ..() update_layer() /obj/structure/bed/chair/OnMouseDrop(atom/over, mob/user) diff --git a/code/game/objects/structures/tables/table.dm b/code/game/objects/structures/tables/table.dm index 7e87919bb7e9..b18d03b6ce89 100644 --- a/code/game/objects/structures/tables/table.dm +++ b/code/game/objects/structures/tables/table.dm @@ -70,7 +70,6 @@ var/list/table_icon_cache = list() update_appearance() /obj/structure/table/LateInitialize() // CURSE YOU DUMB AS ROCKS MATERIAL SYSTEM - . = ..() update_connections(FALSE) update_appearance() diff --git a/code/game/objects/structures/transit_tubes.dm b/code/game/objects/structures/transit_tubes.dm index b365c2d1f606..3bbac7db0104 100644 --- a/code/game/objects/structures/transit_tubes.dm +++ b/code/game/objects/structures/transit_tubes.dm @@ -71,7 +71,6 @@ return INITIALIZE_HINT_LATELOAD /obj/structure/transit_tube_pod/LateInitialize() - . = ..() follow_tube() /obj/structure/transit_tube/Initialize(mapload) diff --git a/code/game/turfs/simulated/floor_types/glass.dm b/code/game/turfs/simulated/floor_types/glass.dm index 49b59058f3e8..a155b45c48fa 100644 --- a/code/game/turfs/simulated/floor_types/glass.dm +++ b/code/game/turfs/simulated/floor_types/glass.dm @@ -23,7 +23,6 @@ CREATE_STANDARD_TURFS(/turf/simulated/floor/glass) return INITIALIZE_HINT_LATELOAD /turf/simulated/floor/glass/LateInitialize() - . = ..() layer = base_layer diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index f673d08940e2..1f1cc5f2231c 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -9,7 +9,7 @@ permit_ao = FALSE initial_gas_mix = GAS_STRING_VACUUM - temperature = 2.7 + temperature = TCMB can_build_into_floor = TRUE z_eventually_space = TRUE @@ -28,12 +28,17 @@ // turn preloader off so it doesn't hit something else global.dmm_preloader_active = FALSE +/** + * Space Initialize + * + * Doesn't call parent, see [/atom/proc/Initialize]. + * When adding new stuff to /atom/Initialize, /turf/Initialize, etc + * don't just add it here unless space actually needs it. + */ /turf/space/Initialize(mapload) SHOULD_CALL_PARENT(FALSE) - atom_flags |= ATOM_INITIALIZED - // we have parallax and don't need this anymore - // icon_state = SPACE_ICON_STATE(x, y, z) + atom_flags |= ATOM_INITIALIZED if (CONFIG_GET(flag/starlight)) update_starlight() @@ -43,21 +48,6 @@ // we don't need to manually check all this in initialize return INITIALIZE_HINT_NORMAL - // var/turf/below = below() - // if(isnull(below)) - // return INITIALIZE_HINT_NORMAL - - // if(isspaceturf(below)) - // return INITIALIZE_HINT_NORMAL - - // var/area/A = below.loc - // if(!below.density && (A.area_flags & AREA_FLAG_EXTERNAL)) - // return INITIALIZE_HINT_NORMAL - - // return INITIALIZE_HINT_NORMAL - // todo: wtf happened there..? - // return INITIALIZE_HINT_LATELOAD // oh no! we need to switch to being a different kind of turf! - /turf/space/Destroy() // Cleanup cached z_eventually_space values above us. if (above) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index af7bc1cc1e4d..56be854724af 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -153,7 +153,6 @@ SETUP_SMOOTHING() - // queue if necessary; QUEUE_SMOOTH implicitly checks IS_SMOOTH so don't check again QUEUE_SMOOTH(src) //atom color stuff @@ -165,8 +164,8 @@ // this is to trigger entered effects // bad news is this is not necessarily currently idempotent // we probably have to deal with this at.. some point. - for(var/atom/movable/AM in src) - Entered(AM) + for(var/atom/movable/content as anything in src) + Entered(content) var/area/A = loc @@ -231,7 +230,7 @@ // clear vis contents here instead of in Init if(length(vis_contents)) - vis_contents.len = 0 + vis_contents.Cut() ..() diff --git a/code/modules/admin/view_variables/color_matrix_editor.dm b/code/modules/admin/view_variables/color_matrix_editor.dm index f8db04662751..29158035c1cb 100644 --- a/code/modules/admin/view_variables/color_matrix_editor.dm +++ b/code/modules/admin/view_variables/color_matrix_editor.dm @@ -60,7 +60,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/color_matrix_proxy_view) else if(istext(_target?.color)) current_color = color_hex2color_matrix(_target.color) else - current_color = color_matrix_identity() + current_color = COLOR_MATRIX_IDENTITY proxy_view = new if(_target) target = WEAKREF(_target) diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 58e91d6e34a6..ab9f5f05d489 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -23,7 +23,6 @@ return INITIALIZE_HINT_LATELOAD /obj/item/assembly/signaler/LateInitialize() - . = ..() set_frequency(frequency) /obj/item/assembly/signaler/activate() diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm index 07e76b1e7ed7..15320033a757 100644 --- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm +++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm @@ -59,7 +59,6 @@ if(port) connect(port) update_icon() - return ..() /obj/machinery/portable_atmospherics/process(delta_time) flow_current = 0 diff --git a/code/modules/industry/disposals/disposal/chute.dm b/code/modules/industry/disposals/disposal/chute.dm index 7fd8681bffb5..29fdecbfa936 100644 --- a/code/modules/industry/disposals/disposal/chute.dm +++ b/code/modules/industry/disposals/disposal/chute.dm @@ -39,7 +39,6 @@ return INITIALIZE_HINT_LATELOAD /obj/machinery/disposal/LateInitialize() - . = ..() trunk = locate() in src.loc if(!trunk) mode = 0 diff --git a/code/modules/industry/disposals/disposal_pipe/trunk.dm b/code/modules/industry/disposals/disposal_pipe/trunk.dm index 3d0b03a73a16..65647cf0efa8 100644 --- a/code/modules/industry/disposals/disposal_pipe/trunk.dm +++ b/code/modules/industry/disposals/disposal_pipe/trunk.dm @@ -9,8 +9,8 @@ return INITIALIZE_HINT_LATELOAD /obj/structure/disposalpipe/trunk/LateInitialize() - . = ..() getlinked() + /obj/structure/disposalpipe/trunk/proc/getlinked() linked = null var/obj/machinery/disposal/D = locate() in src.loc diff --git a/code/modules/mapping/dmm_suite/dmm_parsed.dm b/code/modules/mapping/dmm_suite/dmm_parsed.dm index 387a674526b1..8e1e7ee3f26b 100644 --- a/code/modules/mapping/dmm_suite/dmm_parsed.dm +++ b/code/modules/mapping/dmm_suite/dmm_parsed.dm @@ -299,8 +299,9 @@ var/static/loading = FALSE UNTIL(!loading) - loading = TRUE Master.StartLoadingMap() + loading = TRUE + SSatoms.map_loader_begin(REF(src)) _populate_orientation(context, orientation) context.loaded_dmm = src @@ -312,8 +313,9 @@ context.loaded_bounds = loaded_bounds context.success = !isnull(loaded_bounds) - Master.StopLoadingMap() + SSatoms.map_loader_stop(REF(src)) loading = FALSE + Master.StopLoadingMap() /datum/dmm_parsed/proc/_populate_orientation(datum/dmm_context/context,orientation) var/datum/dmm_orientation/orientation_pattern = GLOB.dmm_orientations["[orientation]"] @@ -523,9 +525,6 @@ //Instanciation //////////////// - //turn off base new Initialization until the whole thing is loaded - SSatoms.map_loader_begin() - //The next part of the code assumes there's ALWAYS an /area AND a /turf on a given tile //first instance the /area and remove it from the members list index = members.len @@ -578,9 +577,6 @@ for(index in 1 to first_turf_index-1) instance_atom(members[index],members_attributes[index],crds,no_changeturf,placeOnTop) - //Restore initialization to the previous value - SSatoms.map_loader_stop() - //////////////// //Helpers procs //////////////// @@ -605,9 +601,9 @@ //custom CHECK_TICK here because we don't want things created while we're sleeping to not initialize if(TICK_CHECK) - SSatoms.map_loader_stop() + SSatoms.map_loader_stop(REF(src)) stoplag() - SSatoms.map_loader_begin() + SSatoms.map_loader_begin(REF(src)) /** * create an atom at a location diff --git a/code/modules/maps/turf_makers/planet_station_turfs/_lythios43c.dm b/code/modules/maps/turf_makers/planet_station_turfs/_lythios43c.dm index 8e02d42d5e69..1af1c55feef9 100644 --- a/code/modules/maps/turf_makers/planet_station_turfs/_lythios43c.dm +++ b/code/modules/maps/turf_makers/planet_station_turfs/_lythios43c.dm @@ -3,10 +3,11 @@ #define LYTHIOS43C_TURF_CREATE(x) x/lythios43c/initial_gas_mix=ATMOSPHERE_ID_LYTHIOS43C;x/lythios43c/outdoors=TRUE #define LYTHIOS43C_TURF_CREATE_UN(x) x/lythios43c/initial_gas_mix=ATMOSPHERE_ID_LYTHIOS43C;x/lythios43c/outdoors=FALSE -/turf/simulated/open/lythios43c/Initialize(mapload) - . = ..() - if(outdoors) - SSplanets.addTurf(src) +// usless init, check [/turf/simulated/Initialize()] +// /turf/simulated/open/lythios43c/Initialize(mapload) +// . = ..() +// if(outdoors) +// SSplanets.addTurf(src) LYTHIOS43C_TURF_CREATE(/turf/simulated/open) diff --git a/code/modules/mob/freelook/ai/eye.dm b/code/modules/mob/freelook/ai/eye.dm index c0fb5e2c9d5f..214b063ce9b2 100644 --- a/code/modules/mob/freelook/ai/eye.dm +++ b/code/modules/mob/freelook/ai/eye.dm @@ -53,7 +53,6 @@ return INITIALIZE_HINT_LATELOAD /mob/living/silicon/ai/LateInitialize() - . = ..() if(eyeobj && loc) eyeobj.forceMove(loc) diff --git a/code/modules/mob/living/bot/medibot_construction.dm b/code/modules/mob/living/bot/medibot_construction.dm index 945266b09022..9f24f995dffd 100644 --- a/code/modules/mob/living/bot/medibot_construction.dm +++ b/code/modules/mob/living/bot/medibot_construction.dm @@ -19,7 +19,6 @@ return INITIALIZE_HINT_LATELOAD /obj/item/bot_assembly/medibot/LateInitialize() - . = ..() update_appearance() /obj/item/bot_assembly/medibot/update_overlays() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index c2005c49631d..f64d28e2f48d 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -57,7 +57,6 @@ //! WARNING SHITCODE REMOVE LATER /mob/living/carbon/human/LateInitialize() - . = ..() regenerate_icons() update_transform() diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 03cde2178079..4339cc4497ac 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -190,8 +190,7 @@ var/list/ai_verbs_default = list( if(!safety)//Only used by AIize() to successfully spawn an AI. if (!B)//If there is no player/brain inside. GLOB.empty_playable_ai_cores += new /obj/structure/AIcore/deactivated(loc)//New empty terminal. - qdel(src)//Delete AI. - return + return INITIALIZE_HINT_QDEL //Delete AI else if (B.brainmob.mind) B.brainmob.mind.transfer(src) @@ -346,8 +345,8 @@ var/list/ai_verbs_default = list( use_power(USE_POWER_IDLE) // Just incase we need to wake up the power system. /obj/machinery/ai_powersupply/Destroy() - . = ..() powered_ai = null + return ..() /obj/machinery/ai_powersupply/process(delta_time) if(!powered_ai || powered_ai.stat == DEAD) diff --git a/code/modules/organs/external/external_icons.dm b/code/modules/organs/external/external_icons.dm index 1af4e4b43306..a421cd26de5d 100644 --- a/code/modules/organs/external/external_icons.dm +++ b/code/modules/organs/external/external_icons.dm @@ -214,7 +214,7 @@ GLOBAL_LIST_EMPTY(limb_icon_cache) else if(s_col && s_col.len >= 3) // Support for species.color_mult if(species.color_force_greyscale) - applying.MapColors(arglist(color_matrix_greyscale())) + applying.MapColors(arglist(COLOR_MATRIX_GRAYSCALE)) icon_cache_key += "_ags" if(species && species.color_mult) applying.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_MULTIPLY) diff --git a/code/modules/overmap/legacy/ships/computers/helm.dm b/code/modules/overmap/legacy/ships/computers/helm.dm index c7ccf8a01be9..15355e7e554a 100644 --- a/code/modules/overmap/legacy/ships/computers/helm.dm +++ b/code/modules/overmap/legacy/ships/computers/helm.dm @@ -45,7 +45,6 @@ GLOBAL_LIST_EMPTY(all_waypoints) return INITIALIZE_HINT_LATELOAD /obj/machinery/computer/ship/helm/LateInitialize() - . = ..() get_known_sectors() /obj/machinery/computer/ship/helm/proc/get_known_sectors() diff --git a/code/modules/overmap/legacy/ships/computers/sensors.dm b/code/modules/overmap/legacy/ships/computers/sensors.dm index f142942fcc8b..4898d391f8a9 100644 --- a/code/modules/overmap/legacy/ships/computers/sensors.dm +++ b/code/modules/overmap/legacy/ships/computers/sensors.dm @@ -24,7 +24,6 @@ return INITIALIZE_HINT_LATELOAD /obj/machinery/computer/ship/sensors/planet/LateInitialize() - . = ..() var/area/overmap/map = locate() in world for(var/obj/overmap/entity/visitable/sector/S in map) if(istype(S,planet_type)) diff --git a/code/modules/power/breaker_box.dm b/code/modules/power/breaker_box.dm index 8314a7a6f63a..1ff84485f96c 100644 --- a/code/modules/power/breaker_box.dm +++ b/code/modules/power/breaker_box.dm @@ -43,7 +43,6 @@ /obj/machinery/power/breakerbox/activated/LateInitialize() set_state(1) - return ..() /obj/machinery/power/breakerbox/examine(mob/user, dist) . = ..() diff --git a/code/modules/power/geothermal_power.dm b/code/modules/power/geothermal_power.dm index 0fcc9139fd29..8842ccdaf919 100644 --- a/code/modules/power/geothermal_power.dm +++ b/code/modules/power/geothermal_power.dm @@ -29,7 +29,6 @@ return INITIALIZE_HINT_LATELOAD /obj/machinery/power/geothermal_controller/prepared/LateInitialize() - . = ..() scan_for_collectors(scanner?.range) /obj/machinery/power/geothermal_controller/examine(mob/user, dist) diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index c602f9b35e71..8c494ad9b372 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -129,13 +129,12 @@ GLOBAL_LIST_EMPTY(gravity_generators) var/list/areas = list() /obj/machinery/gravity_generator/main/Initialize(mapload) - ..() + . = ..() return INITIALIZE_HINT_LATELOAD /obj/machinery/gravity_generator/main/LateInitialize() //Needs to happen after overmap sectors are initialized so we can figure out where we are update_list() update_areas() - return ..() /obj/machinery/gravity_generator/main/set_fix() . = ..() diff --git a/code/modules/power/smes/smes.dm b/code/modules/power/smes/smes.dm index bde57b6dd623..2c2bce4fdd0e 100644 --- a/code/modules/power/smes/smes.dm +++ b/code/modules/power/smes/smes.dm @@ -73,7 +73,6 @@ GLOBAL_LIST_EMPTY(smeses) return INITIALIZE_HINT_LATELOAD /obj/machinery/power/smes/LateInitialize() - . = ..() if(!powernet) connect_to_network() diff --git a/tools/read_init_times.py b/tools/read_init_times.py index 4dca61c40f79..c95af704a0aa 100644 --- a/tools/read_init_times.py +++ b/tools/read_init_times.py @@ -1,5 +1,6 @@ # When passed an `init_times.json` file (received from enabling `PROFILE_MAPLOAD_INIT_ATOM`), # and an optional max-depth level, this will output init times from worst to best. +import errno import json import sys @@ -19,4 +20,10 @@ init_times_per_type[type] = init_times_per_type.get(type, 0) + time for (type, time) in sorted(init_times_per_type.items(), key = lambda x: x[1], reverse = True): - print(type, time) + try: + print(type, time) + except IOError as error: + # Prevents broken pipe error if you do something like `read_init_times.py init_times.json | head` + if error.errno == errno.EPIPE: + sys.stderr.close() + sys.exit(0)