diff --git a/.github/workflows/autowiki.yml b/.github/workflows/autowiki.yml
index 82d0ac76f32f..fec68f2ca332 100644
--- a/.github/workflows/autowiki.yml
+++ b/.github/workflows/autowiki.yml
@@ -8,7 +8,7 @@ permissions:
jobs:
autowiki:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- name: "Check for AUTOWIKI_USERNAME"
id: secrets_set
@@ -32,7 +32,7 @@ jobs:
run: |
sudo dpkg --add-architecture i386
sudo apt update || true
- sudo apt install -o APT::Immediate-Configure=false libssl1.1:i386
+ sudo apt install -o APT::Immediate-Configure=false zlib1g-dev:i386 libssl-dev:i386
bash tools/ci/install_rust_g.sh
- name: Compile and generate Autowiki files
if: steps.secrets_set.outputs.SECRETS_ENABLED
diff --git a/code/__DEFINES/chemistry.dm b/code/__DEFINES/chemistry.dm
index 9a29754381f3..078ccbdc2d94 100644
--- a/code/__DEFINES/chemistry.dm
+++ b/code/__DEFINES/chemistry.dm
@@ -49,6 +49,7 @@
// Nutrition levels
#define NUTRITION_MAX 550
+#define NUTRITION_HIGH 540
#define NUTRITION_NORMAL 400
#define NUTRITION_LOW 250
#define NUTRITION_VERYLOW 50
diff --git a/code/__DEFINES/colours.dm b/code/__DEFINES/colours.dm
index b7457f9ae478..5fa106715f39 100644
--- a/code/__DEFINES/colours.dm
+++ b/code/__DEFINES/colours.dm
@@ -142,6 +142,9 @@
*
* Important note: colours can end up significantly different from the basic html picture, especially when saturated
*/
+
+/// Full white. rgb(255, 255, 255)
+#define LIGHT_COLOR_WHITE "#FFFFFF"
/// Bright but quickly dissipating neon green. rgb(100, 200, 100)
#define LIGHT_COLOUR_GREEN "#64C864"
/// Electric green. rgb(0, 255, 0)
diff --git a/code/__DEFINES/conflict.dm b/code/__DEFINES/conflict.dm
index 7a1b322a19ee..241bcb469622 100644
--- a/code/__DEFINES/conflict.dm
+++ b/code/__DEFINES/conflict.dm
@@ -68,7 +68,7 @@
#define GUN_ANTIQUE (1<<13)
/// Whether the gun has been fired by its current user (reset upon `dropped()`)
#define GUN_RECOIL_BUILDUP (1<<14)
-/// support weapon, bipod will grant IFF
+/// support weapon, bipod will grant autofire
#define GUN_SUPPORT_PLATFORM (1<<15)
/// No gun description, only base desc
#define GUN_NO_DESCRIPTION (1<<16)
@@ -90,6 +90,8 @@
#define ATTACH_IGNORE_EMPTY (1<<5)
/// This attachment should activate if you attack() with it attached.
#define ATTACH_MELEE (1<<6)
+/// Override for attachies so you can fire them with a single hand . ONLY FOR PROJECTILES!!
+#define ATTACH_WIELD_OVERRIDE (1<<7)
//Ammo magazine defines, for flags_magazine
@@ -99,6 +101,8 @@
#define AMMUNITION_HANDFUL_BOX (1<<2)
#define AMMUNITION_HIDE_AMMO (1<<3)
#define AMMUNITION_CANNOT_REMOVE_BULLETS (1<<4)
+/// If this magazine can transfer to other magazines of the same type by slapping one with the other
+#define AMMUNITION_SLAP_TRANSFER (1<<5)
//Slowdown from various armors.
/// How much shoes slow you down by default. Negative values speed you up
@@ -216,6 +220,7 @@
#define UNIFORM_HAS_SENSORS 1
#define UNIFORM_FORCED_SENSORS 2
+#define EYE_PROTECTION_NEGATIVE -1
#define EYE_PROTECTION_NONE 0
#define EYE_PROTECTION_FLAVOR 1
#define EYE_PROTECTION_FLASH 2
diff --git a/code/__DEFINES/cooldowns.dm b/code/__DEFINES/cooldowns.dm
index e1f221dccbde..9368caf3c6e3 100644
--- a/code/__DEFINES/cooldowns.dm
+++ b/code/__DEFINES/cooldowns.dm
@@ -3,6 +3,7 @@
#define COOLDOWN_HIJACK_BARRAGE "gamemode_explosive_barrage"
#define COOLDOWN_HIJACK_GROUND_CHECK "gamemode_ground_check"
#define COOLDOWN_ITEM_HOOD_SOUND "item_hood_sound"
+#define COOLDOWN_LIGHT "cooldown_light"
//Define for ship alt
#define COOLDOWN_ALTITUDE_CHANGE "altitude_change"
diff --git a/code/__DEFINES/dcs/signals/atom/signals_atom.dm b/code/__DEFINES/dcs/signals/atom/signals_atom.dm
index 0cbe28d0438c..7431c5593b17 100644
--- a/code/__DEFINES/dcs/signals/atom/signals_atom.dm
+++ b/code/__DEFINES/dcs/signals/atom/signals_atom.dm
@@ -26,5 +26,22 @@
///from /turf/ChangeTurf
#define COMSIG_ATOM_TURF_CHANGE "movable_turf_change"
+//from atom/set_light(): (l_range, l_power, l_color)
+#define COMSIG_ATOM_SET_LIGHT "atom_set_light"
+
+///Called right before the atom changes the value of light_range to a different one, from base atom/set_light_range(): (new_range)
+#define COMSIG_ATOM_SET_LIGHT_RANGE "atom_set_light_range"
+///Called right before the atom changes the value of light_power to a different one, from base atom/set_light_power(): (new_power)
+#define COMSIG_ATOM_SET_LIGHT_POWER "atom_set_light_power"
+///Called right before the atom changes the value of light_color to a different one, from base atom/set_light_color(): (new_color)
+#define COMSIG_ATOM_SET_LIGHT_COLOR "atom_set_light_color"
+///Called right before the atom changes the value of light_on to a different one, from base atom/set_light_on(): (new_value)
+#define COMSIG_ATOM_SET_LIGHT_ON "atom_set_light_on"
+///Called right before the atom changes the value of light_flags to a different one, from base atom/set_light_flags(): (new_value)
+#define COMSIG_ATOM_SET_LIGHT_FLAGS "atom_set_light_flags"
+
+///from base of atom/set_opacity(): (new_opacity)
+#define COMSIG_ATOM_SET_OPACITY "atom_set_opacity"
+
///When the transform or an atom is varedited through vv topic.
#define COMSIG_ATOM_VV_MODIFY_TRANSFORM "atom_vv_modify_transform"
diff --git a/code/__DEFINES/dcs/signals/atom/signals_item.dm b/code/__DEFINES/dcs/signals/atom/signals_item.dm
index 138e88d21746..b7bbca9f64a3 100644
--- a/code/__DEFINES/dcs/signals/atom/signals_item.dm
+++ b/code/__DEFINES/dcs/signals/atom/signals_item.dm
@@ -54,3 +54,9 @@
#define COMSIG_GUN_AUTOFIREDELAY_MODIFIED "gun_autofiredelay_modified"
#define COMSIG_GUN_BURST_SHOTS_TO_FIRE_MODIFIED "gun_burst_shots_to_fire_modified"
#define COMSIG_GUN_BURST_SHOT_DELAY_MODIFIED "gun_burst_shot_delay_modified"
+
+/// from /obj/item/weapon/gun/proc/recalculate_attachment_bonuses() : ()
+#define COMSIG_GUN_RECALCULATE_ATTACHMENT_BONUSES "gun_recalculate_attachment_bonuses"
+
+/// from /obj/item/weapon/gun/proc/load_into_chamber() : ()
+#define COMSIG_GUN_INTERRUPT_FIRE "gun_interrupt_fire"
diff --git a/code/__DEFINES/dcs/signals/signals_global.dm b/code/__DEFINES/dcs/signals/signals_global.dm
index a288ac2c8be7..e33a75aee132 100644
--- a/code/__DEFINES/dcs/signals/signals_global.dm
+++ b/code/__DEFINES/dcs/signals/signals_global.dm
@@ -59,3 +59,7 @@
/// From
#define COMSIG_GLOB_YAUTJA_ARMORY_OPENED "yautja_armory_opened"
+
+/// From /proc/biohazard_lockdown()
+#define COMSIG_GLOB_RESEARCH_LOCKDOWN "research_lockdown_closed"
+#define COMSIG_GLOB_RESEARCH_LIFT "research_lockdown_opened"
diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm
index 3cbd0d6dac44..b55a1b7ce583 100644
--- a/code/__DEFINES/layers.dm
+++ b/code/__DEFINES/layers.dm
@@ -136,8 +136,6 @@
#define ABOVE_FLY_LAYER 6
-#define ABOVE_LIGHTING_PLANE 16
-
/// blip from motion detector
#define BELOW_FULLSCREEN_LAYER 16.9
#define FULLSCREEN_LAYER 17
@@ -163,11 +161,44 @@
#define CINEMATIC_LAYER 21
-#define TYPING_LAYER 500
-
/// for areas, so they appear above everything else on map file.
#define AREAS_LAYER 999
+//---------- EMISSIVES -------------
+//Layering order of these is not particularly meaningful.
+//Important part is the seperation of the planes for control via plane_master
+
+/// This plane masks out lighting to create an "emissive" effect, ie for glowing lights in otherwise dark areas.
+#define EMISSIVE_PLANE 90
+/// The render target used by the emissive layer.
+#define EMISSIVE_RENDER_TARGET "*EMISSIVE_PLANE"
+/// The layer you should use if you _really_ don't want an emissive overlay to be blocked.
+#define EMISSIVE_LAYER_UNBLOCKABLE 9999
+
+#define LIGHTING_BACKPLANE_LAYER 14.5
+
+#define LIGHTING_RENDER_TARGET "LIGHT_PLANE"
+
+#define SHADOW_RENDER_TARGET "SHADOW_RENDER_TARGET"
+
+/// Plane for balloon text (text that fades up)
+#define BALLOON_CHAT_PLANE 110
+/// Bubble for typing indicators
+#define TYPING_LAYER 500
+
+#define O_LIGHTING_VISUAL_PLANE 120
+#define O_LIGHTING_VISUAL_LAYER 16
+#define O_LIGHTING_VISUAL_RENDER_TARGET "O_LIGHT_VISUAL_PLANE"
+
+#define LIGHTING_PRIMARY_LAYER 15 //The layer for the main lights of the station
+#define LIGHTING_PRIMARY_DIMMER_LAYER 15.1 //The layer that dims the main lights of the station
+#define LIGHTING_SECONDARY_LAYER 16 //The colourful, usually small lights that go on top
+
+#define LIGHTING_SHADOW_LAYER 17 //Where the shadows happen
+
+#define ABOVE_LIGHTING_PLANE 150
+#define ABOVE_LIGHTING_LAYER 18
+
/*=============================*\
| |
| PLANE DEFINES |
@@ -189,6 +220,7 @@
#define GHOST_PLANE 80
+///--------------- FULLSCREEN RUNECHAT BUBBLES ------------
#define LIGHTING_PLANE 100
#define EXTERIOR_LIGHTING_PLANE 101
diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm
index 5a4ba7676233..097a0f5d5e71 100644
--- a/code/__DEFINES/lighting.dm
+++ b/code/__DEFINES/lighting.dm
@@ -1,5 +1,109 @@
+///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
+///A mix of the above, cheaper on moving items than dynamic, but heavier on rendering than movable
+#define HYBRID_LIGHT 3
+///Pointy light
+#define DIRECTIONAL_LIGHT 4
+
+#define LIGHT_ATTACHED (1<<0)
+
+#define MINIMUM_USEFUL_LIGHT_RANGE 1.4
+
+#define LIGHTING_ICON 'icons/effects/lighting_object.dmi' // icon used for lighting shading effects
+#define LIGHTING_ICON_BIG 'icons/effects/lighting_object_big.dmi' //! icon used for lighting shading effects
+
+#define ALPHA_TO_INTENSITY(alpha) (-(((clamp(alpha, 0, 22) - 22) / 6) ** 4) + 255)
+
+
+#define LIGHT_RANGE_FIRE 3 //How many tiles standard fires glow.
+
#define LIGHTING_PLANE_ALPHA_VISIBLE 255
///The dim natural vision of Yautja
#define LIGHTING_PLANE_ALPHA_YAUTJA 235
+#define LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE 192
#define LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE 127
#define LIGHTING_PLANE_ALPHA_INVISIBLE 0
+
+
+#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)
+/// A set of appearance flags applied to all emissive and emissive blocker overlays.
+#define EMISSIVE_APPEARANCE_FLAGS (KEEP_APART|KEEP_TOGETHER|RESET_COLOR|RESET_TRANSFORM)
+/// 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)
+
+
+//Bay lighting engine shit, not in /code/modules/lighting because BYOND is being shit about it //thats how defines work, hello?
+#define LIGHTING_INTERVAL 5 // frequency, in 1/10ths of a second, of the lighting process
+
+#define MOVABLE_MAX_RANGE 7
+
+#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
+#define LIGHTING_ROUND_VALUE (1 / 64) //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.
+
+/// 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.
+#define LIGHTING_BASE_MATRIX \
+ list \
+ ( \
+ 1, 1, 1, 0, \
+ 1, 1, 1, 0, \
+ 1, 1, 1, 0, \
+ 1, 1, 1, 0, \
+ 0, 0, 0, 1 \
+ ) \
+
+#define LIGHTING_NO_UPDATE 0
+#define LIGHTING_VIS_UPDATE 1
+#define LIGHTING_CHECK_UPDATE 2
+#define LIGHTING_FORCE_UPDATE 3
diff --git a/code/__DEFINES/mob_hud.dm b/code/__DEFINES/mob_hud.dm
index 2704e52d2f85..02f992694832 100644
--- a/code/__DEFINES/mob_hud.dm
+++ b/code/__DEFINES/mob_hud.dm
@@ -65,3 +65,6 @@
#define TRACKER_HIVE "Hive Core"
#define TRACKER_LEADER "Leader"
#define TRACKER_TUNNEL "Tunnel"
+
+//These are used to manage the same HUD having multiple sources
+#define HUD_SOURCE_ADMIN "admin"
diff --git a/code/__DEFINES/objects.dm b/code/__DEFINES/objects.dm
index 0a34ac9d6fe9..a6b95c879ae4 100644
--- a/code/__DEFINES/objects.dm
+++ b/code/__DEFINES/objects.dm
@@ -168,3 +168,8 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
// For reinforced table status
#define RTABLE_WEAKENED 1
#define RTABLE_NORMAL 2
+
+//Lights define
+#define CHECKS_PASSED 1
+#define STILL_ON_COOLDOWN 2
+#define NO_LIGHT_STATE_CHANGE 3
diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm
index 22c3827022ff..6187a67825a4 100644
--- a/code/__DEFINES/tgs.dm
+++ b/code/__DEFINES/tgs.dm
@@ -1,6 +1,6 @@
// tgstation-server DMAPI
-#define TGS_DMAPI_VERSION "6.5.2"
+#define TGS_DMAPI_VERSION "6.5.3"
// All functions and datums outside this document are subject to change with any version and should not be relied on.
@@ -154,7 +154,7 @@
#define TGS_TOPIC var/tgs_topic_return = TgsTopic(args[1]); if(tgs_topic_return) return tgs_topic_return
/**
- * Call this as late as possible in [world/proc/Reboot].
+ * Call this as late as possible in [world/proc/Reboot] (BEFORE ..()).
*/
/world/proc/TgsReboot()
return
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 1aaf3714182e..bc939fc2450b 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -203,6 +203,7 @@
// GUN TRAITS
#define TRAIT_GUN_SILENCED "t_gun_silenced"
+#define TRAIT_GUN_LIGHT_DEACTIVATED "t_gun_light_deactivated"
// Miscellaneous item traits.
// Do NOT bloat this category, if needed make a new category (like shoe traits, xeno item traits...)
diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm
index 6c913b016083..fe15e6d84c79 100644
--- a/code/__HELPERS/_lists.dm
+++ b/code/__HELPERS/_lists.dm
@@ -38,6 +38,32 @@
};\
} while(FALSE)
+// binary search sorted insert
+// IN: Object to be inserted
+// LIST: List to insert object into
+#define BINARY_INSERT_NUM(IN, LIST) \
+ var/__BIN_CTTL = length(LIST);\
+ if(!__BIN_CTTL) {\
+ LIST += IN;\
+ } else {\
+ var/__BIN_LEFT = 1;\
+ var/__BIN_RIGHT = __BIN_CTTL;\
+ var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
+ var/__BIN_ITEM;\
+ while(__BIN_LEFT < __BIN_RIGHT) {\
+ __BIN_ITEM = LIST[__BIN_MID];\
+ if(__BIN_ITEM <= IN) {\
+ __BIN_LEFT = __BIN_MID + 1;\
+ } else {\
+ __BIN_RIGHT = __BIN_MID;\
+ };\
+ __BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
+ };\
+ __BIN_ITEM = LIST[__BIN_MID];\
+ __BIN_MID = __BIN_ITEM > IN ? __BIN_MID : __BIN_MID + 1;\
+ LIST.Insert(__BIN_MID, IN);\
+ }
+
//Like typesof() or subtypesof(), but returns a typecache instead of a list
/proc/typecacheof(path, ignore_root_path, only_root_path = FALSE)
if(ispath(path))
diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm
index 4c8e1fe31354..39d91b2ada26 100644
--- a/code/__HELPERS/icons.dm
+++ b/code/__HELPERS/icons.dm
@@ -325,28 +325,25 @@ world
-/// Create a single [/icon] from a given [/atom] or [/image].
-///
-/// Very low-performance. Should usually only be used for HTML, where BYOND's
-/// appearance system (overlays/underlays, etc.) is not available.
-///
-/// Only the first argument is required.
+// Creates a single icon from a given /atom or /image. Only the first argument is required.
/proc/getFlatIcon(image/A, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE)
//Define... defines.
var/static/icon/flat_template = icon('icons/effects/effects.dmi', "nothing")
#define BLANK icon(flat_template)
- #define GENERATE_FLAT_IMAGE_ICON(ICON_VAR, IMG_SOURCE, icon_to_use, icon_state_to_use, dir_to_use)\
- var/icon/SELF_ICON=icon(icon(icon_to_use, icon_state_to_use, dir_to_use), "", SOUTH, no_anim ? 1 : null);\
- if(##IMG_SOURCE.alpha < 255)\
- SELF_ICON.Blend(rgb(255, 255, 255, ##IMG_SOURCE.alpha), ICON_MULTIPLY);\
- if(##IMG_SOURCE.color) {\
- if(islist(##IMG_SOURCE.color))\
- SELF_ICON.MapColors(arglist(##IMG_SOURCE.color));\
- else\
- SELF_ICON.Blend(##IMG_SOURCE.color, ICON_MULTIPLY);\
- }\
- ##ICON_VAR = SELF_ICON;
+ #define SET_SELF(SETVAR) do { \
+ var/icon/SELF_ICON = icon(icon(curicon, curstate, base_icon_dir), "", SOUTH, no_anim ? 1 : null); \
+ if(A.alpha < 255) { \
+ SELF_ICON.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY);\
+ } \
+ if(A.color) { \
+ if(islist(A.color)){ \
+ SELF_ICON.MapColors(arglist(A.color))} \
+ else{ \
+ SELF_ICON.Blend(A.color, ICON_MULTIPLY)} \
+ } \
+ ##SETVAR=SELF_ICON;\
+ } while (0)
#define INDEX_X_LOW 1
#define INDEX_X_HIGH 2
#define INDEX_Y_LOW 3
@@ -361,10 +358,6 @@ world
#define addY1 add_size[INDEX_Y_LOW]
#define addY2 add_size[INDEX_Y_HIGH]
- #define PROCESS_SET_UNDERLAYS 0
- #define PROCESS_SET_VIS_CONTENTS 1
- #define PROCESS_SET_OVERLAYS 2
-
if(!A || A.alpha <= 0)
return BLANK
@@ -418,45 +411,44 @@ world
var/curblend = A.blend_mode || defblend
- var/atom/movable/AM = A
- if(length(A.overlays) || length(A.underlays) || (istype(AM) && AM.vis_contents))
+ if(length(A.overlays) || length(A.underlays))
var/icon/flat = BLANK
// Layers will be a sorted list of icons/overlays, based on the order in which they are displayed
var/list/layers = list()
var/image/copy
// Add the atom's icon itself, without pixel_x/y offsets.
if(!noIcon)
- copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=base_icon_dir)
+ copy = image(icon = curicon, icon_state = curstate, layer = A.layer, dir = base_icon_dir)
copy.color = A.color
copy.alpha = A.alpha
copy.blend_mode = curblend
layers[copy] = A.layer
- // Loop through the underlays, then vis_contents, then overlays, sorting them into the layers list
- for(var/process_set in PROCESS_SET_UNDERLAYS to PROCESS_SET_OVERLAYS)
- var/list/process
+ // Loop through the underlays, then overlays, sorting them into the layers list
+ for(var/process_set in 0 to 2)
+ var/list/process = process_set ? A.overlays : A.underlays
switch(process_set)
- if(PROCESS_SET_UNDERLAYS)
+ if(0)
process = A.underlays
- if(PROCESS_SET_VIS_CONTENTS)
- if(!istype(AM))
- continue
+ if(1)
process = A.vis_contents
- else // PROCESS_SET_OVERLAYS
+ if(2)
process = A.overlays
- for(var/i in 1 to process.len)
+ for(var/i in 1 to length(process))
var/image/current = process[i]
if(!current)
continue
- if(process_set == PROCESS_SET_VIS_CONTENTS && !istype(current))
+ if(current.plane != FLOAT_PLANE && current.plane != A.plane)
+ continue
+ if(process_set == 1 && !istype(current))
current = image(icon = current.icon, icon_state = current.icon_state, layer = current.layer, dir = current.dir)
var/current_layer = current.layer
if(current_layer < 0)
if(current_layer <= -1000)
return flat
- current_layer = A.layer + ((process_set ? 1000 : 0)+current_layer) / 1000
+ current_layer = process_set + A.layer + current_layer / 1000
- for(var/p in 1 to layers.len)
+ for(var/p in 1 to length(layers))
var/image/cmp = layers[p]
if(current_layer < layers[cmp])
layers.Insert(p, current)
@@ -478,10 +470,8 @@ world
if(I == copy) // 'I' is an /image based on the object being flattened.
curblend = BLEND_OVERLAY
add = icon(I.icon, I.icon_state, base_icon_dir)
- else // 'I' is an /image
- var/image_has_icon = I.icon
- if(image_has_icon)
- GENERATE_FLAT_IMAGE_ICON(add, I, I.icon, I.icon_state, base_icon_dir)
+ else // 'I' is an appearance object.
+ add = getFlatIcon(image(I), curdir, curicon, curstate, curblend, FALSE, no_anim)
if(!add)
continue
// Find the new dimensions of the flat icon to fit the added overlay
@@ -495,10 +485,10 @@ world
if(flat_size ~! add_size)
// Resize the flattened icon so the new icon fits
flat.Crop(
- addX1 - flatX1 + 1,
- addY1 - flatY1 + 1,
- addX2 - flatX1 + 1,
- addY2 - flatY1 + 1
+ addX1 - flatX1 + 1,
+ addY1 - flatY1 + 1,
+ addX2 - flatX1 + 1,
+ addY2 - flatY1 + 1
)
flat_size = add_size.Copy()
@@ -523,7 +513,7 @@ world
. = icon(flat, "", SOUTH)
else //There's no overlays.
if(!noIcon)
- GENERATE_FLAT_IMAGE_ICON(., A, curicon, curstate, base_icon_dir)
+ SET_SELF(.)
//Clear defines
#undef flatX1
@@ -540,8 +530,8 @@ world
#undef INDEX_Y_LOW
#undef INDEX_Y_HIGH
- #undef GENERATE_FLAT_IMAGE_ICON
#undef BLANK
+ #undef SET_SELF
/proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N
var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A.
diff --git a/code/__HELPERS/lighting.dm b/code/__HELPERS/lighting.dm
new file mode 100644
index 000000000000..08c360849b58
--- /dev/null
+++ b/code/__HELPERS/lighting.dm
@@ -0,0 +1,11 @@
+/// 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, EMISSIVE_PLANE, alpha, appearance_flags | EMISSIVE_APPEARANCE_FLAGS)
+ appearance.color = GLOB.emissive_color
+ return appearance
+
+/// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EM_BLOCK_COLOR].
+/proc/emissive_blocker(icon, icon_state = "", layer = FLOAT_LAYER, alpha = 255, appearance_flags = NONE)
+ var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, EMISSIVE_PLANE, alpha, appearance_flags | EMISSIVE_APPEARANCE_FLAGS)
+ appearance.color = GLOB.em_block_color
+ return appearance
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 2e48c9f80cd3..575071b76833 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -894,7 +894,7 @@
if(ismob(source))
var/mob/M = source
has_nightvision = M.see_in_dark >= 12
- if(!has_nightvision && target_turf.lighting_lumcount == 0)
+ if(!has_nightvision && target_turf.get_lumcount() == 0)
return FALSE
while(current != target_turf)
@@ -1227,12 +1227,11 @@ var/global/image/action_purple_power_up
if(A.vars.Find(lowertext(varname))) return 1
else return 0
-//Returns: all the non-lighting areas in the world, sorted.
+//Returns: all the areas in the world, sorted.
/proc/return_sorted_areas()
var/list/area/AL = list()
for(var/area/A in GLOB.sorted_areas)
- if(!A.lighting_subarea)
- AL += A
+ AL += A
return AL
//Takes: Area type as text string or as typepath OR an instance of the area.
@@ -1252,13 +1251,8 @@ var/global/image/action_purple_power_up
var/area/A = GLOB.areas_by_type[areatype]
// Fix it up with /area/var/related due to lighting shenanigans
- var/list/area/LA
- if(!length(A.related))
- LA = list(A)
- else LA = A.related
- for(var/area/Ai in LA)
- for(var/turf/T in Ai)
- turfs += T
+ for(var/turf/T in A)
+ turfs += T
return turfs
@@ -1382,7 +1376,7 @@ var/global/image/action_purple_power_up
// if(AR.lighting_use_dynamic) //TODO: rewrite this code so it's not messed by lighting ~Carn
// X.opacity = !X.opacity
-// X.SetOpacity(!X.opacity)
+// X.set_opacity(!X.opacity)
toupdate += X
@@ -1766,6 +1760,85 @@ var/list/WALLITEMS = list(
if(location == src)
return TRUE
+GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
+
+/// Version of view() which ignores darkness, because BYOND doesn't have it (I actually suggested it but it was tagged redundant, BUT HEARERS IS A T- /rant).
+/proc/dview(range = world.view, center, invis_flags = 0)
+ if(!center)
+ return
+
+ GLOB.dview_mob.loc = center
+
+ GLOB.dview_mob.see_invisible = invis_flags
+
+ . = view(range, GLOB.dview_mob)
+ GLOB.dview_mob.loc = null
+
+/mob/dview
+ name = "INTERNAL DVIEW MOB"
+ invisibility = 101
+ density = FALSE
+ see_in_dark = 1e6
+ var/ready_to_die = FALSE
+
+/mob/dview/Initialize() //Properly prevents this mob from gaining huds or joining any global lists
+ SHOULD_CALL_PARENT(FALSE)
+ if(flags_atom & INITIALIZED)
+ stack_trace("Warning: [src]([type]) initialized multiple times!")
+ flags_atom |= INITIALIZED
+ return INITIALIZE_HINT_NORMAL
+
+/mob/dview/Destroy(force = FALSE)
+ if(!ready_to_die)
+ stack_trace("ALRIGHT WHICH FUCKER TRIED TO DELETE *MY* DVIEW?")
+
+ if (!force)
+ return QDEL_HINT_LETMELIVE
+
+ log_world("EVACUATE THE SHITCODE IS TRYING TO STEAL MUH JOBS")
+ GLOB.dview_mob = new
+ return ..()
+
+
+#define FOR_DVIEW(type, range, center, invis_flags) \
+ GLOB.dview_mob.loc = center; \
+ GLOB.dview_mob.see_invisible = invis_flags; \
+ for(type in view(range, GLOB.dview_mob))
+
+#define FOR_DVIEW_END GLOB.dview_mob.loc = null
+
+/proc/get_turf_pixel(atom/AM)
+ if(!istype(AM))
+ return
+
+ //Find AM's matrix so we can use it's X/Y pixel shifts
+ var/matrix/M = matrix(AM.transform)
+
+ var/pixel_x_offset = AM.pixel_x + M.get_x_shift()
+ var/pixel_y_offset = AM.pixel_y + M.get_y_shift()
+
+ //Irregular objects
+ var/icon/AMicon = icon(AM.icon, AM.icon_state)
+ var/AMiconheight = AMicon.Height()
+ var/AMiconwidth = AMicon.Width()
+ if(AMiconheight != world.icon_size || AMiconwidth != world.icon_size)
+ pixel_x_offset += ((AMiconwidth/world.icon_size)-1)*(world.icon_size*0.5)
+ pixel_y_offset += ((AMiconheight/world.icon_size)-1)*(world.icon_size*0.5)
+
+ //DY and DX
+ var/rough_x = round(round(pixel_x_offset,world.icon_size)/world.icon_size)
+ var/rough_y = round(round(pixel_y_offset,world.icon_size)/world.icon_size)
+
+ //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
+
+ if(final_x || final_y)
+ return locate(final_x, final_y, T.z)
+
//used to check if a mob can examine an object
/atom/proc/can_examine(mob/user)
if(!user.client)
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index 4936609d892e..d71125c318f6 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -128,6 +128,7 @@ DEFINE_BITFIELD(flags_magazine, list(
"AMMUNITION_HANDFUL_BOX" = AMMUNITION_HANDFUL_BOX,
"AMMUNITION_HIDE_AMMO" = AMMUNITION_HIDE_AMMO,
"AMMUNITION_CANNOT_REMOVE_BULLETS" = AMMUNITION_CANNOT_REMOVE_BULLETS,
+ "AMMUNITION_SLAP_TRANSFER" = AMMUNITION_SLAP_TRANSFER,
))
DEFINE_BITFIELD(flags_atom, list(
diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm
index 293cdbd6374e..ff271b889e6c 100644
--- a/code/_onclick/hud/fullscreen.dm
+++ b/code/_onclick/hud/fullscreen.dm
@@ -186,3 +186,34 @@
/atom/movable/screen/fullscreen/weather/high
icon_state = "impairedoverlay3"
+
+/atom/movable/screen/fullscreen/lighting_backdrop
+ icon = 'icons/mob/hud/screen1.dmi'
+ icon_state = "flash"
+ transform = matrix(200, 0, 0, 0, 200, 0)
+ plane = LIGHTING_PLANE
+ blend_mode = BLEND_OVERLAY
+ show_when_dead = TRUE
+
+/atom/movable/screen/fullscreen/lighting_backdrop/update_for_view(client_view)
+ return
+
+//Provides darkness to the back of the lighting plane
+/atom/movable/screen/fullscreen/lighting_backdrop/lit_secondary
+ invisibility = INVISIBILITY_LIGHTING
+ layer = BACKGROUND_LAYER + LIGHTING_PRIMARY_DIMMER_LAYER
+ color = "#000"
+ alpha = 60
+
+/atom/movable/screen/fullscreen/lighting_backdrop/backplane
+ invisibility = INVISIBILITY_LIGHTING
+ layer = LIGHTING_BACKPLANE_LAYER
+ color = "#000"
+ blend_mode = BLEND_ADD
+
+/atom/movable/screen/fullscreen/see_through_darkness
+ icon_state = "nightvision"
+ plane = LIGHTING_PLANE
+ layer = LIGHTING_PRIMARY_LAYER
+ blend_mode = BLEND_ADD
+ show_when_dead = TRUE
diff --git a/code/_onclick/hud/rendering/plane_master.dm b/code/_onclick/hud/rendering/plane_master.dm
index d29228f4c16e..91c0e24fae1f 100644
--- a/code/_onclick/hud/rendering/plane_master.dm
+++ b/code/_onclick/hud/rendering/plane_master.dm
@@ -76,6 +76,17 @@
appearance_flags = PLANE_MASTER | NO_CLIENT_COLOR | PIXEL_SCALE
//byond internal end
+/*!
+ * This system works by exploiting BYONDs color matrix filter to use layers to handle emissive blockers.
+ *
+ * Emissive overlays are pasted with an atom color that converts them to be entirely some specific color.
+ * Emissive blockers are pasted with an atom color that converts them to be entirely some different color.
+ * Emissive overlays and emissive blockers are put onto the same plane.
+ * The layers for the emissive overlays and emissive blockers cause them to mask eachother similar to normal BYOND objects.
+ * A color matrix filter is applied to the emissive plane to mask out anything that isn't whatever the emissive color is.
+ * This is then used to alpha mask the lighting plane.
+ */
+
///Contains all lighting objects
/atom/movable/screen/plane_master/lighting
name = "lighting plane master"
@@ -83,10 +94,41 @@
blend_mode_override = BLEND_MULTIPLY
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+/atom/movable/screen/plane_master/lighting/backdrop(mob/mymob)
+ . = ..()
+ mymob.overlay_fullscreen("lighting_backdrop", /atom/movable/screen/fullscreen/lighting_backdrop/backplane)
+ mymob.overlay_fullscreen("lighting_backdrop_lit_secondary", /atom/movable/screen/fullscreen/lighting_backdrop/lit_secondary)
+
+/atom/movable/screen/plane_master/lighting/Initialize()
+ . = ..()
+ add_filter("emissives", 1, alpha_mask_filter(render_source = EMISSIVE_RENDER_TARGET, flags = MASK_INVERSE))
+ add_filter("object_lighting", 2, alpha_mask_filter(render_source = O_LIGHTING_VISUAL_RENDER_TARGET, flags = MASK_INVERSE))
+
/atom/movable/screen/plane_master/lighting/exterior
name = "exterior lighting plane master"
plane = EXTERIOR_LIGHTING_PLANE
+/**
+ * Handles emissive overlays and emissive blockers.
+ */
+/atom/movable/screen/plane_master/emissive
+ name = "emissive plane master"
+ plane = EMISSIVE_PLANE
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ render_target = EMISSIVE_RENDER_TARGET
+ render_relay_plane = null
+
+/atom/movable/screen/plane_master/emissive/Initialize()
+ . = ..()
+ add_filter("em_block_masking", 1, color_matrix_filter(GLOB.em_mask_matrix))
+
+/atom/movable/screen/plane_master/above_lighting
+ name = "above lighting plane master"
+ plane = ABOVE_LIGHTING_PLANE
+ appearance_flags = PLANE_MASTER //should use client color
+ blend_mode = BLEND_OVERLAY
+ render_relay_plane = RENDER_PLANE_GAME
+
/atom/movable/screen/plane_master/runechat
name = "runechat plane master"
plane = RUNECHAT_PLANE
@@ -94,6 +136,14 @@
blend_mode = BLEND_OVERLAY
render_relay_plane = RENDER_PLANE_NON_GAME
+/atom/movable/screen/plane_master/o_light_visual
+ name = "overlight light visual plane master"
+ plane = O_LIGHTING_VISUAL_PLANE
+ render_target = O_LIGHTING_VISUAL_RENDER_TARGET
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ blend_mode = BLEND_MULTIPLY
+ blend_mode_override = BLEND_MULTIPLY
+
/atom/movable/screen/plane_master/runechat/backdrop(mob/mymob)
. = ..()
remove_filter("AO")
diff --git a/code/controllers/_DynamicAreaLighting_TG.dm b/code/controllers/_DynamicAreaLighting_TG.dm
deleted file mode 100644
index 9b6088b9bc1e..000000000000
--- a/code/controllers/_DynamicAreaLighting_TG.dm
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- Modified DynamicAreaLighting for TGstation - Coded by Carnwennan
-
- This is TG's 'new' lighting system. It's basically a heavily modified combination of Forum_Account's and
- ShadowDarke's respective lighting libraries. Credits, where due, to them.
-
- Like sd_DAL (what we used to use), it changes the shading overlays of areas by splitting each type of area into sub-areas
- by using the var/tag variable and moving turfs into the contents list of the correct sub-area. This method is
- much less costly than using overlays or objects.
-
- Unlike sd_DAL however it uses a queueing system. Everytime we call a change to opacity or luminosity
- (through SetOpacity() or SetLuminosity()) we are simply updating variables and scheduling certain lights/turfs for an
- update. Actual updates are handled periodically by the lighting_controller. This carries additional overheads, however it
- means that each thing is changed only once per lighting_controller.processing_interval ticks. Allowing for greater control
- over how much priority we'd like lighting updates to have. It also makes it possible for us to simply delay updates by
- setting lighting_controller.processing = 0 at say, the start of a large explosion, waiting for it to finish, and then
- turning it back on with lighting_controller.processing = 1.
-
- Unlike our old system there are hardcoded maximum luminositys (different for certain atoms).
- This is to cap the cost of creating lighting effects.
- (without this, an atom with luminosity of 20 would have to update 41^2 turfs!) :s
-
- Also, in order for the queueing system to work, each light remembers the effect it casts on each turf. This is going to
- have larger memory requirements than our previous system but it's easily worth the hassle for the greater control we
- gain. It also reduces cost of removing lighting effects by a lot!
-
- Known Issues/TODO:
- Shuttles still do not have support for dynamic lighting (I hope to fix this at some point)
- No directional lighting support. (prototype looked ugly)
-*/
-
-#define LIGHTING_CIRCULAR 1 //comment this out to use old square lighting effects.
-#define LIGHTING_LAYER 10 //Drawing layer for lighting overlays
-#define LIGHTING_ICON 'icons/effects/ss13_dark_alpha6.dmi' //Icon used for lighting shading effects
-#define LIGHTING_STATES 6
-
-// Update these lists if the luminosity cap
-// of 8 is removed
-GLOBAL_LIST_INIT(comp1table, list(
- 0,
- 0.934,
- 1.868,
- 2.802,
- 3.736,
- 4.67,
- 5.604,
- 6.538,
- 7.472,
-))
-GLOBAL_LIST_INIT(comp2table, list(
- 0,
- 0.427,
- 0.854,
- 1.281,
- 1.708,
- 2.135,
- 2.562,
- 2.989,
- 3.416,
-))
-/datum/light_source
- var/atom/owner
- var/changed = 1
- var/list/effect = list()
- var/__x = 0 //x coordinate at last update
- var/__y = 0 //y coordinate at last update
- var/__z = 0 //z coordinate at last update
-
-#define turf_update_lumcount(T, amount)\
- T.lighting_lumcount += amount;\
- if(!T.lighting_changed){\
- SSlighting.changed_turfs += T;\
- T.lighting_changed = TRUE;\
- }
-
-#define ls_remove_effect(ls)\
- for(var/t in ls.effect){\
- var/turf/T = t;\
- turf_update_lumcount(T, -ls.effect[T]);\
- }\
- ls.effect.Cut();
-
-/datum/light_source/New(atom/A)
- if(!istype(A))
- CRASH("The first argument to the light object's constructor must be the atom that is the light source. Expected atom, received '[A]' instead.")
- ..()
- owner = A
- __x = owner.x
- __y = owner.y
- __z = owner.z
- // the lighting object maintains a list of all light sources
- SSlighting.lights.Add(src)
-
-//Check a light to see if its effect needs reprocessing. If it does, remove any old effect and create a new one
-/datum/light_source/proc/check()
- if(!owner)
- ls_remove_effect(src)
- return TRUE //causes it to be removed from our list of lights. The garbage collector will then destroy it.
-
- if(owner.luminosity > 8)
- owner.luminosity = 8
-
- changed = FALSE
-
- ls_remove_effect(src)
- if(owner.loc && owner.luminosity > 0)
- for(var/turf/T in view(owner.luminosity, owner))
- var/dist
- var/dx = abs(T.x - __x)
- var/dy = abs(T.y - __y)
- // Use dx+1 and dy+1 because lists use 1-based indexing
- if(dx >= dy)
- dist = (GLOB.comp1table[dx+1]) + (GLOB.comp2table[dy+1])
- else
- dist = (GLOB.comp2table[dx+1]) + (GLOB.comp1table[dy+1])
- var/delta_lumen = owner.luminosity - dist
- if(delta_lumen > 0)
- effect[T] = delta_lumen
- turf_update_lumcount(T, delta_lumen)
- return FALSE
- else
- owner.light = null
- return TRUE
-
-/datum/light_source/proc/changed()
- if(owner)
- __x = owner.x
- __y = owner.y
-
- if(!changed)
- changed = 1
- SSlighting.lights.Add(src)
-
-
-/datum/light_source/proc/remove_effect()
- // before we apply the effect we remove the light's current effect.
- for(var/turf/T in effect) // negate the effect of this light source
- turf_update_lumcount(T, -effect[T])
- effect.Cut() // clear the effect list
-
-/atom
- var/datum/light_source/light
- var/trueLuminosity = 0 // Typically 'luminosity' squared. The builtin luminosity must remain linear.
- // We may read it, but NEVER set it directly.
-
-//Movable atoms with opacity when they are constructed will trigger nearby lights to update
-//Movable atoms with luminosity when they are constructed will create a light_source automatically
-/atom/movable/Initialize(mapload, ...)
- . = ..()
- if(opacity)
- if(isturf(loc))
- var/turf/T = loc
- if(T.lighting_lumcount > 1)
- UpdateAffectingLights()
- if(luminosity)
- if(light) WARNING("[type] - Don't set lights up manually during New(), We do it automatically.")
- trueLuminosity = luminosity * luminosity
- light = new(src)
-
-//Objects with opacity will trigger nearby lights to update at next lighting process.
-/atom/movable/Destroy()
- if(opacity)
- if(isturf(loc))
- var/turf/T = loc
- if(T.lighting_lumcount > 1)
- UpdateAffectingLights()
- . = ..()
-
-/atom/vv_edit_var(var_name, var_value)
- switch(var_name)
- if(NAMEOF(src, luminosity))
- SetLuminosity(var_value)
- return ..()
-
-//Sets our luminosity.
-//If we have no light it will create one.
-//If we are setting luminosity to 0 the light will be cleaned up by the controller and garbage collected once all its
-//queues are complete.
-//if we have a light already it is merely updated, rather than making a new one.
-/atom/proc/SetLuminosity(new_luminosity, trueLum = FALSE, atom/source)
- if(new_luminosity < 0)
- new_luminosity = 0
- if(!trueLum)
- new_luminosity *= new_luminosity
- if(light)
- if(trueLuminosity != new_luminosity) //non-luminous lights are removed from the lights list in add_effect()
- light.changed()
- else
- if(new_luminosity)
- light = new(src)
- trueLuminosity = new_luminosity
- if (trueLuminosity < 1)
- luminosity = 0
- else if (trueLuminosity <= 100)
- luminosity = sqrtTable[trueLuminosity]
- else
- luminosity = sqrt(trueLuminosity)
-
-//This slightly modifies human luminosity. Source of light do NOT stack.
-//When you drop a light source it should keep a running total of your actual luminosity and set it accordingly.
-/mob/SetLuminosity(new_luminosity, trueLum, atom/source)
- LAZYREMOVE(luminosity_sources, source)
- if(source)
- UnregisterSignal(source, COMSIG_PARENT_QDELETING)
- var/highest_luminosity = 0
- for(var/luminosity_source as anything in luminosity_sources)
- var/lumonisity_rating = luminosity_sources[luminosity_source]
- if(highest_luminosity < lumonisity_rating)
- highest_luminosity = lumonisity_rating
- if(source && new_luminosity > 0)
- LAZYSET(luminosity_sources, source, new_luminosity)
- RegisterSignal(source, COMSIG_PARENT_QDELETING, PROC_REF(remove_luminosity_source))
- if(new_luminosity < highest_luminosity)
- new_luminosity = highest_luminosity
- return ..()
-
-/mob/proc/remove_luminosity_source(atom/source)
- SetLuminosity(0, FALSE, source)
-
-/area/SetLuminosity(new_luminosity) //we don't want dynamic lighting for areas
- luminosity = !!new_luminosity
- trueLuminosity = luminosity
-
-
-//change our opacity (defaults to toggle), and then update all lights that affect us.
-/atom/proc/SetOpacity(new_opacity)
- if(new_opacity == null)
- new_opacity = !opacity //default = toggle opacity
- else if(opacity == new_opacity)
- return FALSE //opacity hasn't changed! don't bother doing anything
- opacity = new_opacity //update opacity, the below procs now call light updates.
- return TRUE
-
-/turf/SetOpacity(new_opacity)
- . = ..()
- //only bother if opacity changed
- if(!.)
- return
- if(lighting_lumcount) //only bother with an update if our turf is currently affected by a light
- UpdateAffectingLights()
-
-/atom/movable/SetOpacity(new_opacity)
- . = ..()
- // only bother if opacity changed
- if(!.)
- return
- // only bother with an update if we're on a turf
- if(isturf(loc))
- var/turf/T = loc
- // only bother with an update if our turf is currently affected by a light
- if(T.lighting_lumcount)
- UpdateAffectingLights()
-
-
-/turf
- var/lighting_lumcount = 0
- var/lighting_changed = 0
- var/cached_lumcount = 0
-
-/turf/open/space
- lighting_lumcount = 4 //starlight
-
-/turf/proc/update_lumcount(amount, removing = 0)
- lighting_lumcount += amount
-
- if(!lighting_changed)
- SSlighting.changed_turfs += src
- lighting_changed = 1
-
-/turf/proc/lighting_tag(const/level)
- var/area/A = loc
- return A.tagbase + "sd_L[level]"
-
-/turf/proc/build_lighting_area(const/tag, const/level)
- var/area/Area = loc
- var/area/A = new Area.type() // create area if it wasn't found
- // replicate vars
- for(var/V in Area.vars)
- switch(V)
- if ("contents","lighting_overlay", "overlays")
- continue
- else
- if(issaved(Area.vars[V])) A.vars[V] = Area.vars[V]
-
- A.tag = tag
- A.lighting_subarea = 1
- A.lighting_space = 0 // in case it was copied from a space subarea
-
- A.SetLightLevel(level)
- Area.related += A
-
- if(SSweather.is_weather_event && SSweather.map_holder.should_affect_area(A))
- A.overlays += SSweather.curr_master_turf_overlay
-
- return A
-
-/turf/proc/shift_to_subarea()
- lighting_changed = 0
- var/area/Area = loc
-
- if(!istype(Area) || !Area.lighting_use_dynamic) return
-
- var/level = min(max(round(lighting_lumcount,1),0),LIGHTING_STATES)
- var/new_tag = lighting_tag(level)
-
- if(Area.tag!=new_tag) //skip if already in this area
- var/area/A = locate(new_tag) // find an appropriate area
-
- if (!A)
- A = build_lighting_area(new_tag, level)
-
- A.contents += src // move the turf into the area
-
-// Dedicated lighting sublevel for space turfs
-// helps us depower things in space, remove space fire alarms,
-// and evens out space lighting
-/turf/open/space/lighting_tag(level)
- var/area/A = loc
- return A.tagbase + "sd_L_space"
-/turf/open/space/build_lighting_area(tag, level)
- var/area/A = ..(tag,4)
- A.lighting_space = 1
- A.SetLightLevel(4)
- A.icon_state = null
- return A
-
-
-/area
- var/lighting_use_dynamic = 1 //Turn this flag off to prevent sd_DynamicAreaLighting from affecting this area
- var/image/lighting_overlay //tracks the darkness image of the area for easy removal
- var/lighting_subarea = 0 //tracks whether we're a lighting sub-area
- var/lighting_space = 0 // true for space-only lighting subareas
- var/tagbase
- var/exterior_light = 2
-
-/area/proc/SetLightLevel(light)
- if(!src) return
- if(light <= 0)
- light = 0
- luminosity = 1
- if(light > LIGHTING_STATES)
- light = LIGHTING_STATES
-
- if(lighting_overlay)
- overlays -= lighting_overlay
- lighting_overlay.icon_state = "[light]"
- else
- lighting_overlay = image(LIGHTING_ICON,,num2text(light),LIGHTING_LAYER)
- lighting_overlay.plane = ceiling <= CEILING_GLASS ? EXTERIOR_LIGHTING_PLANE : LIGHTING_PLANE
- if (light < 6)
- overlays.Add(lighting_overlay)
-
-/area/proc/SetDynamicLighting()
- src.lighting_use_dynamic = 1
- for(var/turf/T in src.contents)
- turf_update_lumcount(T, 0)
-
-/area/proc/InitializeLighting() //TODO: could probably improve this bit ~Carn
- tagbase = "[type]"
- if(!tag) tag = tagbase
- if(!lighting_use_dynamic)
- if(!lighting_subarea) // see if this is a lighting subarea already
- //show the dark overlay so areas, not yet in a lighting subarea, won't be bright as day and look silly.
- SetLightLevel(4)
-
-//#undef LIGHTING_LAYER
-#undef LIGHTING_CIRCULAR
-//#undef LIGHTING_ICON
-
-#define LIGHTING_MAX_LUMINOSITY_STATIC 8 //Maximum luminosity to reduce lag.
-#define LIGHTING_MAX_LUMINOSITY_MOBILE 6 //Moving objects have a lower max luminosity since these update more often. (lag reduction)
-#define LIGHTING_MAX_LUMINOSITY_TURF 1 //turfs have a severely shortened range to protect from inevitable floor-lighttile spam.
-
-//set the changed status of all lights which could have possibly lit this atom.
-//We don't need to worry about lights which lit us but moved away, since they will have change status set already
-//This proc can cause lots of lights to be updated. :(
-/atom/proc/UpdateAffectingLights()
-// for(var/atom/A in oview(LIGHTING_MAX_LUMINOSITY_STATIC-1,src))
-// if(A.light)
-// A.light.changed() //force it to update at next process()
-
-/atom/movable/UpdateAffectingLights()
- if(isturf(loc))
- loc.UpdateAffectingLights()
-
-/turf/UpdateAffectingLights()
- for(var/atom/A in oview(LIGHTING_MAX_LUMINOSITY_STATIC-1,src))
- if(A.light)
- A.light.changed()
-
-//caps luminosity effects max-range based on what type the light's owner is.
-/atom/proc/get_light_range()
- return min(luminosity, LIGHTING_MAX_LUMINOSITY_STATIC)
-
-/atom/movable/get_light_range()
- return min(luminosity, LIGHTING_MAX_LUMINOSITY_MOBILE)
-
-/obj/structure/machinery/light/get_light_range()
- return min(luminosity, LIGHTING_MAX_LUMINOSITY_STATIC)
-
-/turf/get_light_range()
- return min(luminosity, LIGHTING_MAX_LUMINOSITY_TURF)
-
-#undef LIGHTING_MAX_LUMINOSITY_STATIC
-#undef LIGHTING_MAX_LUMINOSITY_MOBILE
-#undef LIGHTING_MAX_LUMINOSITY_TURF
diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm
index 26ee4c9a648e..3c3d14468bc2 100644
--- a/code/controllers/subsystem/lighting.dm
+++ b/code/controllers/subsystem/lighting.dm
@@ -1,68 +1,124 @@
SUBSYSTEM_DEF(lighting)
- name = "Lighting"
+ name = "Lighting"
+ wait = 2
init_order = SS_INIT_LIGHTING
- priority = SS_PRIORITY_LIGHTING
- wait = 0.4 SECONDS
- runlevels = RUNLEVELS_DEFAULT|RUNLEVEL_LOBBY
- var/list/datum/light_source/lights_current = list()
- var/list/datum/light_source/lights = list()
+ //debug var for tracking updates before init is complete
+ var/duplicate_shadow_updates_in_init = 0
+ ///Total times shadows were updated, debug
+ var/total_shadow_calculations = 0
- var/list/turf/changed_turfs_current = list()
- var/list/turf/changed_turfs = list()
+ ///Whether the SS has begun setting up yet
+ var/started = FALSE
+ var/static/list/static_sources_queue = list() //! List of static 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.
-/datum/controller/subsystem/lighting/stat_entry(msg)
- msg = "L:[lights.len]; T:[changed_turfs.len]"
- return ..()
+ var/static/list/mask_queue = list() //! List of hybrid lighting sources queued for update.
/datum/controller/subsystem/lighting/Initialize(timeofday)
- for(var/thing in lights)
- var/datum/light_source/L = thing
- if(L)
- L.check()
- lights.Cut()
+ started = TRUE
+ if(!initialized)
+ //Handle static lightnig
+ create_all_lighting_objects()
+ fire(FALSE, TRUE)
+ return SS_INIT_SUCCESS
- var/z_start = 1
- var/z_finish = world.maxz
+/datum/controller/subsystem/lighting/stat_entry()
+ . = ..("ShCalcs:[total_shadow_calculations]|SourcQ:[static_sources_queue.len]|CcornQ:[corners_queue.len]|ObjQ:[objects_queue.len]|HybrQ:[mask_queue.len]")
- var/list/init_turfs = block(locate(1,1,z_start),locate(world.maxx,world.maxy,z_finish))
+/datum/controller/subsystem/lighting/fire(resumed, init_tick_checks)
+ MC_SPLIT_TICK_INIT(3)
+ if(!init_tick_checks)
+ MC_SPLIT_TICK
+ var/updators_num = 0
+ while(updators_num < length(static_sources_queue))
+ updators_num += 1
- for(var/turf/thing in init_turfs)
- if(istype(thing))
- thing.shift_to_subarea()
+ var/datum/static_light_source/L = static_sources_queue[updators_num]
+ L.update_corners()
- return SS_INIT_SUCCESS
+ if(!QDELETED(L))
+ L.needs_update = LIGHTING_NO_UPDATE
+ else
+ updators_num -= 1
+ if(init_tick_checks)
+ if(!TICK_CHECK)
+ continue
+ static_sources_queue.Cut(1, updators_num + 1)
+ updators_num = 0
+ stoplag()
+ else if (MC_TICK_CHECK)
+ break
+ if(updators_num)
+ static_sources_queue.Cut(1, updators_num + 1)
+ updators_num = 0
+ if(!init_tick_checks)
+ MC_SPLIT_TICK
-/datum/controller/subsystem/lighting/fire(resumed = FALSE)
- if(!resumed)
- lights_current = lights
- lights = list()
- changed_turfs_current = changed_turfs
- changed_turfs = list()
+ while(updators_num < length(corners_queue))
+ updators_num += 1
+ var/datum/static_lighting_corner/C = corners_queue[updators_num]
+ C.needs_update = FALSE //update_objects() can call qdel if the corner is storing no data
+ C.update_objects()
- while(lights_current.len)
- var/datum/light_source/L = lights_current[lights_current.len]
- lights_current.len--
- if(!L)
- continue
- if(!L.owner || L.changed)
- L.check()
- if(MC_TICK_CHECK)
- return
-
- while(changed_turfs_current.len)
- var/turf/T = changed_turfs_current[changed_turfs_current.len]
- changed_turfs_current.len--
- if(!T)
+ if(init_tick_checks)
+ if(!TICK_CHECK)
+ continue
+ corners_queue.Cut(1, updators_num + 1)
+ updators_num = 0
+ stoplag()
+ else if (MC_TICK_CHECK)
+ break
+ if(updators_num)
+ corners_queue.Cut(1, updators_num + 1)
+ updators_num = 0
+ if(!init_tick_checks)
+ MC_SPLIT_TICK
+
+ while(updators_num < length(objects_queue))
+ updators_num += 1
+
+ var/datum/static_lighting_object/O = objects_queue[updators_num]
+ if (QDELETED(O))
continue
- if(T.lighting_changed)
- if(T.lighting_lumcount != T.cached_lumcount)
- T.cached_lumcount = T.lighting_lumcount
- T.shift_to_subarea()
- T.lighting_changed = FALSE
- if (MC_TICK_CHECK)
- return
+ O.update()
+ O.needs_update = FALSE
+
+ if(init_tick_checks)
+ if(!TICK_CHECK)
+ continue
+ objects_queue.Cut(1, updators_num + 1)
+ updators_num = 0
+ else if (MC_TICK_CHECK)
+ break
+ if(updators_num)
+ objects_queue.Cut(1, updators_num + 1)
+ updators_num = 0
+ if(!init_tick_checks)
+ MC_SPLIT_TICK
+
+ while(updators_num > length(mask_queue))
+ updators_num += 1
+
+ var/atom/movable/lighting_mask/mask_to_update = mask_queue[updators_num]
+ mask_to_update.calculate_lighting_shadows()
+
+ if(init_tick_checks)
+ if(!TICK_CHECK)
+ continue
+ mask_queue.Cut(1, updators_num + 1)
+ updators_num = 0
+ stoplag()
+ else if (MC_TICK_CHECK)
+ break
+ if(updators_num)
+ mask_queue.Cut(1, updators_num + 1)
+
+/datum/controller/subsystem/lighting/Recover()
+ initialized = SSlighting.initialized
+ return ..()
diff --git a/code/controllers/subsystem/weather.dm b/code/controllers/subsystem/weather.dm
index 7610c007df90..325c45fe2300 100644
--- a/code/controllers/subsystem/weather.dm
+++ b/code/controllers/subsystem/weather.dm
@@ -47,7 +47,7 @@ SUBSYSTEM_DEF(weather)
/datum/controller/subsystem/weather/proc/setup_weather_areas()
weather_areas = list()
for(var/area/A in all_areas)
- if(A == A.master && A.weather_enabled && map_holder.should_affect_area(A))
+ if(A.weather_enabled && map_holder.should_affect_area(A))
weather_areas += A
curr_master_turf_overlay = new /obj/effect/weather_vfx_holder
@@ -146,8 +146,7 @@ SUBSYSTEM_DEF(weather)
curr_master_turf_overlay.icon_state = weather_event_instance.turf_overlay_icon_state
curr_master_turf_overlay.alpha = weather_event_instance.turf_overlay_alpha
for(var/area/area as anything in weather_areas)
- for(var/area/subarea as anything in area.related)
- subarea.overlays += curr_master_turf_overlay
+ area.overlays += curr_master_turf_overlay
update_mobs_weather()
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_WEATHER_CHANGE)
@@ -169,8 +168,7 @@ SUBSYSTEM_DEF(weather)
message_admins(SPAN_BLUE("Weather Event of unknown type [weather_event_type] ending after [DisplayTimeText(world.time - current_event_start_time)]."))
for(var/area/area as anything in weather_areas)
- for(var/area/subarea as anything in area.related)
- subarea.overlays -= curr_master_turf_overlay
+ area.overlays -= curr_master_turf_overlay
if (map_holder.no_weather_turf_icon_state)
curr_master_turf_overlay.icon_state = map_holder.no_weather_turf_icon_state
diff --git a/code/datums/agents/tools/tranq_gun.dm b/code/datums/agents/tools/tranq_gun.dm
index e95f853cef82..91f6f8c294b7 100644
--- a/code/datums/agents/tools/tranq_gun.dm
+++ b/code/datums/agents/tools/tranq_gun.dm
@@ -1,7 +1,7 @@
/obj/item/weapon/gun/pistol/tranquilizer
name = "Tranquilizer gun"
desc = "Contains horse tranquilizer darts. Useful at knocking people out."
- icon = 'icons/obj/items/weapons/guns/guns_by_faction/upp.dmi'
+ icon = 'icons/obj/items/weapons/guns/guns_by_faction/event.dmi'
icon_state = "pk9r"
item_state = "pk9r"
current_mag = /obj/item/ammo_magazine/pistol/tranq
@@ -28,7 +28,7 @@
name = "\improper Tranquilizer magazine (Horse Tranquilizer)"
default_ammo = /datum/ammo/bullet/pistol/tranq
caliber = ".22"
- icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
+ icon = 'icons/obj/items/weapons/guns/ammo_by_faction/event.dmi'
icon_state = "pk-9_tranq"
max_rounds = 5
gun_type = /obj/item/weapon/gun/pistol/tranquilizer
diff --git a/code/datums/components/autofire/autofire.dm b/code/datums/components/autofire/autofire.dm
index 31ca255f1b88..2b9401e8d346 100644
--- a/code/datums/components/autofire/autofire.dm
+++ b/code/datums/components/autofire/autofire.dm
@@ -15,6 +15,8 @@
var/have_to_reset_at_burst_end = FALSE
///If we are in a burst
var/bursting = FALSE
+ /// The multiplier for how much slower the parent should fire in automatic mode. 1 is normal, 1.2 is 20% slower, 2 is 100% slower, etc.
+ var/automatic_delay_mult = 1
///Callback to set bursting mode on the parent
var/datum/callback/callback_bursting
///Callback to ask the parent to reset its firing vars
@@ -26,7 +28,7 @@
///Callback to set parent's fa_firing
var/datum/callback/callback_set_firing
-/datum/component/automatedfire/autofire/Initialize(auto_fire_shot_delay = 0.3 SECONDS, burstfire_shot_delay, burst_shots_to_fire = 3, fire_mode = GUN_FIREMODE_SEMIAUTO, datum/callback/callback_bursting, datum/callback/callback_reset_fire, datum/callback/callback_fire, datum/callback/callback_display_ammo, datum/callback/callback_set_firing)
+/datum/component/automatedfire/autofire/Initialize(auto_fire_shot_delay = 0.3 SECONDS, burstfire_shot_delay, burst_shots_to_fire = 3, fire_mode = GUN_FIREMODE_SEMIAUTO, automatic_delay_mult = 1, datum/callback/callback_bursting, datum/callback/callback_reset_fire, datum/callback/callback_fire, datum/callback/callback_display_ammo, datum/callback/callback_set_firing)
. = ..()
RegisterSignal(parent, COMSIG_GUN_FIRE_MODE_TOGGLE, PROC_REF(modify_fire_mode))
@@ -35,11 +37,13 @@
RegisterSignal(parent, COMSIG_GUN_BURST_SHOT_DELAY_MODIFIED, PROC_REF(modify_burstfire_shot_delay))
RegisterSignal(parent, COMSIG_GUN_FIRE, PROC_REF(initiate_shot))
RegisterSignal(parent, COMSIG_GUN_STOP_FIRE, PROC_REF(stop_firing))
+ RegisterSignal(parent, COMSIG_GUN_INTERRUPT_FIRE, PROC_REF(hard_reset))
src.auto_fire_shot_delay = auto_fire_shot_delay
src.burstfire_shot_delay = burstfire_shot_delay
src.burst_shots_to_fire = burst_shots_to_fire
src.fire_mode = fire_mode
+ src.automatic_delay_mult = automatic_delay_mult
src.callback_bursting = callback_bursting
src.callback_reset_fire = callback_reset_fire
src.callback_fire = callback_fire
@@ -96,6 +100,7 @@
///Hard reset the autofire, happens when the shooter fall/is thrown, at the end of a burst or when it runs out of ammunition
/datum/component/automatedfire/autofire/proc/hard_reset()
+ SIGNAL_HANDLER
callback_reset_fire.Invoke() //resets the gun
shots_fired = 0
have_to_reset_at_burst_end = FALSE
@@ -131,7 +136,7 @@
next_fire = world.time + burstfire_shot_delay
if(GUN_FIREMODE_AUTOMATIC)
callback_set_firing.Invoke(TRUE)
- next_fire = world.time + auto_fire_shot_delay
+ next_fire = world.time + (auto_fire_shot_delay * automatic_delay_mult)
if(GUN_FIREMODE_SEMIAUTO)
return
schedule_shot()
diff --git a/code/datums/components/overlay_lighting.dm b/code/datums/components/overlay_lighting.dm
new file mode 100644
index 000000000000..00a5e86b5d60
--- /dev/null
+++ b/code/datums/components/overlay_lighting.dm
@@ -0,0 +1,513 @@
+///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 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',
+ "384" = 'icons/effects/light_overlays/light_384.dmi',
+ "416" = 'icons/effects/light_overlays/light_416.dmi',
+ )
+
+ ///Overlay effect to cut into the darkness and provide light.
+ var/image/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 = FALSE
+ ///A cone overlay for directional light, it's alpha and color are dependant on the light
+ var/image/cone
+ ///Current tracked direction for the directional cast behaviour
+ var/current_direction
+ ///Tracks current directional x offset so we dont update unecessarily
+ var/directional_offset_x
+ ///Tracks current directional y offset so we dont update unecessarily
+ var/directional_offset_y
+ ///Cast range for the directional cast (how far away the atom is moved)
+ var/cast_range = 2
+
+
+/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 != DIRECTIONAL_LIGHT)
+ stack_trace("[type] added to [parent], with [movable_parent.light_system] value for the light_system var. Use [MOVABLE_LIGHT]/[DIRECTIONAL_LIGHT] instead.")
+ return COMPONENT_INCOMPATIBLE
+
+ . = ..()
+
+ visible_mask = image('icons/effects/light_overlays/light_32.dmi', icon_state = "light")
+ visible_mask.plane = O_LIGHTING_VISUAL_PLANE
+ visible_mask.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
+ visible_mask.alpha = 0
+ if(is_directional)
+ directional = TRUE
+ cone = image('icons/effects/light_overlays/light_cone.dmi', icon_state = "light")
+ cone.plane = O_LIGHTING_VISUAL_PLANE
+ cone.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
+ cone.alpha = 110
+ 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_REF(on_parent_dir_change))
+ RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_parent_moved))
+ RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(check_holder))
+ RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_RANGE, PROC_REF(set_range))
+ RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_POWER, PROC_REF(set_power))
+ RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_COLOR, PROC_REF(set_color))
+ RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_ON, PROC_REF(on_toggle))
+ RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_FLAGS, PROC_REF(on_light_flags_change))
+ 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_SET_LIGHT_RANGE,
+ COMSIG_ATOM_SET_LIGHT_POWER,
+ COMSIG_ATOM_SET_LIGHT_COLOR,
+ COMSIG_ATOM_SET_LIGHT_ON,
+ COMSIG_ATOM_SET_LIGHT_FLAGS,
+ ))
+ 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()
+ visible_mask = null
+ cone = null
+ parent_attached_to = 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/turf/lit_turf as anything in affected_turfs)
+ 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
+ LAZYINITLIST(affected_turfs)
+ if(range <= 2)
+ //Range here is 1 because actual range of lighting mask is 1 tile even if it says that range is 2
+ for(var/turf/lit_turf in RANGE_TURFS(1, current_holder.loc))
+ lit_turf.dynamic_lumcount += lum_power
+ affected_turfs += lit_turf
+ else
+ for(var/turf/lit_turf in view(lumcount_range, get_turf(current_holder)))
+ lit_turf.dynamic_lumcount += lum_power
+ 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()
+ LAZYSET(current_holder.affected_movable_lights, src, lumcount_range + 1)
+ current_holder.underlays += visible_mask
+ current_holder.update_dynamic_luminosity()
+ if(directional)
+ current_holder.underlays += 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()
+ LAZYREMOVE(current_holder.affected_movable_lights, src)
+ current_holder.underlays -= visible_mask
+ current_holder.update_dynamic_luminosity()
+ if(directional)
+ current_holder.underlays -= cone
+
+///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))
+ if(old_parent_attached_to == current_holder)
+ RegisterSignal(old_parent_attached_to, COMSIG_PARENT_QDELETING, PROC_REF(on_holder_qdel))
+ RegisterSignal(old_parent_attached_to, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved))
+ if(parent_attached_to)
+ if(parent_attached_to == current_holder)
+ UnregisterSignal(current_holder, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED))
+ RegisterSignal(parent_attached_to, COMSIG_PARENT_QDELETING, PROC_REF(on_parent_attached_to_qdel))
+ RegisterSignal(parent_attached_to, COMSIG_MOVABLE_MOVED, PROC_REF(on_parent_attached_to_moved))
+ 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))
+ 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_REF(on_holder_qdel))
+ if(overlay_lighting_flags & LIGHTING_ON)
+ RegisterSignal(new_holder, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved))
+ if(directional)
+ RegisterSignal(new_holder, COMSIG_ATOM_DIR_CHANGE, PROC_REF(on_holder_dir_change))
+ if(directional && current_direction != new_holder.dir)
+ current_direction = new_holder.dir
+ if(overlay_lighting_flags & LIGHTING_ON)
+ add_dynamic_lumi()
+ make_luminosity_update()
+
+
+///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)
+ 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)
+ if(!(overlay_lighting_flags & LIGHTING_ON))
+ 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()
+
+///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()
+
+
+///Changes the range which the light reaches. 0 means no light, 7 is the maximum value.
+/datum/component/overlay_lighting/proc/set_range(atom/source, new_range)
+ SIGNAL_HANDLER
+ if(range == new_range)
+ return
+ if(range == 0)
+ turn_off()
+ range = clamp(CEILING(new_range, 0.5), 1, 7)
+ var/pixel_bounds = ((range - 1) * 64) + 32
+ lumcount_range = CEILING(range, 1)
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays -= visible_mask
+ 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
+ directional_offset_x = 0
+ directional_offset_y = 0
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays += visible_mask
+ 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, new_power)
+ SIGNAL_HANDLER
+ set_lum_power(new_power >= 0 ? 0.5 : -0.5)
+ set_alpha = min(230, (abs(new_power) * 120) + 30)
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays -= visible_mask
+ visible_mask.alpha = set_alpha
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays += visible_mask
+
+ if(!directional)
+ return
+
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays -= cone
+ cone.alpha = min(200, (abs(new_power) * 90)+20)
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays += cone
+
+
+///Changes the light's color, pretty straightforward.
+/datum/component/overlay_lighting/proc/set_color(atom/source, new_color)
+ SIGNAL_HANDLER
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays -= visible_mask
+ visible_mask.color = new_color
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays += visible_mask
+
+ if(!directional)
+ return
+
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays -= cone
+ cone.color = new_color
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays += cone
+
+
+///Toggles the light on and off.
+/datum/component/overlay_lighting/proc/on_toggle(atom/source, new_value)
+ SIGNAL_HANDLER
+ 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, new_flags)
+ SIGNAL_HANDLER
+ var/atom/movable/movable_parent = parent
+
+ 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
+ overlay_lighting_flags |= LIGHTING_ON
+ if(current_holder)
+ add_dynamic_lumi(current_holder)
+ if(directional)
+ cast_directional_light()
+ if(current_holder && current_holder != parent && current_holder != parent_attached_to)
+ RegisterSignal(current_holder, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved))
+ 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
+ if(current_holder && current_holder != parent && current_holder != parent_attached_to)
+ UnregisterSignal(current_holder, COMSIG_MOVABLE_MOVED)
+ 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))
+ final_distance = i
+ break
+ scanning = next_turf
+
+ current_holder.underlays -= visible_mask
+
+ var/translate_x = -((range - 1) * 32)
+ var/translate_y = translate_x
+ switch(current_direction)
+ if(NORTH)
+ translate_y += 32 * final_distance
+ if(SOUTH)
+ translate_y += -32 * final_distance
+ if(EAST)
+ translate_x += 32 * final_distance
+ if(WEST)
+ translate_x += -32 * final_distance
+ if((directional_offset_x != translate_x) || (directional_offset_y != translate_y))
+ directional_offset_x = translate_x
+ directional_offset_y = translate_y
+ var/matrix/transform = matrix()
+ transform.Translate(translate_x, translate_y)
+ visible_mask.transform = transform
+ if(overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays += visible_mask
+
+///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
+
+ if(current_holder?.dir != newdir)
+ return
+
+ 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
+ if(overlay_lighting_flags & LIGHTING_ON)
+ make_luminosity_update()
+
+#undef LIGHTING_ON
+#undef LIGHTING_ATTACHED
+#undef GET_PARENT
+#undef SHORT_CAST
diff --git a/code/datums/effects/acid.dm b/code/datums/effects/acid.dm
index 721fe27a0d0d..d89f7261a223 100644
--- a/code/datums/effects/acid.dm
+++ b/code/datums/effects/acid.dm
@@ -104,7 +104,7 @@
if(!acids_area)
return
- if(SSweather.is_weather_event && locate(acids_area.master) in SSweather.weather_areas)
+ if(SSweather.is_weather_event && locate(acids_area) in SSweather.weather_areas)
//smothering_strength is 1-10, we use this to take a proportional amount off the stats
duration = duration - (duration * (SSweather.weather_event_instance.fire_smothering_strength * 0.1))
damage_in_total_human = damage_in_total_human - (damage_in_total_human * (SSweather.weather_event_instance.fire_smothering_strength * 0.1))
diff --git a/code/datums/elements/light_blocking.dm b/code/datums/elements/light_blocking.dm
new file mode 100644
index 000000000000..9fef194f1cd4
--- /dev/null
+++ b/code/datums/elements/light_blocking.dm
@@ -0,0 +1,43 @@
+/**
+ * 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_REF(on_target_move))
+ var/atom/movable/movable_target = target
+ if(!isturf(movable_target.loc))
+ return
+ for(var/turf/turf_loc as anything in movable_target.locs)
+ turf_loc.add_opacity_source(target)
+
+
+/datum/element/light_blocking/Detach(datum/target)
+ . = ..()
+ UnregisterSignal(target, list(COMSIG_MOVABLE_MOVED))
+ var/atom/movable/movable_target = target
+ if(!isturf(movable_target.loc))
+ return
+ for(var/turf/turf_loc as anything in movable_target.locs)
+ turf_loc.remove_opacity_source(target)
+
+
+///Updates old and new turf loc opacities.
+///Updates old and new turf loc opacities.
+/datum/element/light_blocking/proc/on_target_move(atom/movable/source, atom/old_loc, dir, forced, list/old_locs)
+ SIGNAL_HANDLER
+ if(isturf(old_loc))
+ if(old_locs)
+ for(var/turf/old_turf as anything in old_locs)
+ old_turf.remove_opacity_source(source)
+ else
+ var/turf/old_turf = old_loc
+ old_turf.remove_opacity_source(source)
+ if(isturf(source.loc))
+ for(var/turf/new_turf as anything in source.locs)
+ new_turf.add_opacity_source(source)
diff --git a/code/datums/emergency_calls/emergency_call.dm b/code/datums/emergency_calls/emergency_call.dm
index 3d43917b2bc7..6d41c2d64d0b 100644
--- a/code/datums/emergency_calls/emergency_call.dm
+++ b/code/datums/emergency_calls/emergency_call.dm
@@ -8,12 +8,19 @@
/datum/game_mode
var/list/datum/emergency_call/all_calls = list() //initialized at round start and stores the datums.
var/datum/emergency_call/picked_calls[] = list() //Which distress calls are currently active
+ var/ert_dispatched = FALSE
/datum/game_mode/proc/ares_online()
var/name = "ARES Online"
var/input = "ARES. Online. Good morning, marines."
shipwide_ai_announcement(input, name, 'sound/AI/ares_online.ogg')
+/datum/game_mode/proc/request_ert(user, ares = FALSE)
+ if(!user)
+ return FALSE
+ message_admins("[key_name(user)] has requested a Distress Beacon! [ares ? SPAN_ORANGE("(via ARES)") : ""] ([SSticker.mode.ert_dispatched ? SPAN_RED("A random ERT was dispatched previously.") : SPAN_GREEN("No previous random ERT dispatched.")]) [CC_MARK(user)] (SEND) (DENY) [ADMIN_JMP_USER(user)] [CC_REPLY(user)]")
+ return TRUE
+
//The distress call parent. Cannot be called itself due to "name" being a filtered target.
/datum/emergency_call
var/name = "name"
@@ -106,6 +113,7 @@
give_action(M, /datum/action/join_ert, src)
/datum/game_mode/proc/activate_distress()
+ ert_dispatched = TRUE
var/datum/emergency_call/random_call = get_random_call()
if(!istype(random_call, /datum/emergency_call)) //Something went horribly wrong
return
diff --git a/code/datums/emergency_calls/upp.dm b/code/datums/emergency_calls/upp.dm
index 94d4bf2a0ab6..04bcfecf9128 100644
--- a/code/datums/emergency_calls/upp.dm
+++ b/code/datums/emergency_calls/upp.dm
@@ -77,14 +77,14 @@
var/equipment_path = /datum/equipment_preset/upp/specialist
if(heavy_pick)
if(HAS_FLAG(H.client.prefs.toggles_ert, PLAY_HEAVY) && HAS_FLAG(H.client.prefs.toggles_ert, PLAY_SMARTGUNNER))
- equipment_path = pick(/datum/equipment_preset/upp/specialist, /datum/equipment_preset/upp/minigunner)
+ equipment_path = pick(/datum/equipment_preset/upp/specialist, /datum/equipment_preset/upp/machinegunner)
else if(HAS_FLAG(H.client.prefs.toggles_ert, PLAY_SMARTGUNNER) && !HAS_FLAG(H.client.prefs.toggles_ert, PLAY_HEAVY))
- equipment_path = /datum/equipment_preset/upp/minigunner
+ equipment_path = /datum/equipment_preset/upp/machinegunner
arm_equipment(H, equipment_path, TRUE, TRUE)
else if(smartgunners < max_smartgunners && HAS_FLAG(H.client.prefs.toggles_ert, PLAY_SMARTGUNNER) && check_timelock(H.client, JOB_SQUAD_SMARTGUN, time_required_for_job))
smartgunners++
to_chat(H, SPAN_ROLE_HEADER("You are a sergeant of the Union of Progressive People, a powerful socialist state that rivals the United Americas!"))
- arm_equipment(H, /datum/equipment_preset/upp/minigunner, TRUE, TRUE)
+ arm_equipment(H, /datum/equipment_preset/upp/machinegunner, TRUE, TRUE)
else
to_chat(H, SPAN_ROLE_HEADER("You are a soldier of the Union of Progressive People, a powerful socialist state that rivals the United Americas!"))
arm_equipment(H, /datum/equipment_preset/upp/soldier, TRUE, TRUE)
diff --git a/code/datums/factions/clf.dm b/code/datums/factions/clf.dm
index 38e0d576f805..ce53b505b352 100644
--- a/code/datums/factions/clf.dm
+++ b/code/datums/factions/clf.dm
@@ -31,12 +31,12 @@
list("PRIMARY FIREARMS", 0, null, null, null),
list("ABR-40 Hunting Rifle", 30, /obj/item/weapon/gun/rifle/l42a/abr40, null, VENDOR_ITEM_REGULAR),
list("Basira-Armstrong Bolt-Action", 15, /obj/item/weapon/gun/boltaction, null, VENDOR_ITEM_REGULAR),
- list("CZ-81 Machine Pistol", 20, /obj/item/ammo_magazine/pistol/skorpion, null, VENDOR_ITEM_REGULAR),
list("Double Barrel Shotgun", 30, /obj/item/weapon/gun/shotgun/double, null, VENDOR_ITEM_REGULAR),
list("HG 37-12 Pump Shotgun", 30, /obj/item/weapon/gun/shotgun/double/sawn, null, VENDOR_ITEM_REGULAR),
list("M16 Rifle", 30, /obj/item/weapon/gun/rifle/m16, null, VENDOR_ITEM_REGULAR),
list("MAR-30 Battle Carbine", 30, /obj/item/weapon/gun/rifle/mar40/carbine, null, VENDOR_ITEM_REGULAR),
list("MAR-40 Battle Rifle", 30, /obj/item/weapon/gun/rifle/mar40, null, VENDOR_ITEM_REGULAR),
+ list("Type-64 Submachinegun", 20, /obj/item/weapon/gun/smg/bizon, null, VENDOR_ITEM_REGULAR),
list("MAC-15 Submachinegun", 20, /obj/item/weapon/gun/smg/mac15, null, VENDOR_ITEM_REGULAR),
list("MP27 Submachinegun", 20, /obj/item/weapon/gun/smg/mp27, null, VENDOR_ITEM_REGULAR),
list("MP5 Submachinegun", 20, /obj/item/weapon/gun/smg/mp5, null, VENDOR_ITEM_REGULAR),
@@ -48,12 +48,12 @@
list("Box Of Buckshot Shells", 10, /obj/item/ammo_magazine/shotgun/buckshot, null, VENDOR_ITEM_REGULAR),
list("Box Of Flechette Shells", 10, /obj/item/ammo_magazine/shotgun/flechette, null, VENDOR_ITEM_REGULAR),
list("Box Of Shotgun Slugs", 10, /obj/item/ammo_magazine/shotgun, null, VENDOR_ITEM_REGULAR),
- list("CZ-81 Magazine (.32ACP)", 5, /obj/item/ammo_magazine/pistol/skorpion, null, VENDOR_ITEM_REGULAR),
list("M16 AP Magazine (5.56x45mm)", 15, /obj/item/ammo_magazine/rifle/m16/ap, null, VENDOR_ITEM_REGULAR),
list("M16 Magazine (5.56x45mm)", 5, /obj/item/ammo_magazine/rifle/m16, null, VENDOR_ITEM_REGULAR),
list("MAC-15 Magazine (9mm)", 5, /obj/item/ammo_magazine/smg/mac15, null, VENDOR_ITEM_REGULAR),
list("MAR Magazine (7.62x39mm)", 5, /obj/item/ammo_magazine/rifle/mar40, null, VENDOR_ITEM_REGULAR),
list("MAR Extended Magazine (7.62x39mm)", 15, /obj/item/ammo_magazine/rifle/mar40/extended, null, VENDOR_ITEM_REGULAR),
+ list("Type-64 Helical Magazine (.7.62x19mm)", 5, /obj/item/ammo_magazine/smg/bizon, null, VENDOR_ITEM_REGULAR),
list("MP27 Magazine (4.6x30mm)", 5, /obj/item/ammo_magazine/smg/mp27, null, VENDOR_ITEM_REGULAR),
list("MP5 Magazine (9mm)", 5, /obj/item/ammo_magazine/smg/mp5, null, VENDOR_ITEM_REGULAR),
@@ -99,13 +99,13 @@
list("PRIMARY FIREARMS", -1, null, null),
list("ABR-40 Hunting Rifle", 30, /obj/item/weapon/gun/rifle/l42a/abr40, null, VENDOR_ITEM_REGULAR),
list("Basira-Armstrong Bolt-Action", 15, /obj/item/weapon/gun/boltaction, null, VENDOR_ITEM_REGULAR),
- list("CZ-81 Machine Pistol", 20, /obj/item/ammo_magazine/pistol/skorpion, VENDOR_ITEM_REGULAR),
list("Double Barrel Shotgun", 20, /obj/item/weapon/gun/shotgun/double, VENDOR_ITEM_REGULAR),
list("HG 37-12 Pump Shotgun", 20, /obj/item/weapon/gun/shotgun/double/sawn, VENDOR_ITEM_REGULAR),
list("M16 Rifle", 20, /obj/item/weapon/gun/rifle/m16, VENDOR_ITEM_REGULAR),
list("MAC-15 Submachinegun", 20, /obj/item/weapon/gun/smg/mac15, VENDOR_ITEM_REGULAR),
list("MAR-30 Battle Carbine", 20, /obj/item/weapon/gun/rifle/mar40/carbine, VENDOR_ITEM_REGULAR),
list("MAR-40 Battle Rifle", 20, /obj/item/weapon/gun/rifle/mar40, VENDOR_ITEM_REGULAR),
+ list("Type 64 Submachinegun", 20, /obj/item/weapon/gun/smg/bizon, VENDOR_ITEM_REGULAR),
list("MP27 Submachinegun", 20, /obj/item/weapon/gun/smg/mp27, VENDOR_ITEM_REGULAR),
list("MP5 Submachinegun", 20, /obj/item/weapon/gun/smg/mp5, VENDOR_ITEM_REGULAR),
list("Sawn-Off Shotgun", 20, /obj/item/weapon/gun/shotgun/pump/dual_tube/cmb, VENDOR_ITEM_REGULAR),
@@ -116,12 +116,12 @@
list("Box Of Buckshot Shells", 15, /obj/item/ammo_magazine/shotgun/buckshot, VENDOR_ITEM_REGULAR),
list("Box Of Flechette Shells", 15, /obj/item/ammo_magazine/shotgun/flechette, VENDOR_ITEM_REGULAR),
list("Box Of Shotgun Slugs", 15, /obj/item/ammo_magazine/shotgun, VENDOR_ITEM_REGULAR),
- list("CZ-81 Magazine (.32ACP)", 60, /obj/item/ammo_magazine/pistol/skorpion, VENDOR_ITEM_REGULAR),
list("M16 AP Magazine (5.56x45mm)", 10, /obj/item/ammo_magazine/rifle/m16/ap, VENDOR_ITEM_REGULAR),
list("M16 Magazine (5.56x45mm)", 60, /obj/item/ammo_magazine/rifle/m16, VENDOR_ITEM_REGULAR),
list("MAC-15 Magazine (9mm)", 60, /obj/item/ammo_magazine/smg/mac15, VENDOR_ITEM_REGULAR),
list("MAR Magazine (7.62x39mm)", 60, /obj/item/ammo_magazine/rifle/mar40, VENDOR_ITEM_REGULAR),
list("MAR Extended Magazine (7.62x39mm)", 10, /obj/item/ammo_magazine/rifle/mar40/extended, VENDOR_ITEM_REGULAR),
+ list("Type 64 Helical Magazine (7.62x19mm)", 60, /obj/item/ammo_magazine/smg/bizon, VENDOR_ITEM_REGULAR),
list("MP27 Magazine (4.6x30mm)", 60, /obj/item/ammo_magazine/smg/mp27, VENDOR_ITEM_REGULAR),
list("MP5 Magazine (9mm)", 60, /obj/item/ammo_magazine/smg/mp5, VENDOR_ITEM_REGULAR),
diff --git a/code/datums/factions/upp.dm b/code/datums/factions/upp.dm
index a5a89cfd0a80..9f28e5967831 100644
--- a/code/datums/factions/upp.dm
+++ b/code/datums/factions/upp.dm
@@ -47,24 +47,24 @@
/datum/faction/upp/get_antag_guns_snowflake_equipment()
return list(
list("PRIMARY FIREARMS", 0, null, null, null),
- list("CZ-81 Machine Pistol", 20, /obj/item/weapon/gun/pistol/skorpion/upp, null, VENDOR_ITEM_REGULAR),
+ list("Type 64 Submachinegun", 20, /obj/item/weapon/gun/smg/bizon/upp, null, VENDOR_ITEM_REGULAR),
list("Type 71 Pulse Rifle", 30, /obj/item/weapon/gun/rifle/type71, null, VENDOR_ITEM_REGULAR),
list("Type 71 Pulse Rifle Carbine", 30, /obj/item/weapon/gun/rifle/type71/carbine, null, VENDOR_ITEM_REGULAR),
list("PRIMARY AMMUNITION", 0, null, null, null),
- list("CZ-81 Magazine (.32ACP)", 5, /obj/item/ammo_magazine/pistol/skorpion, null, VENDOR_ITEM_REGULAR),
+ list("Type 64 Helical Magazine (7.62x19mm)", 5, /obj/item/ammo_magazine/smg/bizon, null, VENDOR_ITEM_REGULAR),
list("Type 71 AP Magazine (5.45x39mm)", 15, /obj/item/ammo_magazine/rifle/type71/ap, null, VENDOR_ITEM_REGULAR),
list("Type 71 Magazine (5.45x39mm)", 5, /obj/item/ammo_magazine/rifle/type71, null, VENDOR_ITEM_REGULAR),
list("SIDEARMS", 0, null, null, null),
- list("Highpower Automag", 15, /obj/item/weapon/gun/pistol/highpower, null, VENDOR_ITEM_REGULAR),
- list("Korovin PK-9 Pistol", 15, /obj/item/weapon/gun/pistol/c99/upp, null, VENDOR_ITEM_REGULAR),
- list("N-Y 7.62mm Revolver", 15, /obj/item/weapon/gun/revolver/nagant, null, VENDOR_ITEM_REGULAR),
+ list("Type 73 Pistol", 25, /obj/item/weapon/gun/pistol/t73, null, VENDOR_ITEM_REGULAR),
+ list("NP92 Pistol", 15, /obj/item/weapon/gun/pistol/np92, null, VENDOR_ITEM_REGULAR),
+ list("ZHNK-72 Revolver", 15, /obj/item/weapon/gun/revolver/upp, null, VENDOR_ITEM_REGULAR),
list("SIDEARM AMMUNITION", 0, null, null, null),
- list("Highpower Magazine (9mm)", 5, /obj/item/ammo_magazine/pistol/highpower, null, VENDOR_ITEM_REGULAR),
- list("N-Y Speed Loader (7.62x38mmR)", 5, /obj/item/ammo_magazine/revolver/upp, null, VENDOR_ITEM_REGULAR),
- list("PK-9 Magazine (.22 Hollowpoint)", 5, /obj/item/ammo_magazine/pistol/c99, null, VENDOR_ITEM_REGULAR),
+ list("Type 73 Magazine (7.62x25mm Tokarev)", 5, /obj/item/ammo_magazine/pistol/t73, null, VENDOR_ITEM_REGULAR),
+ list("ZHNK-72 Speed Loader (7.62x38mmR)", 5, /obj/item/ammo_magazine/revolver/upp, null, VENDOR_ITEM_REGULAR),
+ list("NP92 Magazine (9x18mm Makarov)", 40, /obj/item/ammo_magazine/pistol/np92, null, VENDOR_ITEM_REGULAR),
list("ATTACHMENTS", 0, null, null, null),
list("Angled Grip", 15, /obj/item/attachable/angledgrip, null, VENDOR_ITEM_REGULAR),
@@ -86,24 +86,24 @@
/datum/faction/upp/get_antag_guns_sorted_equipment()
return list(
list("PRIMARY FIREARMS", -1, null, null),
- list("CZ-81 Machine Pistol", 20, /obj/item/weapon/gun/pistol/skorpion/upp, VENDOR_ITEM_REGULAR),
+ list("Type 64 Submachinegun", 20, /obj/item/weapon/gun/smg/bizon/upp, VENDOR_ITEM_REGULAR),
list("Type 71 Pulse Rifle", 20, /obj/item/weapon/gun/rifle/type71, VENDOR_ITEM_REGULAR),
list("Type 71 Pulse Rifle Carbine", 20, /obj/item/weapon/gun/rifle/type71/carbine, VENDOR_ITEM_REGULAR),
list("PRIMARY AMMUNITION", -1, null, null),
- list("CZ-81 Magazine (.32ACP)", 60, /obj/item/ammo_magazine/pistol/skorpion, VENDOR_ITEM_REGULAR),
+ list("Type 64 Helical Magazine (7.62x19mm)", 60, /obj/item/ammo_magazine/smg/bizon, VENDOR_ITEM_REGULAR),
list("Type 71 AP Magazine (5.45x39mm)", 60, /obj/item/ammo_magazine/rifle/type71/ap, VENDOR_ITEM_REGULAR),
list("Type 71 Magazine (5.45x39mm)", 60, /obj/item/ammo_magazine/rifle/type71, VENDOR_ITEM_REGULAR),
list("SIDEARMS", -1, null, null),
- list("Highpower Automag", 20, /obj/item/weapon/gun/pistol/highpower, VENDOR_ITEM_REGULAR),
- list("Korovin PK-9 Pistol", 20, /obj/item/weapon/gun/pistol/c99/upp, VENDOR_ITEM_REGULAR),
- list("N-Y 7.62mm Revolver", 20, /obj/item/weapon/gun/revolver/nagant, VENDOR_ITEM_REGULAR),
+ list("Type 73 Pistol", 20, /obj/item/weapon/gun/pistol/t73, VENDOR_ITEM_REGULAR),
+ list("NP02 Pistol", 20, /obj/item/weapon/gun/pistol/np92, VENDOR_ITEM_REGULAR),
+ list("ZHNK-72 Revolver", 20, /obj/item/weapon/gun/revolver/upp, VENDOR_ITEM_REGULAR),
list("SIDEARM AMMUNITION", -1, null, null),
- list("Highpower Magazine (9mm)", 40, /obj/item/ammo_magazine/pistol/highpower, VENDOR_ITEM_REGULAR),
- list("N-Y Speed Loader (7.62x38mmR)", 40, /obj/item/ammo_magazine/revolver/upp, VENDOR_ITEM_REGULAR),
- list("PK-9 Magazine (.22 Hollowpoint)", 40, /obj/item/ammo_magazine/pistol/c99, VENDOR_ITEM_REGULAR),
+ list("Type 73 Magazine (7.62x25mm Tokarev)", 40, /obj/item/ammo_magazine/pistol/t73, VENDOR_ITEM_REGULAR),
+ list("ZHNK-72 Speed Loader (7.62x38mmR)", 40, /obj/item/ammo_magazine/revolver/upp, VENDOR_ITEM_REGULAR),
+ list("NP92 Magazine (9x18mm Makarov)", 40, /obj/item/ammo_magazine/pistol/np92, VENDOR_ITEM_REGULAR),
list("UTILITIES", -1, null, null),
list("M94 Marking Flare Pack", 20, /obj/item/storage/box/m94, VENDOR_ITEM_RECOMMENDED),
diff --git a/code/datums/mob_hud.dm b/code/datums/mob_hud.dm
index aa1bc9b40783..65c5a47896fa 100644
--- a/code/datums/mob_hud.dm
+++ b/code/datums/mob_hud.dm
@@ -30,10 +30,18 @@ var/list/datum/mob_hud/huds = list(
// Stop displaying a HUD to a specific person
// (took off medical glasses)
-/datum/mob_hud/proc/remove_hud_from(mob/user)
+/datum/mob_hud/proc/remove_hud_from(mob/user, source)
+ if(length(hudusers[user]) && (source in hudusers[user]))
+ hudusers[user] -= source
+
+ if(length(hudusers[user]))
+ return FALSE
+
for(var/mob/target in hudmobs)
remove_from_single_hud(user, target)
+
hudusers -= user
+ return TRUE
// Stop rendering a HUD on a target
// "unenroll" them so to speak
@@ -53,8 +61,24 @@ var/list/datum/mob_hud/huds = list(
user.client.images -= target.clone.hud_list[i]
// Allow user to view a HUD (putting on medical glasses)
-/datum/mob_hud/proc/add_hud_to(mob/user)
+/datum/mob_hud/proc/add_hud_to(mob/user, source)
hudusers |= user
+ if(hudusers[user])
+ hudusers[user] |= list(source)
+ else
+ hudusers[user] += list(source)
+
+ for(var/mob/target in hudmobs)
+ add_to_single_hud(user, target)
+
+/// Refreshes the HUD, adding user and sources if missing and then calls to add the HUD
+/datum/mob_hud/proc/refresh_hud(mob/user, list/source)
+ hudusers |= user
+ if(hudusers[user])
+ hudusers[user] |= source
+ else
+ hudusers[user] += source
+
for(var/mob/target in hudmobs)
add_to_single_hud(user, target)
@@ -229,13 +253,13 @@ var/list/datum/mob_hud/huds = list(
for(var/datum/mob_hud/hud in huds)
if(istype(hud, /datum/mob_hud/xeno))
hud.remove_from_hud(src)
- hud.remove_hud_from(src)
+ hud.remove_hud_from(src, src)
else if (istype(hud, /datum/mob_hud/xeno_infection))
- hud.remove_hud_from(src)
+ hud.remove_hud_from(src, src)
if (xeno_hostile_hud)
xeno_hostile_hud = FALSE
var/datum/mob_hud/hostile_hud = huds[MOB_HUD_XENO_HOSTILE]
- hostile_hud.remove_hud_from(src)
+ hostile_hud.remove_hud_from(src, src)
@@ -243,13 +267,7 @@ var/list/datum/mob_hud/huds = list(
var/mob/M = source_mob ? source_mob : src
for(var/datum/mob_hud/hud in huds)
if(M in hud.hudusers)
- readd_hud(hud)
-
-/mob/proc/readd_hud(datum/mob_hud/hud)
- hud.add_hud_to(src)
-
-
-
+ hud.refresh_hud(src, hud.hudusers[M])
//Medical HUDs
diff --git a/code/datums/skills.dm b/code/datums/skills.dm
index 9bc53007173d..a2edde24b8d4 100644
--- a/code/datums/skills.dm
+++ b/code/datums/skills.dm
@@ -1290,6 +1290,7 @@ UNITED PROGRESSIVE PEOPLES
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
SKILL_JTAC = SKILL_JTAC_EXPERT,
+ SKILL_EXECUTION = SKILL_EXECUTION_TRAINED,
)
/datum/skills/upp/conscript
name = "UPP Conscript"
diff --git a/code/datums/supply_packs/ammo.dm b/code/datums/supply_packs/ammo.dm
index e598a11be5e0..164511c25cc0 100644
--- a/code/datums/supply_packs/ammo.dm
+++ b/code/datums/supply_packs/ammo.dm
@@ -122,16 +122,6 @@
containername = "\improper M39 AP magazines crate"
group = "Ammo"
-/datum/supply_packs/ammo_smg_mag_box_ext
- name = "Magazine box (M39, 10x extended mags)"
- contains = list(
- /obj/item/ammo_box/magazine/m39/ext,
- )
- cost = 30
- containertype = /obj/structure/closet/crate/ammo
- containername = "\improper M39 extended magazines crate"
- group = "Ammo"
-
//------------------------For M4RA----------------
/datum/supply_packs/ammo_m4ra_mag_box
diff --git a/code/datums/supply_packs/black_market.dm b/code/datums/supply_packs/black_market.dm
index 65b15997d1b4..1737a66e85a9 100644
--- a/code/datums/supply_packs/black_market.dm
+++ b/code/datums/supply_packs/black_market.dm
@@ -184,10 +184,9 @@ Non-USCM items, from CLF, UPP, colonies, etc. Mostly combat-related.
new /obj/item/ammo_magazine/rifle/mar40/extended(src)
new /obj/item/ammo_magazine/rifle/mar40(src)
else
- new /obj/item/weapon/gun/rifle/m41aMK1/tactical(src)
- new /obj/item/ammo_magazine/rifle/m41aMK1/ap(src)
- new /obj/item/ammo_magazine/rifle/m41aMK1(src)
- new /obj/item/ammo_magazine/rifle/m41aMK1(src)
+ new /obj/item/weapon/gun/rifle/mar40/lmg(src)
+ new /obj/item/ammo_magazine/rifle/mar40/lmg(src)
+ new /obj/item/ammo_magazine/rifle/mar40/lmg(src)
/* Misc. Individual Guns */
@@ -333,15 +332,15 @@ Additionally, weapons that are way too good to put in the basically-flavor black
dollar_cost = 5
containertype = /obj/structure/largecrate/black_market
-/datum/supply_packs/contraband/seized/ppsh
- name = "PPSh-17b submachinegun crate (x5 magazines included)"
+/datum/supply_packs/contraband/seized/pps43
+ name = "Type-19 submachinegun crate (x5 magazines included)"
contains = list(
- /obj/item/weapon/gun/smg/ppsh,
- /obj/item/ammo_magazine/smg/ppsh/extended,
- /obj/item/ammo_magazine/smg/ppsh/extended,
- /obj/item/ammo_magazine/smg/ppsh,
- /obj/item/ammo_magazine/smg/ppsh,
- /obj/item/ammo_magazine/smg/ppsh,
+ /obj/item/weapon/gun/smg/pps43,
+ /obj/item/ammo_magazine/smg/pps43/extended,
+ /obj/item/ammo_magazine/smg/pps43/extended,
+ /obj/item/ammo_magazine/smg/pps43,
+ /obj/item/ammo_magazine/smg/pps43,
+ /obj/item/ammo_magazine/smg/pps43,
)
dollar_cost = 15
containertype = /obj/structure/largecrate/black_market
@@ -374,18 +373,18 @@ Additionally, weapons that are way too good to put in the basically-flavor black
dollar_cost = 45
containertype = /obj/structure/largecrate/black_market
-/datum/supply_packs/contraband/seized/c99
- name = "Korovin PK-9 pistol crate (x6 magazines included)"
+/datum/supply_packs/contraband/seized/t73
+ name = "Type 73 pistol crate (x6 magazines included)"
contains = list(
- /obj/item/weapon/gun/pistol/c99,
- /obj/item/ammo_magazine/pistol/c99,
- /obj/item/ammo_magazine/pistol/c99,
- /obj/item/ammo_magazine/pistol/c99,
- /obj/item/ammo_magazine/pistol/c99,
- /obj/item/ammo_magazine/pistol/c99,
- /obj/item/ammo_magazine/pistol/c99,
+ /obj/item/weapon/gun/pistol/t73,
+ /obj/item/ammo_magazine/pistol/t73,
+ /obj/item/ammo_magazine/pistol/t73,
+ /obj/item/ammo_magazine/pistol/t73,
+ /obj/item/ammo_magazine/pistol/t73,
+ /obj/item/ammo_magazine/pistol/t73,
+ /obj/item/ammo_magazine/pistol/t73,
)
- dollar_cost = 5
+ dollar_cost = 15
containertype = /obj/structure/largecrate/black_market
/datum/supply_packs/contraband/seized/kt42
@@ -416,14 +415,14 @@ Additionally, weapons that are way too good to put in the basically-flavor black
dollar_cost = 5
containertype = /obj/structure/largecrate/black_market
-/datum/supply_packs/contraband/seized/skorpion
- name = "CZ-81 machine pistol (x4 magazines included)"
+/datum/supply_packs/contraband/seized/bizon
+ name = "Type 64 Submachinegun (x4 magazines included)"
contains = list(
- /obj/item/weapon/gun/pistol/skorpion,
- /obj/item/ammo_magazine/pistol/skorpion,
- /obj/item/ammo_magazine/pistol/skorpion,
- /obj/item/ammo_magazine/pistol/skorpion,
- /obj/item/ammo_magazine/pistol/skorpion,
+ /obj/item/weapon/gun/smg/bizon,
+ /obj/item/ammo_magazine/smg/bizon,
+ /obj/item/ammo_magazine/smg/bizon,
+ /obj/item/ammo_magazine/smg/bizon,
+ /obj/item/ammo_magazine/smg/bizon,
)
dollar_cost = 15
containertype = /obj/structure/largecrate/black_market
@@ -457,10 +456,10 @@ Additionally, weapons that are way too good to put in the basically-flavor black
dollar_cost = 15
containertype = /obj/structure/largecrate/black_market
-/datum/supply_packs/contraband/seized/nagant
- name = "N-Y 7.62mm revolver (x6 magazines included)"
+/datum/supply_packs/contraband/seized/upprevolver
+ name = "ZHNK-72 revolver (x6 magazines included)"
contains = list(
- /obj/item/weapon/gun/revolver/nagant,
+ /obj/item/weapon/gun/revolver/upp,
/obj/item/ammo_magazine/revolver/upp,
/obj/item/ammo_magazine/revolver/upp,
/obj/item/ammo_magazine/revolver/upp,
@@ -468,7 +467,7 @@ Additionally, weapons that are way too good to put in the basically-flavor black
/obj/item/ammo_magazine/revolver/upp,
/obj/item/ammo_magazine/revolver/upp,
)
- dollar_cost = 10
+ dollar_cost = 15
containertype = /obj/structure/largecrate/black_market
/datum/supply_packs/contraband/seized/r4t
@@ -1068,11 +1067,11 @@ Things that don't fit anywhere else. If they're meant for shipside use, they pro
new picked_type(loc)
loot_message = SPAN_NOTICE("It's some strange elite gear...?")
if(11 to 15)
- //Skorpion
- new /obj/item/weapon/gun/pistol/skorpion(loc)
- new /obj/item/ammo_magazine/pistol/skorpion(loc)
- new /obj/item/ammo_magazine/pistol/skorpion(loc)
- new /obj/item/ammo_magazine/pistol/skorpion(loc)
+ //Type 64
+ new /obj/item/weapon/gun/smg/bizon(loc)
+ new /obj/item/ammo_magazine/smg/bizon(loc)
+ new /obj/item/ammo_magazine/smg/bizon(loc)
+ new /obj/item/ammo_magazine/smg/bizon(loc)
// Somehow they found a Webley.
new /obj/item/weapon/gun/revolver/m44/custom/webley(loc)
new /obj/item/ammo_magazine/revolver/webley(loc)
@@ -1080,11 +1079,11 @@ Things that don't fit anywhere else. If they're meant for shipside use, they pro
new /obj/item/ammo_magazine/revolver/webley(loc)
loot_message = SPAN_NOTICE("It's some CLF pistol armaments!")
if(16 to 20)
- // PPSH
- new /obj/item/weapon/gun/smg/ppsh/with_drum_mag(loc)
- new /obj/item/ammo_magazine/smg/ppsh/extended(loc)
- new /obj/item/ammo_magazine/smg/ppsh/extended(loc)
- new /obj/item/ammo_magazine/smg/ppsh/extended(loc)
+ // Type 19
+ new /obj/item/weapon/gun/smg/pps43/extended_mag(loc)
+ new /obj/item/ammo_magazine/smg/pps43/extended(loc)
+ new /obj/item/ammo_magazine/smg/pps43/extended(loc)
+ new /obj/item/ammo_magazine/smg/pps43/extended(loc)
// MAC-15
new /obj/item/weapon/gun/smg/mac15/extended(loc)
new /obj/item/ammo_magazine/smg/mac15/extended(loc)
diff --git a/code/game/area/DesertDam.dm b/code/game/area/DesertDam.dm
index 73635eb6385d..96e5eb1f62e5 100644
--- a/code/game/area/DesertDam.dm
+++ b/code/game/area/DesertDam.dm
@@ -682,7 +682,6 @@
/area/desert_dam/exterior
requires_power = 1
always_unpowered = 1
- lighting_use_dynamic = 1
power_light = FALSE
power_equip = FALSE
power_environ = FALSE
diff --git a/code/game/area/IceColony.dm b/code/game/area/IceColony.dm
index 2c7bbee2969c..8b8a245d7cc9 100644
--- a/code/game/area/IceColony.dm
+++ b/code/game/area/IceColony.dm
@@ -28,7 +28,6 @@
icon_state = "cliff_blocked"
requires_power = 1
always_unpowered = 1
- lighting_use_dynamic = 1
power_light = FALSE
power_equip = FALSE
power_environ = FALSE
diff --git a/code/game/area/LV522_Chances_Claim.dm b/code/game/area/LV522_Chances_Claim.dm
index 3d15d49c3df7..926d8d361c83 100644
--- a/code/game/area/LV522_Chances_Claim.dm
+++ b/code/game/area/LV522_Chances_Claim.dm
@@ -52,7 +52,6 @@
name = "Chance's Claim - Dropship Alamo Landing Zone"
icon_state = "shuttle"
icon = 'icons/turf/area_shiva.dmi'
- lighting_use_dynamic = TRUE
/area/lv522/landing_zone_1/lz1_console
name = "Chance's Claim - Dropship Alamo Console"
@@ -75,7 +74,6 @@
name = "Chance's Claim - Dropship Normandy Landing Zone"
icon_state = "shuttle2"
icon = 'icons/turf/area_shiva.dmi'
- lighting_use_dynamic = TRUE
/area/lv522/landing_zone_2/lz2_console
name = "Chance's Claim - Dropship Normandy Console"
diff --git a/code/game/area/Sulaco.dm b/code/game/area/Sulaco.dm
index 851025e1b63a..ae197537143a 100644
--- a/code/game/area/Sulaco.dm
+++ b/code/game/area/Sulaco.dm
@@ -117,7 +117,7 @@
//DISTRESS SHUTTLES
/area/shuttle/distress
- lighting_use_dynamic = FALSE
+ base_lighting_alpha = 255
unique = TRUE
/area/shuttle/distress/start
diff --git a/code/game/area/WhiskeyOutpost.dm b/code/game/area/WhiskeyOutpost.dm
index 583a5dafc299..02d94dc942da 100644
--- a/code/game/area/WhiskeyOutpost.dm
+++ b/code/game/area/WhiskeyOutpost.dm
@@ -79,7 +79,6 @@
//ambience = list('sound/ambience/jungle_amb1.ogg')
requires_power = 1
always_unpowered = 1
- lighting_use_dynamic = 1
power_light = FALSE
power_equip = FALSE
power_environ = FALSE
@@ -180,7 +179,6 @@
ceiling = CEILING_UNDERGROUND_ALLOW_CAS
requires_power = 1
always_unpowered = 1
- lighting_use_dynamic = 1
power_light = FALSE
power_equip = FALSE
power_environ = FALSE
diff --git a/code/game/area/admin_level.dm b/code/game/area/admin_level.dm
index 501047c46d08..a934b5f71570 100644
--- a/code/game/area/admin_level.dm
+++ b/code/game/area/admin_level.dm
@@ -3,14 +3,13 @@
/area/adminlevel
ceiling = CEILING_METAL
+ base_lighting_alpha = 255
/area/adminlevel/bunker01
icon_state = "thunder"
requires_power = FALSE
statistic_exempt = TRUE
flags_area = AREA_NOTUNNEL
- luminosity = TRUE
- lighting_use_dynamic = FALSE
/area/adminlevel/bunker01/mainroom
name = "\improper Bunker Main Room"
@@ -78,8 +77,7 @@
ceiling = CEILING_UNDERGROUND_ALLOW_CAS
always_unpowered = TRUE
requires_power = TRUE
- lighting_use_dynamic = TRUE
- luminosity = FALSE
+ base_lighting_alpha = 0
/area/adminlevel/bunker01/caves/outpost
name = "\improper Bunker Outpost"
@@ -87,8 +85,6 @@
ceiling = CEILING_UNDERGROUND_ALLOW_CAS
requires_power = TRUE
always_unpowered = FALSE
- lighting_use_dynamic = TRUE
- luminosity = FALSE
/area/adminlevel/bunker01/caves/xeno
name = "\improper Bunker Xeno Hive"
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 2c274665fa19..826b2dc0585f 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -28,9 +28,6 @@
var/unique = TRUE
var/has_gravity = 1
- var/area/master // master area used for power calcluations
- // (original area before splitting due to sd_DAL)
- var/list/related // the other areas of the same type as this
// var/list/lights // list of all lights on this area
var/list/all_doors = list() //Added by Strumpetplaya - Alarm Change - Contains a list of doors adjacent to this area
var/air_doors_activated = 0
@@ -89,10 +86,8 @@
if(unique)
GLOB.areas_by_type[type] = src
..()
- master = src //moved outside the spawn(1) to avoid runtimes in lighting.dm when it references loc.loc.master ~Carn
- related = list(src)
- initialize_power_and_lighting()
+ initialize_power()
/area/Initialize(mapload, ...)
icon_state = "" //Used to reset the icon overlay, I assume.
@@ -105,24 +100,26 @@
if(is_mainship_level(z))
GLOB.ship_areas += src
-/area/proc/initialize_power_and_lighting(override_power)
+ if(base_lighting_alpha)
+ return INITIALIZE_HINT_ROUNDSTART
+
+/area/LateInitialize()
+ . = ..()
+
+ update_base_lighting()
+
+/area/proc/initialize_power(override_power)
if(requires_power)
- luminosity = 0
if(override_power) //Reset everything if you want to override.
power_light = TRUE
power_equip = TRUE
power_environ = TRUE
- if(lighting_use_dynamic)
- SetDynamicLighting()
else
power_light = FALSE //rastaf0
power_equip = FALSE //rastaf0
power_environ = FALSE //rastaf0
- luminosity = 1
- lighting_use_dynamic = 0
power_change() // all machines set to current power level, also updates lighting icon
- InitializeLighting()
/// Returns the correct ambience sound track for a client in this area
/area/proc/get_sound_ambience(client/target)
@@ -135,13 +132,12 @@
poweralm = state
if(istype(source)) //Only report power alarms on the z-level where the source is located.
var/list/cameras = list()
- for (var/area/RA in related)
- for (var/obj/structure/machinery/camera/C in RA)
- cameras += C
- if(state == 1)
- C.network.Remove(CAMERA_NET_POWER_ALARMS)
- else
- C.network.Add(CAMERA_NET_POWER_ALARMS)
+ for (var/obj/structure/machinery/camera/C in src)
+ cameras += C
+ if(state == 1)
+ C.network.Remove(CAMERA_NET_POWER_ALARMS)
+ else
+ C.network.Add(CAMERA_NET_POWER_ALARMS)
for (var/mob/living/silicon/aiPlayer in ai_mob_list)
if(aiPlayer.z == source.z)
if (state == 1)
@@ -161,10 +157,9 @@
// return 0 //redudant
//Check all the alarms before lowering atmosalm. Raising is perfectly fine.
- for (var/area/RA in related)
- for (var/obj/structure/machinery/alarm/AA in RA)
- if ( !(AA.inoperable()) && !AA.shorted)
- danger_level = max(danger_level, AA.danger_level)
+ for (var/obj/structure/machinery/alarm/AA in src)
+ if ( !(AA.inoperable()) && !AA.shorted)
+ danger_level = max(danger_level, AA.danger_level)
if(danger_level != atmosalm)
if (danger_level < 1 && atmosalm >= 1)
@@ -172,9 +167,8 @@
air_doors_open()
if (danger_level < 2 && atmosalm >= 2)
- for(var/area/RA in related)
- for(var/obj/structure/machinery/camera/C in RA)
- C.network.Remove(CAMERA_NET_ATMOSPHERE_ALARMS)
+ for(var/obj/structure/machinery/camera/C in src)
+ C.network.Remove(CAMERA_NET_ATMOSPHERE_ALARMS)
for(var/mob/living/silicon/aiPlayer in ai_mob_list)
aiPlayer.cancelAlarm("Atmosphere", src, src)
for(var/obj/structure/machinery/computer/station_alert/a in machines)
@@ -182,11 +176,10 @@
if (danger_level >= 2 && atmosalm < 2)
var/list/cameras = list()
- for(var/area/RA in related)
- //updateicon()
- for(var/obj/structure/machinery/camera/C in RA)
- cameras += C
- C.network.Add(CAMERA_NET_ATMOSPHERE_ALARMS)
+ //updateicon()
+ for(var/obj/structure/machinery/camera/C in src)
+ cameras += C
+ C.network.Add(CAMERA_NET_ATMOSPHERE_ALARMS)
for(var/mob/living/silicon/aiPlayer in ai_mob_list)
aiPlayer.triggerAlarm("Atmosphere", src, cameras, src)
for(var/obj/structure/machinery/computer/station_alert/a in machines)
@@ -194,40 +187,38 @@
air_doors_close()
atmosalm = danger_level
- for(var/area/RA in related)
- for (var/obj/structure/machinery/alarm/AA in RA)
- AA.update_icon()
+ for (var/obj/structure/machinery/alarm/AA in src)
+ AA.update_icon()
return 1
return 0
/area/proc/air_doors_close()
- if(!src.master.air_doors_activated)
- src.master.air_doors_activated = 1
- for(var/obj/structure/machinery/door/firedoor/E in src.master.all_doors)
- if(!E:blocked)
- if(E.operating)
- E:nextstate = OPEN
- else if(!E.density)
- INVOKE_ASYNC(E, TYPE_PROC_REF(/obj/structure/machinery/door, close))
+ for(var/obj/structure/machinery/door/firedoor/E in all_doors)
+ if(E.blocked)
+ continue
+
+ if(E.operating)
+ E.nextstate = OPEN
+ else if(!E.density)
+ E.close()
+
/area/proc/air_doors_open()
- if(src.master.air_doors_activated)
- src.master.air_doors_activated = 0
- for(var/obj/structure/machinery/door/firedoor/E in src.master.all_doors)
- if(!E:blocked)
- if(E.operating)
- E:nextstate = OPEN
- else if(E.density)
- INVOKE_ASYNC(E, TYPE_PROC_REF(/obj/structure/machinery/door, open))
+ for(var/obj/structure/machinery/door/firedoor/E in all_doors)
+ if(E.blocked)
+ continue
+ if(E.operating)
+ E.nextstate = OPEN
+ else if(E.density)
+ E.open()
/area/proc/firealert()
if(name == "Space") //no fire alarms in space
return
if(!(flags_alarm_state & ALARM_WARNING_FIRE))
- flags_alarm_state |= ALARM_WARNING_FIRE
- master.flags_alarm_state |= ALARM_WARNING_FIRE //used for firedoor checks
+ flags_alarm_state |= ALARM_WARNING_FIRE //used for firedoor checks
updateicon()
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
for(var/obj/structure/machinery/door/firedoor/D in all_doors)
@@ -237,10 +228,9 @@
else if(!D.density)
INVOKE_ASYNC(D, TYPE_PROC_REF(/obj/structure/machinery/door, close))
var/list/cameras = list()
- for(var/area/RA in related)
- for (var/obj/structure/machinery/camera/C in RA)
- cameras.Add(C)
- C.network.Add(CAMERA_NET_FIRE_ALARMS)
+ for (var/obj/structure/machinery/camera/C in src)
+ cameras.Add(C)
+ C.network.Add(CAMERA_NET_FIRE_ALARMS)
for (var/mob/living/silicon/ai/aiPlayer in ai_mob_list)
aiPlayer.triggerAlarm("Fire", src, cameras, src)
for (var/obj/structure/machinery/computer/station_alert/a in machines)
@@ -248,8 +238,7 @@
/area/proc/firereset()
if(flags_alarm_state & ALARM_WARNING_FIRE)
- flags_alarm_state &= ~ALARM_WARNING_FIRE
- master.flags_alarm_state &= ~ALARM_WARNING_FIRE //used for firedoor checks
+ flags_alarm_state &= ~ALARM_WARNING_FIRE //used for firedoor checks
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
updateicon()
for(var/obj/structure/machinery/door/firedoor/D in all_doors)
@@ -258,9 +247,8 @@
D.nextstate = OPEN
else if(D.density)
INVOKE_ASYNC(D, TYPE_PROC_REF(/obj/structure/machinery/door, open))
- for(var/area/RA in related)
- for (var/obj/structure/machinery/camera/C in RA)
- C.network.Remove(CAMERA_NET_FIRE_ALARMS)
+ for (var/obj/structure/machinery/camera/C in src)
+ C.network.Remove(CAMERA_NET_FIRE_ALARMS)
for (var/mob/living/silicon/ai/aiPlayer in ai_mob_list)
aiPlayer.cancelAlarm("Fire", src, src)
for (var/obj/structure/machinery/computer/station_alert/a in machines)
@@ -278,16 +266,16 @@
/*
/area/proc/toggle_evacuation() //toggles lights and creates an overlay.
flags_alarm_state ^= ALARM_WARNING_EVAC
- master.flags_alarm_state ^= ALARM_WARNING_EVAC
+ flags_alarm_state ^= ALARM_WARNING_EVAC
//if(flags_alarm_state & ALARM_WARNING_EVAC)
- // master.lightswitch = FALSE
+ // lightswitch = FALSE
//lightswitch = FALSE //Lights going off.
// else
- // master.lightswitch = TRUE
+ // lightswitch = TRUE
//lightswitch = TRUE //Coming on.
- master.updateicon()
+ updateicon()
- //master.power_change()
+ //power_change()
/area/proc/toggle_shut_down()
@@ -312,75 +300,72 @@
if(icon_state != I) icon_state = I //If the icon state changed, change it. Otherwise do nothing.
/area/proc/powered(chan) // return true if the area has power to given channel
- if(!master.requires_power)
+ if(!requires_power)
return 1
- if(master.always_unpowered)
+ if(always_unpowered)
return 0
switch(chan)
if(POWER_CHANNEL_EQUIP)
- return master.power_equip
+ return power_equip
if(POWER_CHANNEL_LIGHT)
- return master.power_light
+ return power_light
if(POWER_CHANNEL_ENVIRON)
- return master.power_environ
+ return power_environ
return 0
/area/proc/update_power_channels(equip, light, environ)
- if(!master)
- CRASH("CALLED update_power_channels on non-master channel!")
var/changed = FALSE
- if(master.power_equip != equip)
- master.power_equip = equip
+ if(power_equip != equip)
+ power_equip = equip
changed = TRUE
- if(master.power_light != light)
- master.power_light = light
+ if(power_light != light)
+ power_light = light
changed = TRUE
- if(master.power_environ != environ)
- master.power_environ = environ
+ if(power_environ != environ)
+ power_environ = environ
changed = TRUE
if(changed) //Something got changed power-wise, time for an update!
power_change()
// called when power status changes
/area/proc/power_change()
- for(var/area/RA in related)
- for(var/obj/structure/machinery/M in RA) // for each machine in the area
- if(!M.gc_destroyed)
- M.power_change() // reverify power status (to update icons etc.)
- if(flags_alarm_state)
- RA.updateicon()
+ for(var/obj/structure/machinery/M in src) // for each machine in the area
+ if(!M.gc_destroyed)
+ M.power_change() // reverify power status (to update icons etc.)
+ if(flags_alarm_state)
+ updateicon()
/area/proc/usage(chan, reset_oneoff = FALSE)
var/used = 0
switch(chan)
if(POWER_CHANNEL_LIGHT)
- used += master.used_light
+ used += used_light
if(POWER_CHANNEL_EQUIP)
- used += master.used_equip
+ used += used_equip
if(POWER_CHANNEL_ENVIRON)
- used += master.used_environ
+ used += used_environ
if(POWER_CHANNEL_ONEOFF)
- used += master.used_oneoff
+ used += used_oneoff
if(reset_oneoff)
- master.used_oneoff = 0
+ used_oneoff = 0
if(POWER_CHANNEL_TOTAL)
- used += master.used_light + master.used_equip + master.used_environ + master.used_oneoff
+ used += used_light + used_equip + used_environ + used_oneoff
if(reset_oneoff)
- master.used_oneoff = 0
+ used_oneoff = 0
return used
/area/proc/use_power(amount, chan)
switch(chan)
if(POWER_CHANNEL_EQUIP)
- master.used_equip += amount
+ used_equip += amount
if(POWER_CHANNEL_LIGHT)
- master.used_light += amount
+ used_light += amount
if(POWER_CHANNEL_ENVIRON)
- master.used_environ += amount
+ used_environ += amount
if(POWER_CHANNEL_ONEOFF)
- master.used_oneoff += amount
+ used_oneoff += amount
/area/Entered(A,atom/OldLoc)
if(ismob(A))
@@ -388,7 +373,7 @@
return
var/mob/M = A
var/area/old_area = get_area(OldLoc)
- if(old_area.master == master)
+ if(old_area == src)
return
M?.client?.soundOutput?.update_ambience(src, null, TRUE)
else if(istype(A, /obj/structure/machinery))
@@ -416,24 +401,21 @@
A.has_gravity = gravitystate
- for(var/area/SubA in A.related)
- SubA.has_gravity = gravitystate
-
- if(gravitystate)
- for(var/mob/living/carbon/human/M in SubA)
- thunk(M)
- for(var/mob/M1 in SubA)
- M1.make_floating(0)
- else
- for(var/mob/M in SubA)
- if(M.Check_Dense_Object() && istype(src,/mob/living/carbon/human/))
- var/mob/living/carbon/human/H = src
- if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags_inventory & NOSLIPPING)) //magboots + dense_object = no floaty effect
- H.make_floating(0)
- else
- H.make_floating(1)
+ if(gravitystate)
+ for(var/mob/living/carbon/human/M in A)
+ thunk(M)
+ for(var/mob/M1 in A)
+ M1.make_floating(0)
+ else
+ for(var/mob/M in A)
+ if(M.Check_Dense_Object() && istype(src,/mob/living/carbon/human/))
+ var/mob/living/carbon/human/H = src
+ if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags_inventory & NOSLIPPING)) //magboots + dense_object = no floaty effect
+ H.make_floating(0)
else
- M.make_floating(1)
+ H.make_floating(1)
+ else
+ M.make_floating(1)
/area/proc/thunk(M)
if(istype(get_turf(M), /turf/open/space)) // Can't fall onto nothing.
diff --git a/code/game/area/areas_event.dm b/code/game/area/areas_event.dm
index fe34d74363d5..c43dae3a65b2 100644
--- a/code/game/area/areas_event.dm
+++ b/code/game/area/areas_event.dm
@@ -47,20 +47,12 @@ structure:
//events are not part of regular gameplay, therefore, no statistics
statistic_exempt = TRUE
- //no dynamic lighting
- exterior_light = 0
- lighting_use_dynamic = FALSE
+ base_lighting_alpha = 255
//always powered
requires_power = FALSE
unlimited_power = TRUE
-/area/event/Initialize()
- . = ..()
- if(exterior_light)
- for(var/turf/T in contents)
- T.update_lumcount(exterior_light)
-
//no dynamic lighting, unpowered.
/area/event/unpowered
name = "Open grounds (event)"
@@ -75,7 +67,6 @@ structure:
icon_state = "event_dyn"
requires_power = TRUE
unlimited_power = TRUE
- lighting_use_dynamic = TRUE
//no dynamic lighting, unpowered.
/area/event/dynamic/unpowered
@@ -83,13 +74,14 @@ structure:
icon_state = "event_dyn_nopower"
unlimited_power = FALSE
+ base_lighting_alpha = 255
//dynamic lighting, lit, powered.
/area/event/dynamic/lit
name = "Open grounds (event PDL)"
icon_state = "event_dyn_lit"
- exterior_light = 3
+ base_lighting_alpha = 255
//dynamic lighting, lit, unpowered.
/area/event/dynamic/lit/unpowered
@@ -97,6 +89,7 @@ structure:
icon_state = "event_dyn_lit_nopower"
unlimited_power = FALSE
+ base_lighting_alpha = 255
//-----------------------CEILING_METAL--------------------------
@@ -122,7 +115,6 @@ structure:
icon_state = "metal_dyn"
requires_power = TRUE
unlimited_power = TRUE
- lighting_use_dynamic = TRUE
//no dynamic lighting, unpowered.
/area/event/metal/dynamic/unpowered
@@ -137,7 +129,7 @@ structure:
name = "Building interior (event PDL)"
icon_state = "metal_dyn_lit"
- exterior_light = 3
+ base_lighting_alpha = 255
//dynamic lighting, lit, unpowered.
/area/event/metal/dynamic/lit/unpowered
@@ -176,7 +168,6 @@ structure:
icon_state = "under_dyn"
requires_power = TRUE
unlimited_power = TRUE
- lighting_use_dynamic = TRUE
//no dynamic lighting, unpowered.
/area/event/underground/dynamic/unpowered
@@ -191,7 +182,7 @@ structure:
name = "Small caves (event PDL)"
icon_state = "under_dyn_lit"
- exterior_light = 3
+ base_lighting_alpha = 255
//dynamic lighting, lit, unpowered.
/area/event/underground/dynamic/lit/unpowered
@@ -232,7 +223,6 @@ structure:
icon_state = "undercas_dyn"
requires_power = TRUE
unlimited_power = TRUE
- lighting_use_dynamic = TRUE
//no dynamic lighting, unpowered.
/area/event/underground_no_CAS/dynamic/unpowered
@@ -246,7 +236,7 @@ structure:
name = "Caves (event PDL)"
icon_state = "undercas_dyn_lit"
- exterior_light = 3
+ base_lighting_alpha = 255
//dynamic lighting, lit, unpowered.
/area/event/underground_no_CAS/dynamic/lit/unpowered
@@ -286,7 +276,6 @@ structure:
icon_state = "deep_dyn"
requires_power = TRUE
unlimited_power = TRUE
- lighting_use_dynamic = TRUE
//no dynamic lighting, unpowered.
/area/event/deep_underground/dynamic/unpowered
@@ -301,7 +290,7 @@ structure:
name = "Deep underground (event PDL)"
icon_state = "deep_dyn_lit"
- exterior_light = 3
+ base_lighting_alpha = 255
//dynamic lighting, lit, unpowered.
/area/event/deep_underground/dynamic/lit/unpowered
diff --git a/code/game/area/chinook.dm b/code/game/area/chinook.dm
index 62bbdee7bd17..b9cd440fd548 100644
--- a/code/game/area/chinook.dm
+++ b/code/game/area/chinook.dm
@@ -9,7 +9,6 @@
requires_power = TRUE
statistic_exempt = TRUE
flags_area = AREA_NOTUNNEL
- lighting_use_dynamic = TRUE
sound_environment = SOUND_ENVIRONMENT_ROOM
unlimited_power = TRUE
ceiling = CEILING_METAL
diff --git a/code/game/area/kutjevo.dm b/code/game/area/kutjevo.dm
index 48f18091df4a..422017c0a46b 100644
--- a/code/game/area/kutjevo.dm
+++ b/code/game/area/kutjevo.dm
@@ -8,20 +8,17 @@
icon_state = "kutjevo"
can_build_special = TRUE //T-Comms structure
temperature = 308.7 //kelvin, 35c, 95f
- lighting_use_dynamic = 1
minimap_color = MINIMAP_AREA_ENGI
/area/shuttle/drop1/kutjevo
name = "Kutjevo - Dropship Alamo Landing Zone"
icon_state = "shuttle"
icon = 'icons/turf/area_kutjevo.dmi'
- lighting_use_dynamic = 1
/area/shuttle/drop2/kutjevo
name = "Kutjevo - Dropship Normandy Landing Zone"
icon_state = "shuttle2"
icon = 'icons/turf/area_kutjevo.dmi'
- lighting_use_dynamic = 1
/area/kutjevo/exterior
name = "Kutjevo - Exterior"
diff --git a/code/game/area/prison_v3_fiorina.dm b/code/game/area/prison_v3_fiorina.dm
index deb5d8758784..a528ee8376bf 100644
--- a/code/game/area/prison_v3_fiorina.dm
+++ b/code/game/area/prison_v3_fiorina.dm
@@ -8,7 +8,6 @@
icon_state = "fiorina"
can_build_special = TRUE //T-Comms structure
temperature = T20C
- lighting_use_dynamic = 1
ceiling = CEILING_GLASS
minimap_color = MINIMAP_AREA_COLONY
diff --git a/code/game/area/shiva.dm b/code/game/area/shiva.dm
index 8ca47c03e5ca..e4939cd67e1e 100644
--- a/code/game/area/shiva.dm
+++ b/code/game/area/shiva.dm
@@ -7,14 +7,12 @@
icon_state = "shiva"
can_build_special = TRUE //T-Comms structure
temperature = ICE_COLONY_TEMPERATURE
- lighting_use_dynamic = TRUE
minimap_color = MINIMAP_AREA_COLONY
/area/shuttle/drop1/shiva
name = "Shiva's Snowball - Dropship Alamo Landing Zone"
icon_state = "shuttle"
icon = 'icons/turf/area_shiva.dmi'
- lighting_use_dynamic = TRUE
is_resin_allowed = FALSE
minimap_color = MINIMAP_AREA_LZ
@@ -22,7 +20,6 @@
name = "Shiva's Snowball - Dropship Normandy Landing Zone"
icon_state = "shuttle2"
icon = 'icons/turf/area_shiva.dmi'
- lighting_use_dynamic = TRUE
is_resin_allowed = FALSE
minimap_color = MINIMAP_AREA_LZ
diff --git a/code/game/area/shuttles.dm b/code/game/area/shuttles.dm
index f61f13097d12..62c42406e795 100644
--- a/code/game/area/shuttles.dm
+++ b/code/game/area/shuttles.dm
@@ -1,13 +1,15 @@
/area/shuttle
name = "Shuttle"
requires_power = FALSE
+ unlimited_power = TRUE
always_unpowered = FALSE
icon_state = "shuttle"
ceiling_muffle = TRUE
// Loading the same shuttle map at a different time will produce distinct area instances.
unique = FALSE
- lighting_use_dynamic = FALSE
+
+ base_lighting_alpha = 255
///area/shuttle/Initialize()
@@ -37,6 +39,7 @@
name = "Hyperspace"
desc = "Weeeeee"
ambience_exterior = 'sound/ambience/shuttle_fly_loop.ogg'
+ base_lighting_alpha = 255
/area/shuttle/vehicle_elevator
name = "Vehicle ASRS"
@@ -52,7 +55,7 @@
/area/shuttle/trijent_shuttle/elevator
requires_power = TRUE
- lighting_use_dynamic = FALSE
+ unlimited_power = FALSE
powernet_name = "ground"
/area/shuttle/trijent_shuttle/lz1
@@ -66,6 +69,7 @@
/area/shuttle/trijent_shuttle/omega
name = "Trijent Omega"
+
/area/shuttle/escape_pod
icon = 'icons/turf/area_almayer.dmi'
icon_state = "lifeboat"
diff --git a/code/game/area/space_station_13_areas.dm b/code/game/area/space_station_13_areas.dm
index 226ca555cd57..df5e54a77013 100644
--- a/code/game/area/space_station_13_areas.dm
+++ b/code/game/area/space_station_13_areas.dm
@@ -18,7 +18,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "\improper Space"
requires_power = 1
always_unpowered = 1
- lighting_use_dynamic = 0
+ base_lighting_alpha = 255
power_light = FALSE
power_equip = FALSE
power_environ = FALSE
@@ -39,7 +39,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
ceiling = CEILING_METAL
/area/admin/droppod
- lighting_use_dynamic = FALSE
+ base_lighting_alpha = 255
/area/admin/droppod/holding
name = "\improper Admin Supply Drops Droppod"
@@ -56,9 +56,9 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "start area"
icon_state = "start"
ceiling = CEILING_MAX
- requires_power = 0
- luminosity = 1
- lighting_use_dynamic = 0
+ requires_power = FALSE
+ static_lighting = FALSE
+ base_lighting_alpha = 255
has_gravity = 1
// === end remove
@@ -72,6 +72,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
statistic_exempt = TRUE
ceiling = CEILING_METAL
+ base_lighting_alpha = 255
+
/area/centcom/control
name = "\improper abandoned Centcom Control"
@@ -86,6 +88,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
statistic_exempt = TRUE
ceiling = CEILING_METAL
+ base_lighting_alpha = 255
+
/area/tdome/tdome1
name = "\improper abandoned Thunderdome (Team 1)"
icon_state = "green"
diff --git a/code/game/area/strata.dm b/code/game/area/strata.dm
index 1cf0eac58d1c..cc658cfe5caf 100644
--- a/code/game/area/strata.dm
+++ b/code/game/area/strata.dm
@@ -18,13 +18,13 @@ EXTERIOR is FUCKING FREEZING, and refers to areas out in the open and or exposed
/area/shuttle/drop1/strata //Not in Sulaco.DM because holy shit we need to sort things.
name = "Dropship Alamo Landing Zone"
icon_state = "shuttle"
- lighting_use_dynamic = 0 //No bad
+ base_lighting_alpha = 255
minimap_color = MINIMAP_AREA_LZ
/area/shuttle/drop2/strata
name = "Dropship Normandy Landing Zone"
icon_state = "shuttle2"
- lighting_use_dynamic = 0
+ base_lighting_alpha = 255
minimap_color = MINIMAP_AREA_LZ
/area/strata/ag
diff --git a/code/game/area/techtree.dm b/code/game/area/techtree.dm
index 70b70e3852be..24510562ab57 100644
--- a/code/game/area/techtree.dm
+++ b/code/game/area/techtree.dm
@@ -1,5 +1,5 @@
/area/techtree
- lighting_use_dynamic = FALSE
+ base_lighting_alpha = 255
ceiling = CEILING_MAX
requires_power = 0
ambience_exterior = AMBIENCE_ALMAYER
diff --git a/code/game/area/varadero.dm b/code/game/area/varadero.dm
index 09b082f2acd6..682f3ded1c66 100644
--- a/code/game/area/varadero.dm
+++ b/code/game/area/varadero.dm
@@ -8,7 +8,6 @@
icon_state = "varadero"
can_build_special = TRUE //T-Comms structure
temperature = TROPICAL_TEMP
- lighting_use_dynamic = TRUE
minimap_color = MINIMAP_AREA_COLONY
//shuttle stuff
@@ -17,7 +16,6 @@
name = "New Varadero - Dropship Alamo Landing Zone"
icon_state = "shuttle"
icon = 'icons/turf/area_varadero.dmi'
- lighting_use_dynamic = TRUE
is_resin_allowed = FALSE
minimap_color = MINIMAP_AREA_LZ
@@ -26,7 +24,6 @@
name = "New Varadero - Dropship Normandy Landing Zone"
icon_state = "shuttle2"
icon = 'icons/turf/area_varadero.dmi'
- lighting_use_dynamic = TRUE
is_resin_allowed = FALSE
minimap_color = MINIMAP_AREA_LZ
@@ -35,7 +32,6 @@
/area/varadero/exterior
name = "New Varadero - Exterior"
ceiling = CEILING_NONE
- lighting_use_dynamic = TRUE
ambience_exterior = AMBIENCE_NV
//soundscape_playlist
@@ -119,7 +115,6 @@
name = "New Varadero - East Beach"
is_resin_allowed = FALSE
icon_state = "varadero1"
- lighting_use_dynamic = TRUE
minimap_color = MINIMAP_AREA_JUNGLE
/area/varadero/exterior/monsoon
@@ -130,7 +125,6 @@
/area/varadero/exterior/pool
name = "New Varadero - Interior Pool"
icon_state = "varadero1"
- lighting_use_dynamic = TRUE
minimap_color = MINIMAP_AREA_COMMAND_CAVE
/area/varadero/exterior/eastocean
@@ -292,8 +286,6 @@
power_light = FALSE
power_equip = FALSE
power_environ = FALSE
- luminosity = 0
- lighting_use_dynamic = 1
sound_environment = SOUND_ENVIRONMENT_AUDITORIUM
minimap_color = MINIMAP_AREA_CAVES
@@ -311,8 +303,7 @@
power_light = FALSE
power_equip = FALSE
power_environ = FALSE
- luminosity = 0
- lighting_use_dynamic = 1
+ minimap_color = MINIMAP_AREA_RESEARCH_CAVE
/area/varadero/interior_protected/caves/central
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index d2cad09edc83..e1541f8368b8 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -59,6 +59,36 @@
///Default pixel y shifting for the atom's icon.
var/base_pixel_y = 0
+ //light stuff
+
+ ///Light systems, only one of the three should be active at the same time.
+ var/light_system = STATIC_LIGHT
+ ///Range of the light in tiles. Zero means no light.
+ var/light_range = 0
+ ///Intensity of the light. The stronger, the less shadows you will see on the lit area.
+ var/light_power = 1
+ ///Hexadecimal RGB string representing the colour of the light. White by default.
+ var/light_color = COLOR_WHITE
+ ///Boolean variable for toggleable lights. Has no effect without the proper light_system, light_range and light_power values.
+ var/light_on = FALSE
+ ///Bitflags to determine lighting-related atom properties.
+ var/light_flags = NONE
+ ///Our light source. Don't fuck with this directly unless you have a good reason!
+ var/tmp/datum/dynamic_light_source/light
+ ///Any light sources that are "inside" of us, for example, if src here was a mob that's carrying a flashlight, that flashlight's light source would be part of this list.
+ var/tmp/list/hybrid_light_sources
+
+ //Values should avoid being close to -16, 16, -48, 48 etc.
+ //Best keep them within 10 units of a multiple of 32, as when the light is closer to a wall, the probability
+ //that a shadow extends to opposite corners of the light mask square is increased, resulting in more shadow
+ //overlays.
+ ///x offset for dynamic lights on this atom
+ var/light_pixel_x
+ ///y offset for dynamic lights on this atom
+ var/light_pixel_y
+ ///typepath for the lighting maskfor dynamic light sources
+ var/light_mask_type = null
+
///The color this atom will be if we choose to draw it on the minimap
var/minimap_color = MINIMAP_SOLID
@@ -77,7 +107,7 @@ Make sure the return value equals the return value of the parent so that the
directive is properly returned.
*/
//===========================================================================
-/atom/Destroy()
+/atom/Destroy(force)
orbiters = null // The component is attached to us normally and will be deleted elsewhere
QDEL_NULL(reagents)
QDEL_NULL(light)
@@ -327,6 +357,12 @@ Parameters are passed from New.
CRASH("Warning: [src]([type]) initialized multiple times!")
flags_atom |= INITIALIZED
+ if(light_system != MOVABLE_LIGHT && light_system != DIRECTIONAL_LIGHT && light_power && light_range)
+ update_light()
+ if(isturf(loc) && opacity)
+ var/turf/opaque_turf = loc
+ opaque_turf.directional_opacity = ALL_CARDINALS // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways.
+
pass_flags = pass_flags_cache[type]
if (isnull(pass_flags))
pass_flags = new()
@@ -569,6 +605,37 @@ Parameters are passed from New.
var/icon/I = icon(icon, icon_state, dir)
return (I.Width() + I.Height()) * 0.5
+/**
+ * If this object has lights, turn it on/off.
+ * user: the mob actioning this
+ * toggle_on: if TRUE, will try to turn ON the light. Opposite if FALSE
+ * cooldown: how long until you can toggle the light on/off again
+ * sparks: if a spark effect will be generated
+ * forced: if TRUE and toggle_on = FALSE, will cause the light to turn on in cooldown second
+ * originated_turf: if not null, will check if the obj_turf is closer than distance_max to originated_turf, and the proc will return if not
+ * distance_max: used to check if originated_turf is close to obj.loc
+*/
+/atom/proc/turn_light(mob/user, toggle_on , cooldown = 1 SECONDS, sparks = FALSE, forced = FALSE, light_again = FALSE)
+ if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_LIGHT) && !forced)
+ return STILL_ON_COOLDOWN
+ if(cooldown <= 0)
+ cooldown = 1 SECONDS
+ TIMER_COOLDOWN_START(src, COOLDOWN_LIGHT, cooldown)
+ if(toggle_on == light_on)
+ return NO_LIGHT_STATE_CHANGE
+ if(light_again && !toggle_on) //Is true when turn light is called by nightfall and the light is already on
+ addtimer(CALLBACK(src, PROC_REF(reset_light)), cooldown + 1)
+ if(sparks && light_on)
+ var/datum/effect_system/spark_spread/spark_system = new
+ spark_system.set_up(5, 0, src)
+ spark_system.attach(src)
+ spark_system.start(src)
+ return CHECKS_PASSED
+
+///Turn on the light, should be called by a timer
+/atom/proc/reset_light()
+ turn_light(null, TRUE, 1 SECONDS, FALSE, TRUE)
+
/**
* Return the markup to for the dropdown list for the VV panel for this atom
*
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 17b37ce76630..9b64833cb547 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -21,13 +21,24 @@
var/datum/component/orbiter/orbiting
+ /// Either FALSE, [EMISSIVE_BLOCK_GENERIC], or [EMISSIVE_BLOCK_UNIQUE]
+ var/blocks_emissive = FALSE
+ ///Internal holder for emissive blocker object, do not use directly use blocks_emissive
+ var/atom/movable/emissive_blocker/em_block
+
+ ///Lazylist to keep track on the sources of illumination.
+ var/list/affected_movable_lights
+ ///Highest-intensity light affecting us, which determines our visibility.
+ var/affecting_dynamic_lumi = 0
+
//===========================================================================
-/atom/movable/Destroy()
+/atom/movable/Destroy(force)
for(var/atom/movable/I in contents)
qdel(I)
if(pulledby)
pulledby.stop_pulling()
QDEL_NULL(launch_metadata)
+ QDEL_NULL(em_block)
if(loc)
loc.on_stored_atom_del(src) //things that container need to do when a movable atom inside it is deleted
@@ -38,6 +49,9 @@
. = ..()
moveToNullspace() //so we move into null space. Must be after ..() b/c atom's Dispose handles deleting our lighting stuff
+ QDEL_NULL(light)
+ QDEL_NULL(static_light)
+
//===========================================================================
//Overlays
@@ -60,6 +74,48 @@
return src.master.attack_hand(a, b, c)
return
+/atom/movable/Initialize(mapload, ...)
+ . = ..()
+ switch(blocks_emissive)
+ if(EMISSIVE_BLOCK_GENERIC)
+ var/mutable_appearance/gen_emissive_blocker = mutable_appearance(icon, icon_state, plane = EMISSIVE_PLANE, alpha = src.alpha)
+ gen_emissive_blocker.color = GLOB.em_block_color
+ gen_emissive_blocker.dir = dir
+ gen_emissive_blocker.appearance_flags |= appearance_flags
+ overlays += gen_emissive_blocker
+ if(EMISSIVE_BLOCK_UNIQUE)
+ render_target = ref(src)
+ em_block = new(src, render_target)
+ overlays += list(em_block)
+ if(opacity)
+ AddElement(/datum/element/light_blocking)
+ if(light_system == MOVABLE_LIGHT)
+ AddComponent(/datum/component/overlay_lighting)
+ if(light_system == DIRECTIONAL_LIGHT)
+ AddComponent(/datum/component/overlay_lighting, is_directional = TRUE)
+
+/*
+
+///Updates this movables emissive overlay
+/atom/movable/proc/update_emissive_block()
+ if(!blocks_emissive)
+ return
+ else if (blocks_emissive == EMISSIVE_BLOCK_GENERIC)
+ var/mutable_appearance/gen_emissive_blocker = emissive_blocker(icon, icon_state, alpha = src.alpha, appearance_flags = src.appearance_flags)
+ gen_emissive_blocker.dir = dir
+ if(blocks_emissive == EMISSIVE_BLOCK_UNIQUE)
+ if(!em_block)
+ render_target = ref(src)
+ em_block = new(src, render_target)
+ return em_block
+
+/atom/movable/update_overlays()
+ . = ..()
+
+ . += update_emissive_block()
+
+*/
+
/atom/movable/vv_get_dropdown()
. = ..()
VV_DROPDOWN_OPTION(VV_HK_EDIT_PARTICLES, "Edit Particles")
@@ -251,10 +307,10 @@
if(light) //Clone lighting
if(!clone.light)
- clone.SetLuminosity(luminosity) //Create clone light
+ clone.set_light(luminosity) //Create clone light
else
if(clone.light)
- clone.SetLuminosity(0) //Kill clone light
+ clone.set_light(0) //Kill clone light
/atom/movable/proc/destroy_clone()
clones.Remove(src.clone)
@@ -279,3 +335,23 @@
//if((force < (move_resist * MOVE_FORCE_THROW_RATIO)) || (move_resist == INFINITY))
// return
return throw_atom(target, range, speed, thrower, spin)
+
+///Keeps track of the sources of dynamic luminosity and updates our visibility with the highest.
+/atom/movable/proc/update_dynamic_luminosity()
+ var/highest = 0
+ for(var/i in affected_movable_lights)
+ if(affected_movable_lights[i] <= highest)
+ continue
+ highest = affected_movable_lights[i]
+ if(highest == affecting_dynamic_lumi)
+ return
+ luminosity -= affecting_dynamic_lumi
+ affecting_dynamic_lumi = highest
+ luminosity += affecting_dynamic_lumi
+
+
+///Helper to change several lighting overlay settings.
+/atom/movable/proc/set_light_range_power_color(range, power, color)
+ set_light_range(range)
+ set_light_power(power)
+ set_light_color(color)
diff --git a/code/game/machinery/ARES/ARES_procs.dm b/code/game/machinery/ARES/ARES_procs.dm
index a335a36994e5..f48ae47cf0e2 100644
--- a/code/game/machinery/ARES/ARES_procs.dm
+++ b/code/game/machinery/ARES/ARES_procs.dm
@@ -563,7 +563,7 @@ GLOBAL_LIST_INIT(maintenance_categories, list(
for(var/client/admin in GLOB.admins)
if((R_ADMIN|R_MOD) & admin.admin_holder.rights)
playsound_client(admin,'sound/effects/sos-morse-code.ogg',10)
- message_admins("[key_name(usr)] has requested a Distress Beacon (via ARES)! [CC_MARK(usr)] (SEND) (DENY) [ADMIN_JMP_USER(usr)] [CC_REPLY(usr)]")
+ SSticker.mode.request_ert(usr, TRUE)
to_chat(usr, SPAN_NOTICE("A distress beacon request has been sent to USCM High Command."))
COOLDOWN_START(src, ares_distress_cooldown, COOLDOWN_COMM_REQUEST)
return TRUE
diff --git a/code/game/machinery/air_alarm.dm b/code/game/machinery/air_alarm.dm
index 28e045163f06..16512a944be1 100644
--- a/code/game/machinery/air_alarm.dm
+++ b/code/game/machinery/air_alarm.dm
@@ -136,8 +136,6 @@
/obj/structure/machinery/alarm/proc/first_run()
alarm_area = get_area(src)
- if (alarm_area.master)
- alarm_area = alarm_area.master
area_uid = alarm_area.uid
if (name == "alarm")
name = "[alarm_area.name] Air Alarm"
@@ -203,11 +201,10 @@
/obj/structure/machinery/alarm/proc/elect_master()
if(!alarm_area)
return 0
- for (var/area/A in alarm_area.related)
- for (var/obj/structure/machinery/alarm/AA in A)
- if (!(AA.inoperable()))
- alarm_area.master_air_alarm = AA
- return 1
+ for (var/obj/structure/machinery/alarm/AA in alarm_area)
+ if (!(AA.inoperable()))
+ alarm_area.master_air_alarm = AA
+ return 1
return 0
/obj/structure/machinery/alarm/proc/get_danger_level(current_value, list/danger_levels)
@@ -314,9 +311,8 @@
/obj/structure/machinery/alarm/proc/apply_mode()
//propagate mode to other air alarms in the area
//TODO: make it so that players can choose between applying the new mode to the room they are in (related area) vs the entire alarm area
- for (var/area/RA in alarm_area.related)
- for (var/obj/structure/machinery/alarm/AA in RA)
- AA.mode = mode
+ for (var/obj/structure/machinery/alarm/AA in alarm_area)
+ AA.mode = mode
switch(mode)
if(AALARM_MODE_SCRUBBING)
diff --git a/code/game/machinery/bio-dome_floodlights.dm b/code/game/machinery/bio-dome_floodlights.dm
index 488cf1ed79cc..a1f028a79f30 100644
--- a/code/game/machinery/bio-dome_floodlights.dm
+++ b/code/game/machinery/bio-dome_floodlights.dm
@@ -60,9 +60,9 @@
spawn(rand(0,50))
if(F.is_lit) //Shut it down
- F.SetLuminosity(0)
+ F.set_light(0)
else
- F.SetLuminosity(F.lum_value)
+ F.set_light(F.lum_value)
F.is_lit = !(F.is_lit)
F.update_icon()
return 0
@@ -101,7 +101,6 @@
if(fswitch?.floodlist)
fswitch.floodlist -= src
fswitch = null
- SetLuminosity(0)
return ..()
/obj/structure/machinery/hydro_floodlight/update_icon()
@@ -130,7 +129,7 @@
user.visible_message(SPAN_NOTICE("[user] finishes welding [src]'s damage."), \
SPAN_NOTICE("You finish welding [src]'s damage."))
if(is_lit)
- SetLuminosity(lum_value)
+ set_light(lum_value)
update_icon()
return 1
else
@@ -161,7 +160,7 @@
if(do_after(user, 50, INTERRUPT_ALL, BUSY_ICON_HOSTILE) && !damaged) //Not when it's already damaged.
if(!src) return 0
damaged = 1
- SetLuminosity(0)
+ set_light(0)
user.visible_message(SPAN_DANGER("[user] slashes up [src]!"),
SPAN_DANGER("You slash up [src]!"))
playsound(src, 'sound/weapons/blade1.ogg', 25, 1)
diff --git a/code/game/machinery/biohazard_lockdown.dm b/code/game/machinery/biohazard_lockdown.dm
new file mode 100644
index 000000000000..fd6205baa1d9
--- /dev/null
+++ b/code/game/machinery/biohazard_lockdown.dm
@@ -0,0 +1,109 @@
+#define LOCKDOWN_READY 0
+#define LOCKDOWN_ACTIVE 1
+GLOBAL_VAR_INIT(lockdown_state, LOCKDOWN_READY)
+
+/obj/structure/machinery/biohazard_lockdown
+ name = "Emergency Containment Breach"
+ icon_state = "big_red_button_tablev"
+ unslashable = TRUE
+ unacidable = TRUE
+ COOLDOWN_DECLARE(containment_lockdown)
+
+/obj/structure/machinery/biohazard_lockdown/ex_act(severity)
+ return FALSE
+
+/obj/structure/machinery/biohazard_lockdown/attack_remote(mob/user as mob)
+ return FALSE
+
+/obj/structure/machinery/biohazard_lockdown/attack_alien(mob/user as mob)
+ return FALSE
+
+/obj/structure/machinery/biohazard_lockdown/attackby(obj/item/attacking_item, mob/user)
+ return attack_hand(user)
+
+/obj/structure/machinery/biohazard_lockdown/attack_hand(mob/living/user)
+ if(isxeno(user))
+ return FALSE
+ if(!allowed(user))
+ to_chat(user, SPAN_DANGER("Access Denied"))
+ flick(initial(icon_state) + "-denied", src)
+ return FALSE
+
+ if(!COOLDOWN_FINISHED(src, containment_lockdown))
+ to_chat(user, SPAN_BOLDWARNING("Biohazard Lockdown procedures are on cooldown! They will be ready in [COOLDOWN_SECONDSLEFT(src, containment_lockdown)] seconds!"))
+ return FALSE
+
+ add_fingerprint(user)
+ biohazard_lockdown(user)
+ COOLDOWN_START(src, containment_lockdown, 5 MINUTES)
+
+/obj/structure/machinery/door/poddoor/almayer/biohazard
+ name = "Biohazard Containment Airlock"
+ density = FALSE
+
+/obj/structure/machinery/door/poddoor/almayer/biohazard/Initialize()
+ . = ..()
+ RegisterSignal(SSdcs, COMSIG_GLOB_RESEARCH_LOCKDOWN, PROC_REF(close))
+ RegisterSignal(SSdcs, COMSIG_GLOB_RESEARCH_LIFT, PROC_REF(open))
+
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white
+ icon_state = "w_almayer_pdoor1"
+ base_icon_state = "w_almayer_pdoor"
+
+/client/proc/admin_biohazard_alert()
+ set name = "Containment Breach Alert"
+ set category = "Admin.Ship"
+
+ if(!admin_holder ||!check_rights(R_EVENT))
+ return FALSE
+
+ var/prompt = tgui_alert(src, "Are you sure you want to trigger a containment breach alert? This will force red alert, and lockdown research.", "Choose.", list("Yes", "No"), 20 SECONDS)
+ if(prompt != "Yes")
+ return FALSE
+
+ prompt = tgui_alert(src, "Do you want to use a custom announcement?", "Choose.", list("Yes", "No"), 20 SECONDS)
+ if(prompt == "Yes")
+ var/whattoannounce = tgui_input_text(src, "Please enter announcement text.", "what?")
+ biohazard_lockdown(usr, whattoannounce, TRUE)
+ else
+ biohazard_lockdown(usr, admin = TRUE)
+ return TRUE
+
+/proc/biohazard_lockdown(mob/user, message, admin = FALSE)
+ if(IsAdminAdvancedProcCall())
+ return PROC_BLOCKED
+
+ var/log = "[key_name(user)] triggered research bio lockdown!"
+ var/ares_log = "[user.name] triggered Medical Research Biohazard Containment Lockdown."
+ if(!message)
+ message = "ATTENTION! \n\nBIOHAZARD CONTAINMENT BREACH. \n\nRESEARCH DEPARTMENT UNDER LOCKDOWN."
+ else
+ log = "[key_name(user)] triggered research bio lockdown! (Using a custom announcement)."
+ if(admin)
+ log += " (Admin Triggered)."
+ ares_log = "[MAIN_AI_SYSTEM] triggered Medical Research Biohazard Containment Lockdown."
+
+ switch(GLOB.lockdown_state)
+ if(LOCKDOWN_READY)
+ GLOB.lockdown_state = LOCKDOWN_ACTIVE
+ set_security_level(SEC_LEVEL_RED, TRUE, FALSE)
+ SEND_GLOBAL_SIGNAL(COMSIG_GLOB_RESEARCH_LOCKDOWN)
+ if(LOCKDOWN_ACTIVE)
+ GLOB.lockdown_state = LOCKDOWN_READY
+ message = "ATTENTION! \n\nBIOHAZARD CONTAINMENT LOCKDOWN LIFTED."
+ log = "[key_name(user)] lifted research bio lockdown!"
+ ares_log = "[user.name] lifted Medical Research Biohazard Containment Lockdown."
+ if(admin)
+ log += " (Admin Triggered)."
+ ares_log = "[MAIN_AI_SYSTEM] lifted Medical Research Biohazard Containment Lockdown."
+
+ set_security_level(SEC_LEVEL_BLUE, TRUE, FALSE)
+ SEND_GLOBAL_SIGNAL(COMSIG_GLOB_RESEARCH_LIFT)
+
+ shipwide_ai_announcement(message, MAIN_AI_SYSTEM, 'sound/effects/biohazard.ogg')
+ message_admins(log)
+ var/datum/ares_link/link = GLOB.ares_link
+ link.log_ares_security("Containment Lockdown", ares_log)
+
+#undef LOCKDOWN_READY
+#undef LOCKDOWN_ACTIVE
diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm
index aff1efa3de66..b7bd61337ee4 100644
--- a/code/game/machinery/bots/bots.dm
+++ b/code/game/machinery/bots/bots.dm
@@ -3,7 +3,8 @@
/obj/structure/machinery/bot
icon = 'icons/obj/structures/machinery/aibots.dmi'
layer = MOB_LAYER
- luminosity = 3
+ light_system = MOVABLE_LIGHT
+ light_range = 3
use_power = USE_POWER_NONE
var/obj/item/card/id/botcard // the ID card that the bot "holds"
var/on = 1
@@ -15,6 +16,12 @@
var/open = 0//Maint panel
var/locked = 1
+/obj/structure/machinery/bot/Initialize(mapload, ...)
+ . = ..()
+
+ if(light_range)
+ set_light_on(TRUE)
+
/obj/structure/machinery/bot/Destroy()
QDEL_NULL(botcard)
. = ..()
@@ -24,12 +31,12 @@
if(stat)
return 0
on = 1
- SetLuminosity(initial(luminosity))
+ set_light(initial(luminosity))
return 1
/obj/structure/machinery/bot/proc/turn_off()
on = 0
- SetLuminosity(0)
+ set_light(0)
/obj/structure/machinery/bot/proc/explode()
qdel(src)
@@ -38,10 +45,6 @@
if(health <= 0)
explode()
-/obj/structure/machinery/bot/Destroy()
- SetLuminosity(0)
- . = ..()
-
/obj/structure/machinery/bot/get_examine_text(mob/user)
. = ..()
if(health < maxhealth)
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 20208a573c61..4d17e4a08803 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -79,7 +79,7 @@
network = list()
cameranet.removeCamera(src)
stat |= EMPED
- SetLuminosity(0)
+ set_light(0)
triggerCameraAlarm()
spawn(900)
network = previous_network
diff --git a/code/game/machinery/computer/almayer_control.dm b/code/game/machinery/computer/almayer_control.dm
index 7d63a2e8c3af..012c1d9eea4a 100644
--- a/code/game/machinery/computer/almayer_control.dm
+++ b/code/game/machinery/computer/almayer_control.dm
@@ -11,11 +11,11 @@
/// requesting a distress beacon
COOLDOWN_DECLARE(cooldown_request)
/// requesting evac
- COOLDOWN_DECLARE(cooldown_destruct)
+ COOLDOWN_DECLARE(cooldown_destruct)
/// messaging HC (admins)
COOLDOWN_DECLARE(cooldown_central)
/// making a ship announcement
- COOLDOWN_DECLARE(cooldown_message)
+ COOLDOWN_DECLARE(cooldown_message)
var/list/messagetitle = list()
var/list/messagetext = list()
@@ -230,7 +230,7 @@
for(var/client/admin_client as anything in GLOB.admins)
if((R_ADMIN|R_MOD) & admin_client.admin_holder.rights)
admin_client << 'sound/effects/sos-morse-code.ogg'
- message_admins("[key_name(usr)] has requested a Distress Beacon! [CC_MARK(usr)] (SEND) (DENY) [ADMIN_JMP_USER(usr)] [CC_REPLY(usr)]")
+ SSticker.mode.request_ert(usr)
to_chat(usr, SPAN_NOTICE("A distress beacon request has been sent to USCM Central Command."))
COOLDOWN_START(src, cooldown_request, COOLDOWN_COMM_REQUEST)
diff --git a/code/game/machinery/computer/area_air_control.dm b/code/game/machinery/computer/area_air_control.dm
index e3f16a988c86..22f4211aa8ee 100644
--- a/code/game/machinery/computer/area_air_control.dm
+++ b/code/game/machinery/computer/area_air_control.dm
@@ -139,14 +139,10 @@
var/turf/T_src = get_turf(src)
if(!T_src.loc) return 0
var/area/A_src = T_src.loc
- if (A_src.master)
- A_src = A_src.master
var/turf/T_scrub = get_turf(scrubber)
if(!T_scrub.loc) return 0
var/area/A_scrub = T_scrub.loc
- if (A_scrub.master)
- A_scrub = A_scrub.master
if(A_scrub != A_src)
return 0
@@ -160,14 +156,11 @@
var/turf/T = get_turf(src)
if(!T.loc) return
- var/area/A = T.loc
- if (A.master)
- A = A.master
for(var/obj/structure/machinery/portable_atmospherics/powered/scrubber/huge/scrubber in machines )
var/turf/T2 = get_turf(scrubber)
if(T2 && T2.loc)
- var/area/A2 = T2.loc
- if(istype(A2) && A2.master && A2.master == A )
+ var/area/A = T2.loc
+ if(istype(A) && A)
connectedscrubbers += scrubber
found = 1
diff --git a/code/game/machinery/computer/camera_console.dm b/code/game/machinery/computer/camera_console.dm
index d4feca457f4a..10c2bcc309eb 100644
--- a/code/game/machinery/computer/camera_console.dm
+++ b/code/game/machinery/computer/camera_console.dm
@@ -17,12 +17,12 @@
var/atom/movable/screen/map_view/cam_screen
var/atom/movable/screen/background/cam_background
- /// All turfs within range of the currently active camera
- var/list/range_turfs = list()
-
var/colony_camera_mapload = TRUE
var/admin_console = FALSE
+ /// All the plane masters that need to be applied.
+ var/list/cam_plane_masters
+
/obj/structure/machinery/computer/cameras/Initialize(mapload)
. = ..()
// Map name has to start and end with an A-Z character,
@@ -33,6 +33,16 @@
if(colony_camera_mapload && mapload && is_ground_level(z))
network = list(CAMERA_NET_COLONY)
+ cam_plane_masters = list()
+ for(var/plane in subtypesof(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master/blackness)
+ var/atom/movable/screen/plane_master/instance = new plane()
+ instance.assigned_map = map_name
+ instance.del_on_map_removal = FALSE
+ if(instance.blend_mode_override)
+ instance.blend_mode = instance.blend_mode_override
+ instance.screen_loc = "[map_name]:CENTER"
+ cam_plane_masters += instance
+
// Initialize map objects
cam_screen = new
cam_screen.icon = null
@@ -51,7 +61,6 @@
qdel(cam_screen)
QDEL_NULL(cam_background)
qdel(cam_background)
- range_turfs = null
last_camera_turf = null
concurrent_users = null
return ..()
@@ -94,6 +103,8 @@
// Register map objects
user.client.register_map_obj(cam_screen)
user.client.register_map_obj(cam_background)
+ for(var/plane in cam_plane_masters)
+ user.client.register_map_obj(plane)
// Open UI
ui = new(user, src, "CameraConsole", name)
ui.open()
@@ -176,13 +187,8 @@
var/list/visible_things = current.isXRay() ? range(current.view_range, cam_location) : view(current.view_range, cam_location)
var/list/visible_turfs = list()
- range_turfs.Cut()
- var/area/A
for(var/turf/visible_turf in visible_things)
- range_turfs += visible_turf
- A = visible_turf.loc
- if(!A.lighting_use_dynamic || visible_turf.lighting_lumcount >= 1)
- visible_turfs += visible_turf
+ visible_turfs += visible_turf
var/list/bbox = get_bbox_of_atoms(visible_turfs)
var/size_x = bbox[3] - bbox[1] + 1
@@ -192,18 +198,6 @@
cam_background.icon_state = "clear"
cam_background.fill_rect(1, 1, size_x, size_y)
- START_PROCESSING(SSfastobj, src) // fastobj to somewhat keep pace with lighting updates
-
-/obj/structure/machinery/computer/cameras/process()
- if(current)
- var/list/visible_turfs = list()
- var/area/A
- for(var/turf/visible_turf as anything in range_turfs)
- A = visible_turf.loc
- if(!A.lighting_use_dynamic || visible_turf.lighting_lumcount >= 1)
- visible_turfs += visible_turf
- cam_screen.vis_contents = visible_turfs
-
/obj/structure/machinery/computer/cameras/ui_close(mob/user)
var/user_ref = WEAKREF(user)
var/is_living = isliving(user)
@@ -215,10 +209,8 @@
if(length(concurrent_users) == 0 && is_living)
current = null
last_camera_turf = null
- range_turfs = list()
if(use_power)
update_use_power(USE_POWER_IDLE)
- STOP_PROCESSING(SSfastobj, src)
user.unset_interaction()
/obj/structure/machinery/computer/cameras/proc/show_camera_static()
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index edc39faf3ddc..f7ea31fba36a 100644
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -200,7 +200,7 @@
for(var/client/C in GLOB.admins)
if((R_ADMIN|R_MOD) & C.admin_holder.rights)
C << 'sound/effects/sos-morse-code.ogg'
- message_admins("[key_name(usr)] has requested a Distress Beacon! [CC_MARK(usr)] (SEND) (DENY) [ADMIN_JMP_USER(usr)] [CC_REPLY(usr)]")
+ SSticker.mode.request_ert(usr)
to_chat(usr, SPAN_NOTICE("A distress beacon request has been sent to USCM Central Command."))
cooldown_request = world.time
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index ed7335ea8778..eb9aed4f71e4 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -185,7 +185,6 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li
flags_atom |= USES_HEARING
/obj/structure/machinery/cryopod/Destroy()
- SetLuminosity(0)
QDEL_NULL(occupant)
QDEL_NULL(announce)
. = ..()
@@ -368,7 +367,7 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li
qdel(G)
icon_state = "body_scanner_open"
- SetLuminosity(0)
+ set_light(0)
if(occupant.key)
occupant.ghostize(0)
@@ -509,7 +508,7 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li
mob.forceMove(src)
occupant = mob
icon_state = "body_scanner_closed"
- SetLuminosity(2)
+ set_light(2)
time_entered = world.time
start_processing()
@@ -532,7 +531,7 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li
occupant = null
stop_processing()
icon_state = "body_scanner_open"
- SetLuminosity(0)
+ set_light(0)
playsound(src, 'sound/machines/pod_open.ogg', 30)
#ifdef OBJECTS_PROXY_SPEECH
diff --git a/code/game/machinery/doors/alarmlock.dm b/code/game/machinery/doors/alarmlock.dm
index b6b9a6133a84..c55250fdc04d 100644
--- a/code/game/machinery/doors/alarmlock.dm
+++ b/code/game/machinery/doors/alarmlock.dm
@@ -25,6 +25,7 @@
return ..()
/obj/structure/machinery/door/airlock/alarmlock/receive_signal(datum/signal/signal)
+/*
..()
if(inoperable())
return
@@ -32,10 +33,6 @@
var/alarm_area = signal.data["zone"]
var/alert = signal.data["alert"]
- var/area/our_area = get_area(src)
- if (our_area.master)
- our_area = our_area.master
-
if(alarm_area == our_area.name)
switch(alert)
if("severe")
@@ -44,3 +41,4 @@
if("minor", "clear")
autoclose = 0
open()
+*/
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index b54658b24245..578ef368f5d9 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -49,7 +49,7 @@
/obj/structure/machinery/door/Destroy()
. = ..()
if(filler && width > 1)
- filler.SetOpacity(0)// Ehh... let's hope there are no walls there. Must fix this
+ filler.set_opacity(0)// Ehh... let's hope there are no walls there. Must fix this
filler = null
density = FALSE
@@ -64,12 +64,12 @@
bound_width = width * world.icon_size
bound_height = world.icon_size
filler = get_step(src,EAST)
- filler.SetOpacity(opacity)
+ filler.set_opacity(opacity)
else
bound_width = world.icon_size
bound_height = width * world.icon_size
filler = get_step(src,NORTH)
- filler.SetOpacity(opacity)
+ filler.set_opacity(opacity)
//process()
//return
@@ -222,9 +222,9 @@
operating = TRUE
do_animate("opening")
icon_state = "door0"
- SetOpacity(FALSE)
+ set_opacity(FALSE)
if(filler)
- filler.SetOpacity(opacity)
+ filler.set_opacity(opacity)
addtimer(CALLBACK(src, PROC_REF(finish_open)), openspeed)
return TRUE
@@ -255,9 +255,9 @@
/obj/structure/machinery/door/proc/finish_close()
update_icon()
if(visible && !glass)
- SetOpacity(TRUE)
+ set_opacity(TRUE)
if(filler)
- filler.SetOpacity(opacity)
+ filler.set_opacity(opacity)
operating = FALSE
/obj/structure/machinery/door/proc/requiresID()
@@ -279,15 +279,15 @@
if(dir in list(EAST, WEST))
bound_width = width * world.icon_size
bound_height = world.icon_size
- filler.SetOpacity(0)
+ filler.set_opacity(0)
filler = (get_step(src,EAST)) //Find new turf
- filler.SetOpacity(opacity)
+ filler.set_opacity(opacity)
else
bound_width = world.icon_size
bound_height = width * world.icon_size
- filler.SetOpacity(0)
+ filler.set_opacity(0)
filler = (get_step(src,NORTH)) //Find new turf
- filler.SetOpacity(opacity)
+ filler.set_opacity(opacity)
/obj/structure/machinery/door/morgue
diff --git a/code/game/machinery/doors/multi_tile.dm b/code/game/machinery/doors/multi_tile.dm
index 2a49b8696a9f..f58d50f3a8cf 100644
--- a/code/game/machinery/doors/multi_tile.dm
+++ b/code/game/machinery/doors/multi_tile.dm
@@ -235,11 +235,11 @@
//We have to find these again since these doors are used on shuttles a lot so the turfs changes
/obj/structure/machinery/door/airlock/multi_tile/almayer/proc/update_filler_turfs()
for(var/turf/T in multi_filler)
- T.SetOpacity(null)
+ T.set_opacity(null)
multi_filler = list()
for(var/turf/T in get_filler_turfs())
- T.SetOpacity(opacity)
+ T.set_opacity(opacity)
multi_filler += list(T)
/obj/structure/machinery/door/airlock/multi_tile/proc/get_filler_turfs()
diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm
index da6137e5e8cb..b2d836ee476f 100644
--- a/code/game/machinery/doors/poddoor.dm
+++ b/code/game/machinery/doors/poddoor.dm
@@ -16,9 +16,9 @@
/obj/structure/machinery/door/poddoor/Initialize()
. = ..()
if(density)
- SetOpacity(1)
+ set_opacity(1)
else
- SetOpacity(0)
+ set_opacity(0)
update_icon()
/obj/structure/machinery/door/poddoor/update_icon()
@@ -42,7 +42,7 @@
operating = 1
flick("[base_icon_state]c0", src)
icon_state = "[base_icon_state]0"
- SetOpacity(0)
+ set_opacity(0)
sleep(15)
density = FALSE
operating = 0
@@ -84,7 +84,7 @@
playsound(loc, 'sound/machines/blastdoor.ogg', 20, 0)
flick("[base_icon_state]c0", src)
icon_state = "[base_icon_state]0"
- SetOpacity(0)
+ set_opacity(0)
addtimer(CALLBACK(src, PROC_REF(finish_open)), openspeed)
return TRUE
@@ -102,7 +102,7 @@
flick("[base_icon_state]c1", src)
icon_state = "[base_icon_state]1"
density = TRUE
- SetOpacity(initial(opacity))
+ set_opacity(initial(opacity))
addtimer(CALLBACK(src, PROC_REF(finish_close)), openspeed)
return
@@ -123,13 +123,13 @@
/obj/structure/machinery/door/poddoor/two_tile/proc/start_opening()
flick("[base_icon_state]c0", src)
icon_state = "[base_icon_state]0"
- SetOpacity(0)
- f1.SetOpacity(0)
- f2.SetOpacity(0)
+ set_opacity(0)
+ f1.set_opacity(0)
+ f2.set_opacity(0)
/obj/structure/machinery/door/poddoor/two_tile/four_tile/start_opening()
- f3.SetOpacity(0)
- f4.SetOpacity(0)
+ f3.set_opacity(0)
+ f4.set_opacity(0)
..()
/obj/structure/machinery/door/poddoor/two_tile/proc/open_fully()
@@ -169,14 +169,14 @@
..()
/obj/structure/machinery/door/poddoor/two_tile/proc/close_fully()
- SetOpacity(initial(opacity))
- f1.SetOpacity(initial(opacity))
- f2.SetOpacity(initial(opacity))
+ set_opacity(initial(opacity))
+ f1.set_opacity(initial(opacity))
+ f2.set_opacity(initial(opacity))
operating = 0
/obj/structure/machinery/door/poddoor/two_tile/four_tile/close_fully()
- f3.SetOpacity(initial(opacity))
- f4.SetOpacity(initial(opacity))
+ f3.set_opacity(initial(opacity))
+ f4.set_opacity(initial(opacity))
..()
/obj/structure/machinery/door/poddoor/two_tile
@@ -194,8 +194,8 @@
f2 = new/obj/structure/machinery/door/poddoor/filler_object (get_step(src,dir))
f1.density = density
f2.density = density
- f1.SetOpacity(opacity)
- f2.SetOpacity(opacity)
+ f1.set_opacity(opacity)
+ f2.set_opacity(opacity)
/obj/structure/machinery/door/poddoor/two_tile/Destroy()
QDEL_NULL(f1)
@@ -223,8 +223,8 @@
f4 = new/obj/structure/machinery/door/poddoor/filler_object (get_step(f3,dir))
f3.density = density
f4.density = density
- f3.SetOpacity(opacity)
- f4.SetOpacity(opacity)
+ f3.set_opacity(opacity)
+ f4.set_opacity(opacity)
/obj/structure/machinery/door/poddoor/two_tile/four_tile/Destroy()
QDEL_NULL(f3)
diff --git a/code/game/machinery/doors/railing.dm b/code/game/machinery/doors/railing.dm
index 8449d5d52256..c86adb2e970b 100644
--- a/code/game/machinery/doors/railing.dm
+++ b/code/game/machinery/doors/railing.dm
@@ -22,7 +22,7 @@
if(density)//Allows preset-open to work
layer = closed_layer
- SetOpacity(initial(opacity))
+ set_opacity(initial(opacity))
/obj/structure/machinery/door/poddoor/railing/update_icon()
if(density)
diff --git a/code/game/machinery/doors/runed_sandstone.dm b/code/game/machinery/doors/runed_sandstone.dm
index d67398baa305..4bf66dfdc8d8 100644
--- a/code/game/machinery/doors/runed_sandstone.dm
+++ b/code/game/machinery/doors/runed_sandstone.dm
@@ -100,7 +100,7 @@
operating = TRUE
do_animate("opening")
icon_state = "door0"
- SetOpacity(FALSE)
+ set_opacity(0)
addtimer(CALLBACK(src, PROC_REF(finish_open)), openspeed)
return
@@ -109,9 +109,9 @@
layer = open_layer
density = FALSE
update_icon()
- SetOpacity(0)
+ set_opacity(0)
if(filler)
- filler.SetOpacity(opacity)
+ filler.set_opacity(opacity)
if(operating)
operating = FALSE
@@ -130,7 +130,7 @@
operating = TRUE
density = TRUE
- SetOpacity(TRUE)
+ set_opacity(1)
layer = closed_layer
do_animate("closing")
diff --git a/code/game/machinery/doors/shutters.dm b/code/game/machinery/doors/shutters.dm
index 39ecbd806e64..da904f255c40 100644
--- a/code/game/machinery/doors/shutters.dm
+++ b/code/game/machinery/doors/shutters.dm
@@ -26,7 +26,7 @@
icon_state = "[base_icon_state]0"
sleep(15)
density = FALSE
- SetOpacity(0)
+ set_opacity(0)
operating = 0
return
return
@@ -46,7 +46,7 @@
/obj/structure/machinery/door/poddoor/shutters/finish_open()
density = FALSE
layer = open_layer
- SetOpacity(0)
+ set_opacity(0)
if(operating) //emag again
operating = FALSE
@@ -63,7 +63,7 @@
layer = closed_layer
density = TRUE
if(visible)
- SetOpacity(1)
+ set_opacity(1)
playsound(loc, 'sound/machines/blastdoor.ogg', 25)
addtimer(CALLBACK(src, PROC_REF(finish_close)), openspeed)
diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm
index 556eab541363..75d0de56dec0 100644
--- a/code/game/machinery/flasher.dm
+++ b/code/game/machinery/flasher.dm
@@ -26,10 +26,10 @@
..()
if ( !(stat & NOPOWER) )
icon_state = "[base_state]1"
-// src.sd_SetLuminosity(2)
+// src.sd_set_light(2)
else
icon_state = "[base_state]1-p"
-// src.sd_SetLuminosity(0)
+// src.sd_set_light(0)
//Don't want to render prison breaks impossible
/obj/structure/machinery/flasher/attackby(obj/item/W as obj, mob/user as mob)
diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm
index 8eec83ed7b70..5f6cd02a4bf8 100644
--- a/code/game/machinery/floodlight.dm
+++ b/code/game/machinery/floodlight.dm
@@ -6,38 +6,40 @@
icon_state = "flood00"
density = TRUE
anchored = TRUE
- var/on = 0
var/obj/item/cell/cell = null
var/use = 0
var/unlocked = 0
var/open = 0
- var/brightness_on = 7 //can't remember what the maxed out value is
+ light_power = 2
unslashable = TRUE
unacidable = TRUE
+ var/on_light_range = 6
+
/obj/structure/machinery/floodlight/Initialize(mapload, ...)
. = ..()
cell = new /obj/item/cell(src)
+ if(light_on)
+ set_light(on_light_range)
/obj/structure/machinery/floodlight/Destroy()
QDEL_NULL(cell)
- SetLuminosity(0)
return ..()
+/obj/structure/machinery/floodlight/turn_light(mob/user, toggle_on)
+ . = ..()
+ if(. == NO_LIGHT_STATE_CHANGE)
+ return
+
+ if(toggle_on)
+ set_light(on_light_range)
+ else
+ set_light(0)
+
+
/obj/structure/machinery/floodlight/proc/updateicon()
- icon_state = "flood[open ? "o" : ""][open && cell ? "b" : ""]0[on]"
-/*
-/obj/structure/machinery/floodlight/process()
- if(on && cell)
- if(cell.charge >= use)
- cell.use(use)
- else
- on = 0
- updateicon()
- SetLuminosity(0)
- src.visible_message(SPAN_WARNING("[src] shuts down due to lack of power!"))
- return
-*/
+ icon_state = "flood[open ? "o" : ""][open && cell ? "b" : ""]0[light_on]"
+
/obj/structure/machinery/floodlight/attack_hand(mob/user as mob)
if(open && cell)
if(ishuman(user))
@@ -55,10 +57,9 @@
updateicon()
return
- if(on)
- on = 0
- to_chat(user, SPAN_NOTICE(" You turn off the light."))
- SetLuminosity(0)
+ if(light_on)
+ to_chat(user, SPAN_NOTICE("You turn off the light."))
+ turn_light(user, toggle_on = FALSE)
unslashable = TRUE
unacidable = TRUE
else
@@ -66,9 +67,8 @@
return
if(cell.charge <= 0)
return
- on = 1
- to_chat(user, SPAN_NOTICE(" You turn on the light."))
- SetLuminosity(brightness_on)
+ to_chat(user, SPAN_NOTICE("You turn on the light."))
+ turn_light(user, toggle_on = TRUE)
unacidable = FALSE
updateicon()
@@ -121,9 +121,8 @@
name = "Landing Light"
desc = "A powerful light stationed near landing zones to provide better visibility."
icon_state = "flood01"
- on = 1
+ light_on = TRUE
in_use = 1
- luminosity = 6
use_power = USE_POWER_NONE
/obj/structure/machinery/floodlight/landing/attack_hand()
diff --git a/code/game/machinery/groundmap_geothermal.dm b/code/game/machinery/groundmap_geothermal.dm
index 4be9c53f0094..808c717e8891 100644
--- a/code/game/machinery/groundmap_geothermal.dm
+++ b/code/game/machinery/groundmap_geothermal.dm
@@ -269,9 +269,9 @@
F.is_lit = !F.is_lit
if(!F.damaged)
if(F.is_lit) //Shut it down
- F.SetLuminosity(F.lum_value)
+ F.set_light(F.lum_value)
else
- F.SetLuminosity(0)
+ F.set_light(0)
F.update_icon()
return 0
@@ -315,7 +315,6 @@
health = 150
/obj/structure/machinery/colony_floodlight/Destroy()
- SetLuminosity(0)
if(fswitch)
fswitch.floodlist -= src
fswitch = null
@@ -362,7 +361,7 @@
user.visible_message(SPAN_NOTICE("[user] screws [src]'s maintenance hatch closed."), \
SPAN_NOTICE("You screw [src]'s maintenance hatch closed."))
if(is_lit)
- SetLuminosity(lum_value)
+ set_light(lum_value)
update_icon()
return TRUE
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 1acb47370d96..2f8f113ddd23 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -142,8 +142,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
hologram.anchored = TRUE//So space wind cannot drag it.
hologram.name = "[A.name] (Hologram)"//If someone decides to right click.
- hologram.SetLuminosity(2) //hologram lighting
- SetLuminosity(2) //pad lighting
+ hologram.set_light(2) //hologram lighting
+ set_light(2) //pad lighting
icon_state = "holopad1"
A.holo = src
master = A//AI is the master.
@@ -151,14 +151,14 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
return 1
/obj/structure/machinery/hologram/holopad/clear_holo()
-// hologram.SetLuminosity(0)//Clear lighting. //handled by the lighting controller when its ower is deleted
+// hologram.set_light(0)//Clear lighting. //handled by the lighting controller when its ower is deleted
if(hologram)
qdel(hologram)//Get rid of hologram.
hologram = null
if(master.holo == src)
master.holo = null
master = null//Null the master, since no-one is using it now.
- SetLuminosity(0) //pad lighting (hologram lighting will be handled automatically since its owner was deleted)
+ set_light(0) //pad lighting (hologram lighting will be handled automatically since its owner was deleted)
icon_state = "holopad0"
use_power = USE_POWER_IDLE//Passive power usage.
return 1
@@ -175,7 +175,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
var/area/holo_area = get_area(src)
var/area/eye_area = get_area(master.eyeobj)
- if(eye_area in holo_area.master.related)
+ if(eye_area == holo_area)
return 1
clear_holo()//If not, we want to get rid of the hologram.
diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm
index 5564ed0220a7..33f75c50e341 100644
--- a/code/game/machinery/igniter.dm
+++ b/code/game/machinery/igniter.dm
@@ -60,10 +60,10 @@
if ( !(stat & NOPOWER) && disable == 0 )
icon_state = "[base_state]"
-// src.sd_SetLuminosity(2)
+// src.sd_set_light(2)
else
icon_state = "[base_state]-p"
-// src.sd_SetLuminosity(0)
+// src.sd_set_light(0)
/obj/structure/machinery/sparker/attackby(obj/item/W as obj, mob/user as mob)
if (HAS_TRAIT(W, TRAIT_TOOL_SCREWDRIVER))
diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm
index ae57f27f2162..66eb0386713f 100644
--- a/code/game/machinery/lightswitch.dm
+++ b/code/game/machinery/lightswitch.dm
@@ -10,7 +10,6 @@
var/on = 1
var/area/area = null
var/otherarea = null
- // luminosity = 1
/obj/structure/machinery/light_switch/Initialize()
. = ..()
@@ -43,15 +42,14 @@
/obj/structure/machinery/light_switch/attack_hand(mob/user)
on = !on
- for(var/area/A in area.master.related)
- A.lightswitch = on
- A.updateicon()
+ area.lightswitch = on
+ area.updateicon()
- for(var/obj/structure/machinery/light_switch/L in A)
- L.on = on
- L.updateicon()
+ for(var/obj/structure/machinery/light_switch/L in area)
+ L.on = on
+ L.updateicon()
- area.master.power_change()
+ area.power_change()
/obj/structure/machinery/light_switch/power_change()
diff --git a/code/game/machinery/mining.dm b/code/game/machinery/mining.dm
index 4f663c5fbca7..0662817174fc 100644
--- a/code/game/machinery/mining.dm
+++ b/code/game/machinery/mining.dm
@@ -26,4 +26,4 @@
icon_state = "furnace"
density = TRUE
anchored = TRUE
- luminosity = 3
+ light_range = 3
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index ad8f5a189267..89c9e9277f4c 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -93,7 +93,6 @@ var/list/obj/structure/machinery/newscaster/allCasters = list() //Global list th
var/c_locked=0; //Will our new channel be locked to public submissions?
var/hitstaken = 0 //Death at 3 hits from an item with force>=15
var/datum/feed_channel/viewing_channel = null
- luminosity = 0
anchored = TRUE
@@ -111,7 +110,6 @@ var/list/obj/structure/machinery/newscaster/allCasters = list() //Global list th
/obj/structure/machinery/newscaster/security_unit/Destroy()
allCasters -= src
- SetLuminosity(0)
return ..()
/obj/structure/machinery/newscaster/update_icon()
diff --git a/code/game/machinery/vending/vendor_types/antag/antag_gear.dm b/code/game/machinery/vending/vendor_types/antag/antag_gear.dm
index c2b27dc91ef1..84cd4a8bcec0 100644
--- a/code/game/machinery/vending/vendor_types/antag/antag_gear.dm
+++ b/code/game/machinery/vending/vendor_types/antag/antag_gear.dm
@@ -49,9 +49,9 @@
/obj/effect/essentials_set/upp_heavy
spawned_gear_list = list(
- /obj/item/weapon/gun/minigun/upp,
- /obj/item/ammo_magazine/minigun,
- /obj/item/ammo_magazine/minigun,
+ /obj/item/weapon/gun/pkp,
+ /obj/item/ammo_magazine/pkp,
+ /obj/item/ammo_magazine/pkp,
)
/obj/effect/essentials_set/leader/upp
diff --git a/code/game/machinery/vending/vendor_types/crew/vehicle_crew.dm b/code/game/machinery/vending/vendor_types/crew/vehicle_crew.dm
index fb9b662be1bc..891a2a907b39 100644
--- a/code/game/machinery/vending/vendor_types/crew/vehicle_crew.dm
+++ b/code/game/machinery/vending/vendor_types/crew/vehicle_crew.dm
@@ -306,7 +306,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_vehicle_crew, list(
list("Gloves", 0, /obj/item/clothing/gloves/yellow, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
list("Tanker Armor", 0, /obj/item/clothing/suit/storage/marine/tanker, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("M50 Tanker Helmet", 0, /obj/item/clothing/head/helmet/marine/tech/tanker, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
- list("SensorMate HUD", 0, /obj/item/clothing/glasses/hud/sensor, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_MANDATORY),
+ list("Medical Helmet Optic", 0, /obj/item/device/helmet_visor/medical, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_MANDATORY),
list("Welding Kit", 0, /obj/item/tool/weldpack, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY),
list("MRE", 0, /obj/item/storage/box/MRE, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
diff --git a/code/game/machinery/vending/vendor_types/intelligence_officer.dm b/code/game/machinery/vending/vendor_types/intelligence_officer.dm
index a2afe897b495..ab38fcb1dfeb 100644
--- a/code/game/machinery/vending/vendor_types/intelligence_officer.dm
+++ b/code/game/machinery/vending/vendor_types/intelligence_officer.dm
@@ -14,8 +14,9 @@ GLOBAL_LIST_INIT(cm_vending_gear_intelligence_officer, list(
list("Fulton Recovery Device", 10, /obj/item/stack/fulton, null, VENDOR_ITEM_REGULAR),
list("Motion Detector", 15, /obj/item/device/motiondetector, null, VENDOR_ITEM_RECOMMENDED),
list("Plastic Explosive", 10, /obj/item/explosive/plastic, null, VENDOR_ITEM_REGULAR),
+ list("Welding Visor", 5, /obj/item/device/helmet_visor/welding_visor, null, VENDOR_ITEM_REGULAR),
+ list("Medical Helmet Optic", 5, /obj/item/device/helmet_visor/medical, null, VENDOR_ITEM_REGULAR),
list("Welding Goggles", 5, /obj/item/clothing/glasses/welding, null, VENDOR_ITEM_REGULAR),
- list("Sensor Medical HUD", 5, /obj/item/clothing/glasses/hud/sensor, null, VENDOR_ITEM_REGULAR),
list("POUCHES", 0, null, null, null),
list("Large Magazine Pouch", 10, /obj/item/storage/pouch/magazine/large, null, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm
index faff01f7f299..d43e53db4f0d 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm
@@ -54,7 +54,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_engi, list(
list("M56D Heavy Machine Gun", 24, /obj/item/storage/box/guncase/m56d, null, VENDOR_ITEM_REGULAR),
list("UTILITIES", 0, null, null, null),
- list("SensorMate Medical HUD", 12, /obj/item/clothing/glasses/hud/sensor, null, VENDOR_ITEM_REGULAR),
+ list("Medical Helmet Optic", 12, /obj/item/device/helmet_visor/medical, null, VENDOR_ITEM_REGULAR),
list("Roller Bed", 5, /obj/item/roller, null, VENDOR_ITEM_REGULAR),
list("Fulton Device Stack", 5, /obj/item/stack/fulton, null, VENDOR_ITEM_REGULAR),
list("M3 B12 Pattern Armor", 24, /obj/item/clothing/suit/storage/marine/leader, null, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm
index 9757576e6d0b..935469b13b47 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm
@@ -67,7 +67,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_leader, list(
list("Injector (Tricord)", 1, /obj/item/reagent_container/hypospray/autoinjector/tricord, null, VENDOR_ITEM_REGULAR),
list("Health Analyzer", 4, /obj/item/device/healthanalyzer, null, VENDOR_ITEM_REGULAR),
- list("SensorMate Medical HUD", 4, /obj/item/clothing/glasses/hud/sensor, null, VENDOR_ITEM_RECOMMENDED),
+ list("Medical Helmet Optic", 4, /obj/item/device/helmet_visor/medical, null, VENDOR_ITEM_RECOMMENDED),
list("Roller Bed", 2, /obj/item/roller, null, VENDOR_ITEM_REGULAR),
list("SPECIAL AMMUNITION", 0, null, null, null),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm
index 7c9682985298..d2ba88096131 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm
@@ -42,7 +42,6 @@ GLOBAL_LIST_INIT(cm_vending_gear_medic, list(
list("MEDICAL UTILITIES", 0, null, null, null),
list("Health Analyzer", 4, /obj/item/device/healthanalyzer, null, VENDOR_ITEM_REGULAR),
- list("Medical HUD Glasses", 4, /obj/item/clothing/glasses/hud/health, null, VENDOR_ITEM_REGULAR),
list("Roller Bed", 4, /obj/item/roller, null, VENDOR_ITEM_REGULAR),
list("Stasis Bag", 6, /obj/item/bodybag/cryobag, null, VENDOR_ITEM_REGULAR),
list("Pressurized Reagent Canister Pouch (EMPTY)", 3, /obj/item/storage/pouch/pressurized_reagent_canister, null, VENDOR_ITEM_REGULAR),
@@ -110,7 +109,6 @@ GLOBAL_LIST_INIT(cm_vending_clothing_medic, list(
list("Boots", 0, /obj/item/clothing/shoes/marine/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
list("Uniform", 0, /obj/item/clothing/under/marine/medic, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY),
list("Gloves", 0, /obj/item/clothing/gloves/marine, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
- list("Medical HUD Glasses", 0, /obj/item/clothing/glasses/hud/health, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_MANDATORY),
list("Headset", 0, /obj/item/device/radio/headset/almayer/marine, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
list("Helmet", 0, /obj/item/clothing/head/helmet/marine/medic, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
list("MRE", 0, /obj/item/storage/box/MRE, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm
index d92eaabf52c1..09881536901e 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm
@@ -76,7 +76,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_marine, list(
list("Brown Webbing Vest", 15, /obj/item/clothing/accessory/storage/black_vest/brown_vest, null, VENDOR_ITEM_REGULAR),
list("Black Webbing Vest", 15, /obj/item/clothing/accessory/storage/black_vest, null, VENDOR_ITEM_REGULAR),
list("Drop Pouch", 15, /obj/item/clothing/accessory/storage/droppouch, null, VENDOR_ITEM_REGULAR),
- list("SensorMate Medical HUD", 15, /obj/item/clothing/glasses/hud/sensor, null, VENDOR_ITEM_REGULAR),
+ list("Medical Helmet Optic", 15, /obj/item/device/helmet_visor/medical, null, VENDOR_ITEM_REGULAR),
list("Roller Bed", 5, /obj/item/roller, null, VENDOR_ITEM_REGULAR),
list("Fulton Device Stack", 5, /obj/item/stack/fulton, null, VENDOR_ITEM_REGULAR),
list("B12 Pattern Marine Armor", 30, /obj/item/clothing/suit/storage/marine/leader, null, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_smartgunner.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_smartgunner.dm
index 5560508ca4c1..d3a606ae6b41 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_smartgunner.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_smartgunner.dm
@@ -34,6 +34,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_smartgun, list(
list("Powerloader Certification", 45, /obj/item/pamphlet/skill/powerloader, null, VENDOR_ITEM_REGULAR),
list("Roller Bed", 5, /obj/item/roller, null, VENDOR_ITEM_REGULAR),
list("Fulton Device Stack", 5, /obj/item/stack/fulton, null, VENDOR_ITEM_REGULAR),
+ list("Medical Helmet Optic", 15, /obj/item/device/helmet_visor/medical, null, VENDOR_ITEM_REGULAR),
list("RADIO KEYS", 0, null, null, null),
list("Engineering Radio Encryption Key", 5, /obj/item/device/encryptionkey/engi, null, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm
index e0900c3fd3c8..b09ae4aa15c5 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm
@@ -38,7 +38,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_spec, list(
list("UTILITIES", 0, null, null, null),
list("Fire Extinguisher (Portable)", 5, /obj/item/tool/extinguisher/mini, null, VENDOR_ITEM_REGULAR),
- list("SensorMate Medical HUD", 15, /obj/item/clothing/glasses/hud/sensor, null, VENDOR_ITEM_REGULAR),
+ list("Medical Helmet Optic", 15, /obj/item/device/helmet_visor/medical, null, VENDOR_ITEM_REGULAR),
list("Roller Bed", 5, /obj/item/roller, null, VENDOR_ITEM_REGULAR),
list("Fulton Device Stack", 5, /obj/item/stack/fulton, null, VENDOR_ITEM_REGULAR),
list("Fuel Tank Strap Pouch", 5, /obj/item/storage/pouch/flamertank, null, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm
index ceef80ab6952..4f64ca7e81fa 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm
@@ -35,7 +35,9 @@ GLOBAL_LIST_INIT(cm_vending_gear_tl, list(
list("Motion Detector", 15, /obj/item/device/motiondetector, null, VENDOR_ITEM_RECOMMENDED),
list("Plastic Explosive", 10, /obj/item/explosive/plastic, null, VENDOR_ITEM_REGULAR),
list("Breaching Charge", 10, /obj/item/explosive/plastic/breaching_charge, null, VENDOR_ITEM_REGULAR),
- list("SensorMate Medical HUD", 15, /obj/item/clothing/glasses/hud/sensor, null, VENDOR_ITEM_REGULAR),
+ list("Welding Visor", 5, /obj/item/device/helmet_visor/welding_visor, null, VENDOR_ITEM_REGULAR),
+ list("Medical Helmet Optic", 15, /obj/item/device/helmet_visor/medical, null, VENDOR_ITEM_REGULAR),
+ list("Welding Goggles", 5, /obj/item/clothing/glasses/welding, null, VENDOR_ITEM_REGULAR),
list("M2 Night Vision Goggles", 30, /obj/item/prop/helmetgarb/helmet_nvg, null, VENDOR_ITEM_RECOMMENDED),
list("Roller Bed", 5, /obj/item/roller, null, VENDOR_ITEM_REGULAR),
list("Fulton Device Stack", 5, /obj/item/stack/fulton, null, VENDOR_ITEM_REGULAR),
@@ -44,7 +46,6 @@ GLOBAL_LIST_INIT(cm_vending_gear_tl, list(
list("Machete Pouch (Full)", 15, /obj/item/storage/pouch/machete/full, null, VENDOR_ITEM_REGULAR),
list("Fire Extinguisher (Portable)", 5, /obj/item/tool/extinguisher/mini, null, VENDOR_ITEM_REGULAR),
list("Whistle", 5, /obj/item/device/whistle, null, VENDOR_ITEM_REGULAR),
- list("Welding Goggles", 5, /obj/item/clothing/glasses/welding, null, VENDOR_ITEM_REGULAR),
list("Powerloader Certification", 45, /obj/item/pamphlet/skill/powerloader, null, VENDOR_ITEM_REGULAR),
list("Insulated Gloves", 3, /obj/item/clothing/gloves/yellow, null, VENDOR_ITEM_REGULAR),
diff --git a/code/game/objects/effects/acid_hole.dm b/code/game/objects/effects/acid_hole.dm
index 549ab45953d2..415df0e7e5a7 100644
--- a/code/game/objects/effects/acid_hole.dm
+++ b/code/game/objects/effects/acid_hole.dm
@@ -165,7 +165,7 @@
F.forceMove(Target)
F.setDir(pick(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
step_away(F,src,rand(1,5))
- F.SetLuminosity(0)
+ F.set_light(0)
if(F.on && loc != user)
- F.SetLuminosity(F.brightness_on)
+ F.set_light_on(F.on)
return
diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm
index b94ee6902321..49d758b52b19 100644
--- a/code/game/objects/effects/aliens.dm
+++ b/code/game/objects/effects/aliens.dm
@@ -332,7 +332,7 @@
if(!acids_area)
return
- if(SSweather.is_weather_event && locate(acids_area.master) in SSweather.weather_areas)
+ if(SSweather.is_weather_event && locate(acids_area) in SSweather.weather_areas)
acid_strength = acid_strength + (SSweather.weather_event_instance.fire_smothering_strength * 0.33) //smothering_strength is 1-10, acid strength is a multiplier
in_weather = SSweather.weather_event_instance.fire_smothering_strength
else
diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm
index 43c3500813a4..9cf2aa3d8e09 100644
--- a/code/game/objects/effects/decals/cleanable/misc.dm
+++ b/code/game/objects/effects/decals/cleanable/misc.dm
@@ -35,12 +35,8 @@
name = "glowing goo"
acid_damage = 1
icon_state = "greenglow"
- luminosity = 1
-
-/obj/effect/decal/cleanable/dirt/greenglow/Destroy()
- SetLuminosity(0)
- return ..()
-
+ light_range = 1
+ light_color = COLOUR_GREEN
/obj/effect/decal/cleanable/flour
name = "flour"
desc = "It's still good. Four second rule!"
@@ -58,7 +54,8 @@
density = FALSE
anchored = TRUE
layer = TURF_LAYER
- luminosity = 1
+ light_range = 1
+ light_color = COLOUR_GREEN
icon = 'icons/effects/effects.dmi'
icon_state = "greenglow"
@@ -68,10 +65,6 @@
. = ..()
QDEL_IN(WEAKREF(src), 2 MINUTES)
-/obj/effect/decal/cleanable/greenglow/Destroy()
- SetLuminosity(0)
- return ..()
-
/obj/effect/decal/cleanable/cobweb
name = "cobweb"
desc = "Somebody should remove that."
diff --git a/code/game/objects/effects/effect_system/chemsmoke.dm b/code/game/objects/effects/effect_system/chemsmoke.dm
index c2323c32c934..eeb17f7c98d0 100644
--- a/code/game/objects/effects/effect_system/chemsmoke.dm
+++ b/code/game/objects/effects/effect_system/chemsmoke.dm
@@ -199,10 +199,10 @@
smoke.pixel_x = -32 + rand(-8,8)
smoke.pixel_y = -32 + rand(-8,8)
walk_to(smoke, T)
- smoke.SetOpacity(1) //switching opacity on after the smoke has spawned, and then
+ smoke.set_opacity(1) //switching opacity on after the smoke has spawned, and then
sleep(150+rand(0,20)) // turning it off before it is deleted results in cleaner
if(smoke.opacity)
- smoke.SetOpacity(0)
+ smoke.set_opacity(0)
fadeOut(smoke)
qdel(smoke)
diff --git a/code/game/objects/effects/effect_system/smoke.dm b/code/game/objects/effects/effect_system/smoke.dm
index 2eb36930c542..da388b1be1e4 100644
--- a/code/game/objects/effects/effect_system/smoke.dm
+++ b/code/game/objects/effects/effect_system/smoke.dm
@@ -36,7 +36,7 @@
/obj/effect/particle_effect/smoke/Destroy()
. = ..()
if(opacity)
- SetOpacity(0)
+ set_opacity(0)
active_smoke_effects -= src
cause_data = null
@@ -53,7 +53,7 @@
else if(time_to_live == 1)
alpha = 180
amount = 0
- SetOpacity(0)
+ set_opacity(0)
apply_smoke_effect(get_turf(src))
diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm
index e54607d6f930..bebe0ec8b27f 100644
--- a/code/game/objects/effects/glowshroom.dm
+++ b/code/game/objects/effects/glowshroom.dm
@@ -39,13 +39,9 @@
else //if on the floor, glowshroom on-floor sprite
icon_state = "glowshroomf"
- SetLuminosity(round(potency/15))
+ set_light(round(potency/15))
lastTick = world.timeofday
-/obj/effect/glowshroom/Destroy()
- SetLuminosity(0)
- . = ..()
-
/obj/effect/glowshroom/proc/CalcDir(turf/location = loc)
set background = 1
var/direction = 16
diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm
index d4cd293030c2..16f30eaf0fd2 100644
--- a/code/game/objects/effects/overlays.dm
+++ b/code/game/objects/effects/overlays.dm
@@ -145,7 +145,7 @@
name = "laser"
anchored = TRUE
mouse_opacity = MOUSE_OPACITY_ICON
- luminosity = 2
+ light_range = 2
icon = 'icons/obj/items/weapons/projectiles.dmi'
icon_state = "laser_target_coordinate"
effect_duration = 600
@@ -156,14 +156,13 @@
source_binoc.laser_cooldown = world.time + source_binoc.cooldown_duration
source_binoc.coord = null
source_binoc = null
- SetLuminosity(0)
. = ..()
/obj/effect/overlay/temp/laser_target
name = "laser"
anchored = TRUE
mouse_opacity = MOUSE_OPACITY_ICON
- luminosity = 2
+ light_range = 2
icon = 'icons/obj/items/weapons/projectiles.dmi'
icon_state = "laser_target2"
effect_duration = 600
@@ -198,7 +197,6 @@
source_binoc.laser = null
source_binoc = null
- SetLuminosity(0)
. = ..()
/obj/effect/overlay/temp/laser_target/ex_act(severity) //immune to explosions
@@ -214,16 +212,12 @@
/obj/effect/overlay/temp/blinking_laser
name = "blinking laser"
anchored = TRUE
- luminosity = 2
+ light_range = 2
effect_duration = 10
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
icon = 'icons/obj/items/weapons/projectiles.dmi'
icon_state = "laser_target3"
-/obj/effect/overlay/temp/blinking_laser/Destroy()
- SetLuminosity(0)
- . = ..()
-
/obj/effect/overlay/temp/emp_sparks
icon = 'icons/effects/effects.dmi'
icon_state = "empdisable"
diff --git a/code/game/objects/effects/spawners/random.dm b/code/game/objects/effects/spawners/random.dm
index 4d5bf88b9e6c..77390d533c9e 100644
--- a/code/game/objects/effects/spawners/random.dm
+++ b/code/game/objects/effects/spawners/random.dm
@@ -400,7 +400,6 @@
/obj/item/weapon/gun/revolver/small = /obj/item/ammo_magazine/revolver/small,
/obj/item/weapon/gun/pistol/heavy = /obj/item/ammo_magazine/pistol/heavy,
/obj/item/weapon/gun/pistol/skorpion = /obj/item/ammo_magazine/pistol/skorpion,
- /obj/item/weapon/gun/pistol/skorpion/upp = /obj/item/ammo_magazine/pistol/skorpion,
)
/obj/effect/spawner/random/gun/pistol/lowchance
@@ -494,7 +493,7 @@
/obj/item/weapon/gun/smg/mp27 = /obj/item/ammo_magazine/smg/mp27,
/obj/item/weapon/gun/smg/mp27 = /obj/item/ammo_magazine/smg/mp27,
/obj/item/weapon/gun/smg/mp27 = /obj/item/ammo_magazine/smg/mp27,
- /obj/item/weapon/gun/smg/ppsh = /obj/item/ammo_magazine/smg/ppsh,
+ /obj/item/weapon/gun/smg/pps43 = /obj/item/ammo_magazine/smg/pps43,
/obj/item/weapon/gun/smg/mac15 = /obj/item/ammo_magazine/smg/mac15,
/obj/item/weapon/gun/smg/mac15 = /obj/item/ammo_magazine/smg/mac15,
/obj/item/weapon/gun/smg/uzi = /obj/item/ammo_magazine/smg/uzi,
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index dd5e99545d11..453c2ef1d9d7 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -2,6 +2,8 @@
name = "item"
icon = 'icons/obj/items/items.dmi'
mouse_drag_pointer = MOUSE_ACTIVE_POINTER
+ light_system = MOVABLE_LIGHT
+
/// this saves our blood splatter overlay, which will be processed not to go over the edges of the sprite
var/image/blood_overlay = null
var/randpixel = 6
@@ -829,6 +831,7 @@ cases. Override_icon_state should be a list.*/
UnregisterSignal(src, list(
COMSIG_ITEM_DROPPED,
COMSIG_ITEM_UNWIELD,
+ COMSIG_PARENT_QDELETING,
))
UnregisterSignal(user, COMSIG_MOB_MOVE_OR_LOOK)
//General reset in case anything goes wrong, the view will always reset to default unless zooming in.
@@ -861,6 +864,7 @@ cases. Override_icon_state should be a list.*/
RegisterSignal(src, list(
COMSIG_ITEM_DROPPED,
COMSIG_ITEM_UNWIELD,
+ COMSIG_PARENT_QDELETING,
), PROC_REF(unzoom_dropped_callback))
RegisterSignal(user, COMSIG_MOB_MOVE_OR_LOOK, PROC_REF(zoom_handle_mob_move_or_look))
diff --git a/code/game/objects/items/devices/cictablet.dm b/code/game/objects/items/devices/cictablet.dm
index b2707a20aa90..fc9bb015ece0 100644
--- a/code/game/objects/items/devices/cictablet.dm
+++ b/code/game/objects/items/devices/cictablet.dm
@@ -160,7 +160,7 @@
for(var/client/C in GLOB.admins)
if((R_ADMIN|R_MOD) & C.admin_holder.rights)
playsound_client(C,'sound/effects/sos-morse-code.ogg',10)
- message_admins("[key_name(usr)] has requested a Distress Beacon! [CC_MARK(usr)] (SEND) (DENY) [ADMIN_JMP_USER(usr)] [CC_REPLY(usr)]")
+ SSticker.mode.request_ert(usr)
to_chat(usr, SPAN_NOTICE("A distress beacon request has been sent to USCM Central Command."))
COOLDOWN_START(src, distress_cooldown, COOLDOWN_COMM_REQUEST)
return TRUE
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index 9bcda4a82bbb..6795f8b436dc 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -10,9 +10,11 @@
matter = list("metal" = 50,"glass" = 20)
+ light_range = 5
+ light_power = 1
+
actions_types = list(/datum/action/item_action)
var/on = FALSE
- var/brightness_on = 5 //luminosity when on
var/raillight_compatible = TRUE //Can this be turned into a rail light ?
var/toggleable = TRUE
@@ -22,6 +24,7 @@
/obj/item/device/flashlight/Initialize()
. = ..()
update_icon()
+ set_light_on(on)
/obj/item/device/flashlight/update_icon()
. = ..()
@@ -30,27 +33,13 @@
else
icon_state = initial(icon_state)
-/obj/item/device/flashlight/Destroy()
- if(on)
- if(ismob(src.loc))
- src.loc.SetLuminosity(0, FALSE, src)
- else
- SetLuminosity(0)
- . = ..()
-
/obj/item/device/flashlight/proc/update_brightness(mob/user = null)
if(on)
+ set_light_range(light_range)
+ set_light_on(TRUE)
update_icon()
- if(loc && loc == user)
- user.SetLuminosity(brightness_on, FALSE, src)
- else if(isturf(loc))
- SetLuminosity(brightness_on)
else
- icon_state = initial(icon_state)
- if(loc && loc == user)
- user.SetLuminosity(0, FALSE, src)
- else if(isturf(loc))
- SetLuminosity(0)
+ set_light_on(FALSE)
/obj/item/device/flashlight/attack_self(mob/user)
..()
@@ -64,7 +53,8 @@
return FALSE
on = !on
- update_brightness(user)
+ set_light_on(on)
+ update_icon()
for(var/X in actions)
var/datum/action/A = X
A.update_button_icon()
@@ -73,8 +63,8 @@
/obj/item/device/flashlight/proc/turn_off_light(mob/bearer)
if(on)
- on = 0
- update_brightness(bearer)
+ on = FALSE
+ set_light_on(on)
for(var/X in actions)
var/datum/action/A = X
A.update_button_icon()
@@ -142,21 +132,7 @@
if(on && can_be_broken)
if(breaking_sound)
playsound(src.loc, breaking_sound, 25, 1)
- on = FALSE
- update_brightness()
-
-/obj/item/device/flashlight/pickup(mob/user)
- if(on)
- user.SetLuminosity(brightness_on, FALSE, src)
- SetLuminosity(0)
- ..()
-
-
-/obj/item/device/flashlight/dropped(mob/user)
- if(on && src.loc != user)
- user.SetLuminosity(0, FALSE, src)
- SetLuminosity(brightness_on)
- ..()
+ turn_off_light()
/obj/item/device/flashlight/on
on = TRUE
@@ -167,7 +143,7 @@
icon_state = "penlight"
item_state = ""
flags_atom = FPRINT|CONDUCT
- brightness_on = 2
+ light_range = 2
w_class = SIZE_TINY
raillight_compatible = 0
@@ -176,7 +152,7 @@
desc = "A miniature lamp, that might be used by small robots."
icon_state = "penlight"
item_state = ""
- brightness_on = 2
+ light_range = 2
w_class = SIZE_TINY
raillight_compatible = 0
@@ -186,23 +162,15 @@
desc = "A desk lamp with an adjustable mount."
icon_state = "lamp"
item_state = "lamp"
- brightness_on = 5
+ light_range = 5
w_class = SIZE_LARGE
on = 0
raillight_compatible = 0
breaking_sound = 'sound/effects/Glasshit.ogg'
-/obj/item/device/flashlight/lamp/Initialize()
- . = ..()
-
- if(on)
- update_brightness()
-
-/obj/item/device/flashlight/lamp/on/Initialize() //unused, but im leaving it here anyways :D
- . = ..()
- on = 1
- update_brightness()
+/obj/item/device/flashlight/lamp/on
+ on = TRUE
//Menorah!
/obj/item/device/flashlight/lamp/menorah
@@ -210,7 +178,7 @@
desc = "For celebrating Chanukah."
icon_state = "menorah"
item_state = "menorah"
- brightness_on = 2
+ light_range = 2
w_class = SIZE_LARGE
on = 1
breaking_sound = null
@@ -230,13 +198,13 @@
desc = "A classic green-shaded desk lamp."
icon_state = "lampgreen"
item_state = "lampgreen"
- brightness_on = 5
+ light_range = 5
/obj/item/device/flashlight/lamp/tripod
name = "tripod lamp"
desc = "An emergency light tube mounted onto a tripod. It seemingly lasts forever."
icon_state = "tripod_lamp"
- brightness_on = 6//pretty good
+ light_range = 6//pretty good
w_class = SIZE_LARGE
on = 1
@@ -261,7 +229,8 @@
name = "flare"
desc = "A red USCM issued flare. There are instructions on the side, it reads 'pull cord, make light'."
w_class = SIZE_SMALL
- brightness_on = 5 //As bright as a flashlight, but more disposable. Doesn't burn forever though
+ light_power = 2
+ light_range = 7
icon_state = "flare"
item_state = "flare"
actions = list() //just pull it manually, neckbeard.
@@ -287,6 +256,7 @@
/obj/item/device/flashlight/flare/Initialize()
. = ..()
fuel = rand(9.5 MINUTES, 10.5 MINUTES)
+ set_light_color(flame_tint)
/obj/item/device/flashlight/flare/update_icon()
overlays?.Cut()
@@ -353,7 +323,7 @@
START_PROCESSING(SSobj, src)
/obj/item/device/flashlight/flare/proc/turn_off()
- on = 0
+ on = FALSE
heat_source = 0
force = initial(force)
damtype = initial(damtype)
@@ -401,7 +371,6 @@
/// Flares deployed by a flare gun
/obj/item/device/flashlight/flare/on/gun
- brightness_on = 7
//Special flare subtype for the illumination flare shell
//Acts like a flare, just even stronger, and set length
@@ -409,9 +378,7 @@
name = "illumination flare"
desc = "It's really bright, and unreachable."
icon_state = "" //No sprite
- invisibility = 101 //Can't be seen or found, it's "up in the sky"
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
- brightness_on = 7 //Way brighter than most lights
show_flame = FALSE
/obj/item/device/flashlight/flare/on/illumination/Initialize()
@@ -432,7 +399,6 @@
name = "burning star shell ash"
desc = "Bright burning ash from a Star Shell 40mm. Don't touch, or it'll burn ya'."
icon_state = "starshell_ash"
- brightness_on = 7
anchored = TRUE//can't be picked up
ammo_datum = /datum/ammo/flare/starshell
show_flame = FALSE
@@ -445,14 +411,14 @@
/obj/item/device/flashlight/flare/on/illumination/chemical
name = "chemical light"
- brightness_on = 0
+ light_range = 0
/obj/item/device/flashlight/flare/on/illumination/chemical/Initialize(mapload, amount)
. = ..()
- brightness_on = round(amount * 0.04)
- if(!brightness_on)
+ light_range = round(amount * 0.04)
+ if(!light_range)
return INITIALIZE_HINT_QDEL
- SetLuminosity(brightness_on)
+ set_light(light_range)
fuel = amount * 5 SECONDS
/obj/item/device/flashlight/slime
@@ -464,7 +430,7 @@
icon_state = "floor1"
item_state = "slime"
w_class = SIZE_TINY
- brightness_on = 6
+ light_range = 6
// Bio-luminesence has one setting, on.
on = TRUE
raillight_compatible = FALSE
@@ -473,7 +439,7 @@
/obj/item/device/flashlight/slime/Initialize()
. = ..()
- SetLuminosity(brightness_on)
+ set_light(light_range)
update_brightness()
icon_state = initial(icon_state)
@@ -483,7 +449,7 @@
name = "lantern"
icon_state = "lantern"
desc = "A mining lantern."
- brightness_on = 6 // luminosity when on
+ light_range = 6 // luminosity when on
//Signal Flare
/obj/item/device/flashlight/flare/signal
diff --git a/code/game/objects/items/devices/helmet_visors.dm b/code/game/objects/items/devices/helmet_visors.dm
new file mode 100644
index 000000000000..dd913daf7620
--- /dev/null
+++ b/code/game/objects/items/devices/helmet_visors.dm
@@ -0,0 +1,98 @@
+/obj/item/device/helmet_visor
+ name = "squad optic"
+ desc = "An insertable visor HUD into a standard USCM helmet."
+ icon = 'icons/obj/items/clothing/helmet_visors.dmi'
+ icon_state = "hud_sight"
+ w_class = SIZE_TINY
+
+ ///The type of HUD our visor shows
+ var/hud_type = MOB_HUD_FACTION_USCM
+
+ ///The sound when toggling on the visor
+ var/toggle_on_sound = 'sound/handling/hud_on.ogg'
+
+ ///The sound when toggling off the visor
+ var/toggle_off_sound = 'sound/handling/hud_off.ogg'
+
+ ///The icon name for our helmet's action
+ var/action_icon_string = "hud_sight_down"
+
+ ///The overlay name for when our visor is active
+ var/helmet_overlay = "hud_sight_right"
+
+/// Called to see if the user can even use this visor
+/obj/item/device/helmet_visor/proc/can_toggle(mob/living/carbon/human/user)
+ return TRUE
+
+/// Called to see if this visor is a special non-HUD visor
+/obj/item/device/helmet_visor/proc/visor_function(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user, silent = FALSE)
+ if(attached_helmet == user.head && attached_helmet.active_visor == src)
+ var/datum/mob_hud/current_mob_hud = huds[hud_type]
+ current_mob_hud.add_hud_to(user, attached_helmet)
+ if(!silent)
+ to_chat(user, SPAN_NOTICE("You activate [src] on [attached_helmet]."))
+ return TRUE
+
+ var/datum/mob_hud/current_mob_hud = huds[hud_type]
+ current_mob_hud.remove_hud_from(user, attached_helmet)
+ if(!silent)
+ to_chat(user, SPAN_NOTICE("You deactivate [src] on [attached_helmet]."))
+ return TRUE
+
+/obj/item/device/helmet_visor/medical
+ name = "basic medical optic"
+ icon_state = "med_sight"
+ hud_type = MOB_HUD_MEDICAL_ADVANCED
+ action_icon_string = "med_sight_down"
+ helmet_overlay = "med_sight_right"
+
+/obj/item/device/helmet_visor/medical/advanced
+ name = "advanced medical optic"
+ helmet_overlay = "med_sight_left"
+
+/obj/item/device/helmet_visor/medical/advanced/can_toggle(mob/living/carbon/human/user)
+ if(!skillcheck(user, SKILL_MEDICAL, SKILL_MEDICAL_MEDIC))
+ to_chat(user, SPAN_NOTICE("You are not skilled enough to use [src]."))
+ return FALSE
+
+ return TRUE
+
+/obj/item/device/helmet_visor/security
+ name = "security optic"
+ icon_state = "sec_sight"
+ hud_type = MOB_HUD_SECURITY_ADVANCED
+ action_icon_string = "sec_sight_down"
+ helmet_overlay = "sec_sight_right"
+
+/obj/item/device/helmet_visor/welding_visor
+ name = "welding visor"
+ icon_state = "sight_empty"
+ hud_type = null
+ action_icon_string = "blank_hud_sight_down"
+ helmet_overlay = "weld_visor"
+
+/obj/item/device/helmet_visor/welding_visor/visor_function(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user, silent = FALSE)
+ if(attached_helmet == user.head && attached_helmet.active_visor == src)
+ attached_helmet.vision_impair = VISION_IMPAIR_MAX
+ attached_helmet.flags_inventory |= COVEREYES|COVERMOUTH
+ attached_helmet.flags_inv_hide |= HIDEEYES|HIDEFACE
+ attached_helmet.eye_protection = EYE_PROTECTION_WELDING
+ user.update_tint()
+ if(!silent)
+ to_chat(user, SPAN_NOTICE("You activate [src] on [attached_helmet]."))
+ return TRUE
+
+ attached_helmet.vision_impair = VISION_IMPAIR_NONE
+ attached_helmet.flags_inventory &= ~(COVEREYES|COVERMOUTH)
+ attached_helmet.flags_inv_hide &= ~(HIDEEYES|HIDEFACE)
+ attached_helmet.eye_protection = EYE_PROTECTION_NONE
+ if(!silent)
+ to_chat(user, SPAN_NOTICE("You deactivate [src] on [attached_helmet]."))
+ user.update_tint()
+ return TRUE
+
+/obj/item/device/helmet_visor/welding_visor/mercenary
+ helmet_overlay = ""
+
+/obj/item/device/helmet_visor/welding_visor/tanker
+ helmet_overlay = "tanker_weld_visor"
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index 7e6b0db056d0..4ab9e19d5ae1 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -238,7 +238,7 @@
RegisterSignal(user, COMSIG_HUMAN_SET_UNDEFIBBABLE, PROC_REF(update_minimap_icon))
if(headset_hud_on)
var/datum/mob_hud/H = huds[hud_type]
- H.add_hud_to(user)
+ H.add_hud_to(user, src)
//squad leader locator is no longer invisible on our player HUD.
if(user.mind && (user.assigned_squad || misc_tracking) && user.hud_used && user.hud_used.locate_leader)
user.show_hud_tracker()
@@ -257,7 +257,7 @@
))
if(istype(user) && user.has_item_in_ears(src)) //dropped() is called before the inventory reference is update.
var/datum/mob_hud/H = huds[hud_type]
- H.remove_hud_from(user)
+ H.remove_hud_from(user, src)
//squad leader locator is invisible again
if(user.hud_used && user.hud_used.locate_leader)
user.hide_hud_tracker()
@@ -290,14 +290,14 @@
if(user.has_item_in_ears(src)) //worn
var/datum/mob_hud/H = huds[hud_type]
if(headset_hud_on)
- H.add_hud_to(usr)
+ H.add_hud_to(usr, src)
if(user.mind && (misc_tracking || user.assigned_squad) && user.hud_used?.locate_leader)
user.show_hud_tracker()
if(misc_tracking)
SStracking.start_misc_tracking(user)
update_minimap_icon()
else
- H.remove_hud_from(usr)
+ H.remove_hud_from(usr, src)
if(user.hud_used?.locate_leader)
user.hide_hud_tracker()
if(misc_tracking)
diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm
index aef577779c06..6aecacd27916 100644
--- a/code/game/objects/items/devices/radio/intercom.dm
+++ b/code/game/objects/items/devices/radio/intercom.dm
@@ -64,10 +64,10 @@
on = FALSE
else
var/area/A = src.loc.loc
- if(!A || !isarea(A) || !A.master)
+ if(!A || !isarea(A))
on = FALSE
else
- on = A.master.powered(POWER_CHANNEL_EQUIP) // set "on" to the power status
+ on = A.powered(POWER_CHANNEL_EQUIP) // set "on" to the power status
if(!on)
icon_state = "intercom-p"
diff --git a/code/game/objects/items/lightstick.dm b/code/game/objects/items/lightstick.dm
index 453d965926ff..70418049994b 100644
--- a/code/game/objects/items/lightstick.dm
+++ b/code/game/objects/items/lightstick.dm
@@ -7,10 +7,18 @@
desc = "You can stick them in the ground"
icon = 'icons/obj/items/lighting.dmi'
icon_state = "lightstick_blue0"
+ light_range = 2
+ light_color = COLOUR_BLUE
var/s_color = "blue"
var/trample_chance = 30
var/can_trample = TRUE
+/obj/item/lightstick/Initialize(mapload, ...)
+ . = ..()
+
+ if(!light_on)
+ set_light_range(0)
+
/obj/item/lightstick/Crossed(mob/living/O)
if(anchored && prob(trample_chance) && can_trample)
if(!istype(O,/mob/living/carbon/xenomorph/larva))
@@ -22,13 +30,13 @@
else
anchored = FALSE
icon_state = "lightstick_[s_color][anchored]"
- SetLuminosity(0)
+ set_light_range(0)
pixel_x = 0
pixel_y = 0
else
anchored = FALSE
icon_state = "lightstick_[s_color][anchored]"
- SetLuminosity(0)
+ set_light_range(0)
pixel_x = 0
pixel_y = 0
@@ -45,31 +53,27 @@
anchored = FALSE
user.visible_message("[user.name] removes \the [src] from the ground.","You remove the [src] from the ground.")
icon_state = "lightstick_[s_color][anchored]"
- SetLuminosity(0)
+ set_light(0)
pixel_x = 0
pixel_y = 0
playsound(user, 'sound/weapons/Genhit.ogg', 25, 1)
- //Remove lightsource
-/obj/item/lightstick/Destroy()
- SetLuminosity(0)
- return ..()
-
//Red
/obj/item/lightstick/planted
icon_state = "lightstick_blue1"
anchored = TRUE
- luminosity = 2
+ light_on = TRUE
/obj/item/lightstick/red
name = "red lightstick"
icon_state = "lightstick_red0"
s_color = "red"
+ light_color = COLOUR_RED
/obj/item/lightstick/red/planted
icon_state = "lightstick_red1"
anchored = TRUE
- luminosity = 2
+ light_on = TRUE
/obj/item/lightstick/red/spoke
name = "red lightstick"
@@ -80,7 +84,7 @@
/obj/item/lightstick/red/spoke/planted
icon_state = "lightstick_spoke1"
anchored = TRUE
- luminosity = 2
+ light_on = TRUE
/obj/item/lightstick/red/variant
name = "red lightstick"
@@ -90,7 +94,7 @@
/obj/item/lightstick/red/variant/planted
icon_state = "lightstick_red_variant1"
anchored = TRUE
- luminosity = 2
+ light_on = TRUE
/obj/item/lightstick/variant //blue
name = "blue lightstick"
@@ -100,4 +104,4 @@
/obj/item/lightstick/variant/planted
icon_state = "lightstick_blue_variant1"
anchored = TRUE
- luminosity = 2
+ light_on = TRUE
diff --git a/code/game/objects/items/reagent_containers/food/snacks.dm b/code/game/objects/items/reagent_containers/food/snacks.dm
index c0e11dac8eb3..06a4d785e677 100644
--- a/code/game/objects/items/reagent_containers/food/snacks.dm
+++ b/code/game/objects/items/reagent_containers/food/snacks.dm
@@ -60,7 +60,7 @@
if(istype(M, /mob/living/carbon))
var/mob/living/carbon/C = M
var/fullness = M.nutrition + (M.reagents.get_reagent_amount("nutriment") * 25)
- if(fullness > 540 && world.time < C.overeat_cooldown)
+ if(fullness > NUTRITION_HIGH && world.time < C.overeat_cooldown)
to_chat(user, SPAN_WARNING("[user == M ? "You" : "They"] don't feel like eating more right now."))
return
if(issynth(C))
@@ -70,22 +70,22 @@
to_chat(user, SPAN_DANGER("[user == M ? "You are" : "[M] is"] unable to eat!"))
return
- if(fullness > 540)
+ if(fullness > NUTRITION_HIGH)
C.overeat_cooldown = world.time + OVEREAT_TIME
if(M == user)//If you're eating it yourself
- if (fullness <= 50)
+ if (fullness <= NUTRITION_VERYLOW)
to_chat(M, SPAN_WARNING("You hungrily chew out a piece of [src] and gobble it!"))
- if (fullness > 50 && fullness <= 150)
+ if (fullness > NUTRITION_VERYLOW && fullness <= NUTRITION_LOW)
to_chat(M, SPAN_NOTICE(" You hungrily begin to eat [src]."))
- if (fullness > 150 && fullness <= 350)
+ if (fullness > NUTRITION_LOW && fullness <= NUTRITION_NORMAL)
to_chat(M, SPAN_NOTICE(" You take a bite of [src]."))
- if (fullness > 350 && fullness <= 540)
+ if (fullness > NUTRITION_NORMAL && fullness <= NUTRITION_HIGH)
to_chat(M, SPAN_NOTICE(" You unwillingly chew a bit of [src]."))
- if (fullness > 540)
+ if (fullness > NUTRITION_HIGH)
to_chat(M, SPAN_WARNING("You reluctantly force more of [src] to go down your throat."))
else
- if (fullness <= 540)
+ if (fullness <= NUTRITION_HIGH)
user.affected_message(M,
SPAN_HELPFUL("You start feeding [user == M ? "yourself" : "[M]"] [src]."),
SPAN_HELPFUL("[user] starts feeding you [src]."),
diff --git a/code/game/objects/items/reagent_containers/food/snacks/grown.dm b/code/game/objects/items/reagent_containers/food/snacks/grown.dm
index d2fdda7d0975..12a5a704f663 100644
--- a/code/game/objects/items/reagent_containers/food/snacks/grown.dm
+++ b/code/game/objects/items/reagent_containers/food/snacks/grown.dm
@@ -189,26 +189,16 @@
/obj/item/reagent_container/food/snacks/grown/glowberries
name = "bunch of glow-berries"
desc = "Nutritious!"
- var/light_on = 1
var/brightness_on = 2 //luminosity when on
filling_color = "#D3FF9E"
icon_state = "glowberrypile"
plantname = "glowberries"
-/obj/item/reagent_container/food/snacks/grown/glowberries/Destroy()
- if(istype(loc,/mob))
- loc.SetLuminosity(0, FALSE, src)
+/obj/item/reagent_container/food/snacks/grown/glowberries/Initialize()
. = ..()
-/obj/item/reagent_container/food/snacks/grown/glowberries/pickup(mob/user)
- . = ..()
- src.SetLuminosity(0)
- user.SetLuminosity(round((potency/5),1), FALSE, src)
-
-/obj/item/reagent_container/food/snacks/grown/glowberries/dropped(mob/user)
- user.SetLuminosity(0, FALSE, src)
- src.SetLuminosity(round(potency/5,1))
- ..()
+ set_light_range(brightness_on)
+ set_light_on(TRUE)
/obj/item/reagent_container/food/snacks/grown/cocoapod
name = "cocoa pod"
@@ -568,22 +558,6 @@
to_chat(user, SPAN_NOTICE("You plant the glowshroom."))
-/obj/item/reagent_container/food/snacks/grown/mushroom/glowshroom/Destroy()
- if(istype(loc,/mob))
- loc.SetLuminosity(0, FALSE, src)
- . = ..()
-
-/obj/item/reagent_container/food/snacks/grown/mushroom/glowshroom/pickup(mob/user)
- . = ..()
- SetLuminosity(0)
- user.SetLuminosity(round((potency/10),1), FALSE, src)
-
-/obj/item/reagent_container/food/snacks/grown/mushroom/glowshroom/dropped(mob/user)
- user.SetLuminosity(0, FALSE, src)
- SetLuminosity(round(potency/10,1))
- ..()
-
-
// *************************************
// Complex Grown Object Defines -
// Putting these at the bottom so they don't clutter the list up. -Cheridan
diff --git a/code/game/objects/items/shards.dm b/code/game/objects/items/shards.dm
index f46f5b5a5fc0..412a14268037 100644
--- a/code/game/objects/items/shards.dm
+++ b/code/game/objects/items/shards.dm
@@ -232,13 +232,13 @@
organ.take_damage(damage_on_move * count, 0, 0, no_limb_loss = TRUE)
embedded_mob.pain.apply_pain(damage_on_move * count)
-/obj/item/shard/shrapnel/nagant
+/obj/item/shard/shrapnel/upp
name = "small shrapnel"
desc = "Some shrapnel that used to be embedded underneath someone's skin."
icon_state = "small"
damage_on_move = 2
-/obj/item/shard/shrapnel/nagant/bits
+/obj/item/shard/shrapnel/upp/bits
name = "tiny shrapnel"
desc = "A tiny piece of shrapnel that used to be embedded underneath someone's skin."
icon_state = "tiny"
diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm
index 3bf3656f4bd2..37320aca0133 100644
--- a/code/game/objects/items/storage/backpack.dm
+++ b/code/game/objects/items/storage/backpack.dm
@@ -497,7 +497,7 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r
var/obj/structure/transmitter/internal/internal_transmitter
var/phone_category = PHONE_MARINE
- var/network_receive = FACTION_MARINE
+ var/list/networks_receive = list(FACTION_MARINE)
var/list/networks_transmit = list(FACTION_MARINE)
var/base_icon
@@ -523,7 +523,7 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r
internal_transmitter.relay_obj = src
internal_transmitter.phone_category = phone_category
internal_transmitter.enabled = FALSE
- internal_transmitter.network_receive = network_receive
+ internal_transmitter.networks_receive = networks_receive
internal_transmitter.networks_transmit = networks_transmit
RegisterSignal(internal_transmitter, COMSIG_TRANSMITTER_UPDATE_ICON, PROC_REF(check_for_ringing))
GLOB.radio_packs += src
@@ -593,7 +593,8 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r
. = ..()
/obj/item/storage/backpack/marine/satchel/rto/upp_net
- network_receive = FACTION_UPP
+ name = "\improper UPP Radio Telephone Pack"
+ networks_receive = list(FACTION_UPP)
networks_transmit = list(FACTION_UPP)
/obj/item/storage/backpack/marine/satchel/rto/small
@@ -602,7 +603,8 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r
/obj/item/storage/backpack/marine/satchel/rto/small/upp_net
- network_receive = FACTION_UPP
+ name = "\improper UPP Radio Telephone Pack"
+ networks_receive = list(FACTION_UPP)
networks_transmit = list(FACTION_UPP)
phone_category = PHONE_UPP_SOLDIER
diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm
index 7721a9643fb5..805f1f49c7ff 100644
--- a/code/game/objects/items/storage/belt.dm
+++ b/code/game/objects/items/storage/belt.dm
@@ -391,6 +391,7 @@
new /obj/item/weapon/baton(src)
new /obj/item/handcuffs(src)
new /obj/item/reagent_container/spray/pepper(src)
+ new /obj/item/ammo_magazine/revolver/upp/shrapnel(src)
/obj/item/storage/belt/security/MP/CMB
name = "\improper CMB duty belt"
@@ -1405,37 +1406,50 @@
/obj/item/storage/belt/gun/type47
name = "\improper Type 47 pistol holster rig"
- desc = "This UPP-designed sidearm rig can very snugly and securely fit either a Nagant-Yamasaki revolver or a Korovin PK-9, and both their magazines or speedloaders. However, it lacks versatility in stored weaponry."
+ desc = "This UPP-designed sidearm rig can very snugly and securely fit a Type-73, NP92, or a ZHNK-72, and their magazines or speedloaders. However, it lacks versatility in stored weaponry."
icon_state = "korovin_holster"
item_state = "upp_belt"
storage_slots = 7
can_hold = list(
- /obj/item/weapon/gun/pistol/c99,
- /obj/item/ammo_magazine/pistol/c99,
- /obj/item/ammo_magazine/pistol/c99/tranq,
- /obj/item/weapon/gun/revolver/nagant,
+ /obj/item/weapon/gun/pistol/t73,
+ /obj/item/ammo_magazine/pistol/t73,
+ /obj/item/ammo_magazine/pistol/t73_impact,
+ /obj/item/weapon/gun/pistol/np92,
+ /obj/item/ammo_magazine/pistol/np92,
+ /obj/item/ammo_magazine/pistol/np92/tranq,
+ /obj/item/weapon/gun/revolver/upp,
/obj/item/ammo_magazine/revolver/upp,
/obj/item/ammo_magazine/revolver/upp/shrapnel,
)
holster_slots = list("1" = list("icon_x" = -1))
-/obj/item/storage/belt/gun/type47/PK9/fill_preset_inventory()
- handle_item_insertion(new /obj/item/weapon/gun/pistol/c99/upp())
+/obj/item/storage/belt/gun/type47/np92/fill_preset_inventory()
+ handle_item_insertion(new /obj/item/weapon/gun/pistol/np92())
for(var/i = 1 to storage_slots - 1)
- new /obj/item/ammo_magazine/pistol/c99(src)
+ new /obj/item/ammo_magazine/pistol/np92(src)
-/obj/item/storage/belt/gun/type47/PK9/tranq/fill_preset_inventory()
- handle_item_insertion(new /obj/item/weapon/gun/pistol/c99/upp/tranq())
+/obj/item/storage/belt/gun/type47/np92/suppressed/fill_preset_inventory()
+ handle_item_insertion(new /obj/item/weapon/gun/pistol/np92/suppressed())
for(var/i = 1 to storage_slots - 1)
- new /obj/item/ammo_magazine/pistol/c99/tranq(src)
+ new /obj/item/ammo_magazine/pistol/np92/suppressed(src)
-/obj/item/storage/belt/gun/type47/NY/fill_preset_inventory()
- handle_item_insertion(new /obj/item/weapon/gun/revolver/nagant())
+/obj/item/storage/belt/gun/type47/t73/fill_preset_inventory()
+ handle_item_insertion(new /obj/item/weapon/gun/pistol/t73())
+ for(var/i = 1 to storage_slots - 1)
+ new /obj/item/ammo_magazine/pistol/t73(src)
+
+/obj/item/storage/belt/gun/type47/t73/leader/fill_preset_inventory()
+ handle_item_insertion(new /obj/item/weapon/gun/pistol/t73/leader())
+ for(var/i = 1 to storage_slots - 1)
+ new /obj/item/ammo_magazine/pistol/t73_impact(src)
+
+/obj/item/storage/belt/gun/type47/revolver/fill_preset_inventory()
+ handle_item_insertion(new /obj/item/weapon/gun/revolver/upp())
for(var/total_storage_slots in 1 to storage_slots - 1)
new /obj/item/ammo_magazine/revolver/upp(src)
-/obj/item/storage/belt/gun/type47/NY/shrapnel/fill_preset_inventory()
- handle_item_insertion(new /obj/item/weapon/gun/revolver/nagant/shrapnel())
+/obj/item/storage/belt/gun/type47/revolver/shrapnel/fill_preset_inventory()
+ handle_item_insertion(new /obj/item/weapon/gun/revolver/upp/shrapnel())
for(var/total_storage_slots in 1 to storage_slots - 1)
new /obj/item/ammo_magazine/revolver/upp/shrapnel(src)
diff --git a/code/game/objects/items/storage/misc.dm b/code/game/objects/items/storage/misc.dm
index eb6f100f6e8b..424a4f5be0e8 100644
--- a/code/game/objects/items/storage/misc.dm
+++ b/code/game/objects/items/storage/misc.dm
@@ -124,6 +124,20 @@
new /obj/item/weapon/gun/pistol/clfpistol(src)
new /obj/item/ammo_magazine/pistol/clfpistol(src)
+/obj/item/storage/box/upp //war trophy luger
+ name = "Type 73 storing case"
+ desc = "A small case containing the once-standard sidearm of the UPP, the Type 73, and two additional magazines. The contained sidearm is probably looted off a dead officer or from a captured stockpile, either way this thing is worth a pretty penny."
+ icon = 'icons/obj/items/storage.dmi'
+ icon_state = "matebacase"
+ w_class = SIZE_MEDIUM
+ max_w_class = SIZE_MEDIUM
+ storage_slots = 3
+
+/obj/item/storage/box/upp/fill_preset_inventory()
+ new /obj/item/weapon/gun/pistol/t73(src)
+ new /obj/item/ammo_magazine/pistol/t73(src)
+ new /obj/item/ammo_magazine/pistol/t73(src)
+
/obj/item/storage/box/co2_knife
name = "M8 cartridge bayonet packaging"
desc = "Contains one M8 Cartridge Bayonet and two sister CO2 cartridges. Thanks for being a dedicated Boots magazine subscriber!"
diff --git a/code/game/objects/items/storage/pouch.dm b/code/game/objects/items/storage/pouch.dm
index 6397c33b76c1..b31dcc9900f1 100644
--- a/code/game/objects/items/storage/pouch.dm
+++ b/code/game/objects/items/storage/pouch.dm
@@ -906,6 +906,9 @@
update_icon()
/obj/item/storage/pouch/pressurized_reagent_canister/afterattack(obj/target, mob/user, flag) //refuel at fueltanks & chem dispensers.
+ if(get_dist(user,target) > 1)
+ return ..()
+
if(!inner)
to_chat(user, SPAN_WARNING("[src] has no internal container!"))
return ..()
@@ -925,8 +928,7 @@
if(!istype(target, /obj/structure/reagent_dispensers/fueltank))
return ..()
- if(get_dist(user,target) > 1)
- return ..()
+
var/obj/O = target
if(!O.reagents || O.reagents.reagent_list.len < 1)
diff --git a/code/game/objects/items/storage/smartpack.dm b/code/game/objects/items/storage/smartpack.dm
index 8d6057e16ce9..8df079c92ca4 100644
--- a/code/game/objects/items/storage/smartpack.dm
+++ b/code/game/objects/items/storage/smartpack.dm
@@ -22,9 +22,6 @@
var/show_exoskeleton = TRUE
- var/flashlight_cooldown = 0 //Cooldown for toggling the light
- var/light_state = FALSE //Is the light on or off
-
var/battery_charge = SMARTPACK_MAX_POWER_STORED //How much power are we storing
var/activated_form = FALSE
var/immobile_form = FALSE
@@ -83,7 +80,7 @@
else
LAZYSET(item_state_slots, WEAR_BACK, initial(item_state))
- if(light_state)
+ if(light_on)
overlays += "+lamp_on"
else
overlays += "+lamp_off"
@@ -116,7 +113,7 @@
var/image/ret = ..()
var/light = "+lamp_on"
- if(!light_state)
+ if(!light_on)
light = "+lamp_off"
var/image/lamp = overlay_image('icons/mob/humans/onmob/back.dmi', light, color, RESET_COLOR)
@@ -134,17 +131,14 @@
else
to_chat(M, SPAN_DANGER("[name] beeps, \"Unathorized user!\""))
- if(light_state && loc != M)
- M.SetLuminosity(BACKPACK_LIGHT_LEVEL, FALSE, src)
- SetLuminosity(0)
..()
/obj/item/storage/backpack/marine/smartpack/dropped(mob/living/M)
for(var/datum/action/human_action/smartpack/S in M.actions)
S.remove_from(M)
- if(light_state && loc != M)
- toggle_light(M)
+ if(light_on && loc != M)
+ turn_light(M, toggle_on = FALSE)
if(immobile_form)
immobile_form = FALSE
@@ -153,47 +147,34 @@
M.unfreeze()
..()
-/obj/item/storage/backpack/marine/smartpack/Destroy()
- if(ismob(loc))
- loc.SetLuminosity(0, FALSE, src)
- else
- SetLuminosity(0)
- . = ..()
-
/obj/item/storage/backpack/marine/smartpack/attack_self(mob/user)
..()
- if(!isturf(user.loc) || flashlight_cooldown > world.time || !ishuman(user))
+ if(!isturf(user.loc) || !ishuman(user))
return
var/mob/living/carbon/human/H = user
if(H.back != src)
return
- toggle_light(user)
+ turn_light(user, toggle_on = !light_on)
return TRUE
-/obj/item/storage/backpack/marine/smartpack/proc/toggle_light(mob/user)
- flashlight_cooldown = world.time + 20 //2 seconds cooldown every time the light is toggled
- if(light_state) //Turn it off.
- if(user)
- user.SetLuminosity(0, FALSE, src)
- else
- SetLuminosity(0)
- playsound(src, 'sound/handling/click_2.ogg', 50, TRUE)
- else //Turn it on.
- if(user)
- user.SetLuminosity(BACKPACK_LIGHT_LEVEL, FALSE, src)
- else
- SetLuminosity(BACKPACK_LIGHT_LEVEL)
+/obj/item/storage/backpack/marine/smartpack/turn_light(mob/user, toggle_on, cooldown, sparks, forced, light_again)
+ . = ..()
+ if(. != CHECKS_PASSED)
+ return
- light_state = !light_state
+ if(toggle_on)
+ set_light_range(BACKPACK_LIGHT_LEVEL)
+ set_light_on(TRUE)
+ else
+ set_light_on(FALSE)
+ playsound(src, 'sound/handling/click_2.ogg', 50, TRUE)
playsound(src, 'sound/handling/light_on_1.ogg', 50, TRUE)
-
update_icon(user)
-
/obj/item/storage/backpack/marine/smartpack/proc/protective_form(mob/living/carbon/human/user)
if(!istype(user) || activated_form || immobile_form)
return
diff --git a/code/game/objects/items/tools/flame_tools.dm b/code/game/objects/items/tools/flame_tools.dm
index 6ebd8ee5982e..862906ec1971 100644
--- a/code/game/objects/items/tools/flame_tools.dm
+++ b/code/game/objects/items/tools/flame_tools.dm
@@ -42,10 +42,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/tool/candle/Destroy()
if(heat_source)
STOP_PROCESSING(SSobj, src)
- if(ismob(src.loc))
- src.loc.SetLuminosity(0, FALSE, src)
- else
- SetLuminosity(0)
+
. = ..()
/obj/item/tool/candle/attackby(obj/item/W as obj, mob/user as mob)
@@ -65,7 +62,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
flavor_text = SPAN_NOTICE("[usr] lights [src].")
for(var/mob/O in viewers(usr, null))
O.show_message(flavor_text, SHOW_MESSAGE_VISIBLE)
- SetLuminosity(CANDLE_LUM)
+ set_light(CANDLE_LUM)
update_icon()
START_PROCESSING(SSobj, src)
@@ -80,34 +77,15 @@ CIGARETTE PACKETS ARE IN FANCY.DM
return
update_icon()
-
-
/obj/item/tool/candle/attack_self(mob/user)
..()
if(heat_source)
heat_source = 0
update_icon()
- SetLuminosity(0)
- user.SetLuminosity(0, FALSE, src)
+ set_light(0)
STOP_PROCESSING(SSobj, src)
-
-/obj/item/tool/candle/pickup(mob/user)
- . = ..()
- if(heat_source)
- SetLuminosity(0)
- user.SetLuminosity(CANDLE_LUM, FALSE, src)
-
-
-/obj/item/tool/candle/dropped(mob/user)
- ..()
- if(heat_source && src.loc != user)
- user.SetLuminosity(0, FALSE, src)
- SetLuminosity(CANDLE_LUM)
-
-
-
///////////
//MATCHES//
///////////
@@ -120,6 +98,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM
var/smoketime = 10 SECONDS
var/burnt_name = "burnt match"
w_class = SIZE_TINY
+ light_range = 2
+ light_power = 1
attack_verb = list("burnt", "singed")
@@ -149,6 +129,13 @@ CIGARETTE PACKETS ARE IN FANCY.DM
burn_out(user)
return ..()
+/obj/item/tool/match/turn_light(mob/user, toggle_on)
+ . = ..()
+ if(. == NO_LIGHT_STATE_CHANGE)
+ return
+
+ set_light_on(toggle_on)
+
/obj/item/tool/match/proc/light_match()
if(heat_source || burnt)
return
@@ -156,10 +143,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
playsound(src.loc,"match",15, 1, 3)
damtype = "burn"
icon_state = "[initial(icon_state)]_lit"
- if(ismob(loc))
- loc.SetLuminosity(2, FALSE, src)
- else
- SetLuminosity(2)
+ turn_light(toggle_on = TRUE)
START_PROCESSING(SSobj, src)
update_icon()
return TRUE
@@ -170,32 +154,17 @@ CIGARETTE PACKETS ARE IN FANCY.DM
damtype = "brute"
icon_state = "[initial(icon_state)]_burnt"
item_state = "cigoff"
- SetLuminosity(0)
+ turn_light(toggle_on = FALSE)
name = burnt_name
desc = "A match. This one has seen better days."
STOP_PROCESSING(SSobj, src)
- if(user)
- user.SetLuminosity(0, FALSE, src)
- return
-
- if(ismob(loc))
- user = loc
- user.SetLuminosity(0, FALSE, src)
- return
-
/obj/item/tool/match/paper
name = "paper match"
desc = "A simple match stick, used for lighting fine smokables."
icon_state = "papermatch"
burnt_name = "burnt paper match"
-/obj/item/tool/lighter/dropped(mob/user)
- if(heat_source && src.loc != user)
- user.SetLuminosity(0, FALSE, src)
- SetLuminosity(2)
- return ..()
-
//////////////////
//FINE SMOKABLES//
//////////////////
@@ -211,6 +180,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
flags_atom = CAN_BE_SYRINGED
attack_verb = list("burnt", "singed")
blood_overlay_type = ""
+ light_color = LIGHT_COLOUR_ORANGE
/// Note - these are in masks.dmi not in cigarette.dmi
var/icon_on = "cigon"
var/icon_off = "cigoff"
@@ -339,6 +309,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM
reagents.handle_reactions()
icon_state = icon_on
item_state = icon_on
+ set_light_range(1)
+ set_light_power(0.5)
+ set_light_on(TRUE)
if(iscarbon(loc))
var/mob/living/carbon/C = loc
if(C.r_hand == src)
@@ -372,7 +345,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
return
var/mob/living/carbon/C = loc
- if(prob(15)) // so it's not an instarape in case of acid
+ if(prob(15))
reagents.reaction(C, INGEST)
reagents.trans_to(C, REAGENTS_METABOLISM)
else // else just remove some of the reagents
@@ -404,6 +377,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
qdel(src)
. = butt
else
+ set_light_on(FALSE)
heat_source = 0
icon_state = icon_off
item_state = icon_off
@@ -679,6 +653,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
icon = 'icons/obj/items/items.dmi'
icon_state = "lighter_g"
item_state = "lighter_g"
+ light_color = LIGHT_COLOUR_LAVA
var/icon_on = "lighter_g_on"
var/icon_off = "lighter_g"
var/clr = "g"
@@ -732,13 +707,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM
icon_off = "lighter_[clr]"
icon_state = icon_off
-/obj/item/tool/lighter/Destroy()
- if(ismob(src.loc))
- src.loc.SetLuminosity(0, FALSE, src)
- else
- SetLuminosity(0)
- . = ..()
-
/obj/item/tool/lighter/attack_self(mob/living/user)
if(user.r_hand == src || user.l_hand == src)
if(!heat_source)
@@ -761,7 +729,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM
user.apply_damage(2,BURN,"r_hand")
user.visible_message(SPAN_NOTICE("After a few attempts, [user] manages to light the [src], they however burn their finger in the process."))
- user.SetLuminosity(2, FALSE, src)
+ set_light_range(2)
+ set_light_on(TRUE)
START_PROCESSING(SSobj, src)
else
turn_off(user, 0)
@@ -781,7 +750,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
else
bearer.visible_message(SPAN_NOTICE("[bearer] quietly shuts off the [src]."))
- bearer.SetLuminosity(0, FALSE, src)
+ set_light_on(FALSE)
STOP_PROCESSING(SSobj, src)
return 1
return 0
@@ -805,18 +774,3 @@ CIGARETTE PACKETS ARE IN FANCY.DM
else
..()
-/obj/item/tool/lighter/process()
-
-
-/obj/item/tool/lighter/pickup(mob/user)
- . = ..()
- if(heat_source)
- SetLuminosity(0)
- user.SetLuminosity(2, FALSE, src)
-
-
-/obj/item/tool/lighter/dropped(mob/user)
- if(heat_source && src.loc != user)
- user.SetLuminosity(0, FALSE, src)
- SetLuminosity(2)
- return ..()
diff --git a/code/game/objects/items/tools/kitchen_tools.dm b/code/game/objects/items/tools/kitchen_tools.dm
index 98974f25be29..bb763ada9911 100644
--- a/code/game/objects/items/tools/kitchen_tools.dm
+++ b/code/game/objects/items/tools/kitchen_tools.dm
@@ -45,6 +45,10 @@
return ..()
if (reagents.total_volume > 0)
+ var/fullness = M.nutrition + (M.reagents.get_reagent_amount("nutriment") * 25)
+ if(fullness > NUTRITION_HIGH)
+ to_chat(user, SPAN_WARNING("[user == M ? "You" : "They"] don't feel like eating more right now."))
+ return ..()
reagents.set_source_mob(user)
reagents.trans_to_ingest(M, reagents.total_volume)
if(M == user)
diff --git a/code/game/objects/items/tools/maintenance_tools.dm b/code/game/objects/items/tools/maintenance_tools.dm
index b8affb0de616..05ba357c80ce 100644
--- a/code/game/objects/items/tools/maintenance_tools.dm
+++ b/code/game/objects/items/tools/maintenance_tools.dm
@@ -175,6 +175,9 @@
inherent_traits = list(TRAIT_TOOL_BLOWTORCH)
+ light_range = 2
+ light_power = 2
+
//blowtorch specific stuff
/// Whether or not the blowtorch is off(0), on(1) or currently welding(2)
@@ -191,13 +194,8 @@
reagents.add_reagent("fuel", max_fuel)
return
-
/obj/item/tool/weldingtool/Destroy()
if(welding)
- if(ismob(loc))
- loc.SetLuminosity(0, FALSE, src)
- else
- SetLuminosity(0)
STOP_PROCESSING(SSobj, src)
. = ..()
@@ -205,8 +203,6 @@
. = ..()
. += "It contains [get_fuel()]/[max_fuel] units of fuel!"
-
-
/obj/item/tool/weldingtool/process()
if(QDELETED(src))
STOP_PROCESSING(SSobj, src)
@@ -218,7 +214,6 @@
else //should never be happening, but just in case
toggle(TRUE)
-
/obj/item/tool/weldingtool/attack(mob/target, mob/user)
if(ishuman(target))
@@ -285,6 +280,13 @@
..()
toggle()
+/obj/item/tool/weldingtool/turn_light(mob/user, toggle_on)
+ . = ..()
+ if(. == NO_LIGHT_STATE_CHANGE)
+ return
+
+ set_light_on(toggle_on)
+
//Returns the amount of fuel in the welder
/obj/item/tool/weldingtool/proc/get_fuel()
if(!reagents)
@@ -330,9 +332,7 @@
welding = 1
if(M)
to_chat(M, SPAN_NOTICE("You switch [src] on."))
- M.SetLuminosity(2, FALSE, src)
- else
- SetLuminosity(2)
+ turn_light((M ? M : null), toggle_on = TRUE)
weld_tick += 8 //turning the tool on does not consume fuel directly, but it advances the process that regularly consumes fuel.
force = 15
damtype = "fire"
@@ -357,13 +357,13 @@
to_chat(M, SPAN_NOTICE("You switch [src] off."))
else
to_chat(M, SPAN_WARNING("[src] shuts off!"))
- M.SetLuminosity(0, FALSE, src)
if(M.r_hand == src)
M.update_inv_r_hand()
if(M.l_hand == src)
M.update_inv_l_hand()
- else
- SetLuminosity(0)
+
+ turn_light((M ? M : null), toggle_on = FALSE)
+
STOP_PROCESSING(SSobj, src)
//Decides whether or not to damage a player's eyes based on what they're wearing as protection
@@ -380,22 +380,27 @@
if(E.robotic == ORGAN_ROBOT)
return
switch(safety)
- if(1)
+ if(EYE_PROTECTION_FLASH)
+ to_chat(user, SPAN_DANGER("You see a bright light in the corner of your vision."))
+ E.take_damage(rand(0, 1), TRUE)
+ if(E.damage > 10)
+ E.take_damage(rand(3, 5), TRUE)
+ if(EYE_PROTECTION_FLAVOR)
to_chat(user, SPAN_DANGER("Your eyes sting a little."))
E.take_damage(rand(1, 2), TRUE)
- if(E.damage > 12)
- H.AdjustEyeBlur(3,6)
- if(0)
+ if(E.damage > 8) // dont abuse your funny flavor glasses
+ E.take_damage(2, TRUE)
+ if(EYE_PROTECTION_NONE)
to_chat(user, SPAN_WARNING("Your eyes burn."))
- E.take_damage(rand(2, 4), TRUE)
+ E.take_damage(rand(3, 4), TRUE)
if(E.damage > 10)
E.take_damage(rand(4, 10), TRUE)
- if(-1)
+ if(EYE_PROTECTION_NEGATIVE)
to_chat(user, SPAN_WARNING("Your thermals intensify [src]'s glow. Your eyes itch and burn severely."))
H.AdjustEyeBlur(12,20)
E.take_damage(rand(12, 16), TRUE)
- if(safety < 2)
+ if(safety < EYE_PROTECTION_WELDING)
if (E.damage >= E.min_broken_damage)
to_chat(H, SPAN_WARNING("You go blind! Maybe welding without protection wasn't such a great idea..."))
return FALSE
@@ -406,20 +411,6 @@
to_chat(H, SPAN_WARNING("Your eyes are really starting to hurt. This can't be good for you!"))
return FALSE
-/obj/item/tool/weldingtool/pickup(mob/user)
- . = ..()
- if(welding)
- SetLuminosity(0)
- user.SetLuminosity(2, FALSE, src)
-
-
-/obj/item/tool/weldingtool/dropped(mob/user)
- if(welding && loc != user)
- user.SetLuminosity(0, FALSE, src)
- SetLuminosity(2)
- return ..()
-
-
/obj/item/tool/weldingtool/largetank
name = "industrial blowtorch"
max_fuel = 40
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 24f019b9f89f..ebe36323d78e 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -42,7 +42,7 @@
if(garbage)
add_to_garbage(src)
-/obj/Destroy()
+/obj/Destroy(force)
if(buckled_mob)
unbuckle()
. = ..()
diff --git a/code/game/objects/structures/blocker.dm b/code/game/objects/structures/blocker.dm
index aadf6d2a099e..a9e7371d7055 100644
--- a/code/game/objects/structures/blocker.dm
+++ b/code/game/objects/structures/blocker.dm
@@ -25,7 +25,10 @@
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/structure/blocker/invisible_wall/Collided(atom/movable/AM)
- to_chat(AM, SPAN_WARNING("You cannot go this way."))
+ var/msg = desc
+ if(!msg)
+ msg = "You cannot go this way."
+ to_chat(AM, SPAN_WARNING(msg))
/obj/structure/blocker/invisible_wall/New()
..()
@@ -35,10 +38,6 @@
desc = "You cannot wade out any further"
icon_state = "map_blocker"
-/obj/structure/blocker/invisible_wall/water/Collided(atom/movable/AM)
- to_chat(AM, SPAN_WARNING("You cannot wade out any further."))
-
-
/obj/structure/blocker/fog
name = "dense fog"
desc = "It looks way too dangerous to traverse. Best wait until it has cleared up."
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index 11b440e0e2ec..9557013268bf 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -105,7 +105,7 @@
new /obj/item/clothing/head/ushanka(src)
new /obj/item/clothing/mask/rebreather/scarf(src)
new /obj/item/clothing/under/rank/veteran/soviet_uniform_01(src)
- new /obj/item/storage/belt/gun/type47/NY(src)
+ new /obj/item/storage/belt/gun/type47/t73(src)
diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm
index 2393b5df8265..becd128830b6 100644
--- a/code/game/objects/structures/crates_lockers/largecrate.dm
+++ b/code/game/objects/structures/crates_lockers/largecrate.dm
@@ -335,13 +335,13 @@
num_guns = 3
num_mags = 3
name = "\improper Hyperdyne firearm crate"
- stuff = list( /obj/item/weapon/gun/revolver/nagant = /obj/item/ammo_magazine/revolver/upp,
- /obj/item/weapon/gun/pistol/c99 = /obj/item/ammo_magazine/pistol/c99,
+ stuff = list( /obj/item/weapon/gun/revolver/upp = /obj/item/ammo_magazine/revolver/upp,
+ /obj/item/weapon/gun/pistol/np92 = /obj/item/ammo_magazine/pistol/np92,
/obj/item/weapon/gun/pistol/kt42 = /obj/item/ammo_magazine/pistol/kt42,
/obj/item/weapon/gun/rifle/mar40 = /obj/item/ammo_magazine/rifle/mar40,
/obj/item/weapon/gun/rifle/mar40/carbine = /obj/item/ammo_magazine/rifle/mar40/extended,
/obj/item/weapon/gun/rifle/sniper/svd = /obj/item/ammo_magazine/sniper/svd,
- /obj/item/weapon/gun/smg/ppsh = /obj/item/ammo_magazine/smg/ppsh
+ /obj/item/weapon/gun/smg/pps43 = /obj/item/ammo_magazine/smg/pps43
)
/obj/structure/largecrate/guns/merc
@@ -357,11 +357,11 @@
/obj/item/weapon/gun/shotgun/merc = /obj/item/ammo_magazine/handful/shotgun/buckshot,
/obj/item/weapon/gun/shotgun/pump/dual_tube/cmb = /obj/item/ammo_magazine/handful/shotgun/buckshot,
/obj/item/weapon/gun/smg/mp27 = /obj/item/ammo_magazine/smg/mp27,
- /obj/item/weapon/gun/pistol/skorpion = /obj/item/ammo_magazine/pistol/skorpion,
+ /obj/item/weapon/gun/smg/bizon = /obj/item/ammo_magazine/smg/bizon,
/obj/item/weapon/gun/smg/mac15 = /obj/item/ammo_magazine/smg/mac15,
/obj/item/weapon/gun/smg/uzi = /obj/item/ammo_magazine/smg/uzi,
/obj/item/weapon/gun/rifle/mar40/carbine = /obj/item/ammo_magazine/rifle/mar40,
- /obj/item/weapon/gun/smg/ppsh = /obj/item/ammo_magazine/smg/ppsh,
+ /obj/item/weapon/gun/smg/pps43 = /obj/item/ammo_magazine/smg/pps43,
/obj/item/weapon/gun/rifle/l42a = /obj/item/ammo_magazine/rifle/l42a,
/obj/item/weapon/gun/rifle/l42a/abr40 = /obj/item/ammo_magazine/rifle/l42a/abr40,
/obj/item/weapon/gun/smg/mp5 = /obj/item/ammo_magazine/smg/mp5,
@@ -525,9 +525,9 @@
new /obj/item/weapon/gun/rifle/mar40(src)
new /obj/item/ammo_magazine/rifle/mar40(src)
new /obj/item/ammo_magazine/rifle/mar40(src)
- new /obj/item/weapon/gun/pistol/skorpion(src)
- new /obj/item/ammo_magazine/pistol/skorpion(src)
- new /obj/item/ammo_magazine/pistol/skorpion(src)
+ new /obj/item/weapon/gun/smg/bizon(src)
+ new /obj/item/ammo_magazine/smg/bizon(src)
+ new /obj/item/ammo_magazine/smg/bizon(src)
new /obj/item/weapon/gun/shotgun/combat(src)
new /obj/item/ammo_magazine/shotgun(src)
new /obj/item/ammo_magazine/shotgun/buckshot(src)
@@ -571,8 +571,8 @@
new /obj/item/ammo_magazine/rifle(src)
new /obj/item/ammo_magazine/rifle/mar40(src)
new /obj/item/ammo_magazine/rifle/mar40(src)
- new /obj/item/ammo_magazine/pistol/skorpion(src)
- new /obj/item/ammo_magazine/pistol/skorpion(src)
+ new /obj/item/ammo_magazine/smg/bizon(src)
+ new /obj/item/ammo_magazine/smg/bizon(src)
new /obj/item/ammo_magazine/shotgun(src)
new /obj/item/ammo_magazine/shotgun/buckshot(src)
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm
index e8e4b3b0966e..173182b6cc3e 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora.dm
@@ -603,11 +603,7 @@ ICEY GRASS. IT LOOKS LIKE IT'S MADE OF ICE.
name = "strange tree"
desc = "Some kind of bizarre alien tree. It oozes with a sickly yellow sap."
icon_state = "alienplant1"
- luminosity = 2
-
-/obj/structure/flora/jungle/alienplant1/Destroy()
- SetLuminosity(0)
- return ..()
+ light_range = 2
/obj/structure/flora/jungle/planttop1
name = "strange tree"
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 5d0d61e59862..21d66efce270 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -167,11 +167,7 @@
/obj/structure/mineral_door/uranium
mineralType = "uranium"
hardness = 3
- luminosity = 2
-
-/obj/structure/mineral_door/uranium/Destroy()
- SetLuminosity(0)
- . = ..()
+ light_range = 2
/obj/structure/mineral_door/sandstone
mineralType = "sandstone"
diff --git a/code/game/objects/structures/pipes/vents/vents.dm b/code/game/objects/structures/pipes/vents/vents.dm
index 2b3d5409dc8a..d540414e4c8e 100644
--- a/code/game/objects/structures/pipes/vents/vents.dm
+++ b/code/game/objects/structures/pipes/vents/vents.dm
@@ -18,8 +18,6 @@
. = ..()
initial_loc = get_area(loc)
- if(initial_loc.master)
- initial_loc = initial_loc.master
area_uid = initial_loc.uid
if(!id_tag)
assign_uid()
diff --git a/code/game/objects/structures/props.dm b/code/game/objects/structures/props.dm
index 66598d602691..66046a59916f 100644
--- a/code/game/objects/structures/props.dm
+++ b/code/game/objects/structures/props.dm
@@ -33,10 +33,10 @@
/obj/structure/prop/dam/drill/proc/update()
icon_state = "thumper[on ? "-on" : ""]"
if(on)
- SetLuminosity(3)
+ set_light(3)
playsound(src, 'sound/machines/turbine_on.ogg')
else
- SetLuminosity(0)
+ set_light(0)
playsound(src, 'sound/machines/turbine_off.ogg')
return
@@ -114,9 +114,9 @@
underlays += "shadow[lit ? "-lit" : ""]"
icon_state = "torii[lit ? "-lit" : ""]"
if(lit)
- SetLuminosity(6)
+ set_light(6)
else
- SetLuminosity(0)
+ set_light(0)
return
/obj/structure/prop/dam/torii/attack_hand(mob/user as mob)
@@ -510,10 +510,10 @@
/obj/structure/prop/turbine/proc/Update()
icon_state = "biomass_turbine[on ? "-on" : ""]"
if (on)
- SetLuminosity(3)
+ set_light(3)
playsound(src, 'sound/machines/turbine_on.ogg')
else
- SetLuminosity(0)
+ set_light(0)
playsound(src, 'sound/machines/turbine_off.ogg')
return
@@ -650,12 +650,19 @@
icon_state = "brazier"
density = TRUE
health = 150
- luminosity = 6
+ light_range = 6
+ light_on = TRUE
/// What obj this becomes when it gets to its next stage of construction / ignition
var/frame_type
/// What is used to progress to the next stage
var/state = STATE_COMPLETE
+/obj/structure/prop/brazier/Initialize()
+ . = ..()
+
+ if(!light_on)
+ set_light(0)
+
/obj/structure/prop/brazier/get_examine_text(mob/user)
. = ..()
switch(state)
@@ -686,20 +693,11 @@
new frame_type(loc)
qdel(src)
-/obj/structure/prop/brazier/Destroy()
- SetLuminosity(0)
- return ..()
-
-/obj/structure/prop/brazier/Initialize()
- . = ..()
- if(luminosity)
- SetLuminosity(luminosity)
-
/obj/structure/prop/brazier/frame
name = "empty brazier"
desc = "An empty brazier."
icon_state = "brazier_frame"
- luminosity = 0
+ light_on = FALSE
frame_type = /obj/structure/prop/brazier/frame/full
state = STATE_FUEL
@@ -715,7 +713,7 @@
desc = "It's a torch."
icon_state = "torch"
density = FALSE
- luminosity = 5
+ light_range = 5
/obj/structure/prop/brazier/frame/full/torch
name = "unlit torch"
@@ -840,7 +838,6 @@
addtimer(CALLBACK(src, PROC_REF(fuel_drain), TRUE), fuel_stage_time)
/obj/structure/prop/brazier/campfire/Destroy()
- SetLuminosity(0)
STOP_PROCESSING(SSobj, src)
return ..()
@@ -1119,7 +1116,8 @@
icon = 'icons/effects/fire.dmi'
icon_state = "dynamic_2"
layer = MOB_LAYER
- luminosity = 3
+ light_range = 3
+ light_on = TRUE
/obj/structure/prop/invuln/fusion_reactor
name = "\improper S-52 fusion reactor"
diff --git a/code/game/objects/structures/props/requests_console.dm b/code/game/objects/structures/props/requests_console.dm
index 95311bce9bad..7c4dd0b42992 100644
--- a/code/game/objects/structures/props/requests_console.dm
+++ b/code/game/objects/structures/props/requests_console.dm
@@ -4,7 +4,6 @@
anchored = TRUE
icon = 'icons/obj/structures/machinery/terminals.dmi'
icon_state = "req_comp0"
- luminosity = 0
/obj/structure/machinery/requests_console/power_change()
..()
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 090c5ad56f87..1a0469a5b9bf 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -36,7 +36,7 @@
LAZYADD(debris, shardtype)
update_nearby_icons()
-/obj/structure/window/Destroy()
+/obj/structure/window/Destroy(force)
density = FALSE
if(is_full_window())
update_nearby_icons()
@@ -507,7 +507,7 @@
relativewall()
relativewall_neighbours()
-/obj/structure/window/framed/Destroy()
+/obj/structure/window/framed/Destroy(force)
for(var/obj/effect/alien/weeds/weedwall/window/found_weedwall in get_turf(src))
qdel(found_weedwall)
var/list/turf/cardinal_neighbors = list(get_step(src, NORTH), get_step(src, SOUTH), get_step(src, EAST), get_step(src, WEST))
@@ -854,9 +854,11 @@
//icon_state = "rwindow0_debug" //Uncomment to check hull in the map editor
var/triggered = FALSE //indicates if the shutters have already been triggered
-/obj/structure/window/framed/prison/reinforced/hull/Destroy()
+/obj/structure/window/framed/prison/reinforced/hull/Destroy(force)
+ if(force)
+ return ..()
spawn_shutters()
- .=..()
+ . = ..()
/obj/structure/window/framed/prison/reinforced/hull/proc/spawn_shutters(from_dir = 0)
if(triggered)
@@ -864,16 +866,17 @@
triggered = TRUE
for(var/direction in cardinal)
- if(direction == from_dir) continue //doesn't check backwards
+ if(direction == from_dir)
+ continue //doesn't check backwards
for(var/obj/structure/window/framed/prison/reinforced/hull/W in get_step(src,direction) )
W.spawn_shutters(turn(direction,180))
- var/obj/structure/machinery/door/poddoor/shutters/almayer/pressure/P = new(get_turf(src))
+ var/obj/structure/machinery/door/poddoor/shutters/almayer/pressure/pressure_door = new(get_turf(src))
switch(junction)
if(4,5,8,9,12)
- P.setDir(SOUTH)
+ pressure_door.setDir(SOUTH)
else
- P.setDir(EAST)
- P.close()
+ pressure_door.setDir(EAST)
+ pressure_door.close()
/obj/structure/window/framed/prison/cell
name = "cell window"
@@ -943,9 +946,12 @@
window_frame = /obj/structure/window_frame/corsat/security
health = 400
-/obj/structure/window/framed/corsat/hull/Destroy()
+/obj/structure/window/framed/corsat/hull/Destroy(force)
+ if(force)
+ return ..()
+
spawn_shutters()
- .=..()
+ . = ..()
/obj/structure/window/framed/corsat/hull/proc/spawn_shutters(from_dir = 0)
if(triggered)
@@ -959,14 +965,14 @@
for(var/obj/structure/window/framed/corsat/hull/W in get_step(src,direction) )
W.spawn_shutters(turn(direction,180))
- var/obj/structure/machinery/door/poddoor/shutters/almayer/pressure/P = new(get_turf(src))
+ var/obj/structure/machinery/door/poddoor/shutters/almayer/pressure/pressure_door = new(get_turf(src))
switch(junction)
if(4,5,8,9,12)
- P.setDir(SOUTH)
+ pressure_door.setDir(SOUTH)
else
- P.setDir(EAST)
+ pressure_door.setDir(EAST)
- INVOKE_ASYNC(P, TYPE_PROC_REF(/obj/structure/machinery/door, close))
+ INVOKE_ASYNC(pressure_door, TYPE_PROC_REF(/obj/structure/machinery/door, close))
/obj/structure/window/framed/corsat/indestructible/
name = "hull window"
diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm
index 350d6047b2a4..4d60c6c263cf 100644
--- a/code/game/supplyshuttle.dm
+++ b/code/game/supplyshuttle.dm
@@ -18,30 +18,26 @@ var/datum/controller/supply/supply_controller = new()
/area/supply/station //DO NOT TURN THE lighting_use_dynamic STUFF ON FOR SHUTTLES. IT BREAKS THINGS.
name = "Supply Shuttle"
icon_state = "shuttle3"
- luminosity = 1
- lighting_use_dynamic = 0
+ base_lighting_alpha = 255
requires_power = 0
ambience_exterior = AMBIENCE_ALMAYER
/area/supply/dock //DO NOT TURN THE lighting_use_dynamic STUFF ON FOR SHUTTLES. IT BREAKS THINGS.
name = "Supply Shuttle"
icon_state = "shuttle3"
- luminosity = 1
- lighting_use_dynamic = 0
+ base_lighting_alpha = 255
requires_power = 0
/area/supply/station_vehicle //DO NOT TURN THE lighting_use_dynamic STUFF ON FOR SHUTTLES. IT BREAKS THINGS.
name = "Vehicle ASRS"
icon_state = "shuttle3"
- luminosity = 1
- lighting_use_dynamic = 0
+ base_lighting_alpha = 255
requires_power = 0
/area/supply/dock_vehicle //DO NOT TURN THE lighting_use_dynamic STUFF ON FOR SHUTTLES. IT BREAKS THINGS.
name = "Vehicle ASRS"
icon_state = "shuttle3"
- luminosity = 1
- lighting_use_dynamic = 0
+ base_lighting_alpha = 255
requires_power = 0
//SUPPLY PACKS MOVED TO /code/defines/obj/supplypacks.dm
diff --git a/code/game/turfs/auto_turf.dm b/code/game/turfs/auto_turf.dm
index 4556289da9ea..45756c30bb9c 100644
--- a/code/game/turfs/auto_turf.dm
+++ b/code/game/turfs/auto_turf.dm
@@ -183,7 +183,7 @@
L.forceMove(src)
L.pixel_x += rand(-5,5)
L.pixel_y += rand(-5,5)
- L.SetLuminosity(2)
+ L.set_light(2)
playsound(user, 'sound/weapons/Genhit.ogg', 25, 1)
//Digging up snow
diff --git a/code/game/turfs/floor.dm b/code/game/turfs/floor.dm
index dc2cda0c2c2a..5f99aba26c09 100644
--- a/code/game/turfs/floor.dm
+++ b/code/game/turfs/floor.dm
@@ -96,7 +96,7 @@
else if(is_light_floor())
icon_state = "light_broken"
broken = 1
- SetLuminosity(0)
+ set_light(0)
else if(is_plating())
icon_state = "platingdmg[pick(1, 2, 3)]"
broken = 1
@@ -135,7 +135,7 @@
//This proc auto corrects the grass tiles' siding.
/turf/open/floor/proc/make_plating()
- SetLuminosity(0)
+ set_light(0)
intact_tile = FALSE
broken = FALSE
burnt = FALSE
diff --git a/code/game/turfs/floors/desert.dm b/code/game/turfs/floors/desert.dm
index 4ecc0bf47cf7..46a481e3bc64 100644
--- a/code/game/turfs/floors/desert.dm
+++ b/code/game/turfs/floors/desert.dm
@@ -111,13 +111,13 @@
..()
switch(toxic)
if(1)
- SetLuminosity(2)
+ set_light(2)
icon = 'icons/turf/floors/desert_water_toxic.dmi'
if(0)
- SetLuminosity(1)
+ set_light(1)
icon = 'icons/turf/floors/desert_water.dmi'
if(-1)
- SetLuminosity(1)
+ set_light(1)
icon = 'icons/turf/floors/desert_water_transition.dmi'
/turf/open/desert/desert_shore/is_weedable()
@@ -196,13 +196,13 @@
..()
switch(toxic)
if(1)
- SetLuminosity(2)
+ set_light(2)
icon = 'icons/turf/floors/desert_water_toxic.dmi'
if(0)
- SetLuminosity(1)
+ set_light(1)
icon = 'icons/turf/floors/desert_water.dmi'
if(-1)
- SetLuminosity(1)
+ set_light(1)
icon = 'icons/turf/floors/desert_water_transition.dmi'
//Desert River Toxic
@@ -221,13 +221,13 @@
..()
switch(toxic)
if(1)
- SetLuminosity(2)
+ set_light(2)
icon = 'icons/turf/floors/desert_water_toxic.dmi'
if(0)
- SetLuminosity(1)
+ set_light(1)
icon = 'icons/turf/floors/desert_water.dmi'
if(-1)
- SetLuminosity(1)
+ set_light(1)
icon = 'icons/turf/floors/desert_water_transition.dmi'
update_overlays()
diff --git a/code/game/turfs/light.dm b/code/game/turfs/light.dm
index 694a51aad83a..219e79e93ef2 100644
--- a/code/game/turfs/light.dm
+++ b/code/game/turfs/light.dm
@@ -14,32 +14,32 @@
switch(state)
if(0)
icon_state = "light_on"
- SetLuminosity(5)
+ set_light(5)
if(1)
icon_state = "light_on-r"
- SetLuminosity(5)
+ set_light(5)
if(2)
icon_state = "light_on-g"
- SetLuminosity(5)
+ set_light(5)
if(3)
icon_state = "light_on-y"
- SetLuminosity(5)
+ set_light(5)
if(4)
icon_state = "light_on-p"
- SetLuminosity(5)
+ set_light(5)
if(5,-1)
icon_state = "light_on-w"
- SetLuminosity(5)
+ set_light(5)
state = -1
else
return //Should never happen ever but what if... returns into the other else which close the light
else if(broken)
icon_state = "light_broken" //It's the same sprite as light off, my artistic skill stops at stickmans anyone feel free to make a better one!
- SetLuminosity(0)
+ set_light(0)
else
icon_state = "light_off"
- SetLuminosity(0)
+ set_light(0)
on = FALSE
/turf/open/floor/light/attackby(obj/item/item_in_hand, mob/user)
diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm
index 41ac80bfdc58..c88f79b43293 100644
--- a/code/game/turfs/open.dm
+++ b/code/game/turfs/open.dm
@@ -304,7 +304,7 @@
L.forceMove(src)
L.pixel_x += rand(-5,5)
L.pixel_y += rand(-5,5)
- L.SetLuminosity(2)
+ L.set_light(2)
playsound(user, 'sound/weapons/Genhit.ogg', 25, 1)
return
@@ -797,7 +797,7 @@
L.forceMove(src)
L.pixel_x += rand(-5,5)
L.pixel_y += rand(-5,5)
- L.SetLuminosity(2)
+ L.set_light(2)
playsound(user, 'sound/weapons/Genhit.ogg', 25, 1)
return
diff --git a/code/game/turfs/snow.dm b/code/game/turfs/snow.dm
index cd5fcf56d15c..72b1f35d0aff 100644
--- a/code/game/turfs/snow.dm
+++ b/code/game/turfs/snow.dm
@@ -30,7 +30,7 @@
L.forceMove(src)
L.pixel_x += rand(-5,5)
L.pixel_y += rand(-5,5)
- L.SetLuminosity(2)
+ L.set_light(2)
playsound(user, 'sound/weapons/Genhit.ogg', 25, 1)
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index bc0375e0b850..26cad71ca23c 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -55,6 +55,14 @@
// Fishing
var/supports_fishing = FALSE // set to false when MRing, this is just for testing
+ ///Lumcount added by sources other than lighting datum objects, such as the overlay lighting component.
+ var/dynamic_lumcount = 0
+ ///List of light sources affecting this turf.
+ ///Which directions does this turf block the vision of, taking into account both the turf's opacity and the movable opacity_sources.
+ var/directional_opacity = NONE
+ ///Lazylist of movable atoms providing opacity sources.
+ var/list/atom/movable/opacity_sources
+
/turf/Initialize(mapload)
SHOULD_CALL_PARENT(FALSE) // this doesn't parent call for optimisation reasons
if(flags_atom & INITIALIZED)
@@ -85,10 +93,21 @@
for(var/atom/movable/AM in src)
Entered(AM)
- if(luminosity)
- if(light) WARNING("[type] - Don't set lights up manually during New(), We do it automatically.")
- trueLuminosity = luminosity * luminosity
- light = new(src)
+ if(light_power && light_range)
+ update_light()
+
+ //Get area light
+ var/area/current_area = loc
+ if(current_area?.lighting_effect)
+ overlays += current_area.lighting_effect
+
+ if(opacity)
+ directional_opacity = ALL_CARDINALS
+
+ //Get area light
+ var/area/A = loc
+ if(A?.lighting_effect)
+ overlays += A.lighting_effect
return INITIALIZE_HINT_NORMAL
@@ -356,8 +375,6 @@
if(/turf/baseturf_bottom)
path = /turf/open/floor/plating
- var/old_lumcount = lighting_lumcount - initial(lighting_lumcount)
-
//if(src.type == new_turf_path) // Put this back if shit starts breaking
// return src
@@ -365,6 +382,16 @@
var/list/old_baseturfs = baseturfs
+ //static lighting
+ var/old_lighting_object = static_lighting_object
+ var/old_lighting_corner_NE = lighting_corner_NE
+ var/old_lighting_corner_SE = lighting_corner_SE
+ var/old_lighting_corner_SW = lighting_corner_SW
+ var/old_lighting_corner_NW = lighting_corner_NW
+ //hybrid lighting
+ var/list/old_hybrid_lights_affecting = hybrid_lights_affecting?.Copy()
+ var/old_directional_opacity = directional_opacity
+
changing_turf = TRUE
qdel(src) //Just get the side effects and call Destroy
var/turf/W = new path(src)
@@ -380,10 +407,34 @@
W.linked_pylons = pylons
- W.lighting_lumcount += old_lumcount
- if(old_lumcount != W.lighting_lumcount)
- W.lighting_changed = 1
- SSlighting.changed_turfs += W
+ W.hybrid_lights_affecting = old_hybrid_lights_affecting
+ W.dynamic_lumcount = dynamic_lumcount
+
+ lighting_corner_NE = old_lighting_corner_NE
+ lighting_corner_SE = old_lighting_corner_SE
+ lighting_corner_SW = old_lighting_corner_SW
+ lighting_corner_NW = old_lighting_corner_NW
+
+ //static Update
+ if(SSlighting.initialized)
+ recalculate_directional_opacity()
+
+ W.static_lighting_object = old_lighting_object
+
+ if(static_lighting_object && !static_lighting_object.needs_update)
+ static_lighting_object.update()
+
+ //Since the old turf was removed from hybrid_lights_affecting, readd the new turf here
+ if(W.hybrid_lights_affecting)
+ for(var/atom/movable/lighting_mask/mask as anything in W.hybrid_lights_affecting)
+ LAZYADD(mask.affecting_turfs, W)
+
+ if(W.directional_opacity != old_directional_opacity)
+ W.reconsider_lights()
+
+ var/area/thisarea = get_area(W)
+ if(thisarea.lighting_effect)
+ W.overlays += thisarea.lighting_effect
W.levelupdate()
return W
@@ -760,13 +811,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
/turf/proc/copyTurf(turf/T)
if(T.type != type)
- var/obj/O
- if(underlays.len) //we have underlays, which implies some sort of transparency, so we want to a snapshot of the previous turf as an underlay
- O = new()
- O.underlays.Add(T)
T.ChangeTurf(type)
- if(underlays.len)
- T.underlays = O.underlays
if(T.icon_state != icon_state)
T.icon_state = icon_state
if(T.icon != icon)
diff --git a/code/game/turfs/walls/wall_types.dm b/code/game/turfs/walls/wall_types.dm
index 5338ae26c000..8262caef4258 100644
--- a/code/game/turfs/walls/wall_types.dm
+++ b/code/game/turfs/walls/wall_types.dm
@@ -125,7 +125,7 @@
operating = TRUE
flick("containment_wall_divide_lowering", src)
icon_state = "containment_wall_divide_lowered"
- SetOpacity(0)
+ set_opacity(0)
density = FALSE
operating = FALSE
change_weeds()
@@ -136,7 +136,7 @@
operating = TRUE
flick("containment_wall_divide_rising", src)
icon_state = "containment_wall_divide"
- SetOpacity(1)
+ set_opacity(1)
density = TRUE
operating = FALSE
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 368e2766ccfc..5e527e6a5442 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -133,7 +133,8 @@ var/list/admin_verbs_minor_event = list(
/client/proc/toggle_shipside_sd,
/client/proc/shakeshipverb,
/client/proc/adminpanelweapons,
- /client/proc/adminpanelgq,
+ /client/proc/admin_general_quarters,
+ /client/proc/admin_biohazard_alert,
/client/proc/toggle_hardcore_perma
)
diff --git a/code/modules/admin/verbs/adminpanelgq.dm b/code/modules/admin/verbs/adminpanelgq.dm
index 13b6e329aa69..8ef1ed869661 100644
--- a/code/modules/admin/verbs/adminpanelgq.dm
+++ b/code/modules/admin/verbs/adminpanelgq.dm
@@ -1,22 +1,24 @@
-/client/proc/adminpanelgq()
+/client/proc/admin_general_quarters()
set name = "Call General Quarters"
set category = "Admin.Ship"
if(security_level == SEC_LEVEL_RED || security_level == SEC_LEVEL_DELTA)
tgui_alert(src, "Security is already red or above, General Quarters cannot be called.", "Acknowledge!", list("ok."), 10 SECONDS)
- else
- var/whattoannounce = "ATTENTION! GENERAL QUARTERS. ALL HANDS, MAN YOUR BATTLESTATIONS."
- var/prompt = tgui_alert(src, "Do you want to leave the announcement as the default one?", "Choose.", list("Yes", "No"), 20 SECONDS)
- if(prompt == "No")
- whattoannounce = tgui_input_text(src, "Please enter announcement text.", "what?")
- prompt = tgui_alert(src, "Are you sure you want to send General Quarters? This will force red alert.", "Choose.", list("Yes", "No"), 20 SECONDS)
- if(prompt == "Yes")
- set_security_level(2, no_sound=1, announce=0)
- shipwide_ai_announcement(whattoannounce, MAIN_AI_SYSTEM, 'sound/effects/GQfullcall.ogg')
- message_admins("[key_name_admin(src)] Sent General Quarters with a custom announcement!")
- else
- prompt = tgui_alert(src, "Are you sure you want to send General Quarters? This will force red alert.", "Choose.", list("Yes", "No"), 20 SECONDS)
- if(prompt == "Yes")
- set_security_level(2, no_sound=1, announce=0)
- shipwide_ai_announcement(whattoannounce, MAIN_AI_SYSTEM, 'sound/effects/GQfullcall.ogg')
- message_admins("[key_name_admin(src)] Sent General Quarters!")
+ return FALSE
+
+ var/prompt = tgui_alert(src, "Are you sure you want to send General Quarters? This will force red alert.", "Choose.", list("Yes", "No"), 20 SECONDS)
+ if(prompt != "Yes")
+ return FALSE
+
+ var/whattoannounce = "ATTENTION! GENERAL QUARTERS. ALL HANDS, MAN YOUR BATTLESTATIONS."
+ var/log = "[key_name_admin(src)] Sent General Quarters!"
+
+ prompt = tgui_alert(src, "Do you want to use a custom announcement?", "Choose.", list("Yes", "No"), 20 SECONDS)
+ if(prompt == "Yes")
+ whattoannounce = tgui_input_text(src, "Please enter announcement text.", "what?")
+ log = "[key_name_admin(src)] Sent General Quarters! (Using a custom announcement)"
+
+ set_security_level(SEC_LEVEL_RED, TRUE, FALSE)
+ shipwide_ai_announcement(whattoannounce, MAIN_AI_SYSTEM, 'sound/effects/GQfullcall.ogg')
+ message_admins(log)
+ return TRUE
diff --git a/code/modules/admin/verbs/mob_verbs.dm b/code/modules/admin/verbs/mob_verbs.dm
index 376115c0d630..4809d9b2e6ee 100644
--- a/code/modules/admin/verbs/mob_verbs.dm
+++ b/code/modules/admin/verbs/mob_verbs.dm
@@ -81,7 +81,7 @@
H = huds[MOB_HUD_XENO_STATUS]
else return
- H.add_hud_to(M)
+ H.add_hud_to(M, HUD_SOURCE_ADMIN)
to_chat(src, SPAN_INFO("[hud_choice] enabled."))
message_admins(SPAN_INFO("[key_name(usr)] has given a [hud_choice] to [M]."))
diff --git a/code/modules/autowiki/pages/guns.dm b/code/modules/autowiki/pages/guns.dm
index 0946b552fe31..ad675c51a409 100644
--- a/code/modules/autowiki/pages/guns.dm
+++ b/code/modules/autowiki/pages/guns.dm
@@ -97,9 +97,10 @@
))
gun_data["attachments"] = attachments
-
- upload_icon(getFlatIcon(generating_gun, no_anim = TRUE), filename)
- gun_data["icon"] = filename
+ var/icon/generated_icon = getFlatIcon(generating_gun, no_anim = TRUE)
+ if(generated_icon)
+ upload_icon(generated_icon, filename)
+ gun_data["icon"] = filename
output += include_template("Autowiki/Gun", gun_data)
diff --git a/code/modules/client/preferences_gear.dm b/code/modules/client/preferences_gear.dm
index e712e267fb2d..106da02a00b6 100644
--- a/code/modules/client/preferences_gear.dm
+++ b/code/modules/client/preferences_gear.dm
@@ -515,6 +515,12 @@ var/global/list/gear_datums_by_name = list()
display_name = "D18 Holdout Pistol"
path = /obj/item/storage/box/clf
+/datum/gear/weapon/upppistol //ww2 war trophy luger
+ display_name = "Type 73 Pistol"
+ path = /obj/item/storage/box/upp
+ slot = WEAR_IN_BACK
+ cost = 4
+
/datum/gear/weapon/m4a3_custom
display_name = "M4A3 Custom Pistol"
path = /obj/item/weapon/gun/pistol/m4a3/custom
diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm
index b81411a26440..b600b39a0018 100644
--- a/code/modules/client/preferences_toggles.dm
+++ b/code/modules/client/preferences_toggles.dm
@@ -623,7 +623,7 @@
if(!isobserver(usr))
return
- var/mob/dead/observer/O = usr
+ var/mob/dead/observer/observer_user = usr
var/datum/mob_hud/H
switch(hud_choice)
if("Medical HUD")
@@ -643,11 +643,11 @@
if("Faction CLF HUD")
H = huds[MOB_HUD_FACTION_CLF]
- O.HUD_toggled[hud_choice] = prefs.observer_huds[hud_choice]
- if(O.HUD_toggled[hud_choice])
- H.add_hud_to(O)
+ observer_user.HUD_toggled[hud_choice] = prefs.observer_huds[hud_choice]
+ if(observer_user.HUD_toggled[hud_choice])
+ H.add_hud_to(observer_user, observer_user)
else
- H.remove_hud_from(O)
+ H.remove_hud_from(observer_user, observer_user)
/client/proc/toggle_ghost_health_scan()
set name = "Toggle Health Scan"
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index 7bcf1dd6645c..a7844631051e 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -70,10 +70,10 @@
if(hud_type)
var/datum/mob_hud/MH = huds[hud_type]
if(active)
- MH.add_hud_to(H)
+ MH.add_hud_to(H, src)
playsound(H, 'sound/handling/hud_on.ogg', 25, 1)
else
- MH.remove_hud_from(H)
+ MH.remove_hud_from(H, src)
playsound(H, 'sound/handling/hud_off.ogg', 25, 1)
if(active) //turning it on? then add the traits
for(var/trait in clothing_traits)
@@ -95,7 +95,7 @@
else if(hud_type)
var/datum/mob_hud/MH = huds[hud_type]
- MH.add_hud_to(user)
+ MH.add_hud_to(user, src)
user.update_sight()
..()
@@ -103,7 +103,7 @@
if(hud_type && active && istype(user))
if(src == user.glasses) //dropped is called before the inventory reference is updated.
var/datum/mob_hud/H = huds[hud_type]
- H.remove_hud_from(user)
+ H.remove_hud_from(user, src)
user.glasses = null
user.update_inv_glasses()
user.update_sight()
diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm
index f5baeb804412..1a133eee0dfe 100644
--- a/code/modules/clothing/glasses/hud.dm
+++ b/code/modules/clothing/glasses/hud.dm
@@ -109,7 +109,7 @@
deactive_state = "sensorhud_d"
flags_armor_protection = 0
toggleable = TRUE
- hud_type = MOB_HUD_MEDICAL_BASIC
+ hud_type = MOB_HUD_MEDICAL_ADVANCED
actions_types = list(/datum/action/item_action/toggle)
req_skill = SKILL_MEDICAL
req_skill_level = SKILL_MEDICAL_DEFAULT
diff --git a/code/modules/clothing/glasses/night.dm b/code/modules/clothing/glasses/night.dm
index 63d0c8f364af..afb711c3ca15 100644
--- a/code/modules/clothing/glasses/night.dm
+++ b/code/modules/clothing/glasses/night.dm
@@ -15,6 +15,7 @@
vision_flags = SEE_TURFS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
fullscreen_vision = null
+ eye_protection = EYE_PROTECTION_NEGATIVE
/obj/item/clothing/glasses/night/helmet //for the integrated NVGs that are in helmetgarb code
name = "\improper M2 night vision goggles"
diff --git a/code/modules/clothing/glasses/thermal.dm b/code/modules/clothing/glasses/thermal.dm
index bfc60d271724..b2ec7597e270 100644
--- a/code/modules/clothing/glasses/thermal.dm
+++ b/code/modules/clothing/glasses/thermal.dm
@@ -12,7 +12,7 @@
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
darkness_view = 12
invisa_view = 2
- eye_protection = -1
+ eye_protection = EYE_PROTECTION_NEGATIVE
deactive_state = "goggles_off"
fullscreen_vision = /atom/movable/screen/fullscreen/thermal
var/blinds_on_emp = TRUE
diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm
index 165dc03f25e2..d94789651b75 100644
--- a/code/modules/clothing/head/hardhat.dm
+++ b/code/modules/clothing/head/hardhat.dm
@@ -3,8 +3,8 @@
desc = "A piece of headgear used in dangerous working conditions to protect the head. Comes with a built-in flashlight."
icon_state = "hardhat0_yellow"
item_state = "hardhat0_yellow"
- var/brightness_on = 4 //luminosity when on
- var/on = FALSE
+ light_range = 4
+ light_power = 2
var/hardhat_color = "yellow" //Determines used sprites: hardhat[on]_[hardhat_color]
var/toggleable = TRUE
armor_melee = CLOTHING_ARMOR_MEDIUM
@@ -30,87 +30,52 @@
/obj/item/clothing/head/hardhat/update_icon()
. = ..()
- if(on)
- icon_state = "hardhat[on]_[hardhat_color]"
- item_state = "hardhat[on]_[hardhat_color]"
+ if(light_on)
+ icon_state = "hardhat[light_on]_[hardhat_color]"
+ item_state = "hardhat[light_on]_[hardhat_color]"
else
icon_state = initial(icon_state)
item_state = initial(item_state)
-/obj/item/clothing/head/hardhat/proc/update_brightness(mob/user)
- if(on)
- update_icon()
- if(loc == user)
- user.SetLuminosity(brightness_on, FALSE, src)
- else if(isturf(loc))
- SetLuminosity(brightness_on)
- else
- icon_state = initial(icon_state)
- if(loc == user)
- user.SetLuminosity(0, FALSE, src)
- else if(isturf(loc))
- SetLuminosity(0)
-
/obj/item/clothing/head/hardhat/attack_self(mob/user)
- ..()
+ . = ..()
if(!toggleable)
to_chat(user, SPAN_WARNING("You cannot toggle [src] on or off."))
return FALSE
if(!isturf(user.loc))
- to_chat(user, SPAN_WARNING("You cannot turn the light [on ? "off" : "on"] while in [user.loc].")) //To prevent some lighting anomalies.
+ to_chat(user, SPAN_WARNING("You cannot turn the light [light_on ? "off" : "on"] while in [user.loc].")) //To prevent some lighting anomalies.
return FALSE
- on = !on
- update_brightness(user)
+ turn_light(user, !light_on)
+
+/obj/item/clothing/head/hardhat/turn_light(mob/user, toggle_on)
+
+ . = ..()
+ if(. != CHECKS_PASSED)
+ return
+
+ set_light_on(toggle_on)
+ if(user == loc)
+ user.update_inv_head()
+
for(var/datum/action/current_action as anything in actions)
current_action.update_button_icon()
- if(ismob(loc))
- var/mob/M = loc
- M.update_inv_head()
-
- return TRUE
+ update_icon()
-/obj/item/clothing/head/hardhat/proc/turn_off_light(mob/bearer)
- if(on)
- on = FALSE
- update_brightness(bearer)
- for(var/X in actions)
- var/datum/action/A = X
- A.update_button_icon()
- return TRUE
- return FALSE
+/obj/item/clothing/head/hardhat/attack_alien(mob/living/carbon/xenomorph/attacking_xeno)
+ if(!can_be_broken)
+ return
-/obj/item/clothing/head/hardhat/attack_alien(mob/living/carbon/xenomorph/M)
- . = ..()
+ if(turn_light(attacking_xeno, toggle_on = FALSE) != CHECKS_PASSED)
+ return
- if(on && can_be_broken)
- if(breaking_sound)
- playsound(src.loc, breaking_sound, 25, 1)
- on = FALSE
- update_brightness()
-
-/obj/item/clothing/head/hardhat/pickup(mob/user)
- if(on)
- user.SetLuminosity(brightness_on, FALSE, src)
- SetLuminosity(0)
- ..()
-
-/obj/item/clothing/head/hardhat/dropped(mob/user)
- if(on)
- user.SetLuminosity(0, FALSE, src)
- SetLuminosity(brightness_on)
- ..()
-
-/obj/item/clothing/head/hardhat/Destroy()
- if(ismob(src.loc))
- src.loc.SetLuminosity(0, FALSE, src)
- else
- SetLuminosity(0)
- return ..()
+ if(!breaking_sound)
+ return
+ playsound(loc, breaking_sound, 25, 1)
/obj/item/clothing/head/hardhat/orange
icon_state = "hardhat0_orange"
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index 0181d239c574..9da634eaba3e 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -360,6 +360,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
var/flags_marine_helmet = HELMET_SQUAD_OVERLAY|HELMET_GARB_OVERLAY|HELMET_DAMAGE_OVERLAY
var/helmet_bash_cooldown = 0
+ //speciality does NOTHING if you have NO_NAME_OVERRIDE
var/specialty = "M10 pattern marine" //Give them a specialty var so that they show up correctly in vendors. speciality does NOTHING if you have NO_NAME_OVERRIDE.
valid_accessory_slots = list(ACCESSORY_SLOT_HELM_C)
restricted_accessory_slots = list(ACCESSORY_SLOT_HELM_C)
@@ -372,11 +373,27 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
var/storage_slots_reserved_for_garb = 1
var/storage_max_w_class = SIZE_TINY // can hold tiny items only, EXCEPT for glasses & metal flask.
var/storage_max_storage_space = 4
+
/// The dmi where the grayscale squad overlays are contained
var/helmet_overlay_icon = 'icons/mob/humans/onmob/head_1.dmi'
-/obj/item/clothing/head/helmet/marine/New(loc,
- new_protection[] = list(MAP_ICE_COLONY = ICE_PLANET_MIN_COLD_PROT))
+ ///Any visors built into the helmet
+ var/list/built_in_visors = list(new /obj/item/device/helmet_visor)
+
+ ///Any visors that have been added into the helmet
+ var/list/inserted_visors = list()
+
+ ///Max amount of inserted visors
+ var/max_inserted_visors = 1
+
+ ///The current active visor that is shown
+ var/obj/item/device/helmet_visor/active_visor = null
+
+ ///Designates a visor type that should start down when initialized
+ var/start_down_visor_type
+
+/obj/item/clothing/head/helmet/marine/Initialize(mapload, new_protection[] = list(MAP_ICE_COLONY = ICE_PLANET_MIN_COLD_PROT))
+ . = ..()
if(!(flags_atom & NO_NAME_OVERRIDE))
name = "[specialty]"
if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD])
@@ -385,7 +402,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
name += " helmet"
if(!(flags_atom & NO_SNOW_TYPE))
- select_gamemode_skin(type,null,new_protection)
+ select_gamemode_skin(type, null, new_protection)
helmet_overlays = list() //To make things simple.
@@ -399,7 +416,24 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
camera = new /obj/structure/machinery/camera(src)
camera.network = list(CAMERA_NET_OVERWATCH)
- ..()
+ if(length(inserted_visors) || length(built_in_visors))
+ var/datum/action/item_action/cycle_helmet_huds/new_action = new(src)
+ LAZYADD(actions, new_action)
+ if(ishuman(loc))
+ var/mob/living/carbon/human/holding_human = loc
+ if(holding_human.head == src)
+ new_action.give_to(holding_human)
+
+ if(start_down_visor_type)
+ for(var/obj/item/device/helmet_visor/cycled_visor in (built_in_visors + inserted_visors))
+ if(cycled_visor.type == start_down_visor_type)
+ active_visor = cycled_visor
+ break
+
+ if(active_visor)
+ var/datum/action/item_action/cycle_helmet_huds/cycle_action = locate() in actions
+ if(cycle_action)
+ cycle_action.set_action_overlay(active_visor)
/obj/item/clothing/head/helmet/marine/Destroy(force)
helmet_overlays = null
@@ -421,9 +455,9 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
if(pockets.handle_mousedrop(usr, over_object))
..()
-/obj/item/clothing/head/helmet/marine/attackby(obj/item/W, mob/user)
- if(istype(W, /obj/item/ammo_magazine) && world.time > helmet_bash_cooldown && user)
- var/obj/item/ammo_magazine/M = W
+/obj/item/clothing/head/helmet/marine/attackby(obj/item/attacking_item, mob/user)
+ if(istype(attacking_item, /obj/item/ammo_magazine) && world.time > helmet_bash_cooldown && user)
+ var/obj/item/ammo_magazine/M = attacking_item
var/ammo_level = "somewhat"
playsound(user, 'sound/items/trayhit1.ogg', 15, FALSE)
if(M.current_rounds > (M.max_rounds/2))
@@ -436,9 +470,48 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
ammo_level = "empty. Uh oh."
user.visible_message("[user] bashes [M] against their helmet", "You bash [M] against your helmet. It is [ammo_level]")
helmet_bash_cooldown = world.time + 20 SECONDS
- else
- ..()
- return pockets.attackby(W, user)
+ return
+
+ if(istype(attacking_item, /obj/item/device/helmet_visor))
+ if(length(inserted_visors) >= max_inserted_visors)
+ to_chat(user, SPAN_NOTICE("[src] has used all of its visor attachment sockets."))
+ return
+
+ var/obj/item/device/helmet_visor/new_visor = attacking_item
+ for(var/obj/item/device/helmet_visor/cycled_visor as anything in (built_in_visors + inserted_visors))
+ if(cycled_visor.type == new_visor.type)
+ to_chat(user, SPAN_NOTICE("[src] already has this type of HUD connected."))
+ return
+ if(!user.drop_held_item())
+ return
+
+ inserted_visors += new_visor
+ to_chat(user, SPAN_NOTICE("You connect [new_visor] to [src]."))
+ new_visor.forceMove(src)
+ if(!(locate(/datum/action/item_action/cycle_helmet_huds) in actions))
+ var/datum/action/item_action/cycle_helmet_huds/new_action = new(src)
+ new_action.give_to(user)
+ return
+
+ if(HAS_TRAIT(attacking_item, TRAIT_TOOL_SCREWDRIVER) && length(inserted_visors))
+ for(var/obj/item/device/visor as anything in inserted_visors)
+ visor.forceMove(get_turf(src))
+
+ inserted_visors = list()
+ to_chat(user, SPAN_NOTICE("You remove the inserted visors."))
+ turn_off_visor(user, active_visor, TRUE)
+
+ var/datum/action/item_action/cycle_helmet_huds/cycle_action = locate() in actions
+ cycle_action.set_default_overlay()
+ if(!length(built_in_visors))
+ cycle_action.remove_from(user)
+
+ active_visor = null
+ recalculate_visors(user)
+ return
+
+ ..()
+ return pockets.attackby(attacking_item, user)
/obj/item/clothing/head/helmet/marine/on_pocket_insertion()
update_icon()
@@ -478,6 +551,9 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
else
helmet_overlays = above_band_layer + below_band_layer
+ if(active_visor)
+ helmet_overlays += active_visor.helmet_overlay
+
if(ismob(loc))
var/mob/M = loc
M.update_inv_head()
@@ -485,22 +561,28 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
/obj/item/clothing/head/helmet/marine/equipped(mob/living/carbon/human/mob, slot)
if(camera)
camera.c_tag = mob.name
+ if(active_visor)
+ recalculate_visors(mob)
..()
/obj/item/clothing/head/helmet/marine/unequipped(mob/user, slot)
. = ..()
if(pockets)
for(var/obj/item/attachable/flashlight/F in pockets)
- if(F.activated)
+ if(F.light_on)
F.activate_attachment(src, user, TRUE)
+ if(active_visor)
+ recalculate_visors(user)
/obj/item/clothing/head/helmet/marine/dropped(mob/living/carbon/human/mob)
if(camera)
camera.c_tag = "Unknown"
if(pockets)
for(var/obj/item/attachable/flashlight/F in pockets)
- if(F.activated)
+ if(F.light_on)
F.activate_attachment(src, mob, TRUE)
+ if(active_visor)
+ recalculate_visors(mob)
..()
/obj/item/clothing/head/helmet/marine/has_garb_overlay()
@@ -518,59 +600,122 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
return pockets
return ..()
-/obj/item/clothing/head/helmet/marine/tech
- name = "\improper M10 technician helmet"
- desc = "A modified M10 marine helmet for ComTechs. Features a toggleable welding screen for eye protection."
- icon_state = "tech_helmet"
- specialty = "M10 technician"
- var/protection_on = FALSE
- ///To remember the helmet's map variant-adjusted icon state
- var/base_icon_state
+/// Recalculates and sets the proper visor effects
+/obj/item/clothing/head/helmet/marine/proc/recalculate_visors(mob/user)
+ turn_off_visors(user)
- actions_types = list(/datum/action/item_action/toggle)
- vision_impair = VISION_IMPAIR_NONE
+ if(!active_visor)
+ return
-/obj/item/clothing/head/helmet/marine/tech/Initialize()
- . = ..()
- base_icon_state = icon_state
+ if(user != loc)
+ return
-/obj/item/clothing/head/helmet/marine/tech/attack_self(mob/user)
- ..()
- toggle()
+ var/mob/living/carbon/human/human_user = user
+ if(!human_user || human_user.head != src)
+ return
-/obj/item/clothing/head/helmet/marine/tech/verb/toggle()
- set category = "Object"
- set name = "Toggle Tech Helmet"
- set src in usr
+ turn_on_visor(human_user)
- if(usr.canmove && !usr.stat && !usr.is_mob_restrained())
- if(protection_on)
- vision_impair = VISION_IMPAIR_NONE
- flags_inventory &= ~(COVEREYES|COVERMOUTH)
- flags_inv_hide &= ~(HIDEEYES|HIDEFACE)
- icon_state = base_icon_state
- eye_protection = EYE_PROTECTION_NONE
- to_chat(usr, "You deactivate the [src]'s welding screen.")
- else
- vision_impair = VISION_IMPAIR_MAX
- flags_inventory |= COVEREYES|COVERMOUTH
- flags_inv_hide |= HIDEEYES|HIDEFACE
- icon_state = "[base_icon_state]_on"
- eye_protection = EYE_PROTECTION_WELDING
- to_chat(usr, "You activate the [src]'s welding screen.")
+/// Turns on the current active visor
+/obj/item/clothing/head/helmet/marine/proc/turn_on_visor(mob/user)
+ if(!active_visor)
+ return
- protection_on = !protection_on
+ if(active_visor.can_toggle(user))
+ active_visor.visor_function(src, user)
- if(ishuman(loc))
- var/mob/living/carbon/human/H = loc
- if(H.head == src)
- H.update_tint()
+ playsound_client(user.client, active_visor.toggle_on_sound, null, 75)
+ update_icon()
+
+/// Turns off the specified visor
+/obj/item/clothing/head/helmet/marine/proc/turn_off_visor(mob/user, obj/item/device/helmet_visor/current_visor, sound = FALSE)
+ if(!current_visor)
+ return
+
+ if(current_visor.can_toggle(user))
+ current_visor.visor_function(src, user)
+
+ if(sound)
+ playsound_client(user.client, current_visor.toggle_off_sound, null, 75)
+ update_icon()
+
+/// Attempts to turn off all visors
+/obj/item/clothing/head/helmet/marine/proc/turn_off_visors(mob/user)
+ var/list/total_visors = built_in_visors + inserted_visors
+
+ for(var/obj/item/device/helmet_visor/cycled_helmet_visor in total_visors)
+ if(cycled_helmet_visor.can_toggle(user))
+ cycled_helmet_visor.visor_function(src, user, TRUE)
+
+ update_icon()
+
+///Cycles the active HUD to the next between built_in_visors and inserted_visors, nullifies if at end and removes all HUDs
+/obj/item/clothing/head/helmet/marine/proc/cycle_huds(mob/user)
+ var/list/total_visors = built_in_visors + inserted_visors
+
+ if(!length(total_visors))
+ return FALSE
+
+ if(active_visor)
+ var/iterator = 1
+ for(var/hud_type in total_visors)
+ if(hud_type == active_visor)
+ if(length(total_visors) > iterator)
+ turn_off_visor(user, active_visor, FALSE)
+ active_visor = total_visors[(iterator + 1)]
+ recalculate_visors(user)
+ return active_visor
+ else
+ turn_off_visor(user, active_visor, TRUE)
+ active_visor = null
+ recalculate_visors(user)
+ return FALSE
+ iterator++
+
+ if(total_visors[1])
+ active_visor = total_visors[1]
+ recalculate_visors(user)
+ return active_visor
+
+ active_visor = null
+ recalculate_visors(user)
+ return FALSE
+
+/datum/action/item_action/cycle_helmet_huds/New(Target, obj/item/holder)
+ . = ..()
+ name = "Cycle helmet HUD"
+ button.name = name
+ set_default_overlay()
+
+/datum/action/item_action/cycle_helmet_huds/action_activate()
+ . = ..()
+ var/obj/item/clothing/head/helmet/marine/holder_helmet = holder_item
+ var/cycled_hud = holder_helmet.cycle_huds(usr)
+
+ set_action_overlay(cycled_hud)
- update_clothing_icon() //so our mob-overlays update
+/// Sets the action overlay based on the visor type
+/datum/action/item_action/cycle_helmet_huds/proc/set_action_overlay(obj/item/device/helmet_visor/new_visor)
+ if(!new_visor)
+ set_default_overlay()
+ return
- for(var/X in actions)
- var/datum/action/A = X
- A.update_button_icon()
+ action_icon_state = new_visor.action_icon_string
+ button.overlays.Cut()
+ button.overlays += image('icons/obj/items/clothing/helmet_visors.dmi', button, action_icon_state)
+
+/// Sets the action overlay to default hud sight up
+/datum/action/item_action/cycle_helmet_huds/proc/set_default_overlay()
+ action_icon_state = "hud_sight_up"
+ button.overlays.Cut()
+ button.overlays += image('icons/obj/items/clothing/helmet_visors.dmi', button, action_icon_state)
+
+/obj/item/clothing/head/helmet/marine/tech
+ name = "\improper M10 technician helmet"
+ desc = "A modified M10 marine helmet for ComTechs. Features a toggleable welding screen for eye protection."
+ icon_state = "tech_helmet"
+ specialty = "M10 technician"
+ built_in_visors = list(new /obj/item/device/helmet_visor, new /obj/item/device/helmet_visor/welding_visor)
/obj/item/clothing/head/helmet/marine/tech/tanker
name = "\improper M50 tanker helmet"
@@ -583,12 +728,15 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
flags_inventory = BLOCKSHARPOBJ
flags_inv_hide = HIDEEARS|HIDETOPHAIR
specialty = "M50 tanker"
+ built_in_visors = list(new /obj/item/device/helmet_visor, new /obj/item/device/helmet_visor/welding_visor/tanker)
/obj/item/clothing/head/helmet/marine/medic
name = "\improper M10 corpsman helmet"
desc = "An M10 marine helmet version worn by marine hospital corpsmen. Has red cross painted on its front."
icon_state = "med_helmet"
specialty = "M10 pattern medic"
+ built_in_visors = list(new /obj/item/device/helmet_visor, new /obj/item/device/helmet_visor/medical/advanced)
+ start_down_visor_type = /obj/item/device/helmet_visor/medical/advanced
/obj/item/clothing/head/helmet/marine/covert
name = "\improper M10 covert helmet"
@@ -613,16 +761,17 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
/obj/item/clothing/head/helmet/marine/rto
name = "\improper M12 pattern dust helmet"
- desc = "An experimental brain-bucket. A dust ruffle hangs from back instead of the standard lobster shell design. Moderately better at deflecting blunt objects at the cost of humiliation. But who will be laughing at the memorial? Not you, you'll be busy getting medals for your fantastic leadership."
+ desc = "An experimental brain-bucket. A dust ruffle hangs from back instead of the standard lobster shell design. Moderately better at deflecting blunt objects at the cost of humiliation, can also hold a second visor optic. But who will be laughing at the memorial? Not you, you'll be busy getting medals for your fantastic leadership."
icon_state = "io"
item_state = "io"
armor_melee = CLOTHING_ARMOR_MEDIUMHIGH
armor_bio = CLOTHING_ARMOR_MEDIUMHIGH
specialty = "M12 pattern"
+ max_inserted_visors = 2
/obj/item/clothing/head/helmet/marine/rto/intel
name = "\improper XM12 pattern intelligence helmet"
- desc = "An experimental brain-bucket. A dust ruffle hangs from back. Moderately better at deflecting blunt objects at the cost of humiliation. But who will be laughing at the memorial? Not you, you'll be busy getting medals for your intel work."
+ desc = "An experimental brain-bucket. A dust ruffle hangs from back. Moderately better at deflecting blunt objects at the cost of humiliation, can also hold a second visor optic. But who will be laughing at the memorial? Not you, you'll be busy getting medals for your intel work."
specialty = "XM12 pattern intel"
/obj/item/clothing/head/helmet/marine/specialist
@@ -729,6 +878,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
armor_bio = CLOTHING_ARMOR_MEDIUMHIGH
specialty = "M10 pattern captain"
flags_atom = NO_SNOW_TYPE
+ built_in_visors = list(new /obj/item/device/helmet_visor, new /obj/item/device/helmet_visor/medical/advanced, new /obj/item/device/helmet_visor/security)
/obj/item/clothing/head/helmet/marine/MP
name = "\improper M10 pattern MP helmet"
@@ -737,6 +887,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
item_state = "mp_helmet"
armor_energy = CLOTHING_ARMOR_MEDIUMLOW
specialty = "M10 pattern military police"
+ built_in_visors = list(new /obj/item/device/helmet_visor/security)
/obj/item/clothing/head/helmet/marine/MP/WO
name = "\improper M3 pattern chief MP helmet"
@@ -751,6 +902,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
icon_state = "helmet"
item_state = "helmet"
specialty = "M10 pattern officer"
+ built_in_visors = list(new /obj/item/device/helmet_visor, new /obj/item/device/helmet_visor/medical/advanced)
/obj/item/clothing/head/helmet/marine/mp/provost/marshal
name = "\improper Provost Marshal Cap"
@@ -770,6 +922,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
armor_bio = CLOTHING_ARMOR_MEDIUMHIGH
specialty = "M10 pattern SOF"
flags_atom = NO_SNOW_TYPE
+ built_in_visors = list(new /obj/item/device/helmet_visor, new /obj/item/device/helmet_visor/medical, new /obj/item/device/helmet_visor/security)
//=============================//PMCS\\==================================\\
@@ -777,6 +930,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
/obj/item/clothing/head/helmet/marine/veteran
flags_atom = NO_SNOW_TYPE|NO_NAME_OVERRIDE //Let's make these keep their name and icon.
+ built_in_visors = list()
/obj/item/clothing/head/helmet/marine/veteran/pmc
name = "\improper PMC tactical cap"
@@ -926,6 +1080,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
armor_rad = CLOTHING_ARMOR_MEDIUMLOW
armor_internaldamage = CLOTHING_ARMOR_HIGH
min_cold_protection_temperature = ICE_PLANET_MIN_COLD_PROT
+ clothing_traits = list(TRAIT_EAR_PROTECTION) //the sprites clearly fully cover the ears and most of the head
/obj/item/clothing/head/helmet/marine/veteran/UPP/engi
name = "\improper UM4-V helmet"
@@ -1137,44 +1292,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
/obj/item/clothing/head/helmet/marine/veteran/mercenary/support/engineer
desc = "A sturdy helmet worn by an unknown mercenary group. Features a toggleable welding screen for eye protection."
- var/protection_on = FALSE
-
- actions_types = list(/datum/action/item_action/toggle)
- vision_impair = VISION_IMPAIR_NONE
-
-/obj/item/clothing/head/helmet/marine/veteran/mercenary/support/engineer/attack_self(mob/user)
- ..()
- toggle()
-
-/obj/item/clothing/head/helmet/marine/veteran/mercenary/support/engineer/verb/toggle()
- set category = "Object"
- set name = "Toggle Helmet Welding Visor"
- set src in usr
-
- if(usr.canmove && !usr.stat && !usr.is_mob_restrained())
- if(protection_on)
- vision_impair = VISION_IMPAIR_NONE
- flags_inventory &= ~(COVEREYES|COVERMOUTH)
- flags_inv_hide &= ~(HIDEEYES|HIDEFACE)
- eye_protection = EYE_PROTECTION_NONE
- to_chat(usr, "You deactivate the [src]'s welding screen.")
- else
- vision_impair = VISION_IMPAIR_MAX
- flags_inventory |= COVEREYES|COVERMOUTH
- flags_inv_hide |= HIDEEYES|HIDEFACE
- eye_protection = EYE_PROTECTION_WELDING
- to_chat(usr, "You activate the [src]'s welding screen.")
-
- protection_on = !protection_on
-
- if(ishuman(loc))
- var/mob/living/carbon/human/H = loc
- if(H.head == src)
- H.update_tint()
-
- for(var/X in actions)
- var/datum/action/A = X
- A.update_button_icon()
+ built_in_visors = list(new /obj/item/device/helmet_visor/welding_visor/mercenary)
//=============================//MEME\\==================================\\
//=======================================================================\\
@@ -1193,6 +1311,8 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
armor_melee = CLOTHING_ARMOR_VERYHIGH
armor_bomb = CLOTHING_ARMOR_GIGAHIGH
+ built_in_visors = list()
+
var/mob/activator = null
var/active = FALSE
var/det_time = 40
@@ -1243,4 +1363,6 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list(
contained_sprite = TRUE
flags_atom = NO_SNOW_TYPE|NO_NAME_OVERRIDE
+ built_in_visors = list()
+
#undef HELMET_GARB_RELAY_ICON_STATE
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index e6dd7be603df..102d8241754f 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -137,25 +137,7 @@
icon_state = "hardhat[on]_pumpkin"
if(on)
- user.SetLuminosity(brightness_on, FALSE, src)
+ set_light_range(brightness_on)
+ set_light_on(TRUE)
else
- user.SetLuminosity(0, FALSE, src)
-
-/obj/item/clothing/head/pumpkinhead/pickup(mob/user)
- ..()
- if(on)
- user.SetLuminosity(brightness_on, FALSE, src)
- SetLuminosity(0)
-
-/obj/item/clothing/head/pumpkinhead/dropped(mob/user)
- ..()
- if(on)
- user.SetLuminosity(0, FALSE, src)
- SetLuminosity(brightness_on)
-
-/obj/item/clothing/head/pumpkinhead/Destroy()
- if(ismob(src.loc))
- src.loc.SetLuminosity(0, FALSE, src)
- else
- SetLuminosity(0)
- return ..()
+ set_light_on(FALSE)
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index 9d53ac1103c0..e3b07a76a2ff 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -159,8 +159,8 @@
max_heat_protection_temperature = SHOE_MAX_HEAT_PROT
/obj/item/clothing/shoes/souto
- name = "\improper Souto Man's boots. Harder than the kick of Souto Red."
- desc = "Souto Man boots"
+ name = "Souto Man boots"
+ desc = "\improper Souto Man's boots. Harder than the kick of Souto Red"
icon_state = "souto_man"
item_state = "souto_man"
flags_inventory = CANTSTRIP|NOSLIPPING
diff --git a/code/modules/clothing/suits/marine_armor.dm b/code/modules/clothing/suits/marine_armor.dm
index 910bb032349e..9976181588d8 100644
--- a/code/modules/clothing/suits/marine_armor.dm
+++ b/code/modules/clothing/suits/marine_armor.dm
@@ -69,6 +69,7 @@
/obj/item/attachable/bayonet,
/obj/item/storage/backpack/general_belt,
/obj/item/storage/large_holster/machete,
+ /obj/item/storage/belt/gun/type47,
/obj/item/storage/belt/gun/m4a3,
/obj/item/storage/belt/gun/m44,
/obj/item/storage/belt/gun/smartpistol,
@@ -79,7 +80,10 @@
)
valid_accessory_slots = list(ACCESSORY_SLOT_MEDAL, ACCESSORY_SLOT_PONCHO)
- var/brightness_on = 6 //Average attachable pocket light
+ light_power = 3
+ light_range = 4
+ light_system = MOVABLE_LIGHT
+
var/flashlight_cooldown = 0 //Cooldown for toggling the light
var/locate_cooldown = 0 //Cooldown for SL locator
var/armor_overlays[]
@@ -98,6 +102,8 @@
/// The dmi where the grayscale squad overlays are contained
var/squad_overlay_icon = 'icons/mob/humans/onmob/suit_1.dmi'
+ var/atom/movable/marine_light/light_holder
+
/obj/item/clothing/suit/storage/marine/Initialize(mapload)
. = ..()
if(!(flags_atom & NO_NAME_OVERRIDE))
@@ -121,6 +127,12 @@
)
pockets.max_storage_space = 8
+ light_holder = new(src)
+
+/obj/item/clothing/suit/storage/marine/Destroy()
+ QDEL_NULL(light_holder)
+ return ..()
+
/obj/item/clothing/suit/storage/marine/update_icon(mob/user)
var/image/I
armor_overlays["lamp"] = null
@@ -150,42 +162,11 @@
icon_state = replacetext(icon_state,"1","[new_look]")
update_icon(user)
-/obj/item/clothing/suit/storage/marine/pickup(mob/user)
- if(flags_marine_armor & ARMOR_LAMP_ON)
- user.SetLuminosity(brightness_on, FALSE, src)
- SetLuminosity(0)
- ..()
-
-/obj/item/clothing/suit/storage/marine/dropped(mob/user)
- if(loc != user)
- turn_off_light(user)
- ..()
-
-
-/obj/item/clothing/suit/storage/marine/proc/is_light_on()
- return flags_marine_armor & ARMOR_LAMP_ON
-
-/obj/item/clothing/suit/storage/marine/proc/turn_off_light(mob/wearer)
- if(is_light_on())
- if(wearer)
- wearer.SetLuminosity(0, FALSE, src)
- SetLuminosity(brightness_on)
- toggle_armor_light() //turn the light off
- return 1
- return 0
-
-/obj/item/clothing/suit/storage/marine/Destroy()
- if(ismob(src.loc))
- src.loc.SetLuminosity(0, FALSE, src)
- else
- SetLuminosity(0)
- return ..()
-
/obj/item/clothing/suit/storage/marine/attack_self(mob/user)
..()
if(!isturf(user.loc))
- to_chat(user, SPAN_WARNING("You cannot turn the light [is_light_on() ? "off" : "on"] while in [user.loc].")) //To prevent some lighting anomalies.
+ to_chat(user, SPAN_WARNING("You cannot turn the light [light_on ? "off" : "on"] while in [user.loc].")) //To prevent some lighting anomalies.
return
if(flashlight_cooldown > world.time)
@@ -197,26 +178,33 @@
if(H.wear_suit != src)
return
- toggle_armor_light(user)
+ turn_light(user, !light_on)
/obj/item/clothing/suit/storage/marine/item_action_slot_check(mob/user, slot)
- if(!ishuman(user)) return FALSE
- if(slot != WEAR_JACKET) return FALSE
+ if(!ishuman(user))
+ return FALSE
+ if(slot != WEAR_JACKET)
+ return FALSE
return TRUE //only give action button when armor is worn.
-/obj/item/clothing/suit/storage/marine/proc/toggle_armor_light(mob/user)
- flashlight_cooldown = world.time + 20 //2 seconds cooldown every time the light is toggled
- if(is_light_on()) //Turn it off.
- if(user) user.SetLuminosity(0, FALSE, src)
- else SetLuminosity(0)
- playsound(src,'sound/handling/click_2.ogg', 50, 1)
- else //Turn it on.
- if(user) user.SetLuminosity(brightness_on, FALSE, src)
- else SetLuminosity(brightness_on)
-
+/obj/item/clothing/suit/storage/marine/turn_light(mob/user, toggle_on)
+ . = ..()
+ if(. != CHECKS_PASSED)
+ return
+ set_light_range(initial(light_range))
+ set_light_power(FLOOR(initial(light_power) * 0.5, 1))
+ set_light_on(toggle_on)
flags_marine_armor ^= ARMOR_LAMP_ON
- playsound(src,'sound/handling/suitlight_on.ogg', 50, 1)
+ light_holder.set_light_flags(LIGHT_ATTACHED)
+ light_holder.set_light_range(initial(light_range))
+ light_holder.set_light_power(initial(light_power))
+ light_holder.set_light_on(toggle_on)
+
+ if(!toggle_on)
+ playsound(src, 'sound/handling/click_2.ogg', 50, 1)
+
+ playsound(src, 'sound/handling/suitlight_on.ogg', 50, 1)
update_icon(user)
for(var/X in actions)
@@ -267,7 +255,7 @@
armor_bio = CLOTHING_ARMOR_MEDIUMHIGH
armor_rad = CLOTHING_ARMOR_MEDIUM
storage_slots = 4
- brightness_on = 7 //slightly higher
+ light_range = 5 //slightly higher
specialty = "M4 pattern marine"
/obj/item/clothing/suit/storage/marine/rto/intel
@@ -1198,7 +1186,7 @@
armor_bomb = CLOTHING_ARMOR_HIGH
armor_rad = CLOTHING_ARMOR_MEDIUM
storage_slots = 2
- brightness_on = 9
+ light_range = 7
slowdown = SLOWDOWN_ARMOR_VERY_LIGHT
uniform_restricted = list(/obj/item/clothing/under/marine/veteran/dutch)
@@ -1268,9 +1256,10 @@
storage_slots = 1
uniform_restricted = list(/obj/item/clothing/under/marine/veteran/UPP, /obj/item/clothing/under/marine/veteran/UPP/medic, /obj/item/clothing/under/marine/veteran/UPP/engi)
-/obj/item/clothing/suit/storage/marine/faction/support
- name = "\improper UM5B personal armor"
- desc = "Standard body armor of the UPP military, the UM5B (Union Medium MK5 Beta) is a light body armor, slightly weaker than the M3 pattern body armor in service with the USCM, specialized towards ballistics protection. This set of personal armor lacks the iconic neck piece and some of the armor in favor of user mobility."
+/obj/item/clothing/suit/storage/marine/faction/UPP/support
+ name = "\improper UL6 personal armor"
+ desc = "Standard body armor of the UPP military, the UL6 (Union Light MK6) is a light body armor, slightly weaker than the M3 pattern body armor in service with the USCM, specialized towards ballistics protection. This set of personal armor lacks the iconic neck piece and some of the armor in favor of user mobility."
+ storage_slots = 3
icon_state = "upp_armor_support"
slowdown = SLOWDOWN_ARMOR_LIGHT
armor_melee = CLOTHING_ARMOR_HIGH
@@ -1278,7 +1267,6 @@
armor_bio = CLOTHING_ARMOR_MEDIUMLOW
armor_rad = CLOTHING_ARMOR_MEDIUMLOW
armor_internaldamage = CLOTHING_ARMOR_HIGH
- uniform_restricted = list(/obj/item/clothing/under/marine/veteran/UPP/officer)
/obj/item/clothing/suit/storage/marine/faction/UPP/commando
name = "\improper UM5CU personal armor"
@@ -1291,6 +1279,7 @@
name = "\improper UH7 heavy plated armor"
desc = "An extremely heavy-duty set of body armor in service with the UPP military, the UH7 (Union Heavy MK7) is known for having powerful ballistic protection, alongside a noticeable neck guard, fortified in order to allow the wearer to endure the stresses of the bulky helmet."
icon_state = "upp_armor_heavy"
+ storage_slots = 3
slowdown = SLOWDOWN_ARMOR_HEAVY
flags_inventory = BLOCKSHARPOBJ|BLOCK_KNOCKDOWN
flags_armor_protection = BODY_FLAG_ALL_BUT_HEAD
@@ -1306,19 +1295,20 @@
/obj/item/clothing/suit/storage/marine/faction/UPP/heavy/Initialize()
. = ..()
pockets.bypass_w_limit = list(
- /obj/item/ammo_magazine/minigun
+ /obj/item/ammo_magazine/minigun,
+ /obj/item/ammo_magazine/pkp,
)
/obj/item/clothing/suit/storage/marine/faction/UPP/officer
- name = "\improper UL6 officers jacket"
- desc = "A lightweight jacket, issued to officers of the UPP's military. Still studded to the brim with kevlar shards, though the synthread construction reduces its effectiveness."
+ name = "\improper UL4 officer jacket"
+ desc = "A lightweight jacket, issued to officers of the UPP's military. Slightly protective from incoming damage, best off with proper armor however."
icon_state = "upp_coat_officer"
- slowdown = SLOWDOWN_ARMOR_VERY_LIGHT
+ slowdown = SLOWDOWN_ARMOR_NONE
flags_armor_protection = BODY_FLAG_CHEST|BODY_FLAG_GROIN|BODY_FLAG_ARMS
- armor_melee = CLOTHING_ARMOR_LOW
- armor_bullet = CLOTHING_ARMOR_MEDIUMLOW
- armor_energy = CLOTHING_ARMOR_MEDIUMLOW
- armor_bomb = CLOTHING_ARMOR_MEDIUMLOW
+ armor_melee = CLOTHING_ARMOR_LOW //wear actual armor if you go into combat
+ armor_bullet = CLOTHING_ARMOR_LOW
+ armor_energy = CLOTHING_ARMOR_LOW
+ armor_bomb = CLOTHING_ARMOR_LOW
armor_bio = CLOTHING_ARMOR_LOW
armor_rad = CLOTHING_ARMOR_LOW
armor_internaldamage = CLOTHING_ARMOR_LOW
@@ -1326,31 +1316,31 @@
uniform_restricted = list(/obj/item/clothing/under/marine/veteran/UPP/officer)
/obj/item/clothing/suit/storage/marine/faction/UPP/kapitan
- name = "\improper UL6 Kapitan's jacket"
- desc = "A lightweight jacket, issued to the Kapitans of the UPP's military. Made of high-quality materials, even going as far as having the ranks and insignia of the Kapitan and their Company emblazoned on the shoulders and front of the jacket."
+ name = "\improper UL4 senior officer jacket"
+ desc = "A lightweight jacket, issued to senior officers of the UPP's military. Made of high-quality materials, even going as far as having the ranks and insignia of the Kapitan and their Company emblazoned on the shoulders and front of the jacket. Slightly protective from incoming damage, best off with proper armor however."
icon_state = "upp_coat_kapitan"
- slowdown = SLOWDOWN_ARMOR_VERY_LIGHT
- flags_armor_protection = BODY_FLAG_CHEST|BODY_FLAG_GROIN|BODY_FLAG_ARMS
- armor_melee = CLOTHING_ARMOR_LOW
- armor_bullet = CLOTHING_ARMOR_MEDIUMLOW
- armor_energy = CLOTHING_ARMOR_MEDIUMLOW
- armor_bomb = CLOTHING_ARMOR_MEDIUMLOW
+ slowdown = SLOWDOWN_ARMOR_NONE
+ armor_melee = CLOTHING_ARMOR_LOW //wear actual armor if you go into combat
+ armor_bullet = CLOTHING_ARMOR_LOW
+ armor_energy = CLOTHING_ARMOR_LOW
+ armor_bomb = CLOTHING_ARMOR_LOW
armor_bio = CLOTHING_ARMOR_LOW
armor_rad = CLOTHING_ARMOR_LOW
armor_internaldamage = CLOTHING_ARMOR_LOW
+ flags_armor_protection = BODY_FLAG_CHEST|BODY_FLAG_GROIN|BODY_FLAG_ARMS
storage_slots = 4
uniform_restricted = list(/obj/item/clothing/under/marine/veteran/UPP/officer)
/obj/item/clothing/suit/storage/marine/faction/UPP/mp
- name = "\improper UL6 camouflaged jacket"
+ name = "\improper UL4 camouflaged jacket"
desc = "A lightweight jacket, issued to troops when they're not expected to engage in combat. Still studded to the brim with kevlar shards, though the synthread construction reduces its effectiveness."
icon_state = "upp_coat_mp"
- slowdown = SLOWDOWN_ARMOR_VERY_LIGHT
+ slowdown = SLOWDOWN_ARMOR_NONE
flags_armor_protection = BODY_FLAG_CHEST|BODY_FLAG_GROIN|BODY_FLAG_ARMS
- armor_melee = CLOTHING_ARMOR_LOW
- armor_bullet = CLOTHING_ARMOR_MEDIUMLOW
- armor_energy = CLOTHING_ARMOR_MEDIUMLOW
- armor_bomb = CLOTHING_ARMOR_MEDIUMLOW
+ armor_melee = CLOTHING_ARMOR_LOW //wear actual armor if you go into combat
+ armor_bullet = CLOTHING_ARMOR_LOW
+ armor_energy = CLOTHING_ARMOR_LOW
+ armor_bomb = CLOTHING_ARMOR_LOW
armor_bio = CLOTHING_ARMOR_LOW
armor_rad = CLOTHING_ARMOR_LOW
armor_internaldamage = CLOTHING_ARMOR_LOW
@@ -1360,8 +1350,8 @@
restricted_accessory_slots = list(ACCESSORY_SLOT_ARMBAND)
/obj/item/clothing/suit/storage/marine/faction/UPP/jacket/ivan
- name = "\improper UH6 Camo Jacket"
- desc = "An experimental heavily armored variant of the UL6 given to only the most elite units... usually."
+ name = "\improper UH4 Camo Jacket"
+ desc = "An experimental heavily armored variant of the UL4 given to only the most elite units... usually."
slowdown = SLOWDOWN_ARMOR_MEDIUM
flags_armor_protection = BODY_FLAG_CHEST|BODY_FLAG_GROIN|BODY_FLAG_LEGS|BODY_FLAG_ARMS|BODY_FLAG_HANDS|BODY_FLAG_FEET
armor_melee = CLOTHING_ARMOR_HIGH
@@ -1727,3 +1717,6 @@
icon_state = "wc_armor"
flags_atom = NO_SNOW_TYPE|NO_NAME_OVERRIDE
contained_sprite = TRUE
+
+/atom/movable/marine_light
+ light_system = DIRECTIONAL_LIGHT
diff --git a/code/modules/cm_aliens/structures/special/pylon_core.dm b/code/modules/cm_aliens/structures/special/pylon_core.dm
index 614c498fefaa..7f945b29a42e 100644
--- a/code/modules/cm_aliens/structures/special/pylon_core.dm
+++ b/code/modules/cm_aliens/structures/special/pylon_core.dm
@@ -8,7 +8,7 @@
desc = "A towering spike of resin. Its base pulsates with large tendrils."
icon_state = "pylon"
health = 1800
- luminosity = 2
+ light_range = 2
block_range = 0
var/cover_range = WEED_RANGE_PYLON
var/node_type = /obj/effect/alien/weeds/node/pylon
@@ -31,6 +31,9 @@
LAZYADD(A.linked_pylons, src)
linked_turfs += A
+ if(light_range)
+ set_light(light_range)
+
/obj/effect/alien/resin/special/pylon/Destroy()
for(var/turf/A as anything in linked_turfs)
LAZYREMOVE(A.linked_pylons, src)
@@ -166,7 +169,7 @@
desc = "A giant pulsating mound of mass. It looks very much alive."
icon_state = "core"
health = 1200
- luminosity = 4
+ light_range = 4
cover_range = WEED_RANGE_CORE
node_type = /obj/effect/alien/weeds/node/pylon/core
var/hardcore = FALSE
diff --git a/code/modules/cm_marines/dropship_equipment.dm b/code/modules/cm_marines/dropship_equipment.dm
index 3568f001c977..707811e77ce1 100644
--- a/code/modules/cm_marines/dropship_equipment.dm
+++ b/code/modules/cm_marines/dropship_equipment.dm
@@ -453,19 +453,16 @@
var/spotlights_cooldown
var/brightness = 11
-/obj/structure/dropship_equipment/electronics/spotlights/get_light_range()
- return min(luminosity, LIGHTING_MAX_LUMINOSITY_SHIPLIGHTS)
-
/obj/structure/dropship_equipment/electronics/spotlights/equipment_interact(mob/user)
if(spotlights_cooldown > world.time)
to_chat(user, SPAN_WARNING("[src] is busy."))
return //prevents spamming deployment/undeployment
if(luminosity != brightness)
- SetLuminosity(brightness)
+ set_light(brightness)
icon_state = "spotlights_on"
to_chat(user, SPAN_NOTICE("You turn on [src]."))
else
- SetLuminosity(0)
+ set_light(0)
icon_state = "spotlights_off"
to_chat(user, SPAN_NOTICE("You turn off [src]."))
spotlights_cooldown = world.time + 50
@@ -480,13 +477,13 @@
else
icon_state = "spotlights"
if(luminosity)
- SetLuminosity(0)
+ set_light(0)
/obj/structure/dropship_equipment/electronics/spotlights/on_launch()
- SetLuminosity(0)
+ set_light(0)
/obj/structure/dropship_equipment/electronics/spotlights/on_arrival()
- SetLuminosity(brightness)
+ set_light(brightness)
#undef LIGHTING_MAX_LUMINOSITY_SHIPLIGHTS
diff --git a/code/modules/cm_marines/equipment/gear.dm b/code/modules/cm_marines/equipment/gear.dm
index ff6c715b520b..b3ec6c800c68 100644
--- a/code/modules/cm_marines/equipment/gear.dm
+++ b/code/modules/cm_marines/equipment/gear.dm
@@ -7,7 +7,7 @@
desc = "A Flashlight designed to be held in the hand, or attached to a rifle"
icon_state = "flashlight"
item_state = "flashlight"
- brightness_on = 5 //Pretty luminous, but still a flashlight that fits in a pocket
+ light_range = 5 //Pretty luminous, but still a flashlight that fits in a pocket
//MARINE SNIPER TARPS
diff --git a/code/modules/cm_marines/equipment/kit_boxes.dm b/code/modules/cm_marines/equipment/kit_boxes.dm
index a552b8eb0927..be60dce0e783 100644
--- a/code/modules/cm_marines/equipment/kit_boxes.dm
+++ b/code/modules/cm_marines/equipment/kit_boxes.dm
@@ -429,7 +429,7 @@
new /obj/item/pamphlet/skill/medical(src)
new /obj/item/storage/pouch/first_responder/full(src)
new /obj/item/storage/pouch/autoinjector/full(src)
- new /obj/item/clothing/glasses/hud/sensor(src)
+ new /obj/item/device/helmet_visor/medical(src)
new /obj/item/roller(src)
diff --git a/code/modules/cm_marines/smartgun_mount.dm b/code/modules/cm_marines/smartgun_mount.dm
index b72120d2038e..62c5a5955679 100644
--- a/code/modules/cm_marines/smartgun_mount.dm
+++ b/code/modules/cm_marines/smartgun_mount.dm
@@ -501,7 +501,6 @@
/obj/structure/machinery/m56d_hmg/Destroy() //Make sure we pick up our trash.
if(operator)
operator.unset_interaction()
- SetLuminosity(0)
STOP_PROCESSING(SSobj, src)
. = ..()
@@ -818,9 +817,9 @@
if(isnull(angle))
return
- SetLuminosity(muzzle_flash_lum)
+ set_light(muzzle_flash_lum)
spawn(10)
- SetLuminosity(-muzzle_flash_lum)
+ set_light(-muzzle_flash_lum)
var/image_layer = layer + 0.1
diff --git a/code/modules/cm_phone/phone.dm b/code/modules/cm_phone/phone.dm
index b3e0ecd87206..a99bb5603dcb 100644
--- a/code/modules/cm_phone/phone.dm
+++ b/code/modules/cm_phone/phone.dm
@@ -31,7 +31,7 @@ GLOBAL_LIST_EMPTY_TYPED(transmitters, /obj/structure/transmitter)
var/timeout_timer_id
var/timeout_duration = 30 SECONDS
- var/network_receive = FACTION_MARINE
+ var/list/networks_receive = list(FACTION_MARINE)
var/list/networks_transmit = list(FACTION_MARINE)
/obj/structure/transmitter/hidden
@@ -82,7 +82,12 @@ GLOBAL_LIST_EMPTY_TYPED(transmitters, /obj/structure/transmitter)
var/obj/structure/transmitter/target_phone = possible_phone
if(TRANSMITTER_UNAVAILABLE(target_phone) || !target_phone.callable) // Phone not available
continue
- if(!(target_phone.network_receive in networks_transmit))
+ var/net_link = FALSE
+ for(var/network in networks_transmit)
+ if(network in target_phone.networks_receive)
+ net_link = TRUE
+ continue
+ if(!net_link)
continue
var/id = target_phone.phone_id
@@ -538,9 +543,19 @@ GLOBAL_LIST_EMPTY_TYPED(transmitters, /obj/structure/transmitter)
UnregisterSignal(attached_to, COMSIG_MOVABLE_MOVED)
reset_tether()
+//rotary desk phones (need a touch tone handset at some point)
+/obj/structure/transmitter/rotary
+ name = "rotary telephone"
+ icon_state = "rotary_phone"
+ desc = "The finger plate is a little stiff."
+
+/obj/structure/transmitter/touchtone
+ name = "touch-tone telephone"
+ icon_state = "rotary_phone"//placeholder
+ desc = "Ancient aliens, it's all true. I'm an expert just like you!"
/obj/structure/transmitter/colony_net
- network_receive = FACTION_COLONIST
+ networks_receive = list(FACTION_COLONIST)
networks_transmit = list(FACTION_COLONIST)
/obj/structure/transmitter/colony_net/rotary
@@ -548,13 +563,29 @@ GLOBAL_LIST_EMPTY_TYPED(transmitters, /obj/structure/transmitter)
icon_state = "rotary_phone"
desc = "The finger plate is a little stiff."
-//rotary desk phones (need a touch tone handset at some point)
-/obj/structure/transmitter/rotary
+/obj/structure/transmitter/upp_net
+ networks_receive = list(FACTION_UPP)
+ networks_transmit = list(FACTION_UPP)
+
+/obj/structure/transmitter/upp_net/rotary
name = "rotary telephone"
icon_state = "rotary_phone"
desc = "The finger plate is a little stiff."
-/obj/structure/transmitter/touchtone
- name = "touch-tone telephone"
- icon_state = "rotary_phone"//placeholder
- desc = "Ancient aliens, it's all true. I'm an expert just like you!"
+/obj/structure/transmitter/clf_net
+ networks_receive = list(FACTION_CLF)
+ networks_transmit = list(FACTION_CLF)
+
+/obj/structure/transmitter/clf_net/rotary
+ name = "rotary telephone"
+ icon_state = "rotary_phone"
+ desc = "The finger plate is a little stiff."
+
+/obj/structure/transmitter/wy_net
+ networks_receive = list(FACTION_WY)
+ networks_transmit = list(FACTION_WY)
+
+/obj/structure/transmitter/wy_net/rotary
+ name = "rotary telephone"
+ icon_state = "rotary_phone"
+ desc = "The finger plate is a little stiff."
diff --git a/code/modules/cm_preds/yaut_mask.dm b/code/modules/cm_preds/yaut_mask.dm
index be0aa8ed761a..94b244b09f14 100644
--- a/code/modules/cm_preds/yaut_mask.dm
+++ b/code/modules/cm_preds/yaut_mask.dm
@@ -155,7 +155,7 @@
if(istype(user) && user.wear_mask == src) //inventory reference is only cleared after dropped().
for(var/listed_hud in mask_huds)
var/datum/mob_hud/H = huds[listed_hud]
- H.remove_hud_from(user)
+ H.remove_hud_from(user, src)
var/obj/item/visor = user.glasses
if(visor) //make your hud fuck off
if(istype(visor, /obj/item/clothing/glasses/night/yautja))
@@ -170,7 +170,7 @@
START_PROCESSING(SSobj, src)
for(var/listed_hud in mask_huds)
var/datum/mob_hud/H = huds[listed_hud]
- H.add_hud_to(user)
+ H.add_hud_to(user, src)
if(current_goggles)
var/obj/item/clothing/gloves/yautja/bracer = user.gloves
if(!bracer || !istype(bracer))
diff --git a/code/modules/cm_preds/yaut_procs.dm b/code/modules/cm_preds/yaut_procs.dm
index 445dfb40bf9f..32d532da72a0 100644
--- a/code/modules/cm_preds/yaut_procs.dm
+++ b/code/modules/cm_preds/yaut_procs.dm
@@ -225,8 +225,7 @@
ambience_exterior = AMBIENCE_YAUTJA
ceiling = CEILING_METAL
requires_power = FALSE
- luminosity = TRUE
- lighting_use_dynamic = FALSE
+ base_lighting_alpha = 255
/mob/living/carbon/human/proc/pred_buy()
set category = "Yautja.Misc"
diff --git a/code/modules/cm_preds/yaut_weapons.dm b/code/modules/cm_preds/yaut_weapons.dm
index 5ff13c843ee3..c1c5f8077f12 100644
--- a/code/modules/cm_preds/yaut_weapons.dm
+++ b/code/modules/cm_preds/yaut_weapons.dm
@@ -961,7 +961,7 @@
ammo = GLOB.ammo_list[/datum/ammo/energy/yautja/rifle/bolt]
charge_time -= 10
var/obj/item/projectile/projectile = create_bullet(ammo, initial(name))
- projectile.SetLuminosity(1)
+ projectile.set_light(1)
in_chamber = projectile
return in_chamber
@@ -1058,7 +1058,7 @@
if(charge_time < 1)
return
var/obj/item/projectile/projectile = create_bullet(ammo, initial(name))
- projectile.SetLuminosity(1)
+ projectile.set_light(1)
in_chamber = projectile
charge_time -= shot_cost
return in_chamber
diff --git a/code/modules/cm_tech/droppod/gear_access_point.dm b/code/modules/cm_tech/droppod/gear_access_point.dm
index cbd70f9d083d..b581764e2d3b 100644
--- a/code/modules/cm_tech/droppod/gear_access_point.dm
+++ b/code/modules/cm_tech/droppod/gear_access_point.dm
@@ -17,7 +17,7 @@
/obj/structure/techpod_vendor/attack_hand(mob/user)
var/area/a = get_area(src)
//no idea why it was made just a structure, so this is gonna be here for now
- if(!a.master || a.master.requires_power && !a.master.unlimited_power && !a.master.power_equip)
+ if(!a || a.requires_power && !a.unlimited_power && !a.power_equip)
return
if(!ishuman(user) || !get_access_permission(user))
diff --git a/code/modules/cm_tech/tech_node.dm b/code/modules/cm_tech/tech_node.dm
index a8f5e02c2303..4e16267b9123 100644
--- a/code/modules/cm_tech/tech_node.dm
+++ b/code/modules/cm_tech/tech_node.dm
@@ -19,6 +19,7 @@
info = tech
name = tech.name
tech.node = src
+
tech.update_icon(src)
/obj/effect/node/update_icon()
diff --git a/code/modules/cm_tech/techtree.dm b/code/modules/cm_tech/techtree.dm
index 5787adafc745..6c39d8ab9cf9 100644
--- a/code/modules/cm_tech/techtree.dm
+++ b/code/modules/cm_tech/techtree.dm
@@ -158,7 +158,12 @@
if(SEND_SIGNAL(M, COMSIG_MOB_ENTER_TREE, src, force) & COMPONENT_CANCEL_TREE_ENTRY) return
- new/mob/hologram/techtree(entrance, M)
+ var/tech_hologram = new/mob/hologram/techtree(entrance, M)
+
+ M.lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
+ M.sync_lighting_plane_alpha()
+
+ M.RegisterSignal(tech_hologram, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/mob, reset_lighting_alpha))
return TRUE
diff --git a/code/modules/defenses/sentry.dm b/code/modules/defenses/sentry.dm
index 86464d97f5a3..cec51d0b1ac2 100644
--- a/code/modules/defenses/sentry.dm
+++ b/code/modules/defenses/sentry.dm
@@ -21,7 +21,7 @@
var/sentry_type = "sentry" //Used for the icon
display_additional_stats = TRUE
/// Light strength when turned on
- var/luminosity_strength = 7
+ var/luminosity_strength = 5
/// Check if they have been upgraded or not, used for sentry post
var/upgraded = FALSE
var/omni_directional = FALSE
@@ -72,7 +72,6 @@
QDEL_NULL(spark_system)
QDEL_NULL(ammo)
stop_processing()
- SetLuminosity(0)
. = ..()
/obj/structure/machinery/defenses/sentry/process()
@@ -181,7 +180,7 @@
/obj/structure/machinery/defenses/sentry/power_on_action()
target = null
- SetLuminosity(luminosity_strength)
+ set_light(luminosity_strength)
visible_message("[icon2html(src, viewers(src))] [SPAN_NOTICE("The [name] hums to life and emits several beeps.")]")
visible_message("[icon2html(src, viewers(src))] [SPAN_NOTICE("The [name] buzzes in a monotone voice: 'Default systems initiated'")]")
@@ -189,7 +188,7 @@
set_range()
/obj/structure/machinery/defenses/sentry/power_off_action()
- SetLuminosity(0)
+ set_light(0)
visible_message("[icon2html(src, viewers(src))] [SPAN_NOTICE("The [name] powers down and goes silent.")]")
stop_processing()
unset_range()
diff --git a/code/modules/defenses/sentry_computer.dm b/code/modules/defenses/sentry_computer.dm
index a56be2bcac99..dd5726d6ccbf 100644
--- a/code/modules/defenses/sentry_computer.dm
+++ b/code/modules/defenses/sentry_computer.dm
@@ -56,8 +56,7 @@
/// camera screen which shows a blank error
var/atom/movable/screen/background/cam_background
- /// All turfs within range of the currently active camera
- var/list/range_turfs = list()
+ var/list/cam_plane_masters
/obj/item/device/sentry_computer/Initialize(mapload)
. = ..()
@@ -75,6 +74,16 @@
cam_background.assigned_map = map_name
cam_background.del_on_map_removal = FALSE
+ cam_plane_masters = list()
+ for(var/plane in subtypesof(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master/blackness)
+ var/atom/movable/screen/plane_master/instance = new plane()
+ instance.assigned_map = map_name
+ instance.del_on_map_removal = FALSE
+ if(instance.blend_mode_override)
+ instance.blend_mode = instance.blend_mode_override
+ instance.screen_loc = "[map_name]:CENTER"
+ cam_plane_masters += instance
+
faction_group = FACTION_LIST_MARINE
transceiver.forceMove(src)
transceiver.set_frequency(SENTRY_FREQ)
@@ -391,6 +400,8 @@
// Register map objects
user.client.register_map_obj(cam_background)
user.client.register_map_obj(cam_screen)
+ for(var/plane in cam_plane_masters)
+ user.client.register_map_obj(plane)
ui = new(user, src, "SentryGunUI", name)
ui.open()
@@ -474,13 +485,9 @@
var/list/guncamera_zone = range("[x_size]x[y_size]", target)
var/list/visible_turfs = list()
- range_turfs.Cut()
for(var/turf/visible_turf in guncamera_zone)
- range_turfs += visible_turf
- var/area/visible_area = visible_turf.loc
- if(!visible_area.lighting_use_dynamic || visible_turf.lighting_lumcount >= 1)
- visible_turfs += visible_turf
+ visible_turfs += visible_turf
var/list/bbox = get_bbox_of_atoms(visible_turfs)
var/size_x = bbox[3] - bbox[1] + 1
diff --git a/code/modules/defenses/tesla_coil.dm b/code/modules/defenses/tesla_coil.dm
index 3ba754db74c2..8dc8e6498ba1 100644
--- a/code/modules/defenses/tesla_coil.dm
+++ b/code/modules/defenses/tesla_coil.dm
@@ -49,12 +49,12 @@
overlays += image(icon, icon_state = "[defense_type] tesla_coil", pixel_y = 3)
/obj/structure/machinery/defenses/tesla_coil/power_on_action()
- SetLuminosity(7)
+ set_light(7)
start_processing()
visible_message("[icon2html(src, viewers(src))] [SPAN_NOTICE("The [name] gives a short zap, as it awakens.")]")
/obj/structure/machinery/defenses/tesla_coil/power_off_action()
- SetLuminosity(0)
+ set_light(0)
stop_processing()
visible_message("[icon2html(src, viewers(src))] [SPAN_NOTICE("The [name] dies out with a last spark.")]")
@@ -155,7 +155,6 @@
if(targets)
targets = null
- SetLuminosity(0)
. = ..()
#define TESLA_COIL_STUN_FIRE_DELAY 3 SECONDS
diff --git a/code/modules/dropships/attach_points/attach_point.dm b/code/modules/dropships/attach_points/attach_point.dm
index 53a9129517ee..6724f5d18bd2 100644
--- a/code/modules/dropships/attach_points/attach_point.dm
+++ b/code/modules/dropships/attach_points/attach_point.dm
@@ -70,6 +70,7 @@
name = "weapon system attach point"
icon_state = "equip_base_front"
base_category = DROPSHIP_WEAPON
+ layer = ABOVE_OBJ_LAYER
var/firing_arc_min
var/firing_arc_max
diff --git a/code/modules/dropships/attach_points/templates.dm b/code/modules/dropships/attach_points/templates.dm
index be5eb24c3d29..51c870f04b0b 100644
--- a/code/modules/dropships/attach_points/templates.dm
+++ b/code/modules/dropships/attach_points/templates.dm
@@ -94,6 +94,7 @@
name = "electronic system attach point"
base_category = DROPSHIP_ELECTRONICS
icon_state = "equip_base_front"
+ layer = ABOVE_OBJ_LAYER
/obj/effect/attach_point/electronics/dropship1
ship_tag = DROPSHIP_ALAMO
diff --git a/code/modules/gear_presets/_select_equipment.dm b/code/modules/gear_presets/_select_equipment.dm
index 94a628553252..89b0fe072c9b 100644
--- a/code/modules/gear_presets/_select_equipment.dm
+++ b/code/modules/gear_presets/_select_equipment.dm
@@ -388,8 +388,7 @@
/obj/item/weapon/gun/pistol/b92fs = /obj/item/ammo_magazine/pistol/b92fs,
/obj/item/weapon/gun/smg/mp27 = /obj/item/ammo_magazine/smg/mp27,
/obj/item/weapon/gun/smg/mp5 = /obj/item/ammo_magazine/smg/mp5,
- /obj/item/weapon/gun/pistol/skorpion = /obj/item/ammo_magazine/pistol/skorpion,
- /obj/item/weapon/gun/pistol/skorpion/upp = /obj/item/ammo_magazine/pistol/skorpion,
+ /obj/item/weapon/gun/smg/bizon = /obj/item/ammo_magazine/smg/bizon,
/obj/item/weapon/gun/smg/mac15 = /obj/item/ammo_magazine/smg/mac15,
/obj/item/weapon/gun/smg/uzi = /obj/item/ammo_magazine/smg/uzi
)
@@ -473,11 +472,10 @@ var/list/rebel_shotguns = list(
)
var/list/rebel_smgs = list(
- /obj/item/weapon/gun/smg/ppsh = /obj/item/ammo_magazine/smg/ppsh,
+ /obj/item/weapon/gun/smg/pps43 = /obj/item/ammo_magazine/smg/pps43,
/obj/item/weapon/gun/smg/mp27 = /obj/item/ammo_magazine/smg/mp27,
/obj/item/weapon/gun/smg/mp5 = /obj/item/ammo_magazine/smg/mp5,
- /obj/item/weapon/gun/pistol/skorpion = /obj/item/ammo_magazine/pistol/skorpion,
- /obj/item/weapon/gun/pistol/skorpion/upp = /obj/item/ammo_magazine/pistol/skorpion,
+ /obj/item/weapon/gun/smg/bizon = /obj/item/ammo_magazine/smg/bizon,
/obj/item/weapon/gun/smg/mac15 = /obj/item/ammo_magazine/smg/mac15,
/obj/item/weapon/gun/smg/uzi = /obj/item/ammo_magazine/smg/uzi,
/obj/item/weapon/gun/smg/fp9000 = /obj/item/ammo_magazine/smg/fp9000
@@ -551,7 +549,6 @@ var/list/rebel_rifles = list(
/obj/item/weapon/gun/pistol/holdout = /obj/item/ammo_magazine/pistol/holdout,
/obj/item/weapon/gun/pistol/highpower = /obj/item/ammo_magazine/pistol/highpower,
/obj/item/weapon/gun/smg/mp27 = /obj/item/ammo_magazine/smg/mp27,
- /obj/item/weapon/gun/pistol/skorpion = /obj/item/ammo_magazine/pistol/skorpion,
/obj/item/weapon/gun/smg/mac15 = /obj/item/ammo_magazine/smg/mac15,
/obj/item/weapon/gun/smg/mac15 = /obj/item/ammo_magazine/smg/mac15/extended)
@@ -565,6 +562,7 @@ var/list/rebel_rifles = list(
/obj/item/weapon/gun/rifle/mar40/lmg = /obj/item/ammo_magazine/rifle/mar40/lmg,
/obj/item/weapon/gun/rifle/m41aMK1 = /obj/item/ammo_magazine/rifle/m41aMK1,
/obj/item/weapon/gun/smg/fp9000 = /obj/item/ammo_magazine/smg/fp9000,
+ /obj/item/weapon/gun/smg/bizon = /obj/item/ammo_magazine/smg/bizon,
/obj/item/weapon/gun/rifle/m16 = /obj/item/ammo_magazine/rifle/m16)
var/gunpath = sidearm? pick(merc_sidearms) : pick(merc_firearms)
@@ -954,21 +952,26 @@ var/list/rebel_rifles = list(
)
/datum/equipment_preset/proc/add_upp_weapon(mob/living/carbon/human/new_human)
- var/random_gun = rand(1,3)
+ var/random_gun = rand(1,5)
switch(random_gun)
- if(1)
+ if(1,2)
new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/rifle/type71(new_human), WEAR_L_HAND)
new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71(new_human), WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71(new_human), WEAR_IN_BACK)
- if(2)
+ if(3)
new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/rifle/type71/carbine(new_human), WEAR_L_HAND)
new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71(new_human), WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71(new_human), WEAR_IN_BACK)
- if(3)
+ if(4)
new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/shotgun/type23(new_human), WEAR_L_HAND)
new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/handful/shotgun/heavy/buckshot(new_human), WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/handful/shotgun/heavy/buckshot(new_human), WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/handful/shotgun/heavy/buckshot(new_human), WEAR_IN_BACK)
+ if(4)
+ new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/smg/bizon(new_human), WEAR_L_HAND)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/smg/bizon(new_human), WEAR_IN_BACK)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/smg/bizon(new_human), WEAR_IN_BACK)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/smg/bizon(new_human), WEAR_IN_BACK)
/datum/equipment_preset/proc/spawn_random_upp_headgear(mob/living/carbon/human/new_human)
var/random_hat = rand(1,10)
@@ -983,7 +986,7 @@ var/list/rebel_rifles = list(
new_human.equip_to_slot_or_del(new /obj/item/clothing/head/uppcap/ushanka(new_human), WEAR_HEAD)
/datum/equipment_preset/proc/spawn_random_upp_armor(mob/living/carbon/human/new_human)
- var/random_gear = rand(1, 4)
+ var/random_gear = rand(1, 5)
switch(random_gear)
if (1, 2, 3)
new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/veteran/UPP (new_human), WEAR_BODY)
@@ -994,11 +997,17 @@ var/list/rebel_rifles = list(
new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/veteran/UPP (new_human), WEAR_BODY)
new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP(new_human), WEAR_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/tool/crowbar(new_human), WEAR_IN_JACKET)
+ if (4)
+ new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/veteran/UPP (new_human), WEAR_BODY)
+ new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/support(new_human), WEAR_JACKET)
+ new_human.equip_to_slot_or_del(new /obj/item/tool/crowbar(new_human), WEAR_IN_JACKET)
/datum/equipment_preset/proc/spawn_random_upp_belt(mob/living/carbon/human/new_human)
- var/random_gun = rand(1, 3)
+ var/random_gun = rand(1, 4)
switch(random_gun)
- if (1, 2)
- new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/NY(new_human), WEAR_WAIST)
+ if (1 to 2)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/np92(new_human), WEAR_WAIST)
if (3)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73(new_human), WEAR_WAIST)
+ if (4)
new_human.equip_to_slot_or_del(new /obj/item/storage/belt/marine/upp(new_human), WEAR_WAIST)
diff --git a/code/modules/gear_presets/clf.dm b/code/modules/gear_presets/clf.dm
index 901de2c21ca3..81abf8bce550 100644
--- a/code/modules/gear_presets/clf.dm
+++ b/code/modules/gear_presets/clf.dm
@@ -675,7 +675,7 @@
list("Injector (Tricord)", 1, /obj/item/reagent_container/hypospray/autoinjector/tricord, null, VENDOR_ITEM_REGULAR),
list("Health Analyzer", 4, /obj/item/device/healthanalyzer, null, VENDOR_ITEM_REGULAR),
- list("Sensor Medical HUD", 4, /obj/item/clothing/glasses/hud/sensor, null, VENDOR_ITEM_MANDATORY),
+ list("Medical Helmet Optic", 4, /obj/item/device/helmet_visor/medical, null, VENDOR_ITEM_MANDATORY),
list("SPECIAL AMMUNITION", 0, null, null, null),
list("M16 AP Magazine (5.56x45mm)", 10, /obj/item/ammo_magazine/rifle/m16/ap, null, VENDOR_ITEM_REGULAR),
@@ -996,7 +996,7 @@
list("Injector (Tricord)", 1, /obj/item/reagent_container/hypospray/autoinjector/tricord, null, VENDOR_ITEM_REGULAR),
list("Health Analyzer", 4, /obj/item/device/healthanalyzer, null, VENDOR_ITEM_REGULAR),
- list("Sensor Medical HUD", 4, /obj/item/clothing/glasses/hud/sensor, null, VENDOR_ITEM_MANDATORY),
+ list("Medical Helmet Optic", 4, /obj/item/device/helmet_visor/medical, null, VENDOR_ITEM_MANDATORY),
list("SPECIAL AMMUNITION", 0, null, null, null),
list("M16 AP Magazine (5.56x45mm)", 10, /obj/item/ammo_magazine/rifle/m16/ap, null, VENDOR_ITEM_REGULAR),
diff --git a/code/modules/gear_presets/other.dm b/code/modules/gear_presets/other.dm
index 9780b739cf67..b440fe4533b2 100644
--- a/code/modules/gear_presets/other.dm
+++ b/code/modules/gear_presets/other.dm
@@ -807,7 +807,7 @@
for(var/hud_to_add in huds_to_add)
var/datum/mob_hud/hud = huds[hud_to_add]
- hud.add_hud_to(new_human)
+ hud.add_hud_to(new_human, new_human)
var/list/actions_to_add = subtypesof(/datum/action/human_action/activable/cult)
diff --git a/code/modules/gear_presets/survivors.dm b/code/modules/gear_presets/survivors.dm
index 78fdc20c8b9f..37bc52936c40 100644
--- a/code/modules/gear_presets/survivors.dm
+++ b/code/modules/gear_presets/survivors.dm
@@ -1707,7 +1707,7 @@
new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/lightpack/five_slot(new_human), WEAR_BACK)
new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71(new_human), WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71(new_human), WEAR_IN_BACK)
- new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/PK9(new_human), WEAR_WAIST)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73(new_human), WEAR_WAIST)
..()
@@ -1725,7 +1725,7 @@
new_human.equip_to_slot_or_del(new /obj/item/tool/crowbar(new_human), WEAR_IN_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/clothing/head/uppcap/beret(new_human), WEAR_HEAD)
new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/lightpack/five_slot(new_human), WEAR_BACK)
- new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/PK9(new_human), WEAR_WAIST)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/revolver(new_human), WEAR_WAIST)
add_upp_weapon(new_human)
..()
diff --git a/code/modules/gear_presets/upp.dm b/code/modules/gear_presets/upp.dm
index 63d1fd48e665..58ee8b0156fa 100644
--- a/code/modules/gear_presets/upp.dm
+++ b/code/modules/gear_presets/upp.dm
@@ -126,9 +126,7 @@
new_human.equip_to_slot_or_del(new /obj/item/storage/box/m94, WEAR_IN_BACK) //3.25
new_human.equip_to_slot_or_del(new /obj/item/storage/box/m94, WEAR_IN_BACK) //4.25
//waist
- var/gunbelt = prob(50) ? /obj/item/storage/belt/gun/type47/NY : /obj/item/storage/belt/gun/type47/PK9
- new_human.equip_to_slot_or_del(new gunbelt, WEAR_WAIST)
- pick_ammotype(new_human)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/np92, WEAR_WAIST)
/datum/equipment_preset/upp/soldier/proc/pick_ammotype(mob/living/carbon/human/new_human)
var/percentage = rand(1, 100)
@@ -266,18 +264,18 @@
new_human.equip_to_slot_or_del(new /obj/item/clothing/head/uppcap, WEAR_HEAD)
//body
new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/veteran/UPP/medic, WEAR_BODY)
- new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP, WEAR_JACKET)
- new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/pistol/skorpion/upp/medic, WEAR_J_STORE)
+ new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/support, WEAR_JACKET) //medic should move fast
+ new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/smg/bizon/upp, WEAR_J_STORE)
//waist
new_human.equip_to_slot_or_del(new /obj/item/storage/belt/medical/lifesaver/upp/full, WEAR_WAIST)
//limbs
new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET)
new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS)
//póckets
- var/obj/item/storage/pouch/magazine/pistol/large/ppouch = new()
+ var/obj/item/storage/pouch/magazine/large/ppouch = new()
new_human.equip_to_slot_or_del(ppouch, WEAR_R_STORE)
for(var/i = 1 to ppouch.storage_slots)
- new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/pistol/skorpion, WEAR_IN_R_STORE)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/smg/bizon, WEAR_IN_R_STORE)
new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/medical, WEAR_L_STORE)
new_human.equip_to_slot_or_del(new /obj/item/tool/surgery/surgical_line, WEAR_IN_L_STORE)
new_human.equip_to_slot_or_del(new /obj/item/tool/surgery/synthgraft, WEAR_IN_L_STORE)
@@ -292,7 +290,7 @@
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
list("Medic Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/medic, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY),
- list("UM5 Personal Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
+ list("UL6 Personal Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/support, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/medic, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
list("Ration", 0, /obj/item/reagent_container/food/snacks/upp, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
@@ -557,9 +555,6 @@
new_human.equip_to_slot_or_del(new /obj/item/tool/extinguisher, WEAR_IN_BACK) //1
new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK) //1.33
new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK) //1.66
- new_human.equip_to_slot_or_del(new /obj/item/clothing/accessory/health/ceramic_plate, WEAR_IN_BACK) //2
- new_human.equip_to_slot_or_del(new /obj/item/clothing/accessory/health/ceramic_plate, WEAR_IN_BACK) //2.33
- new_human.equip_to_slot_or_del(new /obj/item/clothing/accessory/health/ceramic_plate, WEAR_IN_BACK) //2.66
//face
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/UPP, WEAR_L_EAR)
//head
@@ -589,7 +584,8 @@
new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/shotgun/type23/dragon, WEAR_J_STORE)
new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/handful/shotgun/heavy/dragonsbreath, WEAR_IN_JACKET)
//waist
- new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/NY, WEAR_WAIST)
+ var/uppvetsidearm = prob(50) ? /obj/item/storage/belt/gun/type47/t73 : /obj/item/storage/belt/gun/type47/np92
+ new_human.equip_to_slot_or_del(new uppvetsidearm, WEAR_WAIST)
/datum/equipment_preset/upp/specialist/get_antag_clothing_equipment()
return list(
@@ -607,7 +603,7 @@
list("BELT (CHOOSE 1)", 0, null, null, null),
list("Type 41 Ammo Load Rig", 0, /obj/item/storage/belt/marine/upp, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("Type 41 Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("Type 41 Pistol Holster Rig", 0, /obj/item/storage/belt/gun/type47, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
list("Bayonet Sheath", 0, /obj/item/storage/pouch/bayonet/upp, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
@@ -641,9 +637,9 @@
list("Essential Heavy Set", 0, /obj/effect/essentials_set/upp_heavy, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_MANDATORY),
list("SPECIAL AMMUNITION", 0, null, null, null),
- list("Rotating Ammo Drum (7.62x51mm)", 15, /obj/item/ammo_magazine/minigun , null, VENDOR_ITEM_RECOMMENDED),
+ list("QYJ-72 Box Magazine(7.62x54mmR)", 15, /obj/item/ammo_magazine/pkp , null, VENDOR_ITEM_RECOMMENDED),
- list("ATTACHMENTS (NONE FIT GSh-7.62)", 0, null, null, null),
+ list("ATTACHMENTS (NONE FIT QYJ-72)", 0, null, null, null),
list("Angled Grip", 10, /obj/item/attachable/angledgrip, null, VENDOR_ITEM_REGULAR),
list("Extended Barrel", 10, /obj/item/attachable/extended_barrel, null, VENDOR_ITEM_REGULAR),
list("Laser Sight", 10, /obj/item/attachable/lasersight, null, VENDOR_ITEM_REGULAR),
@@ -670,8 +666,8 @@
//*****************************************************************************************************/
-/datum/equipment_preset/upp/minigunner
- name = "UPP Minigunner"
+/datum/equipment_preset/upp/machinegunner
+ name = "UPP Machinegunner"
flags = EQUIPMENT_PRESET_EXTRA
skills = /datum/skills/upp/specialist
@@ -680,15 +676,12 @@
role_comm_title = "Spc"
paygrade = "UE5"
-/datum/equipment_preset/upp/minigunner/load_gear(mob/living/carbon/human/new_human)
+/datum/equipment_preset/upp/machinegunner/load_gear(mob/living/carbon/human/new_human)
//back
new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/lightpack/upp, WEAR_BACK)
new_human.equip_to_slot_or_del(new /obj/item/tool/extinguisher, WEAR_IN_BACK) //1
new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK) //1.33
new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK) //1.66
- new_human.equip_to_slot_or_del(new /obj/item/clothing/accessory/health/ceramic_plate, WEAR_IN_BACK) //2
- new_human.equip_to_slot_or_del(new /obj/item/clothing/accessory/health/ceramic_plate, WEAR_IN_BACK) //2.33
- new_human.equip_to_slot_or_del(new /obj/item/clothing/accessory/health/ceramic_plate, WEAR_IN_BACK) //2.66
//face
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/UPP, WEAR_L_EAR)
//head
@@ -711,12 +704,15 @@
implant.on_implanted(new_human)
//body
- new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/minigun/upp, WEAR_J_STORE)
- new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/minigun, WEAR_IN_JACKET)
+ new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/pkp, WEAR_J_STORE)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/pkp, WEAR_IN_JACKET)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/pkp, WEAR_IN_JACKET)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/pkp, WEAR_IN_JACKET)
//waist
- new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/NY/shrapnel, WEAR_WAIST)
+ var/uppvetsidearm = prob(50) ? /obj/item/storage/belt/gun/type47/t73 : /obj/item/storage/belt/gun/type47/np92
+ new_human.equip_to_slot_or_del(new uppvetsidearm, WEAR_WAIST) // 50/50 np92 or t73
-/datum/equipment_preset/upp/minigunner/get_antag_clothing_equipment()
+/datum/equipment_preset/upp/machinegunner/get_antag_clothing_equipment()
return list(
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
@@ -760,15 +756,15 @@
list("Heat Absorbent Coif", 0, /obj/item/clothing/mask/rebreather/scarf, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR)
)
-/datum/equipment_preset/upp/minigunner/get_antag_gear_equipment()
+/datum/equipment_preset/upp/machinegunner/get_antag_gear_equipment()
return list(
list("HEAVY SET (MANDATORY)", 0, null, null, null),
list("Essential Heavy Set", 0, /obj/effect/essentials_set/upp_heavy, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_MANDATORY),
list("SPECIAL AMMUNITION", 0, null, null, null),
- list("Rotating Ammo Drum (7.62x51mm)", 15, /obj/item/ammo_magazine/minigun , null, VENDOR_ITEM_RECOMMENDED),
+ list("QYJ-72 Box Magazine (7.62x54mmR)", 15, /obj/item/ammo_magazine/pkp , null, VENDOR_ITEM_RECOMMENDED),
- list("ATTACHMENTS (NONE FIT GSh-7.62)", 0, null, null, null),
+ list("ATTACHMENTS (NONE FIT QYJ-72)", 0, null, null, null),
list("Angled Grip", 10, /obj/item/attachable/angledgrip, null, VENDOR_ITEM_REGULAR),
list("Extended Barrel", 10, /obj/item/attachable/extended_barrel, null, VENDOR_ITEM_REGULAR),
list("Laser Sight", 10, /obj/item/attachable/lasersight, null, VENDOR_ITEM_REGULAR),
@@ -806,8 +802,16 @@
paygrade = "UE6"
/datum/equipment_preset/upp/leader/load_gear(mob/living/carbon/human/new_human)
+ var/UPPleadsidearm = rand(1,4)
//back
- new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/jima, WEAR_BACK)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/lightpack/upp, WEAR_BACK)
+ new_human.equip_to_slot_or_del(new /obj/item/tool/extinguisher/mini, WEAR_IN_BACK) //0.66
+ new_human.equip_to_slot_or_del(new /obj/item/explosive/grenade/phosphorus/upp, WEAR_IN_BACK) //1.33
+ new_human.equip_to_slot_or_del(new /obj/item/explosive/grenade/phosphorus/upp, WEAR_IN_BACK) //2
+ new_human.equip_to_slot_or_del(new /obj/item/explosive/grenade/phosphorus/upp, WEAR_IN_BACK) //2.66
+ new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK) //3.33
+ new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK) //4
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_BACK) //5
//face
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/UPP/command, WEAR_L_EAR)
//head
@@ -824,7 +828,14 @@
new_human.equip_to_slot_or_del(new /obj/item/device/binoculars/range, WEAR_IN_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/rifle/type71/flamer, WEAR_J_STORE)
//waist
- new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/NY/shrapnel, WEAR_WAIST)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73, WEAR_WAIST)
+ switch(UPPleadsidearm)
+ if(1 to 2) // 50%
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73, WEAR_WAIST)
+ if(3) //25%
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/np92, WEAR_WAIST)
+ if(4) //25%
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/revolver, WEAR_WAIST)
//limbs
new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET)
new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS)
@@ -962,23 +973,17 @@
//back
new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/lightpack/upp, WEAR_BACK)
new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK)
- new_human.equip_to_slot_or_del(new /obj/item/clothing/accessory/health/ceramic_plate, WEAR_IN_BACK)
//face
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/UPP, WEAR_L_EAR)
new_human.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/pmc/upp, WEAR_FACE)
//head
new_human.equip_to_slot_or_del(new /obj/item/clothing/head/uppcap/beret, WEAR_HEAD)
//uniform
- var/obj/item/clothing/under/marine/veteran/UPP/mp/M = new()
- var/obj/item/clothing/accessory/storage/webbing/W = new()
- M.attach_accessory(new_human, W)
- new_human.equip_to_slot_or_del(M, WEAR_BODY)
- for(var/i in 1 to W.hold.storage_slots)
- new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_ACCESSORY)
+ new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/veteran/UPP/mp, WEAR_BODY)
//jacket
new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/mp, WEAR_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/device/binoculars, WEAR_IN_JACKET)
- new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/rifle/type71/flamer, WEAR_J_STORE)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/revolver, WEAR_J_STORE)
//waist
new_human.equip_to_slot_or_del(new /obj/item/storage/belt/security/MP/UPP/full, WEAR_WAIST)
//limbs
@@ -995,7 +1000,7 @@
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/mp, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY),
- list("UL6 camouflaged jacket", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/mp, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
+ list("UL4 camouflaged jacket", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/mp, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
list("Headset", 0, /obj/item/device/radio/headset/distress/UPP, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
list("Ration", 0, /obj/item/reagent_container/food/snacks/upp, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
@@ -1003,7 +1008,11 @@
list("HELMET (CHOOSE 1)", 0, null, null, null),
list("Armored Beret", 0, /obj/item/clothing/head/uppcap/beret, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_REGULAR),
- list("UM7 Helmet", 0, /obj/item/clothing/head/helmet/marine/veteran/UPP/heavy, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
+ list("UM4 Helmet", 0, /obj/item/clothing/head/helmet/marine/veteran/UPP, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_RECOMMENDED),
+
+ list("ARMOR (CHOOSE 1)", 0, null, null, null),
+ list("UL4 camouflaged jacket", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/mp, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_REGULAR),
+ list("UL6 Personal Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/support, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("BELT (CHOOSE 1)", 0, null, null, null),
list("Type 41 Ammo Load Rig", 0, /obj/item/storage/belt/marine/upp, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
@@ -1118,7 +1127,6 @@
new_human.equip_to_slot_or_del(new /obj/item/tool/extinguisher, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/device/motiondetector/hacked, WEAR_IN_BACK)
- new_human.equip_to_slot_or_del(new /obj/item/clothing/accessory/health/ceramic_plate, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/device/megaphone, WEAR_IN_BACK)
//face
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/UPP/command, WEAR_L_EAR)
@@ -1130,14 +1138,15 @@
M.attach_accessory(new_human, W)
new_human.equip_to_slot_or_del(M, WEAR_BODY)
for(var/i in 1 to W.hold.storage_slots)
- new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/heap, WEAR_IN_ACCESSORY)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_ACCESSORY)
+
//jacket
new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/officer, WEAR_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/device/binoculars/range, WEAR_IN_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/stack/medical/bruise_pack, WEAR_IN_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/rifle/type71/flamer/leader, WEAR_J_STORE)
//waist
- new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/NY, WEAR_WAIST)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/np92, WEAR_WAIST)
//limbs
new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET)
new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS)
@@ -1163,15 +1172,15 @@
list("HELMET (CHOOSE 1)", 0, null, null, null),
list("Armored Beret", 0, /obj/item/clothing/head/uppcap/beret, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_REGULAR),
- list("UM7 Helmet", 0, /obj/item/clothing/head/helmet/marine/veteran/UPP/heavy, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
+ list("UM4 Helmet", 0, /obj/item/clothing/head/helmet/marine/veteran/UPP, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_RECOMMENDED),
list("ARMOR (CHOOSE 1)", 0, null, null, null),
- list("UL6 officers jacket", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/officer, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
- list("UM5B Personal Armor", 0, /obj/item/clothing/suit/storage/marine/faction/support, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
+ list("UL4 officer jacket", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/officer, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_REGULAR),
+ list("UL6 Personal Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/support, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("BELT (CHOOSE 1)", 0, null, null, null),
list("Type 41 Ammo Load Rig", 0, /obj/item/storage/belt/marine/upp, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("Type 47 Pistol Holster Rig NY", 0, /obj/item/storage/belt/gun/type47/NY, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("Type 73 Pistol Holster Rig", 0, /obj/item/storage/belt/gun/type47/t73, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
list("Auto-Injector Pouch", 0, /obj/item/storage/pouch/autoinjector, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
@@ -1278,7 +1287,6 @@
new_human.equip_to_slot_or_del(new /obj/item/tool/extinguisher, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/device/motiondetector/hacked, WEAR_IN_BACK)
- new_human.equip_to_slot_or_del(new /obj/item/clothing/accessory/health/ceramic_plate, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/device/megaphone, WEAR_IN_BACK)
//face
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/UPP/command, WEAR_L_EAR)
@@ -1290,14 +1298,15 @@
M.attach_accessory(new_human, W)
new_human.equip_to_slot_or_del(M, WEAR_BODY)
for(var/i in 1 to W.hold.storage_slots)
- new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/heap, WEAR_IN_ACCESSORY)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_ACCESSORY)
+
//jacket
new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/officer, WEAR_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/device/binoculars/range, WEAR_IN_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/stack/medical/bruise_pack, WEAR_IN_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/rifle/type71/flamer/leader, WEAR_J_STORE)
//waist
- new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/NY/shrapnel, WEAR_WAIST)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73, WEAR_WAIST)
//limbs
new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET)
new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS)
@@ -1316,7 +1325,6 @@
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/officer, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY),
- list("UL6 officers jacket", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/officer, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/command, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
list("Ration", 0, /obj/item/reagent_container/food/snacks/upp, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
@@ -1324,11 +1332,15 @@
list("HELMET (CHOOSE 1)", 0, null, null, null),
list("Armored Beret", 0, /obj/item/clothing/head/uppcap/beret, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_REGULAR),
- list("UM7 Helmet", 0, /obj/item/clothing/head/helmet/marine/veteran/UPP/heavy, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
+ list("UM4 Helmet", 0, /obj/item/clothing/head/helmet/marine/veteran/UPP, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_RECOMMENDED),
+
+ list("ARMOR (CHOOSE 1)", 0, null, null, null),
+ list("UL4 officer jacket", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/officer, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_REGULAR),
+ list("UL6 Personal Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/support, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("BELT (CHOOSE 1)", 0, null, null, null),
list("Type 41 Ammo Load Rig", 0, /obj/item/storage/belt/marine/upp, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("Type 47 Pistol Holster Rig NY", 0, /obj/item/storage/belt/gun/type47/NY/shrapnel, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("Type 73 Pistol Holster Rig", 0, /obj/item/storage/belt/gun/type47/t73, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
list("Auto-Injector Pouch", 0, /obj/item/storage/pouch/autoinjector, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
@@ -1428,6 +1440,7 @@
rank = JOB_UPP_MAY_OFFICER
role_comm_title = "May."
paygrade = "UO3"
+ skills = /datum/skills/upp/commander
/datum/equipment_preset/upp/officer/major/load_gear(mob/living/carbon/human/new_human)
//back
@@ -1435,7 +1448,6 @@
new_human.equip_to_slot_or_del(new /obj/item/tool/extinguisher, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/device/motiondetector/hacked, WEAR_IN_BACK)
- new_human.equip_to_slot_or_del(new /obj/item/clothing/accessory/health/ceramic_plate, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/device/megaphone, WEAR_IN_BACK)
//face
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/UPP/command, WEAR_L_EAR)
@@ -1447,14 +1459,15 @@
M.attach_accessory(new_human, W)
new_human.equip_to_slot_or_del(M, WEAR_BODY)
for(var/i in 1 to W.hold.storage_slots)
- new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/heap, WEAR_IN_ACCESSORY)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_ACCESSORY)
+
//jacket
new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/kapitan, WEAR_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/device/binoculars/range, WEAR_IN_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/stack/medical/bruise_pack, WEAR_IN_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/rifle/type71/flamer/leader, WEAR_J_STORE)
//waist
- new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/mateba/general/impact, WEAR_WAIST)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73/leader, WEAR_WAIST)
//limbs
new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET)
new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS)
@@ -1473,19 +1486,22 @@
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/officer, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY),
- list("UL6 officers jacket", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/officer, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/command, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
list("Ration", 0, /obj/item/reagent_container/food/snacks/upp, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
list("Combat Pack", 0, /obj/item/storage/backpack/lightpack/upp, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY),
list("HELMET (CHOOSE 1)", 0, null, null, null),
- list("Armored Peaked Cap", 0, /obj/item/clothing/head/uppcap/peaked, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_REGULAR),
- list("UM7 Helmet", 0, /obj/item/clothing/head/helmet/marine/veteran/UPP/heavy, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
+ list("Peaked Cap", 0, /obj/item/clothing/head/uppcap/peaked, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_REGULAR),
+ list("UM4 Helmet", 0, /obj/item/clothing/head/helmet/marine/veteran/UPP, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_RECOMMENDED),
+
+ list("ARMOR (CHOOSE 1)", 0, null, null, null),
+ list("UL4 senior officer jacket", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/kapitan, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_REGULAR),
+ list("UL6 Personal Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/support, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("BELT (CHOOSE 1)", 0, null, null, null),
list("Type 41 Ammo Load Rig", 0, /obj/item/storage/belt/marine/upp, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("Type 47 Pistol Holster Rig NY", 0, /obj/item/storage/belt/gun/type47/NY/shrapnel, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("Type 74 Pistol Holster Rig", 0, /obj/item/storage/belt/gun/type47/t73/leader, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
list("Auto-Injector Pouch", 0, /obj/item/storage/pouch/autoinjector, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
@@ -1593,7 +1609,6 @@
new_human.equip_to_slot_or_del(new /obj/item/tool/extinguisher, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/device/motiondetector/hacked, WEAR_IN_BACK)
- new_human.equip_to_slot_or_del(new /obj/item/clothing/accessory/health/ceramic_plate, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/device/megaphone, WEAR_IN_BACK)
//face
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/UPP/command, WEAR_L_EAR)
@@ -1605,14 +1620,15 @@
M.attach_accessory(new_human, W)
new_human.equip_to_slot_or_del(M, WEAR_BODY)
for(var/i in 1 to W.hold.storage_slots)
- new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/heap, WEAR_IN_ACCESSORY)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_ACCESSORY)
+
//jacket
- new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/officer, WEAR_JACKET)
+ new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/kapitan, WEAR_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/device/binoculars/range, WEAR_IN_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/stack/medical/bruise_pack, WEAR_IN_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/rifle/type71/flamer/leader, WEAR_J_STORE)
//waist
- new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/mateba/general/impact, WEAR_WAIST)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73/leader, WEAR_WAIST)
//limbs
new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET)
new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS)
@@ -1631,19 +1647,22 @@
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/officer, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY),
- list("UL6 officers jacket", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/officer, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/command, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
list("Ration", 0, /obj/item/reagent_container/food/snacks/upp, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
list("Combat Pack", 0, /obj/item/storage/backpack/lightpack/upp, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY),
list("HELMET (CHOOSE 1)", 0, null, null, null),
- list("Armored Peaked Cap", 0, /obj/item/clothing/head/uppcap/peaked, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_REGULAR),
- list("UM7 Helmet", 0, /obj/item/clothing/head/helmet/marine/veteran/UPP/heavy, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
+ list("Peaked Cap", 0, /obj/item/clothing/head/uppcap/peaked, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_REGULAR),
+ list("UM4 Helmet", 0, /obj/item/clothing/head/helmet/marine/veteran/UPP, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_RECOMMENDED),
+
+ list("ARMOR (CHOOSE 1)", 0, null, null, null),
+ list("UL4 senior officer jacket", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/kapitan, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_REGULAR),
+ list("UL6 Personal Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/support, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("BELT (CHOOSE 1)", 0, null, null, null),
list("Type 41 Ammo Load Rig", 0, /obj/item/storage/belt/marine/upp, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("Type 47 Pistol Holster Rig NY", 0, /obj/item/storage/belt/gun/type47/NY/shrapnel, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("Type 74 Pistol Holster Rig", 0, /obj/item/storage/belt/gun/type47/t73/leader, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
list("Auto-Injector Pouch", 0, /obj/item/storage/pouch/autoinjector, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
@@ -1742,10 +1761,10 @@
/datum/equipment_preset/upp/sapper/survivor/load_gear(mob/living/carbon/human/new_human)
//back
new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/marine/engineerpack/upp, WEAR_BACK)
- new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/revolver/nagant, WEAR_IN_BACK) //1
- new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/revolver/upp, WEAR_IN_BACK) //1.3
- new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/revolver/upp, WEAR_IN_BACK) //1.6
- new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/revolver/upp, WEAR_IN_BACK) //2
+ new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/pistol/np92, WEAR_IN_BACK) //1
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/pistol/np92, WEAR_IN_BACK) //1.3
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/pistol/np92, WEAR_IN_BACK) //1.6
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/pistol/np92, WEAR_IN_BACK) //2
new_human.equip_to_slot_or_del(new /obj/item/device/motiondetector/hacked, WEAR_IN_BACK) //3
new_human.equip_to_slot_or_del(new /obj/item/defenses/handheld/sentry/mini, WEAR_IN_BACK) //4
//face
@@ -1845,19 +1864,19 @@
var/obj/item/clothing/accessory/storage/black_vest/tool_webbing/W = new()
UPP.attach_accessory(new_human, W)
new_human.equip_to_slot_or_del(UPP, WEAR_BODY)
- new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/jacket, WEAR_JACKET)
+ new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/support, WEAR_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/reagent_container/glass/bottle/tricordrazine, WEAR_IN_JACKET)
- new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/pistol/skorpion/upp/medic, WEAR_J_STORE)
+ new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/smg/bizon/upp, WEAR_J_STORE)
//waist
new_human.equip_to_slot_or_del(new /obj/item/storage/belt/medical/lifesaver/upp/full, WEAR_WAIST)
//limbs
new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET)
new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS)
//póckets
- var/obj/item/storage/pouch/magazine/pistol/large/ppouch = new()
+ var/obj/item/storage/pouch/magazine/large/ppouch = new()
new_human.equip_to_slot_or_del(ppouch, WEAR_R_STORE)
for(var/i = 1 to ppouch.storage_slots)
- new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/pistol/skorpion, WEAR_IN_R_STORE)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/smg/bizon, WEAR_IN_R_STORE)
new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/medical, WEAR_L_STORE)
new_human.equip_to_slot_or_del(new /obj/item/tool/surgery/surgical_line, WEAR_IN_L_STORE)
new_human.equip_to_slot_or_del(new /obj/item/tool/surgery/synthgraft, WEAR_IN_L_STORE)
@@ -2112,8 +2131,10 @@
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/UPP/kdo, WEAR_L_EAR)
new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/veteran/UPP, WEAR_BODY)
new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/commando, WEAR_JACKET)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_JACKET)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/clothing/head/uppcap, WEAR_HEAD)
- new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/PK9/tranq, WEAR_WAIST)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/np92/suppressed, WEAR_WAIST)
new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/marine/satchel/scout_cloak/upp, WEAR_BACK)
new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET)
new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS)
@@ -2131,7 +2152,7 @@
new_human.equip_to_slot_or_del(new /obj/item/handcuffs, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/handcuffs, WEAR_IN_BACK)
- spawn_weapon(/obj/item/weapon/gun/rifle/type71/carbine/commando, /obj/item/ammo_magazine/rifle/type71/heap, new_human, 0, 8)
+ spawn_weapon(/obj/item/weapon/gun/rifle/type71/carbine/commando, /obj/item/ammo_magazine/rifle/type71, new_human, 0, 8)
/datum/equipment_preset/upp/commando/get_antag_clothing_equipment()
return list(
@@ -2152,7 +2173,7 @@
list("BELT (CHOOSE 1)", 0, null, null, null),
list("Type 41 Ammo Load Rig", 0, /obj/item/storage/belt/marine/upp, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("Type 41 Pistol Holster Rig", 0, /obj/item/storage/belt/gun/type47/PK9/tranq, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("NPZ92 Pistol Holster Rig", 0, /obj/item/storage/belt/gun/type47/np92/suppressed, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
list("Auto-Injector Pouch", 0, /obj/item/storage/pouch/autoinjector, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
@@ -2233,6 +2254,8 @@
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/UPP/kdo/medic, WEAR_L_EAR)
new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/veteran/UPP/medic, WEAR_BODY)
new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/commando, WEAR_JACKET)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_JACKET)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/clothing/head/uppcap, WEAR_HEAD)
new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/marine/satchel/scout_cloak/upp, WEAR_BACK)
new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET)
@@ -2260,7 +2283,7 @@
new_human.equip_to_slot_or_del(new /obj/item/handcuffs, WEAR_IN_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/handcuffs, WEAR_IN_JACKET)
- spawn_weapon(/obj/item/weapon/gun/rifle/type71/carbine/commando, /obj/item/ammo_magazine/rifle/type71/heap, new_human, 0, 5)
+ spawn_weapon(/obj/item/weapon/gun/rifle/type71/carbine/commando, /obj/item/ammo_magazine/rifle/type71, new_human, 0, 5)
/datum/equipment_preset/upp/commando/medic/get_antag_clothing_equipment()
return list(
@@ -2401,6 +2424,8 @@
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/UPP/kdo/command, WEAR_L_EAR)
new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/veteran/UPP, WEAR_BODY)
new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/commando, WEAR_JACKET)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_JACKET)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/clothing/head/uppcap/beret, WEAR_HEAD)
new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/marine/satchel/scout_cloak/upp, WEAR_BACK)
new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET)
@@ -2408,7 +2433,7 @@
new_human.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/pmc/upp, WEAR_FACE)
new_human.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/m42_night_goggles/upp, WEAR_EYES)
- new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/PK9/tranq, WEAR_WAIST)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/np92/suppressed, WEAR_WAIST)
new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/explosive/grenade/phosphorus/upp, WEAR_IN_BACK)
@@ -2422,7 +2447,7 @@
new_human.equip_to_slot_or_del(new /obj/item/handcuffs, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/storage/box/handcuffs, WEAR_IN_BACK)
- spawn_weapon(/obj/item/weapon/gun/rifle/type71/carbine/commando, /obj/item/ammo_magazine/rifle/type71/heap, new_human, 0, 7)
+ spawn_weapon(/obj/item/weapon/gun/rifle/type71/carbine/commando, /obj/item/ammo_magazine/rifle/type71, new_human, 0, 7)
/datum/equipment_preset/upp/commando/leader/get_antag_clothing_equipment()
return list(
@@ -2443,7 +2468,7 @@
list("BELT (CHOOSE 1)", 0, null, null, null),
list("Type 41 Ammo Load Rig", 0, /obj/item/storage/belt/marine/upp, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("Type 41 Pistol Holster Rig", 0, /obj/item/storage/belt/gun/type47/PK9/tranq, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("NPZ92 Pistol Holster Rig", 0, /obj/item/storage/belt/gun/type47/np92/suppressed, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
list("Auto-Injector Pouch", 0, /obj/item/storage/pouch/autoinjector, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
@@ -2554,7 +2579,7 @@
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/UPP/cct(new_human), WEAR_L_EAR)
new_human.equip_to_slot_or_del(new /obj/item/clothing/glasses/welding(new_human), WEAR_EYES)
new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/yellow(new_human), WEAR_HANDS)
- new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/PK9(new_human), WEAR_WAIST)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/revolver(new_human), WEAR_WAIST)
new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP(new_human), WEAR_JACKET)
new_human.equip_to_slot_or_del(new /obj/item/tool/weldpack(new_human), WEAR_BACK)
new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/large(new_human), WEAR_L_STORE)
@@ -2576,7 +2601,9 @@
list("MRE", 0, /obj/item/storage/box/MRE, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
list("PERSONAL SIDEARM (CHOOSE 1)", 0, null, null, null),
- list("Korovin PK-9 Pistol", 0, /obj/item/weapon/gun/pistol/c99/upp, MARINE_CAN_BUY_ATTACHMENT, VENDOR_ITEM_REGULAR),
+ list("Type 73 Pistol", 0, /obj/item/weapon/gun/pistol/t73, MARINE_CAN_BUY_ATTACHMENT, VENDOR_ITEM_RECOMMENDED),
+ list("NP92 Pistol", 0, /obj/item/weapon/gun/pistol/np92, MARINE_CAN_BUY_ATTACHMENT, VENDOR_ITEM_REGULAR),
+ list("ZHNK-72 Revolver", 0, /obj/item/weapon/gun/revolver/upp, MARINE_CAN_BUY_ATTACHMENT, VENDOR_ITEM_REGULAR),
list("BELT (CHOOSE 1)", 0, null, null, null),
list("G8-A General Utility Pouch", 0, /obj/item/storage/backpack/general_belt, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
@@ -2667,9 +2694,9 @@
new_human.equip_to_slot_or_del(new /obj/item/device/defibrillator, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/storage/firstaid/adv, WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/roller/surgical, WEAR_IN_BACK)
- new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK)
- new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK)
- new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_BACK)
+ new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/pistol/np92, WEAR_IN_BACK) //targeting unarmed medical personal is not a war crime in aliens(primarily because, off memory, warcrimes aren't really a thing, although this definately is bad manners), and the playerbase is HRP in this concern!(if you don't get the joke, the players regularly execute unarmed doctors in hvh events. :D)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/pistol/np92, WEAR_IN_BACK)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/pistol/np92, WEAR_IN_BACK)
//face
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/UPP, WEAR_L_EAR)
if(new_human.disabilities & NEARSIGHTED)
@@ -2685,12 +2712,15 @@
new_human.equip_to_slot_or_del(UPP, WEAR_BODY)
//waist
new_human.equip_to_slot_or_del(new /obj/item/storage/belt/medical/lifesaver/upp/full, WEAR_WAIST)
+ new_human.equip_to_slot_or_del(new /obj/item/reagent_container/hypospray/autoinjector/oxycodone, WEAR_IN_BELT)
//limbs
new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET)
new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS)
//póckets
- new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/medium, WEAR_R_STORE)
- new_human.equip_to_slot_or_del(new /obj/item/reagent_container/hypospray/autoinjector/oxycodone, WEAR_IN_R_STORE)
+ new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/large, WEAR_R_STORE)
+ new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_R_STORE)
+ new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_R_STORE)
+ new_human.equip_to_slot_or_del(new /obj/item/reagent_container/food/snacks/upp, WEAR_IN_R_STORE)
new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/medical, WEAR_L_STORE)
new_human.equip_to_slot_or_del(new /obj/item/tool/surgery/synthgraft, WEAR_IN_L_STORE)
new_human.equip_to_slot_or_del(new /obj/item/device/healthanalyzer, WEAR_IN_L_STORE)
@@ -2705,6 +2735,7 @@
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
list("Medic Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/medic, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY),
+ list("UL6 Personal Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/support, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
list("Headset", 0, /obj/item/device/radio/headset/distress/UPP, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
list("Ration", 0, /obj/item/reagent_container/food/snacks/upp, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
diff --git a/code/modules/gear_presets/uscm_event.dm b/code/modules/gear_presets/uscm_event.dm
index 77f7665ce5b7..8109a458ac41 100644
--- a/code/modules/gear_presets/uscm_event.dm
+++ b/code/modules/gear_presets/uscm_event.dm
@@ -167,9 +167,9 @@
//Otherwise, if you spawn the spy next to other people
//they will see messages for them putting guns and explosives into their backpack...
new_human.equip_to_slot_or_del(new /obj/item/handcuffs(new_human.back), WEAR_IN_BACK)
- new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/pistol/c99/upp/tranq(new_human.back), WEAR_IN_BACK)
- new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/pistol/c99/tranq(new_human.back), WEAR_IN_BACK)
- new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/pistol/c99/tranq(new_human.back), WEAR_IN_BACK)
+ new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/pistol/np92/suppressed/tranq(new_human.back), WEAR_IN_BACK)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/pistol/np92/tranq(new_human.back), WEAR_IN_BACK)
+ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/pistol/np92/tranq(new_human.back), WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/storage/box/handcuffs(new_human.back), WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/device/chameleon(new_human.back), WEAR_IN_BACK)
new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/large(new_human), WEAR_R_STORE)
diff --git a/code/modules/gear_presets/uscm_ship.dm b/code/modules/gear_presets/uscm_ship.dm
index 578114222c01..f3129acb23d2 100644
--- a/code/modules/gear_presets/uscm_ship.dm
+++ b/code/modules/gear_presets/uscm_ship.dm
@@ -320,7 +320,6 @@
ACCESS_MARINE_CARGO,
ACCESS_MARINE_RO,
ACCESS_MARINE_COMMAND,
- ACCESS_MARINE_DATABASE,
ACCESS_MARINE_ALPHA,
ACCESS_MARINE_BRAVO,
ACCESS_MARINE_CHARLIE,
@@ -637,6 +636,7 @@
. = ..()
access = list(
ACCESS_MARINE_SENIOR,
+ ACCESS_MARINE_DATABASE,
ACCESS_MARINE_ASO,
ACCESS_MARINE_COMMAND,
ACCESS_MARINE_BRIG,
diff --git a/code/modules/hydroponics/hydro_tray.dm b/code/modules/hydroponics/hydro_tray.dm
index 9549b8fa59c1..83824bcedaa6 100644
--- a/code/modules/hydroponics/hydro_tray.dm
+++ b/code/modules/hydroponics/hydro_tray.dm
@@ -225,13 +225,8 @@
var/turf/T = loc
// Handle light requirements.
- var/area/A = T.loc
- if(A)
- var/light_available
- if(A.lighting_use_dynamic)
- light_available = max(0,min(10,T.lighting_lumcount)-5)
- else
- light_available = 5
+ if(T)
+ var/light_available = T.get_lumcount(0, 10)
if(abs(light_available - seed.ideal_light) > seed.light_tolerance)
plant_health -= healthmod
@@ -427,10 +422,10 @@
// Update bioluminescence.
if(seed)
if(seed.biolum)
- SetLuminosity(round(seed.potency/10))
+ set_light(round(seed.potency/10))
return
- SetLuminosity(0)
+ set_light(0)
return
// If a weed growth is sufficient, this proc is called.
@@ -539,8 +534,7 @@
// Bookkeeping.
check_level_sanity()
- force_update = 1
- process()
+
return
@@ -675,10 +669,7 @@
var/area/A = T.loc
var/light_available
if(A)
- if(A.lighting_use_dynamic)
- light_available = max(0,min(10,T.lighting_lumcount)-5)
- else
- light_available = 5
+ light_available = max(0,min(10,T.dynamic_lumcount)-5)
info += "The tray's sensor suite is reporting a light level of [light_available] lumens.\n"
return info
diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm
index 90e1b7ac5351..2aff95eb1fcc 100644
--- a/code/modules/hydroponics/seed_datums.dm
+++ b/code/modules/hydroponics/seed_datums.dm
@@ -608,7 +608,7 @@ var/global/list/gene_tag_masks = list() // Gene obfuscation for delicious tria
product.desc += " On second thought, something about this one looks strange."
if(biolum)
- product.SetLuminosity(biolum)
+ product.set_light(biolum)
//Handle spawning in living, mobile products (like dionaea).
if(istype(product,/mob/living))
diff --git a/code/modules/hydroponics/vines.dm b/code/modules/hydroponics/vines.dm
index 3745848ea254..14091a1d29bb 100644
--- a/code/modules/hydroponics/vines.dm
+++ b/code/modules/hydroponics/vines.dm
@@ -168,10 +168,10 @@
// Update bioluminescence.
if(seed.biolum)
- SetLuminosity(1+round(seed.potency/10))
+ set_light(1+round(seed.potency/10))
return
else
- SetLuminosity(0)
+ set_light(0)
// Update flower/product overlay.
overlays.Cut()
@@ -252,11 +252,7 @@
var/area/A = T.loc
if(A)
- var/light_available
- if(A.lighting_use_dynamic)
- light_available = max(0,min(10,T.lighting_lumcount)-5)
- else
- light_available = 5
+ var/light_available = max(0,min(10,T.dynamic_lumcount)-5)
if(abs(light_available - seed.ideal_light) > seed.light_tolerance)
die()
return
diff --git a/code/modules/lighting/_LIGHTING_README.MD b/code/modules/lighting/_LIGHTING_README.MD
new file mode 100644
index 000000000000..a7e7166e6b8d
--- /dev/null
+++ b/code/modules/lighting/_LIGHTING_README.MD
@@ -0,0 +1,75 @@
+# The Lighting Systems
+## Introduction
+
+Hello reader, and welcome to the coders guide to lighting. TGMC uses three different lighting systems: Static Lighting, Movable Lighting and Hybrid Lighting
+These all have their pros and cons, and are explained later in this file.
+For now we will look at the frameworks we have pertaining to lighting.
+
+```dm
+//Our vars:
+//The "intensity" of our light to determine how much it actually lights up
+var/light_power
+// The range of our light, aka how many turfs are actually lit up
+var/light_range
+//the color of our light
+var/light_color
+///whether the light is actually on or not, use /atom/proc/turn_on() to set this
+var/light_on
+```
+
+Additionally, we have SSlighting, the lighting subsystem which handles lighting updates for Static and Hybrid lighting.
+This subsystems processes enqueued lighting object, corner and source updates, as well as taking enqueued hybrid lighting updates.
+You shouldnt really be touching this as it primarily just stops too many updates from happening at once.
+
+## The Lighting systems
+As mentioned previously,lighting is split into three seperate systems who's functionality, benefits and downsides will be discussed below
+
+Seperate from these systems we also have a system to update the base lighting of an area, we do this using "Base lighting"
+
+```dm
+/area/proc/set_base_lighting(new_base_lighting_color = -1, new_alpha = -1)
+```
+Use this to set areas as required to luminosity. This is expensive-ish to apply/update but is very cheap to maintain. It also enables area specific light intensity and color changes.
+
+### Static Lighting
+Static lighting consists of a single, static_lighting_source light source which gets all turfs in view, then tells their /datum/static_lighting_objects to update themselves. These lighting objects manage two things: lighting corners, and an underlay. The lighting corners hold data for the edges of turfs next to darkness to allow a smooth transition from dark to light, and the actual lighting is done using an underlay which is layered over the darkness layer in order to create light. Color is changed using a color matrix.
+The advantage of this system, is that it is cheap, as long as it does not need to actively update opacity changes or a moving light target.
+This system can also be used for as large lights as you want.
+The disadvantage however is that updating this type of light, such as when it moves is relatively expensive, and colors are not always the prettiest. Additionally, lighting corners are known to be a large source of RAM usage and thus you should only load lighting objects in areas hat it is needed using /area/var/static_lighting.
+Thus this should be your go to choice for large, frequent, immobile lights.
+
+To update lights using this system use
+```dm
+/atom/proc/set_light(l_range, l_power, l_color, mask_type)
+```
+Note that the use of mask_type only is applicable to Hybrid lights.
+
+### Movable lighting
+Movable lighting is extremely simple and cheap as it requires no updates. This is done by replacing a large amount of updating objects with one single, large vis_contents overlay, which we apply and manage through a component (/datum/component/overlay_lighting). This means that it will move smoothly when the owner moves and requires no updating, but also means that rendering issues might occur, where the overlay will seemingly "pop in" to existence as it suddenly renders when someone walks around a corner or into the 1/2-tile render buffer around the edges of the viewport.
+Thus this should be your go to ideal cheap light for small and mobile lights (NOT turfs or anchored objects!). This light also typically has more saturated colors than static lighting.
+
+Note that this lighting type utilises special update procs from the other two lighting types, specifically
+```dm
+//update light variables
+/atom/movable/proc/set_light_range_power_color(range, power, color)
+ set_light_range(range)
+ set_light_power(power)
+ set_light_color(color)
+
+//turn the light on and off without changing any variables
+/atom/proc/set_light_on(new_value)
+```
+
+### Hybrid lighting
+Hybrid lighting is, as the name implies, a hybrid of the two above systems. It still needs to update when the owner moves, or something in view changes like static lighting does, but uses overlays to hide areas using shadows. As a result, this has similar if not better performance to Static lighting, but has a higher drain on player GPU and thus you should ideally avoid lagging players that play on terrible computers too much. This means that you should use this lighting in decently sized lights that act as centerpieces for a scene (i.e. a fire, supermatter, etc.) since it combines the best of static and movable lighting at a clientside performance cost.
+As a rule of thumb most items will be fine using this except for light fixtures, as lag mostly seems to crop up from multiple large lighting sources.
+Using lights for turf based fires and large floodlights is thus fine, but be careful with frquesnt use.
+It functions by fetching all nearby blockers, then calculating triangles behind these blocked areas which it then masks with overlays.
+These overlays then render as an alpha mask blocking the light from appearing.
+This system also supports non-round lights, such as light cones, rotating lights, and shimmering lights through the use of
+```dm
+var/mask_type
+```
+which determines which type of icon we are going to use as the base when drawing this lights (/atom/movable/lighting_mask/flicker for shimmering lights as an example).
+
+Actual updates however are handled through the same procs as Static lighting, and the mask_type argument on set_light() allows you to change the mask type that is being used on the fly.
diff --git a/code/modules/lighting/emissive_blocker.dm b/code/modules/lighting/emissive_blocker.dm
new file mode 100644
index 000000000000..ca9b5c7ff900
--- /dev/null
+++ b/code/modules/lighting/emissive_blocker.dm
@@ -0,0 +1,37 @@
+/**
+ * Internal atom that copies an appearance on to the blocker plane
+ *
+ * Copies an appearance vis render_target and render_source on to the emissive blocking plane.
+ * This means that the atom in question will block any emissive sprites.
+ * This should only be used internally. If you are directly creating more of these, you're
+ * almost guaranteed to be doing something wrong.
+ */
+/atom/movable/emissive_blocker
+ name = "emissive blocker"
+ plane = EMISSIVE_PLANE
+ layer = FLOAT_LAYER
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ //Why?
+ //render_targets copy the transform of the target as well, but vis_contents also applies the transform
+ //to what's in it. Applying RESET_TRANSFORM here makes vis_contents not apply the transform.
+ //Since only render_target handles transform we don't get any applied transform "stacking"
+ appearance_flags = EMISSIVE_APPEARANCE_FLAGS
+
+/atom/movable/emissive_blocker/Initialize(mapload, source)
+ . = ..()
+ verbs.Cut() //Cargo culting from lighting object, this maybe affects memory usage?
+
+ render_source = source
+ color = GLOB.em_block_color
+
+
+/atom/movable/emissive_blocker/ex_act(severity)
+ return FALSE
+
+/atom/movable/emissive_blocker/onTransitZ()
+ return
+
+//Prevents people from moving these after creation, because they shouldn't be.
+/atom/movable/emissive_blocker/forceMove(atom/destination, no_tp=FALSE, harderforce = FALSE)
+ if(harderforce)
+ return ..()
diff --git a/code/modules/lighting/lighting_area.dm b/code/modules/lighting/lighting_area.dm
new file mode 100644
index 000000000000..2b6a1409f38a
--- /dev/null
+++ b/code/modules/lighting/lighting_area.dm
@@ -0,0 +1,59 @@
+/area
+ luminosity = 1
+ ///The mutable appearance we underlay to show light
+ var/mutable_appearance/lighting_effect = null
+ ///Whether this area has a currently active base lighting, bool
+ var/area_has_base_lighting = FALSE
+ ///alpha 0-255 of lighting_effect and thus baselighting intensity
+ var/base_lighting_alpha = 0
+ ///The colour of the light acting on this area
+ var/base_lighting_color = COLOR_WHITE
+
+/area/proc/set_base_lighting(new_base_lighting_color = -1, new_alpha = -1)
+ if(base_lighting_alpha == new_alpha && base_lighting_color == new_base_lighting_color)
+ return FALSE
+ if(new_alpha != -1)
+ base_lighting_alpha = new_alpha
+ if(new_base_lighting_color != -1)
+ base_lighting_color = new_base_lighting_color
+ update_base_lighting()
+ return TRUE
+
+/area/vv_edit_var(var_name, var_value)
+ switch(var_name)
+ if("base_lighting_color")
+ set_base_lighting(new_base_lighting_color = var_value)
+ return TRUE
+ if("base_lighting_alpha")
+ set_base_lighting(new_alpha = var_value)
+ return TRUE
+ return ..()
+
+/area/proc/update_base_lighting()
+ if(!area_has_base_lighting && (!base_lighting_alpha || !base_lighting_color))
+ return
+
+ if(!area_has_base_lighting)
+ add_base_lighting()
+ return
+ remove_base_lighting()
+ if(base_lighting_alpha && base_lighting_color)
+ add_base_lighting()
+
+/area/proc/remove_base_lighting()
+ for(var/turf/T in src)
+ T.overlays -= lighting_effect
+ QDEL_NULL(lighting_effect)
+ area_has_base_lighting = FALSE
+
+/area/proc/add_base_lighting()
+ lighting_effect = mutable_appearance('icons/effects/alphacolors.dmi', "white")
+ lighting_effect.plane = LIGHTING_PLANE
+ lighting_effect.layer = LIGHTING_PRIMARY_LAYER
+ lighting_effect.blend_mode = BLEND_ADD
+ lighting_effect.alpha = base_lighting_alpha
+ lighting_effect.color = base_lighting_color
+ for(var/turf/T in src)
+ T.overlays += lighting_effect
+ T.luminosity = 1
+ area_has_base_lighting = TRUE
diff --git a/code/modules/lighting/lighting_atom.dm b/code/modules/lighting/lighting_atom.dm
new file mode 100644
index 000000000000..2abe8c598032
--- /dev/null
+++ b/code/modules/lighting/lighting_atom.dm
@@ -0,0 +1,178 @@
+
+// The proc you should always use to set the light of this atom.
+// Nonesensical value for l_color default, so we can detect if it gets set to null.
+#define NONSENSICAL_VALUE -99999
+/atom/proc/set_light(l_range, l_power, l_color = NONSENSICAL_VALUE, mask_type = null)
+ if(l_range > 0 && l_range < MINIMUM_USEFUL_LIGHT_RANGE)
+ l_range = MINIMUM_USEFUL_LIGHT_RANGE //Brings the range up to 1.4, which is just barely brighter than the soft lighting that surrounds players.
+
+ if(l_power != null)
+ light_power = l_power
+
+ if(l_range != null)
+ light_range = l_range
+ light_on = (light_range>0) ? TRUE : FALSE
+
+ if(l_color != NONSENSICAL_VALUE)
+ light_color = l_color
+
+ if(mask_type != null)
+ light_mask_type = mask_type
+
+ SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT, l_range, l_power, l_color)
+
+ update_light()
+
+/atom/proc/fade_light(new_colour, time)
+ light_color = new_colour
+ if(light?.our_mask)
+ animate(light.our_mask, color = new_colour, time = time)
+
+/// Will update the light (duh).Creates or destroys it if needed, makes it update values, makes sure it's got the correct source turf...
+/atom/proc/update_light()
+ set waitfor = FALSE
+
+ if(QDELETED(src))
+ return
+ if(light_system == STATIC_LIGHT)
+ static_update_light()
+ return
+
+ if((!light_power || !light_range) && light) // We won't emit light anyways, destroy the light source.
+ QDEL_NULL(light)
+ return
+ if(light && light_mask_type && (light_mask_type != light.mask_type))
+ QDEL_NULL(light)
+ if(!light) // Update the light or create it if it does not exist.
+ light = new /datum/dynamic_light_source(src, light_mask_type)
+ return
+ light.set_light(light_range, light_power, light_color)
+ light.update_position()
+
+
+/**
+ * Updates the atom's opacity value.
+ *
+ * This exists to act as a hook for associated behavior.
+ * It notifies (potentially) affected light sources so they can update (if needed).
+ */
+/atom/proc/set_opacity(new_opacity)
+ if(new_opacity == opacity)
+ return
+ SEND_SIGNAL(src, COMSIG_ATOM_SET_OPACITY, new_opacity)
+ . = opacity
+
+ opacity = new_opacity
+
+/atom/movable/set_opacity(new_opacity)
+ . = ..()
+ if(isnull(.) || !isturf(loc))
+ return
+
+ if(opacity)
+ AddElement(/datum/element/light_blocking)
+ else
+ RemoveElement(/datum/element/light_blocking)
+
+
+/turf/set_opacity(new_opacity)
+ . = ..()
+ if(isnull(.))
+ return
+ recalculate_directional_opacity()
+
+/atom/vv_edit_var(var_name, var_value)
+ switch(var_name)
+ if("light_range")
+ if(light_system != MOVABLE_LIGHT)
+ set_light(l_range = var_value)
+ else
+ set_light_range(var_value)
+ datum_flags |= DF_VAR_EDITED
+ return TRUE
+
+ if("light_power")
+ if(light_system != MOVABLE_LIGHT)
+ set_light(l_power = var_value)
+ else
+ set_light_power(var_value)
+ datum_flags |= DF_VAR_EDITED
+ return TRUE
+
+ if("light_color")
+ if(light_system != MOVABLE_LIGHT)
+ set_light(l_color = var_value)
+ else
+ set_light_color(var_value)
+ datum_flags |= DF_VAR_EDITED
+ return TRUE
+ return ..()
+
+
+/atom/proc/flash_lighting_fx(
+ _range = FLASH_LIGHT_RANGE,
+ _power = FLASH_LIGHT_POWER,
+ _color = LIGHT_COLOR_WHITE,
+ _duration = FLASH_LIGHT_DURATION,
+ _reset_lighting = TRUE,
+ _flash_times = 1)
+ new /obj/effect/light_flash(get_turf(src), _range, _power, _color, _duration, _flash_times)
+
+
+/obj/effect/light_flash/Initialize(mapload, _range = FLASH_LIGHT_RANGE, _power = FLASH_LIGHT_POWER, _color = LIGHT_COLOR_WHITE, _duration = FLASH_LIGHT_DURATION, _flash_times = 1)
+ light_range = _range
+ light_power = _power
+ light_color = _color
+ . = ..()
+ do_flashes(_flash_times, _duration)
+
+/obj/effect/light_flash/proc/do_flashes(_flash_times, _duration)
+ set waitfor = FALSE
+ for(var/i in 1 to _flash_times)
+ //Something bad happened
+ if(!(light?.our_mask))
+ break
+ light.our_mask.alpha = 255
+ animate(light.our_mask, time = _duration, easing = SINE_EASING, alpha = 0, flags = ANIMATION_END_NOW)
+ sleep(_duration) //this is extremely short so it's ok to sleep
+ qdel(src)
+
+/atom/proc/set_light_range(new_range)
+ if(new_range == light_range)
+ return
+ SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_RANGE, new_range)
+ . = light_range
+ light_range = new_range
+
+
+/atom/proc/set_light_power(new_power)
+ if(new_power == light_power)
+ return
+ SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_POWER, new_power)
+ . = light_power
+ light_power = new_power
+
+
+/atom/proc/set_light_color(new_color)
+ if(new_color == light_color)
+ return
+ SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_COLOR, new_color)
+ . = light_color
+ light_color = new_color
+
+
+/atom/proc/set_light_on(new_value)
+ if(new_value == light_on)
+ return
+ SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_ON, new_value)
+ . = light_on
+ light_on = new_value
+
+
+/// Setter for the light flags of this atom.
+/atom/proc/set_light_flags(new_value)
+ if(new_value == light_flags)
+ return
+ SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_FLAGS, new_value)
+ . = light_flags
+ light_flags = new_value
diff --git a/code/modules/lighting/lighting_mask/dynamic_lighting_source.dm b/code/modules/lighting/lighting_mask/dynamic_lighting_source.dm
new file mode 100644
index 000000000000..c0bf02daae48
--- /dev/null
+++ b/code/modules/lighting/lighting_mask/dynamic_lighting_source.dm
@@ -0,0 +1,103 @@
+// This is where the fun begins.
+// These are the main datums that emit light.
+
+/datum/dynamic_light_source
+ ///source atom that we belong to
+ var/atom/source_atom
+ ///The atom that the source atom is contained inside
+ var/atom/movable/contained_atom
+ ///our last loc
+ var/atom/cached_loc
+ //the turf where cached loc was
+ var/turf/source_turf
+ ///the turf the contained atom appears to be covering
+ var/turf/pixel_turf
+ /// Intensity of the emitter light.
+ var/light_power = 0
+ /// The range of the emitted light.
+ var/light_range = 0
+ /// The colour of the light, string, decomposed by PARSE_LIGHT_COLOR()
+ var/light_color = NONSENSICAL_VALUE
+
+ /// Whether we have applied our light yet or not.
+ var/applied = FALSE
+
+ ///typepath for the mask type we are using
+ var/mask_type
+ ///reference to the mask holder effect
+ var/obj/effect/lighting_mask_holder/mask_holder
+ ///reference to the mask contained within the mask_holder objects vis_contents
+ var/atom/movable/lighting_mask/our_mask
+
+/datum/dynamic_light_source/New(atom/movable/owner, mask_type = /atom/movable/lighting_mask)
+ source_atom = owner // Set our new owner.
+ LAZYADD(source_atom.hybrid_light_sources, src)
+
+ //Find the atom that contains us
+ find_containing_atom()
+
+ source_turf = get_turf(source_atom)
+
+ src.mask_type = mask_type
+ mask_holder = new(source_turf)
+ our_mask = new mask_type
+ mask_holder.assign_mask(our_mask)
+ our_mask.attached_atom = owner
+
+ //Set light vars
+ set_light(owner.light_range, owner.light_power, owner.light_color)
+
+ //Calculate shadows
+ our_mask.queue_mask_update()
+
+ //Set direction
+ our_mask.rotate_mask_on_holder_turn(contained_atom.dir)
+ RegisterSignal(our_mask, COMSIG_ATOM_DIR_CHANGE, TYPE_PROC_REF(/atom/movable/lighting_mask, rotate_mask_on_holder_turn))
+
+/datum/dynamic_light_source/Destroy(force)
+ //Remove references to ourself.
+ LAZYREMOVE(source_atom?.hybrid_light_sources, src)
+ LAZYREMOVE(contained_atom?.hybrid_light_sources, src)
+ QDEL_NULL(mask_holder)
+ our_mask = null//deletion handled on holder
+ return ..()
+
+///Updates containing atom
+/datum/dynamic_light_source/proc/find_containing_atom()
+ //Remove ourselves from the old containing atoms light sources
+ if(contained_atom && contained_atom != source_atom)
+ LAZYREMOVE(contained_atom.hybrid_light_sources, src)
+ //Find our new container
+ if(isturf(source_atom) || isarea(source_atom))
+ contained_atom = source_atom
+ return
+ contained_atom = source_atom.loc
+ for(var/sanity in 1 to 20)
+ if(!contained_atom)
+ //Welcome to nullspace my friend.
+ contained_atom = source_atom
+ return
+ if(isturf(contained_atom.loc))
+ break
+ contained_atom = contained_atom.loc
+ //Add ourselves to their light sources
+ if(contained_atom != source_atom)
+ LAZYADD(contained_atom.hybrid_light_sources, src)
+
+///Update light if changed.
+/datum/dynamic_light_source/proc/set_light(l_range, l_power, l_color = NONSENSICAL_VALUE)
+ if(!our_mask)
+ return
+ if(l_range && l_range != light_range)
+ light_range = l_range
+ our_mask.set_radius(l_range)
+ if(l_power && l_power != light_power)
+ light_power = l_power
+ our_mask.set_intensity(l_power)
+ if(l_color != NONSENSICAL_VALUE && l_color != light_color)
+ light_color = l_color
+ our_mask.set_color(l_color)
+
+/datum/dynamic_light_source/proc/update_position()
+ mask_holder.forceMove(get_turf(source_atom))
+ find_containing_atom()
diff --git a/code/modules/lighting/lighting_mask/lighting_mask.dm b/code/modules/lighting/lighting_mask/lighting_mask.dm
new file mode 100644
index 000000000000..bf824033adfb
--- /dev/null
+++ b/code/modules/lighting/lighting_mask/lighting_mask.dm
@@ -0,0 +1,153 @@
+///Lighting mask sprite radius in tiles
+#define LIGHTING_MASK_RADIUS 4
+///Lighting mask sprite diameter in pixels
+#define LIGHTING_MASK_SPRITE_SIZE LIGHTING_MASK_RADIUS * 64
+
+/atom/movable/lighting_mask
+ name = ""
+ icon = LIGHTING_ICON_BIG
+ icon_state = "light_big"
+
+ anchored = TRUE
+ plane = LIGHTING_PLANE
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ layer = LIGHTING_SECONDARY_LAYER
+ invisibility = INVISIBILITY_LIGHTING
+ blend_mode = BLEND_ADD
+ appearance_flags = KEEP_TOGETHER|RESET_TRANSFORM
+
+ ///The current angle the item is pointing at
+ var/current_angle = 0
+
+ ///The radius of illumination of the mask
+ var/radius = 0
+
+ ///The atom that we are attached to, does not need hard del protection as we are deleted with it
+ var/atom/attached_atom
+
+ ///Reference to the holder /obj/effect
+ var/obj/effect/lighting_mask_holder/mask_holder
+
+ ///Prevents us from registering for update twice before SSlighting init
+ var/awaiting_update = FALSE
+ ///Set to TRUE if you want the light to rotate with the owner
+ var/is_directional = FALSE
+
+/atom/movable/lighting_mask/Initialize(mapload, ...)
+ . = ..()
+ add_filter("pixel_smoother", 3, gauss_blur_filter(2))
+ add_filter("shadow_alpha_masking", 4, alpha_mask_filter(render_source = SHADOW_RENDER_TARGET, flags = MASK_INVERSE))
+
+/atom/movable/lighting_mask/Destroy()
+ mask_holder = null
+ attached_atom = null
+ return ..()
+
+///Sets the radius of the mask, and updates everything that needs to be updated
+/atom/movable/lighting_mask/proc/set_radius(new_radius, transform_time = 0)
+ //Update our matrix
+ var/matrix/new_size_matrix = get_matrix(new_radius)
+ apply_matrix(new_size_matrix, transform_time)
+ radius = new_radius
+ //then recalculate and redraw
+ queue_mask_update()
+
+///if you want the matrix to grow or shrink, you can do that using this proc when applyng it
+/atom/movable/lighting_mask/proc/apply_matrix(matrix/to_apply, transform_time = 0)
+ if(transform_time)
+ animate(src, transform = to_apply, time = transform_time)
+ else
+ transform = to_apply
+
+///Creates a matrix for the lighting mak to use
+/atom/movable/lighting_mask/proc/get_matrix(radius = 1)
+ var/matrix/new_size_matrix = new()
+ //Scale
+ // - Scale to the appropriate radius
+ new_size_matrix.Scale(radius / LIGHTING_MASK_RADIUS)
+ //Translate
+ // - Center the overlay image
+ // - Ok so apparently translate is affected by the scale we already did huh.
+ // ^ Future me here, its because it works as translate then scale since its backwards.
+ // ^ ^ Future future me here, it totally shouldnt since the translation component of a matrix is independant to the scale component.
+ new_size_matrix.Translate(-128 + 16)
+ //Adjust for pixel offsets
+ var/invert_offsets = attached_atom.dir & (NORTH | EAST)
+ var/left_or_right = attached_atom.dir & (EAST | WEST)
+ var/offset_x = (left_or_right ? attached_atom.light_pixel_y : attached_atom.light_pixel_x) * (invert_offsets ? -1 : 1)
+ var/offset_y = (left_or_right ? attached_atom.light_pixel_x : attached_atom.light_pixel_y) * (invert_offsets ? -1 : 1)
+ new_size_matrix.Translate(offset_x, offset_y)
+ if(is_directional)
+ //Rotate
+ // - Rotate (Directional lights)
+ new_size_matrix.Turn(current_angle)
+ return new_size_matrix
+
+///Rotates the light source to angle degrees.
+/atom/movable/lighting_mask/proc/rotate(angle = 0)
+ //Converting our transform is pretty simple.
+ var/matrix/rotated_matrix = matrix()
+ rotated_matrix.Turn(angle - current_angle)
+ rotated_matrix *= transform
+ //Overlays cannot be edited while applied, meaning their transform cannot be changed.
+ //Disconnect the shadows from the overlay, apply the transform and then reapply them as an overlay.
+ //Oh also since the matrix is really weird standard rotation matrices wont work here.
+ overlays.Cut()
+ //Disconnect from parent matrix, become a global position
+ for(var/mutable_appearance/shadow as anything in shadows) //Mutable appearances are children of icon
+ shadow.transform *= transform
+ shadow.transform /= rotated_matrix
+ //Apply our matrix
+ transform = rotated_matrix
+ overlays += shadows
+
+ //Now we are facing this direction
+ current_angle = angle
+
+///Setter proc for colors
+/atom/movable/lighting_mask/proc/set_color(colour = "#ffffff")
+ color = colour
+
+///Setter proc for the intensity of the mask
+/atom/movable/lighting_mask/proc/set_intensity(intensity = 1)
+ if(intensity >= 0)
+ alpha = ALPHA_TO_INTENSITY(intensity)
+ blend_mode = BLEND_ADD
+ else
+ alpha = ALPHA_TO_INTENSITY(-intensity)
+ blend_mode = BLEND_SUBTRACT
+
+///The holder atom turned, spins the mask if it's needed
+/atom/movable/lighting_mask/proc/rotate_mask_on_holder_turn(new_direction)
+ SIGNAL_HANDLER
+ rotate(dir2angle(new_direction) - 180)
+
+///Flickering lighting mask
+/atom/movable/lighting_mask/flicker
+ icon_state = "light_flicker"
+
+///Conical Light mask
+/atom/movable/lighting_mask/conical
+ icon_state = "light_conical"
+ is_directional = TRUE
+
+///Rotating Light mask
+/atom/movable/lighting_mask/rotating
+ icon_state = "light_rotating-1"
+
+/atom/movable/lighting_mask/rotating/Initialize(mapload, ...)
+ . = ..()
+ icon_state = "light_rotating-[rand(1, 3)]"
+
+///rotating light mask, but only pointing in one direction
+/atom/movable/lighting_mask/rotating_conical
+ icon_state = "light_conical_rotating"
+
+/atom/movable/lighting_mask/ex_act(severity, target)
+ return
+
+/atom/movable/lighting_mask/fire_act(exposed_temperature, exposed_volume)
+ return
+
+#undef LIGHTING_MASK_SPRITE_SIZE
+#undef LIGHTING_MASK_RADIUS
diff --git a/code/modules/lighting/lighting_mask/lighting_mask_holder.dm b/code/modules/lighting/lighting_mask/lighting_mask_holder.dm
new file mode 100644
index 000000000000..750a16fa1bfb
--- /dev/null
+++ b/code/modules/lighting/lighting_mask/lighting_mask_holder.dm
@@ -0,0 +1,22 @@
+///Holder for lighting mask, this is done for ensuing correct render as a viscontents
+/obj/effect/lighting_mask_holder
+ name = ""
+ anchored = TRUE
+ appearance_flags = NONE //Removes TILE_BOUND meaning that the lighting mask will be visible even if the source turf is not.
+ glide_size = INFINITY //prevent shadow jitter
+ ///The movable mask this holder is holding in its vis contents
+ var/atom/movable/lighting_mask/held_mask
+
+/obj/effect/lighting_mask_holder/proc/assign_mask(atom/movable/lighting_mask/mask)
+ vis_contents += mask
+ held_mask = mask
+ mask.mask_holder = src
+
+/obj/effect/lighting_mask_holder/Destroy(force)
+ vis_contents -= held_mask
+ QDEL_NULL(held_mask)
+ return ..()
+
+/obj/effect/lighting_mask_holder/Moved(atom/OldLoc, Dir)
+ . = ..()
+ held_mask?.queue_mask_update()//held mask can be null when it is deleted
diff --git a/code/modules/lighting/lighting_mask/shadow_calculator.dm b/code/modules/lighting/lighting_mask/shadow_calculator.dm
new file mode 100644
index 000000000000..42f98b47e789
--- /dev/null
+++ b/code/modules/lighting/lighting_mask/shadow_calculator.dm
@@ -0,0 +1,686 @@
+//Lighting texture scales in world units (divide by 32)
+//256 = 8,4,2
+//1024 = 32,16,8
+#define LIGHTING_SHADOW_TEX_SIZE 8
+
+///Eyeball number for radius based offsets do not touch
+#define RADIUS_BASED_OFFSET 3.5
+
+///Inserts a coord list into a grouped list
+#define COORD_LIST_ADD(listtoadd, x, y) \
+ if(islist(listtoadd["[x]"])) { \
+ var/list/_L = listtoadd["[x]"]; \
+ BINARY_INSERT_NUM(y, _L); \
+ } else { \
+ listtoadd["[x]"] = list(y);\
+ }
+
+#ifdef SHADOW_DEBUG
+///Color coded atom debug, note will break when theres planetside lgihting
+#define DEBUG_HIGHLIGHT(x, y, colour) \
+ do { \
+ var/turf/T = locate(x, y, 3); \
+ if(T) { \
+ T.color = colour; \
+ }\
+ } while (FALSE)
+
+//For debugging use when we want to know if a turf is being affected multiple times
+//#define DEBUG_HIGHLIGHT(x, y, colour) do{var/turf/T=locate(x,y,2);if(T){switch(T.color){if("#ff0000"){T.color = "#00ff00"}if("#00ff00"){T.color="#0000ff"}else{T.color="#ff0000"}}}}while(0)
+#define DO_SOMETHING_IF_DEBUGGING_SHADOWS(something) something
+#else
+#define DEBUG_HIGHLIGHT(x, y, colour)
+#define DO_SOMETHING_IF_DEBUGGING_SHADOWS(something)
+#endif
+
+/atom/movable/lighting_mask
+ ///Turfs that are being affected by this mask, this is for the sake of luminosity
+ var/list/turf/affecting_turfs
+ ///list of mutable appearance shadows
+ var/list/mutable_appearance/shadows
+ var/times_calculated = 0
+
+ //Please dont change these
+ var/calculated_position_x
+ var/calculated_position_y
+
+/atom/movable/lighting_mask/Destroy()
+ //Make sure we werent destroyed in init
+ SSlighting.mask_queue -= src
+ //Remove from affecting turfs
+ if(affecting_turfs)
+ for(var/turf/thing as anything in affecting_turfs)
+ var/area/A = thing.loc
+ LAZYREMOVE(thing.hybrid_lights_affecting, src)
+ if(!A.base_lighting_alpha)
+ thing.luminosity -= 1
+ affecting_turfs = null
+ //Cut the shadows. Since they are overlays they will be deleted when cut from overlays.
+ LAZYCLEARLIST(shadows)
+ return ..()
+
+/atom/movable/lighting_mask/proc/link_turf_to_light(turf/T)
+ LAZYOR(affecting_turfs, T)
+ LAZYOR(T.hybrid_lights_affecting, src)
+
+/atom/movable/lighting_mask/proc/unlink_turf_from_light(turf/T)
+ LAZYREMOVE(affecting_turfs, T)
+ LAZYREMOVE(T.hybrid_lights_affecting, src)
+
+///Enqueues the mask in the queue properly
+/atom/movable/lighting_mask/proc/queue_mask_update()
+ SSlighting.mask_queue |= src
+ awaiting_update = TRUE
+
+/**
+ * Returns a list of matrices corresponding to the matrices that should be applied to triangles of
+ * coordinates (0,0),(1,0),(0,1) to create a triangcalculate_shadows_matricesle that respresents the shadows
+ * takes in the old turf to smoothly animate shadow movement
+ */
+/atom/movable/lighting_mask/proc/calculate_lighting_shadows()
+ //Check to make sure lighting is actually started
+ //If not count the amount of duplicate requests created.
+ if(!SSlighting.started)
+ if(awaiting_update)
+ SSlighting.duplicate_shadow_updates_in_init++
+ return
+ queue_mask_update()
+ return
+ awaiting_update = FALSE
+ //we moved to nullspace meanwhile dont bother
+ if(!attached_atom.loc)
+ return
+
+ //Incremement the global counter for shadow calculations
+ SSlighting.total_shadow_calculations ++
+
+ //Ceiling the range since we need it in integer form
+ var/range = CEILING(radius, 1)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/timer = TICK_USAGE)
+
+ //Work out our position
+ //Calculate shadow origin offset
+ var/invert_offsets = attached_atom.dir & (NORTH | EAST)
+ var/left_or_right = attached_atom.dir & (EAST | WEST)
+ var/offset_x = (left_or_right ? attached_atom.light_pixel_y : attached_atom.light_pixel_x) * (invert_offsets ? -1 : 1)
+ var/offset_y = (left_or_right ? attached_atom.light_pixel_x : attached_atom.light_pixel_y) * (invert_offsets ? -1 : 1)
+
+ //Get the origin points
+ var/turf/our_turf = get_turf(attached_atom) //The mask is in nullspace, so we need the source turf of the container
+
+ //Account for pixel shifting and light offset
+ calculated_position_x = our_turf.x + ((offset_x) / world.icon_size)
+ calculated_position_y = our_turf.y + ((offset_y) / world.icon_size)
+
+ //Remove the old shadows
+ overlays.Cut()
+
+
+ //Reset the list
+ if(islist(affecting_turfs))
+ for(var/turf/T as anything in affecting_turfs)
+ LAZYREMOVE(T?.hybrid_lights_affecting, src)
+ //The turf is no longer affected by any lights, make it non-luminous.
+ var/area/A = T.loc
+ if(T?.luminosity && !A.base_lighting_alpha)
+ T.luminosity -= 1
+
+ //Clear the list
+ LAZYCLEARLIST(affecting_turfs)
+ LAZYCLEARLIST(shadows)
+
+ //Optimise grouping by storing as
+ // Key : x (AS A STRING BECAUSE BYOND DOESNT ALLOW FOR INT KEY DICTIONARIES)
+ // Value: List(y values)
+ var/list/opaque_atoms_in_view = list()
+
+ //Rebuild the list
+ var/is_on_closed_turf = istype(our_turf, /turf/closed)
+ for(var/turf/thing in dview(range, get_turf(attached_atom))) //most expensive part of shadow code is this dview and group_atoms
+ link_turf_to_light(thing)
+ //The turf is now affected by our light, make it luminous
+ thing.luminosity += 1
+ //Dont consider shadows about our turf.
+ if(!is_on_closed_turf)
+ if(thing == our_turf)
+ continue
+ if(thing.directional_opacity)
+ //At this point we no longer care about
+ //the atom itself, only the position values
+ COORD_LIST_ADD(opaque_atoms_in_view, thing.x, thing.y)
+ DEBUG_HIGHLIGHT(thing.x, thing.y, "#0000FF")
+
+ //We are too small to consider shadows on, luminsoty has been considered at least.
+ if(radius < 2)
+ return
+
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("[TICK_USAGE_TO_MS(timer)]ms to process view([range], src)."))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/temp_timer = TICK_USAGE)
+
+ //Group atoms together for optimisation
+ var/list/grouped_atoms = group_atoms(opaque_atoms_in_view)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("[TICK_USAGE_TO_MS(temp_timer)]ms to process group_atoms"))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/total_coordgroup_time = 0)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/total_cornergroup_time = 0)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/triangle_time = 0)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/culling_time = 0)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/triangle_to_matrix_time = 0)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/matrix_division_time = 0)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/MA_new_time = 0)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/MA_vars_time = 0)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/overlays_add_time = 0)
+
+ var/list/overlays_to_add = list()
+ for(var/group in grouped_atoms)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE)
+
+ var/list/coordgroup = calculate_corners_in_group(group)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(total_coordgroup_time += TICK_USAGE_TO_MS(temp_timer))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE)
+
+ //This is where the lines are made
+ var/list/cornergroup = get_corners_from_coords(coordgroup)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(total_cornergroup_time += TICK_USAGE_TO_MS(temp_timer))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE)
+
+ var/list/culledlinegroup = cull_blocked_in_group(cornergroup, opaque_atoms_in_view)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(culling_time += TICK_USAGE_TO_MS(temp_timer))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE)
+
+ if(!LAZYLEN(culledlinegroup))
+ continue
+
+ var/list/triangles = calculate_triangle_vertices(culledlinegroup)
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(triangle_time += TICK_USAGE_TO_MS(temp_timer))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE)
+
+ for(var/triangle in triangles)
+ var/matrix/triangle_matrix = triangle_to_matrix(triangle)
+
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(triangle_to_matrix_time += TICK_USAGE_TO_MS(temp_timer))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE)
+
+ triangle_matrix /= transform
+
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(matrix_division_time += TICK_USAGE_TO_MS(temp_timer))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE)
+
+ var/mutable_appearance/shadow = new()
+
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(MA_new_time += TICK_USAGE_TO_MS(temp_timer))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE)
+
+ shadow.icon = LIGHTING_ICON_BIG
+ shadow.icon_state = "triangle"
+ shadow.color = "#000"
+ shadow.transform = triangle_matrix
+ shadow.render_target = SHADOW_RENDER_TARGET
+ shadow.blend_mode = BLEND_OVERLAY
+
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(MA_vars_time += TICK_USAGE_TO_MS(temp_timer))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE)
+
+ LAZYADD(shadows, shadow)
+ overlays_to_add += shadow
+
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(overlays_add_time += TICK_USAGE_TO_MS(temp_timer))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE)
+
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/overlay_apply_time = TICK_USAGE)
+
+ overlays += overlays_to_add //batch appearance generation for free lag(tm)
+
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(overlay_apply_time = TICK_USAGE_TO_MS(overlay_apply_time))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("total_coordgroup_time: [total_coordgroup_time]ms"))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("total_cornergroup_time: [total_cornergroup_time]ms"))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("triangle_time calculation: [triangle_time]ms"))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("triangle_to_matrix_time: [triangle_to_matrix_time]ms"))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("Culling Time: [culling_time]ms"))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("matrix_division_time: [matrix_division_time]ms"))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("MA_new_time: [MA_new_time]ms"))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("MA_vars_time: [MA_vars_time]ms"))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("overlays_add_time: [overlays_add_time]ms"))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("overlay_apply_time: [overlay_apply_time]ms"))
+ DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("[TICK_USAGE_TO_MS(timer)]ms to process total."))
+
+
+/**
+ * Converts a triangle into a matrix that can be applied to a standardized triangle
+ * to make it represent the points.
+ */
+/atom/movable/lighting_mask/proc/triangle_to_matrix(list/triangle)
+ //We need the world position raw, if we use the calculated position then the pixel values will cancel.
+ var/turf/our_turf = get_turf(attached_atom)
+ var/ourx = our_turf.x
+ var/oury = our_turf.y
+
+ var/originx = triangle[1][1] - ourx //~Simultaneous Variable: U
+ var/originy = triangle[1][2] - oury //~Simultaneous Variable: V
+ //Get points translating the first point to (0, 0)
+ var/translatedPoint2x = triangle[2][1] - ourx //Simultaneous Variable: W
+ var/translatedPoint2y = triangle[2][2] - oury //Simultaneous Variable: X
+ var/translatedPoint3x = triangle[3][1] - ourx //Simultaneous Variable: Y
+ var/translatedPoint3y = triangle[3][2] - oury //Simultaneous Variable: Z
+ //message_admins("Point 1: ([originx], [originy])")
+ //message_admins("Point 2: ([translatedPoint2x], [translatedPoint2y])")
+ //message_admins("Point 3: ([translatedPoint3x], [translatedPoint3y])")
+ //Assumption that is incorrect
+ //Triangle points are
+ // (-4, -4)
+ // (-4, 4)
+ // ( 4, -4)
+ //Would be much easier if it was (0, 0) instead of (-4, -4) but since we have 6 inputs and 6 unknowns
+ //we can solve the values of the matrix pretty easilly simultaneously.
+ //In fact since variables U,W,Y,A,B,C are separate to V,X,Z,D,E,F its easy since its 2 identical tri-variable simultaneous equations.
+ //By solving the equations simultaneously we get these results:
+ //a = (y-u)/8
+ var/a = (translatedPoint3x - originx) / LIGHTING_SHADOW_TEX_SIZE
+ //b = (w-u)/ 8
+ var/b = (translatedPoint2x - originx) / LIGHTING_SHADOW_TEX_SIZE
+ //c = (y+w)/2
+ var/c = (translatedPoint3x + translatedPoint2x) / 2
+ //d = (z-v)/8
+ var/d = (translatedPoint3y - originy) / LIGHTING_SHADOW_TEX_SIZE
+ //e = (x-v)/8
+ var/e = (translatedPoint2y - originy) / LIGHTING_SHADOW_TEX_SIZE
+ //f = (z+x)/2
+ var/f = (translatedPoint3y + translatedPoint2y) / 2
+ //Matrix time g
+ //a,b,d and e can be used to define the shape, C and F can be used for translation god matrices are so beautiful
+ //Completely random offset that I didnt derive, I just trialled and errored for about 4 hours until it randomly worked
+ //var/radius_based_offset = radius * 3 + RADIUS_BASED_OFFSET <-- for 1024x1024 lights DO NOT USE 1024x1024 SHADOWS UNLESS YOU ARE PLAYING WITH RTX200000 OR SOMETHING
+ var/radius_based_offset = RADIUS_BASED_OFFSET
+ var/matrix/M = matrix(a, b, (c * 32) - ((radius_based_offset) * 32), d, e, (f * 32) - ((radius_based_offset) * 32))
+ //log_game("[M.a], [M.d], 0")
+ //log_game("[M.b], [M.e], 0")
+ //log_game("[M.c], [M.f], 1")
+ return M
+
+/**
+ * Basically takes the 2-4 corners, extends them and then generates triangle coordinates representing shadows
+ * Input: list(list(list(x, y), list(x, y)))
+ * Layer 1: Lines
+ * Layer 2: Vertex
+ * Layer 3: X/Y value
+ * OUTPUT: The same thing but with 3 lists embedded rather than 2 because they are triangles not lines now.
+ */
+/atom/movable/lighting_mask/proc/calculate_triangle_vertices(list/cornergroup)
+ var/shadow_radius = max(radius + 1, 3)
+ //Get the origin poin's
+ var/ourx = calculated_position_x
+ var/oury = calculated_position_y
+ //The output
+ . = list()
+ //Every line has 2 triangles innit
+ for(var/list/line as anything in cornergroup)
+ //Get the corner vertices
+ var/vertex1 = line[1]
+ var/vertex2 = line[2]
+ //Extend them and get end vertices
+ //Calculate vertex 3 position
+ var/delta_x = vertex1[1] - ourx
+ var/delta_y = vertex1[2] - oury
+ var/vertex3 = extend_line_to_radius(delta_x, delta_y, shadow_radius, ourx, oury)
+ var/vertex3side = (vertex3[1] - ourx) == -shadow_radius ? WEST : (vertex3[1] - ourx) == shadow_radius ? EAST : (vertex3[2] - oury) == shadow_radius ? NORTH : SOUTH
+
+ //For vertex 4
+ delta_x = vertex2[1] - ourx
+ delta_y = vertex2[2] - oury
+ var/vertex4 = extend_line_to_radius(delta_x, delta_y, shadow_radius, ourx, oury)
+ var/vertex4side = (vertex4[1] - ourx) == -shadow_radius ? WEST : (vertex4[1] - ourx) == shadow_radius ? EAST : (vertex4[2] - oury) == shadow_radius ? NORTH : SOUTH
+
+ //If vertex3 is not on the same border as vertex 4 then we need more triangles to fill in the space.
+ if(vertex3side != vertex4side)
+ var/eitherNorth = (vertex3side == NORTH || vertex4side == NORTH)
+ var/eitherEast = (vertex3side == EAST || vertex4side == EAST)
+ var/eitherSouth = (vertex3side == SOUTH || vertex4side == SOUTH)
+ var/eitherWest = (vertex3side == WEST || vertex4side == WEST)
+ if(eitherNorth && eitherEast)
+ //Add a vertex top right
+ var/vertex5 = list(shadow_radius + ourx, shadow_radius + oury)
+ var/triangle3 = list(vertex3, vertex4, vertex5)
+ . += list(triangle3)
+ else if(eitherNorth && eitherWest)
+ //Add a vertex top left
+ var/vertex5 = list(-shadow_radius + ourx, shadow_radius + oury)
+ var/triangle3 = list(vertex3, vertex4, vertex5)
+ . += list(triangle3)
+ else if(eitherNorth && eitherSouth) //BLOCKER IS A | SHAPE
+ //If vertex3 is to the right of the center, both vertices are to the right.
+ if(vertex3[1] > ourx)
+ //New vertexes are on the right
+ var/vertex5 = list(ourx + shadow_radius, oury + shadow_radius)
+ var/vertex6 = list(ourx + shadow_radius, oury - shadow_radius)
+ //If vertex 4 is greater than 3 then triangles link as 4,5,6 and 3,4,6
+ if(vertex4[2] > vertex3[2])
+ var/triangle3 = list(vertex3, vertex5, vertex6)
+ . += list(triangle3)
+ var/triangle4 = list(vertex3, vertex4, vertex5)
+ . += list(triangle4)
+ else
+ //Vertex 3 is greater than 4, so triangles link as 3,5,6 and 3,4,6
+ var/triangle3 = list(vertex3, vertex4, vertex5)
+ . += list(triangle3)
+ var/triangle4 = list(vertex4, vertex5, vertex6)
+ . += list(triangle4)
+ else
+ //New vertexes are on the left
+ var/vertex5 = list(ourx - shadow_radius, oury + shadow_radius)
+ var/vertex6 = list(ourx - shadow_radius, oury - shadow_radius)
+ //If vertex 4 is higher than 3 then triangles link as 4,5,6 and 3,4,6
+ if(vertex4[2] > vertex3[2])
+ var/triangle3 = list(vertex3, vertex5, vertex6)
+ . += list(triangle3)
+ var/triangle4 = list(vertex3, vertex4, vertex5)
+ . += list(triangle4)
+ else
+ //Vertex 3 is greater than 4, so triangles link as 3,5,6 and 3,4,6
+ var/triangle3 = list(vertex3, vertex4, vertex5)
+ . += list(triangle3)
+ var/triangle4 = list(vertex4, vertex5, vertex6)
+ . += list(triangle4)
+ else if(eitherEast && eitherSouth)
+ //Add a vertex bottom right
+ var/vertex5 = list(shadow_radius + ourx, -shadow_radius + oury)
+ var/triangle3 = list(vertex3, vertex4, vertex5)
+ . += list(triangle3)
+ else if(eitherEast && eitherWest) //BLOCKER IS A --- SHAPE
+ //If vertex3 is above the center, then pointers are along the top
+ if(vertex3[2] > oury)
+ //New vertexes are on the right
+ var/vertex5 = list(ourx + shadow_radius, oury + shadow_radius)
+ var/vertex6 = list(ourx - shadow_radius, oury + shadow_radius)
+ //If vertex 4 is greater than 3 then triangles link as 4,5,6 and 3,4,6
+ if(vertex4[1] > vertex3[1])
+ var/triangle3 = list(vertex3, vertex5, vertex6)
+ . += list(triangle3)
+ var/triangle4 = list(vertex3, vertex4, vertex5)
+ . += list(triangle4)
+ else
+ //Vertex 3 is greater than 4, so triangles link as 3,5,6 and 3,4,6
+ var/triangle3 = list(vertex3, vertex4, vertex5)
+ . += list(triangle3)
+ var/triangle4 = list(vertex4, vertex5, vertex6)
+ . += list(triangle4)
+ else
+ //New vertexes are on the bottom
+ var/vertex5 = list(ourx + shadow_radius, oury - shadow_radius)
+ var/vertex6 = list(ourx - shadow_radius, oury - shadow_radius)
+ //If vertex 4 is higher than 3 then triangles link as 4,5,6 and 3,4,6
+ if(vertex4[1] > vertex3[1])
+ var/triangle3 = list(vertex3, vertex4, vertex5)
+ . += list(triangle3)
+ var/triangle4 = list(vertex3, vertex5, vertex6)
+ . += list(triangle4)
+ else
+ //Vertex 3 is greater than 4, so triangles link as 3,5,6 and 3,4,6
+ var/triangle3 = list(vertex3, vertex4, vertex5)
+ . += list(triangle3)
+ var/triangle4 = list(vertex4, vertex5, vertex6)
+ . += list(triangle4)
+ else if(eitherSouth && eitherWest)
+ //Bottom left
+ var/vertex5 = list(-shadow_radius + ourx, -shadow_radius + oury)
+ var/triangle3 = list(vertex3, vertex4, vertex5)
+ . += list(triangle3)
+ else
+ //bug
+ stack_trace("Major error: vertex in a bad position (North: [eitherNorth], East: [eitherEast], South: [eitherSouth], West: [eitherWest])")
+
+ //Generate triangles
+ var/triangle1 = list(vertex1, vertex2, vertex3)
+ var/triangle2 = list(vertex2, vertex3, vertex4)
+ . += list(triangle1)
+ . += list(triangle2)
+
+///Takes in the list of lines and sight blockers and returns only the lines that are not blocked
+/atom/movable/lighting_mask/proc/cull_blocked_in_group(list/lines, list/sight_blockers)
+ . = list()
+ for(var/list/line in lines)
+ var/vertex1 = line[1]
+ var/vertex2 = line[2]
+ var/list/lines_to_add = list()
+ if(vertex1[1] == vertex2[1])
+ //Vertical line.
+ //Requires a block to the left and right all the way from the bottom to the top
+ var/left = vertex1[1] - 0.5
+ var/right = vertex1[1] + 0.5
+ var/bottom = min(vertex1[2], vertex2[2]) + 0.5
+ var/top = max(vertex1[2], vertex2[2]) - 0.5
+ var/list/current_bottom_vertex = list(vertex1[1], bottom - 0.5)
+ var/list/current_top_vertex = list(vertex1[1], bottom - 0.5)
+ for(var/i in bottom to top)
+ var/list/left_list = sight_blockers["[left]"]
+ var/isLeftBlocked = left_list?.Find(i) ? TRUE : FALSE
+ var/list/right_list = sight_blockers["[right]"]
+ var/isRightBlocked = right_list?.Find(i) ? TRUE : FALSE
+ if(isLeftBlocked == isRightBlocked)
+ if(current_bottom_vertex[2] != current_top_vertex[2])
+ lines_to_add += list(list(current_bottom_vertex, current_top_vertex))
+ current_bottom_vertex = list(vertex1[1], i + 0.5)
+ current_top_vertex = list(vertex1[1], i + 0.5)
+ if(current_bottom_vertex[2] != current_top_vertex[2])
+ lines_to_add += list(list(current_bottom_vertex, current_top_vertex))
+ else
+ //Horizontal line
+ //Requires a block above and below for every position from left to right
+ var/left = min(vertex1[1], vertex2[1]) + 0.5
+ var/right = max(vertex1[1], vertex2[1]) - 0.5
+ var/top = vertex1[2] + 0.5
+ var/bottom = vertex1[2] - 0.5
+ var/list/current_left_vertex = list(left - 0.5, vertex1[2])
+ var/list/current_right_vertex = list(left - 0.5, vertex1[2])
+ for(var/i in left to right)
+ var/list/check_list = sight_blockers["[i]"]
+ var/isAboveBlocked = check_list?.Find(top) ? TRUE : FALSE
+ var/isBelowBlocked = check_list?.Find(bottom) ? TRUE : FALSE
+ if(isAboveBlocked == isBelowBlocked)
+ if(current_left_vertex[1] != current_right_vertex[1])
+ lines_to_add += list(list(current_left_vertex, current_right_vertex))
+ current_left_vertex = list(i + 0.5, vertex1[2])
+ current_right_vertex = list(i + 0.5, vertex1[2])
+ if(current_left_vertex[1] != current_right_vertex[1])
+ lines_to_add += list(list(current_left_vertex, current_right_vertex))
+ . += lines_to_add
+
+/**
+ * Converts the corners into the 3 (or 2) valid points
+ * For example if a wall is top right of the source, the bottom left wall corner
+ * can be removed otherwise the wall itself will be in the shadow.
+ * Input: list(list(x1, y1), list(x2, y2))
+ * Output: list(list(list(x, y), list(x, y))) <-- 2 coordinates that form a line
+ */
+/atom/movable/lighting_mask/proc/get_corners_from_coords(list/coordgroup)
+ //Get the raw numbers
+ var/xlow = coordgroup[1][1]
+ var/ylow = coordgroup[1][2]
+ var/xhigh = coordgroup[2][1]
+ var/yhigh = coordgroup[2][2]
+
+ var/ourx = calculated_position_x
+ var/oury = calculated_position_y
+
+ //The source is above the point (Bottom Quad)
+ if(oury > yhigh)
+ //Bottom Right
+ if(ourx < xlow)
+ return list(
+ list(list(xlow, ylow), list(xhigh, ylow)),
+ list(list(xhigh, ylow), list(xhigh, yhigh)),
+ )
+ //Bottom Left
+ else if(ourx > xhigh)
+ return list(
+ list(list(xlow, yhigh), list(xlow, ylow)),
+ list(list(xlow, ylow), list(xhigh, ylow)),
+ )
+ //Bottom Middle
+ else
+ return list(
+ list(list(xlow, yhigh), list(xlow, ylow)),
+ list(list(xlow, ylow), list(xhigh, ylow)),
+ list(list(xhigh, ylow), list(xhigh, yhigh))
+ )
+ //The source is below the point (Top quad)
+ else if(oury < ylow)
+ //Top Right
+ if(ourx < xlow)
+ return list(
+ list(list(xlow, yhigh), list(xhigh, yhigh)),
+ list(list(xhigh, yhigh), list(xhigh, ylow)),
+ )
+ //Top Left
+ else if(ourx > xhigh)
+ return list(
+ list(list(xlow, ylow), list(xlow, yhigh)),
+ list(list(xlow, yhigh), list(xhigh, yhigh)),
+ )
+ //Top Middle
+ else
+ return list(
+ list(list(xlow, ylow), list(xlow, yhigh)),
+ list(list(xlow, yhigh), list(xhigh, yhigh)),
+ list(list(xhigh, yhigh), list(xhigh, ylow))
+ )
+ //the source is between the group Middle something
+ else
+ //Middle Right
+ if(ourx < xlow)
+ return list(
+ list(list(xlow, yhigh), list(xhigh, yhigh)),
+ list(list(xhigh, yhigh), list(xhigh, ylow)),
+ list(list(xhigh, ylow), list(xlow, ylow))
+ )
+ //Middle Left
+ else if(ourx > xhigh)
+ return list(
+ list(list(xhigh, ylow), list(xlow, ylow)),
+ list(list(xlow, ylow), list(xlow, yhigh)),
+ list(list(xlow, yhigh), list(xhigh, yhigh))
+ )
+ //Middle Middle (Why?????????)
+ else
+ return list(
+ list(list(xhigh, ylow), list(xlow, ylow)),
+ list(list(xlow, ylow), list(xlow, yhigh)),
+ list(list(xlow, yhigh), list(xhigh, yhigh)),
+ list(list(xlow, yhigh), list(xhigh, ylow))
+ )
+
+//Calculates the coordinates of the corner
+//Takes a list of blocks and calculates the bottom left corner and the top right corner.
+//Input: Group list(list(list(x,y), list(x,y)), list(list(x, y)))
+//Output: Coordinates list(list(left, bottom), list(right, top))
+/atom/movable/lighting_mask/proc/calculate_corners_in_group(list/group)
+ if(length(group) == 0)
+ CRASH("Calculate_corners_in_group called on a group of length 0. Critical error.")
+ if(length(group) == 1)
+ var/x = group[1][1]
+ var/y = group[1][2]
+ return list(
+ list(x - 0.5, y - 0.5),
+ list(x + 0.5, y + 0.5)
+ )
+ //Group is multiple length, find top left and bottom right
+ var/first = group[1]
+ var/second = group[2]
+ var/group_direction = NORTH
+ if(first[1] != second[1])
+ group_direction = EAST
+#ifdef SHADOW_DEBUG6
+ else if(first[2] != second[2])
+ message_admins("Major error, group is not 1xN or Nx1")
+#endif
+ var/lowest = INFINITY
+ var/highest = 0
+ for(var/vector in group)
+ var/value_to_comp = vector[1]
+ if(group_direction == NORTH)
+ value_to_comp = vector[2]
+ lowest = min(lowest, value_to_comp)
+ highest = max(highest, value_to_comp)
+ //done ez
+ if(group_direction == NORTH)
+ return list(
+ list(first[1] - 0.5, lowest - 0.5),
+ list(first[1] + 0.5, highest + 0.5)
+ )
+ else
+ return list(
+ list(lowest - 0.5, first[2] - 0.5),
+ list(highest + 0.5, first[2] + 0.5)
+ )
+
+///Groups things into vertical and horizontal lines.
+///Input: All atoms ungrouped list(atom1, atom2, atom3)
+///Output: List(List(Group), list(group2), ... , list(groupN))
+///Output: List(List(atom1, atom2), list(atom3, atom4...), ... , list(atom))
+/atom/movable/lighting_mask/proc/group_atoms(list/ungrouped_things)
+ . = list()
+ //Ungrouped things comes in as
+ // Key: X
+ // Value = list(y values)
+ //This makes sorting vertically easy, however sorting horizontally is harder
+ //While grouping elements vertically, we can put them into a new list with
+ // Key: Y
+ // Value = list(x values)
+ //to make it much easier.
+ var/list/horizontal_atoms = list()
+ //=================================================
+ //Vertical sorting (X locked)
+ for(var/x_key in ungrouped_things)
+ var/list/y_components = ungrouped_things[x_key]
+ var/pointer = y_components[1]
+ var/list/group = list(list(text2num(x_key), y_components[1]))
+ for(var/i in 2 to length(y_components))
+ var/next = y_components[i]
+ if(next != pointer + 1)
+ if(length(group) == 1)
+ //Add the element in group to horizontal
+ COORD_LIST_ADD(horizontal_atoms, pointer, text2num(x_key))
+ DEBUG_HIGHLIGHT(text2num(x_key), pointer, "#FFFF00")
+ else
+ //Add the group to the output
+ . += list(group)
+ group = list()
+ group += list(list(text2num(x_key), next))
+ DEBUG_HIGHLIGHT(text2num(x_key), next, "#FF0000")
+ pointer = next
+ if(length(group) == 1)
+ //Add the element in group to horizontal
+ COORD_LIST_ADD(horizontal_atoms, pointer, text2num(x_key))
+ DEBUG_HIGHLIGHT(text2num(x_key), pointer, "#FFFF00")
+ else
+ //Add the group to the output
+ . += list(group)
+ //=================================================
+ //Horizontal sorting (Y locked)
+ for(var/y_key in horizontal_atoms)
+ var/list/x_components = horizontal_atoms[y_key]
+ var/pointer = x_components[1]
+ var/list/group = list(list(x_components[1], text2num(y_key)))
+ for(var/i in 2 to length(x_components))
+ var/next = x_components[i]
+ if(next != pointer + 1)
+ . += list(group)
+ group = list()
+ group += list(list(next, text2num(y_key)))
+ DEBUG_HIGHLIGHT(next, text2num(y_key), "#00FF00")
+ pointer = next
+ . += list(group)
+
+///gets a line from a x and y, to the offset x and y of length radius
+/proc/extend_line_to_radius(delta_x, delta_y, radius, offset_x, offset_y)
+ if(abs(delta_x) < abs(delta_y))
+ //top or bottom
+ var/proportion = radius / abs(delta_y)
+ return list(delta_x * proportion + offset_x, delta_y * proportion + offset_y)
+ else
+ var/proportion = radius / abs(delta_x)
+ return list(delta_x * proportion + offset_x, delta_y * proportion + offset_y)
+
+#undef LIGHTING_SHADOW_TEX_SIZE
+#undef COORD_LIST_ADD
+#undef DEBUG_HIGHLIGHT
+#undef DO_SOMETHING_IF_DEBUGGING_SHADOWS
diff --git a/code/modules/lighting/lighting_static/static_lighting_area.dm b/code/modules/lighting/lighting_static/static_lighting_area.dm
new file mode 100644
index 000000000000..2e95c77e9ecd
--- /dev/null
+++ b/code/modules/lighting/lighting_static/static_lighting_area.dm
@@ -0,0 +1,12 @@
+/area
+ ///Whether this area allows static lighting and thus loads the lighting objects
+ var/static_lighting = TRUE
+
+//Non static lighting areas.
+//Any lighting area that wont support static lights.
+//These areas will NOT have corners generated.
+
+/area/space
+ static_lighting = FALSE
+ base_lighting_alpha = 255
+
diff --git a/code/modules/lighting/lighting_static/static_lighting_atom.dm b/code/modules/lighting/lighting_static/static_lighting_atom.dm
new file mode 100644
index 000000000000..0f7be52b351f
--- /dev/null
+++ b/code/modules/lighting/lighting_static/static_lighting_atom.dm
@@ -0,0 +1,25 @@
+
+/atom
+ ///The light source, datum. Dont fuck with this directly
+ var/tmp/datum/static_light_source/static_light
+ ///Static light sources currently attached to this atom, this includes ones owned by atoms inside this atom
+ var/tmp/list/static_light_sources
+
+///Pretty simple, just updates static lights on this atom
+/atom/proc/static_update_light()
+ set waitfor = FALSE
+ if (QDELETED(src))
+ return
+
+ if (!light_power || !light_range) // We won't emit light anyways, destroy the light source.
+ QDEL_NULL(static_light)
+ else
+ if(!ismovableatom(loc)) // We choose what atom should be the top atom of the light here.
+ . = src
+ else
+ . = loc
+
+ if(static_light) // Update the light or create it if it does not exist.
+ static_light.update(.)
+ else
+ static_light = new/datum/static_light_source(src, .)
diff --git a/code/modules/lighting/lighting_static/static_lighting_corner.dm b/code/modules/lighting/lighting_static/static_lighting_corner.dm
new file mode 100644
index 000000000000..4f026e05e864
--- /dev/null
+++ b/code/modules/lighting/lighting_static/static_lighting_corner.dm
@@ -0,0 +1,176 @@
+// Because we can control each corner of every lighting object.
+// And corners get shared between multiple turfs (unless you're on the corners of the map, then 1 corner doesn't).
+// For the record: these should never ever ever be deleted, even if the turf doesn't have dynamic lighting.
+
+/datum/static_lighting_corner
+ var/list/datum/static_light_source/affecting // Light sources affecting us.
+
+ var/x = 0
+ var/y = 0
+
+ var/turf/master_NE
+ var/turf/master_SE
+ var/turf/master_SW
+ var/turf/master_NW
+
+ var/lum_r = 0
+ var/lum_g = 0
+ var/lum_b = 0
+
+ //true color values, guaranteed to be between 0 and 1
+ var/cache_r = LIGHTING_SOFT_THRESHOLD
+ var/cache_g = LIGHTING_SOFT_THRESHOLD
+ var/cache_b = LIGHTING_SOFT_THRESHOLD
+
+ ///the maximum of lum_r, lum_g, and lum_b. if this is > 1 then the three cached color values are divided by this
+ var/largest_color_luminosity = 0
+
+ ///whether we are to be added to SSlighting's corners_queue list for an update
+ var/needs_update = FALSE
+
+/datum/static_lighting_corner/New(turf/new_turf, diagonal)
+ . = ..()
+ save_master(new_turf, turn(diagonal, 180))
+
+ var/vertical = diagonal & ~(diagonal - 1) // The horizontal directions (4 and 8) are bigger than the vertical ones (1 and 2), so we can reliably say the lsb is the horizontal direction.
+ var/horizontal = diagonal & ~vertical // Now that we know the horizontal one we can get the vertical one.
+
+ x = new_turf.x + (horizontal == EAST ? 0.5 : -0.5)
+ y = new_turf.y + (vertical == NORTH ? 0.5 : -0.5)
+
+ // My initial plan was to make this loop through a list of all the dirs (horizontal, vertical, diagonal).
+ // Issue being that the only way I could think of doing it was very messy, slow and honestly overengineered.
+ // So we'll have this hardcode instead.
+ var/turf/new_master_turf
+
+ // Diagonal one is easy.
+ new_master_turf = get_step(new_turf, diagonal)
+ if(new_master_turf) // In case we're on the map's border.
+ save_master(new_master_turf, diagonal)
+
+ // Now the horizontal one.
+ new_master_turf = get_step(new_turf, horizontal)
+ if(new_master_turf) // Ditto.
+ save_master(new_master_turf, ((new_master_turf.x > x) ? EAST : WEST) | ((new_master_turf.y > y) ? NORTH : SOUTH)) // Get the dir based on coordinates.
+
+ // And finally the vertical one.
+ new_master_turf = get_step(new_turf, vertical)
+ if (new_master_turf)
+ save_master(new_master_turf, ((new_master_turf.x > x) ? EAST : WEST) | ((new_master_turf.y > y) ? NORTH : SOUTH)) // Get the dir based on coordinates.
+
+/datum/static_lighting_corner/proc/save_master(turf/master, dir)
+ switch (dir)
+ if (NORTHEAST)
+ master_NE = master
+ master.lighting_corner_SW = src
+ if (SOUTHEAST)
+ master_SE = master
+ master.lighting_corner_NW = src
+ if (SOUTHWEST)
+ master_SW = master
+ master.lighting_corner_NE = src
+ if (NORTHWEST)
+ master_NW = master
+ master.lighting_corner_SE = src
+
+/datum/static_lighting_corner/proc/self_destruct_if_idle()
+ if (!LAZYLEN(affecting))
+ qdel(src, force = TRUE)
+
+/datum/static_lighting_corner/proc/vis_update()
+ for (var/datum/static_light_source/light_source as anything in affecting)
+ light_source.vis_update()
+
+/datum/static_lighting_corner/proc/full_update()
+ for (var/datum/static_light_source/light_source as anything in affecting)
+ light_source.recalc_corner(src)
+
+// God that was a mess, now to do the rest of the corner code! Hooray!
+/datum/static_lighting_corner/proc/update_lumcount(delta_r, delta_g, delta_b)
+
+ if(!(delta_r || delta_g || delta_b)) // 0 is falsey ok
+ return
+
+ lum_r += delta_r
+ lum_g += delta_g
+ lum_b += delta_b
+
+ if(!needs_update)
+ needs_update = TRUE
+ SSlighting.corners_queue += src
+
+/datum/static_lighting_corner/proc/update_objects()
+ // Cache these values a head of time so 4 individual lighting objects don't all calculate them individually.
+ var/lum_r = src.lum_r
+ var/lum_g = src.lum_g
+ var/lum_b = src.lum_b
+ var/largest_color_luminosity = max(lum_r, lum_g, lum_b) // Scale it so one of them is the strongest lum, if it is above 1.
+ . = 1 // factor
+ if (largest_color_luminosity > 1)
+ . = 1 / largest_color_luminosity
+
+ #if LIGHTING_SOFT_THRESHOLD != 0
+ else if (largest_color_luminosity < LIGHTING_SOFT_THRESHOLD)
+ . = 0 // 0 means soft lighting.
+
+ cache_r = round(lum_r * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
+ cache_g = round(lum_g * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
+ cache_b = round(lum_b * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
+ #else
+ cache_r = round(lum_r * ., LIGHTING_ROUND_VALUE)
+ cache_g = round(lum_g * ., LIGHTING_ROUND_VALUE)
+ cache_b = round(lum_b * ., LIGHTING_ROUND_VALUE)
+ #endif
+
+ src.largest_color_luminosity = round(largest_color_luminosity, LIGHTING_ROUND_VALUE)
+
+ var/datum/static_lighting_object/lighting_object = master_NE?.static_lighting_object
+ if (lighting_object && !lighting_object.needs_update)
+ lighting_object.needs_update = TRUE
+ SSlighting.objects_queue += lighting_object
+
+ lighting_object = master_SE?.static_lighting_object
+ if (lighting_object && !lighting_object.needs_update)
+ lighting_object.needs_update = TRUE
+ SSlighting.objects_queue += lighting_object
+
+ lighting_object = master_SW?.static_lighting_object
+ if (lighting_object && !lighting_object.needs_update)
+ lighting_object.needs_update = TRUE
+ SSlighting.objects_queue += lighting_object
+
+ lighting_object = master_NW?.static_lighting_object
+ if (lighting_object && !lighting_object.needs_update)
+ lighting_object.needs_update = TRUE
+ SSlighting.objects_queue += lighting_object
+
+ self_destruct_if_idle()
+
+
+/datum/static_lighting_corner/dummy/New()
+ return
+
+
+/datum/static_lighting_corner/Destroy(force)
+ if (!force)
+ return QDEL_HINT_LETMELIVE
+
+ for(var/datum/static_light_source/light_source as anything in affecting)
+ LAZYREMOVE(light_source.effect_str, src)
+ affecting = null
+
+ if(master_NE)
+ master_NE.lighting_corner_SW = null
+ master_NE.lighting_corners_initialised = FALSE
+ if(master_SE)
+ master_SE.lighting_corner_NW = null
+ master_SE.lighting_corners_initialised = FALSE
+ if(master_SW)
+ master_SW.lighting_corner_NE = null
+ master_SW.lighting_corners_initialised = FALSE
+ if(master_NW)
+ master_NW.lighting_corner_SE = null
+ master_NW.lighting_corners_initialised = FALSE
+ if(needs_update)
+ SSlighting.corners_queue -= src
+ return ..()
diff --git a/code/modules/lighting/lighting_static/static_lighting_object.dm b/code/modules/lighting/lighting_static/static_lighting_object.dm
new file mode 100644
index 000000000000..a3e6c5054bee
--- /dev/null
+++ b/code/modules/lighting/lighting_static/static_lighting_object.dm
@@ -0,0 +1,115 @@
+/datum/static_lighting_object
+ ///the underlay we are currently applying to our turf to apply light
+ var/mutable_appearance/current_underlay
+
+ ///whether we are already in the SSlighting.objects_queue list
+ var/needs_update = FALSE
+
+ ///the turf that our light is applied to
+ var/turf/affected_turf
+
+/datum/static_lighting_object/New(turf/source)
+ if(!isturf(source))
+ qdel(src, force=TRUE)
+ stack_trace("a lighting object was assigned to [source], a non turf! ")
+ return
+ ..()
+
+ current_underlay = mutable_appearance(LIGHTING_ICON, "transparent", source.z, LIGHTING_PLANE, 255, RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM)
+
+ affected_turf = source
+ if (affected_turf.static_lighting_object)
+ qdel(affected_turf.static_lighting_object, force = TRUE)
+ stack_trace("a lighting object was assigned to a turf that already had a lighting object!")
+
+ affected_turf.static_lighting_object = src
+ affected_turf.luminosity = 0
+
+ needs_update = TRUE
+ SSlighting.objects_queue += src
+
+/datum/static_lighting_object/Destroy(force)
+ if (!force)
+ return QDEL_HINT_LETMELIVE
+ SSlighting.objects_queue -= src
+ if (isturf(affected_turf))
+ affected_turf.static_lighting_object = null
+ affected_turf.luminosity = 1
+ affected_turf.underlays -= current_underlay
+ affected_turf = null
+ return ..()
+
+/datum/static_lighting_object/proc/update()
+
+ // To the future coder who sees this and thinks
+ // "Why didn't he just use a loop?"
+ // Well my man, it's because the loop performed like shit.
+ // And there's no way to improve it because
+ // without a loop you can make the list all at once which is the fastest you're gonna get.
+ // Oh it's also shorter line wise.
+ // Including with these comments.
+
+ var/static/datum/static_lighting_corner/dummy/dummy_lighting_corner = new
+
+ var/datum/static_lighting_corner/red_corner = affected_turf.lighting_corner_SW || dummy_lighting_corner
+ var/datum/static_lighting_corner/green_corner = affected_turf.lighting_corner_SE || dummy_lighting_corner
+ var/datum/static_lighting_corner/blue_corner = affected_turf.lighting_corner_NW || dummy_lighting_corner
+ var/datum/static_lighting_corner/alpha_corner = affected_turf.lighting_corner_NE || dummy_lighting_corner
+
+ var/max = max(red_corner.largest_color_luminosity, green_corner.largest_color_luminosity, blue_corner.largest_color_luminosity, alpha_corner.largest_color_luminosity)
+
+ var/rr = red_corner.cache_r
+ var/rg = red_corner.cache_g
+ var/rb = red_corner.cache_b
+
+ var/gr = green_corner.cache_r
+ var/gg = green_corner.cache_g
+ var/gb = green_corner.cache_b
+
+ var/br = blue_corner.cache_r
+ var/bg = blue_corner.cache_g
+ var/bb = blue_corner.cache_b
+
+ var/ar = alpha_corner.cache_r
+ var/ag = alpha_corner.cache_g
+ var/ab = alpha_corner.cache_b
+
+ #if LIGHTING_SOFT_THRESHOLD != 0
+ var/set_luminosity = max > LIGHTING_SOFT_THRESHOLD
+ #else
+ // Because of floating points�?, it won't even be a flat 0.
+ // This number is mostly arbitrary.
+ var/set_luminosity = max > 1e-6
+ #endif
+
+ if((rr & gr & br & ar) && (rg + gg + bg + ag + rb + gb + bb + ab == 8))
+ //anything that passes the first case is very likely to pass the second, and addition is a little faster in this case
+ affected_turf.underlays -= current_underlay
+ current_underlay.icon_state = "transparent"
+ current_underlay.color = null
+ affected_turf.underlays += current_underlay
+ else if(!set_luminosity)
+ affected_turf.underlays -= current_underlay
+ current_underlay.icon_state = "dark"
+ current_underlay.color = null
+ affected_turf.underlays += current_underlay
+ else
+ affected_turf.underlays -= current_underlay
+ current_underlay.icon_state = null
+ current_underlay.color = list(
+ rr, rg, rb, 00,
+ gr, gg, gb, 00,
+ br, bg, bb, 00,
+ ar, ag, ab, 00,
+ 00, 00, 00, 01
+ )
+
+ affected_turf.underlays += current_underlay
+
+ var/area/A = affected_turf.loc
+ //We are luminous
+ if(set_luminosity)
+ affected_turf.luminosity = set_luminosity
+ //We are not lit by static light OR dynamic light.
+ else if(!LAZYLEN(affected_turf.hybrid_lights_affecting) && !A.base_lighting_alpha)
+ affected_turf.luminosity = 0
diff --git a/code/modules/lighting/lighting_static/static_lighting_setup.dm b/code/modules/lighting/lighting_static/static_lighting_setup.dm
new file mode 100644
index 000000000000..6e1641585b91
--- /dev/null
+++ b/code/modules/lighting/lighting_static/static_lighting_setup.dm
@@ -0,0 +1,10 @@
+/proc/create_all_lighting_objects()
+ for(var/area/A in world)
+
+ if(!A.static_lighting)
+ continue
+
+ for(var/turf/T in A)
+ new/datum/static_lighting_object(T)
+ CHECK_TICK
+ CHECK_TICK
diff --git a/code/modules/lighting/lighting_static/static_lighting_source.dm b/code/modules/lighting/lighting_static/static_lighting_source.dm
new file mode 100644
index 000000000000..e650a432fc63
--- /dev/null
+++ b/code/modules/lighting/lighting_static/static_lighting_source.dm
@@ -0,0 +1,277 @@
+// This is where the fun begins.
+// These are the main datums that emit light.
+
+/datum/static_light_source
+ ///The atom we're emitting light from (for example a mob if we're from a flashlight that's being held).
+ var/atom/top_atom
+ ///The atom that we belong to.
+ var/atom/source_atom
+
+ ///The turf under the source atom.
+ var/turf/source_turf
+ ///The turf the top_atom appears to over.
+ var/turf/pixel_turf
+ ///Intensity of the emitter light.
+ var/light_power
+ /// The range of the emitted light.
+ var/light_range
+ /// The colour of the light, string, decomposed by parse_light_color()
+ var/light_color
+ // Variables for keeping track of the colour.
+ var/lum_r
+ var/lum_g
+ var/lum_b
+
+ // The lumcount values used to apply the light.
+ var/tmp/applied_lum_r
+ var/tmp/applied_lum_g
+ var/tmp/applied_lum_b
+
+ /// List used to store how much we're affecting corners.
+ var/list/datum/static_lighting_corner/effect_str
+
+ /// Whether we have applied our light yet or not.
+ var/applied = FALSE
+
+ /// whether we are to be added to SSlighting's static_sources_queue list for an update
+ var/needs_update = LIGHTING_NO_UPDATE
+
+// Thanks to Lohikar for flinging this tiny bit of code at me, increasing my brain cell count from 1 to 2 in the process.
+// This macro will only offset up to 1 tile, but anything with a greater offset is an outlier and probably should handle its own lighting offsets.
+// Anything pixelshifted 16px or more will be considered on the next tile.
+#define GET_APPROXIMATE_PIXEL_DIR(PX, PY) ((!(PX) ? 0 : ((PX >= 16 ? EAST : (PX <= -16 ? WEST : 0)))) | (!PY ? 0 : (PY >= 16 ? NORTH : (PY <= -16 ? SOUTH : 0))))
+#define UPDATE_APPROXIMATE_PIXEL_TURF var/_mask = GET_APPROXIMATE_PIXEL_DIR(top_atom.pixel_x, top_atom.pixel_y); pixel_turf = _mask ? (get_step(source_turf, _mask) || source_turf) : source_turf
+
+/datum/static_light_source/New(atom/owner, atom/top)
+ source_atom = owner // Set our new owner.
+ LAZYADD(source_atom.static_light_sources, src)
+ top_atom = top
+ if (top_atom != source_atom)
+ LAZYADD(top_atom.static_light_sources, src)
+
+ source_turf = top_atom
+ UPDATE_APPROXIMATE_PIXEL_TURF
+
+ light_power = source_atom.light_power
+ light_range = source_atom.light_range
+ light_color = source_atom.light_color
+
+ PARSE_LIGHT_COLOR(src)
+
+ update()
+
+/datum/static_light_source/Destroy(force)
+ remove_lum()
+ if (source_atom)
+ LAZYREMOVE(source_atom.static_light_sources, src)
+
+ if (top_atom)
+ LAZYREMOVE(top_atom.static_light_sources, src)
+
+ if (needs_update)
+ SSlighting.static_sources_queue -= src
+ return ..()
+
+#define EFFECT_UPDATE(level) \
+ if (needs_update == LIGHTING_NO_UPDATE) \
+ SSlighting.static_sources_queue += src; \
+ if (needs_update < level) \
+ needs_update = level; \
+
+
+/// This proc will cause the light source to update the top atom, and add itself to the update queue.
+/datum/static_light_source/proc/update(atom/new_top_atom)
+ // This top atom is different.
+ if (new_top_atom && new_top_atom != top_atom)
+ if(top_atom != source_atom && top_atom.static_light_sources) // Remove ourselves from the light sources of that top atom.
+ LAZYREMOVE(top_atom.static_light_sources, src)
+
+ top_atom = new_top_atom
+
+ if (top_atom != source_atom)
+ LAZYADD(top_atom.static_light_sources, src) // Add ourselves to the light sources of our new top atom.
+
+ EFFECT_UPDATE(LIGHTING_CHECK_UPDATE)
+
+/// Will force an update without checking if it's actually needed.
+/datum/static_light_source/proc/force_update()
+ EFFECT_UPDATE(LIGHTING_FORCE_UPDATE)
+
+/// Will cause the light source to recalculate turfs that were removed or added to visibility only.
+/datum/static_light_source/proc/vis_update()
+ EFFECT_UPDATE(LIGHTING_VIS_UPDATE)
+
+// Macro that applies light to a new corner.
+// It is a macro in the interest of speed, yet not having to copy paste it.
+// If you're wondering what's with the backslashes, the backslashes cause BYOND to not automatically end the line.
+// As such this all gets counted as a single line.
+// The braces and semicolons are there to be able to do this on a single line.
+
+//Original lighting falloff calculation. This looks the best out of the three. However, this is also the most expensive.
+//#define LUM_FALLOFF(C, T) (1 - CLAMP01(sqrt((C.x - T.x) ** 2 + (C.y - T.y) ** 2 + LIGHTING_HEIGHT) / max(1, light_range)))
+
+//Cubic lighting falloff. This has the *exact* same range as the original lighting falloff calculation, down to the exact decimal, but it looks a little unnatural due to the harsher falloff and how it's generally brighter across the board.
+//#define LUM_FALLOFF(C, T) (1 - CLAMP01((((C.x - T.x) * (C.x - T.x)) + ((C.y - T.y) * (C.y - T.y)) + LIGHTING_HEIGHT) / max(1, light_range*light_range)))
+
+//Linear lighting falloff. This resembles the original lighting falloff calculation the best, but results in lights having a slightly larger range, which is most noticable with large light sources. This also results in lights being diamond-shaped, fuck. This looks the darkest out of the three due to how lights are brighter closer to the source compared to the original falloff algorithm. This falloff method also does not at all take into account lighting height, as it acts as a flat reduction to light range with this method.
+//#define LUM_FALLOFF(C, T) (1 - CLAMP01(((abs(C.x - T.x) + abs(C.y - T.y))) / max(1, light_range+1)))
+
+//Linear lighting falloff but with an octagonal shape in place of a diamond shape. Lummox JR please add pointer support.
+#define GET_LUM_DIST(DISTX, DISTY) (DISTX + DISTY + abs(DISTX - DISTY)*0.4)
+#define LUM_FALLOFF(C, T) (1 - CLAMP01(max(GET_LUM_DIST(abs(C.x - T.x), abs(C.y - T.y)),LIGHTING_HEIGHT) / max(1, light_range+1)))
+
+#define APPLY_CORNER(C) \
+ . = LUM_FALLOFF(C, pixel_turf); \
+ . *= light_power; \
+ var/OLD = effect_str[C]; \
+ C.update_lumcount \
+ ( \
+ (. * lum_r) - (OLD * applied_lum_r), \
+ (. * lum_g) - (OLD * applied_lum_g), \
+ (. * lum_b) - (OLD * applied_lum_b) \
+ );
+
+#define REMOVE_CORNER(C) \
+ . = -effect_str[C]; \
+ C.update_lumcount \
+ ( \
+ . * applied_lum_r, \
+ . * applied_lum_g, \
+ . * applied_lum_b \
+ );
+
+/// This is the define used to calculate falloff.
+/datum/static_light_source/proc/remove_lum()
+ applied = FALSE
+ for(var/datum/static_lighting_corner/corner as anything in effect_str)
+ REMOVE_CORNER(corner)
+ LAZYREMOVE(corner.affecting, src)
+
+ effect_str = null
+
+/datum/static_light_source/proc/recalc_corner(datum/static_lighting_corner/corner)
+ LAZYINITLIST(effect_str)
+ if (effect_str[corner]) // Already have one.
+ REMOVE_CORNER(corner)
+ effect_str[corner] = 0
+
+ APPLY_CORNER(corner)
+ effect_str[corner] = .
+
+/datum/static_light_source/proc/update_corners()
+ var/update = FALSE
+ var/atom/source_atom = src.source_atom
+
+ if (QDELETED(source_atom))
+ qdel(src)
+ return
+
+ if (source_atom.light_power != light_power)
+ light_power = source_atom.light_power
+ update = TRUE
+
+ if (source_atom.light_range != light_range)
+ light_range = source_atom.light_range
+ update = TRUE
+
+ if (!top_atom)
+ top_atom = source_atom
+ update = TRUE
+
+ if (!light_range || !light_power)
+ qdel(src)
+ return
+
+ if (isturf(top_atom))
+ if (source_turf != top_atom)
+ source_turf = top_atom
+ UPDATE_APPROXIMATE_PIXEL_TURF
+ update = TRUE
+ else if (top_atom.loc != source_turf)
+ source_turf = top_atom.loc
+ UPDATE_APPROXIMATE_PIXEL_TURF
+ update = TRUE
+ else
+ var/pixel_loc = get_turf_pixel(top_atom)
+ if (pixel_loc != pixel_turf)
+ pixel_turf = pixel_loc
+ update = TRUE
+
+ if (!isturf(source_turf))
+ if (applied)
+ remove_lum()
+ return
+
+ if (light_range && light_power && !applied)
+ update = TRUE
+
+ if (source_atom.light_color != light_color)
+ light_color = source_atom.light_color
+ PARSE_LIGHT_COLOR(src)
+ update = TRUE
+
+ else if (applied_lum_r != lum_r || applied_lum_g != lum_g || applied_lum_b != lum_b)
+ update = TRUE
+
+ if (update)
+ needs_update = LIGHTING_CHECK_UPDATE
+ applied = TRUE
+ else if (needs_update == LIGHTING_CHECK_UPDATE)
+ return //nothing's changed
+
+ var/list/datum/static_lighting_corner/corners = list()
+ var/list/turf/turfs = list()
+ if (source_turf)
+ var/oldlum = source_turf.luminosity
+ source_turf.luminosity = CEILING(light_range, 1)
+ for(var/turf/T in view(CEILING(light_range, 1), source_turf))
+ if(!IS_OPAQUE_TURF(T))
+ if (!T.lighting_corners_initialised)
+ T.static_generate_missing_corners()
+ corners[T.lighting_corner_NE] = 0
+ corners[T.lighting_corner_SE] = 0
+ corners[T.lighting_corner_SW] = 0
+ corners[T.lighting_corner_NW] = 0
+ turfs += T
+ source_turf.luminosity = oldlum
+
+ var/list/datum/static_lighting_corner/new_corners = (corners - effect_str)
+ LAZYINITLIST(effect_str)
+ if (needs_update == LIGHTING_VIS_UPDATE)
+ for (var/datum/static_lighting_corner/corner as anything in new_corners)
+ APPLY_CORNER(corner)
+ if (. != 0)
+ LAZYADD(corner.affecting, src)
+ effect_str[corner] = .
+ else
+ for (var/datum/static_lighting_corner/corner as anything in new_corners)
+ APPLY_CORNER(corner)
+ if (. != 0)
+ LAZYADD(corner.affecting, src)
+ effect_str[corner] = .
+
+ for (var/datum/static_lighting_corner/corner as anything in corners - new_corners) // Existing corners
+ APPLY_CORNER(corner)
+ if (. != 0)
+ effect_str[corner] = .
+ else
+ LAZYREMOVE(corner.affecting, src)
+ effect_str -= corner
+
+ var/list/datum/static_lighting_corner/gone_corners = effect_str - corners
+ for (var/datum/static_lighting_corner/corner as anything in gone_corners)
+ REMOVE_CORNER(corner)
+ LAZYREMOVE(corner.affecting, src)
+ effect_str -= gone_corners
+
+ applied_lum_r = lum_r
+ applied_lum_g = lum_g
+ applied_lum_b = lum_b
+
+ UNSETEMPTY(effect_str)
+
+#undef EFFECT_UPDATE
+#undef LUM_FALLOFF
+#undef GET_LUM_DIST
+#undef REMOVE_CORNER
+#undef APPLY_CORNER
diff --git a/code/modules/lighting/lighting_static/static_lighting_turf.dm b/code/modules/lighting/lighting_static/static_lighting_turf.dm
new file mode 100644
index 000000000000..2fe918fa88bb
--- /dev/null
+++ b/code/modules/lighting/lighting_static/static_lighting_turf.dm
@@ -0,0 +1,61 @@
+/turf
+ var/tmp/lighting_corners_initialised = FALSE
+ var/tmp/datum/static_lighting_object/static_lighting_object
+
+ ///Lighting Corner datums.
+ var/tmp/datum/static_lighting_corner/lighting_corner_NE
+ var/tmp/datum/static_lighting_corner/lighting_corner_SE
+ var/tmp/datum/static_lighting_corner/lighting_corner_SW
+ var/tmp/datum/static_lighting_corner/lighting_corner_NW
+
+/turf/proc/static_lighting_clear_overlay()
+ if (static_lighting_object)
+ qdel(static_lighting_object, TRUE)
+
+/// Builds a lighting object for us, but only if our area is dynamic.
+/turf/proc/static_lighting_build_overlay(area/our_area = loc)
+ if(static_lighting_object)
+ qdel(static_lighting_object, force=TRUE) //Shitty fix for lighting objects persisting after death
+
+ new/datum/static_lighting_object(src)
+
+
+
+// Returns a boolean whether the turf is on soft lighting.
+// Soft lighting being the threshold at which point the overlay considers
+// itself as too dark to allow sight and see_in_dark becomes useful.
+// So basically if this returns true the tile is unlit black.
+/turf/proc/static_is_softly_lit()
+ if (!static_lighting_object)
+ return FALSE
+
+ return !(luminosity || dynamic_lumcount)
+
+/turf/proc/change_area(area/old_area, area/new_area)
+ if(SSlighting.initialized)
+ if (new_area.static_lighting != old_area.static_lighting)
+ if (new_area.static_lighting)
+ static_lighting_build_overlay(new_area)
+ else
+ static_lighting_clear_overlay()
+ //Inherit overlay of new area
+ if(old_area.lighting_effect)
+ overlays -= old_area.lighting_effect
+ if(new_area.lighting_effect)
+ overlays += new_area.lighting_effect
+
+/turf/proc/static_generate_missing_corners()
+ if (!lighting_corner_NE)
+ lighting_corner_NE = new/datum/static_lighting_corner(src, NORTH|EAST)
+
+ if (!lighting_corner_SE)
+ lighting_corner_SE = new/datum/static_lighting_corner(src, SOUTH|EAST)
+
+ if (!lighting_corner_SW)
+ lighting_corner_SW = new/datum/static_lighting_corner(src, SOUTH|WEST)
+
+ if (!lighting_corner_NW)
+ lighting_corner_NW = new/datum/static_lighting_corner(src, NORTH|WEST)
+
+ lighting_corners_initialised = TRUE
+
diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm
new file mode 100644
index 000000000000..c1fb288e9dd2
--- /dev/null
+++ b/code/modules/lighting/lighting_turf.dm
@@ -0,0 +1,94 @@
+///Estimates the light power based on the alpha of the light and the range.
+///Assumes a linear fallout at (0, alpha/255) to (range, 0)
+///Used for lightig mask lumcount calculations
+#define LIGHT_POWER_ESTIMATION(alpha, range, distance) max((alpha * (range - distance)) / (255 * range), 0)
+
+/turf
+ ///hybrid lights affecting this turf
+ var/tmp/list/atom/movable/lighting_mask/hybrid_lights_affecting
+
+/turf/Destroy(force)
+ if(hybrid_lights_affecting)
+ for(var/atom/movable/lighting_mask/mask as anything in hybrid_lights_affecting)
+ LAZYREMOVE(mask.affecting_turfs, src)
+ hybrid_lights_affecting.Cut()
+ return ..()
+
+/// Causes any affecting light sources to be queued for a visibility update, for example a door got opened.
+/turf/proc/reconsider_lights()
+ //Consider static lights
+ lighting_corner_NE?.vis_update()
+ lighting_corner_SE?.vis_update()
+ lighting_corner_SW?.vis_update()
+ lighting_corner_NW?.vis_update()
+
+ //consider dynamic lights
+ for(var/atom/movable/lighting_mask/mask as anything in hybrid_lights_affecting)
+ mask.queue_mask_update()
+
+// Used to get a scaled lumcount.
+/turf/proc/get_lumcount(minlum = 0, maxlum = 1)
+ var/totallums = 0
+ if (static_lighting_object)
+ var/datum/static_lighting_corner/L
+ L = lighting_corner_NE
+ if (L)
+ totallums += L.lum_r + L.lum_b + L.lum_g
+ L = lighting_corner_SE
+ if (L)
+ totallums += L.lum_r + L.lum_b + L.lum_g
+ L = lighting_corner_SW
+ if (L)
+ totallums += L.lum_r + L.lum_b + L.lum_g
+ L = lighting_corner_NW
+ if (L)
+ totallums += L.lum_r + L.lum_b + L.lum_g
+
+ totallums /= 12 // 4 corners, each with 3 channels, get the average.
+
+ totallums = (totallums - minlum) / (maxlum - minlum)
+
+ totallums = CLAMP01(totallums)
+ else
+ totallums = 1
+
+ for(var/atom/movable/lighting_mask/mask as anything in hybrid_lights_affecting)
+ if(mask.blend_mode == BLEND_ADD)
+ totallums += LIGHT_POWER_ESTIMATION(mask.alpha, mask.radius, get_dist(src, get_turf(mask.attached_atom)))
+ else
+ totallums -= LIGHT_POWER_ESTIMATION(mask.alpha, mask.radius, get_dist(src, get_turf(mask.attached_atom)))
+ return clamp(totallums, 0.0, 1.0)
+
+///Proc to add movable sources of opacity on the turf and let it handle lighting code.
+/turf/proc/add_opacity_source(atom/movable/new_source)
+ LAZYADD(opacity_sources, new_source)
+ if(opacity)
+ return
+ recalculate_directional_opacity()
+
+
+///Proc to remove movable sources of opacity on the turf and let it handle lighting code.
+/turf/proc/remove_opacity_source(atom/movable/old_source)
+ LAZYREMOVE(opacity_sources, old_source)
+ if(opacity) //Still opaque, no need to worry on updating.
+ return
+ recalculate_directional_opacity()
+
+
+///Calculate on which directions this turfs block view.
+/turf/proc/recalculate_directional_opacity()
+ . = directional_opacity
+ if(opacity)
+ directional_opacity = ALL_CARDINALS
+ if(. != directional_opacity)
+ reconsider_lights()
+ return
+ directional_opacity = NONE
+ for(var/atom/movable/opacity_source as anything in opacity_sources)
+ if(opacity_source.flags_atom & ON_BORDER)
+ directional_opacity |= opacity_source.dir
+ else //If fulltile and opaque, then the whole tile blocks view, no need to continue checking.
+ directional_opacity = ALL_CARDINALS
+ break
+ if(. != directional_opacity && (. == ALL_CARDINALS || directional_opacity == ALL_CARDINALS))
+ reconsider_lights() //The lighting system only cares whether the tile is fully concealed from all directions or not.
diff --git a/code/modules/mob/camera/imaginary_friend.dm b/code/modules/mob/camera/imaginary_friend.dm
index a78de70a7e15..3d6d5d5a0aa2 100644
--- a/code/modules/mob/camera/imaginary_friend.dm
+++ b/code/modules/mob/camera/imaginary_friend.dm
@@ -168,10 +168,10 @@
hud = huds[MOB_HUD_FACTION_CLF]
if(hud_choice in current_huds)
- hud.remove_hud_from(src)
+ hud.remove_hud_from(src, src)
current_huds -= hud_choice
else
- hud.add_hud_to(src)
+ hud.add_hud_to(src, src)
current_huds += hud_choice
/mob/camera/imaginary_friend/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language, ignore_spam = FALSE, forced)
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index c134f5a0cd13..0d41203ae1f9 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -85,6 +85,7 @@
life_kills_total = body.life_kills_total //kills also copy over
appearance = body.appearance
+ underlays.Cut()
base_transform = matrix(body.base_transform)
body.alter_ghost(src)
apply_transform(matrix())
@@ -269,28 +270,28 @@
switch(i)
if("Medical HUD")
H = huds[MOB_HUD_MEDICAL_OBSERVER]
- H.add_hud_to(src)
+ H.add_hud_to(src, src)
if("Security HUD")
H = huds[MOB_HUD_SECURITY_ADVANCED]
- H.add_hud_to(src)
+ H.add_hud_to(src, src)
if("Squad HUD")
H = huds[MOB_HUD_FACTION_OBSERVER]
- H.add_hud_to(src)
+ H.add_hud_to(src, src)
if("Xeno Status HUD")
H = huds[MOB_HUD_XENO_STATUS]
- H.add_hud_to(src)
+ H.add_hud_to(src, src)
if("Faction UPP HUD")
H = huds[MOB_HUD_FACTION_UPP]
- H.add_hud_to(src)
+ H.add_hud_to(src, src)
if("Faction Wey-Yu HUD")
H = huds[MOB_HUD_FACTION_WY]
- H.add_hud_to(src)
+ H.add_hud_to(src, src)
if("Faction TWE HUD")
H = huds[MOB_HUD_FACTION_TWE]
- H.add_hud_to(src)
+ H.add_hud_to(src, src)
if("Faction CLF HUD")
H = huds[MOB_HUD_FACTION_CLF]
- H.add_hud_to(src)
+ H.add_hud_to(src, src)
see_invisible = INVISIBILITY_OBSERVER
@@ -560,7 +561,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/mob/living/carbon/human/original_human = mind.original
- if(!original_human.check_tod() || !original_human.is_revivable() || !can_reenter_corpse)
+ if((original_human.stat == DEAD && !original_human.check_tod() || !original_human.is_revivable()) || !can_reenter_corpse)
view_health_scan(target)
return
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index a6062276bd8e..ab3ce823c68e 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -12,8 +12,9 @@
if(stat != DEAD && bodytemperature >= 170) //Dead or cryosleep people do not pump the blood.
//Blood regeneration if there is some space
- if(blood_volume < max_blood)
+ if(blood_volume < max_blood && nutrition >= 1)
blood_volume += 0.1 // regenerate blood VERY slowly
+ nutrition -= 0.25
else if(blood_volume > max_blood)
blood_volume -= 0.1 // The reverse in case we've gotten too much blood in our body
if(blood_volume > limit_blood)
@@ -43,12 +44,6 @@
if(oxyloss < maximum_oxyloss)
oxyloss += round(max(additional_oxyloss, 0))
- //Bloodloss effects on nutrition
- if(nutrition >= 300)
- nutrition -= 10
- else if(nutrition >= 200)
- nutrition -= 3
-
switch(b_volume)
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
if(prob(1))
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index aa0cbba74a5a..6e99ca1e5a15 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -512,25 +512,30 @@
//Helper procedure. Called by /mob/living/carbon/human/get_examine_text() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records.
-/proc/hasHUD(mob/M, hudtype)
- if(istype(M, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = M
- if (issynth(H))
+/proc/hasHUD(mob/passed_mob, hudtype)
+ if(istype(passed_mob, /mob/living/carbon/human))
+ var/mob/living/carbon/human/passed_human = passed_mob
+ if (issynth(passed_human))
return 1
switch(hudtype)
if("security")
- //only MPs can use the security HUD glasses's functionalities
- if(skillcheck(H, SKILL_POLICE, SKILL_POLICE_SKILLED))
- return istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud)
+ if(skillcheck(passed_human, SKILL_POLICE, SKILL_POLICE_SKILLED))
+ var/datum/mob_hud/sec_hud = huds[MOB_HUD_SECURITY_ADVANCED]
+ if(locate(passed_mob) in sec_hud.hudusers)
+ return TRUE
if("medical")
- if(skillcheck(H, SKILL_MEDICAL, SKILL_MEDICAL_MEDIC))
- return istype(H.glasses, /obj/item/clothing/glasses/hud/health)
+ if(skillcheck(passed_human, SKILL_MEDICAL, SKILL_MEDICAL_MEDIC))
+ var/datum/mob_hud/med_hud = huds[MOB_HUD_MEDICAL_ADVANCED]
+ if(locate(passed_mob) in med_hud.hudusers)
+ return TRUE
if("squadleader")
- return H.mind && H.assigned_squad && H.assigned_squad.squad_leader == H && H.get_type_in_ears(/obj/item/device/radio/headset/almayer/marine)
+ var/datum/mob_hud/faction_hud = huds[MOB_HUD_FACTION_USCM]
+ if(passed_human.mind && passed_human.assigned_squad && passed_human.assigned_squad.squad_leader == passed_human && locate(passed_mob) in faction_hud.hudusers)
+ return TRUE
else
return 0
- else if(isrobot(M))
- var/mob/living/silicon/robot/R = M
+ else if(isrobot(passed_mob))
+ var/mob/living/silicon/robot/R = passed_mob
switch(hudtype)
if("security")
return istype(R.module_state_1, /obj/item/robot/sight/hud/sec) || istype(R.module_state_2, /obj/item/robot/sight/hud/sec) || istype(R.module_state_3, /obj/item/robot/sight/hud/sec)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 0d67e7cafd74..c9092ed479b9 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1388,12 +1388,15 @@
sight &= ~BLIND // Never have blind on by default
lighting_alpha = default_lighting_alpha
- sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS)
+ sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS|SEE_BLACKNESS)
see_in_dark = species.darksight
sight |= species.flags_sight
if(glasses)
process_glasses(glasses)
+ if(!(sight & SEE_TURFS) && !(sight & SEE_MOBS) && !(sight & SEE_OBJS))
+ sight |= SEE_BLACKNESS
+
SEND_SIGNAL(src, COMSIG_HUMAN_POST_UPDATE_SIGHT)
sync_lighting_plane_alpha()
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 989ee52fa63c..7c7ad7a0166b 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -1,4 +1,5 @@
/mob/living/carbon/human
+ light_system = MOVABLE_LIGHT
//Hair color and style
var/r_hair = 0
var/g_hair = 0
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index e6a0db99637d..7f36df8ceae2 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -268,15 +268,14 @@
var/goes_out = 0
if(armor)
if(istype(wear_suit, /obj/item/clothing/suit/storage/marine))
- var/obj/item/clothing/suit/storage/marine/S = wear_suit
- if(S.turn_off_light(src))
+ if(wear_suit.turn_light(src, toggle_on = FALSE))
light_off++
for(var/obj/item/clothing/head/helmet/marine/H in contents)
for(var/obj/item/attachable/flashlight/FL in H.pockets)
if(FL.activate_attachment(H, src, TRUE))
light_off++
for(var/obj/item/clothing/head/hardhat/headlamp in contents)
- if(headlamp.turn_off_light(src))
+ if(headlamp.turn_light(src, toggle_on = FALSE))
light_off++
if(guns)
for(var/obj/item/weapon/gun/G in contents)
diff --git a/code/modules/mob/living/carbon/human/powers/human_powers.dm b/code/modules/mob/living/carbon/human/powers/human_powers.dm
index 1c8c011f7c71..10b13225b314 100644
--- a/code/modules/mob/living/carbon/human/powers/human_powers.dm
+++ b/code/modules/mob/living/carbon/human/powers/human_powers.dm
@@ -240,9 +240,9 @@
if(synthetic_HUD_toggled[chosen_HUD])
synthetic_HUD_toggled[chosen_HUD] = FALSE
- H.remove_hud_from(src)
+ H.remove_hud_from(src, src)
to_chat(src, SPAN_INFO("[hud_choice] Disabled"))
else
synthetic_HUD_toggled[chosen_HUD] = TRUE
- H.add_hud_to(src)
+ H.add_hud_to(src, src)
to_chat(src, SPAN_INFO("[hud_choice] Enabled"))
diff --git a/code/modules/mob/living/carbon/human/species/zombie.dm b/code/modules/mob/living/carbon/human/species/zombie.dm
index 07fe8f5e1255..5fa928a67f36 100644
--- a/code/modules/mob/living/carbon/human/species/zombie.dm
+++ b/code/modules/mob/living/carbon/human/species/zombie.dm
@@ -68,7 +68,7 @@
D.stage = 5
var/datum/mob_hud/Hu = huds[MOB_HUD_MEDICAL_OBSERVER]
- Hu.add_hud_to(zombie)
+ Hu.add_hud_to(zombie, zombie)
return ..()
@@ -77,7 +77,7 @@
..()
remove_from_revive(zombie)
var/datum/mob_hud/Hu = huds[MOB_HUD_MEDICAL_OBSERVER]
- Hu.remove_hud_from(zombie)
+ Hu.remove_hud_from(zombie, zombie)
/datum/species/zombie/handle_unique_behavior(mob/living/carbon/human/zombie)
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 6ee249a6333e..88887126b1c1 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -701,17 +701,22 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate,
/mob/living/carbon/human/update_fire()
remove_overlay(FIRE_LAYER)
if(!on_fire)
+ set_light_on(FALSE)
return
var/image/I
switch(fire_stacks)
if(1 to 14)
I = image("icon"='icons/mob/humans/onmob/OnFire.dmi', "icon_state"="Standing_weak", "layer"= -FIRE_LAYER)
+ set_light_range(2)
if(15 to INFINITY)
I = image("icon"='icons/mob/humans/onmob/OnFire.dmi', "icon_state"="Standing_medium", "layer"= -FIRE_LAYER)
+ set_light_range(3)
else
return
I.appearance_flags |= RESET_COLOR|RESET_ALPHA
I.color = fire_reagent.burncolor
+ set_light_color(fire_reagent.burncolor)
+ set_light_on(TRUE)
overlays_standing[FIRE_LAYER] = I
apply_overlay(FIRE_LAYER)
diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm
index 6365d4247476..3fba527fb0d7 100644
--- a/code/modules/mob/living/carbon/human/whisper.dm
+++ b/code/modules/mob/living/carbon/human/whisper.dm
@@ -95,7 +95,7 @@
//now mobs
var/speech_bubble_test = say_test(message)
- var/image/speech_bubble = image('icons/mob/hud/talk.dmi',src,"h[speech_bubble_test]")
+ var/image/speech_bubble = image('icons/mob/effects/talk.dmi',src,"[bubble_icon][speech_bubble_test]")
speech_bubble.appearance_flags = NO_CLIENT_COLOR|KEEP_APART|RESET_COLOR
var/not_dead_speaker = (stat != DEAD)
diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
index dc8e693c7038..5c1210f5c845 100644
--- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
@@ -52,6 +52,7 @@
icon_size = 48
black_market_value = KILL_MENDOZA
dead_black_market_value = 50
+ light_system = MOVABLE_LIGHT
var/obj/item/clothing/suit/wear_suit = null
var/obj/item/clothing/head/head = null
var/obj/item/r_store = null
@@ -755,6 +756,9 @@
/mob/living/carbon/xenomorph/start_pulling(atom/movable/AM, lunge, no_msg)
+ if(next_move >= world.time)
+ return FALSE
+
if(SEND_SIGNAL(AM, COMSIG_MOVABLE_XENO_START_PULLING, src) & COMPONENT_ALLOW_PULL)
return do_pull(AM, lunge, no_msg)
@@ -810,7 +814,7 @@
//and display them
add_to_all_mob_huds()
var/datum/mob_hud/MH = huds[MOB_HUD_XENO_INFECTION]
- MH.add_hud_to(src)
+ MH.add_hud_to(src, src)
/mob/living/carbon/xenomorph/check_improved_pointing()
@@ -1070,6 +1074,7 @@
. = ..()
if (.)
UnregisterSignal(src, COMSIG_XENO_PRE_HEAL)
+ handle_luminosity()
/mob/living/carbon/xenomorph/proc/cancel_heal()
SIGNAL_HANDLER
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/runner/runner_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/runner/runner_powers.dm
index 64e4b73cfbd2..6835fb724294 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/runner/runner_powers.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/runner/runner_powers.dm
@@ -183,7 +183,8 @@
to_chat(X, SPAN_XENOWARNING("Your stomach starts turning and twisting, getting ready to compress the built up acid."))
X.color = "#22FF22"
- X.SetLuminosity(3)
+ X.set_light_color("#22FF22")
+ X.set_light_range(3)
BD.caboom_trigger = TRUE
BD.caboom_left = BD.caboom_timer
@@ -204,7 +205,7 @@
behavior.caboom_trigger = FALSE
xeno.color = null
- xeno.SetLuminosity(0)
+ xeno.set_light_range(0)
behavior.modify_acid(-behavior.max_acid / 4)
// Done this way rather than setting to 0 in case something else slowed us
diff --git a/code/modules/mob/living/carbon/xenomorph/attack_alien.dm b/code/modules/mob/living/carbon/xenomorph/attack_alien.dm
index 8e64afa3f733..25f6108c14f6 100644
--- a/code/modules/mob/living/carbon/xenomorph/attack_alien.dm
+++ b/code/modules/mob/living/carbon/xenomorph/attack_alien.dm
@@ -851,7 +851,7 @@
playsound(src, "glassbreak", 70, 1)
damaged = TRUE
if(is_lit)
- SetLuminosity(0)
+ set_light(0)
update_icon()
else
playsound(loc, 'sound/effects/Glasshit.ogg', 25, 1)
diff --git a/code/modules/mob/living/carbon/xenomorph/death.dm b/code/modules/mob/living/carbon/xenomorph/death.dm
index 7fa8fc002826..d81413b68651 100644
--- a/code/modules/mob/living/carbon/xenomorph/death.dm
+++ b/code/modules/mob/living/carbon/xenomorph/death.dm
@@ -14,7 +14,7 @@
if(SSticker?.mode?.hardcore)
ghostize()
- SetLuminosity(0)
+ set_light_range(0)
if(pulledby)
pulledby.stop_pulling()
diff --git a/code/modules/mob/living/carbon/xenomorph/life.dm b/code/modules/mob/living/carbon/xenomorph/life.dm
index 6f9a667642e3..0542594f1ab6 100644
--- a/code/modules/mob/living/carbon/xenomorph/life.dm
+++ b/code/modules/mob/living/carbon/xenomorph/life.dm
@@ -544,7 +544,11 @@ Make sure their actual health updates immediately.*/
new_luminosity += caste.caste_luminosity
if(on_fire)
new_luminosity += min(fire_stacks, 5)
- SetLuminosity(new_luminosity) // light up xenos
+ set_light_range(new_luminosity) // light up xenos
+ if(new_luminosity)
+ set_light_on(TRUE)
+ else
+ set_light_on(FALSE)
/mob/living/carbon/xenomorph/handle_stunned()
if(stunned)
diff --git a/code/modules/mob/living/carbon/xenomorph/xeno_verbs.dm b/code/modules/mob/living/carbon/xenomorph/xeno_verbs.dm
index 583d26de3ee5..94218b224e2d 100644
--- a/code/modules/mob/living/carbon/xenomorph/xeno_verbs.dm
+++ b/code/modules/mob/living/carbon/xenomorph/xeno_verbs.dm
@@ -83,9 +83,9 @@
var/datum/mob_hud/H = huds[MOB_HUD_XENO_STATUS]
if (xeno_mobhud)
- H.remove_hud_from(usr)
+ H.remove_hud_from(usr, usr)
else
- H.add_hud_to(usr)
+ H.add_hud_to(usr, usr)
xeno_mobhud = !xeno_mobhud
@@ -96,9 +96,9 @@
var/datum/mob_hud/H = huds[MOB_HUD_XENO_HOSTILE]
if (xeno_hostile_hud)
- H.remove_hud_from(usr)
+ H.remove_hud_from(usr, usr)
else
- H.add_hud_to(usr)
+ H.add_hud_to(usr, usr)
xeno_hostile_hud = !xeno_hostile_hud
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index d74003cde331..fa33af97275e 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -148,7 +148,6 @@
on_fire = FALSE
fire_stacks = 0
update_fire()
- SetLuminosity(0)
return TRUE
return FALSE
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 49dc25bd57ea..18d6ece8e238 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -355,13 +355,13 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/reset_view(atom/A)
if(camera)
- camera.SetLuminosity(0)
+ camera.set_light(0)
if(istype(A,/obj/structure/machinery/camera))
camera = A
..()
if(istype(A,/obj/structure/machinery/camera))
- if(camera_light_on) A.SetLuminosity(AI_CAMERA_LUMINOSITY)
- else A.SetLuminosity(0)
+ if(camera_light_on) A.set_light(AI_CAMERA_LUMINOSITY)
+ else A.set_light(0)
/mob/living/silicon/ai/proc/switchCamera(obj/structure/machinery/camera/C)
@@ -539,7 +539,7 @@ var/list/ai_verbs_default = list(
to_chat(src, "Camera lights [camera_light_on ? "activated" : "deactivated"].")
if(!camera_light_on)
if(camera)
- camera.SetLuminosity(0)
+ camera.set_light(0)
camera = null
else
lightNearbyCamera()
@@ -554,20 +554,20 @@ var/list/ai_verbs_default = list(
if(src.camera)
var/obj/structure/machinery/camera/camera = near_range_camera(src.eyeobj)
if(camera && src.camera != camera)
- src.camera.SetLuminosity(0)
+ src.camera.set_light(0)
if(!camera.light_disabled)
src.camera = camera
- src.camera.SetLuminosity(AI_CAMERA_LUMINOSITY)
+ src.camera.set_light(AI_CAMERA_LUMINOSITY)
else
src.camera = null
else if(isnull(camera))
- src.camera.SetLuminosity(0)
+ src.camera.set_light(0)
src.camera = null
else
var/obj/structure/machinery/camera/camera = near_range_camera(src.eyeobj)
if(camera && !camera.light_disabled)
src.camera = camera
- src.camera.SetLuminosity(AI_CAMERA_LUMINOSITY)
+ src.camera.set_light(AI_CAMERA_LUMINOSITY)
camera_light_on = world.timeofday + 1 * 20 // Update the light every 2 seconds.
diff --git a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm
index 162bc4acc45e..1e1cef2b7a8e 100644
--- a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm
@@ -29,7 +29,7 @@
. = ..()
// STRUCTURES
-/obj/structure/Destroy()
+/obj/structure/Destroy(force)
if(z && SSatoms.initialized != INITIALIZATION_INSSATOMS)
cameranet.updateVisibility(src)
. = ..()
@@ -97,7 +97,7 @@
if(can_use())
cameranet.addCamera(src)
else
- SetLuminosity(0)
+ set_light(0)
cameranet.removeCamera(src)
/obj/structure/machinery/camera/Initialize()
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index 070ec202803e..5b190143f5bc 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -47,7 +47,7 @@
forceMove(T.loc)
if (istype(loc, /area))
//stage = 4
- if (!loc.master.power_equip && !istype(src.loc,/obj/item))
+ if (!loc.power_equip && !istype(src.loc,/obj/item))
//stage = 5
blind = 1
@@ -95,7 +95,7 @@
src.see_in_dark = 0
src.see_invisible = SEE_INVISIBLE_LIVING
- if (((!loc.master.power_equip) || istype(T, /turf/open/space)) && !istype(src.loc,/obj/item))
+ if (((!loc.power_equip) || istype(T, /turf/open/space)) && !istype(src.loc,/obj/item))
if (src:aiRestorePowerRoutine==0)
src:aiRestorePowerRoutine = 1
@@ -106,7 +106,7 @@
spawn(20)
to_chat(src, "Backup battery online. Scanners, camera, and radio interface offline. Beginning fault-detection.")
sleep(50)
- if (loc.master.power_equip)
+ if (loc.power_equip)
if (!istype(T, /turf/open/space))
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
src:aiRestorePowerRoutine = 0
@@ -133,18 +133,17 @@
var/PRP //like ERP with the code, at least this stuff is no more 4x sametext
for (PRP=1, PRP<=4, PRP++)
var/area/AIarea = get_area(src)
- for(var/area/A in AIarea.master.related)
- for (var/obj/structure/machinery/power/apc/APC in A)
- if (!(APC.stat & BROKEN))
- theAPC = APC
- break
+ for (var/obj/structure/machinery/power/apc/APC in AIarea)
+ if (!(APC.stat & BROKEN))
+ theAPC = APC
+ break
if (!theAPC)
switch(PRP)
if (1) to_chat(src, "Unable to locate APC!")
else to_chat(src, "Lost connection with the APC!")
src:aiRestorePowerRoutine = 2
return
- if (loc.master.power_equip)
+ if (loc.power_equip)
if (!istype(T, /turf/open/space))
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
src:aiRestorePowerRoutine = 0
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index e623b499a686..21ddaf76b33c 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -56,7 +56,7 @@
src.has_power = 0
if(lights_on) // Light is on but there is no power!
lights_on = 0
- SetLuminosity(0)
+ set_light(0)
/mob/living/silicon/robot/handle_regular_status_updates(regular_update = TRUE)
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 7edcb7d4fede..6f68f94bcb5d 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -337,9 +337,9 @@ var/list/robot_verbs_default = list(
lights_on = !lights_on
to_chat(usr, "You [lights_on ? "enable" : "disable"] your integrated light.")
if(lights_on)
- SetLuminosity(integrated_light_power) // 1.5x luminosity of flashlight
+ set_light(integrated_light_power) // 1.5x luminosity of flashlight
else
- SetLuminosity(0)
+ set_light(0)
/mob/living/silicon/robot/verb/self_diagnosis_verb()
set category = "Robot Commands"
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 2910da65cb79..b0f08acc33fa 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -160,11 +160,11 @@
if(HUD_toggled[HUD_nbr])
HUD_toggled[HUD_nbr] = 0
- H.remove_hud_from(src)
+ H.remove_hud_from(src, src)
to_chat(src, SPAN_NOTICE(" [hud_choice] Disabled"))
else
HUD_toggled[HUD_nbr] = 1
- H.add_hud_to(src)
+ H.add_hud_to(src, src)
to_chat(src, SPAN_NOTICE(" [hud_choice] Enabled"))
/mob/living/silicon/verb/pose()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 06df71427e4f..4dfa0644aa21 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -327,7 +327,6 @@
if (exterior_lighting)
exterior_lighting.alpha = min(GLOB.minimum_exterior_lighting_alpha, lighting_alpha)
-
//puts the item "W" into an appropriate slot in a human's inventory
//returns 0 if it cannot, 1 if successful
/mob/proc/equip_to_appropriate_slot(obj/item/W, ignore_delay = 1, list/slot_equipment_priority = DEFAULT_SLOT_PRIORITY)
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 995bf232777f..461a5e018ce5 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -529,6 +529,7 @@ var/global/list/limb_types_by_name = list(
/mob/proc/get_paygrade()
return
+
/proc/notify_ghosts(message, ghost_sound = null, enter_link = null, enter_text = null, atom/source = null, mutable_appearance/alert_overlay = null, action = NOTIFY_JUMP, flashwindow = TRUE, ignore_mapload = TRUE, ignore_key, header = null, notify_volume = 100, extra_large = FALSE) //Easy notification of ghosts.
if(ignore_mapload && SSatoms.initialized != INITIALIZATION_INNEW_REGULAR) //don't notify for objects created during a map load
return
@@ -586,3 +587,10 @@ var/global/list/limb_types_by_name = list(
alert_overlay.plane = FLOAT_PLANE
screen_alert.overlays += alert_overlay
+
+/mob/proc/reset_lighting_alpha()
+ SIGNAL_HANDLER
+
+ lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
+ sync_lighting_plane_alpha()
+
diff --git a/code/modules/movement/movement.dm b/code/modules/movement/movement.dm
index ee2a184518a0..da0c76cba9d5 100644
--- a/code/modules/movement/movement.dm
+++ b/code/modules/movement/movement.dm
@@ -92,12 +92,12 @@
/atom/movable/proc/Moved(atom/oldloc, direction, Forced = FALSE)
SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, oldloc, direction, Forced)
- if (isturf(loc))
- if (opacity)
- oldloc.UpdateAffectingLights()
- else
- if (light)
- light.changed()
+ for(var/datum/dynamic_light_source/light as anything in hybrid_light_sources)
+ light.source_atom.update_light()
+ if(!isturf(loc))
+ light.find_containing_atom()
+ for(var/datum/static_light_source/L as anything in static_light_sources) // Cycle through the light sources on this atom and tell them to update.
+ L.source_atom.static_update_light()
return TRUE
/atom/movable/proc/forceMove(atom/destination)
diff --git a/code/modules/nightmare/nmtasks/mapscheduler.dm b/code/modules/nightmare/nmtasks/mapscheduler.dm
index 2a8279e13608..34ceecafb876 100644
--- a/code/modules/nightmare/nmtasks/mapscheduler.dm
+++ b/code/modules/nightmare/nmtasks/mapscheduler.dm
@@ -28,8 +28,6 @@
for(var/turf/T as anything in tainted)
var/area/A = T.loc
- if(!A?.lighting_use_dynamic)
+ if(!A?.area_has_base_lighting)
continue
- T.cached_lumcount = -1 // Invalidate lumcount to force update here
- T.lighting_changed = TRUE
- SSlighting.changed_turfs += T
+ T.update_light()
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index e7a160095705..ef4c5cc292ce 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -148,7 +148,7 @@ GLOBAL_LIST_INIT(apc_wire_descriptions, list(
if(building == 0)
init()
else
- area = loc.loc:master
+ area = get_area(src)
opened = APC_COVER_OPEN
operating = 0
name = "\improper [area.name] APC"
@@ -1314,11 +1314,10 @@ GLOBAL_LIST_INIT(apc_wire_descriptions, list(
if(cell && cell.charge >= 20)
cell.use(20)
spawn(0)
- for(var/area/A in area.related)
- for(var/obj/structure/machinery/light/L in A)
- L.on = 1
- L.broken()
- sleep(1)
+ for(var/obj/structure/machinery/light/L in area)
+ L.on = 1
+ L.broken()
+ sleep(1)
/obj/structure/machinery/power/apc/Destroy()
area.power_light = 0
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 094cdf5ac9ac..9978b9f2c5b3 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -143,6 +143,7 @@
idle_power_usage = 2
active_power_usage = 20
power_channel = POWER_CHANNEL_LIGHT //Lights are calc'd via area so they dont need to be in the machine list
+ light_system = STATIC_LIGHT
var/on = 0 // 1 if on, 0 if off
var/on_gs = 0
var/brightness = 8 // luminosity when on, also used in power calculation
@@ -272,7 +273,6 @@
if(A)
on = 0
// A.update_lights()
- SetLuminosity(0)
. = ..()
/obj/structure/machinery/light/proc/is_broken()
@@ -296,7 +296,6 @@
// update the icon_state and luminosity of the light depending on its state
/obj/structure/machinery/light/proc/update(trigger = 1)
- SSlighting.lights_current.Add(light)
update_icon()
if(on)
if(luminosity != brightness)
@@ -312,13 +311,13 @@
status = LIGHT_BURNED
icon_state = "[base_state]-burned"
on = 0
- SetLuminosity(0)
+ set_light(0)
else
update_use_power(USE_POWER_ACTIVE)
- SetLuminosity(brightness)
+ set_light(brightness)
else
update_use_power(USE_POWER_NONE)
- SetLuminosity(0)
+ set_light(0)
if(on != on_gs)
on_gs = on
@@ -441,8 +440,8 @@
/obj/structure/machinery/light/proc/has_power()
var/area/A = src.loc.loc
if(!src.needs_power)
- return A.master.lightswitch
- return A.master.lightswitch && A.master.power_light
+ return A.lightswitch
+ return A.lightswitch && A.power_light
/obj/structure/machinery/light/proc/flicker(amount = rand(10, 20))
if(flickering) return
@@ -592,9 +591,8 @@
/obj/structure/machinery/light/power_change()
spawn(10)
if(loc)
- var/area/A = src.loc.loc
- A = A.master
- if(!src.needs_power)
+ var/area/A = get_area(src)
+ if(!needs_power || A.unlimited_power)
seton(A.lightswitch)
return
seton(A.lightswitch && A.power_light)
@@ -776,7 +774,7 @@
/obj/structure/machinery/landinglight/proc/turn_off()
icon_state = initial(icon_state)
- SetLuminosity(0)
+ set_light(0)
/obj/structure/machinery/landinglight/ds1
id = "USS Almayer Dropship 1" // ID for landing zone
@@ -786,42 +784,42 @@
/obj/structure/machinery/landinglight/proc/turn_on()
icon_state = initial(icon_state) + "0"
- SetLuminosity(2)
+ set_light(2)
/obj/structure/machinery/landinglight/ds1/delayone/turn_on()
icon_state = initial(icon_state) + "1"
- SetLuminosity(2)
+ set_light(2)
/obj/structure/machinery/landinglight/ds1/delaytwo/turn_on()
icon_state = initial(icon_state) + "2"
- SetLuminosity(2)
+ set_light(2)
/obj/structure/machinery/landinglight/ds1/delaythree/turn_on()
icon_state = initial(icon_state) + "3"
- SetLuminosity(2)
+ set_light(2)
/obj/structure/machinery/landinglight/ds2/delayone/turn_on()
icon_state = initial(icon_state) + "1"
- SetLuminosity(2)
+ set_light(2)
/obj/structure/machinery/landinglight/ds2/delaytwo/turn_on()
icon_state = initial(icon_state) + "2"
- SetLuminosity(2)
+ set_light(2)
/obj/structure/machinery/landinglight/ds2/delaythree/turn_on()
icon_state = initial(icon_state) + "3"
- SetLuminosity(2)
+ set_light(2)
/obj/structure/machinery/landinglight/ds1/spoke
icon_state = "lz_spoke_light"
/obj/structure/machinery/landinglight/ds1/spoke/turn_on()
icon_state = initial(icon_state) + "1"
- SetLuminosity(3)
+ set_light(3)
/obj/structure/machinery/landinglight/ds2/spoke
icon_state = "lz_spoke_light"
/obj/structure/machinery/landinglight/ds2/spoke/turn_on()
icon_state = initial(icon_state) + "1"
- SetLuminosity(3)
+ set_light(3)
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index ac3daee900ab..bee3e0aac8c2 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -51,21 +51,21 @@
// return 1
var/area/A = src.loc.loc // make sure it's in an area
- if(!A || !isarea(A) || !A.master)
+ if(!A || !isarea(A))
return 0 // if not, then not powered
if(chan == -1)
chan = power_channel
- return A.master.powered(chan) // return power status of the area
+ return A.powered(chan) // return power status of the area
// increment the power usage stats for an area
/obj/structure/machinery/proc/use_power(amount, chan = POWER_CHANNEL_ONEOFF, autocalled = 0) // defaults to one-off power charge, not constant power change
var/area/A = get_area(src) // make sure it's in an area
- if(!A || !isarea(A) || !A.master)
+ if(!A || !isarea(A))
return
- A.master.use_power(amount, chan)
+ A.use_power(amount, chan)
if(!autocalled)
- log_power_update_request(A.master, src)
+ log_power_update_request(A, src)
return 1
//The master_area optional argument can be used to save on a lot of processing if the master area is already known. This is mainly intended for when this proc is called by the master controller.
@@ -274,10 +274,9 @@
return null
/area/proc/get_apc()
- for(var/area/RA in src.related)
- var/obj/structure/machinery/power/apc/FINDME = locate() in RA
- if (FINDME)
- return FINDME
+ var/obj/structure/machinery/power/apc/FINDME = locate() in src
+ if (FINDME)
+ return FINDME
//Determines how strong could be shock, deals damage to mob, uses power.
diff --git a/code/modules/projectiles/ammo_boxes/ammo_boxes.dm b/code/modules/projectiles/ammo_boxes/ammo_boxes.dm
index 69179a209f8b..831923415453 100644
--- a/code/modules/projectiles/ammo_boxes/ammo_boxes.dm
+++ b/code/modules/projectiles/ammo_boxes/ammo_boxes.dm
@@ -18,10 +18,6 @@
//---------------------GENERAL PROCS
-/obj/item/ammo_box/Destroy()
- SetLuminosity(0)
- . = ..()
-
/obj/item/ammo_box/attack_self(mob/living/user)
..()
if(burning)
@@ -45,14 +41,14 @@
/obj/item/ammo_box/proc/deploy_ammo_box(mob/user, turf/T)
user.drop_held_item()
-
+
//---------------------FIRE HANDLING PROCS
/obj/item/ammo_box/flamer_fire_act(severity, datum/cause_data/flame_cause_data)
if(burning)
return
burning = TRUE
- SetLuminosity(3)
+ set_light(3)
apply_fire_overlay()
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), src), 5 SECONDS)
@@ -239,11 +235,11 @@
if(host_box)
host_box.apply_fire_overlay(will_explode)
- host_box.SetLuminosity(3)
+ host_box.set_light(3)
host_box.visible_message(SPAN_WARNING(shown_message))
else
apply_fire_overlay(will_explode)
- SetLuminosity(3)
+ set_light(3)
visible_message(SPAN_WARNING(shown_message))
/obj/item/ammo_box/magazine/apply_fire_overlay(will_explode = FALSE)
@@ -424,7 +420,7 @@
visible_message(SPAN_WARNING("\The [src] catches on fire!"))
apply_fire_overlay(will_explode)
- SetLuminosity(3)
+ set_light(3)
/obj/item/ammo_box/rounds/apply_fire_overlay(will_explode = FALSE)
//original fire overlay is made for standard mag boxes, so they don't need additional offsetting
diff --git a/code/modules/projectiles/ammo_boxes/box_structures.dm b/code/modules/projectiles/ammo_boxes/box_structures.dm
index 9169706aec4a..cb119e1a2190 100644
--- a/code/modules/projectiles/ammo_boxes/box_structures.dm
+++ b/code/modules/projectiles/ammo_boxes/box_structures.dm
@@ -18,7 +18,6 @@
//---------------------GENERAL PROCS
/obj/structure/magazine_box/Destroy()
- SetLuminosity(0)
if(item_box)
qdel(item_box)
item_box = null
diff --git a/code/modules/projectiles/ammo_boxes/misc_boxes.dm b/code/modules/projectiles/ammo_boxes/misc_boxes.dm
index e6a80537130b..d09a69e5bb50 100644
--- a/code/modules/projectiles/ammo_boxes/misc_boxes.dm
+++ b/code/modules/projectiles/ammo_boxes/misc_boxes.dm
@@ -34,11 +34,11 @@
/obj/item/ammo_box/magazine/misc/handle_side_effects(obj/structure/magazine_box/host_box)
if(host_box)
host_box.apply_fire_overlay()
- host_box.SetLuminosity(3)
+ host_box.set_light(3)
host_box.visible_message(SPAN_WARNING("\The [src] catches on fire!"))
else
apply_fire_overlay()
- SetLuminosity(3)
+ set_light(3)
visible_message(SPAN_WARNING("\The [src] catches on fire!"))
/obj/item/ammo_box/magazine/misc/apply_fire_overlay(will_explode = FALSE)
@@ -117,11 +117,11 @@
if(host_box)
host_box.apply_fire_overlay()
- host_box.SetLuminosity(3)
+ host_box.set_light(3)
host_box.visible_message(SPAN_WARNING(shown_message))
else
apply_fire_overlay()
- SetLuminosity(3)
+ set_light(3)
visible_message(SPAN_WARNING(shown_message))
//for flare box, instead of actually exploding, we throw out a flare at random direction
diff --git a/code/modules/projectiles/ammo_datums.dm b/code/modules/projectiles/ammo_datums.dm
index d09c7ad7bb26..9315a1dd0c68 100644
--- a/code/modules/projectiles/ammo_datums.dm
+++ b/code/modules/projectiles/ammo_datums.dm
@@ -410,6 +410,13 @@
penetration = ARMOR_PENETRATION_TIER_10
damage = 45
+/datum/ammo/bullet/pistol/heavy/super/highimpact/upp
+ name = "high-impact pistol bullet"
+ sound_override = 'sound/weapons/gun_DE50.ogg'
+ penetration = ARMOR_PENETRATION_TIER_6
+ debilitate = list(0,1.5,0,0,0,1,0,0)
+ flags_ammo_behavior = AMMO_BALLISTIC
+
/datum/ammo/bullet/pistol/heavy/super/highimpact/New()
..()
RegisterSignal(src, COMSIG_AMMO_POINT_BLANK, PROC_REF(handle_battlefield_execution))
@@ -617,42 +624,43 @@
BULLET_TRAIT_ENTRY(/datum/element/bullet_trait_penetrating)
))
-/datum/ammo/bullet/revolver/nagant
- name = "nagant revolver bullet"
- headshot_state = HEADSHOT_OVERLAY_LIGHT //Smaller bullet.
- damage = 40
+/datum/ammo/bullet/revolver/upp
+ name = "heavy revolver bullet"
+ headshot_state = HEADSHOT_OVERLAY_MEDIUM
+ penetration = ARMOR_PENETRATION_TIER_4
+ damage = 70
-/datum/ammo/bullet/revolver/nagant/shrapnel
+/datum/ammo/bullet/revolver/upp/shrapnel
name = "shrapnel shot"
headshot_state = HEADSHOT_OVERLAY_HEAVY //Gol-dang shotgun blow your fething head off.
debilitate = list(0,0,0,0,0,0,0,0)
icon_state = "shrapnelshot"
handful_state = "shrapnel"
- bonus_projectiles_type = /datum/ammo/bullet/revolver/nagant/shrapnel_bits
+ bonus_projectiles_type = /datum/ammo/bullet/revolver/upp/shrapnel_bits
max_range = 6
- damage = 25 // + TIER_4 * 3
+ damage = 40 // + TIER_4 * 3
damage_falloff = DAMAGE_FALLOFF_TIER_7
- penetration = ARMOR_PENETRATION_TIER_6
+ penetration = ARMOR_PENETRATION_TIER_8
bonus_projectiles_amount = EXTRA_PROJECTILES_TIER_3
shrapnel_chance = 100
- shrapnel_type = /obj/item/shard/shrapnel/nagant
- //roughly 35 or so damage
+ shrapnel_type = /obj/item/shard/shrapnel/upp
+ //roughly 90 or so damage with the additional shrapnel, around 130 in total with primary round
-/datum/ammo/bullet/revolver/nagant/shrapnel/on_hit_mob(mob/M, obj/item/projectile/P)
+/datum/ammo/bullet/revolver/upp/shrapnel/on_hit_mob(mob/M, obj/item/projectile/P)
pushback(M, P, 1)
-/datum/ammo/bullet/revolver/nagant/shrapnel_bits
+/datum/ammo/bullet/revolver/upp/shrapnel_bits
name = "small shrapnel"
icon_state = "shrapnelshot_bit"
max_range = 6
- damage = 20
- penetration = ARMOR_PENETRATION_TIER_1
+ damage = 30
+ penetration = ARMOR_PENETRATION_TIER_4
scatter = SCATTER_AMOUNT_TIER_1
bonus_projectiles_amount = 0
- shrapnel_type = /obj/item/shard/shrapnel/nagant/bits
+ shrapnel_type = /obj/item/shard/shrapnel/upp/bits
/datum/ammo/bullet/revolver/small
name = "small revolver bullet"
@@ -862,6 +870,15 @@
damage_falloff = DAMAGE_FALLOFF_TIER_7
scatter = SCATTER_AMOUNT_TIER_5
+/datum/ammo/bullet/smg/pps43
+ name = "simple submachinegun bullet"
+ damage = 35
+ accurate_range = 7
+ effective_range_max = 10
+ penetration = ARMOR_PENETRATION_TIER_4
+ damage_falloff = DAMAGE_FALLOFF_TIER_6
+ scatter = SCATTER_AMOUNT_TIER_6
+
/*
//======
Rifle Ammo
@@ -1057,21 +1074,21 @@
/datum/ammo/bullet/rifle/type71
name = "heavy rifle bullet"
- damage = 35
- penetration = ARMOR_PENETRATION_TIER_2
+ damage = 55
+ penetration = ARMOR_PENETRATION_TIER_3
/datum/ammo/bullet/rifle/type71/ap
name = "heavy armor-piercing rifle bullet"
- damage = 20
+ damage = 40
penetration = ARMOR_PENETRATION_TIER_10
/datum/ammo/bullet/rifle/type71/heap
name = "heavy high-explosive armor-piercing rifle bullet"
headshot_state = HEADSHOT_OVERLAY_HEAVY
- damage = 50
- penetration = ARMOR_PENETRATION_TIER_8
+ damage = 65
+ penetration = ARMOR_PENETRATION_TIER_10
/*
//======
@@ -1599,6 +1616,11 @@
. = ..()
pushback(M, P, 3)
+/datum/ammo/bullet/sniper/upp
+ name = "armor-piercing sniper bullet"
+ damage = 80
+ penetration = ARMOR_PENETRATION_TIER_10
+
/datum/ammo/bullet/sniper/anti_materiel
name = "anti-materiel sniper bullet"
@@ -1865,6 +1887,18 @@
penetration= ARMOR_PENETRATION_TIER_6
shrapnel_chance = SHRAPNEL_CHANCE_TIER_2
+/datum/ammo/bullet/pkp
+ name = "machinegun bullet"
+ headshot_state = HEADSHOT_OVERLAY_MEDIUM
+
+ accuracy = HIT_ACCURACY_TIER_1
+ accuracy_var_low = PROJECTILE_VARIANCE_TIER_8
+ accuracy_var_high = PROJECTILE_VARIANCE_TIER_6
+ accurate_range = 14
+ damage = 35
+ penetration= ARMOR_PENETRATION_TIER_6
+ shrapnel_chance = SHRAPNEL_CHANCE_TIER_2
+
/*
//======
Rocket Ammo
@@ -2079,6 +2113,42 @@
/datum/ammo/rocket/wp/do_at_max_range(obj/item/projectile/P)
drop_flame(get_turf(P), P.weapon_cause_data)
+/datum/ammo/rocket/wp/upp
+ name = "extreme-intensity incendiary rocket"
+ flags_ammo_behavior = AMMO_ROCKET|AMMO_EXPLOSIVE|AMMO_STRIKES_SURFACE
+ damage_type = BURN
+
+ accuracy_var_low = PROJECTILE_VARIANCE_TIER_6
+ accurate_range = 8
+ damage = 150
+ max_range = 10
+
+/datum/ammo/rocket/wp/upp/set_bullet_traits()
+ . = ..()
+ LAZYADD(traits_to_give, list(
+ BULLET_TRAIT_ENTRY(/datum/element/bullet_trait_incendiary)
+ ))
+
+/datum/ammo/rocket/wp/upp/drop_flame(turf/T, datum/cause_data/cause_data)
+ playsound(T, 'sound/weapons/gun_flamethrower3.ogg', 75, 1, 7)
+ if(!istype(T)) return
+ smoke.set_up(1, T)
+ smoke.start()
+ var/datum/reagent/napalm/upp/R = new()
+ new /obj/flamer_fire(T, cause_data, R, 3)
+
+/datum/ammo/rocket/wp/upp/on_hit_mob(mob/M, obj/item/projectile/P)
+ drop_flame(get_turf(M), P.weapon_cause_data)
+
+/datum/ammo/rocket/wp/upp/on_hit_obj(obj/O, obj/item/projectile/P)
+ drop_flame(get_turf(O), P.weapon_cause_data)
+
+/datum/ammo/rocket/wp/upp/on_hit_turf(turf/T, obj/item/projectile/P)
+ drop_flame(T, P.weapon_cause_data)
+
+/datum/ammo/rocket/wp/upp/do_at_max_range(obj/item/projectile/P)
+ drop_flame(get_turf(P), P.weapon_cause_data)
+
/datum/ammo/rocket/wp/quad
name = "thermobaric rocket"
flags_ammo_behavior = AMMO_ROCKET|AMMO_STRIKES_SURFACE
diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm
index 1947f87c574a..d747525f3feb 100644
--- a/code/modules/projectiles/ammunition.dm
+++ b/code/modules/projectiles/ammunition.dm
@@ -116,14 +116,17 @@ They're all essentially identical when it comes to getting the job done.
/obj/item/ammo_magazine/attackby(obj/item/I, mob/living/user, bypass_hold_check = 0)
if(istype(I, /obj/item/ammo_magazine))
var/obj/item/ammo_magazine/MG = I
- if(MG.flags_magazine & AMMUNITION_HANDFUL) //got a handful of bullets
+ if((MG.flags_magazine & AMMUNITION_HANDFUL) || (MG.flags_magazine & AMMUNITION_SLAP_TRANSFER)) //got a handful of bullets
if(flags_magazine & AMMUNITION_REFILLABLE) //and a refillable magazine
var/obj/item/ammo_magazine/handful/transfer_from = I
if(src == user.get_inactive_hand() || bypass_hold_check) //It has to be held.
if(default_ammo == transfer_from.default_ammo)
- transfer_ammo(transfer_from,user,transfer_from.current_rounds) // This takes care of the rest.
- else to_chat(user, "Those aren't the same rounds. Better not mix them up.")
- else to_chat(user, "Try holding [src] before you attempt to restock it.")
+ if(transfer_ammo(transfer_from,user,transfer_from.current_rounds)) // This takes care of the rest.
+ to_chat(user, SPAN_NOTICE("You transfer rounds to [src] from [transfer_from]."))
+ else
+ to_chat(user, SPAN_NOTICE("Those aren't the same rounds. Better not mix them up."))
+ else
+ to_chat(user, SPAN_NOTICE("Try holding [src] before you attempt to restock it."))
//Generic proc to transfer ammo between ammo mags. Can work for anything, mags, handfuls, etc.
/obj/item/ammo_magazine/proc/transfer_ammo(obj/item/ammo_magazine/source, mob/user, transfer_amount = 1)
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 832f243a9602..0b54d973549a 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -25,6 +25,7 @@
)
flags_atom = FPRINT|CONDUCT
flags_item = TWOHANDED
+ light_system = DIRECTIONAL_LIGHT
var/accepted_ammo = list()
///Determines what kind of bullet is created when the gun is unloaded - used to match rounds to magazines. Set automatically when reloading.
@@ -127,7 +128,7 @@
///How many full-auto shots to get to max scatter?
var/fa_scatter_peak = 4
///How bad does the scatter get on full auto?
- var/fa_max_scatter = 8.5
+ var/fa_max_scatter = 6.5
///Click parameters to use when firing full-auto
var/fa_params = null
@@ -228,6 +229,8 @@
VAR_PROTECTED/start_semiauto = TRUE
/// If this gun should spawn with automatic fire. Protected due to it never needing to be edited.
VAR_PROTECTED/start_automatic = FALSE
+ /// The multiplier for how much slower this should fire in automatic mode. 1 is normal, 1.2 is 20% slower, 2 is 100% slower, etc. Protected due to it never needing to be edited.
+ VAR_PROTECTED/autofire_slow_mult = 1
/**
@@ -274,7 +277,7 @@
AddElement(/datum/element/drop_retrieval/gun, auto_retrieval_slot)
update_icon() //for things like magazine overlays
gun_firemode = gun_firemode_list[1] || GUN_FIREMODE_SEMIAUTO
- AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, CALLBACK(src, PROC_REF(set_bursting)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(fire_wrapper)), CALLBACK(src, PROC_REF(display_ammo)), CALLBACK(src, PROC_REF(set_auto_firing))) //This should go after handle_starting_attachment() and setup_firemodes() to get the proper values set.
+ AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_delay, burst_amount, gun_firemode, autofire_slow_mult, CALLBACK(src, PROC_REF(set_bursting)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(fire_wrapper)), CALLBACK(src, PROC_REF(display_ammo)), CALLBACK(src, PROC_REF(set_auto_firing))) //This should go after handle_starting_attachment() and setup_firemodes() to get the proper values set.
/obj/item/weapon/gun/proc/set_gun_attachment_offsets()
attachable_offset = null
@@ -292,9 +295,6 @@
var/obj/item/attachable/potential_attachment = attachments[slot]
if(!potential_attachment)
continue
- loc.SetLuminosity(0, FALSE, src)
- else
- SetLuminosity(0)
attachments = null
attachable_overlays = null
QDEL_NULL(active_attachable)
@@ -425,6 +425,10 @@
else if(M.r_hand == src)
M.update_inv_r_hand()
+ setup_firemodes()
+
+ SEND_SIGNAL(src, COMSIG_GUN_RECALCULATE_ATTACHMENT_BONUSES)
+
/obj/item/weapon/gun/proc/handle_random_attachments()
var/attachmentchoice
@@ -502,16 +506,19 @@ As sniper rifles have both and weapon mods can change them as well. ..() deals w
if(slot in list(WEAR_L_HAND, WEAR_R_HAND))
set_gun_user(user)
+ if(HAS_TRAIT_FROM_ONLY(src, TRAIT_GUN_LIGHT_DEACTIVATED, user))
+ force_light(on = TRUE)
+ REMOVE_TRAIT(src, TRAIT_GUN_LIGHT_DEACTIVATED, user)
else
set_gun_user(null)
+ force_light(on = FALSE)
+ ADD_TRAIT(src, TRAIT_GUN_LIGHT_DEACTIVATED, user)
return ..()
/obj/item/weapon/gun/dropped(mob/user)
. = ..()
- disconnect_light_from_mob(user)
-
var/delay_left = (last_fired + fire_delay + additional_fire_group_delay) - world.time
if(fire_delay_group && delay_left > 0)
for(var/group in fire_delay_group)
@@ -939,6 +946,10 @@ and you're good to go.
//Let's check on the active attachable. It loads ammo on the go, so it never chambers anything
if(active_attachable)
+ if(shots_fired >= 1) // This is what you'll want to remove if you want automatic underbarrel guns in the future
+ SEND_SIGNAL(src, COMSIG_GUN_INTERRUPT_FIRE)
+ return
+
if(active_attachable.current_rounds > 0) //If it's still got ammo and stuff.
active_attachable.current_rounds--
var/obj/item/projectile/bullet = create_bullet(active_attachable.ammo, initial(name))
@@ -1073,10 +1084,10 @@ and you're good to go.
This is where the grenade launcher and flame thrower function as attachments.
This is also a general check to see if the attachment can fire in the first place.
*/
- var/check_for_attachment_fire = 0
+ var/check_for_attachment_fire = FALSE
if(active_attachable?.flags_attach_features & ATTACH_WEAPON) //Attachment activated and is a weapon.
- check_for_attachment_fire = 1
+ check_for_attachment_fire = TRUE
if(!(active_attachable.flags_attach_features & ATTACH_PROJECTILE)) //If it's unique projectile, this is where we fire it.
if((active_attachable.current_rounds <= 0) && !(active_attachable.flags_attach_features & ATTACH_IGNORE_EMPTY))
click_empty(user) //If it's empty, let them know.
@@ -1202,8 +1213,7 @@ and you're good to go.
shots_fired++
- else // This happens in very rare circumstances when you're moving a lot while burst firing, so I'm going to toss it up to guns jamming.
- clear_jam(projectile_to_fire,user)
+ else
return TRUE
//>>POST PROCESSING AND CLEANUP BEGIN HERE.<<
@@ -1503,8 +1513,12 @@ not all weapons use normal magazines etc. load_into_chamber() itself is designed
if(flags_gun_features & GUN_TRIGGER_SAFETY)
to_chat(user, SPAN_WARNING("The safety is on!"))
return
-
- if((flags_gun_features & GUN_WIELDED_FIRING_ONLY) && !(flags_item & WIELDED)) //If we're not holding the weapon with both hands when we should.
+ if(active_attachable)
+ if(active_attachable.flags_attach_features & ATTACH_PROJECTILE)
+ if(!(active_attachable.flags_attach_features & ATTACH_WIELD_OVERRIDE) && !(flags_item & WIELDED))
+ to_chat(user, SPAN_WARNING("You must wield [src] to fire [active_attachable]!"))
+ return
+ if((flags_gun_features & GUN_WIELDED_FIRING_ONLY) && !(flags_item & WIELDED) && !active_attachable) //If we're not holding the weapon with both hands when we should.
to_chat(user, SPAN_WARNING("You need a more secure grip to fire this weapon!"))
return
@@ -1716,9 +1730,11 @@ not all weapons use normal magazines etc. load_into_chamber() itself is designed
if(!istype(user) || !istype(user.loc,/turf))
return
- if(user.luminosity <= muzzle_flash_lum)
- user.SetLuminosity(muzzle_flash_lum, FALSE, src)
- addtimer(CALLBACK(user, TYPE_PROC_REF(/atom, SetLuminosity), 0, FALSE, src), 10)
+ var/prev_light = light_range
+ if(!light_on && (light_range <= muzzle_flash_lum))
+ set_light_range(muzzle_flash_lum)
+ set_light_on(TRUE)
+ addtimer(CALLBACK(src, PROC_REF(reset_light_range), prev_light), 0.5 SECONDS)
var/image_layer = (user && user.dir == SOUTH) ? MOB_LAYER+0.1 : MOB_LAYER-0.1
var/offset = 5
@@ -1730,6 +1746,13 @@ not all weapons use normal magazines etc. load_into_chamber() itself is designed
I.transform = rotate
I.flick_overlay(user, 3)
+/// called by a timer to remove the light range from muzzle flash
+/obj/item/weapon/gun/proc/reset_light_range(lightrange)
+ set_light_range(lightrange)
+ if(lightrange <= 0)
+ set_light_on(FALSE)
+
+
/obj/item/weapon/gun/attack_alien(mob/living/carbon/xenomorph/xeno)
..()
var/slashed_light = FALSE
@@ -1892,7 +1915,7 @@ not all weapons use normal magazines etc. load_into_chamber() itself is designed
if(!target)
target = src.target
if(!user)
- user = src.gun_user
+ user = gun_user
return Fire(target, user, params, reflex, dual_wield)
/// Setter proc for fa_firing
diff --git a/code/modules/projectiles/gun_attachables.dm b/code/modules/projectiles/gun_attachables.dm
index 7d2dbf5288be..c7b88ef0c1ae 100644
--- a/code/modules/projectiles/gun_attachables.dm
+++ b/code/modules/projectiles/gun_attachables.dm
@@ -594,7 +594,7 @@ Defined in conflicts.dm of the #defines folder.
icon = 'icons/obj/items/weapons/guns/attachments/rail.dmi'
icon_state = "flashlight"
attach_icon = "flashlight_a"
- light_mod = 7
+ light_mod = 5
slot = "rail"
matter = list("metal" = 50,"glass" = 20)
flags_attach_features = ATTACH_REMOVABLE|ATTACH_ACTIVATION
@@ -604,8 +604,8 @@ Defined in conflicts.dm of the #defines folder.
var/original_state = "flashlight"
var/original_attach = "flashlight_a"
- var/activated = FALSE
- var/helm_mounted_light_mod = 5
+ var/helm_mounted_light_power = 2
+ var/helm_mounted_light_range = 3
var/datum/action/item_action/activation
var/obj/item/attached_item
@@ -636,7 +636,7 @@ Defined in conflicts.dm of the #defines folder.
SIGNAL_HANDLER
if(!attached_item)
return
- if(activated)
+ if(light_on)
icon_state = original_state
attach_icon = original_attach
activate_attachment(attached_item, attached_item.loc, TRUE)
@@ -652,33 +652,54 @@ Defined in conflicts.dm of the #defines folder.
activate_attachment(attached_item, owner)
/obj/item/attachable/flashlight/activate_attachment(obj/item/weapon/gun/G, mob/living/user, turn_off)
- if(istype(G, /obj/item/clothing/head/helmet/marine))
- var/atom/movable/light_source = user
- . = (turn_off && activated)
- if(turn_off || activated)
- if(activated)
+ turn_light(user, turn_off ? !turn_off : !light_on)
+
+/obj/item/attachable/flashlight/turn_light(mob/user, toggle_on, cooldown, sparks, forced, light_again)
+ . = ..()
+ if(. != CHECKS_PASSED)
+ return
+
+ if(istype(attached_item, /obj/item/clothing/head/helmet/marine))
+ if(!toggle_on || light_on)
+ if(light_on)
playsound(user, deactivation_sound, 15, 1)
icon_state = original_state
attach_icon = original_attach
- activated = FALSE
+ light_on = FALSE
else
playsound(user, activation_sound, 15, 1)
icon_state += "-on"
attach_icon += "-on"
- activated = TRUE
+ light_on = TRUE
attached_item.update_icon()
- light_source.SetLuminosity(helm_mounted_light_mod * activated, FALSE, G)
- attached_item.SetLuminosity(helm_mounted_light_mod * activated, FALSE, G)
+ attached_item.set_light_range(helm_mounted_light_range)
+ attached_item.set_light_power(helm_mounted_light_power)
+ attached_item.set_light_on(light_on)
activation.update_button_icon()
return
- if(turn_off && !(G.flags_gun_features & GUN_FLASHLIGHT_ON))
- return FALSE
- var/flashlight_on = (G.flags_gun_features & GUN_FLASHLIGHT_ON) ? 0 : 1
- var/atom/movable/light_source = ismob(G.loc) ? G.loc : G
- light_source.SetLuminosity(light_mod * flashlight_on, FALSE, G)
- G.flags_gun_features ^= GUN_FLASHLIGHT_ON
- if(G.flags_gun_features & GUN_FLASHLIGHT_ON)
+ if(!isgun(loc))
+ return
+
+ var/obj/item/weapon/gun/attached_gun = loc
+
+ if(toggle_on && !light_on)
+ attached_gun.set_light_range(attached_gun.light_range + light_mod)
+ attached_gun.set_light_power(attached_gun.light_power + (light_mod * 0.5))
+ if(!(attached_gun.flags_gun_features & GUN_FLASHLIGHT_ON))
+ attached_gun.set_light_on(TRUE)
+ light_on = TRUE
+ attached_gun.flags_gun_features |= GUN_FLASHLIGHT_ON
+
+ if(!toggle_on && light_on)
+ attached_gun.set_light_range(attached_gun.light_range - light_mod)
+ attached_gun.set_light_power(attached_gun.light_power - (light_mod * 0.5))
+ if(attached_gun.flags_gun_features & GUN_FLASHLIGHT_ON)
+ attached_gun.set_light_on(FALSE)
+ light_on = FALSE
+ attached_gun.flags_gun_features &= ~GUN_FLASHLIGHT_ON
+
+ if(attached_gun.flags_gun_features & GUN_FLASHLIGHT_ON)
icon_state += "-on"
attach_icon += "-on"
playsound(user, deactivation_sound, 15, 1)
@@ -686,17 +707,14 @@ Defined in conflicts.dm of the #defines folder.
icon_state = original_state
attach_icon = original_attach
playsound(user, activation_sound, 15, 1)
- G.update_attachable(slot)
+ attached_gun.update_attachable(slot)
- for(var/X in G.actions)
+ for(var/X in attached_gun.actions)
var/datum/action/A = X
if(A.target == src)
A.update_button_icon()
return TRUE
-
-
-
/obj/item/attachable/flashlight/attackby(obj/item/I, mob/user)
if(HAS_TRAIT(I, TRAIT_TOOL_SCREWDRIVER))
to_chat(user, SPAN_NOTICE("You strip the rail flashlight of its mount, converting it to a normal flashlight."))
@@ -852,6 +870,28 @@ Defined in conflicts.dm of the #defines folder.
delay_scoped_nerf = FIRE_DELAY_TIER_11 //to compensate initial debuff. We want "high_fire_delay"
damage_falloff_scoped_buff = -0.4 //has to be negative
+/obj/item/attachable/scope/Attach(obj/item/weapon/gun/gun)
+ . = ..()
+ RegisterSignal(gun, COMSIG_GUN_RECALCULATE_ATTACHMENT_BONUSES, PROC_REF(handle_attachment_recalc))
+
+/obj/item/attachable/scope/Detach(mob/user, obj/item/weapon/gun/detaching_gub)
+ . = ..()
+ UnregisterSignal(detaching_gub, COMSIG_GUN_RECALCULATE_ATTACHMENT_BONUSES)
+
+
+/// Due to the bipod's interesting way of handling stat modifications, this is necessary to prevent exploits.
+/obj/item/attachable/scope/proc/handle_attachment_recalc(obj/item/weapon/gun/source)
+ SIGNAL_HANDLER
+
+ if(!source.zoom)
+ return
+
+ if(using_scope)
+ source.accuracy_mult += accuracy_scoped_buff
+ source.modify_fire_delay(delay_scoped_nerf)
+ source.damage_falloff_mult += damage_falloff_scoped_buff
+
+
/obj/item/attachable/scope/proc/apply_scoped_buff(obj/item/weapon/gun/G, mob/living/carbon/user)
if(G.zoom)
G.accuracy_mult += accuracy_scoped_buff
@@ -952,6 +992,9 @@ Defined in conflicts.dm of the #defines folder.
//other variable zoom scopes
+/obj/item/attachable/scope/variable_zoom/integrated
+ name = "variable zoom scope"
+
/obj/item/attachable/scope/variable_zoom/slavic
icon_state = "slavicscope"
attach_icon = "slavicscope"
@@ -1655,6 +1698,81 @@ Defined in conflicts.dm of the #defines folder.
if(MAP_PRISON_STATION, MAP_PRISON_STATION_V3, MAP_LV522_CHANCES_CLAIM)
attach_icon = new_attach_icon ? new_attach_icon : "c_" + attach_icon
+/obj/item/attachable/upp_rpg_breech
+ name = "HJRA-12 Breech"
+ desc = "This isn't supposed to be seperated from the gun, how'd this happen?"
+ icon = 'icons/obj/items/weapons/guns/attachments/stock.dmi'
+ icon_state = "hjra_breech"
+ attach_icon = "hjra_breech"
+ slot = "stock"
+ wield_delay_mod = WIELD_DELAY_NONE
+ flags_attach_features = NO_FLAGS
+ melee_mod = 0
+ size_mod = 0
+
+/obj/item/attachable/pkpbarrel
+ name = "QYJ-72 Barrel"
+ desc = "This isn't supposed to be seperated from the gun, how'd this happen?"
+ icon = 'icons/obj/items/weapons/guns/attachments/barrel.dmi'
+ icon_state = "uppmg_barrel"
+ attach_icon = "uppmg_barrel"
+ slot = "muzzle"
+ wield_delay_mod = WIELD_DELAY_NONE
+ flags_attach_features = NO_FLAGS
+ melee_mod = 0
+ size_mod = 0
+
+/obj/item/attachable/stock/pkpstock
+ name = "QYJ-72 Stock"
+ desc = "This isn't supposed to be seperated from the gun, how'd this happen?"
+ icon = 'icons/obj/items/weapons/guns/attachments/stock.dmi'
+ icon_state = "uppmg_stock"
+ attach_icon = "uppmg_stock"
+ slot = "stock"
+ wield_delay_mod = WIELD_DELAY_NONE
+ flags_attach_features = NO_FLAGS
+ melee_mod = 20 //the thought of a upp spec beating people to death with a pk makes me laugh
+ size_mod = 0
+
+/obj/item/attachable/type88_barrel
+ name = "Type-88 Barrel"
+ desc = "This isn't supposed to be seperated from the gun, how'd this happen?"
+ icon = 'icons/obj/items/weapons/guns/attachments/barrel.dmi'
+ icon_state = "type88_barrel"
+ attach_icon = "type88_barrel"
+ slot = "special"
+ wield_delay_mod = WIELD_DELAY_NONE
+ flags_attach_features = NO_FLAGS
+ melee_mod = 0
+ size_mod = 0
+
+/obj/item/attachable/type73suppressor
+ name = "Type 73 Integrated Suppressor"
+ desc = "This isn't supposed to be seperated from the gun, how'd this happen?"
+ icon = 'icons/obj/items/weapons/guns/attachments/barrel.dmi'
+ icon_state = "type73_suppressor"
+ attach_icon = "type73_suppressor"
+ slot = "muzzle"
+ wield_delay_mod = WIELD_DELAY_NONE
+ flags_attach_features = NO_FLAGS
+ melee_mod = 0
+ size_mod = 0
+
+/obj/item/attachable/stock/type71
+ name = "Type 71 Stock"
+ desc = "This isn't supposed to be seperated from the gun, how'd this happen?"
+ icon = 'icons/obj/items/weapons/guns/attachments/stock.dmi'
+ icon_state = "type71_stock"
+ attach_icon = "type71_stock"
+ slot = "stock"
+ wield_delay_mod = WIELD_DELAY_NONE
+ flags_attach_features = NO_FLAGS
+ melee_mod = 15
+ size_mod = 0
+
+/obj/item/attachable/stock/type71/New()
+ ..()
+
/obj/item/attachable/stock/smg
name = "submachinegun stock"
desc = "A rare ARMAT stock distributed in small numbers to USCM forces. Compatible with the M39, this stock reduces recoil and improves accuracy, but at a reduction to handling and agility. Seemingly a bit more effective in a brawl"
@@ -1976,6 +2094,8 @@ Defined in conflicts.dm of the #defines folder.
G.damage_mult = 1
icon_state += "-on"
+ SEND_SIGNAL(G, COMSIG_GUN_INTERRUPT_FIRE)
+
for(var/X in G.actions)
var/datum/action/A = X
A.update_button_icon()
@@ -2261,7 +2381,7 @@ Defined in conflicts.dm of the #defines folder.
var/obj/item/weapon/gun/attached_gun = loc
if(!(attached_gun.flags_item & WIELDED))
- to_chat(user, SPAN_WARNING("You must wield \the [attached_gun] to fire \the [src]!"))
+ to_chat(user, SPAN_WARNING("You must wield [attached_gun] to fire [src]!"))
return
if(current_rounds > round_usage_per_tile && ..())
@@ -2407,6 +2527,9 @@ Defined in conflicts.dm of the #defines folder.
/obj/item/attachable/attached_gun/extinguisher/fire_attachment(atom/target, obj/item/weapon/gun/gun, mob/living/user)
if(!internal_extinguisher)
return
+ if(!(gun.flags_item & WIELDED))
+ to_chat(user, SPAN_WARNING("You must wield [gun] to fire [src]!"))
+ return
if(..())
return internal_extinguisher.afterattack(target, user)
@@ -2467,7 +2590,7 @@ Defined in conflicts.dm of the #defines folder.
return
if((gun.flags_gun_features & GUN_WIELDED_FIRING_ONLY) && !(gun.flags_item & WIELDED))
- to_chat(user, SPAN_WARNING("You need a more secure grip to fire this weapon!"))
+ to_chat(user, SPAN_WARNING("You must wield [gun] to fire [src]!"))
return
if(gun.flags_gun_features & GUN_TRIGGER_SAFETY)
@@ -2646,13 +2769,14 @@ Defined in conflicts.dm of the #defines folder.
burst_scatter_mod = 0
delay_mod = FIRE_DELAY_TIER_12
G.recalculate_attachment_bonuses()
+ G.stop_fire()
var/mob/living/user
if(isliving(G.loc))
user = G.loc
UnregisterSignal(user, COMSIG_MOB_MOVE_OR_LOOK)
if(G.flags_gun_features & GUN_SUPPORT_PLATFORM)
- G.remove_bullet_trait("iff")
+ G.remove_firemode(GUN_FIREMODE_AUTOMATIC)
if(!QDELETED(G))
playsound(user,'sound/items/m56dauto_rotate.ogg', 55, 1)
@@ -2683,12 +2807,13 @@ Defined in conflicts.dm of the #defines folder.
else
delay_mod = -FIRE_DELAY_TIER_12
G.recalculate_attachment_bonuses()
+ G.stop_fire()
initial_mob_dir = user.dir
RegisterSignal(user, COMSIG_MOB_MOVE_OR_LOOK, PROC_REF(handle_mob_move_or_look))
if(G.flags_gun_features & GUN_SUPPORT_PLATFORM)
- G.add_bullet_trait(BULLET_TRAIT_ENTRY_ID("iff", /datum/element/bullet_trait_iff))
+ G.add_firemode(GUN_FIREMODE_AUTOMATIC)
else
to_chat(user, SPAN_NOTICE("You retract [src]."))
diff --git a/code/modules/projectiles/gun_helpers.dm b/code/modules/projectiles/gun_helpers.dm
index a60773c88be7..d58385d3edc0 100644
--- a/code/modules/projectiles/gun_helpers.dm
+++ b/code/modules/projectiles/gun_helpers.dm
@@ -136,20 +136,6 @@ DEFINES in setup.dm, referenced here.
else
..()
-
-/// This function disconnects the luminosity from the mob and back to the gun
-/obj/item/weapon/gun/proc/disconnect_light_from_mob(mob/bearer)
- if (!(flags_gun_features & GUN_FLASHLIGHT_ON))
- return FALSE
- for (var/slot in attachments)
- var/obj/item/attachable/attachment = attachments[slot]
- if (!attachment || !attachment.light_mod)
- continue
- bearer.SetLuminosity(0, FALSE, src)
- SetLuminosity(attachment.light_mod)
- return TRUE
- return FALSE
-
/// This function actually turns the lights on the gun off
/obj/item/weapon/gun/proc/turn_off_light(mob/bearer)
if (!(flags_gun_features & GUN_FLASHLIGHT_ON))
@@ -165,15 +151,6 @@ DEFINES in setup.dm, referenced here.
/obj/item/weapon/gun/pickup(mob/user)
..()
- if (flags_gun_features & GUN_FLASHLIGHT_ON)
- for (var/slot in attachments)
- var/obj/item/attachable/attachment = attachments[slot]
- if (!attachment || !attachment.light_mod)
- continue
- user.SetLuminosity(attachment.light_mod, FALSE, src)
- SetLuminosity(0)
- break
-
unwield(user)
/obj/item/weapon/gun/proc/wy_allowed_check(mob/living/carbon/human/user)
@@ -700,6 +677,9 @@ DEFINES in setup.dm, referenced here.
CRASH("add_firemode called with a resulting gun_firemode_list length of [length(gun_firemode_list)].")
/obj/item/weapon/gun/proc/remove_firemode(removed_firemode, mob/user)
+ if(!(removed_firemode in gun_firemode_list))
+ return
+
if(!length(gun_firemode_list) || (length(gun_firemode_list) == 1))
CRASH("remove_firemode called with gun_firemode_list length [length(gun_firemode_list)].")
@@ -710,7 +690,9 @@ DEFINES in setup.dm, referenced here.
do_toggle_firemode(user, gun_firemode)
/obj/item/weapon/gun/proc/setup_firemodes()
+ var/old_firemode = gun_firemode
gun_firemode_list.len = 0
+
if(start_semiauto)
gun_firemode_list |= GUN_FIREMODE_SEMIAUTO
@@ -722,6 +704,10 @@ DEFINES in setup.dm, referenced here.
if(!length(gun_firemode_list))
CRASH("[src] called setup_firemodes() with an empty gun_firemode_list")
+
+ else if(old_firemode in gun_firemode_list)
+ gun_firemode = old_firemode
+
else
gun_firemode = gun_firemode_list[1]
@@ -951,3 +937,15 @@ DEFINES in setup.dm, referenced here.
if(!istype(target, /atom/movable/screen/click_catcher))
return null
return params2turf(modifiers["screen-loc"], get_turf(user), user.client)
+
+/// If this gun has a relevant flashlight attachable attached, (de)activate it
+/obj/item/weapon/gun/proc/force_light(on)
+ var/obj/item/attachable/flashlight/torch
+ for(var/slot in attachments)
+ torch = attachments[slot]
+ if(istype(torch))
+ break
+ if(!torch)
+ return FALSE
+ torch.turn_light(toggle_on = on, forced = TRUE)
+ return TRUE
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index 61ea0442a427..5733b01195ff 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -181,6 +181,7 @@
fire_sound = 'sound/weapons/Laser4.ogg'
has_charge_meter = FALSE
charge_icon = "+laz_uzi_empty"
+ start_automatic = TRUE
/obj/item/weapon/gun/energy/laz_uzi/set_gun_config_values()
..()
@@ -194,6 +195,7 @@
scatter_unwielded = SCATTER_AMOUNT_TIER_6
damage_mult = BASE_BULLET_DAMAGE_MULT
recoil_unwielded = RECOIL_AMOUNT_TIER_5
+ fa_scatter_peak = SCATTER_AMOUNT_TIER_8
//############################ Taser ##################
// Lots of bits for it so splitting off an area
diff --git a/code/modules/projectiles/guns/flamer/flamer.dm b/code/modules/projectiles/guns/flamer/flamer.dm
index a108b3a9948f..13ccd03c3e82 100644
--- a/code/modules/projectiles/guns/flamer/flamer.dm
+++ b/code/modules/projectiles/guns/flamer/flamer.dm
@@ -370,7 +370,7 @@
/obj/item/weapon/gun/flamer/M240T/auto/set_gun_config_values()
. = ..()
- set_fire_delay(FIRE_DELAY_TIER_3)
+ set_fire_delay(FIRE_DELAY_TIER_7)
GLOBAL_LIST_EMPTY(flamer_particles)
/particles/flamer_fire
@@ -404,6 +404,12 @@ GLOBAL_LIST_EMPTY(flamer_particles)
icon_state = "dynamic_2"
layer = BELOW_OBJ_LAYER
+ light_system = STATIC_LIGHT
+ light_on = TRUE
+ light_range = 3
+ light_power = 3
+ light_color = "#f88818"
+
var/firelevel = 12 //Tracks how much "fire" there is. Basically the timer of how long the fire burns
var/burnlevel = 10 //Tracks how HOT the fire is. This is basically the heat level of the fire and determines the temperature.
@@ -443,6 +449,8 @@ GLOBAL_LIST_EMPTY(flamer_particles)
else
flame_icon = R.burn_sprite
+ set_light(l_color = R.burncolor)
+
if(!GLOB.flamer_particles[R.burncolor])
GLOB.flamer_particles[R.burncolor] = new /particles/flamer_fire(R.burncolor)
particles = GLOB.flamer_particles[R.burncolor]
@@ -576,7 +584,6 @@ GLOBAL_LIST_EMPTY(flamer_particles)
RegisterSignal(SSdcs, COMSIG_GLOB_WEATHER_CHANGE, PROC_REF(update_in_weather_status))
/obj/flamer_fire/Destroy()
- SetLuminosity(0)
STOP_PROCESSING(SSobj, src)
to_call = null
tied_reagent = null
@@ -668,7 +675,7 @@ GLOBAL_LIST_EMPTY(flamer_particles)
flame_level++ //the initial flame burst is 1 level higher for a small time
icon_state = "[flame_icon]_[flame_level]"
- SetLuminosity(flame_level * 2)
+ set_light(flame_level * 2)
/obj/flamer_fire/proc/un_burst_flame()
initial_burst = FALSE
@@ -683,12 +690,12 @@ GLOBAL_LIST_EMPTY(flamer_particles)
var/damage = burnlevel*delta_time
T.flamer_fire_act(damage)
- update_flame()
-
if(!firelevel)
qdel(src)
return
+ update_flame()
+
for(var/atom/thing in loc)
thing.handle_flamer_fire(src, damage, delta_time)
@@ -703,7 +710,7 @@ GLOBAL_LIST_EMPTY(flamer_particles)
var/area/A = get_area(src)
if(!A)
return
- if(SSweather.is_weather_event && locate(A.master) in SSweather.weather_areas)
+ if(SSweather.is_weather_event && locate(A) in SSweather.weather_areas)
weather_smothering_strength = SSweather.weather_event_instance.fire_smothering_strength
else
weather_smothering_strength = 0
diff --git a/code/modules/projectiles/guns/misc.dm b/code/modules/projectiles/guns/misc.dm
index 373587ff881a..5503ab03a1da 100644
--- a/code/modules/projectiles/guns/misc.dm
+++ b/code/modules/projectiles/guns/misc.dm
@@ -4,7 +4,7 @@
/obj/item/weapon/gun/minigun
name = "\improper Ol' Painless"
desc = "An enormous multi-barreled rotating gatling gun. This thing will no doubt pack a punch."
- icon = 'icons/obj/items/weapons/guns/guns_by_faction/upp.dmi'
+ icon = 'icons/obj/items/weapons/guns/guns_by_faction/event.dmi'
icon_state = "painless"
item_state = "painless"
@@ -159,6 +159,125 @@
return FALSE
+/obj/item/weapon/gun/pkp
+ name = "\improper QYJ-72 General Purpose Machine Gun"
+ desc = "The QYJ-72 is the standard GPMG of the Union of Progressive Peoples, chambered in 7.62x54mmR, it fires a hard-hitting cartridge with a high rate of fire. With an extremely large box at 250 rounds, the QJY-72 is designed with suppressing fire and accuracy by volume of fire at its forefront. \nAlt-click it to open the feed cover and allow for reloading."
+ icon = 'icons/obj/items/weapons/guns/guns_by_faction/upp.dmi'
+ icon_state = "qjy72"
+ item_state = "qjy72"
+
+ fire_sound = 'sound/weapons/gun_mg.ogg'
+ cocked_sound = 'sound/weapons/gun_m60_cocked.ogg'
+ current_mag = /obj/item/ammo_magazine/pkp
+ w_class = SIZE_LARGE
+ force = 30 //the image of a upp machinegunner beating someone to death with a gpmg makes me laugh
+ start_semiauto = FALSE
+ start_automatic = TRUE
+ flags_gun_features = GUN_WIELDED_FIRING_ONLY|GUN_CAN_POINTBLANK|GUN_AUTO_EJECTOR|GUN_SPECIALIST|GUN_AMMO_COUNTER
+ gun_category = GUN_CATEGORY_HEAVY
+ attachable_allowed = list(
+ /obj/item/attachable/pkpbarrel,
+ /obj/item/attachable/stock/pkpstock,
+ )
+ var/cover_open = FALSE //if the gun's feed-cover is open or not.
+
+
+/obj/item/weapon/gun/pkp/handle_starting_attachment()
+ ..()
+ var/obj/item/attachable/attachie = new /obj/item/attachable/pkpbarrel(src)
+ attachie.flags_attach_features &= ~ATTACH_REMOVABLE
+ attachie.Attach(src)
+ update_attachable(attachie.slot)
+
+ var/obj/item/attachable/pkpstock = new /obj/item/attachable/stock/pkpstock(src)
+ pkpstock.flags_attach_features &= ~ATTACH_REMOVABLE
+ pkpstock.Attach(src)
+ update_attachable(pkpstock.slot)
+
+ //invisible mag harness
+ var/obj/item/attachable/magnetic_harness/Integrated = new(src)
+ Integrated.hidden = TRUE
+ Integrated.flags_attach_features &= ~ATTACH_REMOVABLE
+ Integrated.Attach(src)
+ update_attachable(Integrated.slot)
+
+/obj/item/weapon/gun/pkp/Initialize(mapload, spawn_empty)
+ . = ..()
+ if(current_mag && current_mag.current_rounds > 0)
+ load_into_chamber()
+
+/obj/item/weapon/gun/pkp/set_gun_attachment_offsets()
+ attachable_offset = list("muzzle_x" = 34, "muzzle_y" = 18,"rail_x" = 5, "rail_y" = 5, "under_x" = 39, "under_y" = 7, "stock_x" = 10, "stock_y" = 13)
+
+
+/obj/item/weapon/gun/pkp/set_gun_config_values()
+ ..()
+ fire_delay = FIRE_DELAY_TIER_10
+ burst_amount = BURST_AMOUNT_TIER_6
+ burst_delay = FIRE_DELAY_TIER_9
+ accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
+ accuracy_mult_unwielded = BASE_ACCURACY_MULT
+ fa_max_scatter = SCATTER_AMOUNT_TIER_8
+ scatter = SCATTER_AMOUNT_TIER_10
+ burst_scatter_mult = SCATTER_AMOUNT_TIER_8
+ scatter_unwielded = SCATTER_AMOUNT_TIER_10
+ damage_mult = BASE_BULLET_DAMAGE_MULT
+ recoil = RECOIL_AMOUNT_TIER_5
+ empty_sound = 'sound/weapons/gun_empty.ogg'
+
+/obj/item/weapon/gun/pkp/clicked(mob/user, list/mods)
+ if(!mods["alt"] || !CAN_PICKUP(user, src))
+ return ..()
+ else
+ if(!locate(src) in list(user.get_active_hand(), user.get_inactive_hand()))
+ return TRUE
+ if(user.get_active_hand() && user.get_inactive_hand())
+ to_chat(user, SPAN_WARNING("You can't do that with your hands full!"))
+ return TRUE
+ if(!cover_open)
+ playsound(src.loc, 'sound/handling/smartgun_open.ogg', 50, TRUE, 3)
+ to_chat(user, SPAN_NOTICE("You open [src]'s feed cover, allowing the belt to be removed."))
+ cover_open = TRUE
+ else
+ playsound(src.loc, 'sound/handling/smartgun_close.ogg', 50, TRUE, 3)
+ to_chat(user, SPAN_NOTICE("You close [src]'s feed cover."))
+ cover_open = FALSE
+ update_icon()
+ return TRUE
+
+/obj/item/weapon/gun/pkp/replace_magazine(mob/user, obj/item/ammo_magazine/magazine)
+ if(!cover_open)
+ to_chat(user, SPAN_WARNING("[src]'s feed cover is closed! You can't put a new belt in! (alt-click to open it)"))
+ return
+ return ..()
+
+/obj/item/weapon/gun/pkp/unload(mob/user, reload_override, drop_override, loc_override)
+ if(!cover_open)
+ to_chat(user, SPAN_WARNING("[src]'s feed cover is closed! You can't take out the belt! (alt-click to open it)"))
+ return
+ return ..()
+
+/obj/item/weapon/gun/pkp/update_icon()
+ . = ..()
+ if(cover_open)
+ overlays += "+[base_gun_icon]_cover_open"
+ else
+ overlays += "+[base_gun_icon]_cover_closed"
+
+/obj/item/weapon/gun/pkp/able_to_fire(mob/living/user)
+ . = ..()
+ if(.)
+ if(cover_open)
+ to_chat(user, SPAN_WARNING("You can't fire [src] with the feed cover open! (alt-click to close)"))
+ return FALSE
+ if(!skillcheck(user, SKILL_FIREARMS, SKILL_FIREARMS_TRAINED))
+ to_chat(user, SPAN_WARNING("You don't seem to know how to use [src]..."))
+ return 0
+ if(!skillcheck(user, SKILL_SPEC_WEAPONS, SKILL_SPEC_ALL) && user.skills.get_skill_level(SKILL_SPEC_WEAPONS) != SKILL_SPEC_UPP)
+ to_chat(user, SPAN_WARNING("You don't seem to know how to use [src]..."))
+ return 0
+
+
/obj/effect/syringe_gun_dummy
name = ""
desc = ""
diff --git a/code/modules/projectiles/guns/pistols.dm b/code/modules/projectiles/guns/pistols.dm
index e2985df6a12a..c17ca5bca739 100644
--- a/code/modules/projectiles/guns/pistols.dm
+++ b/code/modules/projectiles/guns/pistols.dm
@@ -258,66 +258,132 @@
icon_state = "g_deagle"
item_state = "g_deagle"
base_gun_icon = "g_deagle"
+
//-------------------------------------------------------
-//MAUSER MERC PISTOL //Inspired by the Makarov, specifically the "PB" version, an integrally silenced Makarov.
-//Rebalanced: Now acts like an UPP M4A3.
+//NP92 pistol
+//Its a makarov
+
+/obj/item/weapon/gun/pistol/np92
+ name = "\improper NP92 pistol"
+ desc = "The standard issue sidearm of the UPP. The NP92 is a small but powerful sidearm, well-liked by most it is issued to, although some prefer the weapon it was meant to replace, the Type 73. Takes 12 round magazines."
+ icon = 'icons/obj/items/weapons/guns/guns_by_faction/upp.dmi'
+ icon_state = "np92"
+ item_state = "np92"
+ fire_sound = "88m4"
+ current_mag = /obj/item/ammo_magazine/pistol/np92
+ flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK|GUN_ONE_HAND_WIELDED|GUN_AMMO_COUNTER
+ attachable_allowed = list(
+ /obj/item/attachable/suppressor,
+ /obj/item/attachable/reddot,
+ /obj/item/attachable/reflex,
+ /obj/item/attachable/flashlight,
+ )
+
+/obj/item/weapon/gun/pistol/np92/set_gun_attachment_offsets()
+ attachable_offset = list("muzzle_x" = 27, "muzzle_y" = 20,"rail_x" = 13, "rail_y" = 22, "under_x" = 21, "under_y" = 18, "stock_x" = 21, "stock_y" = 18)
+
+/obj/item/weapon/gun/pistol/np92/set_gun_config_values()
+ ..()
+ set_fire_delay(FIRE_DELAY_TIER_12)
+ accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_5
+ accuracy_mult_unwielded = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_5
+ scatter = SCATTER_AMOUNT_TIER_6
+ burst_scatter_mult = SCATTER_AMOUNT_TIER_6
+ scatter_unwielded = SCATTER_AMOUNT_TIER_6
+ damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_3
-/obj/item/weapon/gun/pistol/c99
- name = "\improper Korovin PK-9 pistol"
- desc = "The Korovin PK-9 is a cheap, robust and reliable sidearm, its design is strongly inspired by the classic ancient Makarov pistol. Commonly used by many groups, mostly those worried about cost."
+/obj/item/weapon/gun/pistol/np92/suppressed
+ name = "\improper NPZ92 pistol"
+ desc = "The NPZ92 is a version of the NP92 that includes an integrated suppressor, issued sparingly to Kommando units."
icon = 'icons/obj/items/weapons/guns/guns_by_faction/upp.dmi'
- icon_state = "pk9"
- item_state = "pk9"
+ icon_state = "npz92"
+ item_state = "npz92"
inherent_traits = list(TRAIT_GUN_SILENCED)
- fire_sound = 'sound/weapons/gun_c99.ogg'
- current_mag = /obj/item/ammo_magazine/pistol/c99
- flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK|GUN_ONE_HAND_WIELDED
+ fire_sound = "gun_silenced"
+ current_mag = /obj/item/ammo_magazine/pistol/np92/suppressed
+ flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK|GUN_ONE_HAND_WIELDED|GUN_AMMO_COUNTER
+ attachable_allowed = list(
+ /obj/item/attachable/reddot,
+ /obj/item/attachable/reflex,
+ /obj/item/attachable/flashlight,
+ )
+
+/obj/item/weapon/gun/pistol/np92/suppressed/tranq
+ current_mag = /obj/item/ammo_magazine/pistol/np92/tranq
+
+//-------------------------------------------------------
+//Type 73 pistol
+//Its a TT
+
+/obj/item/weapon/gun/pistol/t73
+ name = "\improper Type 73 pistol"
+ desc = "The Type 73 is the once-standard issue sidearm of the UPP. Replaced by the NP92 in UPP use, it remains popular with veteran UPP troops due to familiarity and extra power. Due to an extremely large amount being produced, they tend to end up in the hands of forces attempting to arm themselves on a budget. Users include the Union of Progressive Peoples, Colonial Liberation Front, and just about any mercenary or pirate group out there."
+ icon = 'icons/obj/items/weapons/guns/guns_by_faction/upp.dmi'
+ icon_state = "tt"
+ item_state = "tt"
+ fire_sound = 'sound/weapons/gun_tt.ogg'
+ current_mag = /obj/item/ammo_magazine/pistol/t73
+ flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK|GUN_ONE_HAND_WIELDED|GUN_AMMO_COUNTER
attachable_allowed = list(
/obj/item/attachable/reddot,
/obj/item/attachable/reflex,
/obj/item/attachable/flashlight,
/obj/item/attachable/lasersight,
- /obj/item/attachable/burstfire_assembly,
+ /obj/item/attachable/suppressor,
)
-/obj/item/weapon/gun/pistol/c99/set_gun_attachment_offsets()
- attachable_offset = list("muzzle_x" = 30, "muzzle_y" = 19,"rail_x" = 10, "rail_y" = 22, "under_x" = 21, "under_y" = 18, "stock_x" = 21, "stock_y" = 18)
+/obj/item/weapon/gun/pistol/t73/set_gun_attachment_offsets()
+ attachable_offset = list("muzzle_x" = 28, "muzzle_y" = 20,"rail_x" = 13, "rail_y" = 22, "under_x" = 22, "under_y" = 15, "stock_x" = 21, "stock_y" = 18)
-/obj/item/weapon/gun/pistol/c99/set_gun_config_values()
+/obj/item/weapon/gun/pistol/t73/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_12)
- accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
- accuracy_mult_unwielded = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
+ set_fire_delay(FIRE_DELAY_TIER_11)
+ accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_5
+ accuracy_mult_unwielded = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_5
scatter = SCATTER_AMOUNT_TIER_6
burst_scatter_mult = SCATTER_AMOUNT_TIER_6
scatter_unwielded = SCATTER_AMOUNT_TIER_6
- damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_7
+ damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_6
-/obj/item/weapon/gun/pistol/c99/upp
- desc = "The Korovin PK-9 is a cheap, robust and reliable sidearm, its design is strongly inspired by the classic ancient Makarov pistol. This version has been refitted for military usage by the UPP."
- icon_state = "pk9u"
- item_state = "pk9u"
-/obj/item/weapon/gun/pistol/c99/upp/tranq
- desc = "The Korovin PK-9 is a cheap, robust and reliable sidearm, its design strongly inspired by the classic ancient Makarov pistol. This version contains a customized exterior, an integrated laser and reflex sight, and is noticeably easy to handle."
- icon_state = "pk9r"
- item_state = "pk9r"
- current_mag = /obj/item/ammo_magazine/pistol/c99/tranq
- aim_slowdown = 0
- wield_delay = WIELD_DELAY_MIN
+/obj/item/weapon/gun/pistol/t73/leader
+ name = "\improper Type 74 pistol"
+ desc = "The Type 74 is the designation for a specially modified Type 73 with an integrated laser sight system, multiple lightning cuts to reduce weight in order to allow a higher pressure round to be used with the same recoil sping, and a more comfortable grip. Due to the adoption of the NP92, the Type 74 was produced in limited numbers, because of this it is typically only issued on request to high-ranking officers."
+ icon = 'icons/obj/items/weapons/guns/guns_by_faction/upp.dmi'
+ icon_state = "ttb"
+ item_state = "ttb"
+ current_mag = /obj/item/ammo_magazine/pistol/t73_impact
+ flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK|GUN_ONE_HAND_WIELDED|GUN_AMMO_COUNTER
+ accepted_ammo = list(
+ /obj/item/ammo_magazine/pistol/t73,
+ /obj/item/ammo_magazine/pistol/t73_impact,
+ )
+ attachable_allowed = list(
+ /obj/item/attachable/reddot,
+ /obj/item/attachable/reflex,
+ /obj/item/attachable/flashlight,
+ /obj/item/attachable/suppressor,
+ /obj/item/attachable/heavy_barrel,
+ )
-/obj/item/weapon/gun/pistol/c99/upp/tranq/handle_starting_attachment()
+/obj/item/weapon/gun/pistol/t73/leader/handle_starting_attachment()
..()
- var/obj/item/attachable/lasersight/LS = new(src)
- LS.flags_attach_features &= ~ATTACH_REMOVABLE
- LS.Attach(src)
- update_attachable(LS.slot)
+ var/obj/item/attachable/lasersight/TT = new(src)
+ TT.flags_attach_features &= ~ATTACH_REMOVABLE
+ TT.hidden = TRUE
+ TT.Attach(src)
+ update_attachable(TT.slot)
- var/obj/item/attachable/reflex/RX = new(src)
- RX.flags_attach_features &= ~ATTACH_REMOVABLE
- RX.Attach(src)
- update_attachable(RX.slot)
+/obj/item/weapon/gun/pistol/t73/leader/set_gun_config_values()
+ ..()
+ set_fire_delay(FIRE_DELAY_TIER_11)
+ accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_6
+ accuracy_mult_unwielded = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_6
+ scatter = SCATTER_AMOUNT_TIER_7
+ burst_scatter_mult = SCATTER_AMOUNT_TIER_6
+ scatter_unwielded = SCATTER_AMOUNT_TIER_7
+ damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_6
//-------------------------------------------------------
//KT-42 //Inspired by the .44 Auto Mag pistol
@@ -770,7 +836,7 @@ It is a modified Beretta 93R, and can fire three-round burst or single fire. Whe
/obj/item/weapon/gun/pistol/skorpion
name = "\improper CZ-81 machine pistol"
desc = "A robust, 20th century firearm that's a combination of pistol and submachinegun. Fires .32ACP caliber rounds from a 20-round magazine."
- icon = 'icons/obj/items/weapons/guns/guns_by_faction/upp.dmi'
+ icon = 'icons/obj/items/weapons/guns/guns_by_faction/colony.dmi'
icon_state = "skorpion"
item_state = "skorpion"
@@ -798,36 +864,8 @@ It is a modified Beretta 93R, and can fire three-round burst or single fire. Whe
..()
set_fire_delay(FIRE_DELAY_TIER_11)
fa_scatter_peak = 15 //shots
- fa_max_scatter = SCATTER_AMOUNT_TIER_4
-
- accuracy_mult = BASE_ACCURACY_MULT
- scatter = SCATTER_AMOUNT_TIER_6
- damage_mult = BASE_BULLET_DAMAGE_MULT
-
-/obj/item/weapon/gun/pistol/skorpion/upp
- desc = "A robust, 20th century firearm modernized for the 23rd century. Fires .32ACP caliber rounds from a 20-round magazine."
- icon_state = "skorpion_u"
- item_state = "skorpion_u"
-
-/obj/item/weapon/gun/pistol/skorpion/upp/medic
- random_spawn_chance = 100
- random_rail_chance = 70
- random_spawn_rail = list(
- /obj/item/attachable/reflex,
- /obj/item/attachable/flashlight,
- )
- random_muzzle_chance = 50
- random_spawn_muzzle = list(
- /obj/item/attachable/suppressor,
- )
- random_under_chance = 60
- random_spawn_under = list(
- /obj/item/attachable/lasersight,
- )
-
-/obj/item/weapon/gun/pistol/skorpion/set_gun_config_values()
- ..()
fa_max_scatter = SCATTER_AMOUNT_TIER_5
+ accuracy_mult = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_7
damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_2
diff --git a/code/modules/projectiles/guns/revolvers.dm b/code/modules/projectiles/guns/revolvers.dm
index 7a8782f34d7d..7f89e652ef4e 100644
--- a/code/modules/projectiles/guns/revolvers.dm
+++ b/code/modules/projectiles/guns/revolvers.dm
@@ -440,14 +440,20 @@
//-------------------------------------------------------
//RUSSIAN REVOLVER //Based on the 7.62mm Russian revolvers.
-/obj/item/weapon/gun/revolver/nagant
- name = "\improper N-Y 7.62mm revolver"
- desc = "The Nagant-Yamasaki 7.62 is an effective killing machine designed by a consortion of shady Not-Americans. It is frequently found in the hands of criminals or mercenaries."
+/obj/item/weapon/gun/revolver/upp
+ name = "\improper ZHNK-72 revolver"
+ desc = "The ZHNK-72 is a UPP designed revolver. The ZHNK-72 is used by the UPP armed forces in a policing role as well as limited numbers in the hands of SNCOs."
icon = 'icons/obj/items/weapons/guns/guns_by_faction/upp.dmi'
- icon_state = "ny762"
- item_state = "ny762"
+ icon_state = "zhnk72"
+ item_state = "zhnk72"
- fire_sound = 'sound/weapons/gun_pistol_medium.ogg'
+ fire_sound = "gun_pkd" //sounds stolen from bladerunner revolvers bc they arent used and sound awesome
+ fire_rattle = 'sound/weapons/gun_pkd_fire01_rattle.ogg'
+ reload_sound = 'sound/weapons/handling/pkd_speed_load.ogg'
+ cocked_sound = 'sound/weapons/handling/pkd_cock.wav'
+ unload_sound = 'sound/weapons/handling/pkd_open_chamber.ogg'
+ chamber_close_sound = 'sound/weapons/handling/pkd_close_chamber.ogg'
+ hand_reload_sound = 'sound/weapons/gun_revolver_load3.ogg'
current_mag = /obj/item/ammo_magazine/internal/revolver/upp
force = 8
attachable_allowed = list(
@@ -460,23 +466,22 @@
/obj/item/attachable/bayonet/upp,
/obj/item/attachable/heavy_barrel,
/obj/item/attachable/extended_barrel,
- /obj/item/attachable/compensator,
/obj/item/attachable/lasersight, // Underbarrel
)
-/obj/item/weapon/gun/revolver/nagant/set_gun_attachment_offsets()
- attachable_offset = list("muzzle_x" = 28, "muzzle_y" = 21,"rail_x" = 14, "rail_y" = 23, "under_x" = 24, "under_y" = 19, "stock_x" = 24, "stock_y" = 19)
+/obj/item/weapon/gun/revolver/upp/set_gun_attachment_offsets()
+ attachable_offset = list("muzzle_x" = 28, "muzzle_y" = 21,"rail_x" = 14, "rail_y" = 23, "under_x" = 19, "under_y" = 17, "stock_x" = 24, "stock_y" = 19)
-/obj/item/weapon/gun/revolver/nagant/set_gun_config_values()
+/obj/item/weapon/gun/revolver/upp/set_gun_config_values()
..()
set_fire_delay(FIRE_DELAY_TIER_9)
accuracy_mult = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_6
- damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_1
+ damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_4
recoil = 0
recoil_unwielded = 0
-/obj/item/weapon/gun/revolver/nagant/shrapnel
+/obj/item/weapon/gun/revolver/upp/shrapnel
current_mag = /obj/item/ammo_magazine/internal/revolver/upp/shrapnel
random_spawn_chance = 100
random_under_chance = 100
diff --git a/code/modules/projectiles/guns/rifles.dm b/code/modules/projectiles/guns/rifles.dm
index 18ffb082217c..167fb2c66809 100644
--- a/code/modules/projectiles/guns/rifles.dm
+++ b/code/modules/projectiles/guns/rifles.dm
@@ -75,6 +75,7 @@
flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER
starting_attachment_types = list(/obj/item/attachable/attached_gun/grenade, /obj/item/attachable/stock/rifle/collapsible)
map_specific_decoration = TRUE
+ start_automatic = TRUE
/obj/item/weapon/gun/rifle/m41a/set_gun_attachment_offsets()
attachable_offset = list("muzzle_x" = 32, "muzzle_y" = 18,"rail_x" = 12, "rail_y" = 23, "under_x" = 24, "under_y" = 13, "stock_x" = 24, "stock_y" = 13)
@@ -88,7 +89,6 @@
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4 + 2*HIT_ACCURACY_MULT_TIER_1
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_7
scatter = SCATTER_AMOUNT_TIER_8
- //fa_scatter_peak = FULL_AUTO_SCATTER_PEAK_TIER_8 //Zonenote
burst_scatter_mult = SCATTER_AMOUNT_TIER_10
scatter_unwielded = SCATTER_AMOUNT_TIER_2
damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_2
@@ -150,6 +150,7 @@
/obj/item/attachable/attached_gun/flamer/advanced,
)
start_semiauto = FALSE
+ start_automatic = TRUE
/obj/item/weapon/gun/rifle/nsg23/Initialize(mapload, spawn_empty)
. = ..()
@@ -171,6 +172,7 @@
damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_8
recoil_unwielded = RECOIL_AMOUNT_TIER_2
damage_falloff_mult = 0
+ fa_max_scatter = SCATTER_AMOUNT_TIER_5
/obj/item/weapon/gun/rifle/nsg23/handle_starting_attachment()
..()
@@ -383,6 +385,7 @@
flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER
starting_attachment_types = list(/obj/item/attachable/attached_gun/grenade/mk1, /obj/item/attachable/stock/rifle/collapsible)
+ start_automatic = TRUE
/obj/item/weapon/gun/rifle/m41aMK1/set_gun_attachment_offsets()
attachable_offset = list("muzzle_x" = 32, "muzzle_y" = 18,"rail_x" = 12, "rail_y" = 23, "under_x" = 23, "under_y" = 13, "stock_x" = 24, "stock_y" = 14)
@@ -528,6 +531,7 @@
scatter_unwielded = SCATTER_AMOUNT_TIER_2
damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_3
recoil_unwielded = RECOIL_AMOUNT_TIER_2
+ fa_max_scatter = SCATTER_AMOUNT_TIER_7
/obj/item/weapon/gun/rifle/m46c/able_to_fire(mob/user)
. = ..()
@@ -633,9 +637,11 @@
if(iff_enabled)
modify_fire_delay(FIRE_DELAY_TIER_12)
remove_firemode(GUN_FIREMODE_BURSTFIRE)
+ remove_firemode(GUN_FIREMODE_AUTOMATIC)
else
add_firemode(GUN_FIREMODE_BURSTFIRE)
+ add_firemode(GUN_FIREMODE_AUTOMATIC)
/obj/item/weapon/gun/rifle/m46c/proc/name_after_co(mob/living/carbon/human/H)
@@ -719,6 +725,7 @@
)
flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK
+ start_automatic = TRUE
@@ -1232,7 +1239,7 @@
/obj/item/attachable/magnetic_harness,
)
- flags_gun_features = GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER|GUN_WIELDED_FIRING_ONLY
+ flags_gun_features = GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER|GUN_WIELDED_FIRING_ONLY|GUN_SUPPORT_PLATFORM
gun_category = GUN_CATEGORY_HEAVY
/obj/item/weapon/gun/rifle/lmg/set_gun_attachment_offsets()
@@ -1270,6 +1277,8 @@
item_state = "type71"
fire_sound = 'sound/weapons/gun_type71.ogg'
+ reload_sound = 'sound/weapons/handling/m41_reload.ogg'
+ unload_sound = 'sound/weapons/handling/m41_unload.ogg'
current_mag = /obj/item/ammo_magazine/rifle/type71
wield_delay = WIELD_DELAY_FAST
attachable_allowed = list(
@@ -1285,10 +1294,8 @@
/obj/item/attachable/extended_barrel,
/obj/item/attachable/heavy_barrel,
/obj/item/attachable/verticalgrip, // Underbarrel
- /obj/item/attachable/angledgrip,
/obj/item/attachable/flashlight/grip,
/obj/item/attachable/lasersight,
- /obj/item/attachable/bipod,
/obj/item/attachable/burstfire_assembly,
/obj/item/attachable/attached_gun/flamer,
/obj/item/attachable/attached_gun/flamer/advanced,
@@ -1297,13 +1304,14 @@
flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER
flags_equip_slot = SLOT_BACK
+ start_automatic = TRUE
/obj/item/weapon/gun/rifle/type71/set_gun_attachment_offsets()
- attachable_offset = list("muzzle_x" = 32, "muzzle_y" = 18,"rail_x" = 18, "rail_y" = 23, "under_x" = 20, "under_y" = 13, "stock_x" = 24, "stock_y" = 13)
+ attachable_offset = list("muzzle_x" = 33, "muzzle_y" = 17,"rail_x" = 10, "rail_y" = 23, "under_x" = 20, "under_y" = 13, "stock_x" = 11, "stock_y" = 13)
/obj/item/weapon/gun/rifle/type71/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_11)
+ set_fire_delay(FIRE_DELAY_TIER_8)
set_burst_amount(BURST_AMOUNT_TIER_4)
set_burst_delay(FIRE_DELAY_TIER_9)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
@@ -1311,9 +1319,16 @@
scatter = SCATTER_AMOUNT_TIER_6
burst_scatter_mult = SCATTER_AMOUNT_TIER_10
scatter_unwielded = SCATTER_AMOUNT_TIER_4
- damage_mult = BASE_BULLET_DAMAGE_MULT
+ damage_mult = BASE_BULLET_DAMAGE_MULT //10~ more damage than m41, as well as higher ap from bullet, slightly higher DPS, 133>137.5
recoil_unwielded = RECOIL_AMOUNT_TIER_3
+/obj/item/weapon/gun/rifle/type71/handle_starting_attachment()
+ ..()
+ var/obj/item/attachable/stock/type71/STOCK = new(src)
+ STOCK.flags_attach_features &= ~ATTACH_REMOVABLE
+ STOCK.Attach(src)
+ update_attachable(STOCK.slot)
+
/obj/item/weapon/gun/rifle/type71/rifleman
//add GL
random_spawn_chance = 100
@@ -1328,9 +1343,7 @@
)
random_under_chance = 40
random_spawn_under = list(
- /obj/item/attachable/lasersight,
/obj/item/attachable/verticalgrip,
- /obj/item/attachable/angledgrip,
)
/obj/item/weapon/gun/rifle/type71/dual
@@ -1348,7 +1361,6 @@
random_spawn_under = list(
/obj/item/attachable/lasersight,
/obj/item/attachable/verticalgrip,
- /obj/item/attachable/angledgrip,
)
/obj/item/weapon/gun/rifle/type71/sapper
@@ -1367,7 +1379,6 @@
)
random_under_chance = 90
random_spawn_under = list(
- /obj/item/attachable/lasersight,
/obj/item/attachable/attached_gun/extinguisher,
)
@@ -1375,10 +1386,17 @@
name = "\improper Type 71-F pulse rifle"
desc = " This appears to be a less common variant of the Type 71 with an integrated flamethrower that seems especially powerful."
attachable_allowed = list(
- /obj/item/attachable/suppressor,
+ /obj/item/attachable/flashlight, // Rail
+ /obj/item/attachable/magnetic_harness,
+ /obj/item/attachable/scope,
+ /obj/item/attachable/scope/mini,
/obj/item/attachable/reddot,
/obj/item/attachable/reflex,
+ /obj/item/attachable/suppressor, // Muzzle
+ /obj/item/attachable/bayonet,
+ /obj/item/attachable/bayonet/upp,
/obj/item/attachable/extended_barrel,
+ /obj/item/attachable/heavy_barrel,
)
/obj/item/weapon/gun/rifle/type71/flamer/handle_starting_attachment()
@@ -1410,16 +1428,35 @@
aim_slowdown = SLOWDOWN_ADS_QUICK //Carbine is more lightweight
wield_delay = WIELD_DELAY_VERY_FAST
bonus_overlay_x = 2
+ force = 20 //integrated melee mod from stock, which doesn't fit on the gun but is still clearly there on the sprite
+ attachable_allowed = list(
+ /obj/item/attachable/flashlight, // Rail
+ /obj/item/attachable/magnetic_harness,
+ /obj/item/attachable/scope,
+ /obj/item/attachable/scope/mini,
+ /obj/item/attachable/reddot,
+ /obj/item/attachable/reflex,
+ /obj/item/attachable/suppressor, // Muzzle
+ /obj/item/attachable/bayonet,
+ /obj/item/attachable/bayonet/upp,
+ /obj/item/attachable/extended_barrel,
+ /obj/item/attachable/heavy_barrel,
+ /obj/item/attachable/verticalgrip, // Underbarrel
+ /obj/item/attachable/burstfire_assembly,
+ )
random_spawn_muzzle = list() //no default bayonet
/obj/item/weapon/gun/rifle/type71/carbine/set_gun_attachment_offsets()
- attachable_offset = list("muzzle_x" = 30, "muzzle_y" = 18,"rail_x" = 19, "rail_y" = 22, "under_x" = 21, "under_y" = 14, "stock_x" = 24, "stock_y" = 13)
+ attachable_offset = list("muzzle_x" = 33, "muzzle_y" = 17,"rail_x" = 14, "rail_y" = 23, "under_x" = 25, "under_y" = 14, "stock_x" = 24, "stock_y" = 13)
+
+/obj/item/weapon/gun/rifle/type71/carbine/handle_starting_attachment()
+ return //integrated attachment code makes me want to blow my brains out
/obj/item/weapon/gun/rifle/type71/carbine/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_11)
- damage_mult = BASE_BULLET_DAMAGE_MULT - BULLET_DAMAGE_MULT_TIER_2
+ set_fire_delay(FIRE_DELAY_TIER_11)//same fire rate as m41
+ damage_mult = BASE_BULLET_DAMAGE_MULT - BULLET_DAMAGE_MULT_TIER_4//same damage as m41 reg bullets probably
scatter_unwielded = SCATTER_AMOUNT_TIER_5
recoil_unwielded = RECOIL_AMOUNT_TIER_4
@@ -1436,9 +1473,7 @@
)
random_under_chance = 40
random_spawn_under = list(
- /obj/item/attachable/lasersight,
/obj/item/attachable/verticalgrip,
- /obj/item/attachable/angledgrip,
)
/obj/item/weapon/gun/rifle/type71/carbine/commando
@@ -1446,12 +1481,13 @@
desc = "A much rarer variant of the Type 71, this version contains an integrated suppressor, integrated scope, and extensive fine-tuning. Many parts have been replaced, filed down, and improved upon. As a result, this variant is rarely seen outside of commando units."
icon_state = "type73"
item_state = "type73"
+
+ fire_sound = "gun_silenced"
wield_delay = 0 //Ends up being .5 seconds due to scope
- current_mag = /obj/item/ammo_magazine/rifle/type71/heap
+ inherent_traits = list(TRAIT_GUN_SILENCED)
+ current_mag = /obj/item/ammo_magazine/rifle/type71/ap
attachable_allowed = list(
- /obj/item/attachable/lasersight,
/obj/item/attachable/verticalgrip,
- /obj/item/attachable/angledgrip,
)
random_spawn_chance = 0
random_spawn_rail = list()
@@ -1459,24 +1495,23 @@
bonus_overlay_x = 1
bonus_overlay_y = 0
-/obj/item/weapon/gun/rifle/type71/carbine/commando/handle_starting_attachment()//Making the gun have an invisible silencer since it's supposed to have one.
+/obj/item/weapon/gun/rifle/type71/carbine/commando/handle_starting_attachment()
..()
//suppressor
- var/obj/item/attachable/suppressor/S = new(src)
- S.hidden = TRUE
- S.flags_attach_features &= ~ATTACH_REMOVABLE
- S.Attach(src)
- update_attachable(S.slot)
+ var/obj/item/attachable/type73suppressor/suppressor = new(src)
+ suppressor.flags_attach_features &= ~ATTACH_REMOVABLE
+ suppressor.Attach(src)
+ update_attachable(suppressor.slot)
//scope
- var/obj/item/attachable/scope/mini/F = new(src)
- F.hidden = TRUE
- F.flags_attach_features &= ~ATTACH_REMOVABLE
- F.Attach(src)
- update_attachable(F.slot)
+ var/obj/item/attachable/scope/mini/scope = new(src)
+ scope.hidden = TRUE
+ scope.flags_attach_features &= ~ATTACH_REMOVABLE
+ scope.Attach(src)
+ update_attachable(scope.slot)
/obj/item/weapon/gun/rifle/type71/carbine/commando/set_gun_attachment_offsets()
- attachable_offset = list("muzzle_x" = 30, "muzzle_y" = 19,"rail_x" = 10, "rail_y" = 22, "under_x" = 21, "under_y" = 18, "stock_x" = 21, "stock_y" = 18)
+ attachable_offset = list("muzzle_x" = 35, "muzzle_y" = 17,"rail_x" = 10, "rail_y" = 22, "under_x" = 23, "under_y" = 14, "stock_x" = 21, "stock_y" = 18)
/obj/item/weapon/gun/rifle/type71/carbine/commando/set_gun_config_values()
@@ -1534,7 +1569,7 @@
set_burst_amount(0)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_5
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_4
- damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_6
+ damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_8
recoil_unwielded = RECOIL_AMOUNT_TIER_4
damage_falloff_mult = 0
scatter = SCATTER_AMOUNT_TIER_8
diff --git a/code/modules/projectiles/guns/shotguns.dm b/code/modules/projectiles/guns/shotguns.dm
index a154062c9d10..1cf35623408c 100644
--- a/code/modules/projectiles/guns/shotguns.dm
+++ b/code/modules/projectiles/guns/shotguns.dm
@@ -391,7 +391,7 @@ can cause issues with ammo types getting mixed up during the burst.
starting_attachment_types = list(/obj/item/attachable/stock/type23)
/obj/item/weapon/gun/shotgun/type23/set_gun_attachment_offsets()
- attachable_offset = list("muzzle_x" = 31, "muzzle_y" = 19,"rail_x" = 13, "rail_y" = 21, "under_x" = 24, "under_y" = 15, "stock_x" = 1, "stock_y" = 16)
+ attachable_offset = list("muzzle_x" = 33, "muzzle_y" = 19,"rail_x" = 13, "rail_y" = 21, "under_x" = 24, "under_y" = 15, "stock_x" = -1, "stock_y" = 17)
/obj/item/weapon/gun/shotgun/type23/set_gun_config_values()
..()
@@ -1186,7 +1186,7 @@ can cause issues with ammo types getting mixed up during the burst.
/obj/item/weapon/gun/shotgun/pump/dual_tube
name = "generic dual-tube pump shotgun"
- desc = "A twenty-round pump action shotgun with dual internal tube magazines. You can switch the active internal magazine by toggling burst fire mode."
+ desc = "A twenty-round pump action shotgun with dual internal tube magazines. You can switch the active internal magazine by toggling the shotgun tube."
current_mag = /obj/item/ammo_magazine/internal/shotgun
var/obj/item/ammo_magazine/internal/shotgun/primary_tube
var/obj/item/ammo_magazine/internal/shotgun/secondary_tube
@@ -1220,7 +1220,12 @@ can cause issues with ammo types getting mixed up during the burst.
playsound(src, 'sound/machines/switch.ogg', 15, TRUE)
return TRUE
-/obj/item/weapon/gun/shotgun/pump/dual_tube/set_bursting()
+/obj/item/weapon/gun/shotgun/pump/dual_tube/verb/toggle_tube()
+ set category = "Weapons"
+ set name = "Toggle Shotgun Tube"
+ set desc = "Toggles which shotgun tube your gun loads from."
+ set src = usr.contents
+
var/obj/item/weapon/gun/shotgun/pump/dual_tube/shotgun = get_active_firearm(usr)
if(shotgun == src)
swap_tube(usr)
@@ -1229,7 +1234,7 @@ can cause issues with ammo types getting mixed up during the burst.
/obj/item/weapon/gun/shotgun/pump/dual_tube/cmb
name = "\improper HG 37-12 pump shotgun"
- desc = "A eight-round pump action shotgun with four-round capacity dual internal tube magazines allowing for quick reloading and highly accurate fire. Used exclusively by Colonial Marshals. You can switch the active internal magazine by toggling burst fire mode."
+ desc = "A eight-round pump action shotgun with four-round capacity dual internal tube magazines allowing for quick reloading and highly accurate fire. Used exclusively by Colonial Marshals. You can switch the active internal magazine by toggling the shotgun tube."
icon = 'icons/obj/items/weapons/guns/guns_by_faction/colony.dmi'
icon_state = "hg3712"
item_state = "hg3712"
@@ -1269,7 +1274,7 @@ can cause issues with ammo types getting mixed up during the burst.
/obj/item/weapon/gun/shotgun/pump/dual_tube/cmb/m3717
name = "\improper M37-17 pump shotgun"
- desc = "A military version of the iconic HG 37-12, this design can fit one extra shell in each of its dual-tube internal magazines, and fires shells with increased velocity, resulting in more damage. Issued to select USCM vessels out on the rim. You can switch the active internal magazine by toggling burst fire mode."
+ desc = "A military version of the iconic HG 37-12, this design can fit one extra shell in each of its dual-tube internal magazines, and fires shells with increased velocity, resulting in more damage. Issued to select USCM vessels out on the rim. You can switch the active internal magazine by toggling the shotgun tube."
icon = 'icons/obj/items/weapons/guns/guns_by_faction/uscm.dmi'
icon_state = "m3717"
item_state = "m3717"
diff --git a/code/modules/projectiles/guns/smgs.dm b/code/modules/projectiles/guns/smgs.dm
index 70b0acb3f2c8..89e6594c64e7 100644
--- a/code/modules/projectiles/guns/smgs.dm
+++ b/code/modules/projectiles/guns/smgs.dm
@@ -20,6 +20,7 @@
flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK
gun_category = GUN_CATEGORY_SMG
+ start_automatic = TRUE
/obj/item/weapon/gun/smg/Initialize(mapload, spawn_empty)
. = ..()
@@ -32,6 +33,7 @@
/obj/item/weapon/gun/smg/set_gun_config_values()
..()
movement_onehanded_acc_penalty_mult = 4
+ fa_max_scatter = SCATTER_AMOUNT_TIER_5
//-------------------------------------------------------
//M39 SMG
@@ -85,6 +87,7 @@
scatter_unwielded = SCATTER_AMOUNT_TIER_4
damage_mult = BASE_BULLET_DAMAGE_MULT
recoil_unwielded = RECOIL_AMOUNT_TIER_5
+ fa_max_scatter = SCATTER_AMOUNT_TIER_10 + 0.5
/obj/item/weapon/gun/smg/m39/training
@@ -270,6 +273,8 @@
scatter_unwielded = SCATTER_AMOUNT_TIER_4
damage_mult = BASE_BULLET_DAMAGE_MULT
recoil_unwielded = RECOIL_AMOUNT_TIER_5
+ fa_max_scatter = SCATTER_AMOUNT_TIER_9
+ fa_scatter_peak = 1 // Seems a bit funny, but it works pretty well in the end
/obj/item/weapon/gun/smg/ppsh/with_drum_mag
current_mag = /obj/item/ammo_magazine/smg/ppsh/extended
@@ -333,6 +338,89 @@
#undef PPSH_UNJAM_CHANCE
+//-------------------------------------------------------
+//Type-19,
+
+/obj/item/weapon/gun/smg/pps43
+ name = "\improper Type-19 Submachinegun" //placeholder
+ desc = "An outdated, but reliable and powerful, submachinegun originating in the Union of Progressive Peoples, it is still in limited service in the UPP but is most often used by paramilitary groups or corporate security forces. It is usually used with a 35 round stick magazine, or a 71 round drum."
+ icon = 'icons/obj/items/weapons/guns/guns_by_faction/upp.dmi'
+ icon_state = "insasu"
+ item_state = "insasu"
+
+ fire_sound = 'sound/weapons/smg_heavy.ogg'
+ current_mag = /obj/item/ammo_magazine/smg/pps43
+ flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER
+ attachable_allowed = list(
+ /obj/item/attachable/suppressor,
+ /obj/item/attachable/reddot,
+ /obj/item/attachable/reflex,
+ /obj/item/attachable/flashlight/grip,
+ /obj/item/attachable/verticalgrip,
+ /obj/item/attachable/lasersight,
+ /obj/item/attachable/flashlight,
+ /obj/item/attachable/extended_barrel,
+ /obj/item/attachable/magnetic_harness,
+ )
+
+/obj/item/weapon/gun/smg/pps43/set_gun_attachment_offsets()
+ attachable_offset = list("muzzle_x" = 33, "muzzle_y" = 20,"rail_x" = 20, "rail_y" = 24, "under_x" = 25, "under_y" = 17, "stock_x" = 26, "stock_y" = 15)
+
+/obj/item/weapon/gun/smg/pps43/set_gun_config_values()
+ ..()
+ fire_delay = FIRE_DELAY_TIER_SMG
+ burst_delay = FIRE_DELAY_TIER_SMG
+ burst_amount = BURST_AMOUNT_TIER_3
+ accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_3
+ accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_5
+ scatter = SCATTER_AMOUNT_TIER_6
+ burst_scatter_mult = SCATTER_AMOUNT_TIER_4
+ scatter_unwielded = SCATTER_AMOUNT_TIER_4
+ damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_4
+ recoil_unwielded = RECOIL_AMOUNT_TIER_5
+
+/obj/item/weapon/gun/smg/pps43/extended_mag
+ current_mag = /obj/item/ammo_magazine/smg/pps43/extended
+//-------------------------------------------------------
+//Type 64
+
+/obj/item/weapon/gun/smg/bizon
+ name = "\improper Type 64 Submachinegun"
+ desc = "The standard submachinegun of the UPP, sporting an unusual 64 round helical magazine, it has a high fire-rate, but is unusually accurate. This one has a faux-wood grip, denoting it as civilian use or as an export model."
+ desc_lore = "The Type 64 finds its way into the hands of more than just UPP soldiers, it has an active life with rebel groups, corporate security forces, mercenaries, less well-armed militaries, and just about everything or everyone in between."
+ icon = 'icons/obj/items/weapons/guns/guns_by_faction/upp.dmi'
+ icon_state = "type64"
+ item_state = "type64"
+
+ fire_sound = 'sound/weapons/smg_heavy.ogg'
+ current_mag = /obj/item/ammo_magazine/smg/bizon
+ flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK|GUN_AMMO_COUNTER
+ wield_delay = WIELD_DELAY_MIN
+ aim_slowdown = SLOWDOWN_ADS_QUICK_MINUS
+
+/obj/item/weapon/gun/smg/bizon/set_gun_attachment_offsets()
+ attachable_offset = list("muzzle_x" = 33, "muzzle_y" = 20,"rail_x" = 18, "rail_y" = 23, "under_x" = 26, "under_y" = 15, "stock_x" = 26, "stock_y" = 15)
+
+/obj/item/weapon/gun/smg/bizon/set_gun_config_values()
+ ..()
+ fire_delay = FIRE_DELAY_TIER_SMG
+ burst_delay = FIRE_DELAY_TIER_SMG
+ burst_amount = BURST_AMOUNT_TIER_4
+ accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_5
+ accuracy_mult_unwielded = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_3
+ scatter = SCATTER_AMOUNT_TIER_9
+ burst_scatter_mult = SCATTER_AMOUNT_TIER_8
+ scatter_unwielded = SCATTER_AMOUNT_TIER_4
+ damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_3
+ recoil_unwielded = RECOIL_AMOUNT_TIER_5
+
+/obj/item/weapon/gun/smg/bizon/upp
+ name = "\improper Type 64 Submachinegun"
+ desc = "The standard submachinegun of the UPP, sporting an unusual 64 round helical magazine, it has a high fire-rate, but is unusually accurate. This one has a black polymer grip, denoting it as in-use by the UPP military."
+ desc_lore = "The Type 64 finds its way into the hands of more than just UPP soldiers, it has an active life with rebel groups, corporate security forces, mercenaries, less well-armed militaries, and just about everything or everyone in between."
+ icon_state = "type64_u"
+ item_state = "type64"
+
//-------------------------------------------------------
//GENERIC UZI //Based on the uzi submachinegun, of course.
@@ -361,7 +449,6 @@
)
wield_delay = WIELD_DELAY_NONE
aim_slowdown = SLOWDOWN_ADS_NONE
- start_automatic = TRUE
/obj/item/weapon/gun/smg/mac15/set_gun_attachment_offsets()
attachable_offset = list("muzzle_x" = 32, "muzzle_y" = 20,"rail_x" = 16, "rail_y" = 22, "under_x" = 22, "under_y" = 16, "stock_x" = 22, "stock_y" = 16)
@@ -410,7 +497,6 @@
)
wield_delay = WIELD_DELAY_MIN
aim_slowdown = SLOWDOWN_ADS_QUICK
- start_automatic = TRUE
var/jammed = FALSE
/obj/item/weapon/gun/smg/uzi/set_gun_attachment_offsets()
@@ -567,6 +653,7 @@
flags_gun_features = GUN_AUTO_EJECTOR|GUN_CAN_POINTBLANK
gun_category = GUN_CATEGORY_SMG
civilian_usable_override = TRUE
+ start_automatic = FALSE
var/nailing_speed = 2 SECONDS //Time to apply a sheet for patching. Also haha name. Try to keep sync with soundbyte duration
var/repair_sound = 'sound/weapons/nailgun_repair_long.ogg'
diff --git a/code/modules/projectiles/guns/souto.dm b/code/modules/projectiles/guns/souto.dm
index 8d7a1b2550a4..6f45f57e1d61 100644
--- a/code/modules/projectiles/guns/souto.dm
+++ b/code/modules/projectiles/guns/souto.dm
@@ -14,6 +14,8 @@
var/obj/item/storage/backpack/souto/soutopack
current_mag = null
auto_retrieval_slot = WEAR_IN_BACK
+ start_automatic = TRUE
+ autofire_slow_mult = 0.8 //Fires FASTER when in Full Auto, that is the power of Souta
/obj/item/weapon/gun/souto/set_gun_config_values()
. = ..()
diff --git a/code/modules/projectiles/guns/specialist.dm b/code/modules/projectiles/guns/specialist.dm
index 7152106869a9..7708032c5436 100644
--- a/code/modules/projectiles/guns/specialist.dm
+++ b/code/modules/projectiles/guns/specialist.dm
@@ -267,11 +267,15 @@
if(toggling_action)
toggling_action.update_button_icon()
-/obj/item/weapon/gun/rifle/sniper/set_bursting(mob/user)
- if(has_aimed_shot)
- toggle_laser(user)
- else
- ..()
+/obj/item/weapon/gun/rifle/sniper/verb/toggle_gun_laser()
+ set category = "Weapons"
+ set name = "Toggle Laser"
+ set desc = "Toggles your laser on or off."
+ set src = usr.contents
+
+ var/obj/item/weapon/gun/rifle/sniper/sniper = get_active_firearm(usr)
+ if((sniper == src) && has_aimed_shot)
+ toggle_laser(usr)
//Pow! Headshot.
/obj/item/weapon/gun/rifle/sniper/M42A
@@ -446,73 +450,56 @@
step(PMC_sniper,turn(PMC_sniper.dir,180))
PMC_sniper.apply_effect(5, WEAKEN)
-//SVD //Based on the actual Dragunov DMR rifle.
+//Type 88 //Based on the actual Dragunov DMR rifle.
/obj/item/weapon/gun/rifle/sniper/svd
- name = "\improper SVD Dragunov-033 designated marksman rifle"
- desc = "A wannabe replica of an SVD, constructed from a MAR-40 by someone probably illiterate that thought the original SVD was built from an AK pattern. Fires 7.62x54mmR rounds."
+ name = "\improper Type 88 designated marksman rifle"
+ desc = "The standard issue DMR of the UPP, the Type 88 is sought after by competitive shooters and terrorists alike for its high degree of accuracy. Typically loaded with armor-piercing 7.62x54mmR rounds in a 12 round magazine."
icon = 'icons/obj/items/weapons/guns/guns_by_faction/upp.dmi'
- icon_state = "svd003"
- item_state = "svd003" //NEEDS A ONE HANDED STATE
+ icon_state = "type88"
+ item_state = "type88"
- fire_sound = 'sound/weapons/gun_kt42.ogg'
+ fire_sound = 'sound/weapons/gun_mg.ogg'
current_mag = /obj/item/ammo_magazine/sniper/svd
attachable_allowed = list(
//Muzzle,
/obj/item/attachable/bayonet,
/obj/item/attachable/bayonet/upp_replica,
/obj/item/attachable/bayonet/upp,
- /obj/item/attachable/extended_barrel,
- /obj/item/attachable/heavy_barrel,
- //Barrel,
- /obj/item/attachable/slavicbarrel,
- //Rail,
- /obj/item/attachable/reddot,
- /obj/item/attachable/reflex,
- /obj/item/attachable/flashlight,
- /obj/item/attachable/magnetic_harness,
- /obj/item/attachable/scope,
- /obj/item/attachable/scope/variable_zoom,
- /obj/item/attachable/scope/variable_zoom/slavic,
- /obj/item/attachable/scope/mini,
- /obj/item/attachable/scope/slavic,
//Under,
/obj/item/attachable/verticalgrip,
- /obj/item/attachable/angledgrip,
- /obj/item/attachable/lasersight,
/obj/item/attachable/bipod,
- //Stock,
- /obj/item/attachable/stock/slavic,
+ //Integrated,
+ /obj/item/attachable/type88_barrel,
)
has_aimed_shot = FALSE
- flags_gun_features = GUN_AUTO_EJECTOR|GUN_WIELDED_FIRING_ONLY
- starting_attachment_types = list(/obj/item/attachable/scope/variable_zoom/slavic)
+ flags_gun_features = GUN_AUTO_EJECTOR|GUN_WIELDED_FIRING_ONLY|GUN_AMMO_COUNTER|GUN_CAN_POINTBLANK
+ starting_attachment_types = list()
sniper_beam_type = null
skill_locked = FALSE
/obj/item/weapon/gun/rifle/sniper/svd/handle_starting_attachment()
..()
- var/obj/item/attachable/attachie = new /obj/item/attachable/slavicbarrel(src)
+ var/obj/item/attachable/attachie = new /obj/item/attachable/type88_barrel(src)
attachie.flags_attach_features &= ~ATTACH_REMOVABLE
attachie.Attach(src)
update_attachable(attachie.slot)
- attachie = new /obj/item/attachable/stock/slavic(src)
- attachie.flags_attach_features &= ~ATTACH_REMOVABLE
- attachie.Attach(src)
- update_attachable(attachie.slot)
+ var/obj/item/attachable/scope/variable_zoom/integrated/type88sight = new(src)
+ type88sight.flags_attach_features &= ~ATTACH_REMOVABLE
+ type88sight.hidden = TRUE
+ type88sight.Attach(src)
+ update_attachable(type88sight.slot)
/obj/item/weapon/gun/rifle/sniper/svd/set_gun_attachment_offsets()
- attachable_offset = list("muzzle_x" = 32, "muzzle_y" = 17,"rail_x" = 13, "rail_y" = 19, "under_x" = 24, "under_y" = 13, "stock_x" = 24, "stock_y" = 13)
+ attachable_offset = list("muzzle_x" = 32, "muzzle_y" = 17,"rail_x" = 13, "rail_y" = 19, "under_x" = 26, "under_y" = 14, "stock_x" = 24, "stock_y" = 13, "special_x" = 39, "special_y" = 18)
/obj/item/weapon/gun/rifle/sniper/svd/set_gun_config_values()
..()
set_fire_delay(FIRE_DELAY_TIER_6)
- set_burst_amount(BURST_AMOUNT_TIER_2)
- set_burst_delay(FIRE_DELAY_TIER_11)
- accuracy_mult = BASE_ACCURACY_MULT
+ set_burst_amount(BURST_AMOUNT_TIER_1)
+ accuracy_mult = BASE_ACCURACY_MULT * 3
scatter = SCATTER_AMOUNT_TIER_8
- burst_scatter_mult = SCATTER_AMOUNT_TIER_6
damage_mult = BASE_BULLET_DAMAGE_MULT
recoil = RECOIL_AMOUNT_TIER_5
damage_falloff_mult = 0
@@ -580,7 +567,7 @@
/obj/item/weapon/gun/rifle/m4ra_custom/set_gun_attachment_offsets()
- attachable_offset = list("muzzle_x" = 43, "muzzle_y" = 17,"rail_x" = 23, "rail_y" = 21, "under_x" = 30, "under_y" = 11, "stock_x" = 24, "stock_y" = 13, "special_x" = 39, "special_y" = 17)
+ attachable_offset = list("muzzle_x" = 43, "muzzle_y" = 17,"rail_x" = 23, "rail_y" = 21, "under_x" = 30, "under_y" = 11, "stock_x" = 24, "stock_y" = 13, "special_x" = 37, "special_y" = 16)
/obj/item/weapon/gun/rifle/m4ra_custom/set_gun_config_values()
..()
@@ -1332,6 +1319,56 @@
qdel(src)
user.put_in_active_hand(F)
+//-------------------------------------------------------
+//UPP Rocket Launcher
+
+/obj/item/weapon/gun/launcher/rocket/upp
+ name = "\improper HJRA-12 Handheld Anti-Tank Grenade Launcher"
+ desc = "The HJRA-12 Handheld Anti-Tank Grenade Launcher is the standard Anti-Armor weapon of the UPP. It is designed to be easy to use and to take out or disable armored vehicles."
+ icon = 'icons/obj/items/weapons/guns/guns_by_faction/upp.dmi'
+ icon_state = "hjra12"
+ item_state = "hjra12"
+ skill_locked = FALSE
+ current_mag = /obj/item/ammo_magazine/rocket/upp/at
+
+ attachable_allowed = list(/obj/item/attachable/upp_rpg_breech)
+
+ flags_gun_features = GUN_WIELDED_FIRING_ONLY
+
+ flags_item = TWOHANDED
+
+/obj/item/weapon/gun/launcher/rocket/upp/set_gun_attachment_offsets()
+ attachable_offset = list("muzzle_x" = 33, "muzzle_y" = 18,"rail_x" = 6, "rail_y" = 19, "under_x" = 19, "under_y" = 14, "stock_x" = -6, "stock_y" = 16, "special_x" = 37, "special_y" = 16)
+
+/obj/item/weapon/gun/launcher/rocket/upp/handle_starting_attachment()
+ ..()
+ var/obj/item/attachable/upp_rpg_breech/S = new(src)
+ S.flags_attach_features &= ~ATTACH_REMOVABLE
+ S.Attach(src)
+ update_attachables()
+
+ var/obj/item/attachable/magnetic_harness/Integrated = new(src)
+ Integrated.hidden = TRUE
+ Integrated.flags_attach_features &= ~ATTACH_REMOVABLE
+ Integrated.Attach(src)
+ update_attachable(Integrated.slot)
+
+/obj/item/weapon/gun/launcher/rocket/upp/apply_bullet_effects(obj/item/projectile/projectile_to_fire, mob/user, i = 1, reflex = 0)
+ . = ..()
+ if(!HAS_TRAIT(user, TRAIT_EAR_PROTECTION) && ishuman(user))
+ return
+
+ var/backblast_loc = get_turf(get_step(user.loc, turn(user.dir, 180)))
+ smoke.set_up(1, 0, backblast_loc, turn(user.dir, 180))
+ smoke.start()
+ playsound(src, 'sound/weapons/gun_rocketlauncher.ogg', 100, TRUE, 10)
+ for(var/mob/living/carbon/C in backblast_loc)
+ if(!C.lying && !HAS_TRAIT(C, TRAIT_EAR_PROTECTION)) //Have to be standing up to get the fun stuff
+ C.apply_damage(15, BRUTE) //The shockwave hurts, quite a bit. It can knock unarmored targets unconscious in real life
+ C.apply_effect(4, STUN) //For good measure
+ C.apply_effect(6, STUTTER)
+ C.emote("pain")
+
//-------------------------------------------------------
//Flare gun. Close enough to a specialist gun?
diff --git a/code/modules/projectiles/magazines/misc.dm b/code/modules/projectiles/magazines/misc.dm
index d224498ebceb..87568c953211 100644
--- a/code/modules/projectiles/magazines/misc.dm
+++ b/code/modules/projectiles/magazines/misc.dm
@@ -6,7 +6,7 @@
name = "rotating ammo drum (7.62x51mm)"
desc = "A huge ammo drum for a huge gun."
caliber = "7.62x51mm"
- icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
+ icon = 'icons/obj/items/weapons/guns/ammo_by_faction/event.dmi'
icon_state = "painless" //PLACEHOLDER
matter = list("metal" = 10000)
@@ -31,6 +31,19 @@
reload_delay = 8
gun_type = /obj/item/weapon/gun/m60
+/obj/item/ammo_magazine/pkp
+ name = "QYJ-72 ammo box (7.62x54mmR)"
+ desc = "A 250 round box for the UPP's standard GPMG, the QYJ-72. Chambered in 7.62x54mmR."
+ caliber = "7.62x54mmR"
+ icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
+ icon_state = "qjy72"
+
+ matter = list("metal" = 10000)
+ default_ammo = /datum/ammo/bullet/pkp
+ max_rounds = 250
+ reload_delay = 12
+ gun_type = /obj/item/weapon/gun/pkp
+
//rocket launchers
/obj/item/ammo_magazine/rifle/grenadespawner
diff --git a/code/modules/projectiles/magazines/pistols.dm b/code/modules/projectiles/magazines/pistols.dm
index dae86cc813cc..11e6fe9dbfeb 100644
--- a/code/modules/projectiles/magazines/pistols.dm
+++ b/code/modules/projectiles/magazines/pistols.dm
@@ -192,21 +192,53 @@
ammo_band_color = AMMO_BAND_COLOR_AP
//-------------------------------------------------------
-//MAUSER MERC PISTOL //Inspired by the Makarov.
+//Type 31 pistol. //A makarov
-/obj/item/ammo_magazine/pistol/c99
- name = "\improper PK-9 magazine (.380)"
+/obj/item/ammo_magazine/pistol/np92
+ name = "\improper NP92 magazine (9x18mm Makarov)"
default_ammo = /datum/ammo/bullet/pistol
- caliber = ".380"
+ caliber = "9x18mm Makarov"
icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
- icon_state = "pk-9"
- max_rounds = 8
- gun_type = /obj/item/weapon/gun/pistol/c99
+ icon_state = "np92mag"
+ max_rounds = 12
+ gun_type = /obj/item/weapon/gun/pistol/np92
+
+/obj/item/ammo_magazine/pistol/np92/suppressed
+ name = "\improper NPZ92 magazine (9x18mm Makarov)"
+ default_ammo = /datum/ammo/bullet/pistol
+ caliber = "9x18mm Makarov"
+ icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
+ icon_state = "npz92mag"
+ max_rounds = 12
-/obj/item/ammo_magazine/pistol/c99/tranq
- name = "\improper PK-9 tranquilizer magazine (.380)"
+/obj/item/ammo_magazine/pistol/np92/tranq
+ name = "\improper NPZ92 tranq magazine (9x18mm Makarov)"
default_ammo = /datum/ammo/bullet/pistol/tranq
- icon_state = "pk-9_tranq"
+ caliber = "9x18mm Makarov"
+ icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
+ icon_state = "npz92tranqmag"
+ max_rounds = 12
+
+//-------------------------------------------------------
+//Type 73 pistol. //A TT
+
+/obj/item/ammo_magazine/pistol/t73
+ name = "\improper Type 73 magazine (7.62x25mm Tokarev)"
+ default_ammo = /datum/ammo/bullet/pistol/heavy
+ caliber = "7.62x25mm Tokarev"
+ icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
+ icon_state = "ttmag"
+ max_rounds = 9
+ gun_type = /obj/item/weapon/gun/pistol/t73
+
+/obj/item/ammo_magazine/pistol/t73_impact
+ name = "\improper High Impact Type 74 magazine (7.62x25mm Tokarev)"
+ default_ammo = /datum/ammo/bullet/pistol/heavy/super/highimpact/upp
+ caliber = "7.62x25mm Tokarev"
+ icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
+ icon_state = "ttmag_impact"
+ max_rounds = 9
+ gun_type = /obj/item/weapon/gun/pistol/t73/leader
//-------------------------------------------------------
//KT-42 //Inspired by the .44 Auto Mag pistol
@@ -316,7 +348,7 @@ It is a modified Beretta 93R, and can fire three-round burst or single fire. Whe
name = "\improper CZ-81 20-round magazine (.32ACP)"
desc = "A .32ACP caliber magazine for the CZ-81."
caliber = ".32ACP"
- icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
+ icon = 'icons/obj/items/weapons/guns/ammo_by_faction/colony.dmi'
icon_state = "skorpion" //PLACEHOLDER
gun_type = /obj/item/weapon/gun/pistol/skorpion
max_rounds = 20
diff --git a/code/modules/projectiles/magazines/revolvers.dm b/code/modules/projectiles/magazines/revolvers.dm
index c9803fdf5671..07fc75a50fad 100644
--- a/code/modules/projectiles/magazines/revolvers.dm
+++ b/code/modules/projectiles/magazines/revolvers.dm
@@ -55,18 +55,18 @@
caliber = ".44 sabot"
/obj/item/ammo_magazine/revolver/upp
- name = "\improper N-Y speed loader (7.62x38mmR)"
- default_ammo = /datum/ammo/bullet/revolver/nagant
+ name = "\improper ZHNK-72 speed loader (7.62x38mmR)"
+ default_ammo = /datum/ammo/bullet/revolver/upp
caliber = "7.62x38mmR"
icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
- icon_state = "ny762"
- gun_type = /obj/item/weapon/gun/revolver/nagant
+ icon_state = "zhnk72loader"
+ gun_type = /obj/item/weapon/gun/revolver/upp
/obj/item/ammo_magazine/revolver/upp/shrapnel
- name = "\improper N-Y shrapnel-shot speed loader (7.62x38mmR)"
+ name = "\improper ZHNK-72 shrapnel-shot speed loader (7.62x38mmR)"
desc = "This speedloader contains seven 'shrapnel-shot' bullets, cheap recycled casings picked up off the ground and refilled with gunpowder and random scrap metal. Acts similarly to flechette."
- default_ammo = /datum/ammo/bullet/revolver/nagant/shrapnel
- icon_state = "ny762_shrapnel"
+ default_ammo = /datum/ammo/bullet/revolver/upp/shrapnel
+ icon_state = "zhnk72loader_shrapnel"
/obj/item/ammo_magazine/revolver/small
name = "\improper S&W speed loader (.38)"
@@ -167,13 +167,13 @@
//RUSSIAN REVOLVER //Based on the 7.62mm Russian revolvers.
/obj/item/ammo_magazine/internal/revolver/upp
- default_ammo = /datum/ammo/bullet/revolver/nagant
+ default_ammo = /datum/ammo/bullet/revolver/upp
caliber = "7.62x38mmR"
max_rounds = 7
- gun_type = /obj/item/weapon/gun/revolver/nagant
+ gun_type = /obj/item/weapon/gun/revolver/upp
/obj/item/ammo_magazine/internal/revolver/upp/shrapnel
- default_ammo = /datum/ammo/bullet/revolver/nagant/shrapnel
+ default_ammo = /datum/ammo/bullet/revolver/upp/shrapnel
//-------------------------------------------------------
diff --git a/code/modules/projectiles/magazines/rifles.dm b/code/modules/projectiles/magazines/rifles.dm
index ca008c2d1376..f960cc82535b 100644
--- a/code/modules/projectiles/magazines/rifles.dm
+++ b/code/modules/projectiles/magazines/rifles.dm
@@ -263,7 +263,7 @@
icon_state = "m41ae2"
max_rounds = 300
gun_type = /obj/item/weapon/gun/rifle/lmg
- flags_magazine = AMMUNITION_CANNOT_REMOVE_BULLETS|AMMUNITION_REFILLABLE
+ flags_magazine = AMMUNITION_CANNOT_REMOVE_BULLETS|AMMUNITION_REFILLABLE|AMMUNITION_SLAP_TRANSFER
ammo_band_icon = "+m41ae2_band"
ammo_band_icon_empty = "+m41ae2_band_e"
@@ -290,7 +290,9 @@
desc = "A 5.45x39mm high-capacity casket magazine for the Type 71 rifle."
caliber = "5.45x39mm"
icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
- icon_state = "type_71"
+ icon_state = "type71"
+ ammo_band_icon = "+type71_band"
+ ammo_band_icon_empty = "+type71_band_e"
default_ammo = /datum/ammo/bullet/rifle/type71
max_rounds = 60
gun_type = /obj/item/weapon/gun/rifle/type71
@@ -298,16 +300,14 @@
/obj/item/ammo_magazine/rifle/type71/ap
name = "\improper Type 71 AP magazine (5.45x39mm)"
desc = "A 5.45x39mm high-capacity casket magazine containing armor piercing rounds for the Type 71 rifle."
- icon_state = "type_71_ap"
default_ammo = /datum/ammo/bullet/rifle/type71/ap
- bonus_overlay = "type71_ap"
+ ammo_band_color = AMMO_BAND_COLOR_AP
/obj/item/ammo_magazine/rifle/type71/heap
name = "\improper Type 71 HEAP magazine (5.45x39mm)"
desc = "A 5.45x39mm high-capacity casket magazine containing the standard high explosive armor piercing rounds for the Type 71 rifle."
- icon_state = "type_71_heap"
default_ammo = /datum/ammo/bullet/rifle/type71/heap
- bonus_overlay = "type71_heap"
+ ammo_band_color = AMMO_BAND_COLOR_HEAP
//-------------------------------------------------------
//L42A Battle Rifle
diff --git a/code/modules/projectiles/magazines/smgs.dm b/code/modules/projectiles/magazines/smgs.dm
index 333d47e19931..b89aee06f6be 100644
--- a/code/modules/projectiles/magazines/smgs.dm
+++ b/code/modules/projectiles/magazines/smgs.dm
@@ -150,6 +150,44 @@
#undef PPSH_STICK_MAGAZINE_JAM_CHANCE
#undef PPSH_DRUM_MAGAZINE_JAM_CHANCE
+//-------------------------------------------------------
+//Type-19, based on the PPS-43
+
+/obj/item/ammo_magazine/smg/pps43
+ name = "\improper Type-19 stick magazine (7.62x25mm)"
+ desc = "A stick magazine for the Type-19 submachinegun."
+ caliber = "7.62x25mm"
+ icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
+ icon_state = "insasu_stickmag"
+ bonus_overlay = "insasu_stickmag_overlay"
+ max_rounds = 35
+ gun_type = /obj/item/weapon/gun/smg/pps43
+ default_ammo = /datum/ammo/bullet/smg/pps43
+ var/bonus_mag_aim_slowdown = 0
+ var/bonus_mag_wield_delay = 0
+
+
+/obj/item/ammo_magazine/smg/pps43/extended
+ name = "\improper Type-19 drum magazine (7.62x25mm)"
+ desc = "A drum magazine for the Type-19 submachinegun."
+ icon_state = "insasu_drum"
+ bonus_overlay = "insasu_drum_overlay"
+ max_rounds = 71
+ w_class = SIZE_MEDIUM
+ bonus_mag_aim_slowdown = SLOWDOWN_ADS_QUICK_MINUS
+ bonus_mag_wield_delay = WIELD_DELAY_VERY_FAST
+//-------------------------------------------------------
+//Type 64 SMG, based on the PP Bizon.
+
+/obj/item/ammo_magazine/smg/bizon
+ name = "\improper Type 64 Helical Magazine (7.62x19mm)"
+ desc = "A 64 round magazine for the Type 64 submachinegun, the standard SMG of the UPP armed forces."
+ caliber = "7.62x19mm"
+ icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
+ icon_state = "type64mag"
+ max_rounds = 64
+ gun_type = /obj/item/weapon/gun/smg/bizon
+
//-------------------------------------------------------
//GENERIC UZI //Based on the uzi submachinegun, of course.
diff --git a/code/modules/projectiles/magazines/specialist.dm b/code/modules/projectiles/magazines/specialist.dm
index 23b540202c40..2730563e2cbb 100644
--- a/code/modules/projectiles/magazines/specialist.dm
+++ b/code/modules/projectiles/magazines/specialist.dm
@@ -48,16 +48,16 @@
max_rounds = 6
-//SVD //Based on the actual Dragunov designated marksman rifle.
+//Type 88 //Based on the actual Dragunov designated marksman rifle.
/obj/item/ammo_magazine/sniper/svd
- name = "\improper SVD magazine (7.62x54mmR)"
- desc = "A large caliber magazine for the SVD designated marksman rifle."
+ name = "\improper Type-88 Magazine (7.62x54mmR)"
+ desc = "A large caliber magazine for the Type-88 designated marksman rifle."
caliber = "7.62x54mmR"
icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
- icon_state = "svd"
- default_ammo = /datum/ammo/bullet/sniper/crude
- max_rounds = 10
+ icon_state = "type88mag"
+ default_ammo = /datum/ammo/bullet/sniper/upp
+ max_rounds = 12
gun_type = /obj/item/weapon/gun/rifle/sniper/svd
//M4RA magazines
@@ -331,3 +331,47 @@
default_ammo = /datum/ammo/rocket/ap/anti_tank
gun_type = /obj/item/weapon/gun/launcher/rocket/anti_tank
reload_delay = 100
+
+
+//-------------------------------------------------------
+//UPP Rockets
+
+/obj/item/ammo_magazine/rocket/upp
+ name = "\improper HJRA-12 High-Explosive Rocket"
+ desc = "A rocket for the UPP standard-issue HJRA-12 Handheld Anti-Tank Grenade Launcher. This one is a standard High-Explosive rocket for anti-personal or light-vehicle use."
+ caliber = "88mm"
+ icon_state = "hjra_explosive"
+ icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
+
+ max_rounds = 1
+ default_ammo = /datum/ammo/rocket
+ gun_type = /obj/item/weapon/gun/launcher/rocket/upp
+ reload_delay = 85
+
+/obj/item/ammo_magazine/rocket/upp/update_icon()
+ if(current_rounds <= 0)
+ qdel(src)
+ else
+ icon_state = initial(icon_state)
+
+/obj/item/ammo_magazine/rocket/upp/at
+ name = "\improper HJRA-12 Anti-Tank Rocket"
+ desc = "A rocket for the UPP standard-issue HJRA-12 Handheld Anti-Tank Grenade Launcher. This one is a standard Anti-Tank rocket designed to disable or destroy hostile vehicles."
+ caliber = "88mm"
+ icon_state = "hjra_tank"
+
+ max_rounds = 1
+ default_ammo = /datum/ammo/rocket/ap/anti_tank
+ gun_type = /obj/item/weapon/gun/launcher/rocket/upp
+ reload_delay = 85
+
+/obj/item/ammo_magazine/rocket/upp/incen
+ name = "\improper HJRA-12 Extreme-Intensity Incendiary Rocket"
+ desc = "A rocket for the UPP standard-issue HJRA-12 Handheld Anti-Tank Grenade Launcher. This one is an extreme-intensity incendiary rocket, using an experimental chemical designated R-189 by the UPP, it is designed to melt through fortified positions and bunkers but is most commonly used in an anti-personnal role due to over-issuing and the tempatures after use in its intended role leaving the tempature of the air incompatible with human life."
+ caliber = "88mm"
+ icon_state = "hjra_incen"
+
+ max_rounds = 1
+ default_ammo = /datum/ammo/rocket/wp/upp
+ gun_type = /obj/item/weapon/gun/launcher/rocket/upp
+ reload_delay = 85
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index e4251f5f6b31..eccba14a442a 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -110,7 +110,7 @@
/obj/item/projectile/Crossed(atom/movable/AM)
/* Fun fact: Crossed is called for any contents involving operations.
* This notably means, inserting a magazing in a gun Crossed() it with the bullets in the gun. */
- if(!loc.z)
+ if(!loc?.z)
return // Not on the map. Don't scan a turf. Don't shoot the poor guy reloading his gun.
if(AM && !(AM in permutated))
if(scan_a_turf(get_turf(AM)))
@@ -1143,11 +1143,16 @@
// Need to do this in order to prevent the ping from being deleted
addtimer(CALLBACK(I, TYPE_PROC_REF(/image, flick_overlay), src, 3), 1)
+/// People getting shot by a large amount of bullets in a very short period of time can lag them out, with chat messages being one cause, so a 1s cooldown per hit message is introduced to assuage that
+/mob/var/shot_cooldown = 0
+
/mob/proc/bullet_message(obj/item/projectile/P)
if(!P)
return
- visible_message(SPAN_DANGER("[src] is hit by the [P.name] in the [parse_zone(P.def_zone)]!"), \
- SPAN_HIGHDANGER("You are hit by the [P.name] in the [parse_zone(P.def_zone)]!"), null, 4, CHAT_TYPE_TAKING_HIT)
+ if(COOLDOWN_FINISHED(src, shot_cooldown))
+ visible_message(SPAN_DANGER("[src] is hit by the [P.name] in the [parse_zone(P.def_zone)]!"), \
+ SPAN_HIGHDANGER("You are hit by the [P.name] in the [parse_zone(P.def_zone)]!"), null, 4, CHAT_TYPE_TAKING_HIT)
+ COOLDOWN_START(src, shot_cooldown, 1 SECONDS)
last_damage_data = P.weapon_cause_data
if(P.firer && ismob(P.firer))
diff --git a/code/modules/reagents/chemistry_machinery/chem_dispenser.dm b/code/modules/reagents/chemistry_machinery/chem_dispenser.dm
index 98896013c6ec..6778bdd3c72b 100644
--- a/code/modules/reagents/chemistry_machinery/chem_dispenser.dm
+++ b/code/modules/reagents/chemistry_machinery/chem_dispenser.dm
@@ -235,6 +235,7 @@
if(HAS_TRAIT(attacking_object, TRAIT_TOOL_WRENCH))
if(!wrenchable)
to_chat(user, "[src] cannot be unwrenched.")
+ return
if(!do_after(user, 2 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
return
diff --git a/code/modules/reagents/chemistry_reagents/other.dm b/code/modules/reagents/chemistry_reagents/other.dm
index a7f0a1143428..45e66c182e6a 100644
--- a/code/modules/reagents/chemistry_reagents/other.dm
+++ b/code/modules/reagents/chemistry_reagents/other.dm
@@ -788,6 +788,20 @@
PROPERTY_FIRE_PENETRATING = 1
)
+/datum/reagent/napalm/upp
+ name = "R189"
+ id = "R189"
+ description = "A UPP chemical, it burns at an extremely high tempature and is designed to melt directly through fortified positions or bunkers."
+ color = "#ffe49c"
+ burncolor = "#ffe49c"
+ burn_sprite = "dynamic"
+ properties = list(
+ PROPERTY_INTENSITY = BURN_LEVEL_TIER_9,
+ PROPERTY_DURATION = BURN_TIME_TIER_3,
+ PROPERTY_RADIUS = 6,
+ PROPERTY_FIRE_PENETRATING = 1,
+ )
+
/datum/reagent/chlorinetrifluoride
name = "Chlorine Trifluoride"
id = "chlorine trifluoride"
diff --git a/code/modules/shuttle/computers/dropship_computer.dm b/code/modules/shuttle/computers/dropship_computer.dm
index 837f9a7f6aeb..7e8dc34f6892 100644
--- a/code/modules/shuttle/computers/dropship_computer.dm
+++ b/code/modules/shuttle/computers/dropship_computer.dm
@@ -147,6 +147,10 @@
return
if(dropship_control_lost && skillcheck(user, SKILL_PILOT, SKILL_PILOT_EXPERT))
+ var/remaining_time = timeleft(door_control_cooldown) / 10
+ if(remaining_time > 60)
+ to_chat(user, SPAN_WARNING("The shuttle is not responding, try again in [remaining_time] seconds."))
+ return
to_chat(user, SPAN_NOTICE("You start to remove the Queens override."))
if(!do_after(user, 3 MINUTES, INTERRUPT_ALL, BUSY_ICON_HOSTILE))
to_chat(user, SPAN_WARNING("You fail to remove the Queens override"))
diff --git a/code/modules/shuttle/dropship.dm b/code/modules/shuttle/dropship.dm
new file mode 100644
index 000000000000..cbca500f8f71
--- /dev/null
+++ b/code/modules/shuttle/dropship.dm
@@ -0,0 +1,217 @@
+/obj/structure/shuttle/part
+ opacity = TRUE
+ density = TRUE
+ unslashable = TRUE
+ unacidable = TRUE
+ breakable = FALSE
+ indestructible = TRUE
+
+/obj/structure/shuttle/part/dropship1
+ name = "\improper Alamo"
+ icon = 'icons/turf/dropship.dmi'
+ icon_state = "1"
+
+/obj/structure/shuttle/part/dropship1/ex_act(severity, direction)
+ return FALSE
+
+/obj/structure/shuttle/part/dropship1/transparent
+ opacity = FALSE
+
+/obj/structure/shuttle/part/dropship1/transparent/nose_top_right
+ icon_state = "102"
+
+/obj/structure/shuttle/part/dropship1/transparent/nose_center
+ icon_state = "101"
+
+/obj/structure/shuttle/part/dropship1/transparent/nose_top_left
+ icon_state = "100"
+
+/obj/structure/shuttle/part/dropship1/nose_front_left
+ icon_state = "95"
+
+/obj/structure/shuttle/part/dropship1/nose_front_right
+ icon_state = "99"
+
+/obj/structure/shuttle/part/dropship1/transparent/inner_right_weapons
+ icon_state = "90"
+
+/obj/structure/shuttle/part/dropship1/transparent/outer_right_weapons
+ icon_state = "91"
+
+/obj/structure/shuttle/part/dropship1/transparent/inner_left_weapons
+ icon_state = "85"
+
+/obj/structure/shuttle/part/dropship1/transparent/outer_left_weapons
+ icon_state = "84"
+
+/obj/structure/shuttle/part/dropship1/transparent/upper_right_wing
+ icon_state = "74"
+
+/obj/structure/shuttle/part/dropship1/transparent/middle_right_wing
+ icon_state = "70"
+
+/obj/structure/shuttle/part/dropship1/transparent/lower_right_wing
+ icon_state = "65"
+
+/obj/structure/shuttle/part/dropship1/transparent/upper_left_wing
+ icon_state = "71"
+
+/obj/structure/shuttle/part/dropship1/transparent/middle_left_wing
+ icon_state = "66"
+
+/obj/structure/shuttle/part/dropship1/transparent/lower_left_wing
+ icon_state = "61"
+
+/obj/structure/shuttle/part/dropship1/lower_left_wall
+ icon_state = "46"
+
+/obj/structure/shuttle/part/dropship1/lower_right_wall
+ icon_state = "49"
+
+/obj/structure/shuttle/part/dropship1/transparent/engine_left_cap
+ icon_state = "40"
+
+/obj/structure/shuttle/part/dropship1/transparent/engine_right_cap
+ icon_state = "41"
+
+/obj/structure/shuttle/part/dropship1/transparent/engine_left_exhaust
+ icon_state = "16"
+
+/obj/structure/shuttle/part/dropship1/transparent/engine_right_exhaust
+ icon_state = "17"
+
+/obj/structure/shuttle/part/dropship1/bottom_left_wall
+ icon_state = "9"
+
+/obj/structure/shuttle/part/dropship1/bottom_right_wall
+ icon_state = "15"
+
+/obj/structure/shuttle/part/dropship1/left_inner_wing_connector
+ icon_state = "7"
+
+/obj/structure/shuttle/part/dropship1/right_inner_wing_connector
+ icon_state = "8"
+
+/obj/structure/shuttle/part/dropship1/left_outer_wing_connector
+ icon_state = "3"
+
+/obj/structure/shuttle/part/dropship1/right_outer_wing_connector
+ icon_state = "4"
+
+/obj/structure/shuttle/part/dropship1/transparent/left_inner_bottom_wing
+ icon_state = "1"
+
+/obj/structure/shuttle/part/dropship1/transparent/left_outer_bottom_wing
+ icon_state = "2"
+
+/obj/structure/shuttle/part/dropship1/transparent/right_inner_bottom_wing
+ icon_state = "5"
+
+/obj/structure/shuttle/part/dropship1/transparent/right_outer_bottom_wing
+ icon_state = "6"
+
+/obj/structure/shuttle/part/dropship2
+ name = "\improper Normandy"
+ icon = 'icons/turf/dropship2.dmi'
+ icon_state = "1"
+ opacity = TRUE
+
+/obj/structure/shuttle/part/dropship2/ex_act(severity, direction)
+ return FALSE
+
+/obj/structure/shuttle/part/dropship2/transparent
+ opacity = FALSE
+
+/obj/structure/shuttle/part/dropship2/transparent/nose_top_right
+ icon_state = "102"
+
+/obj/structure/shuttle/part/dropship2/transparent/nose_center
+ icon_state = "101"
+
+/obj/structure/shuttle/part/dropship2/transparent/nose_top_left
+ icon_state = "100"
+
+/obj/structure/shuttle/part/dropship2/nose_front_left
+ icon_state = "95"
+
+/obj/structure/shuttle/part/dropship2/nose_front_right
+ icon_state = "99"
+
+/obj/structure/shuttle/part/dropship2/transparent/inner_right_weapons
+ icon_state = "90"
+
+/obj/structure/shuttle/part/dropship2/transparent/outer_right_weapons
+ icon_state = "91"
+
+/obj/structure/shuttle/part/dropship2/transparent/inner_left_weapons
+ icon_state = "85"
+
+/obj/structure/shuttle/part/dropship2/transparent/outer_left_weapons
+ icon_state = "84"
+
+/obj/structure/shuttle/part/dropship2/transparent/upper_right_wing
+ icon_state = "74"
+
+/obj/structure/shuttle/part/dropship2/transparent/middle_right_wing
+ icon_state = "70"
+
+/obj/structure/shuttle/part/dropship2/transparent/lower_right_wing
+ icon_state = "65"
+
+/obj/structure/shuttle/part/dropship2/transparent/upper_left_wing
+ icon_state = "71"
+
+/obj/structure/shuttle/part/dropship2/transparent/middle_left_wing
+ icon_state = "66"
+
+/obj/structure/shuttle/part/dropship2/transparent/lower_left_wing
+ icon_state = "61"
+
+/obj/structure/shuttle/part/dropship2/lower_left_wall
+ icon_state = "46"
+
+/obj/structure/shuttle/part/dropship2/lower_right_wall
+ icon_state = "49"
+
+/obj/structure/shuttle/part/dropship2/transparent/engine_left_cap
+ icon_state = "40"
+
+/obj/structure/shuttle/part/dropship2/transparent/engine_right_cap
+ icon_state = "41"
+
+/obj/structure/shuttle/part/dropship2/transparent/engine_left_exhaust
+ icon_state = "16"
+
+/obj/structure/shuttle/part/dropship2/transparent/engine_right_exhaust
+ icon_state = "17"
+
+/obj/structure/shuttle/part/dropship2/bottom_left_wall
+ icon_state = "9"
+
+/obj/structure/shuttle/part/dropship2/bottom_right_wall
+ icon_state = "15"
+
+/obj/structure/shuttle/part/dropship2/left_inner_wing_connector
+ icon_state = "7"
+
+/obj/structure/shuttle/part/dropship2/right_inner_wing_connector
+ icon_state = "8"
+
+/obj/structure/shuttle/part/dropship2/left_outer_wing_connector
+ icon_state = "3"
+
+/obj/structure/shuttle/part/dropship2/right_outer_wing_connector
+ icon_state = "4"
+
+/obj/structure/shuttle/part/dropship2/transparent/left_outer_bottom_wing
+ icon_state = "1"
+
+/obj/structure/shuttle/part/dropship2/transparent/left_outer_inner_wing
+ icon_state = "2"
+
+/obj/structure/shuttle/part/dropship2/transparent/right_inner_bottom_wing
+ icon_state = "5"
+
+/obj/structure/shuttle/part/dropship2/transparent/right_outer_bottom_wing
+ icon_state = "6"
+
diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm
index 7bd3bcb5df7c..15f1f6790591 100644
--- a/code/modules/shuttle/on_move.dm
+++ b/code/modules/shuttle/on_move.dm
@@ -114,8 +114,8 @@ All ShuttleMove procs go here
if (newT.z != oldT.z)
onTransitZ(oldT.z, newT.z)
- //if(light) // tg lighting
- // update_light()
+ if(light)
+ update_light()
if(rotation)
shuttleRotate(rotation)
@@ -151,7 +151,7 @@ All ShuttleMove procs go here
contents -= oldT
underlying_old_area.contents += oldT
- //oldT.change_area(src, underlying_old_area) //lighting
+ oldT.change_area(src, underlying_old_area) //lighting
//The old turf has now been given back to the area that turf originaly belonged to
var/area/old_dest_area = newT.loc
@@ -159,7 +159,7 @@ All ShuttleMove procs go here
old_dest_area.contents -= newT
contents += newT
- //newT.change_area(old_dest_area, src) //lighting
+ newT.change_area(old_dest_area, src) //lighting
return TRUE
// Called on areas after everything has been moved
diff --git a/code/modules/shuttle/shuttles/dropship.dm b/code/modules/shuttle/shuttles/dropship.dm
index 303d4c0494ed..d81484b0343d 100644
--- a/code/modules/shuttle/shuttles/dropship.dm
+++ b/code/modules/shuttle/shuttles/dropship.dm
@@ -1,6 +1,10 @@
/obj/docking_port/mobile/marine_dropship
width = 11
height = 21
+
+ dwidth = 5
+ dheight = 10
+
preferred_direction = SOUTH
callTime = DROPSHIP_TRANSIT_DURATION
rechargeTime = SHUTTLE_RECHARGE
@@ -157,7 +161,9 @@
dir = NORTH
width = 11
height = 21
- dwidth = 1
+ dwidth = 5
+ dheight = 10
+
var/list/landing_lights = list()
var/auto_open = FALSE
var/landing_lights_on = FALSE
@@ -256,7 +262,6 @@
/obj/docking_port/stationary/marine_dropship/crash_site
auto_open = TRUE
- dwidth = 1
/obj/docking_port/stationary/marine_dropship/crash_site/on_prearrival(obj/docking_port/mobile/arriving_shuttle)
. = ..()
diff --git a/code/modules/shuttle/shuttles/escape_shuttle.dm b/code/modules/shuttle/shuttles/escape_shuttle.dm
index daf91034036f..941785e60d9d 100644
--- a/code/modules/shuttle/shuttles/escape_shuttle.dm
+++ b/code/modules/shuttle/shuttles/escape_shuttle.dm
@@ -274,8 +274,7 @@
escape_shuttle.door_handler.control_doors("force-unlock")
for(var/area/shuttle_area in arriving_shuttle.shuttle_areas)
- shuttle_area.SetDynamicLighting()
- shuttle_area.SetLightLevel(0)
+ shuttle_area.remove_base_lighting()
shuttle_area.flags_alarm_state &= ~ALARM_WARNING_FIRE
shuttle_area.updateicon()
diff --git a/code/modules/unit_tests/create_and_destroy.dm b/code/modules/unit_tests/create_and_destroy.dm
index 46f900eee71e..eb4672b84fc9 100644
--- a/code/modules/unit_tests/create_and_destroy.dm
+++ b/code/modules/unit_tests/create_and_destroy.dm
@@ -12,10 +12,13 @@ GLOBAL_VAR_INIT(running_create_and_destroy, FALSE)
/mob/living/carbon,
/obj/effect/node,
/obj/item/seeds/cutting,
+ //lighting singleton
+ /mob/dview,
// These use walkaway() after initialization, which causes false positives
/obj/item/explosive/grenade/flashbang/cluster/segment,
/obj/item/explosive/grenade/flashbang/cluster_piece,
/obj/effect/fake_attacker,
+ /atom/movable/lighting_mask, //leave it alone
)
//This turf existing is an error in and of itself
ignore += typesof(/turf/baseturf_skipover)
diff --git a/code/modules/vehicles/apc/apc.dm b/code/modules/vehicles/apc/apc.dm
index 2d0c823dd638..d71db37074f1 100644
--- a/code/modules/vehicles/apc/apc.dm
+++ b/code/modules/vehicles/apc/apc.dm
@@ -34,7 +34,6 @@ GLOBAL_LIST_EMPTY(command_apc_list)
movement_sound = 'sound/vehicles/tank_driving.ogg'
- luminosity = 7
var/gunner_view_buff = 10
hardpoints_allowed = list(
diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm
index ac22c0e79812..40085ad078ea 100644
--- a/code/modules/vehicles/cargo_train.dm
+++ b/code/modules/vehicles/cargo_train.dm
@@ -4,11 +4,13 @@
icon = 'icons/obj/vehicles/vehicles.dmi'
icon_state = "cargo_engine"
on = 0
- luminosity = 5 //Pretty strong because why not
powered = 1
locked = 0
charge_use = 15
+ light_system = MOVABLE_LIGHT
+ light_range = 5
+
var/car_limit = 3 //how many cars an engine can pull before performance degrades
active_engines = 1
var/obj/item/key/cargo_train/key
@@ -24,7 +26,7 @@
name = "cargo train trolley"
icon = 'icons/obj/vehicles/vehicles.dmi'
icon_state = "cargo_trailer"
- luminosity = 0
+ light_range = 0
anchored = FALSE
locked = 0
can_buckle = FALSE
@@ -38,6 +40,10 @@
key = new()
var/image/I = new(icon = 'icons/obj/vehicles/vehicles.dmi', icon_state = "cargo_engine_overlay", layer = src.layer + 0.2) //over mobs
overlays += I
+
+ if(light_range)
+ set_light_on(TRUE)
+
turn_off() //so engine verbs are correctly set
/obj/vehicle/train/cargo/engine/Move()
diff --git a/code/modules/vehicles/hardpoints/hardpoint_ammo/minigun_ammo.dm b/code/modules/vehicles/hardpoints/hardpoint_ammo/minigun_ammo.dm
index 23219f551a47..78222cdb3a40 100644
--- a/code/modules/vehicles/hardpoints/hardpoint_ammo/minigun_ammo.dm
+++ b/code/modules/vehicles/hardpoints/hardpoint_ammo/minigun_ammo.dm
@@ -1,6 +1,6 @@
/obj/item/ammo_magazine/hardpoint/ltaaap_minigun
name = "LTAA-AP Minigun Magazine"
- icon = 'icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi'
+ icon = 'icons/obj/items/weapons/guns/ammo_by_faction/event.dmi'
desc = "A primary armament minigun magazine."
caliber = "7.62x51mm" //Correlates to miniguns
icon_state = "painless"
diff --git a/code/modules/vehicles/interior/areas.dm b/code/modules/vehicles/interior/areas.dm
index 85ec4a319769..605b32079fcc 100644
--- a/code/modules/vehicles/interior/areas.dm
+++ b/code/modules/vehicles/interior/areas.dm
@@ -3,6 +3,7 @@
requires_power = 0
unlimited_power = 1
icon = 'icons/turf/areas_interiors.dmi'
+ base_lighting_alpha = 255
ambience_exterior = 'sound/ambience/vehicle_interior1.ogg'
sound_environment = SOUND_ENVIRONMENT_ROOM
diff --git a/code/modules/vehicles/multitile/multitile.dm b/code/modules/vehicles/multitile/multitile.dm
index 7802d9a7edbd..20cf6217cc06 100644
--- a/code/modules/vehicles/multitile/multitile.dm
+++ b/code/modules/vehicles/multitile/multitile.dm
@@ -21,6 +21,14 @@
can_buckle = FALSE
+ light_system = MOVABLE_LIGHT
+ light_range = 5
+
+ var/atom/movable/vehicle_light_holder/lighting_holder
+
+ var/vehicle_light_range = 5
+ var/vehicle_light_power = 2
+
//Yay! Working cameras in the vehicles at last!!
var/obj/structure/machinery/camera/vehicle/camera = null
var/obj/structure/machinery/camera/vehicle/camera_int = null
@@ -167,6 +175,18 @@
rotate_entrances(angle_to_turn)
rotate_bounds(angle_to_turn)
+ if(bound_width > world.icon_size || bound_height > world.icon_size)
+ lighting_holder = new(src)
+ lighting_holder.set_light_range(vehicle_light_range)
+ lighting_holder.set_light_power(vehicle_light_power)
+ lighting_holder.set_light_on(vehicle_light_range || vehicle_light_power)
+
+ light_pixel_x = -bound_x
+ light_pixel_y = -bound_y
+
+ if(light_range)
+ set_light_on(TRUE)
+
healthcheck()
update_icon()
@@ -364,8 +384,8 @@
handle_all_modules_broken()
//vehicle is dead, no more lights
- if(health <= 0 && luminosity)
- SetLuminosity(0)
+ if(health <= 0 && lighting_holder.light_range)
+ lighting_holder.set_light_on(FALSE)
update_icon()
/*
@@ -421,3 +441,19 @@
/obj/vehicle/multitile/proc/handle_acidic_environment(atom/A)
for(var/obj/item/hardpoint/locomotion/Loco in hardpoints)
Loco.handle_acid_damage(A)
+
+/atom/movable/vehicle_light_holder
+ light_system = MOVABLE_LIGHT
+
+/atom/movable/vehicle_light_holder/Initialize(mapload, ...)
+ . = ..()
+
+ var/atom/attached_to = loc
+
+ forceMove(attached_to.loc)
+ RegisterSignal(attached_to, COMSIG_MOVABLE_MOVED, PROC_REF(handle_parent_move))
+
+/atom/movable/vehicle_light_holder/proc/handle_parent_move(atom/movable/mover, atom/oldloc, direction)
+ SIGNAL_HANDLER
+
+ forceMove(get_turf(mover))
diff --git a/code/modules/vehicles/multitile/multitile_interaction.dm b/code/modules/vehicles/multitile/multitile_interaction.dm
index ca2b5922ecf0..f956d64ebf12 100644
--- a/code/modules/vehicles/multitile/multitile_interaction.dm
+++ b/code/modules/vehicles/multitile/multitile_interaction.dm
@@ -209,7 +209,7 @@
to_chat(user, SPAN_NOTICE("Hull integrity is at [SPAN_HELPFUL(100.0*health/max_hp)]%."))
health = initial(health)
- SetLuminosity(initial(luminosity))
+ lighting_holder.set_light_range(vehicle_light_range)
toggle_cameras_status(TRUE)
update_icon()
user.visible_message(SPAN_NOTICE("[user] finishes [repair_message] on \the [src]."), SPAN_NOTICE("You finish [repair_message] on \the [src]. Hull integrity is at [SPAN_HELPFUL(100.0*health/max_hp)]%. "))
diff --git a/code/modules/vehicles/powerloader.dm b/code/modules/vehicles/powerloader.dm
index 11beaf597985..88d917b90b3e 100644
--- a/code/modules/vehicles/powerloader.dm
+++ b/code/modules/vehicles/powerloader.dm
@@ -6,7 +6,7 @@
layer = POWERLOADER_LAYER //so the top appears above windows and wall mounts
anchored = TRUE
density = TRUE
- luminosity = 5
+ light_range = 5
move_delay = 8
buckling_y = 9
health = 200
diff --git a/code/modules/vehicles/tank/tank.dm b/code/modules/vehicles/tank/tank.dm
index 3ed4e6623ea1..ad69f80cdfb6 100644
--- a/code/modules/vehicles/tank/tank.dm
+++ b/code/modules/vehicles/tank/tank.dm
@@ -36,7 +36,7 @@
move_momentum_build_factor = 1.8
move_turn_momentum_loss_factor = 0.6
- luminosity = 7
+ vehicle_light_range = 7
// Rest (all the guns) is handled by the tank turret hardpoint
hardpoints_allowed = list(
diff --git a/code/modules/vehicles/van/van.dm b/code/modules/vehicles/van/van.dm
index 5e9e467bf56d..1124f5348140 100644
--- a/code/modules/vehicles/van/van.dm
+++ b/code/modules/vehicles/van/van.dm
@@ -41,7 +41,7 @@
movement_sound = 'sound/vehicles/tank_driving.ogg'
honk_sound = 'sound/vehicles/honk_2_truck.ogg'
- luminosity = 8
+ vehicle_light_range = 8
move_max_momentum = 3
diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm
index 0681b7df05ac..3a79f14de51a 100644
--- a/code/modules/vehicles/vehicle.dm
+++ b/code/modules/vehicles/vehicle.dm
@@ -5,7 +5,6 @@
density = TRUE
anchored = TRUE
animate_movement = 1
- luminosity = 2
can_buckle = TRUE
// The mobs that are in each position/seat of the vehicle
@@ -166,13 +165,13 @@
if(powered && cell.charge < charge_use)
return 0
on = 1
- SetLuminosity(initial(luminosity))
+ set_light(initial(light_range))
update_icon()
return 1
/obj/vehicle/proc/turn_off()
on = 0
- SetLuminosity(0)
+ set_light(0)
update_icon()
/obj/vehicle/proc/explode()
@@ -262,10 +261,6 @@
. = ..()
seats[VEHICLE_DRIVER] = null
-/obj/vehicle/Destroy()
- SetLuminosity(0)
- . = ..()
-
//-------------------------------------------------------
// Stat update procs
//-------------------------------------------------------
diff --git a/colonialmarines.dme b/colonialmarines.dme
index 42e7880bd313..03f1e780e4a1 100644
--- a/colonialmarines.dme
+++ b/colonialmarines.dme
@@ -1,6 +1,6 @@
-// DM Environment file for colonialmarines.dme.
+s// DM Environment file for colonialmarines.dme.
// All manual changes should be made outside the BEGIN_ and END_ blocks.
- // New source code should be placed in .dm files: choose File/New --> Code File.
+// New source code should be placed in .dm files: choose File/New --> Code File.
// BEGIN_INTERNALS
// END_INTERNALS
// BEGIN_FILE_DIR
@@ -152,6 +152,7 @@
#include "code\__HELPERS\icons.dm"
#include "code\__HELPERS\job.dm"
#include "code\__HELPERS\level_traits.dm"
+#include "code\__HELPERS\lighting.dm"
#include "code\__HELPERS\lists.dm"
#include "code\__HELPERS\logging.dm"
#include "code\__HELPERS\matrices.dm"
@@ -209,7 +210,6 @@
#include "code\_onclick\hud\rendering\plane_master.dm"
#include "code\_onclick\hud\rendering\plane_master_controller.dm"
#include "code\_onclick\hud\rendering\render_plate.dm"
-#include "code\controllers\_DynamicAreaLighting_TG.dm"
#include "code\controllers\shuttle_controller.dm"
#include "code\controllers\topic.dm"
#include "code\controllers\configuration\config_entry.dm"
@@ -369,6 +369,7 @@
#include "code\datums\components\id_lock.dm"
#include "code\datums\components\label.dm"
#include "code\datums\components\orbiter.dm"
+#include "code\datums\components\overlay_lighting.dm"
#include "code\datums\components\rename.dm"
#include "code\datums\components\speed_modifier.dm"
#include "code\datums\components\toxin_buildup.dm"
@@ -440,6 +441,7 @@
#include "code\datums\elements\_element.dm"
#include "code\datums\elements\bloody_feet.dm"
#include "code\datums\elements\drop_retrieval.dm"
+#include "code\datums\elements\light_blocking.dm"
#include "code\datums\elements\mouth_drop_item.dm"
#include "code\datums\elements\poor_eyesight_correction.dm"
#include "code\datums\elements\suturing.dm"
@@ -741,6 +743,7 @@
#include "code\game\machinery\autolathe_datums.dm"
#include "code\game\machinery\Beacon.dm"
#include "code\game\machinery\bio-dome_floodlights.dm"
+#include "code\game\machinery\biohazard_lockdown.dm"
#include "code\game\machinery\bioprinter.dm"
#include "code\game\machinery\buttons.dm"
#include "code\game\machinery\cell_charger.dm"
@@ -1017,6 +1020,7 @@
#include "code\game\objects\items\devices\flash.dm"
#include "code\game\objects\items\devices\flashlight.dm"
#include "code\game\objects\items\devices\floor_painter.dm"
+#include "code\game\objects\items\devices\helmet_visors.dm"
#include "code\game\objects\items\devices\lightreplacer.dm"
#include "code\game\objects\items\devices\megaphone.dm"
#include "code\game\objects\items\devices\motion_detector.dm"
@@ -1685,6 +1689,21 @@
#include "code\modules\law\laws\major_crime.dm"
#include "code\modules\law\laws\minor_crime.dm"
#include "code\modules\law\laws\optional.dm"
+#include "code\modules\lighting\emissive_blocker.dm"
+#include "code\modules\lighting\lighting_area.dm"
+#include "code\modules\lighting\lighting_atom.dm"
+#include "code\modules\lighting\lighting_turf.dm"
+#include "code\modules\lighting\lighting_mask\dynamic_lighting_source.dm"
+#include "code\modules\lighting\lighting_mask\lighting_mask.dm"
+#include "code\modules\lighting\lighting_mask\lighting_mask_holder.dm"
+#include "code\modules\lighting\lighting_mask\shadow_calculator.dm"
+#include "code\modules\lighting\lighting_static\static_lighting_area.dm"
+#include "code\modules\lighting\lighting_static\static_lighting_atom.dm"
+#include "code\modules\lighting\lighting_static\static_lighting_corner.dm"
+#include "code\modules\lighting\lighting_static\static_lighting_object.dm"
+#include "code\modules\lighting\lighting_static\static_lighting_setup.dm"
+#include "code\modules\lighting\lighting_static\static_lighting_source.dm"
+#include "code\modules\lighting\lighting_static\static_lighting_turf.dm"
#include "code\modules\logging\global_logs.dm"
#include "code\modules\logging\log_category.dm"
#include "code\modules\logging\log_holder.dm"
@@ -2159,6 +2178,7 @@
#include "code\modules\security_levels\security_levels.dm"
#include "code\modules\shuttle\computer.dm"
#include "code\modules\shuttle\docking.dm"
+#include "code\modules\shuttle\dropship.dm"
#include "code\modules\shuttle\dropship_hijack.dm"
#include "code\modules\shuttle\helpers.dm"
#include "code\modules\shuttle\lifeboats.dm"
diff --git a/html/changelogs/AutoChangeLog-pr-4035.yml b/html/changelogs/AutoChangeLog-pr-4035.yml
deleted file mode 100644
index 90ffb5a71740..000000000000
--- a/html/changelogs/AutoChangeLog-pr-4035.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-author: "realforest2001"
-delete-after: True
-changes:
- - code_imp: "Overhauled how ID accesses are assigned via proc, compiling all the many different procs we used into one."
- - rscadd: "Added faction specific accesses to all major factions."
- - rscdel: "Removed almost all marine accesses from non marine presets. No more free CIC access to CLF."
- - code_imp: "Removed duplicate code in the VAI file."
- - rscadd: "Adds a mapping var to indicate a door has non-standard access tags. This is to make it significantly easier for any future access changes to know if they need to look somewhere."
- - maptweak: "Applied this var to every door I could find on the Almayer that has non-standard access. Colonies and other stuff to come in a future update."
- - rscadd: "Added various new accesses to colonial doors, added WY_SECURITY and WY_RESEARCH to marine research doors."
- - maptweak: "Added reinforced piping to lifeboats area. Didn't make much sense for a cruicial part of the evacuation procedures to be prone to spontaneous explosions that can singlehandedly end a marine evacuation without hostiles ever seeing it."
- - maptweak: "Added reinforced piping to the research closed loop (it's a closed loop). Also removed CIC access from containment shutters as CIC access can't open the doors."
- - maptweak: "Changed a couple walls around research from standard to reinforced, to fit with the containment breach shutters."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4205.yml b/html/changelogs/AutoChangeLog-pr-4205.yml
deleted file mode 100644
index 5615e43f39d2..000000000000
--- a/html/changelogs/AutoChangeLog-pr-4205.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "harryob"
-delete-after: True
-changes:
- - rscadd: "you always see lobby art while the world is setting up"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4226.yml b/html/changelogs/AutoChangeLog-pr-4226.yml
deleted file mode 100644
index 781b47852cf1..000000000000
--- a/html/changelogs/AutoChangeLog-pr-4226.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CapCamIII"
-delete-after: True
-changes:
- - bugfix: "UPP soldier preset works again"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4229.yml b/html/changelogs/AutoChangeLog-pr-4229.yml
new file mode 100644
index 000000000000..540f5be31d69
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4229.yml
@@ -0,0 +1,4 @@
+author: "TiviPlus, A-lexa, SyncIt21, Azarak, harryob, MorrowWolf, Zonespace"
+delete-after: True
+changes:
+ - rscadd: "shadows are now in the game, and light follows you."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4258.yml b/html/changelogs/AutoChangeLog-pr-4258.yml
new file mode 100644
index 000000000000..ef01fcfa19ff
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4258.yml
@@ -0,0 +1,4 @@
+author: "MikeKuwait"
+delete-after: True
+changes:
+ - bugfix: "teleporting canister pouch to chemical dispenser"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4259.yml b/html/changelogs/AutoChangeLog-pr-4259.yml
new file mode 100644
index 000000000000..76d084cf6b12
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4259.yml
@@ -0,0 +1,4 @@
+author: "MikeKuwait"
+delete-after: True
+changes:
+ - bugfix: "Plants should not grow every time it's sampled"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4261.yml b/html/changelogs/AutoChangeLog-pr-4261.yml
new file mode 100644
index 000000000000..78cd6c82d21a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4261.yml
@@ -0,0 +1,4 @@
+author: "Morrow"
+delete-after: True
+changes:
+ - bugfix: "Fixed pointblanks"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4263.yml b/html/changelogs/AutoChangeLog-pr-4263.yml
new file mode 100644
index 000000000000..f6beeab795db
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4263.yml
@@ -0,0 +1,5 @@
+author: "Steelpoint"
+delete-after: True
+changes:
+ - rscadd: "IO's and FTL's can now purchase a 'welding visor' from their vendor. This visor grants whichever helmet it is attached with the ability to flip a protective visor that prevents the user's eyes from taking damage while welding."
+ - balance: "The M12 Helmet, normally used by FTL's and USCM Officers, can mount two visors at once, instead of only one."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4264.yml b/html/changelogs/AutoChangeLog-pr-4264.yml
new file mode 100644
index 000000000000..515720e1fb06
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4264.yml
@@ -0,0 +1,4 @@
+author: "Morrow"
+delete-after: True
+changes:
+ - bugfix: "Fixed western medbay door buttons"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4265.yml b/html/changelogs/AutoChangeLog-pr-4265.yml
new file mode 100644
index 000000000000..0dfffbd61f9c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4265.yml
@@ -0,0 +1,4 @@
+author: "CapCamIII"
+delete-after: True
+changes:
+ - bugfix: "actually fixes m4ra custom barrel offset"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4266.yml b/html/changelogs/AutoChangeLog-pr-4266.yml
new file mode 100644
index 000000000000..6db5fd504bd5
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4266.yml
@@ -0,0 +1,4 @@
+author: "Xufysz"
+delete-after: True
+changes:
+ - bugfix: "Fixes the kitchen soda fountain being wrenchable."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4267.yml b/html/changelogs/AutoChangeLog-pr-4267.yml
new file mode 100644
index 000000000000..9951fc30945a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4267.yml
@@ -0,0 +1,5 @@
+author: "realforest2001"
+delete-after: True
+changes:
+ - code_imp: "Moved the Request ERT message to a proc to reduce duplication."
+ - admin: "Added a detail in ERT request to indicate if a RANDOM ERT was granted by staff already or not. This will not work for manual specific chosen ERTs."
\ No newline at end of file
diff --git a/html/changelogs/archive/2023-08.yml b/html/changelogs/archive/2023-08.yml
index ee712fb75694..bcbe26a9a6c4 100644
--- a/html/changelogs/archive/2023-08.yml
+++ b/html/changelogs/archive/2023-08.yml
@@ -287,3 +287,139 @@
CapCamIII:
- bugfix: fixes the offset on m4ra custom barrel, it should appropriately be sat
right on the gun sprite
+2023-08-23:
+ CapCamIII:
+ - bugfix: UPP soldier preset works again
+ Drathek:
+ - bugfix: Fixed a cade attack exploit
+ Huffie56:
+ - bugfix: you will no longer be able to feed without any limit with the fork.
+ - bugfix: Whiskey Outpost Chem master will now be connected to the smartfridge.
+ harryob:
+ - rscadd: you always see lobby art while the world is setting up
+ realforest2001:
+ - code_imp: Overhauled how ID accesses are assigned via proc, compiling all the
+ many different procs we used into one.
+ - rscadd: Added faction specific accesses to all major factions.
+ - rscdel: Removed almost all marine accesses from non marine presets. No more free
+ CIC access to CLF.
+ - code_imp: Removed duplicate code in the VAI file.
+ - rscadd: Adds a mapping var to indicate a door has non-standard access tags. This
+ is to make it significantly easier for any future access changes to know if
+ they need to look somewhere.
+ - maptweak: Applied this var to every door I could find on the Almayer that has
+ non-standard access. Colonies and other stuff to come in a future update.
+ - rscadd: Added various new accesses to colonial doors, added WY_SECURITY and WY_RESEARCH
+ to marine research doors.
+ - maptweak: Added reinforced piping to lifeboats area. Didn't make much sense for
+ a cruicial part of the evacuation procedures to be prone to spontaneous explosions
+ that can singlehandedly end a marine evacuation without hostiles ever seeing
+ it.
+ - maptweak: Added reinforced piping to the research closed loop (it's a closed loop).
+ Also removed CIC access from containment shutters as CIC access can't open the
+ doors.
+ - maptweak: Changed a couple walls around research from standard to reinforced,
+ to fit with the containment breach shutters.
+2023-08-24:
+ Morrow:
+ - bugfix: Possible fix for binoc perma zoom
+ - balance: M4RA damage buffed by 10%
+ Zonespace27:
+ - balance: The M41A, M41Amk1, m39, m46c (iff off), mar-30/40/60, type 71, laser
+ uzi, and every SMG now has automatic fire.
+ - balance: The HPR can now fire in full auto when bipodded.
+ - bugfix: Adding/removing attachments now keeps the current firemode, if possible.
+ - bugfix: The dualtube and spec sniper now can switch tubes/toggle laser again.
+ - bugfix: Fixed a long-standing exploit with bipods and scopes.
+ - bugfix: Fixed guns jamming when shooting UI elements.
+ - bugfix: Fixed a bunch of guns unintentionally having burst.
+ - balance: You can transfer ammo between HPR ammo boxes by hitting one with another.
+ realforest2001:
+ - rscadd: Gave the ASO ability to modify IDs.
+ - rscdel: Removed this from the QM.
+2023-08-25:
+ Huffie56:
+ - bugfix: add a check before people start the long process of unlock the DS so that
+ people don't waste time.
+ realforest2001:
+ - rscadd: Added a new lockdown system to research.
+ - rscadd: Added an admin button to interact with above.
+2023-08-26:
+ CapCamIII:
+ - rscadd: Adds 6(8 if you're pedantic) new guns for the UPP, details for each in
+ following lines.
+ - rscadd: Type 19, Replacement for PPsh on colonies and black market.
+ - rscadd: Type 64, replacement for scorpion, full sized SMG, 2 versions, 1 for upp,
+ 1 for not upp
+ - rscadd: HJRA-12, RPG for UPP.
+ - rscadd: Type 73, pistol for higher ranked UPP troops, UPP COs get a Type 74 which
+ has high-impact rounds, replaces PK9 in non-UPP use.
+ - rscadd: NP92, pistol, replaces PK9 in UPP use(mostly), integrally suppressed version
+ called NPZ92 for UPP Commandos.
+ - rscadd: QYJ-72, UPP GPMG, replaces minigun with UPP Minigunners
+ - rscadd: Technically resprites but due to changes closer to replaces N-Y revolver
+ with ZHNK-72
+ - rscadd: Adds a character custom loadout Type 73, 2 mags spare.
+ - rscadd: UPP helmets now work as ear protection, intended use with HJRA-12 RPG
+ - rscadd: UPP officers now have regular UM4 helmets instead of UH7 helmets in their
+ vendors as UH7 looked ugly with their combat gear
+ - rscdel: Removes the PK9 entirely
+ - rscdel: Removes tranqs from UPP Commando loadout
+ - rscdel: Removes HEAP ammo from UPP officers and commandos, replaced with normal
+ and AP mags when applicable
+ - balance: UPP jackets no longer have massive armor, in exchange they no longer
+ slow and in clothing vendors a light version of UPP armor is vendable
+ - balance: UPP MPs are now armed with a ZHNK-72 belt on their jacket, with an additional
+ shrapnelshot loader in their belt.
+ - balance: Rebalances Type 71 damage/firerate/AP to be a sidegrade of M41A, about
+ equal DPS, higher damage per shot and AP, lower fire rate, carbine is round-about
+ the exact same as M41A however.
+ - balance: Fixes UPP support armor, given to medics on their person and officers
+ in their vendor, lighter version of UPP armor, exchanges protection for speed.
+ - balance: Seperates SVD bullet damage from crude rifle bullet and buffs it as a
+ hard-hitting AP bullet.
+ - balance: Rebalances UPP revolver(now ZHNK-72), much harder hitting and has higher
+ AP, but rarer, shrapnelshot extremely rare and good.
+ - balance: Due to ammo changes, SVD no longer has burst.
+ - balance: Removes ceramic plates from UPP loadouts
+ - bugfix: UPP Major now has the correct UPP Commander skillset
+ - bugfix: UPP Commander skillset can BE
+ - bugfix: Fixes typepath for UPP support/light armor, actually works now.
+ - spellcheck: Renames SVD to Type 88
+ - spellcheck: Renames UPP Minigunner to UPP Machinegunner
+ - spellcheck: Renames UPP jackets to UL4 all around
+ - soundadd: Adds firing sounds for Type 73 and SVD/UPP MG
+ - imageadd: Resprites the SVD, Type 71, and Type 23, all sprites by wei/esselnek
+ - imageadd: Adds sprites for all above guns, all sprites by wei/esselnek
+ - maptweak: Changes instances of skorpion to non-upp type 64, also changes instances
+ of ppsh to type 19
+ Diegoflores31:
+ - balance: Masterkey and underbarrel extinguisher now must be wielded in order to
+ be used.
+ - bugfix: Underbarrel extinguisher no longer bypass wielding restrictions on flamers.
+ Morrow:
+ - balance: You now lose nutrition when gaining blood rather than losing a ton of
+ nutrition when you have low effective blood
+ Morrow, Frans_Feiffer (beautiful sprites):
+ - rscadd: Added in built HUDs to various helmets
+ - rscadd: Sensormates used by squads without medical skills have been converted
+ to buyable helmet optics
+ realforest2001:
+ - code_imp: Changed backend for the message of walking into an invisible wall to
+ reduce duplication.
+ - rscadd: Telephones can now receive calls from multiple networks.
+ - rscadd: Adds UPP, CLF and WY prefab phones.
+ - bugfix: UPP RTO pack is now titled UPP rather than USCM
+2023-08-27:
+ AnuvKH:
+ - maptweak: Fixed deep ocean around NV monsoon, removed incend ammo.
+ Diegoflores31:
+ - bugfix: Glasses with flash protection can no longer be used for welding.
+ - refactor: Adds defines for negative welding protection.
+ Morrow:
+ - bugfix: fixed a bypass to allow ghost scan health when it should not be allowed
+ cuberound:
+ - rscadd: UPP SL gets proper bag with mini fire extinguisher three WP grenades ,
+ two snacks and an AP mag
+ harryob:
+ - bugfix: whispering no longer uses the old speech bubble
diff --git a/icons/effects/alphacolors.dmi b/icons/effects/alphacolors.dmi
index 02316fbf64de..6bb903862ca0 100644
Binary files a/icons/effects/alphacolors.dmi and b/icons/effects/alphacolors.dmi differ
diff --git a/icons/effects/light_overlays/light_128.dmi b/icons/effects/light_overlays/light_128.dmi
new file mode 100644
index 000000000000..22dc0b010870
Binary files /dev/null and b/icons/effects/light_overlays/light_128.dmi differ
diff --git a/icons/effects/light_overlays/light_160.dmi b/icons/effects/light_overlays/light_160.dmi
new file mode 100644
index 000000000000..26dfa453c516
Binary files /dev/null and b/icons/effects/light_overlays/light_160.dmi differ
diff --git a/icons/effects/light_overlays/light_192.dmi b/icons/effects/light_overlays/light_192.dmi
new file mode 100644
index 000000000000..aca94ee0caf5
Binary files /dev/null and b/icons/effects/light_overlays/light_192.dmi differ
diff --git a/icons/effects/light_overlays/light_224.dmi b/icons/effects/light_overlays/light_224.dmi
new file mode 100644
index 000000000000..9fab531d1a69
Binary files /dev/null and b/icons/effects/light_overlays/light_224.dmi differ
diff --git a/icons/effects/light_overlays/light_256.dmi b/icons/effects/light_overlays/light_256.dmi
new file mode 100644
index 000000000000..701562efcd8f
Binary files /dev/null and b/icons/effects/light_overlays/light_256.dmi differ
diff --git a/icons/effects/light_overlays/light_288.dmi b/icons/effects/light_overlays/light_288.dmi
new file mode 100644
index 000000000000..b6eac180f7aa
Binary files /dev/null and b/icons/effects/light_overlays/light_288.dmi differ
diff --git a/icons/effects/light_overlays/light_32.dmi b/icons/effects/light_overlays/light_32.dmi
new file mode 100644
index 000000000000..5269b1fba36d
Binary files /dev/null and b/icons/effects/light_overlays/light_32.dmi differ
diff --git a/icons/effects/light_overlays/light_320.dmi b/icons/effects/light_overlays/light_320.dmi
new file mode 100644
index 000000000000..bf263c4b29be
Binary files /dev/null and b/icons/effects/light_overlays/light_320.dmi differ
diff --git a/icons/effects/light_overlays/light_352.dmi b/icons/effects/light_overlays/light_352.dmi
new file mode 100644
index 000000000000..f895792da42d
Binary files /dev/null and b/icons/effects/light_overlays/light_352.dmi differ
diff --git a/icons/effects/light_overlays/light_384.dmi b/icons/effects/light_overlays/light_384.dmi
new file mode 100644
index 000000000000..ef2a4c97e047
Binary files /dev/null and b/icons/effects/light_overlays/light_384.dmi differ
diff --git a/icons/effects/light_overlays/light_416.dmi b/icons/effects/light_overlays/light_416.dmi
new file mode 100644
index 000000000000..6a32ecbda661
Binary files /dev/null and b/icons/effects/light_overlays/light_416.dmi differ
diff --git a/icons/effects/light_overlays/light_64.dmi b/icons/effects/light_overlays/light_64.dmi
new file mode 100644
index 000000000000..37fc5084abcf
Binary files /dev/null and b/icons/effects/light_overlays/light_64.dmi differ
diff --git a/icons/effects/light_overlays/light_96.dmi b/icons/effects/light_overlays/light_96.dmi
new file mode 100644
index 000000000000..b689a1370163
Binary files /dev/null and b/icons/effects/light_overlays/light_96.dmi differ
diff --git a/icons/effects/light_overlays/light_cone.dmi b/icons/effects/light_overlays/light_cone.dmi
new file mode 100644
index 000000000000..75f322a93717
Binary files /dev/null and b/icons/effects/light_overlays/light_cone.dmi differ
diff --git a/icons/effects/light_overlays/shockwave.dmi b/icons/effects/light_overlays/shockwave.dmi
new file mode 100644
index 000000000000..c22acfa1d59e
Binary files /dev/null and b/icons/effects/light_overlays/shockwave.dmi differ
diff --git a/icons/effects/lighting_object.dmi b/icons/effects/lighting_object.dmi
new file mode 100644
index 000000000000..60ca2d313f6c
Binary files /dev/null and b/icons/effects/lighting_object.dmi differ
diff --git a/icons/effects/lighting_object_big.dmi b/icons/effects/lighting_object_big.dmi
new file mode 100644
index 000000000000..d96db059bedb
Binary files /dev/null and b/icons/effects/lighting_object_big.dmi differ
diff --git a/icons/mob/humans/onmob/back.dmi b/icons/mob/humans/onmob/back.dmi
index 969016a4a4e5..e4f228109127 100644
Binary files a/icons/mob/humans/onmob/back.dmi and b/icons/mob/humans/onmob/back.dmi differ
diff --git a/icons/mob/humans/onmob/head_1.dmi b/icons/mob/humans/onmob/head_1.dmi
index 0fb5700225e3..7f78ce119341 100644
Binary files a/icons/mob/humans/onmob/head_1.dmi and b/icons/mob/humans/onmob/head_1.dmi differ
diff --git a/icons/mob/humans/onmob/helmet_garb.dmi b/icons/mob/humans/onmob/helmet_garb.dmi
index 3bb63088783f..325aed72b155 100644
Binary files a/icons/mob/humans/onmob/helmet_garb.dmi and b/icons/mob/humans/onmob/helmet_garb.dmi differ
diff --git a/icons/mob/humans/onmob/items_lefthand_1.dmi b/icons/mob/humans/onmob/items_lefthand_1.dmi
index d65bcccc02af..75c578316c83 100644
Binary files a/icons/mob/humans/onmob/items_lefthand_1.dmi and b/icons/mob/humans/onmob/items_lefthand_1.dmi differ
diff --git a/icons/mob/humans/onmob/items_righthand_1.dmi b/icons/mob/humans/onmob/items_righthand_1.dmi
index f9b5350d6a7b..4f98571ff715 100644
Binary files a/icons/mob/humans/onmob/items_righthand_1.dmi and b/icons/mob/humans/onmob/items_righthand_1.dmi differ
diff --git a/icons/mob/humans/onmob/suit_slot.dmi b/icons/mob/humans/onmob/suit_slot.dmi
index df588b9b59ca..9f0e15209fe6 100644
Binary files a/icons/mob/humans/onmob/suit_slot.dmi and b/icons/mob/humans/onmob/suit_slot.dmi differ
diff --git a/icons/obj/items/clothing/belts.dmi b/icons/obj/items/clothing/belts.dmi
index e561b5f84548..989a2eb5b9ec 100644
Binary files a/icons/obj/items/clothing/belts.dmi and b/icons/obj/items/clothing/belts.dmi differ
diff --git a/icons/obj/items/clothing/helmet_visors.dmi b/icons/obj/items/clothing/helmet_visors.dmi
new file mode 100644
index 000000000000..6ba0cfe5623e
Binary files /dev/null and b/icons/obj/items/clothing/helmet_visors.dmi differ
diff --git a/icons/obj/items/weapons/guns/ammo_by_faction/colony.dmi b/icons/obj/items/weapons/guns/ammo_by_faction/colony.dmi
index 6d0e08c40623..2adece3b1ab1 100644
Binary files a/icons/obj/items/weapons/guns/ammo_by_faction/colony.dmi and b/icons/obj/items/weapons/guns/ammo_by_faction/colony.dmi differ
diff --git a/icons/obj/items/weapons/guns/ammo_by_faction/event.dmi b/icons/obj/items/weapons/guns/ammo_by_faction/event.dmi
index 7328f00f8b3d..868ae1a1211a 100644
Binary files a/icons/obj/items/weapons/guns/ammo_by_faction/event.dmi and b/icons/obj/items/weapons/guns/ammo_by_faction/event.dmi differ
diff --git a/icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi b/icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi
index a6b212b5f0dc..6f160bbbe7cb 100644
Binary files a/icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi and b/icons/obj/items/weapons/guns/ammo_by_faction/upp.dmi differ
diff --git a/icons/obj/items/weapons/guns/attachments.dmi b/icons/obj/items/weapons/guns/attachments.dmi
index 4a879f0d91c0..332217fe1cf0 100644
Binary files a/icons/obj/items/weapons/guns/attachments.dmi and b/icons/obj/items/weapons/guns/attachments.dmi differ
diff --git a/icons/obj/items/weapons/guns/attachments/barrel.dmi b/icons/obj/items/weapons/guns/attachments/barrel.dmi
index d040aa85fd5d..aaa591f64a88 100644
Binary files a/icons/obj/items/weapons/guns/attachments/barrel.dmi and b/icons/obj/items/weapons/guns/attachments/barrel.dmi differ
diff --git a/icons/obj/items/weapons/guns/attachments/stock.dmi b/icons/obj/items/weapons/guns/attachments/stock.dmi
index 8eb95d15770f..330102213689 100644
Binary files a/icons/obj/items/weapons/guns/attachments/stock.dmi and b/icons/obj/items/weapons/guns/attachments/stock.dmi differ
diff --git a/icons/obj/items/weapons/guns/guns_by_faction/colony.dmi b/icons/obj/items/weapons/guns/guns_by_faction/colony.dmi
index 1e659671c999..caa62ef55605 100644
Binary files a/icons/obj/items/weapons/guns/guns_by_faction/colony.dmi and b/icons/obj/items/weapons/guns/guns_by_faction/colony.dmi differ
diff --git a/icons/obj/items/weapons/guns/guns_by_faction/event.dmi b/icons/obj/items/weapons/guns/guns_by_faction/event.dmi
index 3494faec7f7e..4c517b712bb2 100644
Binary files a/icons/obj/items/weapons/guns/guns_by_faction/event.dmi and b/icons/obj/items/weapons/guns/guns_by_faction/event.dmi differ
diff --git a/icons/obj/items/weapons/guns/guns_by_faction/upp.dmi b/icons/obj/items/weapons/guns/guns_by_faction/upp.dmi
index 68919a4b9db4..669efcfc59c4 100644
Binary files a/icons/obj/items/weapons/guns/guns_by_faction/upp.dmi and b/icons/obj/items/weapons/guns/guns_by_faction/upp.dmi differ
diff --git a/icons/obj/items/weapons/guns/legacy/old_cmguns.dmi b/icons/obj/items/weapons/guns/legacy/old_cmguns.dmi
index 24cade43454f..0c416b3605e4 100644
Binary files a/icons/obj/items/weapons/guns/legacy/old_cmguns.dmi and b/icons/obj/items/weapons/guns/legacy/old_cmguns.dmi differ
diff --git a/icons/obj/structures/doors/blastdoors_shutters.dmi b/icons/obj/structures/doors/blastdoors_shutters.dmi
index 0c91c00f0f79..c5ec97be49b8 100644
Binary files a/icons/obj/structures/doors/blastdoors_shutters.dmi and b/icons/obj/structures/doors/blastdoors_shutters.dmi differ
diff --git a/maps/map_files/BigRed/BigRed.dmm b/maps/map_files/BigRed/BigRed.dmm
index 32259fa72f45..4ec089e10bdd 100644
--- a/maps/map_files/BigRed/BigRed.dmm
+++ b/maps/map_files/BigRed/BigRed.dmm
@@ -30946,6 +30946,28 @@
icon_state = "floor5"
},
/area/bigredv2/oob)
+"jRi" = (
+/obj/item/ammo_magazine/smg/bizon{
+ pixel_x = 5;
+ pixel_y = -5
+ },
+/obj/item/weapon/gun/smg/bizon{
+ pixel_x = 1;
+ pixel_y = 11
+ },
+/obj/item/ammo_magazine/smg/bizon{
+ pixel_x = 11;
+ pixel_y = -3
+ },
+/obj/item/ammo_magazine/smg/bizon,
+/obj/structure/machinery/light/small{
+ dir = 8
+ },
+/turf/open/floor/plating{
+ dir = 8;
+ icon_state = "platingdmg3"
+ },
+/area/bigredv2/caves/mining)
"jUc" = (
/obj/structure/surface/table,
/obj/effect/landmark/item_pool_spawner/survivor_ammo/buckshot,
@@ -32113,28 +32135,6 @@
icon_state = "platingdmg3"
},
/area/bigredv2/caves/mining)
-"mmz" = (
-/obj/item/ammo_magazine/pistol/skorpion{
- pixel_x = 5;
- pixel_y = -5
- },
-/obj/item/weapon/gun/pistol/skorpion{
- pixel_x = 1;
- pixel_y = 11
- },
-/obj/item/ammo_magazine/pistol/skorpion{
- pixel_x = 11;
- pixel_y = -3
- },
-/obj/item/ammo_magazine/pistol/skorpion,
-/obj/structure/machinery/light/small{
- dir = 8
- },
-/turf/open/floor/plating{
- dir = 8;
- icon_state = "platingdmg3"
- },
-/area/bigredv2/caves/mining)
"moE" = (
/turf/open/mars_cave{
icon_state = "mars_cave_9"
@@ -42324,7 +42324,7 @@ aao
aao
uHQ
rMg
-mmz
+jRi
uHQ
rYD
rtS
@@ -43253,7 +43253,7 @@ aah
aah
aaF
aah
-aau
+aah
aei
aaf
aaf
@@ -44111,7 +44111,7 @@ aah
aah
aah
aah
-aah
+aau
aah
aah
aah
@@ -44655,7 +44655,7 @@ bjo
bie
bje
bie
-biI
+bie
bsc
eWd
eWd
@@ -45513,7 +45513,7 @@ bie
bie
bie
bie
-bie
+biI
bie
bie
bie
diff --git a/maps/map_files/CORSAT/Corsat.dmm b/maps/map_files/CORSAT/Corsat.dmm
index 3fefea9f08b0..88b90c7180e0 100644
--- a/maps/map_files/CORSAT/Corsat.dmm
+++ b/maps/map_files/CORSAT/Corsat.dmm
@@ -585,15 +585,6 @@
icon_state = "warnplate"
},
/area/corsat/gamma/hangar)
-"abW" = (
-/obj/docking_port/stationary/marine_dropship/lz1{
- dwidth = 1;
- name = "Gamma Landing Zone"
- },
-/turf/open/floor/plating{
- icon_state = "warnplate"
- },
-/area/corsat/gamma/hangar)
"abX" = (
/turf/open/floor/plating/icefloor{
icon_state = "warnplate"
@@ -1897,15 +1888,6 @@
icon_state = "warnplate"
},
/area/corsat/sigma/hangar)
-"afO" = (
-/obj/docking_port/stationary/marine_dropship/lz2{
- dwidth = 1;
- name = "Sigma Landing Zone"
- },
-/turf/open/floor/plating{
- icon_state = "warnplate"
- },
-/area/corsat/sigma/hangar)
"afP" = (
/turf/open/floor/plating/icefloor{
icon_state = "warnplate"
@@ -37491,6 +37473,13 @@
icon_state = "purplewhite"
},
/area/corsat/gamma/biodome/virology)
+"drp" = (
+/obj/docking_port/stationary/marine_dropship/lz1{
+ dwidth = 1;
+ name = "Gamma Landing Zone"
+ },
+/turf/open/floor/plating,
+/area/corsat/gamma/hangar)
"drv" = (
/obj/effect/landmark/hunter_secondary,
/turf/open/gm/river/desert/shallow{
@@ -38260,6 +38249,13 @@
icon_state = "purplewhite"
},
/area/corsat/omega/complex)
+"dUj" = (
+/obj/docking_port/stationary/marine_dropship/lz2{
+ dwidth = 1;
+ name = "Sigma Landing Zone"
+ },
+/turf/open/floor/plating,
+/area/corsat/sigma/hangar)
"dUn" = (
/obj/structure/machinery/camera/autoname{
network = list("gamma")
@@ -93444,7 +93440,7 @@ aaG
aaG
aaX
aaG
-abW
+bBX
aco
aaG
acG
@@ -94414,7 +94410,7 @@ aaG
aaG
aaG
aaG
-aaG
+drp
aaG
aaG
aaG
@@ -120957,7 +120953,7 @@ afi
afi
aeN
afi
-afO
+eDz
ajU
aeB
vkW
@@ -121927,7 +121923,7 @@ afi
afi
afi
afi
-afi
+dUj
afi
afi
afi
diff --git a/maps/map_files/DesertDam/Desert_Dam.dmm b/maps/map_files/DesertDam/Desert_Dam.dmm
index 938092bde688..3eb5dabff911 100644
--- a/maps/map_files/DesertDam/Desert_Dam.dmm
+++ b/maps/map_files/DesertDam/Desert_Dam.dmm
@@ -70315,7 +70315,7 @@ cDY
cDY
cDY
cDY
-cFa
+cDY
cML
cBS
cUl
@@ -71241,7 +71241,7 @@ cDY
cDY
cDY
cDY
-cDY
+cFa
cDY
cDY
cDY
@@ -73177,7 +73177,7 @@ aWh
aWh
aWh
aWh
-dGU
+aWh
bDO
aVi
aVh
@@ -74103,7 +74103,7 @@ aWh
aWh
aWh
aWh
-aWh
+dGU
aWh
aWh
aWh
diff --git a/maps/map_files/FOP_v2_Cellblocks/Prison_Station_FOP.dmm b/maps/map_files/FOP_v2_Cellblocks/Prison_Station_FOP.dmm
index 9cba60a14b40..0fd8b269d33c 100644
--- a/maps/map_files/FOP_v2_Cellblocks/Prison_Station_FOP.dmm
+++ b/maps/map_files/FOP_v2_Cellblocks/Prison_Station_FOP.dmm
@@ -88624,7 +88624,7 @@ amu
amu
amu
amu
-aoj
+amu
axz
jDr
uaW
@@ -89462,7 +89462,7 @@ amu
amu
amu
amu
-amu
+aoj
amu
amu
amu
@@ -99271,7 +99271,7 @@ aYM
aYM
aYM
aYM
-bcF
+aYM
btu
blH
bkt
@@ -100109,7 +100109,7 @@ aYM
aYM
aYM
aYM
-aYM
+bcF
aYM
aYM
aYM
diff --git a/maps/map_files/FOP_v3_Sciannex/Fiorina_SciAnnex.dmm b/maps/map_files/FOP_v3_Sciannex/Fiorina_SciAnnex.dmm
index 4e1f9e3437ce..9d8033ae0ae8 100644
--- a/maps/map_files/FOP_v3_Sciannex/Fiorina_SciAnnex.dmm
+++ b/maps/map_files/FOP_v3_Sciannex/Fiorina_SciAnnex.dmm
@@ -2251,10 +2251,6 @@
icon_state = "yellow"
},
/area/fiorina/station/lowsec)
-"bju" = (
-/obj/docking_port/stationary/marine_dropship/lz1,
-/turf/open/floor/plating/prison,
-/area/fiorina/lz/near_lzI)
"bjx" = (
/turf/open/floor/prison{
dir = 1;
@@ -6556,6 +6552,12 @@
icon_state = "blue_plate"
},
/area/fiorina/station/botany)
+"dYp" = (
+/obj/docking_port/stationary/marine_dropship/lz1{
+ name = "Hangar Landing Zone"
+ },
+/turf/open/floor/plating/prison,
+/area/fiorina/lz/near_lzI)
"dYr" = (
/obj/structure/surface/table/reinforced/prison,
/obj/item/explosive/grenade/incendiary/molotov,
@@ -16469,10 +16471,6 @@
icon_state = "bluefull"
},
/area/fiorina/station/power_ring)
-"kfE" = (
-/obj/docking_port/stationary/marine_dropship/lz2,
-/turf/open/floor/plating/prison,
-/area/fiorina/lz/near_lzII)
"kfF" = (
/obj/item/stack/sheet/metal,
/obj/item/stack/sheet/metal,
@@ -38473,6 +38471,10 @@
icon_state = "floor_plate"
},
/area/fiorina/station/civres_blue)
+"xYg" = (
+/obj/docking_port/stationary/marine_dropship/lz2,
+/turf/open/floor/plating/prison,
+/area/fiorina/lz/near_lzII)
"xYA" = (
/turf/open/floor/prison{
dir = 8;
@@ -72352,7 +72354,7 @@ wSm
wSm
xnU
wSm
-kfE
+wSm
eSF
qnB
fHB
@@ -73190,7 +73192,7 @@ wSm
wSm
wSm
wSm
-wSm
+xYg
wSm
wSm
wSm
@@ -88169,7 +88171,7 @@ xeO
xeO
cCx
xeO
-bju
+xeO
sLo
hlK
hKI
@@ -89007,7 +89009,7 @@ xeO
xeO
xeO
xeO
-xeO
+dYp
xeO
xeO
xeO
diff --git a/maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm b/maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm
index 76257b973b43..aaaaeb0c1199 100644
--- a/maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm
+++ b/maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm
@@ -16687,12 +16687,6 @@
"aWp" = (
/turf/open/floor/plating,
/area/ice_colony/exterior/surface/landing_pad)
-"aWq" = (
-/obj/docking_port/stationary/marine_dropship/lz1{
- name = "Hangar Landing Zone"
- },
-/turf/open/floor/plating,
-/area/ice_colony/exterior/surface/landing_pad)
"aWr" = (
/obj/structure/machinery/landinglight/ds1/delayone{
dir = 4
@@ -19850,12 +19844,6 @@
icon_state = "dark2"
},
/area/ice_colony/underground/requesition/lobby)
-"bhs" = (
-/obj/docking_port/stationary/marine_dropship/lz2,
-/turf/open/floor/plating/icefloor{
- icon_state = "warnplate"
- },
-/area/ice_colony/underground/hangar)
"bht" = (
/turf/open/floor/plating/icefloor{
icon_state = "warnplate"
@@ -34506,6 +34494,10 @@
icon_state = "dark2"
},
/area/ice_colony/surface/research)
+"cEG" = (
+/obj/docking_port/stationary/marine_dropship/lz2,
+/turf/open/floor/plating/icefloor,
+/area/ice_colony/underground/hangar)
"cVM" = (
/obj/structure/machinery/light/small{
dir = 8
@@ -34910,6 +34902,12 @@
icon_state = "darkbrown2"
},
/area/ice_colony/surface/hangar/alpha)
+"sto" = (
+/obj/docking_port/stationary/marine_dropship/lz1{
+ name = "Hangar Landing Zone"
+ },
+/turf/open/floor/plating,
+/area/ice_colony/exterior/surface/landing_pad)
"sKH" = (
/obj/structure/surface/table,
/obj/item/device/analyzer,
@@ -52476,7 +52474,7 @@ aZW
bcy
bbc
aZW
-bhs
+bht
bhG
bht
aZW
@@ -53594,7 +53592,7 @@ aZW
aZW
aZW
aZW
-aZW
+cEG
aZW
aZW
aZW
@@ -89400,7 +89398,7 @@ aWp
aWp
aWp
aWQ
-aWq
+aWp
bbl
aUP
aUP
@@ -90518,7 +90516,7 @@ aWp
aWp
aWp
aWp
-aWp
+sto
aWp
aWp
aWp
diff --git a/maps/map_files/Ice_Colony_v3/Shivas_Snowball.dmm b/maps/map_files/Ice_Colony_v3/Shivas_Snowball.dmm
index d221090da880..631e40c22643 100644
--- a/maps/map_files/Ice_Colony_v3/Shivas_Snowball.dmm
+++ b/maps/map_files/Ice_Colony_v3/Shivas_Snowball.dmm
@@ -10613,10 +10613,6 @@
icon_state = "multi_tiles"
},
/area/shiva/interior/colony/research_hab)
-"fiy" = (
-/obj/docking_port/stationary/marine_dropship/lz2,
-/turf/open/floor/plating,
-/area/shiva/exterior/lz2_fortress)
"fiK" = (
/turf/open/floor/wood,
/area/shiva/interior/colony/botany)
@@ -13499,6 +13495,16 @@
/obj/structure/machinery/colony_floodlight,
/turf/open/auto_turf/snow/layer3,
/area/shiva/exterior/cp_lz2)
+"ipY" = (
+/obj/structure/closet/secure_closet/engineering_personal,
+/obj/structure/machinery/light/double,
+/obj/item/weapon/gun/smg/pps43,
+/obj/item/ammo_magazine/smg/pps43,
+/obj/item/ammo_magazine/smg/pps43,
+/turf/open/floor/shiva{
+ dir = 1
+ },
+/area/shiva/interior/colony/medseceng)
"iqh" = (
/obj/item/device/flashlight,
/turf/open/floor/wood,
@@ -14877,6 +14883,15 @@
icon_state = "floor3"
},
/area/shiva/interior/caves/cp_camp)
+"jOA" = (
+/obj/structure/closet/secure_closet/engineering_personal,
+/obj/item/weapon/gun/smg/pps43,
+/obj/item/ammo_magazine/smg/pps43,
+/obj/item/ammo_magazine/smg/pps43,
+/turf/open/floor/shiva{
+ dir = 1
+ },
+/area/shiva/interior/colony/medseceng)
"jOP" = (
/obj/effect/decal/warning_stripes{
icon_state = "E-corner"
@@ -17359,6 +17374,12 @@
/obj/item/device/flashlight,
/turf/open/auto_turf/ice/layer0,
/area/shiva/interior/caves/s_lz2)
+"mlX" = (
+/obj/docking_port/stationary/marine_dropship/lz2{
+ name = "Research Landing Zone"
+ },
+/turf/open/floor/plating,
+/area/shiva/exterior/lz2_fortress)
"mms" = (
/turf/open/floor/shiva{
dir = 1
@@ -24176,15 +24197,6 @@
/obj/structure/blocker/invisible_wall,
/turf/open/auto_turf/snow/layer2,
/area/shiva/exterior/junkyard)
-"tJX" = (
-/obj/structure/closet/secure_closet/engineering_personal,
-/obj/item/weapon/gun/smg/ppsh,
-/obj/item/ammo_magazine/smg/ppsh,
-/obj/item/ammo_magazine/smg/ppsh,
-/turf/open/floor/shiva{
- dir = 1
- },
-/area/shiva/interior/colony/medseceng)
"tJY" = (
/obj/effect/decal/warning_stripes{
icon_state = "SW-out"
@@ -24854,9 +24866,6 @@
dir = 1
},
/area/shiva/interior/colony/medseceng)
-"ukJ" = (
-/turf/open/floor/shiva,
-/area/shiva/interior/colony/research_hab)
"ukU" = (
/obj/structure/surface/table,
/obj/item/clipboard,
@@ -27083,16 +27092,6 @@
/obj/structure/window/framed/shiva,
/turf/open/floor/plating/icefloor,
/area/shiva/interior/telecomm/lz1_biceps)
-"wOf" = (
-/obj/structure/closet/secure_closet/engineering_personal,
-/obj/structure/machinery/light/double,
-/obj/item/weapon/gun/smg/ppsh,
-/obj/item/ammo_magazine/smg/ppsh,
-/obj/item/ammo_magazine/smg/ppsh,
-/turf/open/floor/shiva{
- dir = 1
- },
-/area/shiva/interior/colony/medseceng)
"wOq" = (
/obj/structure/reagent_dispensers/water_cooler,
/turf/open/floor/shiva{
@@ -31179,7 +31178,7 @@ gkY
gkY
mFm
aar
-fiy
+gkY
kiv
mhP
mFm
@@ -31817,7 +31816,7 @@ gkY
gkY
gkY
gkY
-gkY
+mlX
gkY
gkY
gkY
@@ -36780,7 +36779,7 @@ tRq
chU
ogu
rZt
-ukJ
+rZt
asz
asz
qNE
@@ -54988,7 +54987,7 @@ fIz
acT
age
agh
-wOf
+ipY
acT
pCJ
agh
@@ -55150,7 +55149,7 @@ pxi
acT
afv
agh
-tJX
+jOA
acT
sxp
hCX
@@ -59474,7 +59473,7 @@ cQW
cQW
kLM
gGH
-boD
+cQW
kLM
uqb
lNg
@@ -60112,7 +60111,7 @@ cQW
cQW
cQW
cQW
-cQW
+boD
cQW
cQW
cQW
diff --git a/maps/map_files/Kutjevo/Kutjevo.dmm b/maps/map_files/Kutjevo/Kutjevo.dmm
index e5a6a43cf617..646ed4dcbc8c 100644
--- a/maps/map_files/Kutjevo/Kutjevo.dmm
+++ b/maps/map_files/Kutjevo/Kutjevo.dmm
@@ -4752,6 +4752,12 @@
},
/turf/open/auto_turf/sand/layer0,
/area/kutjevo/interior/oob)
+"gnj" = (
+/obj/docking_port/stationary/marine_dropship/lz1{
+ name = "Dunes Landing Zone"
+ },
+/turf/open/floor/plating/kutjevo,
+/area/shuttle/drop1/kutjevo)
"gnP" = (
/turf/open/floor/kutjevo/colors/cyan/tile,
/area/kutjevo/interior/complex/med/cells)
@@ -7172,12 +7178,6 @@
"jYS" = (
/turf/open/auto_turf/sand/layer2,
/area/kutjevo/interior/colony_S_East)
-"jZJ" = (
-/obj/docking_port/stationary/marine_dropship/lz1{
- name = "Dunes Landing Zone"
- },
-/turf/open/floor/plating/kutjevo,
-/area/shuttle/drop1/kutjevo)
"jZT" = (
/turf/open/floor/kutjevo/colors/cyan/edge{
dir = 8
@@ -7494,12 +7494,6 @@
/obj/effect/landmark/structure_spawner/setup/distress/xeno_wall,
/turf/open/auto_turf/sand/layer1,
/area/kutjevo/interior/colony_north)
-"kvd" = (
-/obj/docking_port/stationary/marine_dropship/lz2{
- name = "NW Colony Landing Zone"
- },
-/turf/open/floor/plating/kutjevo,
-/area/shuttle/drop2/kutjevo)
"kvf" = (
/obj/structure/platform_decoration/kutjevo/rock{
dir = 4
@@ -8095,6 +8089,12 @@
/obj/effect/landmark/corpsespawner/colonist/kutjevo,
/turf/open/gm/river/desert/deep/covered,
/area/kutjevo/interior/power/comms)
+"lkY" = (
+/obj/docking_port/stationary/marine_dropship/lz2{
+ name = "NW Colony Landing Zone"
+ },
+/turf/open/floor/plating/kutjevo,
+/area/shuttle/drop2/kutjevo)
"llg" = (
/obj/effect/decal/cleanable/blood/drip,
/turf/open/auto_turf/sand/layer0,
@@ -19888,7 +19888,7 @@ lAI
lAI
nbV
nbV
-jZJ
+lAI
nbV
usd
cWV
@@ -20546,7 +20546,7 @@ lAI
lAI
lAI
lAI
-lAI
+gnj
lAI
lAI
lAI
@@ -20960,7 +20960,7 @@ ppX
ppX
hzN
hzN
-kvd
+ppX
hzN
lNl
xBm
@@ -21618,7 +21618,7 @@ ppX
ppX
ppX
ppX
-ppX
+lkY
ppX
ppX
ppX
diff --git a/maps/map_files/LV522_Chances_Claim/LV522_Chances_Claim.dmm b/maps/map_files/LV522_Chances_Claim/LV522_Chances_Claim.dmm
index f8b678e825dd..9fcb8b7386a7 100644
--- a/maps/map_files/LV522_Chances_Claim/LV522_Chances_Claim.dmm
+++ b/maps/map_files/LV522_Chances_Claim/LV522_Chances_Claim.dmm
@@ -1009,6 +1009,12 @@
},
/turf/open/floor/plating,
/area/lv522/outdoors/colony_streets/north_east_street)
+"aDE" = (
+/obj/docking_port/stationary/marine_dropship/lz2{
+ name = "Southeast Landing Zone"
+ },
+/turf/open/floor/plating,
+/area/shuttle/drop2/lv522)
"aDS" = (
/turf/open/floor/corsat{
dir = 5;
@@ -2166,12 +2172,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/lv522/indoors/c_block/cargo)
-"bhy" = (
-/obj/docking_port/stationary/marine_dropship/lz1{
- name = "Southwest Landing Zone"
- },
-/turf/open/floor/plating,
-/area/shuttle/drop1/lv522)
"bhD" = (
/obj/structure/platform_decoration{
dir = 1
@@ -6938,6 +6938,12 @@
icon_state = "marked"
},
/area/lv522/indoors/a_block/dorms)
+"dos" = (
+/obj/docking_port/stationary/marine_dropship/lz1{
+ name = "Southwest Landing Zone"
+ },
+/turf/open/floor/plating,
+/area/shuttle/drop1/lv522)
"dox" = (
/obj/structure/prop/invuln/ice_prefab/roof_greeble{
icon_state = "vent5";
@@ -11236,12 +11242,6 @@
/obj/item/trash/plate,
/turf/open/floor/carpet,
/area/lv522/indoors/b_block/bar)
-"fdt" = (
-/obj/docking_port/stationary/marine_dropship/lz2{
- name = "Southeast Landing Zone"
- },
-/turf/open/floor/plating,
-/area/shuttle/drop2/lv522)
"fdC" = (
/obj/structure/machinery/light{
dir = 4
@@ -66151,7 +66151,7 @@ sYH
sYH
nFj
nFj
-bhy
+sYH
gnf
ryU
wes
@@ -67049,7 +67049,7 @@ sYH
sYH
sYH
sYH
-sYH
+dos
sYH
sYH
sYH
@@ -98401,7 +98401,7 @@ aIp
aIp
xYA
xYA
-fdt
+aIp
kcR
hIf
cDi
@@ -99299,7 +99299,7 @@ aIp
aIp
aIp
aIp
-aIp
+aDE
aIp
aIp
aIp
diff --git a/maps/map_files/LV624/LV624.dmm b/maps/map_files/LV624/LV624.dmm
index c0babffe0d94..d438b91d214a 100644
--- a/maps/map_files/LV624/LV624.dmm
+++ b/maps/map_files/LV624/LV624.dmm
@@ -28950,7 +28950,7 @@ aRg
aRg
aCi
aKO
-aBo
+aRg
aEw
aRg
wLz
@@ -29852,7 +29852,7 @@ aRg
aKO
aRg
aRg
-aRg
+aBo
aRg
aRg
aRg
@@ -55633,7 +55633,7 @@ ank
ank
ank
ank
-aLz
+ank
aSa
aMq
aky
@@ -56535,7 +56535,7 @@ ank
ank
ank
ank
-ank
+aLz
ank
ank
ank
diff --git a/maps/map_files/LV624/standalone/clfship.dmm b/maps/map_files/LV624/standalone/clfship.dmm
index 362eef00fd21..e69c2de5bcb8 100644
--- a/maps/map_files/LV624/standalone/clfship.dmm
+++ b/maps/map_files/LV624/standalone/clfship.dmm
@@ -161,9 +161,7 @@
},
/area/lv624/lazarus/crashed_ship)
"fA" = (
-/obj/structure/transmitter/colony_net{
- network_receive = "CLF";
- networks_transmit = list("CLF");
+/obj/structure/transmitter/clf_net{
phone_category = "CR-116";
phone_id = "Armoury";
pixel_y = 32
@@ -666,9 +664,7 @@
"sI" = (
/obj/structure/surface/table/reinforced/prison,
/obj/effect/spawner/random/toolbox,
-/obj/structure/transmitter/colony_net/rotary{
- network_receive = "CLF";
- networks_transmit = list("CLF");
+/obj/structure/transmitter/clf_net/rotary{
phone_category = "CR-116";
phone_color = "yellow";
phone_id = "Engineering"
@@ -1661,9 +1657,7 @@
/area/lv624/lazarus/crashed_ship)
"Qj" = (
/obj/structure/machinery/body_scanconsole,
-/obj/structure/transmitter/colony_net{
- network_receive = "CLF";
- networks_transmit = list("CLF");
+/obj/structure/transmitter/clf_net{
phone_category = "CR-116";
phone_color = "green";
phone_id = "Medical Bay";
@@ -1993,9 +1987,7 @@
},
/area/lv624/lazarus/crashed_ship)
"XM" = (
-/obj/structure/transmitter/colony_net{
- network_receive = "CLF";
- networks_transmit = list("CLF");
+/obj/structure/transmitter/clf_net{
phone_category = "CR-116";
phone_id = "Cargo Bay";
pixel_y = 32
diff --git a/maps/map_files/New_Varadero/New_Varadero.dmm b/maps/map_files/New_Varadero/New_Varadero.dmm
index 4488d13b9bc7..d315d9bfd84b 100644
--- a/maps/map_files/New_Varadero/New_Varadero.dmm
+++ b/maps/map_files/New_Varadero/New_Varadero.dmm
@@ -158,6 +158,30 @@
icon_state = "yellow"
},
/area/varadero/interior/cargo)
+"agi" = (
+/obj/structure/window/reinforced{
+ dir = 4;
+ pixel_x = -2;
+ pixel_y = 4
+ },
+/obj/structure/window/reinforced{
+ dir = 8;
+ layer = 3.3;
+ pixel_y = 4
+ },
+/obj/structure/bed{
+ can_buckle = 0
+ },
+/obj/structure/bed{
+ buckling_y = 13;
+ layer = 3.5;
+ pixel_y = 13
+ },
+/obj/structure/barricade/handrail/wire{
+ layer = 3.1
+ },
+/turf/open/floor/wood,
+/area/varadero/interior/bunks)
"agl" = (
/obj/effect/decal/cleanable/blood,
/turf/open/floor/wood,
@@ -1540,6 +1564,19 @@
icon_state = "asteroidplating"
},
/area/varadero/interior/maintenance/north)
+"aXn" = (
+/obj/structure/prop/rock/brown,
+/obj/effect/landmark/lv624/fog_blocker{
+ time_to_dispel = 25000
+ },
+/obj/effect/landmark/lv624/fog_blocker{
+ time_to_dispel = 25000
+ },
+/turf/open/gm/river{
+ name = "shallow ocean";
+ default_name = "shallow ocean"
+ },
+/area/varadero/exterior/eastocean)
"aXt" = (
/obj/structure/catwalk,
/obj/effect/decal/cleanable/blood/oil,
@@ -6621,6 +6658,18 @@
icon_state = "red"
},
/area/varadero/interior/medical)
+"esA" = (
+/obj/effect/landmark/lv624/fog_blocker{
+ time_to_dispel = 25000
+ },
+/obj/effect/landmark/lv624/fog_blocker{
+ time_to_dispel = 25000
+ },
+/turf/open/gm/river{
+ name = "shallow ocean";
+ default_name = "shallow ocean"
+ },
+/area/varadero/exterior/eastocean)
"esB" = (
/obj/structure/closet/radiation,
/obj/effect/landmark/crap_item,
@@ -8973,6 +9022,16 @@
icon_state = "asteroidplating"
},
/area/varadero/exterior/eastbeach)
+"fPy" = (
+/obj/structure/prop/rock/brown,
+/obj/effect/landmark/lv624/fog_blocker{
+ time_to_dispel = 25000
+ },
+/turf/open/gm/river{
+ name = "shallow ocean";
+ default_name = "shallow ocean"
+ },
+/area/varadero/exterior/eastocean)
"fPJ" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/auto_turf/sand_white/layer1,
@@ -10420,13 +10479,6 @@
icon_state = "greenfull"
},
/area/varadero/interior/hall_SE)
-"gIE" = (
-/obj/structure/flora/bush/ausbushes/var3/fernybush,
-/turf/open/gm/river/ocean{
- name = "deep ocean";
- default_name = "deep ocean"
- },
-/area/varadero/exterior/eastocean)
"gJs" = (
/obj/structure/pipes/standard/simple/hidden/green{
dir = 4
@@ -12233,15 +12285,6 @@
},
/turf/open/gm/dirt,
/area/varadero/exterior/pontoon_beach)
-"hXg" = (
-/obj/structure/bed/chair{
- dir = 1
- },
-/obj/structure/machinery/light,
-/turf/open/floor/shiva{
- icon_state = "green"
- },
-/area/varadero/interior/court)
"hXq" = (
/turf/open/floor/plating/icefloor{
icon_state = "asteroidplating"
@@ -17733,6 +17776,13 @@
icon_state = "asteroidplating"
},
/area/varadero/interior/comms1)
+"lxs" = (
+/obj/structure/flora/bush/ausbushes/var3/fernybush,
+/turf/open/gm/river{
+ name = "shallow ocean";
+ default_name = "shallow ocean"
+ },
+/area/varadero/exterior/eastocean)
"lxy" = (
/obj/structure/closet/secure_closet/personal,
/turf/open/floor/shiva{
@@ -20015,16 +20065,6 @@
default_name = "shallow ocean"
},
/area/varadero/exterior/pontoon_beach)
-"mRk" = (
-/obj/structure/prop/rock/brown,
-/obj/effect/landmark/lv624/fog_blocker{
- time_to_dispel = 25000
- },
-/turf/open/gm/river/ocean{
- name = "deep ocean";
- default_name = "deep ocean"
- },
-/area/varadero/exterior/eastocean)
"mRq" = (
/obj/structure/window/framed/colony,
/turf/open/floor/plating,
@@ -24535,19 +24575,6 @@
icon_state = "blue"
},
/area/varadero/interior/maintenance)
-"pNZ" = (
-/obj/structure/prop/rock/brown,
-/obj/effect/landmark/lv624/fog_blocker{
- time_to_dispel = 25000
- },
-/obj/effect/landmark/lv624/fog_blocker{
- time_to_dispel = 25000
- },
-/turf/open/gm/river/ocean{
- name = "deep ocean";
- default_name = "deep ocean"
- },
-/area/varadero/exterior/eastocean)
"pOa" = (
/obj/structure/largecrate/supply,
/turf/open/floor/plating/icefloor{
@@ -26171,15 +26198,6 @@
icon_state = "asteroidplating"
},
/area/varadero/interior/maintenance/research)
-"qNr" = (
-/obj/structure/flora/bush/ausbushes/var3/sparsegrass{
- icon_state = "sparsegrass_2"
- },
-/obj/effect/landmark/lv624/fog_blocker{
- time_to_dispel = 25000
- },
-/turf/open/gm/coast/beachcorner2/north_west,
-/area/varadero/exterior/eastocean)
"qNu" = (
/turf/open/gm/dirt{
icon_state = "desert1"
@@ -28386,15 +28404,6 @@
},
/turf/open/auto_turf/sand_white/layer1,
/area/varadero/interior/caves/east)
-"sfo" = (
-/obj/effect/landmark/lv624/fog_blocker{
- time_to_dispel = 25000
- },
-/turf/open/gm/river/ocean{
- name = "deep ocean";
- default_name = "deep ocean"
- },
-/area/varadero/exterior/eastocean)
"sfs" = (
/obj/structure/pipes/standard/simple/hidden/green{
dir = 4
@@ -31115,6 +31124,17 @@
icon_state = "multi_tiles"
},
/area/varadero/interior/hall_NW)
+"tTq" = (
+/obj/effect/landmark/lv624/fog_blocker{
+ time_to_dispel = 25000
+ },
+/obj/structure/blocker/invisible_wall/water,
+/obj/structure/flora/bush/ausbushes/var3/stalkybush,
+/turf/open/gm/river{
+ name = "shallow ocean";
+ default_name = "shallow ocean"
+ },
+/area/varadero/exterior/farocean)
"tTN" = (
/obj/structure/stairs/perspective{
color = "#b29082";
@@ -32077,18 +32097,6 @@
/obj/item/device/flashlight/lamp/green,
/turf/open/floor/wood,
/area/varadero/interior/hall_SE)
-"uDr" = (
-/obj/effect/landmark/lv624/fog_blocker{
- time_to_dispel = 25000
- },
-/obj/effect/landmark/lv624/fog_blocker{
- time_to_dispel = 25000
- },
-/turf/open/gm/river/ocean{
- name = "deep ocean";
- default_name = "deep ocean"
- },
-/area/varadero/exterior/eastocean)
"uDw" = (
/obj/structure/disposalpipe/segment{
dir = 4;
@@ -32219,31 +32227,6 @@
icon_state = "multi_tiles"
},
/area/varadero/interior/disposals)
-"uIj" = (
-/obj/structure/window/reinforced{
- dir = 4;
- pixel_x = -2;
- pixel_y = 4
- },
-/obj/structure/window/reinforced{
- dir = 8;
- layer = 3.3;
- pixel_y = 4
- },
-/obj/structure/bed{
- can_buckle = 0
- },
-/obj/structure/bed{
- buckling_y = 13;
- layer = 3.5;
- pixel_y = 13
- },
-/obj/structure/barricade/handrail/wire{
- layer = 3.1
- },
-/obj/item/ammo_magazine/handful/shotgun/incendiary,
-/turf/open/floor/wood,
-/area/varadero/interior/bunks)
"uIl" = (
/obj/structure/machinery/alarm{
dir = 4;
@@ -34499,6 +34482,32 @@
},
/turf/open/gm/dirt,
/area/varadero/exterior/eastbeach)
+"vYQ" = (
+/obj/structure/window/reinforced{
+ dir = 4;
+ pixel_x = -2;
+ pixel_y = 4
+ },
+/obj/structure/window/reinforced{
+ dir = 8;
+ layer = 3.3;
+ pixel_y = 4
+ },
+/obj/structure/bed{
+ can_buckle = 0
+ },
+/obj/structure/bed{
+ buckling_y = 13;
+ layer = 3.5;
+ pixel_y = 13
+ },
+/obj/structure/barricade/handrail/wire{
+ layer = 3.1
+ },
+/obj/item/ammo_magazine/handful/shotgun/buckshot,
+/obj/item/ammo_magazine/handful/shotgun/buckshot,
+/turf/open/floor/wood,
+/area/varadero/interior/bunks)
"vYW" = (
/turf/open/auto_turf/sand_white/layer1,
/area/varadero/interior_protected/caves)
@@ -34946,17 +34955,6 @@
icon_state = "multi_tiles"
},
/area/varadero/interior/technical_storage)
-"wkJ" = (
-/obj/effect/landmark/lv624/fog_blocker{
- time_to_dispel = 25000
- },
-/obj/structure/blocker/invisible_wall/water,
-/obj/structure/flora/bush/ausbushes/var3/stalkybush,
-/turf/open/gm/river/ocean{
- name = "deep ocean";
- default_name = "deep ocean"
- },
-/area/varadero/exterior/farocean)
"wkM" = (
/obj/structure/window/reinforced{
dir = 4;
@@ -35285,6 +35283,18 @@
icon_state = "asteroidfloor"
},
/area/varadero/exterior/eastbeach)
+"wts" = (
+/obj/structure/flora/bush/ausbushes/var3/sparsegrass{
+ icon_state = "sparsegrass_2"
+ },
+/obj/effect/landmark/lv624/fog_blocker{
+ time_to_dispel = 25000
+ },
+/turf/open/gm/river{
+ name = "shallow ocean";
+ default_name = "shallow ocean"
+ },
+/area/varadero/exterior/eastocean)
"wty" = (
/obj/structure/disposalpipe/segment,
/turf/open/floor/shiva{
@@ -50142,7 +50152,7 @@ bZU
qOh
rtm
bZU
-oXw
+bZU
bwP
mrC
wMw
@@ -50860,7 +50870,7 @@ bZU
bZU
bZU
bZU
-bZU
+oXw
bZU
bZU
bZU
@@ -54388,7 +54398,7 @@ iLd
iTP
jZG
tNE
-uIj
+vYQ
lgb
fEI
wfy
@@ -54732,7 +54742,7 @@ eMi
qRy
moK
hPD
-hXg
+uQH
riJ
aQc
qqA
@@ -55298,7 +55308,7 @@ bAE
kIg
nmC
ben
-uIj
+agi
hDk
aZb
rAy
@@ -63604,7 +63614,7 @@ wlB
nFX
ias
lTg
-aAX
+wlB
lTg
lTg
iQr
@@ -64322,7 +64332,7 @@ wlB
wlB
wlB
wlB
-wlB
+aAX
wlB
wlB
wlB
@@ -67132,10 +67142,10 @@ bGU
rqg
gPi
xeU
-xFb
-sfo
-sfo
-pNZ
+dRs
+spv
+spv
+aXn
kyj
gPi
bko
@@ -67311,16 +67321,16 @@ bko
gPi
bko
gPi
-qNr
-xFb
-sfo
-xFb
-sfo
-sfo
-sfo
-xFb
-xFb
-sfo
+wts
+dRs
+spv
+dRs
+spv
+spv
+spv
+dRs
+dRs
+spv
ghN
pZS
kyD
@@ -67490,19 +67500,19 @@ qoI
gPi
xfQ
spv
-xFb
-uDr
-xFb
-uDr
-xFb
-sfo
-xFb
-xFb
-sfo
-sfo
-xFb
-sfo
-sfo
+dRs
+esA
+dRs
+esA
+dRs
+spv
+dRs
+dRs
+spv
+spv
+dRs
+spv
+spv
ghN
gRj
bGU
@@ -67670,21 +67680,21 @@ gPi
gPi
xfQ
bUP
-jFL
-sfo
-xFb
-sfo
-tHc
-sfo
-xFb
-xFb
-uDr
-sfo
-sfo
-xFb
-xFb
-sfo
-xFb
+bUP
+spv
+dRs
+spv
+ulb
+spv
+dRs
+dRs
+esA
+spv
+spv
+dRs
+dRs
+spv
+dRs
veV
bko
gPi
@@ -67850,25 +67860,25 @@ bUP
bUP
bUP
bUP
-xFb
-xFb
-sfo
-xFb
-xFb
-sfo
-xFb
-xFb
-sfo
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-sfo
-xFb
-xFb
-sfo
+dRs
+dRs
+spv
+dRs
+dRs
+spv
+dRs
+dRs
+spv
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+spv
+dRs
+dRs
+spv
hwE
ghN
pZS
@@ -68025,33 +68035,33 @@ xFb
xFb
dRs
dRs
-xFb
-xFb
-xFb
-xFb
dRs
dRs
-xFb
-xFb
-xFb
-uDr
-xFb
-xFb
-sfo
-xFb
-xFb
-sfo
-xFb
-xFb
-xFb
-xFb
-xFb
-sfo
-sfo
-xFb
-sfo
-xFb
-xFb
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+esA
+dRs
+dRs
+spv
+dRs
+dRs
+spv
+dRs
+dRs
+dRs
+dRs
+dRs
+spv
+spv
+dRs
+spv
+dRs
+dRs
aaG
dkS
qlw
@@ -68201,39 +68211,39 @@ xFb
xFb
xFb
xFb
+dRs
xFb
xFb
xFb
xFb
-xFb
-xFb
-xFb
-tHc
dRs
-xFb
-xFb
dRs
-xFb
-xFb
-sfo
-uDr
-xFb
-xFb
-sfo
-xFb
-xFb
-xFb
-sfo
-sfo
-xFb
-xFb
-mRk
-sfo
-xFb
-sfo
-xFb
-xFb
-uDr
+ulb
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+spv
+esA
+dRs
+dRs
+spv
+dRs
+dRs
+dRs
+spv
+spv
+dRs
+dRs
+fPy
+spv
+dRs
+spv
+dRs
+dRs
+esA
ihC
ghN
pmM
@@ -68384,38 +68394,38 @@ xFb
xFb
xFb
xFb
-xFb
-xFb
-xFb
dRs
xFb
xFb
-xFb
dRs
xFb
xFb
-xFb
dRs
-xFb
-uDr
-sfo
-xFb
-xFb
-sfo
-sfo
-xFb
-xFb
-xFb
-sfo
-uDr
-sfo
-sfo
-xFb
-xFb
-uDr
-xFb
-uDr
-xFb
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+esA
+spv
+dRs
+dRs
+spv
+spv
+dRs
+dRs
+dRs
+spv
+esA
+spv
+spv
+dRs
+dRs
+esA
+dRs
+esA
+dRs
bUP
ghN
bGU
@@ -68572,31 +68582,31 @@ xFb
xFb
byC
xFb
-xFb
-xFb
-xFb
-byC
-xFb
-byC
-xFb
-uDr
-xFb
-gIE
-xFb
-xFb
-uDr
-sfo
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-sfo
-sfo
-xFb
+dRs
+dRs
+dRs
+exX
+dRs
+exX
+dRs
+esA
+dRs
+lxs
+dRs
+dRs
+esA
+spv
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+spv
+spv
+dRs
dRs
bUP
veV
@@ -68759,26 +68769,26 @@ xVw
wBp
wBp
wBp
-rYC
+bBV
wBp
xBH
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-uDr
-sfo
-xFb
-xFb
-xFb
-xFb
-sfo
-uDr
-uDr
-xFb
-xFb
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+esA
+spv
+dRs
+dRs
+dRs
+dRs
+spv
+esA
+esA
+dRs
+dRs
dRs
bUP
bUP
@@ -68934,7 +68944,7 @@ mPk
mPk
mPk
mPk
-mPk
+pRa
cJL
mPk
mPk
@@ -68943,25 +68953,25 @@ mPk
mPk
cJL
mPk
-wkJ
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-sfo
-sfo
-sfo
-sfo
-sfo
-sfo
-xFb
-xFb
+tTq
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+spv
+spv
+spv
+spv
+spv
+spv
+dRs
+dRs
+dRs
dRs
-xFb
bUP
ucL
ghN
@@ -69120,31 +69130,31 @@ mPk
mPk
mPk
mPk
-mPk
+pRa
mPk
mPk
mPk
mPk
rYC
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
bUP
ghN
bGU
@@ -69306,27 +69316,27 @@ mPk
mPk
mPk
mPk
-cJL
-wBp
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-tHc
+rUa
+mPW
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+ulb
bUP
veV
jTR
@@ -69490,26 +69500,26 @@ mPk
mPk
mPk
xVw
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
bUP
ghN
bGU
@@ -69671,153 +69681,138 @@ mPk
mPk
mPk
mPk
-wBp
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-dRs
-xFb
-bUP
-veV
-jTR
-bGU
-bGU
-bGU
-vNB
-rvD
-pGs
-pGs
-pGs
-pGs
-pGs
-pGs
-pGs
-pGs
-pGs
-bsf
-bsf
-bsf
-bsf
-bsf
-ulv
-uvd
-uvd
-uvd
-brT
-kjI
-vNT
-brT
-reA
-brT
-brT
-snS
-kjI
-kjI
-snS
-brT
-brT
-rmS
-brT
-qwU
-nnk
-brT
-uvd
-uvd
-uvd
-brT
-bsf
-bsf
-bsf
-bsf
-bsf
-pGs
-pGs
-pGs
-wUU
-"}
-(175,1,1) = {"
-wUU
-nvv
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-pkl
-kkF
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
-mPk
+wBp
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+bUP
+veV
+jTR
+bGU
+bGU
+bGU
+vNB
+rvD
+pGs
+pGs
+pGs
+pGs
+pGs
+pGs
+pGs
+pGs
+pGs
+bsf
+bsf
+bsf
+bsf
+bsf
+ulv
+uvd
+uvd
+uvd
+brT
+kjI
+vNT
+brT
+reA
+brT
+brT
+snS
+kjI
+kjI
+snS
+brT
+brT
+rmS
+brT
+qwU
+nnk
+brT
+uvd
+uvd
+uvd
+brT
+bsf
+bsf
+bsf
+bsf
+bsf
+pGs
+pGs
+pGs
+wUU
+"}
+(175,1,1) = {"
+wUU
+nvv
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+pkl
+kkF
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
mPk
mPk
mPk
@@ -69853,27 +69848,42 @@ mPk
mPk
mPk
mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+mPk
+pRa
wBp
byC
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
xFb
xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-dRs
bUP
bUP
ghN
@@ -70038,26 +70048,26 @@ mPk
rYC
xFb
xFb
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
xFb
xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
+dRs
+dRs
tHc
-bUP
+jFL
ghN
bGU
bGU
@@ -70222,24 +70232,24 @@ byC
xFb
xFb
xFb
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
+dRs
xFb
+dRs
+dRs
xFb
+dRs
xFb
+dRs
+dRs
xFb
xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-xFb
-bUP
+jFL
ghN
vNB
rvD
@@ -70402,18 +70412,18 @@ mPk
wBp
xFb
xFb
-xFb
+dRs
xFb
byC
+dRs
xFb
-xFb
-xFb
+dRs
byC
xFb
xFb
-xFb
+dRs
byC
-xFb
+dRs
xFb
byC
xFb
@@ -70766,6 +70776,7 @@ mPk
mPk
mPk
mPk
+pRa
mPk
mPk
mPk
@@ -70775,14 +70786,13 @@ mPk
mPk
mPk
mPk
-mPk
-mPk
+pRa
cJL
mPk
mPk
mPk
cJL
-mPk
+pRa
mPk
mPk
mPk
@@ -70951,10 +70961,10 @@ mPk
mPk
mPk
mPk
+pRa
mPk
-mPk
-mPk
-mPk
+pRa
+pRa
mPk
mPk
mPk
diff --git a/maps/map_files/Sorokyne_Strata/Sorokyne_Strata.dmm b/maps/map_files/Sorokyne_Strata/Sorokyne_Strata.dmm
index c43a02dddf12..ff1d99eb8f78 100644
--- a/maps/map_files/Sorokyne_Strata/Sorokyne_Strata.dmm
+++ b/maps/map_files/Sorokyne_Strata/Sorokyne_Strata.dmm
@@ -1473,11 +1473,6 @@
icon_state = "red1"
},
/area/strata/ug/interior/jungle/deep/structures/res)
-"aem" = (
-/obj/item/weapon/gun/pistol/c99,
-/obj/effect/decal/cleanable/blood/gibs/core,
-/turf/open/auto_turf/snow/brown_base/layer0,
-/area/strata/ag/interior/outpost/gen/bball/nest)
"aen" = (
/obj/effect/landmark/monkey_spawn,
/turf/open/auto_turf/snow/brown_base/layer0,
@@ -1550,13 +1545,6 @@
/obj/structure/flora/bush/ausbushes/grassybush,
/turf/open/auto_turf/strata_grass/layer1,
/area/strata/ug/interior/jungle/deep/minehead)
-"aeA" = (
-/obj/structure/surface/rack,
-/obj/item/weapon/gun/pistol/c99,
-/turf/open/floor/strata{
- icon_state = "red1"
- },
-/area/strata/ug/interior/jungle/deep/structures/res)
"aeB" = (
/obj/structure/surface/table/reinforced/prison,
/turf/open/floor/strata{
@@ -4300,11 +4288,6 @@
/obj/effect/decal/cleanable/blood,
/turf/open/auto_turf/snow/brown_base/layer0,
/area/strata/ag/exterior/paths/cabin_area)
-"amy" = (
-/obj/effect/decal/strata_decals/catwalk/prison,
-/obj/item/weapon/gun/pistol/c99,
-/turf/open/floor/greengrid,
-/area/strata/ag/exterior/research_decks)
"amz" = (
/obj/structure/machinery/light/small{
dir = 4
@@ -7014,16 +6997,6 @@
icon_state = "white_cyan1"
},
/area/strata/ag/interior/outpost/canteen/lower_cafeteria)
-"auS" = (
-/obj/item/weapon/gun/pistol/c99,
-/obj/structure/pipes/standard/manifold/hidden/cyan{
- dir = 1
- },
-/turf/open/floor/strata{
- dir = 4;
- icon_state = "white_cyan1"
- },
-/area/strata/ag/interior/outpost/canteen/lower_cafeteria)
"auU" = (
/obj/effect/decal/cleanable/blood/gibs/down,
/obj/item/dogtag,
@@ -9158,15 +9131,6 @@
},
/turf/closed/wall/strata_outpost,
/area/strata/ag/interior/dorms)
-"aBr" = (
-/obj/structure/surface/table/reinforced/prison,
-/obj/item/storage/pouch/flare/full,
-/obj/item/weapon/gun/pistol/c99,
-/obj/effect/landmark/item_pool_spawner/survivor_ammo/buckshot,
-/turf/open/floor/strata{
- icon_state = "orange_tile"
- },
-/area/strata/ag/interior/dorms)
"aBs" = (
/obj/structure/pipes/vents/pump{
dir = 1
@@ -14757,10 +14721,6 @@
/obj/structure/pipes/standard/simple/hidden/cyan,
/turf/open/floor/strata,
/area/strata/ag/exterior/research_decks)
-"aTo" = (
-/obj/item/weapon/gun/pistol/c99,
-/turf/open/floor/strata,
-/area/strata/ag/exterior/research_decks)
"aTp" = (
/obj/structure/largecrate/random/case/small,
/turf/open/asphalt/cement,
@@ -20781,11 +20741,6 @@
/obj/effect/decal/cleanable/blood/gibs/limb,
/turf/open/auto_turf/snow/brown_base/layer0,
/area/strata/ag/exterior/paths/southresearch)
-"bpt" = (
-/obj/item/weapon/gun/pistol/c99,
-/obj/effect/decal/cleanable/blood/gibs/core,
-/turf/open/auto_turf/snow/brown_base/layer0,
-/area/strata/ag/exterior/paths/southresearch)
"bpu" = (
/obj/structure/machinery/colony_floodlight,
/turf/open/auto_turf/snow/brown_base/layer1,
@@ -22037,16 +21992,6 @@
/obj/structure/bed/chair,
/turf/open/auto_turf/snow/brown_base/layer2,
/area/strata/ag/exterior/marsh/center)
-"buh" = (
-/obj/structure/surface/rack,
-/obj/item/tool/shovel/etool/folded,
-/obj/item/weapon/gun/pistol/c99,
-/obj/item/attachable/bayonet/upp,
-/obj/effect/landmark/item_pool_spawner/survivor_ammo/buckshot,
-/turf/open/floor/prison{
- icon_state = "darkredfull2"
- },
-/area/strata/ag/interior/landingzone_checkpoint)
"bui" = (
/obj/structure/tunnel{
id = "hole1"
@@ -26679,11 +26624,6 @@
icon_state = "multi_tiles"
},
/area/strata/ag/interior/outpost/canteen)
-"caT" = (
-/obj/item/weapon/gun/pistol/c99,
-/obj/effect/decal/cleanable/blood/gibs/core,
-/turf/open/auto_turf/ice/layer1,
-/area/strata/ag/interior/outpost/gen/bball/nest)
"caV" = (
/obj/item/stack/sheet/wood,
/obj/effect/decal/cleanable/blood,
@@ -27004,13 +26944,6 @@
icon_state = "red1"
},
/area/strata/ag/interior/outpost/security)
-"cdf" = (
-/obj/structure/surface/rack,
-/obj/item/weapon/gun/pistol/c99,
-/turf/open/floor/strata{
- icon_state = "red1"
- },
-/area/strata/ag/interior/outpost/security)
"cdh" = (
/turf/open/floor/strata,
/area/strata/ag/interior/outpost/canteen/lower_cafeteria)
@@ -28838,12 +28771,6 @@
"cpg" = (
/turf/closed/wall/strata_ice/jungle,
/area/strata/ug/interior/jungle/deep/east_dorms)
-"cph" = (
-/obj/item/weapon/gun/pistol/c99,
-/obj/effect/decal/cleanable/blood,
-/obj/effect/decal/cleanable/blood/gibs/core,
-/turf/open/auto_turf/ice/layer1,
-/area/strata/ag/interior/outpost/gen/bball/nest)
"cpi" = (
/obj/item/stack/medical/ointment,
/obj/item/stack/medical/splint,
@@ -29821,6 +29748,16 @@
icon_state = "cyan3"
},
/area/strata/ag/interior/outpost/med)
+"cHm" = (
+/obj/item/weapon/gun/pistol/t73,
+/obj/structure/pipes/standard/manifold/hidden/cyan{
+ dir = 1
+ },
+/turf/open/floor/strata{
+ dir = 4;
+ icon_state = "white_cyan1"
+ },
+/area/strata/ag/interior/outpost/canteen/lower_cafeteria)
"cIM" = (
/obj/structure/machinery/door/airlock/prison{
dir = 1;
@@ -30522,6 +30459,13 @@
"dWm" = (
/turf/closed/wall/strata_outpost/reinforced,
/area/strata/ag/interior/outpost/gen/bball)
+"dWu" = (
+/obj/structure/surface/rack,
+/obj/item/weapon/gun/pistol/t73,
+/turf/open/floor/strata{
+ icon_state = "red1"
+ },
+/area/strata/ag/interior/outpost/security)
"dXc" = (
/obj/effect/landmark/static_comms/net_one,
/turf/open/auto_turf/snow/brown_base/layer0,
@@ -30640,6 +30584,11 @@
icon_state = "red1"
},
/area/strata/ug/interior/outpost/jung/dorms/sec2)
+"ejw" = (
+/obj/item/weapon/gun/pistol/t73,
+/obj/effect/decal/cleanable/blood/gibs/core,
+/turf/open/auto_turf/strata_grass/layer1,
+/area/strata/ug/interior/jungle/deep/east_engi)
"ekc" = (
/obj/structure/barricade/snow,
/turf/open/auto_turf/ice/layer1,
@@ -30694,13 +30643,6 @@
},
/turf/open/auto_turf/ice/layer1,
/area/strata/ag/exterior/marsh/center)
-"enQ" = (
-/obj/structure/surface/rack,
-/obj/item/weapon/gun/pistol/c99,
-/turf/open/floor/strata{
- icon_state = "red1"
- },
-/area/strata/ug/interior/jungle/deep/structures/engi)
"enU" = (
/obj/structure/machinery/light/small{
dir = 8
@@ -33121,6 +33063,20 @@
icon_state = "purp2"
},
/area/strata/ug/interior/jungle/deep/structures/engi)
+"iuh" = (
+/obj/structure/sink{
+ dir = 8;
+ pixel_x = -11
+ },
+/obj/structure/mirror{
+ pixel_x = -29
+ },
+/obj/item/weapon/gun/pistol/t73,
+/turf/open/floor/strata{
+ dir = 8;
+ icon_state = "white_cyan2"
+ },
+/area/strata/ug/interior/outpost/jung/dorms/sec1)
"iuB" = (
/obj/structure/machinery/light/small{
dir = 1;
@@ -33591,16 +33547,6 @@
},
/turf/closed/wall/strata_outpost,
/area/strata/ag/exterior/research_decks)
-"jhu" = (
-/obj/structure/surface/rack,
-/obj/item/tool/shovel/etool/folded,
-/obj/item/weapon/gun/pistol/c99,
-/obj/item/attachable/bayonet/upp,
-/obj/effect/landmark/item_pool_spawner/survivor_ammo/buckshot,
-/turf/open/floor/strata{
- icon_state = "red1"
- },
-/area/strata/ag/interior/landingzone_checkpoint)
"jit" = (
/turf/open/asphalt/cement{
icon_state = "cement2"
@@ -33759,14 +33705,6 @@
/obj/structure/sign/safety/biohazard,
/turf/closed/wall/strata_outpost/reinforced/hull,
/area/strata/ag/interior/mountain)
-"jwS" = (
-/obj/structure/surface/rack,
-/obj/item/weapon/gun/pistol/c99,
-/obj/item/handcuffs,
-/turf/open/floor/strata{
- icon_state = "red1"
- },
-/area/strata/ag/interior/research_decks/security)
"jxc" = (
/obj/effect/decal/strata_decals/catwalk/prison,
/obj/structure/disposalpipe/segment,
@@ -35210,6 +35148,10 @@
icon_state = "fake_wood"
},
/area/strata/ag/interior/outpost/gen/bball)
+"lUw" = (
+/obj/item/weapon/gun/pistol/t73,
+/turf/open/floor/strata,
+/area/strata/ag/exterior/research_decks)
"lVF" = (
/obj/effect/blocker/sorokyne_cold_water,
/obj/structure/platform/strata{
@@ -35277,6 +35219,13 @@
icon_state = "red1"
},
/area/strata/ag/interior/outpost/gen/bball)
+"mcD" = (
+/obj/structure/surface/rack,
+/obj/item/weapon/gun/pistol/t73,
+/turf/open/floor/strata{
+ icon_state = "red1"
+ },
+/area/strata/ug/interior/jungle/deep/structures/res)
"mcX" = (
/obj/structure/surface/rack,
/obj/item/tool/shovel/snow,
@@ -38789,6 +38738,10 @@
/obj/effect/decal/cleanable/blood/oil,
/turf/open/floor/strata,
/area/strata/ag/interior/tcomms)
+"sah" = (
+/obj/item/weapon/gun/pistol/t73,
+/turf/open/auto_turf/strata_grass/layer1,
+/area/strata/ug/interior/jungle/deep/east_engi)
"sau" = (
/obj/structure/machinery/power/terminal{
dir = 8
@@ -38956,6 +38909,11 @@
icon_state = "cement9"
},
/area/strata/ug/interior/jungle/platform/east/scrub)
+"spp" = (
+/obj/item/weapon/gun/pistol/t73,
+/obj/effect/decal/cleanable/blood/gibs/core,
+/turf/open/auto_turf/ice/layer1,
+/area/strata/ag/interior/outpost/gen/bball/nest)
"sqT" = (
/turf/closed/wall/strata_ice/dirty,
/area/strata/ag/exterior/marsh/crash)
@@ -39249,11 +39207,6 @@
icon_state = "white_cyan1"
},
/area/strata/ag/interior/dorms)
-"sWr" = (
-/obj/item/weapon/gun/pistol/c99,
-/obj/effect/decal/cleanable/blood/gibs/core,
-/turf/open/auto_turf/strata_grass/layer1,
-/area/strata/ug/interior/jungle/deep/east_engi)
"sWO" = (
/obj/structure/machinery/light/small{
dir = 1;
@@ -39413,6 +39366,11 @@
icon_state = "floor3"
},
/area/strata/ag/exterior/research_decks)
+"thz" = (
+/obj/effect/decal/strata_decals/catwalk/prison,
+/obj/item/weapon/gun/pistol/t73,
+/turf/open/floor/greengrid,
+/area/strata/ag/exterior/research_decks)
"tio" = (
/obj/structure/pipes/standard/manifold/hidden/cyan{
dir = 4
@@ -40021,6 +39979,16 @@
"uaH" = (
/turf/open/floor/strata,
/area/strata/ug/interior/outpost/jung/dorms/admin2)
+"ubo" = (
+/obj/structure/surface/rack,
+/obj/item/tool/shovel/etool/folded,
+/obj/item/weapon/gun/pistol/t73,
+/obj/item/attachable/bayonet/upp,
+/obj/effect/landmark/item_pool_spawner/survivor_ammo/buckshot,
+/turf/open/floor/prison{
+ icon_state = "darkredfull2"
+ },
+/area/strata/ag/interior/landingzone_checkpoint)
"ubx" = (
/obj/structure/largecrate/random,
/obj/item/paper_bin,
@@ -40154,6 +40122,14 @@
},
/turf/open/floor/strata,
/area/strata/ag/exterior/research_decks)
+"ulv" = (
+/obj/structure/surface/rack,
+/obj/item/weapon/gun/pistol/t73,
+/obj/item/handcuffs,
+/turf/open/floor/strata{
+ icon_state = "red1"
+ },
+/area/strata/ag/interior/research_decks/security)
"ulL" = (
/obj/structure/platform/strata/metal{
dir = 1
@@ -40488,6 +40464,21 @@
},
/turf/open/auto_turf/ice/layer1,
/area/strata/ag/exterior/paths/north_outpost)
+"uPH" = (
+/obj/structure/surface/rack,
+/obj/item/tool/shovel/etool/folded,
+/obj/item/weapon/gun/pistol/t73,
+/obj/item/attachable/bayonet/upp,
+/obj/effect/landmark/item_pool_spawner/survivor_ammo/buckshot,
+/turf/open/floor/strata{
+ icon_state = "red1"
+ },
+/area/strata/ag/interior/landingzone_checkpoint)
+"uPR" = (
+/obj/item/weapon/gun/pistol/t73,
+/obj/effect/decal/cleanable/blood/gibs/core,
+/turf/open/auto_turf/snow/brown_base/layer0,
+/area/strata/ag/exterior/paths/southresearch)
"uRy" = (
/obj/structure/pipes/standard/simple/hidden/cyan{
dir = 4
@@ -40867,10 +40858,6 @@
icon_state = "purp2"
},
/area/strata/ug/interior/jungle/deep/structures/engi)
-"vsG" = (
-/obj/item/weapon/gun/pistol/c99,
-/turf/open/auto_turf/strata_grass/layer1,
-/area/strata/ug/interior/jungle/deep/east_engi)
"vsL" = (
/obj/item/reagent_container/food/snacks/donkpocket,
/turf/open/floor/strata{
@@ -41068,20 +41055,6 @@
icon_state = "cyan2"
},
/area/strata/ag/interior/outpost/med)
-"vDl" = (
-/obj/structure/sink{
- dir = 8;
- pixel_x = -11
- },
-/obj/structure/mirror{
- pixel_x = -29
- },
-/obj/item/weapon/gun/pistol/c99,
-/turf/open/floor/strata{
- dir = 8;
- icon_state = "white_cyan2"
- },
-/area/strata/ug/interior/outpost/jung/dorms/sec1)
"vDm" = (
/obj/structure/blocker/forcefield/multitile_vehicles,
/turf/open/floor/strata{
@@ -41571,6 +41544,11 @@
/obj/effect/landmark/good_item,
/turf/open/floor/strata,
/area/strata/ug/interior/outpost/jung/dorms/admin2)
+"wEU" = (
+/obj/item/weapon/gun/pistol/t73,
+/obj/effect/decal/cleanable/blood/gibs/core,
+/turf/open/auto_turf/snow/brown_base/layer0,
+/area/strata/ag/interior/outpost/gen/bball/nest)
"wFG" = (
/turf/open/auto_turf/strata_grass/layer1,
/area/strata/ug/interior/jungle/deep/south_engi)
@@ -42100,6 +42078,12 @@
icon_state = "multi_tiles"
},
/area/strata/ag/exterior/research_decks)
+"xFT" = (
+/obj/item/weapon/gun/pistol/t73,
+/obj/effect/decal/cleanable/blood,
+/obj/effect/decal/cleanable/blood/gibs/core,
+/turf/open/auto_turf/ice/layer1,
+/area/strata/ag/interior/outpost/gen/bball/nest)
"xGb" = (
/obj/structure/pipes/standard/simple/hidden/cyan{
dir = 6
@@ -42347,6 +42331,13 @@
"xUg" = (
/turf/open/gm/coast/south,
/area/strata/ug/interior/jungle/deep/south_engi)
+"xUo" = (
+/obj/structure/surface/rack,
+/obj/item/weapon/gun/pistol/t73,
+/turf/open/floor/strata{
+ icon_state = "red1"
+ },
+/area/strata/ug/interior/jungle/deep/structures/engi)
"xVQ" = (
/obj/structure/bed/chair/dropship/passenger{
dir = 4
@@ -42461,6 +42452,15 @@
icon_state = "floor3"
},
/area/strata/ag/interior/tcomms)
+"yis" = (
+/obj/structure/surface/table/reinforced/prison,
+/obj/item/storage/pouch/flare/full,
+/obj/item/weapon/gun/pistol/t73,
+/obj/effect/landmark/item_pool_spawner/survivor_ammo/buckshot,
+/turf/open/floor/strata{
+ icon_state = "orange_tile"
+ },
+/area/strata/ag/interior/dorms)
"yjG" = (
/obj/structure/flora/bush/ausbushes/var3/fullgrass,
/turf/open/auto_turf/strata_grass/layer1,
@@ -43739,7 +43739,7 @@ crE
crE
crE
crE
-ciy
+crE
crE
fuA
cmA
@@ -44509,7 +44509,7 @@ crE
crE
crE
crE
-crE
+ciy
crE
crE
crE
@@ -47289,7 +47289,7 @@ cwS
fzN
cwS
cbO
-jhu
+uPH
iVZ
cxg
bsU
@@ -50849,7 +50849,7 @@ jWs
jWs
jWs
jWs
-iUK
+jWs
jWs
qbk
wvF
@@ -51138,7 +51138,7 @@ bWy
bZV
ctC
azL
-aBr
+yis
ctC
aDN
aER
@@ -51619,7 +51619,7 @@ jWs
jWs
jWs
jWs
-jWs
+iUK
jWs
jWs
jWs
@@ -54731,7 +54731,7 @@ aac
aac
aac
mfp
-buh
+ubo
mLe
cxg
kkL
@@ -57560,7 +57560,7 @@ aac
aac
nkp
kcw
-amy
+thz
kcw
kcw
kcw
@@ -60122,7 +60122,7 @@ aKB
oKo
oKo
ras
-aTo
+lUw
cuP
cuP
fBh
@@ -61910,7 +61910,7 @@ cva
ybN
jWi
bdU
-jwS
+ulv
ybN
aGf
aGL
@@ -64062,7 +64062,7 @@ blE
blJ
blJ
bpU
-bpt
+uPR
bqa
bqv
bqJ
@@ -64162,7 +64162,7 @@ pIa
cdo
aam
aar
-aem
+wEU
adC
cdo
ced
@@ -64946,7 +64946,7 @@ aam
ahn
aar
aar
-cph
+xFT
ced
ced
hmw
@@ -66114,7 +66114,7 @@ cdo
aar
aam
aJn
-caT
+spp
aJn
aar
aar
@@ -68884,7 +68884,7 @@ caf
ijo
aAC
aCc
-cdf
+dWu
cea
ceI
cfx
@@ -69664,7 +69664,7 @@ cdZ
gAm
aAF
aCf
-cdf
+dWu
cea
ceI
cfx
@@ -70327,7 +70327,7 @@ tjo
rqL
oWO
sHP
-vDl
+iuh
tPl
sHP
aad
@@ -71803,7 +71803,7 @@ bPf
bPf
asO
cdh
-auS
+cHm
cgW
cgW
bZB
@@ -83966,7 +83966,7 @@ ixD
sXl
eUW
kmt
-enQ
+xUo
sXl
pqG
vsy
@@ -84846,7 +84846,7 @@ aad
uux
adR
aeh
-aeA
+mcD
adz
afs
ady
@@ -86040,7 +86040,7 @@ abX
aue
aiV
awv
-aeA
+mcD
adz
ccz
vEp
@@ -87083,7 +87083,7 @@ mLn
tgC
tgC
tgC
-sWr
+ejw
tgC
tgC
wHW
@@ -87477,7 +87477,7 @@ wHW
wHW
hyu
wHW
-vsG
+sah
tgC
mLn
mLn
diff --git a/maps/map_files/USS_Almayer/USS_Almayer.dmm b/maps/map_files/USS_Almayer/USS_Almayer.dmm
index 92b4422aeebe..e96d6b18a31e 100644
--- a/maps/map_files/USS_Almayer/USS_Almayer.dmm
+++ b/maps/map_files/USS_Almayer/USS_Almayer.dmm
@@ -3493,20 +3493,6 @@
},
/turf/open/floor/wood/ship,
/area/almayer/living/commandbunks)
-"alk" = (
-/obj/structure/machinery/door/poddoor/shutters/almayer{
- dir = 4;
- id = "W_Containment Cell 1";
- name = "\improper Containment Cell 5";
- unacidable = 1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/closed/wall/almayer/research/containment/wall/purple,
-/area/almayer/medical/containment/cell)
"all" = (
/obj/structure/disposalpipe/segment,
/obj/structure/pipes/standard/simple/hidden/supply,
@@ -4489,22 +4475,6 @@
icon_state = "red"
},
/area/almayer/lifeboat_pumps/north1)
-"aoJ" = (
-/obj/structure/machinery/door/poddoor/shutters/almayer{
- dir = 4;
- id = "W_Containment Cell 1";
- name = "\improper Containment Cell 5";
- unacidable = 1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/closed/wall/almayer/research/containment/wall/purple{
- dir = 1
- },
-/area/almayer/medical/containment/cell)
"aoK" = (
/obj/structure/surface/table/almayer,
/obj/effect/decal/warning_stripes{
@@ -4939,22 +4909,6 @@
icon_state = "test_floor4"
},
/area/almayer/engineering/engineering_workshop/hangar)
-"apU" = (
-/obj/structure/machinery/door/poddoor/shutters/almayer{
- dir = 4;
- id = "W_Containment Cell 2";
- name = "\improper Containment Cell 5";
- unacidable = 1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/closed/wall/almayer/research/containment/wall/purple{
- dir = 8
- },
-/area/almayer/medical/containment/cell)
"apV" = (
/obj/structure/machinery/light{
dir = 8
@@ -5246,35 +5200,6 @@
icon_state = "plate"
},
/area/almayer/command/cic)
-"aqP" = (
-/obj/structure/machinery/door/airlock/almayer/research/glass/reinforced{
- dir = 1;
- id = "Containment Cell 1";
- locked = 1;
- name = "\improper Containment Cell 1"
- },
-/obj/structure/machinery/door/poddoor/shutters/almayer{
- id = "Containment Cell 1";
- name = "\improper Containment Cell 1";
- unacidable = 1
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "E";
- pixel_x = 1
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "E";
- pixel_x = 1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/obj/structure/pipes/standard/simple/hidden/supply/no_boom,
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/containment/cell)
"aqS" = (
/obj/structure/pipes/standard/simple/hidden/supply/no_boom,
/turf/open/floor/almayer{
@@ -5739,17 +5664,6 @@
allow_construction = 0
},
/area/almayer/stair_clone/upper)
-"asn" = (
-/obj/structure/window/framed/almayer/white,
-/obj/structure/machinery/door/firedoor/border_only/almayer{
- dir = 2
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/open/floor/plating,
-/area/almayer/medical/upper_medical)
"aso" = (
/turf/open/floor/almayer{
dir = 8;
@@ -8149,18 +8063,6 @@
icon_state = "sterile_green"
},
/area/almayer/medical/medical_science)
-"ayZ" = (
-/obj/structure/pipes/standard/simple/hidden/supply,
-/obj/structure/machinery/light{
- dir = 1
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/almayer{
- icon_state = "dark_sterile"
- },
-/area/almayer/medical/medical_science)
"azb" = (
/obj/effect/decal/warning_stripes{
icon_state = "E";
@@ -8821,22 +8723,6 @@
icon_state = "sterile_green_side"
},
/area/almayer/medical/morgue)
-"aBe" = (
-/obj/structure/machinery/door/poddoor/shutters/almayer{
- dir = 4;
- id = "W_Containment Cell 2";
- name = "\improper Containment Cell 5";
- unacidable = 1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/closed/wall/almayer/research/containment/wall/purple{
- dir = 4
- },
-/area/almayer/medical/containment/cell)
"aBf" = (
/obj/structure/machinery/door/airlock/almayer/secure/reinforced{
name = "Telecommunications";
@@ -10569,21 +10455,6 @@
icon_state = "silver"
},
/area/almayer/command/cichallway)
-"aIo" = (
-/obj/structure/window/framed/almayer/white,
-/obj/structure/machinery/door/firedoor/border_only/almayer,
-/obj/structure/machinery/door/poddoor/shutters/almayer/open{
- dir = 8;
- id = "researchlockdownext_windoor";
- name = "\improper Research Windoor Shutter"
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/open/floor/plating,
-/area/almayer/medical/medical_science)
"aIq" = (
/obj/structure/machinery/power/apc/almayer{
dir = 1
@@ -12399,28 +12270,6 @@
icon_state = "mono"
},
/area/almayer/medical/hydroponics)
-"aRd" = (
-/obj/structure/surface/table/reinforced/prison,
-/obj/structure/machinery/door/window/westright,
-/obj/structure/machinery/door/firedoor/border_only/almayer,
-/obj/structure/machinery/door/window/westright{
- dir = 4;
- req_access_txt = "28"
- },
-/obj/structure/machinery/door/poddoor/shutters/almayer/open{
- dir = 8;
- id = "researchlockdownext_windoor";
- name = "\improper Research Windoor Shutter"
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/medical_science)
"aRi" = (
/obj/structure/bed/chair/office/dark{
dir = 1
@@ -26610,6 +26459,20 @@
icon_state = "test_floor4"
},
/area/almayer/hallways/port_hallway)
+"chJ" = (
+/obj/structure/machinery/door/poddoor/shutters/almayer{
+ dir = 4;
+ id = "W_Containment Cell 3";
+ name = "\improper Containment Cell 5";
+ unacidable = 1
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/closed/wall/almayer/research/containment/wall/purple{
+ dir = 4
+ },
+/area/almayer/medical/containment/cell)
"chL" = (
/obj/structure/pipes/standard/simple/hidden/supply{
dir = 4
@@ -28924,6 +28787,18 @@
icon_state = "plate"
},
/area/almayer/engineering/lower_engineering)
+"cHS" = (
+/obj/structure/window/framed/almayer/white,
+/obj/structure/machinery/door/poddoor/shutters/almayer/open{
+ id = "researchlockdownext_se_2";
+ name = "\improper Research Window Shutter"
+ },
+/obj/structure/machinery/door/firedoor/border_only/almayer{
+ dir = 1
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
+/turf/open/floor/plating,
+/area/almayer/medical/medical_science)
"cIe" = (
/obj/structure/machinery/light{
dir = 4
@@ -32052,22 +31927,6 @@
/obj/structure/pipes/standard/simple/hidden/supply,
/turf/open/floor/almayer,
/area/almayer/living/port_emb)
-"ean" = (
-/obj/structure/machinery/door/poddoor/shutters/almayer{
- dir = 4;
- id = "W_Containment Cell 3";
- name = "\improper Containment Cell 5";
- unacidable = 1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/closed/wall/almayer/research/containment/wall/purple{
- dir = 4
- },
-/area/almayer/medical/containment/cell)
"eas" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -32604,6 +32463,15 @@
icon_state = "mono"
},
/area/almayer/hallways/aft_hallway)
+"ejr" = (
+/obj/structure/pipes/standard/simple/hidden/supply{
+ dir = 10
+ },
+/turf/open/floor/almayer{
+ dir = 6;
+ icon_state = "sterile_green_side"
+ },
+/area/almayer/medical/medical_science)
"ejt" = (
/turf/open/floor/almayer/uscm/directional{
dir = 4
@@ -33051,6 +32919,28 @@
/obj/structure/pipes/standard/simple/hidden/supply,
/turf/open/floor/plating/plating_catwalk,
/area/almayer/living/gym)
+"esP" = (
+/obj/effect/decal/warning_stripes{
+ icon_state = "NE-out";
+ pixel_x = 1;
+ pixel_y = 1
+ },
+/obj/effect/decal/warning_stripes{
+ icon_state = "NW-out";
+ pixel_x = -1;
+ pixel_y = 1
+ },
+/obj/structure/machinery/door/airlock/almayer/research/reinforced{
+ dir = 8;
+ name = "\improper Containment Airlock"
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/medical_science)
"esT" = (
/turf/open/floor/almayer/uscm/directional{
dir = 9
@@ -33437,13 +33327,6 @@
},
/turf/open/floor/plating/plating_catwalk,
/area/almayer/hallways/starboard_umbilical)
-"eBO" = (
-/obj/structure/pipes/standard/simple/hidden/supply,
-/obj/structure/bed,
-/turf/open/floor/almayer{
- icon_state = "mono"
- },
-/area/almayer/medical/medical_science)
"eBV" = (
/obj/structure/window/reinforced{
dir = 8;
@@ -34075,6 +33958,20 @@
"eRL" = (
/turf/open/floor/almayer,
/area/almayer/shipboard/brig/main_office)
+"eRM" = (
+/obj/structure/pipes/standard/simple/hidden/supply,
+/obj/effect/decal/warning_stripes{
+ icon_state = "SW-out";
+ pixel_x = -1
+ },
+/obj/structure/machinery/door/airlock/multi_tile/almayer/medidoor/research{
+ name = "\improper Research Hydroponics Workshop"
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/hydroponics)
"eRR" = (
/obj/structure/surface/rack,
/obj/effect/spawner/random/tool,
@@ -34565,6 +34462,17 @@
},
/turf/open/floor/plating,
/area/almayer/shipboard/brig/execution)
+"fce" = (
+/obj/structure/pipes/standard/simple/hidden/supply,
+/obj/structure/machinery/door/poddoor/shutters/almayer/open{
+ id = "researchlockdownext_door";
+ name = "\improper Research Doorway Shutter"
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/medical_science)
"fcf" = (
/obj/structure/pipes/vents/pump{
dir = 4
@@ -34854,6 +34762,20 @@
icon_state = "plate"
},
/area/almayer/living/grunt_rnr)
+"fhW" = (
+/obj/structure/machinery/door/poddoor/shutters/almayer{
+ dir = 4;
+ id = "W_Containment Cell 1";
+ name = "\improper Containment Cell 5";
+ unacidable = 1
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/closed/wall/almayer/research/containment/wall/purple{
+ dir = 1
+ },
+/area/almayer/medical/containment/cell)
"fiq" = (
/turf/closed/wall/almayer,
/area/almayer/hull/lower_hull/l_m_p)
@@ -39028,6 +38950,31 @@
icon_state = "green"
},
/area/almayer/hallways/port_hallway)
+"hbi" = (
+/obj/structure/machinery/door/airlock/almayer/research/glass/reinforced{
+ dir = 1;
+ id = "Containment Cell 5";
+ locked = 1;
+ name = "\improper Containment Cell 5"
+ },
+/obj/structure/machinery/door/poddoor/shutters/almayer{
+ id = "Containment Cell 5";
+ name = "\improper Containment Cell 5";
+ unacidable = 1
+ },
+/obj/effect/decal/warning_stripes{
+ icon_state = "W"
+ },
+/obj/effect/decal/warning_stripes{
+ icon_state = "E";
+ pixel_x = 1
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
+/obj/structure/pipes/standard/simple/hidden/supply/no_boom,
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/containment/cell)
"hbu" = (
/obj/structure/bed/chair{
dir = 1
@@ -39757,22 +39704,6 @@
icon_state = "redfull"
},
/area/almayer/command/cic)
-"hrn" = (
-/obj/structure/machinery/door/airlock/almayer/research/glass/reinforced{
- name = "\improper Research Reception Laboratory"
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 8;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/medical_science)
"hrF" = (
/obj/structure/pipes/standard/simple/hidden/supply{
dir = 4
@@ -40674,21 +40605,6 @@
},
/turf/open/floor/almayer,
/area/almayer/hallways/port_hallway)
-"hPe" = (
-/obj/structure/disposalpipe/segment,
-/obj/structure/machinery/door/airlock/multi_tile/almayer/medidoor/research,
-/obj/structure/machinery/door/poddoor/shutters/almayer/open{
- id = "researchlockdownext_door";
- name = "\improper Research Doorway Shutter"
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/medical_science)
"hPg" = (
/obj/structure/machinery/constructable_frame{
icon_state = "box_2"
@@ -41012,15 +40928,6 @@
},
/turf/open/floor/plating/plating_catwalk,
/area/almayer/shipboard/brig/cic_hallway)
-"hVf" = (
-/obj/structure/pipes/standard/manifold/hidden/supply{
- dir = 1
- },
-/turf/open/floor/almayer{
- dir = 6;
- icon_state = "sterile_green_side"
- },
-/area/almayer/medical/medical_science)
"hVz" = (
/obj/structure/machinery/light{
dir = 1
@@ -41272,6 +41179,26 @@
icon_state = "plating_striped"
},
/area/almayer/squads/req)
+"icn" = (
+/obj/effect/decal/warning_stripes{
+ icon_state = "E";
+ pixel_x = 1
+ },
+/obj/effect/decal/warning_stripes{
+ icon_state = "W";
+ pixel_x = -1
+ },
+/obj/structure/machinery/door/airlock/almayer/research/reinforced{
+ dir = 8;
+ name = "\improper Containment Airlock"
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/containment)
"icp" = (
/turf/open/floor/almayer{
dir = 8;
@@ -41662,6 +41589,20 @@
icon_state = "plate"
},
/area/almayer/shipboard/brig/main_office)
+"ikN" = (
+/obj/structure/machinery/door/poddoor/shutters/almayer{
+ dir = 4;
+ id = "W_Containment Cell 2";
+ name = "\improper Containment Cell 5";
+ unacidable = 1
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/closed/wall/almayer/research/containment/wall/purple{
+ dir = 8
+ },
+/area/almayer/medical/containment/cell)
"ils" = (
/obj/structure/window/framed/almayer/hull,
/turf/open/floor/plating,
@@ -42072,6 +42013,16 @@
icon_state = "red"
},
/area/almayer/command/lifeboat)
+"iui" = (
+/obj/effect/decal/warning_stripes{
+ icon_state = "E";
+ pixel_x = 1
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/hydroponics)
"iun" = (
/obj/effect/spawner/random/tool,
/turf/open/floor/plating/plating_catwalk,
@@ -42514,6 +42465,35 @@
icon_state = "silver"
},
/area/almayer/living/auxiliary_officer_office)
+"iEh" = (
+/obj/structure/machinery/door/airlock/almayer/research/glass/reinforced{
+ id = "Containment Cell 3";
+ locked = 1;
+ name = "\improper Containment Cell 3";
+ unacidable = 1
+ },
+/obj/structure/machinery/door/poddoor/shutters/almayer/containment{
+ dir = 4;
+ id = "Containment Cell 3";
+ name = "\improper Containment Cell 3"
+ },
+/obj/effect/decal/warning_stripes{
+ icon_state = "S"
+ },
+/obj/effect/decal/warning_stripes{
+ icon_state = "N";
+ pixel_y = 1
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/obj/structure/pipes/standard/simple/hidden/supply/no_boom{
+ dir = 4
+ },
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/containment/cell)
"iEr" = (
/obj/structure/pipes/standard/simple/hidden/supply{
dir = 4
@@ -42896,6 +42876,17 @@
icon_state = "sterile_green_side"
},
/area/almayer/medical/lower_medical_medbay)
+"iMK" = (
+/obj/effect/decal/warning_stripes{
+ icon_state = "S"
+ },
+/obj/structure/pipes/standard/simple/hidden/supply/no_boom{
+ dir = 4
+ },
+/turf/open/floor/almayer{
+ icon_state = "sterile_green_side"
+ },
+/area/almayer/medical/medical_science)
"iNZ" = (
/obj/structure/machinery/light{
dir = 8
@@ -43756,6 +43747,20 @@
icon_state = "orange"
},
/area/almayer/engineering/engine_core)
+"jfV" = (
+/obj/structure/machinery/door/poddoor/shutters/almayer{
+ dir = 4;
+ id = "W_Containment Cell 5";
+ name = "\improper Containment Cell 5";
+ unacidable = 1
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/closed/wall/almayer/research/containment/wall/purple{
+ dir = 1
+ },
+/area/almayer/medical/containment/cell)
"jfY" = (
/obj/structure/surface/table/almayer,
/obj/effect/landmark/map_item,
@@ -44635,22 +44640,6 @@
icon_state = "plate"
},
/area/almayer/hull/upper_hull/u_a_s)
-"jBO" = (
-/obj/structure/machinery/door/poddoor/shutters/almayer{
- dir = 4;
- id = "W_Containment Cell 3";
- name = "\improper Containment Cell 5";
- unacidable = 1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/closed/wall/almayer/research/containment/wall/purple{
- dir = 8
- },
-/area/almayer/medical/containment/cell)
"jCa" = (
/obj/structure/machinery/disposal,
/obj/structure/disposalpipe/trunk,
@@ -44761,6 +44750,34 @@
icon_state = "test_floor4"
},
/area/almayer/hull/upper_hull/u_a_s)
+"jGm" = (
+/obj/structure/machinery/door/airlock/almayer/research/glass/reinforced{
+ id = "Containment Cell 2";
+ locked = 1;
+ name = "\improper Containment Cell 2"
+ },
+/obj/structure/machinery/door/poddoor/shutters/almayer/containment{
+ dir = 4;
+ id = "Containment Cell 2";
+ name = "\improper Containment Cell 2"
+ },
+/obj/effect/decal/warning_stripes{
+ icon_state = "S"
+ },
+/obj/effect/decal/warning_stripes{
+ icon_state = "N";
+ pixel_y = 1
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/obj/structure/pipes/standard/simple/hidden/supply/no_boom{
+ dir = 4
+ },
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/containment/cell)
"jGn" = (
/obj/structure/machinery/light{
dir = 1
@@ -44887,6 +44904,21 @@
icon_state = "plating"
},
/area/almayer/shipboard/port_missiles)
+"jKy" = (
+/obj/structure/machinery/door/airlock/multi_tile/almayer/medidoor{
+ name = "\improper Medical Bay";
+ req_one_access = null
+ },
+/obj/structure/machinery/door/firedoor/border_only/almayer{
+ dir = 2
+ },
+/obj/structure/disposalpipe/segment,
+/obj/structure/pipes/standard/simple/hidden/supply,
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/upper_medical)
"jKz" = (
/obj/effect/decal/warning_stripes{
icon_state = "N";
@@ -45051,37 +45083,6 @@
},
/turf/open/floor/almayer,
/area/almayer/living/briefing)
-"jNc" = (
-/obj/structure/machinery/door/airlock/almayer/research/glass/reinforced{
- id = "Containment Cell 3";
- locked = 1;
- name = "\improper Containment Cell 3";
- unacidable = 1
- },
-/obj/structure/machinery/door/poddoor/shutters/almayer/containment{
- dir = 4;
- id = "Containment Cell 3";
- name = "\improper Containment Cell 3"
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "S"
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "N";
- pixel_y = 1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/obj/structure/pipes/standard/simple/hidden/supply/no_boom{
- dir = 4
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/containment/cell)
"jNq" = (
/obj/structure/closet/secure_closet/personal/cabinet{
req_access = null
@@ -45929,21 +45930,6 @@
icon_state = "plate"
},
/area/almayer/hallways/starboard_hallway)
-"kgs" = (
-/obj/structure/window/framed/almayer/white,
-/obj/structure/machinery/door/poddoor/shutters/almayer/open{
- id = "researchlockdownext_se_2";
- name = "\improper Research Window Shutter"
- },
-/obj/structure/machinery/door/firedoor/border_only/almayer{
- dir = 1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/open/floor/plating,
-/area/almayer/medical/medical_science)
"khd" = (
/obj/structure/bed/chair{
dir = 4
@@ -46637,6 +46623,23 @@
icon_state = "dark_sterile"
},
/area/almayer/engineering/laundry)
+"kxx" = (
+/obj/structure/machinery/door/airlock/almayer/research/glass/reinforced{
+ name = "\improper Research Reception Laboratory"
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/pipes/standard/simple/hidden/supply{
+ dir = 4
+ },
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/medical_science)
"kxL" = (
/obj/structure/closet/coffin/woodencrate,
/obj/structure/largecrate/random/mini/wooden{
@@ -46884,6 +46887,14 @@
icon_state = "dark_sterile"
},
/area/almayer/medical/containment)
+"kCP" = (
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/medical_science)
"kCS" = (
/obj/structure/pipes/standard/simple/hidden/supply,
/turf/open/floor/almayer,
@@ -48545,17 +48556,6 @@
icon_state = "plate"
},
/area/almayer/squads/charlie)
-"lou" = (
-/obj/structure/pipes/standard/manifold/hidden/supply{
- dir = 8
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "S"
- },
-/turf/open/floor/almayer{
- icon_state = "sterile_green_side"
- },
-/area/almayer/medical/medical_science)
"loK" = (
/obj/structure/closet/crate/medical,
/obj/item/storage/firstaid/adv,
@@ -49077,6 +49077,24 @@
icon_state = "plate"
},
/area/almayer/living/auxiliary_officer_office)
+"lyf" = (
+/obj/structure/machinery/door/airlock/almayer/research/reinforced{
+ dir = 8;
+ name = "\improper Containment Airlock"
+ },
+/obj/effect/decal/warning_stripes{
+ icon_state = "S"
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/obj/structure/pipes/standard/simple/hidden/supply/no_boom{
+ dir = 4
+ },
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/medical_science)
"lyi" = (
/obj/structure/surface/table/almayer,
/obj/item/trash/pistachios,
@@ -49175,6 +49193,18 @@
icon_state = "orange"
},
/area/almayer/squads/bravo)
+"lAq" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/pipes/standard/manifold/hidden/supply{
+ dir = 8
+ },
+/turf/open/floor/almayer{
+ dir = 4;
+ icon_state = "sterile_green_side"
+ },
+/area/almayer/medical/medical_science)
"lAy" = (
/obj/structure/bed/chair/comfy/beige{
dir = 8
@@ -49678,21 +49708,6 @@
icon_state = "cargo"
},
/area/almayer/living/cryo_cells)
-"lJv" = (
-/obj/structure/window/framed/almayer/white,
-/obj/structure/machinery/door/firedoor/border_only/almayer{
- dir = 1
- },
-/obj/structure/machinery/door/poddoor/shutters/almayer/open{
- id = "researchlockdownext";
- name = "\improper Research Window Shutter"
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/open/floor/plating,
-/area/almayer/medical/medical_science)
"lJG" = (
/obj/structure/pipes/standard/manifold/hidden/supply,
/obj/structure/disposalpipe/segment{
@@ -49910,20 +49925,6 @@
icon_state = "sterile_green_side"
},
/area/almayer/medical/operating_room_two)
-"lON" = (
-/obj/structure/pipes/standard/simple/hidden/supply,
-/obj/structure/machinery/door/poddoor/shutters/almayer/open{
- id = "researchlockdownext_door";
- name = "\improper Research Doorway Shutter"
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/medical_science)
"lPB" = (
/obj/structure/surface/table/almayer,
/obj/item/device/lightreplacer,
@@ -50740,21 +50741,6 @@
},
/turf/open/floor/plating/plating_catwalk,
/area/almayer/hull/lower_hull/l_f_s)
-"mmN" = (
-/obj/structure/machinery/door/firedoor/border_only/almayer{
- dir = 1
- },
-/obj/structure/machinery/door/poddoor/shutters/almayer/open{
- id = "researchlockdownext_se_2";
- name = "\improper Research Window Shutter"
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/obj/structure/window/framed/almayer/white,
-/turf/open/floor/plating,
-/area/almayer/medical/medical_science)
"mnf" = (
/obj/structure/window/framed/almayer,
/obj/structure/machinery/door/firedoor/border_only/almayer,
@@ -51014,6 +51000,32 @@
icon_state = "orange"
},
/area/almayer/squads/bravo)
+"msw" = (
+/obj/structure/machinery/door/airlock/almayer/research/glass/reinforced{
+ dir = 1;
+ id = "Containment Cell 1";
+ locked = 1;
+ name = "\improper Containment Cell 1"
+ },
+/obj/structure/machinery/door/poddoor/shutters/almayer{
+ id = "Containment Cell 1";
+ name = "\improper Containment Cell 1";
+ unacidable = 1
+ },
+/obj/effect/decal/warning_stripes{
+ icon_state = "E";
+ pixel_x = 1
+ },
+/obj/effect/decal/warning_stripes{
+ icon_state = "E";
+ pixel_x = 1
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
+/obj/structure/pipes/standard/simple/hidden/supply/no_boom,
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/containment/cell)
"msV" = (
/obj/structure/largecrate/random/case/double,
/turf/open/floor/plating/plating_catwalk,
@@ -51600,6 +51612,26 @@
icon_state = "silver"
},
/area/almayer/command/airoom)
+"mHG" = (
+/obj/structure/surface/table/reinforced/prison,
+/obj/structure/machinery/door/window/westright,
+/obj/structure/machinery/door/firedoor/border_only/almayer,
+/obj/structure/machinery/door/window/westright{
+ dir = 4;
+ req_access_txt = "28"
+ },
+/obj/structure/machinery/door/poddoor/shutters/almayer/open{
+ dir = 8;
+ id = "researchlockdownext_windoor";
+ name = "\improper Research Windoor Shutter"
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/medical_science)
"mHO" = (
/obj/structure/machinery/light,
/turf/open/floor/almayer,
@@ -51743,6 +51775,19 @@
"mKq" = (
/turf/closed/wall/almayer/reinforced,
/area/almayer/living/bridgebunks)
+"mKs" = (
+/obj/structure/window/framed/almayer/white,
+/obj/structure/machinery/door/firedoor/border_only/almayer,
+/obj/structure/machinery/door/poddoor/shutters/almayer/open{
+ dir = 8;
+ id = "researchlockdownext_windoor";
+ name = "\improper Research Windoor Shutter"
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/almayer/medical/medical_science)
"mKw" = (
/obj/structure/disposalpipe/junction{
dir = 1
@@ -52332,17 +52377,6 @@
icon_state = "red"
},
/area/almayer/shipboard/brig/general_equipment)
-"mWs" = (
-/obj/structure/pipes/standard/simple/hidden/supply{
- dir = 4
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "S"
- },
-/turf/open/floor/almayer{
- icon_state = "sterile_green_side"
- },
-/area/almayer/medical/medical_science)
"mWw" = (
/obj/structure/pipes/standard/simple/hidden/supply,
/obj/structure/disposalpipe/segment,
@@ -52445,6 +52479,15 @@
icon_state = "mono"
},
/area/almayer/lifeboat_pumps/south1)
+"mYT" = (
+/obj/structure/bed,
+/obj/structure/machinery/power/apc/almayer{
+ dir = 4
+ },
+/turf/open/floor/almayer{
+ icon_state = "mono"
+ },
+/area/almayer/medical/medical_science)
"mYY" = (
/obj/effect/decal/warning_stripes{
icon_state = "SW-out"
@@ -52546,20 +52589,6 @@
icon_state = "kitchen"
},
/area/almayer/engineering/upper_engineering/port)
-"naR" = (
-/obj/structure/pipes/standard/simple/hidden/supply{
- dir = 4
- },
-/obj/structure/machinery/iv_drip,
-/obj/effect/decal/warning_stripes{
- icon_state = "E";
- pixel_x = 1
- },
-/turf/open/floor/almayer{
- dir = 4;
- icon_state = "sterile_green_corner"
- },
-/area/almayer/medical/medical_science)
"naV" = (
/obj/structure/machinery/door/airlock/almayer/generic{
dir = 2;
@@ -53553,10 +53582,6 @@
},
/turf/open/floor/plating,
/area/almayer/shipboard/brig/main_office)
-"nxF" = (
-/obj/structure/pipes/standard/simple/hidden/supply,
-/turf/closed/wall/almayer/white/reinforced,
-/area/almayer/medical/medical_science)
"nxK" = (
/obj/structure/sign/safety/high_voltage{
pixel_y = -32
@@ -56281,30 +56306,6 @@
icon_state = "plate"
},
/area/almayer/hull/lower_hull/l_m_s)
-"oIr" = (
-/obj/effect/decal/warning_stripes{
- icon_state = "NE-out";
- pixel_x = 1;
- pixel_y = 1
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "NW-out";
- pixel_x = -1;
- pixel_y = 1
- },
-/obj/structure/machinery/door/airlock/almayer/research/reinforced{
- dir = 8;
- name = "\improper Containment Airlock"
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/medical_science)
"oIB" = (
/turf/closed/wall/almayer,
/area/almayer/command/combat_correspondent)
@@ -56947,6 +56948,18 @@
icon_state = "plate"
},
/area/almayer/hull/lower_hull/l_m_p)
+"oYj" = (
+/obj/structure/machinery/door/firedoor/border_only/almayer{
+ dir = 1
+ },
+/obj/structure/machinery/door/poddoor/shutters/almayer/open{
+ id = "researchlockdownext_se_2";
+ name = "\improper Research Window Shutter"
+ },
+/obj/structure/window/framed/almayer/white,
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
+/turf/open/floor/plating,
+/area/almayer/medical/medical_science)
"oYp" = (
/obj/structure/bed/chair/office/dark{
dir = 8
@@ -58239,6 +58252,18 @@
},
/turf/open/floor/plating,
/area/almayer/shipboard/brig/perma)
+"pFz" = (
+/obj/structure/machinery/door/poddoor/shutters/almayer{
+ dir = 4;
+ id = "W_Containment Cell 5";
+ name = "\improper Containment Cell 5";
+ unacidable = 1
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/closed/wall/almayer/research/containment/wall/purple,
+/area/almayer/medical/containment/cell)
"pFA" = (
/obj/structure/pipes/standard/simple/visible{
dir = 4
@@ -58483,22 +58508,6 @@
icon_state = "dark_sterile"
},
/area/almayer/medical/lower_medical_medbay)
-"pLO" = (
-/obj/structure/machinery/door/poddoor/shutters/almayer{
- dir = 4;
- id = "W_Containment Cell 5";
- name = "\improper Containment Cell 5";
- unacidable = 1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/closed/wall/almayer/research/containment/wall/purple{
- dir = 1
- },
-/area/almayer/medical/containment/cell)
"pLW" = (
/obj/structure/machinery/firealarm{
dir = 4;
@@ -58756,18 +58765,6 @@
icon_state = "plate"
},
/area/almayer/living/offices)
-"pRn" = (
-/obj/structure/pipes/standard/manifold/hidden/supply{
- dir = 4
- },
-/obj/structure/bed,
-/obj/structure/machinery/power/apc/almayer{
- dir = 4
- },
-/turf/open/floor/almayer{
- icon_state = "mono"
- },
-/area/almayer/medical/medical_science)
"pRy" = (
/turf/open/floor/almayer/research/containment/corner_var1{
dir = 4
@@ -59435,6 +59432,15 @@
icon_state = "plate"
},
/area/almayer/squads/alpha_bravo_shared)
+"qfu" = (
+/obj/structure/machinery/door/firedoor/border_only/almayer{
+ dir = 2
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/upper_medical)
"qfy" = (
/obj/effect/decal/warning_stripes{
icon_state = "N";
@@ -59848,6 +59854,20 @@
icon_state = "plate"
},
/area/almayer/hull/lower_hull/l_a_s)
+"qnZ" = (
+/obj/structure/machinery/door/poddoor/shutters/almayer{
+ dir = 4;
+ id = "W_Containment Cell 2";
+ name = "\improper Containment Cell 5";
+ unacidable = 1
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/closed/wall/almayer/research/containment/wall/purple{
+ dir = 4
+ },
+/area/almayer/medical/containment/cell)
"qof" = (
/obj/structure/window/framed/almayer,
/obj/structure/machinery/door/poddoor/shutters/almayer/open{
@@ -60115,7 +60135,7 @@
},
/obj/structure/machinery/door/airlock/multi_tile/almayer/medidoor{
dir = 2;
- id_tag = "tc04";
+ id_tag = "tc02";
name = "\improper Treatment Center"
},
/turf/open/floor/almayer{
@@ -60201,20 +60221,6 @@
icon_state = "silver"
},
/area/almayer/command/airoom)
-"qxm" = (
-/obj/structure/machinery/door/poddoor/shutters/almayer{
- dir = 4;
- id = "W_Containment Cell 5";
- name = "\improper Containment Cell 5";
- unacidable = 1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/closed/wall/almayer/research/containment/wall/purple,
-/area/almayer/medical/containment/cell)
"qxA" = (
/obj/structure/closet/firecloset,
/turf/open/floor/almayer{
@@ -60508,23 +60514,6 @@
icon_state = "plating"
},
/area/almayer/command/cic)
-"qEn" = (
-/obj/structure/pipes/standard/simple/hidden/supply,
-/obj/effect/decal/warning_stripes{
- icon_state = "SW-out";
- pixel_x = -1
- },
-/obj/structure/machinery/door/airlock/multi_tile/almayer/medidoor/research{
- name = "\improper Research Hydroponics Workshop"
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/hydroponics)
"qEy" = (
/obj/structure/disposalpipe/segment,
/obj/structure/pipes/standard/simple/hidden/supply{
@@ -61766,6 +61755,17 @@
icon_state = "plate"
},
/area/almayer/shipboard/port_point_defense)
+"rfY" = (
+/obj/structure/pipes/standard/simple/hidden/supply{
+ dir = 4
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/medical_science)
"rgy" = (
/obj/structure/pipes/standard/manifold/hidden/supply{
dir = 1
@@ -62027,16 +62027,6 @@
icon_state = "dark_sterile"
},
/area/almayer/medical/lower_medical_medbay)
-"rmc" = (
-/obj/structure/pipes/standard/simple/hidden/supply,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/almayer{
- dir = 4;
- icon_state = "sterile_green_side"
- },
-/area/almayer/medical/medical_science)
"rmv" = (
/obj/structure/machinery/door/airlock/almayer/security{
dir = 2;
@@ -62994,7 +62984,7 @@
},
/obj/structure/machinery/door/airlock/multi_tile/almayer/medidoor{
dir = 2;
- id_tag = "tc04";
+ id_tag = "tc01";
name = "\improper Treatment Center"
},
/turf/open/floor/almayer{
@@ -63714,6 +63704,18 @@
icon_state = "plate"
},
/area/almayer/hallways/port_hallway)
+"rZL" = (
+/obj/structure/machinery/door/poddoor/shutters/almayer{
+ dir = 4;
+ id = "W_Containment Cell 1";
+ name = "\improper Containment Cell 5";
+ unacidable = 1
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/closed/wall/almayer/research/containment/wall/purple,
+/area/almayer/medical/containment/cell)
"rZP" = (
/obj/structure/surface/table/almayer,
/obj/item/tool/weldpack,
@@ -64877,6 +64879,17 @@
icon_state = "silver"
},
/area/almayer/shipboard/brig/cic_hallway)
+"sCU" = (
+/obj/structure/machinery/iv_drip,
+/obj/effect/decal/warning_stripes{
+ icon_state = "E";
+ pixel_x = 1
+ },
+/turf/open/floor/almayer{
+ dir = 4;
+ icon_state = "sterile_green_corner"
+ },
+/area/almayer/medical/medical_science)
"sDu" = (
/obj/item/clothing/under/marine/dress,
/turf/open/floor/almayer{
@@ -65436,6 +65449,17 @@
icon_state = "sterile_green_side"
},
/area/almayer/medical/lower_medical_medbay)
+"sQt" = (
+/obj/effect/decal/warning_stripes{
+ icon_state = "S"
+ },
+/obj/structure/pipes/standard/simple/hidden/supply/no_boom{
+ dir = 9
+ },
+/turf/open/floor/almayer{
+ icon_state = "sterile_green_side"
+ },
+/area/almayer/medical/medical_science)
"sQF" = (
/turf/open/floor/almayer{
icon_state = "red"
@@ -65949,36 +65973,6 @@
icon_state = "red"
},
/area/almayer/hallways/starboard_hallway)
-"taH" = (
-/obj/structure/machinery/door/airlock/almayer/research/glass/reinforced{
- id = "Containment Cell 2";
- locked = 1;
- name = "\improper Containment Cell 2"
- },
-/obj/structure/machinery/door/poddoor/shutters/almayer/containment{
- dir = 4;
- id = "Containment Cell 2";
- name = "\improper Containment Cell 2"
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "S"
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "N";
- pixel_y = 1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/obj/structure/pipes/standard/simple/hidden/supply/no_boom{
- dir = 4
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/containment/cell)
"tbD" = (
/obj/structure/ladder{
height = 2;
@@ -66456,6 +66450,12 @@
},
/turf/open/floor/almayer,
/area/almayer/living/briefing)
+"tmI" = (
+/obj/structure/bed,
+/turf/open/floor/almayer{
+ icon_state = "mono"
+ },
+/area/almayer/medical/medical_science)
"tmK" = (
/obj/structure/machinery/door/airlock/almayer/maint{
dir = 1;
@@ -68197,6 +68197,17 @@
icon_state = "plate"
},
/area/almayer/shipboard/port_point_defense)
+"tZd" = (
+/obj/effect/decal/warning_stripes{
+ icon_state = "S"
+ },
+/obj/structure/pipes/standard/simple/hidden/supply/no_boom{
+ dir = 5
+ },
+/turf/open/floor/almayer{
+ icon_state = "sterile_green_side"
+ },
+/area/almayer/medical/medical_science)
"tZe" = (
/obj/item/trash/USCMtray{
pixel_x = -4;
@@ -68951,6 +68962,18 @@
},
/turf/open/floor/almayer,
/area/almayer/command/lifeboat)
+"urH" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/machinery/door/airlock/multi_tile/almayer/medidoor/research,
+/obj/structure/machinery/door/poddoor/shutters/almayer/open{
+ id = "researchlockdownext_door";
+ name = "\improper Research Doorway Shutter"
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
+/turf/open/floor/almayer{
+ icon_state = "test_floor4"
+ },
+/area/almayer/medical/medical_science)
"urM" = (
/obj/structure/machinery/light{
dir = 8
@@ -69009,17 +69032,6 @@
},
/turf/open/floor/plating/plating_catwalk,
/area/almayer/engineering/engine_core)
-"usy" = (
-/obj/structure/pipes/standard/simple/hidden/supply{
- dir = 9
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "S"
- },
-/turf/open/floor/almayer{
- icon_state = "sterile_green_side"
- },
-/area/almayer/medical/medical_science)
"usB" = (
/obj/structure/pipes/standard/manifold/hidden/supply/no_boom{
dir = 8
@@ -69896,6 +69908,21 @@
},
/turf/open/floor/almayer,
/area/almayer/shipboard/brig/main_office)
+"uJM" = (
+/obj/effect/decal/warning_stripes{
+ icon_state = "E";
+ pixel_x = 1
+ },
+/obj/effect/decal/warning_stripes{
+ icon_state = "W";
+ pixel_x = -1
+ },
+/obj/structure/window/framed/almayer/white,
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/almayer/medical/containment)
"uJU" = (
/obj/structure/machinery/cryopod/right{
pixel_y = 6
@@ -71896,6 +71923,14 @@
icon_state = "greenfull"
},
/area/almayer/shipboard/brig/cells)
+"vzA" = (
+/obj/structure/window/framed/almayer/white,
+/obj/structure/machinery/door/firedoor/border_only/almayer{
+ dir = 2
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
+/turf/open/floor/plating,
+/area/almayer/medical/upper_medical)
"vzK" = (
/turf/open/floor/almayer,
/area/almayer/engineering/ce_room)
@@ -72048,6 +72083,31 @@
icon_state = "dark_sterile"
},
/area/almayer/shipboard/brig/chief_mp_office)
+"vCM" = (
+/obj/structure/surface/table/almayer,
+/obj/item/reagent_container/glass/beaker{
+ pixel_x = 8
+ },
+/obj/item/paper_bin/wy{
+ pixel_x = -5;
+ pixel_y = 6
+ },
+/obj/item/tool/pen{
+ pixel_y = -2
+ },
+/obj/item/reagent_container/dropper{
+ pixel_x = -1;
+ pixel_y = 9
+ },
+/obj/structure/machinery/biohazard_lockdown{
+ pixel_x = 8;
+ pixel_y = 10
+ },
+/obj/structure/pipes/standard/simple/hidden/supply/no_boom,
+/turf/open/floor/almayer{
+ icon_state = "sterile_green"
+ },
+/area/almayer/medical/containment)
"vCO" = (
/obj/effect/landmark/start/bridge,
/turf/open/floor/plating/plating_catwalk,
@@ -72266,6 +72326,18 @@
icon_state = "blue"
},
/area/almayer/hallways/aft_hallway)
+"vIQ" = (
+/obj/structure/window/framed/almayer/white,
+/obj/structure/machinery/door/firedoor/border_only/almayer{
+ dir = 1
+ },
+/obj/structure/machinery/door/poddoor/shutters/almayer/open{
+ id = "researchlockdownext";
+ name = "\improper Research Window Shutter"
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white,
+/turf/open/floor/plating,
+/area/almayer/medical/medical_science)
"vJg" = (
/obj/structure/machinery/light/small,
/turf/open/floor/almayer{
@@ -72384,24 +72456,6 @@
icon_state = "plate"
},
/area/almayer/hull/lower_hull/l_f_s)
-"vLj" = (
-/obj/structure/machinery/door/airlock/multi_tile/almayer/medidoor{
- name = "\improper Medical Bay";
- req_one_access = null
- },
-/obj/structure/machinery/door/firedoor/border_only/almayer{
- dir = 2
- },
-/obj/structure/disposalpipe/segment,
-/obj/structure/pipes/standard/simple/hidden/supply,
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/upper_medical)
"vLA" = (
/obj/effect/decal/warning_stripes{
icon_state = "W";
@@ -72500,18 +72554,6 @@
"vOy" = (
/turf/closed/wall/almayer/white/reinforced,
/area/almayer/medical/medical_science)
-"vOP" = (
-/obj/structure/machinery/door/firedoor/border_only/almayer{
- dir = 2
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/upper_medical)
"vPj" = (
/obj/structure/surface/table/reinforced/almayer_B,
/obj/item/device/flashlight/lamp{
@@ -73077,33 +73119,6 @@
icon_state = "sterile_green_side"
},
/area/almayer/medical/lower_medical_medbay)
-"vYz" = (
-/obj/structure/surface/table/almayer,
-/obj/item/reagent_container/glass/beaker{
- pixel_x = 8
- },
-/obj/item/paper_bin/wy{
- pixel_x = -5;
- pixel_y = 6
- },
-/obj/item/tool/pen{
- pixel_y = -2
- },
-/obj/structure/machinery/door_control/brbutton/alt{
- id = "Containment Breach";
- name = "Emergency Containment Breach";
- pixel_x = 8;
- pixel_y = 10
- },
-/obj/item/reagent_container/dropper{
- pixel_x = -1;
- pixel_y = 9
- },
-/obj/structure/pipes/standard/simple/hidden/supply/no_boom,
-/turf/open/floor/almayer{
- icon_state = "sterile_green"
- },
-/area/almayer/medical/containment)
"vYC" = (
/obj/effect/decal/warning_stripes{
icon_state = "S"
@@ -73310,26 +73325,6 @@
},
/turf/open/floor/almayer,
/area/almayer/living/auxiliary_officer_office)
-"wdo" = (
-/obj/structure/pipes/standard/simple/hidden/supply{
- dir = 4
- },
-/obj/structure/machinery/door/airlock/almayer/research/reinforced{
- dir = 8;
- name = "\improper Containment Airlock"
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "S"
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/medical_science)
"wdr" = (
/obj/structure/machinery/power/apc/almayer,
/turf/open/floor/almayer{
@@ -73364,19 +73359,6 @@
icon_state = "plate"
},
/area/almayer/engineering/upper_engineering/starboard)
-"wei" = (
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "E";
- pixel_x = 1
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/hydroponics)
"wex" = (
/obj/structure/machinery/light{
dir = 4
@@ -73683,19 +73665,6 @@
icon_state = "sterile_green"
},
/area/almayer/medical/lockerroom)
-"wky" = (
-/obj/structure/pipes/standard/simple/hidden/supply{
- dir = 4
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/medical_science)
"wkH" = (
/obj/structure/surface/table/reinforced/almayer_B,
/obj/item/device/whistle{
@@ -74807,23 +74776,6 @@
icon_state = "plate"
},
/area/almayer/command/combat_correspondent)
-"wKP" = (
-/obj/effect/decal/warning_stripes{
- icon_state = "E";
- pixel_x = 1
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "W";
- pixel_x = -1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/obj/structure/window/framed/almayer/white,
-/turf/open/floor/plating,
-/area/almayer/medical/containment)
"wLi" = (
/obj/structure/machinery/door_control/airlock{
id = "s_engi";
@@ -74938,16 +74890,6 @@
icon_state = "cargo"
},
/area/almayer/squads/alpha)
-"wMO" = (
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/medical_science)
"wNl" = (
/obj/structure/surface/table/almayer,
/obj/item/trash/USCMtray{
@@ -76099,6 +76041,20 @@
icon_state = "greencorner"
},
/area/almayer/hallways/port_hallway)
+"xlf" = (
+/obj/structure/machinery/door/poddoor/shutters/almayer{
+ dir = 4;
+ id = "W_Containment Cell 3";
+ name = "\improper Containment Cell 5";
+ unacidable = 1
+ },
+/obj/structure/machinery/door/poddoor/almayer/biohazard/white{
+ dir = 4
+ },
+/turf/closed/wall/almayer/research/containment/wall/purple{
+ dir = 8
+ },
+/area/almayer/medical/containment/cell)
"xlk" = (
/obj/structure/surface/table/almayer,
/turf/open/floor/almayer,
@@ -76485,6 +76441,20 @@
icon_state = "sterile_green_side"
},
/area/almayer/medical/lower_medical_lobby)
+"xtT" = (
+/obj/structure/machinery/light{
+ dir = 1
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/pipes/standard/simple/hidden/supply{
+ dir = 10
+ },
+/turf/open/floor/almayer{
+ icon_state = "dark_sterile"
+ },
+/area/almayer/medical/medical_science)
"xuc" = (
/obj/structure/surface/table/almayer,
/obj/item/tool/extinguisher,
@@ -76506,34 +76476,6 @@
},
/turf/open/floor/plating/plating_catwalk,
/area/almayer/hull/upper_hull/u_f_p)
-"xuE" = (
-/obj/structure/machinery/door/airlock/almayer/research/glass/reinforced{
- dir = 1;
- id = "Containment Cell 5";
- locked = 1;
- name = "\improper Containment Cell 5"
- },
-/obj/structure/machinery/door/poddoor/shutters/almayer{
- id = "Containment Cell 5";
- name = "\improper Containment Cell 5";
- unacidable = 1
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "W"
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "E";
- pixel_x = 1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/obj/structure/pipes/standard/simple/hidden/supply/no_boom,
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/containment/cell)
"xuI" = (
/obj/structure/sign/safety/water{
pixel_x = 8;
@@ -78582,28 +78524,6 @@
icon_state = "plate"
},
/area/almayer/shipboard/brig/main_office)
-"ylc" = (
-/obj/effect/decal/warning_stripes{
- icon_state = "E";
- pixel_x = 1
- },
-/obj/effect/decal/warning_stripes{
- icon_state = "W";
- pixel_x = -1
- },
-/obj/structure/machinery/door/poddoor/almayer/open{
- dir = 4;
- id = "Containment Breach";
- name = "\improper Secure Airlock"
- },
-/obj/structure/machinery/door/airlock/almayer/research/reinforced{
- dir = 8;
- name = "\improper Containment Airlock"
- },
-/turf/open/floor/almayer{
- icon_state = "test_floor4"
- },
-/area/almayer/medical/containment)
"yle" = (
/obj/effect/landmark/start/marine/engineer/delta,
/obj/effect/landmark/late_join/delta,
@@ -96277,7 +96197,7 @@ baI
baI
baI
baI
-bFJ
+baI
bGG
bHB
btO
@@ -97079,7 +96999,7 @@ baI
baI
baI
baI
-baI
+bFJ
baI
baI
baI
@@ -100743,7 +100663,7 @@ baI
baI
baI
baI
-bFR
+baI
bGN
bHB
xAY
@@ -101545,7 +101465,7 @@ baI
baI
baI
baI
-baI
+bFR
baI
baI
baI
@@ -108556,8 +108476,8 @@ vOy
vOy
vOy
vOy
-wMO
-wky
+kCP
+rfY
sqf
hon
ajt
@@ -109163,11 +109083,11 @@ vti
gGx
vti
lid
-lJv
+vIQ
aCC
kXw
pxo
-asn
+vzA
ago
asW
cwJ
@@ -109366,11 +109286,11 @@ ueJ
ueJ
oDi
trF
-lJv
+vIQ
edv
kXw
pxo
-asn
+vzA
ayT
akU
avj
@@ -109560,7 +109480,7 @@ hng
dnC
hPN
vCk
-qEn
+eRM
qam
riE
gAS
@@ -109569,11 +109489,11 @@ dVu
eSo
qmD
aIC
-lJv
+vIQ
aCt
kXw
pxo
-asn
+vzA
ayT
aii
avm
@@ -109763,7 +109683,7 @@ xyt
wiW
tOr
dBj
-wei
+iui
kBP
kBP
jsx
@@ -109976,10 +109896,10 @@ kXw
vtm
emK
fGu
-hPe
+urH
sdu
btC
-vLj
+jKy
ahM
kSJ
avj
@@ -110176,13 +110096,13 @@ vkp
cfT
hec
gNp
-hVf
+ejr
dVu
-rmc
-lON
+lAq
+fce
dVu
oDR
-vOP
+qfu
bYe
bnD
aWH
@@ -110379,12 +110299,12 @@ vkp
aoM
kBo
kBP
-naR
+sCU
vOy
-hrn
+kxx
vOy
-aRd
-aIo
+mHG
+mKs
vOy
qLK
akU
@@ -110580,11 +110500,11 @@ vOy
dHV
vkp
jUM
-lou
-eBO
-pRn
-nxF
-ayZ
+tZd
+tmI
+mYT
+vOy
+xtT
aCD
hFC
qmy
@@ -110781,9 +110701,9 @@ mKx
kZV
vOy
vOy
-oIr
+esP
vOy
-wdo
+lyf
vOy
vOy
vOy
@@ -110791,7 +110711,7 @@ qqQ
aoM
aoM
vgB
-kgs
+cHS
ayT
aii
avj
@@ -110986,7 +110906,7 @@ vOy
jFf
vkp
jrM
-mWs
+iMK
lmw
vOy
dyb
@@ -110994,7 +110914,7 @@ tsM
prx
fpT
eVT
-kgs
+cHS
ayT
aii
avj
@@ -111189,7 +111109,7 @@ vOy
vqZ
vkp
rDr
-usy
+sQt
nDo
vOy
glB
@@ -111197,7 +111117,7 @@ vkp
ger
aoM
aFf
-mmN
+oYj
ayT
aii
avj
@@ -111796,9 +111716,9 @@ mSK
mSK
vOy
vOy
-ylc
-wKP
-ylc
+icn
+uJM
+icn
vOy
vOy
rhO
@@ -112607,11 +112527,11 @@ wWz
anw
wLy
jlG
-aqP
+msw
kCE
wLN
npt
-xuE
+hbi
hqh
wLy
eiE
@@ -113011,15 +112931,15 @@ avj
vOy
woh
vgO
-aoJ
-alk
+fhW
+rZL
xAe
avH
wse
cXC
woh
-pLO
-qxm
+jfV
+pFz
vgO
xAe
vOy
@@ -113625,7 +113545,7 @@ apR
aqS
mnW
nPf
-vYz
+vCM
awR
uoi
vOy
@@ -114230,13 +114150,13 @@ vOy
elR
xXh
xXh
-apU
-taH
-aBe
+ikN
+jGm
+qnZ
otu
-jBO
-jNc
-ean
+xlf
+iEh
+chJ
xXh
xXh
dMK
diff --git a/maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm b/maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm
index a39d7d7fffba..eb4f5fdb6025 100644
--- a/maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm
+++ b/maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm
@@ -1061,13 +1061,6 @@
/obj/effect/landmark/late_join,
/turf/open/gm/dirt,
/area/whiskey_outpost/inside/caves/tunnel)
-"dV" = (
-/obj/structure/machinery/chem_master,
-/turf/open/floor{
- dir = 9;
- icon_state = "whitegreen"
- },
-/area/whiskey_outpost/inside/hospital)
"dW" = (
/turf/open/floor/plating{
icon_state = "platebot"
@@ -1202,16 +1195,6 @@
/obj/effect/landmark/late_join,
/turf/open/gm/dirt,
/area/whiskey_outpost/inside/caves/tunnel)
-"ez" = (
-/obj/structure/machinery/chem_dispenser,
-/obj/structure/machinery/light/small{
- dir = 8
- },
-/turf/open/floor{
- dir = 1;
- icon_state = "whitegreen"
- },
-/area/whiskey_outpost/inside/hospital)
"eB" = (
/turf/closed/wall/rock/brown,
/area/whiskey_outpost/outside/lane/three_north)
@@ -1958,13 +1941,6 @@
/obj/structure/machinery/defenses/sentry/premade,
/turf/open/gm/dirt,
/area/whiskey_outpost/outside/lane/four_north)
-"he" = (
-/obj/structure/machinery/chem_dispenser,
-/turf/open/floor{
- dir = 6;
- icon_state = "whitegreen"
- },
-/area/whiskey_outpost/inside/hospital)
"hf" = (
/obj/structure/disposalpipe/segment{
dir = 1;
@@ -2225,6 +2201,9 @@
icon_state = "floor_plate"
},
/area/whiskey_outpost/inside/living)
+"hP" = (
+/turf/open/space/basic,
+/area/whiskey_outpost/inside/caves)
"hQ" = (
/turf/open/floor/prison{
icon_state = "floor_plate"
@@ -2425,13 +2404,6 @@
icon_state = "warnplate"
},
/area/whiskey_outpost/outside/north/northeast)
-"ix" = (
-/obj/structure/machinery/chem_master,
-/turf/open/floor{
- dir = 10;
- icon_state = "whitegreen"
- },
-/area/whiskey_outpost/inside/hospital)
"iy" = (
/obj/effect/landmark/start/whiskey/cargo,
/turf/open/floor/prison{
@@ -4299,6 +4271,15 @@
/obj/item/shard,
/turf/open/floor/plating,
/area/whiskey_outpost/outside/south/far)
+"pn" = (
+/obj/structure/machinery/floodlight{
+ light_on = 1
+ },
+/turf/open/floor/plating{
+ dir = 6;
+ icon_state = "asteroidwarning"
+ },
+/area/whiskey_outpost/outside/north/platform)
"pq" = (
/turf/closed/wall/r_wall,
/area/whiskey_outpost/inside/living)
@@ -5967,15 +5948,6 @@
icon_state = "floor_plate"
},
/area/whiskey_outpost/inside/bunker)
-"vd" = (
-/obj/structure/machinery/floodlight{
- on = 1
- },
-/turf/open/floor/plating{
- dir = 6;
- icon_state = "asteroidwarning"
- },
-/area/whiskey_outpost/outside/north/platform)
"ve" = (
/turf/closed/wall,
/area/whiskey_outpost/outside/lane/one_north)
@@ -7369,28 +7341,10 @@
"Af" = (
/turf/open/gm/coast/beachcorner/north_west,
/area/whiskey_outpost/outside/lane/four_south)
-"Ag" = (
-/obj/structure/machinery/floodlight{
- on = 1
- },
-/turf/open/floor/plating{
- dir = 5;
- icon_state = "asteroidwarning"
- },
-/area/whiskey_outpost/outside/north/platform)
"Ah" = (
/obj/structure/sign/poster,
/turf/closed/wall/r_wall,
/area/whiskey_outpost/inside/supply)
-"Ak" = (
-/obj/structure/machinery/floodlight{
- on = 1
- },
-/turf/open/floor/plating{
- dir = 9;
- icon_state = "asteroidwarning"
- },
-/area/whiskey_outpost/outside/north/platform)
"Am" = (
/obj/structure/surface/rack,
/obj/effect/landmark/wo_supplies/guns/common/m41a,
@@ -7969,6 +7923,15 @@
icon_state = "asteroidfloor"
},
/area/whiskey_outpost/outside/north/platform)
+"Cs" = (
+/obj/structure/machinery/chem_master{
+ tether_range = 4
+ },
+/turf/open/floor{
+ dir = 6;
+ icon_state = "whitegreen"
+ },
+/area/whiskey_outpost/inside/hospital)
"Ct" = (
/obj/structure/platform_decoration{
dir = 4
@@ -8037,6 +8000,16 @@
icon_state = "floor_plate"
},
/area/whiskey_outpost/inside/bunker/pillbox/three)
+"CC" = (
+/obj/structure/machinery/chem_dispenser,
+/obj/structure/machinery/light/small{
+ dir = 8
+ },
+/turf/open/floor{
+ dir = 10;
+ icon_state = "whitegreen"
+ },
+/area/whiskey_outpost/inside/hospital)
"CD" = (
/turf/open/gm/river,
/area/whiskey_outpost/outside/lane/one_north)
@@ -8095,6 +8068,15 @@
/obj/structure/machinery/colony_floodlight,
/turf/open/gm/dirt,
/area/whiskey_outpost/outside/lane/four_south)
+"CU" = (
+/obj/structure/machinery/floodlight{
+ light_on = 1
+ },
+/turf/open/floor/plating{
+ dir = 5;
+ icon_state = "asteroidwarning"
+ },
+/area/whiskey_outpost/outside/north/platform)
"CY" = (
/obj/structure/platform,
/turf/open/gm/river,
@@ -8430,6 +8412,15 @@
"Ee" = (
/turf/open/gm/coast/east,
/area/whiskey_outpost/outside/river/east)
+"Ef" = (
+/obj/structure/machinery/floodlight{
+ light_on = 1
+ },
+/turf/open/floor/plating{
+ dir = 9;
+ icon_state = "asteroidwarning"
+ },
+/area/whiskey_outpost/outside/north/platform)
"Eg" = (
/turf/open/gm/coast/beachcorner/north_west,
/area/whiskey_outpost/outside/river/west)
@@ -8476,15 +8467,6 @@
},
/turf/open/gm/coast/beachcorner2/south_east,
/area/whiskey_outpost/outside/lane/four_north)
-"Et" = (
-/obj/structure/machinery/floodlight{
- on = 1
- },
-/turf/open/floor/plating{
- dir = 10;
- icon_state = "asteroidwarning"
- },
-/area/whiskey_outpost/outside/north/platform)
"Eu" = (
/turf/open/gm/coast/beachcorner/north_east,
/area/whiskey_outpost/outside/river/west)
@@ -10027,6 +10009,15 @@
"Lh" = (
/turf/open/gm/coast/south,
/area/whiskey_outpost/outside/river/west)
+"Li" = (
+/obj/structure/machinery/chem_master{
+ tether_range = 4
+ },
+/turf/open/floor{
+ dir = 1;
+ icon_state = "whitegreen"
+ },
+/area/whiskey_outpost/inside/hospital)
"Lj" = (
/obj/effect/landmark/start/whiskey/medic,
/turf/open/floor/prison{
@@ -12535,6 +12526,13 @@
icon_state = "desert2"
},
/area/whiskey_outpost/inside/caves/caverns/west)
+"WA" = (
+/obj/structure/machinery/chem_dispenser,
+/turf/open/floor{
+ dir = 9;
+ icon_state = "whitegreen"
+ },
+/area/whiskey_outpost/inside/hospital)
"WC" = (
/obj/structure/disposalpipe/segment{
dir = 4;
@@ -12653,6 +12651,15 @@
/obj/effect/landmark/start/whiskey/marine,
/turf/open/jungle,
/area/whiskey_outpost/outside/lane/two_south)
+"Xi" = (
+/obj/structure/machinery/floodlight{
+ light_on = 1
+ },
+/turf/open/floor/plating{
+ dir = 10;
+ icon_state = "asteroidwarning"
+ },
+/area/whiskey_outpost/outside/north/platform)
"Xj" = (
/obj/structure/machinery/light/small{
dir = 8
@@ -22662,7 +22669,7 @@ mT
mT
mT
mT
-mT
+hP
mT
mT
dl
@@ -23061,12 +23068,12 @@ mT
mT
mT
mT
+hP
mT
mT
mT
mT
-mT
-mT
+hP
mT
mT
qz
@@ -23074,11 +23081,11 @@ JF
qB
yh
qz
-dV
+WA
gN
hb
JT
-ix
+CC
qz
CE
RU
@@ -23478,11 +23485,11 @@ SC
la
As
qz
-ez
+Li
qB
hb
oQ
-he
+Cs
qz
iV
js
@@ -24322,13 +24329,13 @@ BN
BN
ed
Dp
-vd
+pn
aj
Av
zY
Av
aj
-Ag
+CU
Dn
kI
fI
@@ -25534,13 +25541,13 @@ sQ
ed
ed
Dp
-Et
+Xi
aj
xM
mY
xM
aj
-Ak
+Ef
Dn
kI
FX
@@ -28564,13 +28571,13 @@ sQ
ed
ed
Dp
-vd
+pn
aj
Av
Bt
FV
aj
-Ag
+CU
Dn
Dp
CM
@@ -29359,13 +29366,13 @@ uv
sU
sQ
Dp
-vd
+pn
aj
Av
Bt
Av
aj
-Ag
+CU
Dn
BN
BN
@@ -29776,13 +29783,13 @@ BN
ed
ed
Dp
-Et
+Xi
aj
xM
Bw
xM
aj
-Ak
+Ef
Dn
kI
fI
@@ -30571,13 +30578,13 @@ mT
in
ed
Dp
-Et
+Xi
aj
xM
Bw
xM
aj
-Ak
+Ef
Dn
ed
AC
diff --git a/maps/shuttles/dropship_alamo.dmm b/maps/shuttles/dropship_alamo.dmm
index 8ccfac333080..7c49edfdd0d2 100644
--- a/maps/shuttles/dropship_alamo.dmm
+++ b/maps/shuttles/dropship_alamo.dmm
@@ -15,19 +15,16 @@
},
/area/shuttle/drop1/sulaco)
"ax" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "101"
- },
+/obj/structure/shuttle/part/dropship1/transparent/nose_center,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"be" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "74"
- },
+/obj/structure/shuttle/part/dropship1/transparent/upper_right_wing,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"bj" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "102"
- },
+/obj/structure/shuttle/part/dropship1/transparent/nose_top_right,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"cr" = (
/obj/structure/machinery/camera/autoname/almayer/dropship_one{
@@ -47,14 +44,8 @@
},
/area/shuttle/drop1/sulaco)
"cC" = (
-/turf/closed/shuttle/dropship1{
- icon_state = "99"
- },
-/area/shuttle/drop1/sulaco)
-"cK" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "17"
- },
+/obj/structure/shuttle/part/dropship1/nose_front_right,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"cR" = (
/obj/item/device/radio/intercom/alamo{
@@ -83,9 +74,8 @@
},
/area/shuttle/drop1/sulaco)
"eD" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "41"
- },
+/obj/structure/shuttle/part/dropship1/transparent/engine_right_cap,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"hG" = (
/turf/closed/shuttle/dropship1{
@@ -93,9 +83,8 @@
},
/area/shuttle/drop1/sulaco)
"if" = (
-/turf/closed/shuttle/dropship1{
- icon_state = "3"
- },
+/obj/structure/shuttle/part/dropship1/left_outer_wing_connector,
+/turf/open/space/basic,
/area/shuttle/drop1/sulaco)
"ig" = (
/turf/closed/shuttle/dropship1{
@@ -133,9 +122,8 @@
},
/area/shuttle/drop1/sulaco)
"jz" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "70"
- },
+/obj/structure/shuttle/part/dropship1/transparent/middle_right_wing,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"mb" = (
/turf/template_noop,
@@ -180,9 +168,8 @@
},
/area/shuttle/drop1/sulaco)
"oW" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "66"
- },
+/obj/structure/shuttle/part/dropship1/transparent/middle_left_wing,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"po" = (
/turf/closed/shuttle/dropship1{
@@ -196,9 +183,8 @@
/area/shuttle/drop1/sulaco)
"qu" = (
/obj/effect/attach_point/weapon/dropship1/left_wing,
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "61"
- },
+/obj/structure/shuttle/part/dropship1/transparent/lower_left_wing,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"qy" = (
/turf/closed/shuttle/dropship1/transparent{
@@ -222,9 +208,8 @@
},
/area/shuttle/drop1/sulaco)
"rl" = (
-/turf/closed/shuttle/dropship1{
- icon_state = "49"
- },
+/obj/structure/shuttle/part/dropship1/lower_right_wall,
+/turf/open/space/basic,
/area/shuttle/drop1/sulaco)
"rr" = (
/turf/closed/shuttle/dropship1/transparent{
@@ -240,14 +225,12 @@
},
/area/shuttle/drop1/sulaco)
"rV" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "2"
- },
+/obj/structure/shuttle/part/dropship1/transparent/left_outer_bottom_wing,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"sA" = (
-/turf/closed/shuttle/dropship1{
- icon_state = "46"
- },
+/obj/structure/shuttle/part/dropship1/lower_left_wall,
+/turf/open/space/basic,
/area/shuttle/drop1/sulaco)
"tR" = (
/obj/item/device/radio/intercom/alamo{
@@ -259,16 +242,10 @@
icon_state = "rasputin15"
},
/area/shuttle/drop1/sulaco)
-"wh" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "20"
- },
-/area/shuttle/drop1/sulaco)
"wk" = (
/obj/effect/attach_point/weapon/dropship1/right_wing,
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "65"
- },
+/obj/structure/shuttle/part/dropship1/transparent/lower_right_wing,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"wr" = (
/obj/effect/attach_point/crew_weapon/dropship1,
@@ -297,15 +274,9 @@
icon_state = "rasputin15"
},
/area/shuttle/drop1/sulaco)
-"xu" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "44"
- },
-/area/shuttle/drop1/sulaco)
"xM" = (
-/turf/closed/shuttle/dropship1{
- icon_state = "15"
- },
+/obj/structure/shuttle/part/dropship1/bottom_right_wall,
+/turf/open/space/basic,
/area/shuttle/drop1/sulaco)
"yQ" = (
/turf/closed/shuttle/dropship1/transparent{
@@ -313,14 +284,12 @@
},
/area/shuttle/drop1/sulaco)
"yU" = (
-/turf/closed/shuttle/dropship1{
- icon_state = "9"
- },
+/obj/structure/shuttle/part/dropship1/bottom_left_wall,
+/turf/open/space/basic,
/area/shuttle/drop1/sulaco)
"zw" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "71"
- },
+/obj/structure/shuttle/part/dropship1/transparent/upper_left_wing,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"zN" = (
/turf/closed/shuttle/dropship1/transparent{
@@ -378,17 +347,15 @@
/obj/effect/attach_point/electronics/dropship1{
dir = 1
},
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "85"
- },
+/obj/structure/shuttle/part/dropship1/transparent/inner_left_weapons,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"De" = (
/obj/effect/attach_point/electronics/dropship1{
dir = 1
},
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "90"
- },
+/obj/structure/shuttle/part/dropship1/transparent/inner_right_weapons,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"Et" = (
/turf/closed/shuttle/dropship1{
@@ -401,19 +368,12 @@
},
/area/shuttle/drop1/sulaco)
"EN" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "16"
- },
+/obj/structure/shuttle/part/dropship1/transparent/engine_left_exhaust,
+/turf/open/space/basic,
/area/shuttle/drop1/sulaco)
"FA" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "40"
- },
-/area/shuttle/drop1/sulaco)
-"Gl" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "45"
- },
+/obj/structure/shuttle/part/dropship1/transparent/engine_left_cap,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"Gw" = (
/turf/closed/shuttle/dropship1/transparent{
@@ -436,9 +396,8 @@
/area/shuttle/drop1/sulaco)
"HP" = (
/obj/effect/attach_point/weapon/dropship1/right_fore,
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "91"
- },
+/obj/structure/shuttle/part/dropship1/transparent/outer_right_weapons,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"HS" = (
/obj/structure/machinery/door/airlock/multi_tile/almayer/dropshiprear/ds1{
@@ -459,9 +418,8 @@
},
/area/shuttle/drop1/sulaco)
"Jm" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "21"
- },
+/obj/structure/shuttle/part/dropship1/transparent/engine_right_exhaust,
+/turf/open/space/basic,
/area/shuttle/drop1/sulaco)
"JP" = (
/turf/closed/shuttle/dropship1{
@@ -486,9 +444,8 @@
},
/area/shuttle/drop1/sulaco)
"Me" = (
-/turf/closed/shuttle/dropship1{
- icon_state = "7"
- },
+/obj/structure/shuttle/part/dropship1/left_inner_wing_connector,
+/turf/open/space/basic,
/area/shuttle/drop1/sulaco)
"MP" = (
/turf/closed/shuttle/dropship1{
@@ -496,8 +453,8 @@
},
/area/shuttle/drop1/sulaco)
"NQ" = (
-/obj/docking_port/mobile/marine_dropship/alamo,
-/turf/closed/shuttle/dropship1/transparent,
+/obj/structure/shuttle/part/dropship1/transparent/left_inner_bottom_wing,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"Oq" = (
/turf/closed/shuttle/dropship1/transparent{
@@ -505,6 +462,7 @@
},
/area/shuttle/drop1/sulaco)
"OK" = (
+/obj/docking_port/mobile/marine_dropship/alamo,
/turf/closed/shuttle/dropship1{
icon_state = "53"
},
@@ -549,14 +507,12 @@
},
/area/shuttle/drop1/sulaco)
"QT" = (
-/turf/closed/shuttle/dropship1{
- icon_state = "95"
- },
+/obj/structure/shuttle/part/dropship1/nose_front_left,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"QW" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "6"
- },
+/obj/structure/shuttle/part/dropship1/transparent/right_outer_bottom_wing,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"RI" = (
/turf/closed/shuttle/dropship1{
@@ -569,14 +525,12 @@
},
/area/shuttle/drop1/sulaco)
"Ta" = (
-/turf/closed/shuttle/dropship1{
- icon_state = "8"
- },
+/obj/structure/shuttle/part/dropship1/right_inner_wing_connector,
+/turf/open/space/basic,
/area/shuttle/drop1/sulaco)
"Te" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "5"
- },
+/obj/structure/shuttle/part/dropship1/transparent/right_inner_bottom_wing,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"Tt" = (
/turf/open/shuttle/dropship{
@@ -617,9 +571,8 @@
/area/shuttle/drop1/sulaco)
"TM" = (
/obj/effect/attach_point/weapon/dropship1/left_fore,
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "84"
- },
+/obj/structure/shuttle/part/dropship1/transparent/outer_left_weapons,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"Ua" = (
/obj/effect/attach_point/fuel/dropship1,
@@ -644,14 +597,12 @@
},
/area/shuttle/drop1/sulaco)
"VM" = (
-/turf/closed/shuttle/dropship1/transparent{
- icon_state = "100"
- },
+/obj/structure/shuttle/part/dropship1/transparent/nose_top_left,
+/turf/template_noop,
/area/shuttle/drop1/sulaco)
"Wg" = (
-/turf/closed/shuttle/dropship1{
- icon_state = "4"
- },
+/obj/structure/shuttle/part/dropship1/right_outer_wing_connector,
+/turf/open/space/basic,
/area/shuttle/drop1/sulaco)
"WQ" = (
/turf/closed/shuttle/dropship1{
@@ -733,7 +684,7 @@ eD
Il
iC
rr
-cK
+Jm
mb
mb
NQ
@@ -913,11 +864,11 @@ Pf
nC
nE
rl
-xu
+FA
Bn
Qh
TE
-wh
+EN
mb
mb
QW
@@ -936,7 +887,7 @@ mb
mb
mb
mb
-Gl
+eD
Gw
os
qy
diff --git a/maps/shuttles/dropship_normandy.dmm b/maps/shuttles/dropship_normandy.dmm
index e5aaaa568590..f1595cd97db9 100644
--- a/maps/shuttles/dropship_normandy.dmm
+++ b/maps/shuttles/dropship_normandy.dmm
@@ -5,9 +5,8 @@
},
/area/shuttle/drop2/sulaco)
"af" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "74"
- },
+/obj/structure/shuttle/part/dropship2/transparent/upper_right_wing,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"aH" = (
/obj/structure/blocker/invisible_wall,
@@ -17,8 +16,8 @@
},
/area/shuttle/drop2/sulaco)
"bc" = (
-/obj/docking_port/mobile/marine_dropship/normandy,
-/turf/closed/shuttle/dropship2/transparent,
+/obj/structure/shuttle/part/dropship2/transparent/left_outer_bottom_wing,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"bJ" = (
/turf/closed/shuttle/dropship2{
@@ -34,9 +33,8 @@
},
/area/shuttle/drop2/sulaco)
"cj" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "6"
- },
+/obj/structure/shuttle/part/dropship2/transparent/right_outer_bottom_wing,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"do" = (
/obj/effect/attach_point/crew_weapon/dropship2,
@@ -78,9 +76,8 @@
},
/area/shuttle/drop2/sulaco)
"fQ" = (
-/turf/closed/shuttle/dropship2{
- icon_state = "7"
- },
+/obj/structure/shuttle/part/dropship2/left_inner_wing_connector,
+/turf/open/space/basic,
/area/shuttle/drop2/sulaco)
"gD" = (
/turf/closed/shuttle/dropship2/transparent{
@@ -118,9 +115,8 @@
},
/area/shuttle/drop2/sulaco)
"iI" = (
-/turf/closed/shuttle/dropship2{
- icon_state = "8"
- },
+/obj/structure/shuttle/part/dropship2/right_inner_wing_connector,
+/turf/open/space/basic,
/area/shuttle/drop2/sulaco)
"jc" = (
/obj/item/device/radio/intercom/normandy{
@@ -137,19 +133,16 @@
},
/area/shuttle/drop2/sulaco)
"ko" = (
-/turf/closed/shuttle/dropship2{
- icon_state = "15"
- },
+/obj/structure/shuttle/part/dropship2/bottom_right_wall,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"kP" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "70"
- },
+/obj/structure/shuttle/part/dropship2/transparent/middle_right_wing,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"kT" = (
-/turf/closed/shuttle/dropship2{
- icon_state = "9"
- },
+/obj/structure/shuttle/part/dropship2/bottom_left_wall,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"lh" = (
/turf/closed/shuttle/dropship2/transparent{
@@ -158,9 +151,8 @@
/area/shuttle/drop2/sulaco)
"lz" = (
/obj/effect/attach_point/weapon/dropship2/right_fore,
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "91"
- },
+/obj/structure/shuttle/part/dropship2/transparent/outer_right_weapons,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"lH" = (
/obj/structure/machinery/computer/dropship_weapons/dropship2,
@@ -200,24 +192,20 @@
/area/shuttle/drop2/sulaco)
"nq" = (
/obj/effect/attach_point/weapon/dropship2/left_fore,
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "84"
- },
+/obj/structure/shuttle/part/dropship2/transparent/outer_left_weapons,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"nS" = (
-/turf/closed/shuttle/dropship2{
- icon_state = "46"
- },
+/obj/structure/shuttle/part/dropship2/lower_left_wall,
+/turf/open/space/basic,
/area/shuttle/drop2/sulaco)
"oc" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "102"
- },
+/obj/structure/shuttle/part/dropship2/transparent/nose_top_right,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"os" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "66"
- },
+/obj/structure/shuttle/part/dropship2/transparent/middle_left_wing,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"oS" = (
/turf/closed/shuttle/dropship2/transparent{
@@ -248,9 +236,8 @@
},
/area/shuttle/drop2/sulaco)
"rw" = (
-/turf/closed/shuttle/dropship2{
- icon_state = "99"
- },
+/obj/structure/shuttle/part/dropship2/nose_front_right,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"sk" = (
/turf/closed/shuttle/dropship2/transparent{
@@ -258,9 +245,8 @@
},
/area/shuttle/drop2/sulaco)
"uk" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "71"
- },
+/obj/structure/shuttle/part/dropship2/transparent/upper_left_wing,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"vd" = (
/turf/open/shuttle/dropship{
@@ -282,9 +268,8 @@
/obj/effect/attach_point/electronics/dropship2{
dir = 1
},
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "90"
- },
+/obj/structure/shuttle/part/dropship2/transparent/inner_right_weapons,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"xe" = (
/turf/closed/shuttle/dropship2{
@@ -302,9 +287,8 @@
},
/area/shuttle/drop2/sulaco)
"yh" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "41"
- },
+/obj/structure/shuttle/part/dropship2/transparent/engine_right_cap,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"yl" = (
/turf/closed/shuttle/dropship2{
@@ -316,11 +300,6 @@
icon_state = "27"
},
/area/shuttle/drop2/sulaco)
-"Ac" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "40"
- },
-/area/shuttle/drop2/sulaco)
"AN" = (
/turf/closed/shuttle/dropship2{
icon_state = "48"
@@ -347,14 +326,8 @@
},
/area/shuttle/drop2/sulaco)
"BG" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "20"
- },
-/area/shuttle/drop2/sulaco)
-"BM" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "44"
- },
+/obj/structure/shuttle/part/dropship2/transparent/engine_left_cap,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"Cl" = (
/turf/closed/shuttle/dropship2{
@@ -373,9 +346,8 @@
/area/shuttle/drop2/sulaco)
"DW" = (
/obj/effect/attach_point/weapon/dropship2/right_wing,
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "65"
- },
+/obj/structure/shuttle/part/dropship2/transparent/lower_right_wing,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"En" = (
/obj/structure/machinery/door/airlock/dropship_hatch/two{
@@ -431,6 +403,7 @@
},
/area/shuttle/drop2/sulaco)
"Iv" = (
+/obj/docking_port/mobile/marine_dropship/normandy,
/turf/closed/shuttle/dropship2{
icon_state = "53"
},
@@ -444,9 +417,8 @@
/obj/effect/attach_point/electronics/dropship2{
dir = 1
},
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "85"
- },
+/obj/structure/shuttle/part/dropship2/transparent/inner_left_weapons,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"Le" = (
/turf/closed/shuttle/dropship2/transparent{
@@ -484,14 +456,12 @@
},
/area/shuttle/drop2/sulaco)
"LY" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "101"
- },
+/obj/structure/shuttle/part/dropship2/transparent/nose_center,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"Mx" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "100"
- },
+/obj/structure/shuttle/part/dropship2/transparent/nose_top_left,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"ME" = (
/turf/closed/shuttle/dropship2/transparent{
@@ -512,9 +482,8 @@
/area/shuttle/drop2/sulaco)
"Nt" = (
/obj/effect/attach_point/weapon/dropship2/left_wing,
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "61"
- },
+/obj/structure/shuttle/part/dropship2/transparent/lower_left_wing,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"Nw" = (
/turf/closed/shuttle/dropship2{
@@ -522,14 +491,12 @@
},
/area/shuttle/drop2/sulaco)
"NM" = (
-/turf/closed/shuttle/dropship2{
- icon_state = "3"
- },
+/obj/structure/shuttle/part/dropship2/left_outer_wing_connector,
+/turf/open/space/basic,
/area/shuttle/drop2/sulaco)
"Ov" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "5"
- },
+/obj/structure/shuttle/part/dropship2/transparent/right_inner_bottom_wing,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"OI" = (
/turf/closed/shuttle/dropship2{
@@ -588,9 +555,8 @@
},
/area/shuttle/drop2/sulaco)
"QK" = (
-/turf/closed/shuttle/dropship2{
- icon_state = "49"
- },
+/obj/structure/shuttle/part/dropship2/lower_right_wall,
+/turf/open/space/basic,
/area/shuttle/drop2/sulaco)
"Rr" = (
/turf/template_noop,
@@ -609,14 +575,12 @@
},
/area/shuttle/drop2/sulaco)
"RJ" = (
-/turf/closed/shuttle/dropship2{
- icon_state = "4"
- },
+/obj/structure/shuttle/part/dropship2/right_outer_wing_connector,
+/turf/open/space/basic,
/area/shuttle/drop2/sulaco)
"SB" = (
-/turf/closed/shuttle/dropship2{
- icon_state = "95"
- },
+/obj/structure/shuttle/part/dropship2/nose_front_left,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"SC" = (
/obj/structure/machinery/door/airlock/dropship_hatch/two{
@@ -658,9 +622,8 @@
},
/area/shuttle/drop2/sulaco)
"Uu" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "17"
- },
+/obj/structure/shuttle/part/dropship2/transparent/engine_right_exhaust,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"UP" = (
/turf/closed/shuttle/dropship2/transparent{
@@ -673,9 +636,8 @@
},
/area/shuttle/drop2/sulaco)
"Vh" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "2"
- },
+/obj/structure/shuttle/part/dropship2/transparent/left_outer_inner_wing,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"Vs" = (
/turf/closed/shuttle/dropship2/transparent{
@@ -687,11 +649,6 @@
icon_state = "25"
},
/area/shuttle/drop2/sulaco)
-"VC" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "45"
- },
-/area/shuttle/drop2/sulaco)
"VW" = (
/obj/structure/machinery/door/airlock/hatch/cockpit/two,
/obj/structure/blocker/forcefield/multitile_vehicles,
@@ -710,14 +667,8 @@
},
/area/shuttle/drop2/sulaco)
"Xr" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "16"
- },
-/area/shuttle/drop2/sulaco)
-"XX" = (
-/turf/closed/shuttle/dropship2/transparent{
- icon_state = "21"
- },
+/obj/structure/shuttle/part/dropship2/transparent/engine_left_exhaust,
+/turf/template_noop,
/area/shuttle/drop2/sulaco)
"ZK" = (
/turf/closed/shuttle/dropship2{
@@ -739,7 +690,7 @@ Rr
Rr
Rr
Rr
-Ac
+BG
SQ
vw
sk
@@ -946,11 +897,11 @@ En
gG
RG
QK
-BM
+BG
gD
oW
lh
-BG
+Xr
Rr
Rr
cj
@@ -969,11 +920,11 @@ Rr
Rr
Rr
Rr
-VC
+yh
UP
es
zt
-XX
+Uu
Rr
Rr
Rr
diff --git a/maps/templates/clf_ert_station.dmm b/maps/templates/clf_ert_station.dmm
index 330f7b2a1819..9d6ccd92aaa0 100644
--- a/maps/templates/clf_ert_station.dmm
+++ b/maps/templates/clf_ert_station.dmm
@@ -1823,7 +1823,7 @@
"RB" = (
/obj/structure/flora/jungle/plantbot1{
icon_state = "alienplant1";
- luminosity = 2
+ light_range = 2
},
/turf/open/gm/river,
/area/adminlevel/ert_station/clf_station)
diff --git a/sound/effects/biohazard.ogg b/sound/effects/biohazard.ogg
new file mode 100644
index 000000000000..b6528f9311ca
Binary files /dev/null and b/sound/effects/biohazard.ogg differ
diff --git a/sound/weapons/gun_mg.ogg b/sound/weapons/gun_mg.ogg
new file mode 100644
index 000000000000..9741526d31b0
Binary files /dev/null and b/sound/weapons/gun_mg.ogg differ
diff --git a/sound/weapons/gun_tt.ogg b/sound/weapons/gun_tt.ogg
new file mode 100644
index 000000000000..e55663329860
Binary files /dev/null and b/sound/weapons/gun_tt.ogg differ