diff --git a/code/__DEFINES/autowiki.dm b/code/__DEFINES/autowiki.dm
new file mode 100644
index 000000000000..4edf385bcc82
--- /dev/null
+++ b/code/__DEFINES/autowiki.dm
@@ -0,0 +1,7 @@
+#ifdef AUTOWIKI
+ #define AUTOWIKI_SKIP(skip) autowiki_skip = skip
+ #define IS_AUTOWIKI_SKIP(datum) datum.autowiki_skip
+#else
+ #define AUTOWIKI_SKIP(skip)
+ #define IS_AUTOWIKI_SKIP(datum) UNLINT(FALSE)
+#endif
diff --git a/code/__DEFINES/camera.dm b/code/__DEFINES/camera.dm
index f50d7d8e2c72..b13adf43e8cd 100644
--- a/code/__DEFINES/camera.dm
+++ b/code/__DEFINES/camera.dm
@@ -3,6 +3,7 @@
#define CAMERA_NET_CONTAINMENT "Containment"
#define CAMERA_NET_CONTAINMENT_HIDDEN "Containment Hidden"
#define CAMERA_NET_RESEARCH "Research"
+#define CAMERA_NET_BRIG "Brig"
#define CAMERA_NET_ALAMO "Alamo"
#define CAMERA_NET_NORMANDY "Normandy"
#define CAMERA_NET_COLONY "Colony"
diff --git a/code/__DEFINES/chemistry.dm b/code/__DEFINES/chemistry.dm
index 35e040654881..a3b3b1a4768f 100644
--- a/code/__DEFINES/chemistry.dm
+++ b/code/__DEFINES/chemistry.dm
@@ -2,8 +2,10 @@
* Chemistry defines
*/
+/// Amount of bottle icon variations in total
+#define BOTTLE_ICON_CHOICES 4
/// Amount of random icon variations for pills in total
-#define PILL_ICON_CHOICES 21
+#define PILL_ICON_CHOICES 22
/* Pill icon classes to generate mappings for */
#define PILL_ICON_CLASSES list("bica", "kelo", "dex", "para", "tram", "atox", "tox", "inap", "peri", "spac", "drug", "stim", "alky", "imi", "qc", "tric", "psych", "oxy")
diff --git a/code/__DEFINES/conflict.dm b/code/__DEFINES/conflict.dm
index a6a7aa53f182..17fd8b32c280 100644
--- a/code/__DEFINES/conflict.dm
+++ b/code/__DEFINES/conflict.dm
@@ -54,24 +54,25 @@
#define GUN_TRIGGER_SAFETY (1<<1)
#define GUN_UNUSUAL_DESIGN (1<<2)
#define GUN_SILENCED (1<<3)
+#define GUN_CANT_EXECUTE (1<<4)
///If checking for ammo with current.mag you have to check it against numerical values, as booleans will not trigger.
-#define GUN_INTERNAL_MAG (1<<4)
-#define GUN_AUTO_EJECTOR (1<<5)
-#define GUN_AMMO_COUNTER (1<<6)
-#define GUN_BURST_FIRING (1<<7)
-#define GUN_FLASHLIGHT_ON (1<<8)
-#define GUN_WY_RESTRICTED (1<<9)
-#define GUN_SPECIALIST (1<<10)
-#define GUN_WIELDED_FIRING_ONLY (1<<11)
+#define GUN_INTERNAL_MAG (1<<5)
+#define GUN_AUTO_EJECTOR (1<<6)
+#define GUN_AMMO_COUNTER (1<<7)
+#define GUN_BURST_FIRING (1<<8)
+#define GUN_FLASHLIGHT_ON (1<<9)
+#define GUN_WY_RESTRICTED (1<<10)
+#define GUN_SPECIALIST (1<<11)
+#define GUN_WIELDED_FIRING_ONLY (1<<12)
/// removes unwielded accuracy and scatter penalties (not recoil)
-#define GUN_ONE_HAND_WIELDED (1<<12)
-#define GUN_ANTIQUE (1<<13)
+#define GUN_ONE_HAND_WIELDED (1<<13)
+#define GUN_ANTIQUE (1<<14)
/// Whether the gun has been fired by its current user (reset upon `dropped()`)
-#define GUN_RECOIL_BUILDUP (1<<14)
+#define GUN_RECOIL_BUILDUP (1<<15)
/// support weapon, bipod will grant autofire
-#define GUN_SUPPORT_PLATFORM (1<<15)
+#define GUN_SUPPORT_PLATFORM (1<<16)
/// No gun description, only base desc
-#define GUN_NO_DESCRIPTION (1<<16)
+#define GUN_NO_DESCRIPTION (1<<17)
// NOTE: Don't add flags past 1<<23, it'll break things due to BYOND limitations. You can usually use a Component instead.
#define USES_STREAKS (1<<0)
diff --git a/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm b/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm
index ab233e9cf82c..e76768a82b46 100644
--- a/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm
+++ b/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm
@@ -50,6 +50,10 @@
/// From /datum/action/xeno_action/proc/use_ability_wrapper(): (mob/owner)
#define COMSIG_XENO_ACTION_USED "xeno_action_used"
+/// From /datum/action/xeno_action/proc/use_ability_wrapper(): (mob/owner)
+#define COMSIG_XENO_PRE_ACTION_USED "xeno_pre_action_used"
+/// From /datum/action/xeno_action/proc/use_ability_wrapper(): (mob/owner)
+#define COMSIG_XENO_FAILED_ACTION_USED "xeno_failed_action_used"
/// From /mob/living/carbon/xenomorph/proc/check_blood_splash()
#define COMSIG_XENO_DEAL_ACID_DAMAGE "xeno_deal_acid_damage"
/// From /mob/living/carbon/xenomorph/proc/recalculate_speed()
diff --git a/code/__DEFINES/dcs/signals/atom/signals_item.dm b/code/__DEFINES/dcs/signals/atom/signals_item.dm
index 5ba79960657b..88f99bbff578 100644
--- a/code/__DEFINES/dcs/signals/atom/signals_item.dm
+++ b/code/__DEFINES/dcs/signals/atom/signals_item.dm
@@ -83,3 +83,5 @@
#define COMSIG_CAMERA_SET_AREA "camera_manager_set_area"
#define COMSIG_CAMERA_CLEAR "camera_manager_clear_target"
#define COMSIG_CAMERA_REFRESH "camera_manager_refresh"
+
+#define COMSIG_PRED_BRACER_DECLOAKED "pred_bracer_decloaked"
diff --git a/code/__DEFINES/dcs/signals/atom/signals_movable.dm b/code/__DEFINES/dcs/signals/atom/signals_movable.dm
index ba889d0b5212..ad4be2b1dc9f 100644
--- a/code/__DEFINES/dcs/signals/atom/signals_movable.dm
+++ b/code/__DEFINES/dcs/signals/atom/signals_movable.dm
@@ -11,6 +11,9 @@
#define COMPONENT_CANCEL_MOVE (1<<0)
/// From /turf/open/gm/river/Entered(): (turf/open/gm/river/river, covered)
#define COMSIG_MOVABLE_ENTERED_RIVER "movable_entered_river"
+/// From /atom/movable/proc/doMove: I think it only works with forceMove so watch out
+#define COMSIG_MOVABLE_FORCEMOVE_PRE_CROSSED "movable_forcemove_pre_crossed"
+ #define COMPONENT_IGNORE_CROSS (1<<0)
///from /mob/living/carbon/xenomorph/start_pulling(): (mob/living/carbon/xenomorph/X)
#define COMSIG_MOVABLE_XENO_START_PULLING "movable_xeno_start_pulling"
diff --git a/code/__DEFINES/dcs/signals/signals_datum.dm b/code/__DEFINES/dcs/signals/signals_datum.dm
index b798d510763e..c35038fcf3e9 100644
--- a/code/__DEFINES/dcs/signals/signals_datum.dm
+++ b/code/__DEFINES/dcs/signals/signals_datum.dm
@@ -34,6 +34,8 @@
#define COMSIG_ACTION_HIDDEN "action_hidden"
/// From base of /datum/action/proc/unhide_from(): (mob/owner)
#define COMSIG_ACTION_UNHIDDEN "action_unhidden"
+/// From base of /datum/action/proc/action_activate() : ()
+#define COMSIG_ACTION_ACTIVATED "action_activated"
///from /datum/component/bonus_damage_stack
#define COMSIG_BONUS_DAMAGE "bonus_damage"
diff --git a/code/__DEFINES/job.dm b/code/__DEFINES/job.dm
index 79f40c89bb53..3fd552f5369f 100644
--- a/code/__DEFINES/job.dm
+++ b/code/__DEFINES/job.dm
@@ -360,6 +360,7 @@ GLOBAL_LIST_INIT(job_command_roles, JOB_COMMAND_ROLES_LIST)
#define JOB_XENOMORPH_QUEEN "Queen"
// For coloring the ranks in the statistics menu
+#define JOB_PLAYTIME_TIER_0 (0 HOURS)
#define JOB_PLAYTIME_TIER_1 (10 HOURS)
#define JOB_PLAYTIME_TIER_2 (25 HOURS)
#define JOB_PLAYTIME_TIER_3 (70 HOURS)
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 77f2393e6542..53ad9904abd0 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -113,7 +113,7 @@
#define CANROOT (1<<6)
#define GODMODE (1<<12)
#define FAKEDEATH (1<<13) //Replaces stuff like changeling.changeling_fakedeath
-#define DISFIGURED (1<<14) //I'll probably move this elsewhere if I ever get wround to writing a bitflag mob-damage system
+//#define DISFIGURED (1<<14) //unused
#define XENO_HOST (1<<15) //Tracks whether we're gonna be a baby alien's mummy.
#define IMMOBILE_ACTION (1<<16) // If you are performing an action that prevents you from being pushed by your own people.
#define PERMANENTLY_DEAD (1<<17)
@@ -166,8 +166,9 @@
#define ORGAN_ROBOT 2
#define ORGAN_HEALTHY 0
-#define ORGAN_BRUISED 1
-#define ORGAN_BROKEN 2
+#define ORGAN_LITTLE_BRUISED 1 //used by stethoscopes and penlights
+#define ORGAN_BRUISED 2
+#define ORGAN_BROKEN 3
//=================================================
diff --git a/code/__DEFINES/skills.dm b/code/__DEFINES/skills.dm
index d33e26c1c3f6..e4965907f707 100644
--- a/code/__DEFINES/skills.dm
+++ b/code/__DEFINES/skills.dm
@@ -70,10 +70,11 @@
// engineer skill
#define SKILL_ENGINEER_DEFAULT 0
-#define SKILL_ENGINEER_TRAINED 1 //barricade repair && c4 use (mini-engis, specs)
-#define SKILL_ENGINEER_ENGI 2 //plasteel barricade deconstruction, hacking&&planet engine fixing&&apc building, Telecomms fixing (Combat Engi, OT, etc.)
-#define SKILL_ENGINEER_MASTER 3 //Synths
-#define SKILL_ENGINEER_MAX 3
+#define SKILL_ENGINEER_NOVICE 1 //barricade repair && c4 use (mini-engis, specs)
+#define SKILL_ENGINEER_TRAINED 2 //plasteel barricade deconstruction, hacking&&planet engine fixing&&apc building, Telecomms fixing (OT, etc.)
+#define SKILL_ENGINEER_ENGI 3 // Slightly faster at everything (Combat Technicians)
+#define SKILL_ENGINEER_MASTER 4 //Synths
+#define SKILL_ENGINEER_MAX 4
//medical skill
#define SKILL_MEDICAL_DEFAULT 0
diff --git a/code/__DEFINES/sounds.dm b/code/__DEFINES/sounds.dm
index 807305174b34..35f388f351ea 100644
--- a/code/__DEFINES/sounds.dm
+++ b/code/__DEFINES/sounds.dm
@@ -31,6 +31,28 @@
#define SOUND_CHANNEL_LOBBY 1023
#define SOUND_CHANNEL_Z 1024
+
+//default byond sound echo list index positions.
+//ECHO_DIRECT and ECHO_ROOM are the only two that actually appear to do anything, and represent the dry and wet channels of the environment effects, respectively.
+#define ECHO_DIRECT 1
+#define ECHO_DIRECTHF 2
+#define ECHO_ROOM 3
+#define ECHO_ROOMHF 4
+#define ECHO_OBSTRUCTION 5
+#define ECHO_OBSTRUCTIONLFRATIO 6
+#define ECHO_OCCLUSION 7
+#define ECHO_OCCLUSIONLFRATIO 8
+#define ECHO_OCCLUSIONROOMRATIO 9
+#define ECHO_OCCLUSIONDIRECTRATIO 10
+#define ECHO_EXCLUSION 11
+#define ECHO_EXCLUSIONLFRATIO 12
+#define ECHO_OUTSIDEVOLUMEHF 13
+#define ECHO_DOPPLERFACTOR 14
+#define ECHO_ROLLOFFFACTOR 15
+#define ECHO_ROOMROLLOFFFACTOR 16
+#define ECHO_AIRABSORPTIONFACTOR 17
+#define ECHO_FLAGS 18
+
//default byond sound environments
#define SOUND_ENVIRONMENT_NONE -1
#define SOUND_ENVIRONMENT_GENERIC 0
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 47aa0e732c76..88496c79d630 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -123,6 +123,7 @@
#define SS_INIT_NIGHTMARE 21.5
#define SS_INIT_TIMETRACK 21.1
#define SS_INIT_HUMANS 21
+#define SS_INIT_WHO 20
#define SS_INIT_POWER 19
#define SS_INIT_INFLUXMCSTATS 12
#define SS_INIT_INFLUXSTATS 11
diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm
index e2c89df90e9b..17464b44dae8 100644
--- a/code/__DEFINES/tgs.dm
+++ b/code/__DEFINES/tgs.dm
@@ -1,6 +1,6 @@
// tgstation-server DMAPI
-#define TGS_DMAPI_VERSION "7.1.2"
+#define TGS_DMAPI_VERSION "7.1.3"
// All functions and datums outside this document are subject to change with any version and should not be relied on.
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 964e77402655..e6b9c4c4b9ee 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -161,6 +161,8 @@
#define TRAIT_MERGED_WITH_WEEDS "merged_with_weeds"
/// Apply this to identify a mob as temporarily muted
#define TRAIT_TEMPORARILY_MUTED "temporarily_muted"
+/// Mob wont get hit by stray projectiles
+#define TRAIT_NO_STRAY "trait_no_stray"
// SPECIES TRAITS
/// Knowledge of Yautja technology
diff --git a/code/__DEFINES/turfs.dm b/code/__DEFINES/turfs.dm
index 158c66754e18..1b549440deee 100644
--- a/code/__DEFINES/turfs.dm
+++ b/code/__DEFINES/turfs.dm
@@ -1,15 +1,16 @@
-#define RANGE_TURFS(RADIUS, CENTER) \
- block( \
- (CENTER).x-(RADIUS), (CENTER).y-(RADIUS), (CENTER).z, \
- (CENTER).x+(RADIUS), (CENTER).y+(RADIUS), (CENTER).z \
- )
-
+/// Returns a list of turfs within H_RADIUS tiles horizontally and V_RADIUS tiles vertically of CENTER.
#define RECT_TURFS(H_RADIUS, V_RADIUS, CENTER) \
block( \
(CENTER).x-(H_RADIUS), (CENTER).y-(V_RADIUS), (CENTER).z, \
(CENTER).x+(H_RADIUS), (CENTER).y+(V_RADIUS), (CENTER).z \
)
+/// Returns a list of turfs within Dist tiles of Center. When Dist >= 5 faster than a `range()` filtered to `/turf`s.
+#define RANGE_TURFS(Dist, Center) RECT_TURFS(Dist, Dist, Center)
+
+/// Returns a list of turfs within Dist tiles of Center, excluding Center. When Dist >= 5 faster than an `orange()` filtered to `/turf`s.
+#define ORANGE_TURFS(Dist, Center) (RANGE_TURFS(Dist, Center) - Center)
+
///Returns all turfs in a zlevel
#define Z_TURFS(ZLEVEL) block(1, 1, (ZLEVEL), world.maxx, world.maxy, (ZLEVEL))
diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm
index e46c92df543a..aa73d6008e02 100644
--- a/code/__HELPERS/_lists.dm
+++ b/code/__HELPERS/_lists.dm
@@ -128,17 +128,23 @@
* You should only pass integers in.
*/
/proc/pick_weight(list/list_to_pick)
+ if(length(list_to_pick) == 0)
+ return null
+
var/total = 0
- var/item
- for(item in list_to_pick)
+ for(var/item in list_to_pick)
if(!list_to_pick[item])
list_to_pick[item] = 0
total += list_to_pick[item]
- total = rand(0, total)
- for(item in list_to_pick)
- total -= list_to_pick[item]
- if(total <= 0 && list_to_pick[item])
+ total = rand(1, total)
+ for(var/item in list_to_pick)
+ var/item_weight = list_to_pick[item]
+ if(item_weight == 0)
+ continue
+
+ total -= item_weight
+ if(total <= 0)
return item
return null
diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm
index 31308ac5812f..e27add2c9601 100644
--- a/code/__HELPERS/cmp.dm
+++ b/code/__HELPERS/cmp.dm
@@ -57,6 +57,9 @@ GLOBAL_LIST_INIT(cmp_field, "name")
/proc/cmp_typepaths_asc(A, B)
return sorttext("[B]","[A]")
+/proc/cmp_typepaths_name_asc(atom/A, atom/B)
+ return sorttext(initial(A.name), initial(B.name))
+
/// Compares mobs based on their timeofdeath value in ascending order
/proc/cmp_mob_deathtime_asc(mob/A, mob/B)
return A.timeofdeath - B.timeofdeath
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 5bf36f785746..ba27d4192ded 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -45,7 +45,7 @@
var/list/turfs = new/list()
var/rsq = radius * (radius+0.5)
- for(var/turf/T in range(radius, centerturf))
+ for(var/turf/T as anything in RANGE_TURFS(radius, centerturf))
var/dx = T.x - centerturf.x
var/dy = T.y - centerturf.y
if(dx*dx + dy*dy <= rsq)
@@ -235,7 +235,7 @@
* * hive - The hive we're filling a slot for to check if the player is banished
* * sorted - Whether to sort by larva_queue_time (default TRUE) or leave unsorted
*/
-/proc/get_alien_candidates(datum/hive_status/hive = null, sorted = TRUE)
+/proc/get_alien_candidates(datum/hive_status/hive = null, sorted = TRUE, abomination = FALSE)
var/list/candidates = list()
for(var/mob/dead/observer/cur_obs as anything in GLOB.observer_list)
@@ -275,6 +275,11 @@
if(banished)
continue
+ if(abomination)
+ if(!(/datum/tutorial/xenomorph/abomination::tutorial_id in cur_obs.client.prefs.completed_tutorials))
+ to_chat(cur_obs, SPAN_BOLDNOTICE("You were passed over for playing as an Abomination because you have not completed its tutorial."))
+ continue
+
candidates += cur_obs
// Optionally sort by larva_queue_time
diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm
index d5212611a04b..32ea0f5ec32e 100644
--- a/code/__HELPERS/lists.dm
+++ b/code/__HELPERS/lists.dm
@@ -87,22 +87,6 @@
result = first ^ second
return result
-//Pretends to pick an element based on its weight but really just seems to pick a random element.
-/proc/pickweight(list/L)
- var/total = 0
- var/item
- for (item in L)
- if (!L[item])
- L[item] = 1
- total += L[item]
-
- total = rand(1, total)
- for (item in L)
- total -=L [item]
- if (total <= 0)
- return item
- return null
-
/// Pick a random element from the list and remove it from the list.
/proc/pick_n_take(list/L)
RETURN_TYPE(L[_].type)
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index d8eebf79bca6..5a307ac02ed5 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1100,11 +1100,17 @@ GLOBAL_DATUM(action_purple_power_up, /image)
else
air_master.tiles_to_update += T2*/
-/proc/get_cardinal_dir(atom/A, atom/B)
- var/dx = abs(B.x - A.x)
- var/dy = abs(B.y - A.y)
- return get_dir(A, B) & (rand() * (dx+dy) < dy ? 3 : 12)
-
+/// Returns the nearest cardinal dir between two atoms. Favors NORTH/SOUTH on perfect diagonals. Consistent and reversible.
+/proc/get_cardinal_dir(atom/start, atom/end) as num
+ var/dx = end.x - start.x
+ var/dy = end.y - start.y
+ if(!(dx || dy))
+ return 0 //returns 0 when on same x/y, consistent with get_dir()
+
+ if(abs(dx) > abs(dy))
+ return dx < 0 ? WEST : EAST
+ else
+ return dy < 0 ? SOUTH : NORTH
//Returns the 2 dirs perpendicular to the arg
/proc/get_perpen_dir(dir)
@@ -1283,10 +1289,7 @@ GLOBAL_LIST_INIT(WALLITEMS, list(
origin = get_turf(origin)
if(!origin)
return
- var/list/turfs = list()
- for(var/turf/T in orange(origin, outer_range))
- if(!inner_range || get_dist(origin, T) >= inner_range)
- turfs += T
+ var/list/turfs = (RANGE_TURFS(outer_range, origin) - RANGE_TURFS(inner_range - 1, origin))
if(length(turfs))
return pick(turfs)
@@ -1337,29 +1340,35 @@ GLOBAL_LIST_INIT(WALLITEMS, list(
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)
+/proc/dview(range = world.view, atom/center, invis_flags = 0)
if(!center)
return
- GLOB.dview_mob.loc = center
-
+ GLOB.dview_mob.loc = isturf(center) ? center : center.loc
GLOB.dview_mob.see_invisible = invis_flags
- . = view(range, GLOB.dview_mob)
+ . = oview(range, GLOB.dview_mob)
GLOB.dview_mob.loc = null
+/// Version of oview() which ignores darkness
+/proc/doview(range, atom/center, invis_flags)
+ if(!center)
+ return
+
+ return dview(range, center, invis_flags) - center
+
/mob/dview
name = "INTERNAL DVIEW MOB"
- invisibility = 101
+ invisibility = INVISIBILITY_ABSTRACT
density = FALSE
- see_in_dark = 1e6
+ see_in_dark = INFINITY
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)
+ if(CHECK_BITFIELD(flags_atom, INITIALIZED))
stack_trace("Warning: [src]([type]) initialized multiple times!")
- flags_atom |= INITIALIZED
+ ENABLE_BITFIELD(flags_atom, INITIALIZED)
return INITIALIZE_HINT_NORMAL
/mob/dview/Destroy(force = FALSE)
@@ -1375,12 +1384,19 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
#define FOR_DVIEW(type, range, center, invis_flags) \
- GLOB.dview_mob.loc = center; \
+ GLOB.dview_mob.loc = isturf(center) ? (center) : (center).loc; \
GLOB.dview_mob.see_invisible = invis_flags; \
- for(type in view(range, GLOB.dview_mob))
+ for(type in oview(range, GLOB.dview_mob))
#define FOR_DVIEW_END GLOB.dview_mob.loc = null
+#define FOR_DOVIEW(type, range, center, invis_flags) \
+ GLOB.dview_mob.loc = isturf(center) ? (center) : (center).loc; \
+ GLOB.dview_mob.see_invisible = invis_flags; \
+ for(type in oview(range, GLOB.dview_mob) - (center))
+
+#define FOR_DOVIEW_END FOR_DVIEW_END
+
/proc/get_turf_pixel(atom/AM)
if(!istype(AM))
return
diff --git a/code/__pragmas.dm b/code/__pragmas.dm
index 84fcc0dfc307..309883fbda20 100644
--- a/code/__pragmas.dm
+++ b/code/__pragmas.dm
@@ -21,6 +21,7 @@
#pragma InvalidOverride error
#pragma DanglingVarType error
#pragma MissingInterpolatedExpression error
+#pragma InvalidIndexOperation error
//3000-3999
#pragma EmptyBlock error
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index facc2b951ad3..72e02deb8c1a 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -108,6 +108,7 @@ DEFINE_BITFIELD(flags_gun_features, list(
"GUN_TRIGGER_SAFETY" = GUN_TRIGGER_SAFETY,
"GUN_UNUSUAL_DESIGN" = GUN_UNUSUAL_DESIGN,
"GUN_SILENCED" = GUN_SILENCED,
+ "GUN_CANT_EXECUTE" = GUN_CANT_EXECUTE,
"GUN_INTERNAL_MAG" = GUN_INTERNAL_MAG,
"GUN_AUTO_EJECTOR" = GUN_AUTO_EJECTOR,
"GUN_AMMO_COUNTER" = GUN_AMMO_COUNTER,
@@ -356,7 +357,6 @@ DEFINE_BITFIELD(status_flags, list(
"PASSEMOTES" = PASSEMOTES,
"GODMODE" = GODMODE,
"FAKEDEATH" = FAKEDEATH,
- "DISFIGURED" = DISFIGURED,
"XENO_HOST" = XENO_HOST,
"IMMOBILE_ACTION" = IMMOBILE_ACTION,
"PERMANENTLY_DEAD" = PERMANENTLY_DEAD,
diff --git a/code/_globalvars/global_lists.dm b/code/_globalvars/global_lists.dm
index c054b9a4bf1f..d2165fecc9b1 100644
--- a/code/_globalvars/global_lists.dm
+++ b/code/_globalvars/global_lists.dm
@@ -119,11 +119,42 @@ GLOBAL_LIST(chemical_reactions_filtered_list) //List of all /datum/chemical_reac
GLOBAL_LIST(chemical_reactions_list) //List of all /datum/chemical_reaction datums indexed by reaction id. Used to search for the result instead of the components.
GLOBAL_LIST(chemical_reagents_list) //List of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff
GLOBAL_LIST(chemical_properties_list) //List of all /datum/chem_property datums indexed by property name
+//list of all properties that conflict with each other.
+GLOBAL_LIST_INIT_TYPED(conflicting_properties, /list, list( PROPERTY_NUTRITIOUS = PROPERTY_HEMORRAGING, PROPERTY_NUTRITIOUS = PROPERTY_HEMOLYTIC, PROPERTY_TOXIC = PROPERTY_ANTITOXIC,\
+ PROPERTY_CORROSIVE = PROPERTY_ANTICORROSIVE, PROPERTY_BIOCIDIC = PROPERTY_NEOGENETIC, PROPERTY_HYPERTHERMIC = PROPERTY_HYPOTHERMIC,\
+ PROPERTY_NUTRITIOUS = PROPERTY_KETOGENIC, PROPERTY_PAINING = PROPERTY_PAINKILLING, PROPERTY_HALLUCINOGENIC = PROPERTY_ANTIHALLUCINOGENIC,\
+ PROPERTY_HEPATOTOXIC = PROPERTY_HEPATOPEUTIC, PROPERTY_NEPHROTOXIC = PROPERTY_NEPHROPEUTIC, PROPERTY_PNEUMOTOXIC = PROPERTY_PNEUMOPEUTIC,\
+ PROPERTY_OCULOTOXIC = PROPERTY_OCULOPEUTIC, PROPERTY_CARDIOTOXIC = PROPERTY_CARDIOPEUTIC, PROPERTY_NEUROTOXIC = PROPERTY_NEUROPEUTIC,\
+ PROPERTY_FLUXING = PROPERTY_REPAIRING, PROPERTY_RELAXING = PROPERTY_MUSCLESTIMULATING, PROPERTY_HEMOGENIC = PROPERTY_HEMOLYTIC,\
+ PROPERTY_HEMOGENIC = PROPERTY_HEMORRAGING, PROPERTY_NUTRITIOUS = PROPERTY_EMETIC,\
+ PROPERTY_HYPERGENETIC = PROPERTY_NEOGENETIC, PROPERTY_HYPERGENETIC = PROPERTY_HEPATOPEUTIC, PROPERTY_HYPERGENETIC = PROPERTY_NEPHROPEUTIC,\
+ PROPERTY_HYPERGENETIC = PROPERTY_PNEUMOPEUTIC, PROPERTY_HYPERGENETIC = PROPERTY_OCULOPEUTIC, PROPERTY_HYPERGENETIC = PROPERTY_CARDIOPEUTIC,\
+ PROPERTY_HYPERGENETIC = PROPERTY_NEUROPEUTIC, PROPERTY_ADDICTIVE = PROPERTY_ANTIADDICTIVE, PROPERTY_NEUROSHIELDING = PROPERTY_NEUROTOXIC,\
+ PROPERTY_HYPOMETABOLIC = PROPERTY_HYPERMETABOLIC, PROPERTY_HYPERTHROTTLING = PROPERTY_NEUROINHIBITING,
+ PROPERTY_FOCUSING = PROPERTY_NERVESTIMULATING, PROPERTY_THERMOSTABILIZING = PROPERTY_HYPERTHERMIC, PROPERTY_THERMOSTABILIZING = PROPERTY_HYPOTHERMIC,
+ PROPERTY_AIDING = PROPERTY_NEUROINHIBITING, PROPERTY_OXYGENATING = PROPERTY_HYPOXEMIC, PROPERTY_ANTICARCINOGENIC = PROPERTY_CARCINOGENIC, \
+ PROPERTY_CIPHERING = PROPERTY_CIPHERING_PREDATOR, PROPERTY_TRANSFORMATIVE = PROPERTY_ANTITOXIC, PROPERTY_MUSCLESTIMULATING = PROPERTY_NERVESTIMULATING))
+//list of all properties that combine into something else, now featured in global list
+GLOBAL_LIST_INIT_TYPED(combining_properties, /list, list( PROPERTY_DEFIBRILLATING = list(PROPERTY_MUSCLESTIMULATING, PROPERTY_CARDIOPEUTIC),\
+ PROPERTY_THANATOMETABOL = list(PROPERTY_HYPOXEMIC, PROPERTY_CRYOMETABOLIZING, PROPERTY_NEUROCRYOGENIC),\
+ PROPERTY_HYPERDENSIFICATING = list(PROPERTY_MUSCLESTIMULATING, PROPERTY_BONEMENDING, PROPERTY_CARCINOGENIC),\
+ PROPERTY_HYPERTHROTTLING = list(PROPERTY_PSYCHOSTIMULATING, PROPERTY_HALLUCINOGENIC),\
+ PROPERTY_NEUROSHIELDING = list(PROPERTY_ALCOHOLIC, PROPERTY_BALDING),\
+ PROPERTY_ANTIADDICTIVE = list(PROPERTY_PSYCHOSTIMULATING, PROPERTY_ANTIHALLUCINOGENIC),\
+ PROPERTY_ADDICTIVE = list(PROPERTY_PSYCHOSTIMULATING, PROPERTY_NEUROTOXIC),\
+ PROPERTY_CIPHERING_PREDATOR = list(PROPERTY_CIPHERING, PROPERTY_CROSSMETABOLIZING),\
+ PROPERTY_FIRE_PENETRATING = list(PROPERTY_OXYGENATING, PROPERTY_VISCOUS),\
+ PROPERTY_BONEMENDING = list(PROPERTY_HYPERDENSIFICATING, PROPERTY_NUTRITIOUS),\
+ PROPERTY_BONEMENDING = list(PROPERTY_HYPERDENSIFICATING, PROPERTY_NUTRITIOUS),\
+ PROPERTY_ENCEPHALOPHRASIVE = list(PROPERTY_NERVESTIMULATING, PROPERTY_PSYCHOSTIMULATING)))
//List of all id's from classed /datum/reagent datums indexed by class or tier. Used by chemistry generator and chem spawners.
GLOBAL_LIST_INIT_TYPED(chemical_gen_classes_list, /list, list("C" = list(),"C1" = list(),"C2" = list(),"C3" = list(),"C4" = list(),"C5" = list(),"C6" = list(),"T1" = list(),"T2" = list(),"T3" = list(),"T4" = list(),"tau", list()))
//properties generated in chemicals, helps to make sure the same property doesn't show up 10 times
GLOBAL_LIST_INIT_TYPED(generated_properties, /list, list("positive" = list(), "negative" = list(), "neutral" = list()))
+GLOBAL_LIST_INIT_TYPED(space_weapons, /datum/space_weapon, setup_ship_weapon())
+GLOBAL_LIST_INIT_TYPED(space_weapons_ammo, /datum/space_weapon_ammo, setup_ship_ammo())
+
GLOBAL_LIST_INIT_TYPED(ammo_list, /datum/ammo, setup_ammo()) //List of all ammo types. Used by guns to tell the projectile how to act.
GLOBAL_REFERENCE_LIST_INDEXED(joblist, /datum/job, title) //List of all jobstypes, minus borg and AI
@@ -320,6 +351,20 @@ GLOBAL_LIST_INIT(hj_emotes, setup_hazard_joe_emotes())
all_species[S.name] = S
return all_species
+/proc/setup_ship_weapon()
+ var/list/ammo_list = list()
+ for(var/weapon_type in subtypesof(/datum/space_weapon))
+ var/datum/space_weapon/new_weapon = new weapon_type
+ ammo_list[new_weapon.type] = new_weapon
+ return ammo_list
+
+/proc/setup_ship_ammo()
+ var/list/ammo_list = list()
+ for(var/ammo_type in subtypesof(/datum/space_weapon_ammo))
+ var/datum/space_weapon_ammo/new_ammo = new ammo_type
+ ammo_list[new_ammo.type] = new_ammo
+ return ammo_list
+
/proc/setup_ammo()
var/list/blacklist = list(/datum/ammo/energy, /datum/ammo/energy/yautja, /datum/ammo/energy/yautja/rifle, /datum/ammo/bullet/shotgun, /datum/ammo/xeno)
var/list/ammo_list = list()
diff --git a/code/_macros.dm b/code/_macros.dm
index abfa83df7d36..9b92dc8730c3 100644
--- a/code/_macros.dm
+++ b/code/_macros.dm
@@ -95,6 +95,9 @@
#define GENERATE_DEBUG_ID "[rand(0, 9)][rand(0, 9)][rand(0, 9)][rand(0, 9)][pick(alphabet_lowercase)][pick(alphabet_lowercase)][pick(alphabet_lowercase)][pick(alphabet_lowercase)]"
#define RECT new /datum/shape/rectangle
+#define SQUARE new /datum/shape/rectangle/square
+#define ELLIPSE new /datum/shape/ellipse
+#define CIRCLE new /datum/shape/ellipse/circle
#define QTREE new /datum/quadtree
#define SEARCH_QTREE(qtree, shape_range, flags) qtree.query_range(shape_range, null, flags)
diff --git a/code/_onclick/human.dm b/code/_onclick/human.dm
index b09c26ffb92f..4a353d5ed5c5 100644
--- a/code/_onclick/human.dm
+++ b/code/_onclick/human.dm
@@ -38,7 +38,7 @@
if (A != src) return ..()
var/mob/living/carbon/human/H = A
- if (last_chew + 75 > world.time)
+ if (last_chew + 1 > world.time)
to_chat(H, SPAN_DANGER("You can't bite your hand again yet..."))
return
diff --git a/code/_onclick/xeno.dm b/code/_onclick/xeno.dm
index 3bb69fe05419..15dc1c39f495 100644
--- a/code/_onclick/xeno.dm
+++ b/code/_onclick/xeno.dm
@@ -3,7 +3,7 @@
*/
/mob/living/carbon/xenomorph/UnarmedAttack(atom/target, proximity, click_parameters, tile_attack = FALSE, ignores_resin = FALSE)
- if(body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_ABILITY_BURROWED)) //No attacks while laying down
+ if(body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_ABILITY_BURROWED) || cannot_slash) //No attacks while laying down
return FALSE
var/mob/alt
diff --git a/code/controllers/subsystem/communications.dm b/code/controllers/subsystem/communications.dm
index 7397d98a0d52..e0ca12c341bd 100644
--- a/code/controllers/subsystem/communications.dm
+++ b/code/controllers/subsystem/communications.dm
@@ -272,7 +272,6 @@ SUBSYSTEM_DEF(radio)
"[VAI_FREQ]" = "vairadio",
"[RMC_FREQ]" = "rmcradio",
"[CMB_FREQ]" = "cmbradio",
- "[CLF_FREQ]" = "clfradio",
"[ALPHA_FREQ]" = "alpharadio",
"[BRAVO_FREQ]" = "bravoradio",
"[CHARLIE_FREQ]" = "charlieradio",
@@ -287,6 +286,17 @@ SUBSYSTEM_DEF(radio)
"[COLONY_FREQ]" = "deptradio",
"[BUG_A_FREQ]" = "airadio",
"[BUG_B_FREQ]" = "aiprivradio",
+ "[UPP_FREQ]" = "syndradio",
+ "[UPP_CMD_FREQ]" = "opforcmd",
+ "[UPP_ENGI_FREQ]" = "opforeng",
+ "[UPP_MED_FREQ]" = "opformed",
+ "[UPP_CCT_FREQ]" = "opforcct",
+ "[UPP_KDO_FREQ]" = "opforspe",
+ "[CLF_FREQ]" = "clfradio",
+ "[CLF_CMD_FREQ]" = "opforcmd",
+ "[CLF_ENGI_FREQ]" = "opforeng",
+ "[CLF_MED_FREQ]" = "opformed",
+ "[CLF_CCT_FREQ]" = "opforcct",
)
/datum/controller/subsystem/radio/proc/add_object(obj/device as obj, new_frequency as num, filter = null as text|null)
@@ -359,10 +369,6 @@ SUBSYSTEM_DEF(radio)
return freq_span
if(frequency in PMC_FREQS)
return "pmcradio"
- if(frequency in UPP_FREQS)
- return "syndradio"
- if(frequency in CLF_FREQS)
- return "clfradio"
if(frequency in ERT_FREQS)
return "centradio"
if(frequency in DEPT_FREQS)
diff --git a/code/controllers/subsystem/init/lobby_art.dm b/code/controllers/subsystem/init/lobby_art.dm
index 7c49d5fe1787..4b26d576b8df 100644
--- a/code/controllers/subsystem/init/lobby_art.dm
+++ b/code/controllers/subsystem/init/lobby_art.dm
@@ -6,5 +6,5 @@ SUBSYSTEM_DEF(lobby_art)
/datum/controller/subsystem/lobby_art/Initialize()
var/list/lobby_arts = CONFIG_GET(str_list/lobby_art_images)
if(length(lobby_arts))
- force_lobby_art(rand(1,length(lobby_arts)))
+ force_lobby_art(rand(1, length(lobby_arts)))
return SS_INIT_SUCCESS
diff --git a/code/controllers/subsystem/sound.dm b/code/controllers/subsystem/sound.dm
index 024df7cc45ad..3cc3f0ef8090 100644
--- a/code/controllers/subsystem/sound.dm
+++ b/code/controllers/subsystem/sound.dm
@@ -19,8 +19,7 @@ SUBSYSTEM_DEF(sound)
if(!run_hearers) // Initialize for handling next template
run_hearers = run_queue[run_template] // get base hearers
if(run_template.range) // ranging
- var/datum/shape/rectangle/zone = RECT(run_template.x, run_template.y, run_template.range * 2, run_template.range * 2)
- run_hearers |= SSquadtree.players_in_range(zone, run_template.z)
+ run_hearers |= SSquadtree.players_in_range(SQUARE(run_template.x, run_template.y, run_template.range * 2), run_template.z)
if(MC_TICK_CHECK)
return
while(length(run_hearers)) // Output sound to hearers
diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm
index 85e2a57cc6d6..25f522753543 100644
--- a/code/controllers/subsystem/vote.dm
+++ b/code/controllers/subsystem/vote.dm
@@ -414,6 +414,7 @@ SUBSYSTEM_DEF(vote)
qdel(src)
/datum/action/innate/vote/action_activate()
+ . = ..()
owner.vote()
/datum/action/innate/vote/proc/remove_from_client()
diff --git a/code/controllers/subsystem/who.dm b/code/controllers/subsystem/who.dm
new file mode 100644
index 000000000000..6c817fb1245e
--- /dev/null
+++ b/code/controllers/subsystem/who.dm
@@ -0,0 +1,293 @@
+SUBSYSTEM_DEF(who)
+ name = "Who"
+ flags = SS_BACKGROUND
+ runlevels = RUNLEVELS_DEFAULT|RUNLEVEL_LOBBY
+ init_order = SS_INIT_WHO
+ wait = 5 SECONDS
+
+ var/datum/player_list/who = new
+ var/datum/player_list/staff/staff_who = new
+
+/datum/controller/subsystem/who/Initialize()
+ who.update_data()
+ staff_who.update_data()
+ return SS_INIT_SUCCESS
+
+/datum/controller/subsystem/who/fire(resumed = TRUE)
+ who.update_data()
+ staff_who.update_data()
+
+
+
+// WHO DATA
+/datum/player_list
+ var/tgui_name = "Who"
+ var/tgui_interface_name = "Who"
+ var/list/base_data = list()
+ var/list/admin_sorted_additional = list()
+
+/datum/player_list/proc/update_data()
+ var/list/base_data = list()
+ var/list/admin_sorted_additional = list()
+
+ var/list/factions_additional = list()
+ admin_sorted_additional["factions_additional"] = list("flags" = R_MOD|R_ADMIN, "data" = factions_additional)
+
+ var/list/player_additional = list()
+ admin_sorted_additional["player_additional"] = list("flags" = R_MOD|R_ADMIN, "data" = player_additional)
+
+ var/list/player_stealthed_additional = list()
+ admin_sorted_additional["player_stealthed_additional"] = list("flags" = R_STEALTH, "data" = player_stealthed_additional)
+
+ var/list/counted_additional = list(
+ "lobby" = 0,
+ "admin_observers" = 0,
+ "observers" = 0,
+ "yautja" = 0,
+ "infected_preds" = 0,
+ "humans" = 0,
+ "infected_humans" = 0,
+ "uscm" = 0,
+ "uscm_marines" = 0,
+ )
+ var/list/counted_factions = list()
+
+ // Running thru all clients and doing some counts
+ for(var/client/client as anything in sortTim(GLOB.clients, GLOBAL_PROC_REF(cmp_ckey_asc)))
+ var/list/client_payload = list()
+ client_payload["text"] = client.key
+ client_payload["ckey_color"] = "white"
+ if(CLIENT_IS_STEALTHED(client))
+ player_stealthed_additional["total_players"] += list(list(client.key = list(client_payload)))
+ else if(client.admin_holder?.fakekey)
+ player_additional["total_players"] += list(list(client.key = list(client_payload)))
+ else
+ base_data["total_players"] += list(list(client.key = list(client_payload.Copy())))
+ player_additional["total_players"] += list(list(client.key = list(client_payload)))
+
+ var/mob/client_mob = client.mob
+ if(client_mob)
+ if(istype(client_mob, /mob/new_player))
+ client_payload["text"] += " - in Lobby"
+ counted_additional["lobby"]++
+
+ else if(isobserver(client_mob))
+ client_payload["text"] += " - Playing as [client_mob.real_name]"
+ if(CLIENT_IS_STAFF(client))
+ counted_additional["admin_observers"]++
+ else
+ counted_additional["observers"]++
+
+ var/mob/dead/observer/observer = client_mob
+ if(observer.started_as_observer)
+ client_payload["color"] = "#ce89cd"
+ client_payload["text"] += " - Spectating"
+ else
+ client_payload["color"] = "#A000D0"
+ client_payload["text"] += " - DEAD"
+
+ else
+ client_payload["text"] += " - Playing as [client_mob.real_name]"
+
+ switch(client_mob.stat)
+ if(UNCONSCIOUS)
+ client_payload["color"] = "#B0B0B0"
+ client_payload["text"] += " - Unconscious"
+ if(DEAD)
+ client_payload["color"] = "#A000D0"
+ client_payload["text"] += " - DEAD"
+
+ if(client_mob.stat != DEAD)
+ if(isxeno(client_mob))
+ client_payload["color"] = "#ec3535"
+ client_payload["text"] += " - Xenomorph"
+
+ else if(ishuman(client_mob))
+ if(client_mob.faction == FACTION_ZOMBIE)
+ counted_factions[FACTION_ZOMBIE]++
+ client_payload["color"] = "#2DACB1"
+ client_payload["text"] += " - Zombie"
+ else if(client_mob.faction == FACTION_YAUTJA)
+ client_payload["color"] = "#7ABA19"
+ client_payload["text"] += " - Yautja"
+ counted_additional["yautja"]++
+ if(client_mob.status_flags & XENO_HOST)
+ counted_additional["infected_preds"]++
+ else
+ counted_additional["humans"]++
+ if(client_mob.status_flags & XENO_HOST)
+ counted_additional["infected_humans"]++
+ if(client_mob.faction == FACTION_MARINE)
+ counted_additional["uscm"]++
+ if(client_mob.job in (GLOB.ROLES_MARINES))
+ counted_additional["uscm_marines"]++
+ else
+ counted_factions[client_mob.faction]++
+
+ //Bulky section with pre writen names and desc for counts
+ factions_additional += list(list("content" = "In Lobby: [counted_additional["lobby"]]", "color" = "#777", "text" = "Player in lobby"))
+ factions_additional += list(list("content" = "Spectating Players: [counted_additional["observers"]]", "color" = "#777", "text" = "Spectating players"))
+ factions_additional += list(list("content" = "Spectating Admins: [counted_additional["admin_observers"]]", "color" = "#777", "text" = "Spectating administrators"))
+ factions_additional += list(list("content" = "Humans: [counted_additional["humans"]]", "color" = "#2C7EFF", "text" = "Players playing as Human"))
+ factions_additional += list(list("content" = "Infected Humans: [counted_additional["infected_humans"]]", "color" = "#ec3535", "text" = "Players playing as Infected Human"))
+ factions_additional += list(list("content" = "[MAIN_SHIP_NAME] Personnel: [counted_additional["uscm"]]", "color" = "#5442bd", "text" = "Players playing as [MAIN_SHIP_NAME] Personnel"))
+ factions_additional += list(list("content" = "Marines: [counted_additional["uscm_marines"]]", "color" = "#5442bd", "text" = "Players playing as Marines"))
+ factions_additional += list(list("content" = "Yautjas: [counted_additional["yautja"]]", "color" = "#7ABA19", "text" = "Players playing as Yautja"))
+ factions_additional += list(list("content" = "Infected Predators: [counted_additional["infected_preds"]]", "color" = "#7ABA19", "text" = "Players playing as Infected Yautja"))
+
+ for(var/i in 1 to length(counted_factions))
+ if(!counted_factions[counted_factions[i]])
+ continue
+ factions_additional += list(list("content" = "[counted_factions[i]]: [counted_factions[counted_factions[i]]]", "color" = "#2C7EFF", "text" = "Other"))
+
+ if(counted_factions[FACTION_NEUTRAL])
+ factions_additional += list(list("content" = "[FACTION_NEUTRAL] Humans: [counted_factions[FACTION_NEUTRAL]]", "color" = "#688944", "text" = "Neutrals"))
+
+ for(var/faction_to_get in ALL_XENO_HIVES)
+ var/datum/hive_status/hive = GLOB.hive_datum[faction_to_get]
+ if(!hive || !length(hive.totalXenos))
+ continue
+ factions_additional += list(list("content" = "[hive.name]: [length(hive.totalXenos)]", "color" = hive.color ? hive.color : "#8200FF", "text" = "Queen: [hive.living_xeno_queen ? "Alive" : "Dead"]"))
+
+ src.base_data = base_data
+ src.admin_sorted_additional = admin_sorted_additional
+
+/datum/player_list/tgui_interact(mob/user, datum/tgui/ui)
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, tgui_name, tgui_interface_name)
+ ui.open()
+ ui.set_autoupdate(TRUE)
+
+/datum/player_list/ui_data(mob/user)
+ . = list()
+ // Sending base client data, this data sended to EVERYONE
+ .["base_data"] = base_data
+
+ // Admin rights based data
+ if(!CLIENT_IS_STAFF(user.client))
+ return
+ for(var/data_packet_name in admin_sorted_additional) // One by one for Drulikar complains
+ if(!check_client_rights(user.client, admin_sorted_additional[data_packet_name]["flags"], FALSE))
+ continue
+ . += list("[data_packet_name]" = admin_sorted_additional[data_packet_name]["data"])
+
+/datum/player_list/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
+ . = ..()
+ if(.)
+ return
+
+ switch(action)
+ if("get_player_panel")
+ if(!CLIENT_IS_STAFF(ui.user.client))
+ return
+ var/chosen_ckey = params["ckey"]
+ for(var/client/target in GLOB.clients)
+ if(target.key != chosen_ckey)
+ continue
+ if(target.mob)
+ GLOB.admin_datums[ui.user.client.ckey].show_player_panel(target.mob)
+ break
+
+/datum/player_list/ui_status(mob/user, datum/ui_state/state)
+ return UI_INTERACTIVE
+
+
+// STAFF DATA
+/datum/player_list/staff
+ tgui_name = "StaffWho"
+ tgui_interface_name = "Staff Who"
+
+ var/list/category_colors = list(
+ "Management" = "purple",
+ "Maintainers" = "blue",
+ "Administrators" = "red",
+ "Moderators" = "orange",
+ "Mentors" = "green"
+ )
+
+/datum/player_list/staff/update_data()
+ var/list/base_data = list()
+ var/list/admin_sorted_additional = list()
+
+ var/list/admin_additional = list()
+ admin_sorted_additional["admin_additional"] = list("flags" = R_MOD|R_ADMIN, "data" = admin_additional)
+
+ var/list/admin_stealthed_additional = list()
+ admin_sorted_additional["admin_stealthed_additional"] = list("flags" = R_STEALTH, "data" = admin_stealthed_additional)
+
+ var/list/listings = list()
+ if(CONFIG_GET(flag/show_manager))
+ listings["Management"] = list(R_PERMISSIONS, list())
+ if(CONFIG_GET(flag/show_devs))
+ listings["Maintainers"] = list(R_PROFILER, list())
+ listings["Administrators"] = list(R_ADMIN, list())
+ if(CONFIG_GET(flag/show_mods))
+ listings["Moderators"] = list(R_MOD|R_BAN, list())
+ if(CONFIG_GET(flag/show_mentors))
+ listings["Mentors"] = list(R_MENTOR, list())
+
+ for(var/client/client as anything in GLOB.admins)
+ for(var/category in listings)
+ if(CLIENT_HAS_RIGHTS(client, listings[category][1]))
+ listings[category][2] += client
+ break
+
+ for(var/category in listings)
+ base_data["categories"] += list(list(
+ "category" = category,
+ "category_color" = category_colors[category],
+ ))
+
+ for(var/client/client as anything in listings[category][2])
+ var/list/admin_payload = list()
+ admin_payload["category"] = category
+ var/rank = client.admin_holder.rank
+ if(client.admin_holder.extra_titles?.len)
+ for(var/srank in client.admin_holder.extra_titles)
+ rank += " & [srank]"
+
+ if(CLIENT_IS_STEALTHED(client))
+ admin_payload["special_color"] = "#b60d0d"
+ admin_payload["special_text"] = " (STEALTHED)"
+ admin_stealthed_additional["total_admins"] += list(list("[client.key] ([rank])" = list(admin_payload)))
+ else if(client.admin_holder?.fakekey)
+ admin_payload["special_color"] = "#7b582f"
+ admin_payload["special_text"] += " (HIDDEN)"
+ admin_additional["total_admins"] += list(list("[client.key] ([rank])" = list(admin_payload)))
+ else
+ admin_additional["total_admins"] += list(list("[client.key] ([rank])" = list(admin_payload)))
+ base_data["total_admins"] += list(list("[client.key] ([rank])" = list(admin_payload.Copy())))
+
+ admin_payload["text"] = ""
+ if(istype(client.mob, /mob/dead/observer))
+ admin_payload["color"] = "#808080"
+ admin_payload["text"] += "Spectating"
+
+ else if(istype(client.mob, /mob/new_player))
+ admin_payload["color"] = "#FFFFFF"
+ admin_payload["text"] += "in Lobby"
+ else
+ admin_payload["color"] = "#688944"
+ admin_payload["text"] += "Playing"
+
+ if(client.is_afk())
+ admin_payload["color"] = "#A040D0"
+ admin_payload["special_text"] += " (AFK)"
+
+ src.base_data = base_data
+ src.admin_sorted_additional = admin_sorted_additional
+
+
+// VERBS
+/mob/verb/who()
+ set category = "OOC"
+ set name = "Who"
+
+ SSwho.who.tgui_interact(src)
+
+/mob/verb/staffwho()
+ set category = "Admin"
+ set name = "StaffWho"
+
+ SSwho.staff_who.tgui_interact(src)
diff --git a/code/datums/action.dm b/code/datums/action.dm
index d1768655a2da..e6c87eca6a0d 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -43,7 +43,9 @@
return
/datum/action/proc/action_activate()
- return
+ SHOULD_CALL_PARENT(TRUE)
+
+ SEND_SIGNAL(src, COMSIG_ACTION_ACTIVATED)
/// handler for when a keybind signal is received by the action, calls the action_activate proc asynchronous
/datum/action/proc/keybind_activation()
@@ -158,6 +160,10 @@
hidden = FALSE
L.update_action_buttons()
+/proc/get_action(mob/action_mob, action_path)
+ for(var/datum/action/action in action_mob.actions)
+ if(istype(action, action_path))
+ return action
/datum/action/item_action
name = "Use item"
@@ -181,11 +187,6 @@
holder_item = null
return ..()
-/datum/action/item_action/action_activate()
- if(target)
- var/obj/item/I = target
- I.ui_action_click(owner, holder_item)
-
/datum/action/item_action/can_use_action()
if(ishuman(owner) && !owner.is_mob_incapacitated())
var/mob/living/carbon/human/human = owner
@@ -206,6 +207,17 @@
name = "Toggle [target]"
button.name = name
+/datum/action/item_action/toggle/action_activate()
+ . = ..()
+ if(target)
+ var/obj/item/I = target
+ I.ui_action_click(owner, holder_item)
+
+/datum/action/item_action/toggle/use/New(target)
+ . = ..()
+ name = "Use [target]"
+ button.name = name
+
//This is the proc used to update all the action buttons.
/mob/proc/update_action_buttons(reload_screen)
if(!client)
diff --git a/code/datums/agents/tools/decoy.dm b/code/datums/agents/tools/decoy.dm
index 57c8e5130fee..57eef25a446d 100644
--- a/code/datums/agents/tools/decoy.dm
+++ b/code/datums/agents/tools/decoy.dm
@@ -1,4 +1,6 @@
/obj/item/explosive/grenade/decoy
+ AUTOWIKI_SKIP(TRUE)
+
name = "decoy grenade"
desc = "A grenade typically used to distract the enemy. Emits a loud bang. Detonates in 5 seconds. Has 3 uses"
diff --git a/code/datums/ammo/ammo.dm b/code/datums/ammo/ammo.dm
index 022909691cfc..587ffd805b6c 100644
--- a/code/datums/ammo/ammo.dm
+++ b/code/datums/ammo/ammo.dm
@@ -173,6 +173,10 @@
living_mob.apply_stamina_damage(fired_projectile.ammo.damage, fired_projectile.def_zone, ARMOR_BULLET)
/datum/ammo/proc/slowdown(mob/living/living_mob, obj/projectile/fired_projectile)
+ if(isxeno(living_mob))
+ var/mob/living/carbon/xenomorph/xeno = living_mob
+ if(xeno.caste.tier > 2 || (xeno.caste.tier == 0 && xeno.mob_size >= MOB_SIZE_BIG))
+ return //tier 3 and big tier 0 (like queen) are not affected
if(iscarbonsizexeno(living_mob))
var/mob/living/carbon/xenomorph/target = living_mob
target.apply_effect(1, SUPERSLOW)
diff --git a/code/datums/ammo/bullet/lever_action.dm b/code/datums/ammo/bullet/lever_action.dm
index 2770231b6811..e1475146b21f 100644
--- a/code/datums/ammo/bullet/lever_action.dm
+++ b/code/datums/ammo/bullet/lever_action.dm
@@ -52,7 +52,7 @@
/datum/ammo/bullet/lever_action/xm88
name = ".458 SOCOM round"
- damage = 80
+ damage = 104
penetration = ARMOR_PENETRATION_TIER_2
accuracy = HIT_ACCURACY_TIER_1
shell_speed = AMMO_SPEED_TIER_6
diff --git a/code/datums/ammo/bullet/pistol.dm b/code/datums/ammo/bullet/pistol.dm
index ced951241754..8b5239ba9127 100644
--- a/code/datums/ammo/bullet/pistol.dm
+++ b/code/datums/ammo/bullet/pistol.dm
@@ -180,12 +180,12 @@
headshot_state = HEADSHOT_OVERLAY_MEDIUM
debilitate = list(0,0,0,0,0,0,0,2)
- effective_range_max = 3
+ effective_range_max = 6
accuracy = HIT_ACCURACY_TIER_4
damage = 45
penetration= ARMOR_PENETRATION_TIER_6
shrapnel_chance = SHRAPNEL_CHANCE_TIER_2
- damage_falloff = DAMAGE_FALLOFF_TIER_6 //"VP78 - the only pistol viable as a primary."-Vampmare, probably.
+ damage_falloff = DAMAGE_FALLOFF_TIER_6
/datum/ammo/bullet/pistol/squash/toxin
name = "toxic squash-head pistol bullet"
diff --git a/code/datums/ammo/energy.dm b/code/datums/ammo/energy.dm
index 3ddd11eedf55..6eb865034cbe 100644
--- a/code/datums/ammo/energy.dm
+++ b/code/datums/ammo/energy.dm
@@ -204,7 +204,7 @@
/datum/ammo/energy/yautja/caster/sphere/stun/proc/do_area_stun(obj/projectile/P)
playsound(P, 'sound/weapons/wave.ogg', 75, 1, 25)
- for (var/mob/living/carbon/M in view(src.stun_range, get_turf(P)))
+ FOR_DVIEW(var/mob/living/carbon/M, src.stun_range, get_turf(P), HIDE_INVISIBLE_OBSERVER)
var/stun_time = src.stun_time
log_attack("[key_name(M)] was stunned by a plasma immobilizer from [key_name(P.firer)] at [get_area(P)]")
if (isyautja(M))
@@ -214,6 +214,7 @@
to_chat(M, SPAN_DANGER("A powerful electric shock ripples through your body, freezing you in place!"))
M.apply_effect(stun_time, STUN)
M.apply_effect(stun_time, WEAKEN)
+ FOR_DVIEW_END
/datum/ammo/energy/yautja/rifle/bolt
name = "plasma rifle bolt"
diff --git a/code/datums/ammo/misc.dm b/code/datums/ammo/misc.dm
index 9a9ed2fb505b..28610f283df2 100644
--- a/code/datums/ammo/misc.dm
+++ b/code/datums/ammo/misc.dm
@@ -49,10 +49,21 @@
drop_flame(get_turf(P), P.weapon_cause_data)
/datum/ammo/flamethrower/tank_flamer
- flamer_reagent_id = "napalmx"
-
+ flamer_reagent_id = "highdamagenapalm"
max_range = 8
+/datum/ammo/flamethrower/tank_flamer/drop_flame(turf/turf, datum/cause_data/cause_data)
+ if(!istype(turf))
+ return
+
+ var/datum/reagent/napalm/high_damage/reagent = new()
+ new /obj/flamer_fire(turf, cause_data, reagent, 1)
+
+ var/datum/effect_system/smoke_spread/landingsmoke = new /datum/effect_system/smoke_spread
+ landingsmoke.set_up(1, 0, turf, null, 4, cause_data)
+ landingsmoke.start()
+ landingsmoke = null
+
/datum/ammo/flamethrower/sentry_flamer
flags_ammo_behavior = AMMO_IGNORE_ARMOR|AMMO_IGNORE_COVER|AMMO_FLAME
flamer_reagent_id = "napalmx"
diff --git a/code/datums/ammo/shrapnel.dm b/code/datums/ammo/shrapnel.dm
index 39b0813fad25..836e142489e1 100644
--- a/code/datums/ammo/shrapnel.dm
+++ b/code/datums/ammo/shrapnel.dm
@@ -122,16 +122,36 @@
name = "glass shrapnel"
icon_state = "shrapnel_glass"
-/datum/ammo/bullet/shrapnel/light/effect/ // no damage, but looks bright and neat
- name = "sparks"
-
- damage = 1 // Tickle tickle
+/particles/shrapnel
+ icon = 'icons/obj/items/weapons/projectiles.dmi'
+ icon_state = "shrapnel_bright2"
+ width = 1000
+ height = 1000
+ count = 100
+ spawning = 0
+ lifespan = 0.6 SECONDS
+ fadein = 0.2 SECONDS
+ velocity = generator("square", 32 * 0.85, 32 * 1.15)
+ rotation = generator("num", 0, 359)
+
+/obj/shrapnel_effect
+ anchored = TRUE
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ unacidable = TRUE
+ blocks_emissive = EMISSIVE_BLOCK_GENERIC
+
+/obj/shrapnel_effect/New()
+ . = ..()
+ particles = new /particles/shrapnel
+ particles.spawning = rand(5,9) + rand(5,9)
+ addtimer(CALLBACK(src, PROC_REF(stop)), 0.1 SECONDS)
+ QDEL_IN(src, 0.9 SECONDS)
-/datum/ammo/bullet/shrapnel/light/effect/ver1
- icon_state = "shrapnel_bright1"
+/obj/shrapnel_effect/proc/stop()
+ particles.spawning = 0
-/datum/ammo/bullet/shrapnel/light/effect/ver2
- icon_state = "shrapnel_bright2"
+/obj/shrapnel_effect/get_applying_acid_time()
+ return -1
/datum/ammo/bullet/shrapnel/jagged
shrapnel_chance = SHRAPNEL_CHANCE_TIER_2
diff --git a/code/datums/autocells/explosion.dm b/code/datums/autocells/explosion.dm
index ecc6f9925800..7736d85509ee 100644
--- a/code/datums/autocells/explosion.dm
+++ b/code/datums/autocells/explosion.dm
@@ -264,7 +264,9 @@ as having entered the turf.
falloff = max(falloff, power/100)
- msg_admin_attack("Explosion with Power: [power], Falloff: [falloff], Shape: [falloff_shape] in [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z]).", epicenter.x, epicenter.y, epicenter.z)
+ var/obj/causing_obj = explosion_cause_data?.resolve_cause()
+ var/mob/causing_mob = explosion_cause_data?.resolve_mob()
+ msg_admin_attack("Explosion with Power: [power], Falloff: [falloff], Shape: [falloff_shape],[causing_obj ? " from [causing_obj]" : ""][causing_mob ? " by [key_name(causing_mob)]" : ""] in [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z]).", epicenter.x, epicenter.y, epicenter.z)
playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(power^2,1))
@@ -293,8 +295,7 @@ as having entered the turf.
if(power >= 100) // powerful explosions send out some special effects
epicenter = get_turf(epicenter) // the ex_acts might have changed the epicenter
- create_shrapnel(epicenter, rand(5,9), , ,/datum/ammo/bullet/shrapnel/light/effect/ver1, explosion_cause_data)
- create_shrapnel(epicenter, rand(5,9), , ,/datum/ammo/bullet/shrapnel/light/effect/ver2, explosion_cause_data)
+ new /obj/shrapnel_effect(epicenter)
/proc/log_explosion(atom/A, datum/automata_cell/explosion/E)
if(isliving(A))
diff --git a/code/datums/beam.dm b/code/datums/beam.dm
index 4b024df585f9..e700016b5f32 100644
--- a/code/datums/beam.dm
+++ b/code/datums/beam.dm
@@ -215,13 +215,7 @@
return newbeam
/proc/zap_beam(atom/source, zap_range, damage, list/blacklistmobs)
- var/list/zap_data = list()
- for(var/mob/living/carbon/xenomorph/beno in oview(zap_range, source))
- zap_data += beno
- for(var/xeno in zap_data)
- var/mob/living/carbon/xenomorph/living = xeno
- if(!living)
- return
+ FOR_DOVIEW(var/mob/living/carbon/xenomorph/living, zap_range, source, HIDE_INVISIBLE_OBSERVER)
if(living.stat == DEAD)
continue
if(living in blacklistmobs)
@@ -229,3 +223,4 @@
source.beam(living, icon_state="lightning[rand(1,12)]", time = 3, maxdistance = zap_range + 2)
living.set_effect(2, SLOW)
log_attack("[living] was zapped by [source]")
+ FOR_DOVIEW_END
diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm
index f356fc5c1077..24cf93ed119f 100644
--- a/code/datums/components/_component.dm
+++ b/code/datums/components/_component.dm
@@ -362,7 +362,8 @@
var/datum/component/C = dc[c_type]
if(C)
if(length(C))
- C = C[1]
+ var/list/component_list = C
+ C = component_list[1]
if(C.type == c_type)
return C
return null
diff --git a/code/datums/components/bad_leg.dm b/code/datums/components/bad_leg.dm
index 4a8678c4da76..8793271803dc 100644
--- a/code/datums/components/bad_leg.dm
+++ b/code/datums/components/bad_leg.dm
@@ -149,6 +149,7 @@
CRASH("No bound wound to link action")
/datum/action/human_action/rest_legs/action_activate()
+ . = ..()
var/mob/living/carbon/human/homan = owner
if(in_use)
to_chat(homan, SPAN_WARNING("You're already doing that!"))
diff --git a/code/datums/components/bonus_damage_stack.dm b/code/datums/components/bonus_damage_stack.dm
index 78da5e036ce4..7a9bf5aa9560 100644
--- a/code/datums/components/bonus_damage_stack.dm
+++ b/code/datums/components/bonus_damage_stack.dm
@@ -60,7 +60,7 @@
var/color = COLOR_BONUS_DAMAGE
var/intensity = bonus_damage_stacks / (initial(bonus_damage_cap) * 2)
// if intensity is too high of a value, the hex code will become invalid
- color += num2text(BONUS_DAMAGE_MAX_ALPHA * clamp(intensity, 0, 0.5), 1, 16)
+ color += num2text(BONUS_DAMAGE_MAX_ALPHA * clamp(intensity, 0, 0.5), 2, 16)
if(parent)
var/atom/A = parent
A.add_filter("bonus_damage_stacks", 2, list("type" = "outline", "color" = color, "size" = 1 + clamp(intensity, 0, 1)))
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index ca4eca8a1a49..44e8924ef68d 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -6,6 +6,8 @@ GLOBAL_DATUM_INIT(data_core, /datum/datacore, new)
var/security[] = list()
//This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
var/locked[] = list()
+ var/leveled_riflemen = 0
+ var/leveled_riflemen_max = 7
/datum/datacore/proc/get_manifest(monochrome, OOC, nonHTML)
var/list/cic = GLOB.ROLES_CIC.Copy()
@@ -261,7 +263,7 @@ GLOBAL_DATUM_INIT(data_core, /datum/datacore, new)
record_general.fields["age"] = target.age
record_general.fields["p_stat"] = "Active"
record_general.fields["m_stat"] = "Stable"
- record_general.fields["sex"] = target.gender
+ record_general.fields["sex"] = capitalize(target.gender)
record_general.fields["species"] = target.get_species()
record_general.fields["origin"] = target.origin
record_general.fields["faction"] = target.personal_faction
diff --git a/code/datums/datum.dm b/code/datums/datum.dm
index e926dfd022ca..2370987b4cfc 100644
--- a/code/datums/datum.dm
+++ b/code/datums/datum.dm
@@ -70,6 +70,10 @@
var/list/cached_vars
#endif
+#ifdef AUTOWIKI
+ var/autowiki_skip = FALSE
+#endif
+
/**
* Default implementation of clean-up code.
*
diff --git a/code/datums/disease.dm b/code/datums/disease.dm
index 024337c8e065..497c62cddec6 100644
--- a/code/datums/disease.dm
+++ b/code/datums/disease.dm
@@ -121,10 +121,11 @@ GLOBAL_LIST_INIT(diseases, typesof(/datum/disease) - /datum/disease)
check_range = 1 // everything else, like infect-on-contact things, only infect things on top of it
if(isturf(source.loc))
- for(var/mob/living/carbon/victim in oview(check_range, source))
+ FOR_DOVIEW(var/mob/living/carbon/victim, check_range, source, HIDE_INVISIBLE_OBSERVER)
if(isturf(victim.loc))
if(AStar(source.loc, victim.loc, /turf/proc/AdjacentTurfs, /turf/proc/Distance, check_range))
victim.contract_disease(src, 0, 1, force_spread)
+ FOR_DOVIEW_END
return
diff --git a/code/datums/elements/strippable.dm b/code/datums/elements/strippable.dm
index e0daaee74a8c..d93b07234c9d 100644
--- a/code/datums/elements/strippable.dm
+++ b/code/datums/elements/strippable.dm
@@ -126,6 +126,14 @@
to_chat(user, SPAN_WARNING("You can't do this right now."))
return FALSE
+ if (user.is_mob_incapacitated())
+ to_chat(user, SPAN_WARNING("You can't do this right now."))
+ return FALSE
+
+ if (HAS_TRAIT(user, TRAIT_IMMOBILIZED) || HAS_TRAIT(user, TRAIT_FLOORED))
+ to_chat(user, SPAN_WARNING("You can't do this right now."))
+ return FALSE
+
if ((item.flags_inventory & CANTSTRIP) || ((item.flags_item & NODROP) && !(item.flags_item & FORCEDROP_CONDITIONAL)) || (item.flags_item & ITEM_ABSTRACT))
return FALSE
diff --git a/code/datums/emergency_calls/cryo_marines.dm b/code/datums/emergency_calls/cryo_marines.dm
index fb8d4b8a5a69..56fa434d09c3 100644
--- a/code/datums/emergency_calls/cryo_marines.dm
+++ b/code/datums/emergency_calls/cryo_marines.dm
@@ -37,10 +37,11 @@
human.create_hud()
if(!mind)
- for(var/obj/structure/machinery/cryopod/pod in view(7,human))
+ FOR_DVIEW(var/obj/structure/machinery/cryopod/pod, 7, human, HIDE_INVISIBLE_OBSERVER)
if(pod && !pod.occupant)
pod.go_in_cryopod(human, silent = TRUE)
break
+ FOR_DVIEW_END
sleep(5)
var/datum/squad/marine/cryo/cryo_squad = GLOB.RoleAuthority.squads_by_type[/datum/squad/marine/cryo]
diff --git a/code/datums/emergency_calls/cryo_spec.dm b/code/datums/emergency_calls/cryo_spec.dm
index 8d563b0693f8..5d4f621a473a 100644
--- a/code/datums/emergency_calls/cryo_spec.dm
+++ b/code/datums/emergency_calls/cryo_spec.dm
@@ -8,6 +8,16 @@
shuttle_id = ""
spawn_max_amount = TRUE
+/datum/emergency_call/cryo_spec/remove_nonqualifiers(list/datum/mind/candidates_list)
+ var/list/datum/mind/candidates_clean = list()
+ for(var/datum/mind/single_candidate in candidates_list)
+ if(check_timelock(single_candidate.current?.client, JOB_SQUAD_ROLES_LIST, time_required_for_job))
+ candidates_clean.Add(single_candidate)
+ continue
+ if(single_candidate.current)
+ to_chat(single_candidate.current, SPAN_WARNING("You didn't qualify for the ERT beacon because you don't have the specialist job unlocked!"))
+ return candidates_clean
+
/datum/emergency_call/cryo_spec/create_member(datum/mind/mind, turf/override_spawn_loc)
set waitfor = FALSE
if(SSmapping.configs[GROUND_MAP].map_name == MAP_WHISKEY_OUTPOST)
@@ -25,10 +35,11 @@
human.create_hud()
if(!mind)
- for(var/obj/structure/machinery/cryopod/pod in view(7,human))
+ FOR_DVIEW(var/obj/structure/machinery/cryopod/pod, 7, human, HIDE_INVISIBLE_OBSERVER)
if(pod && !pod.occupant)
pod.go_in_cryopod(human, silent = TRUE)
break
+ FOR_DVIEW_END
sleep(5)
human.client?.prefs.copy_all_to(human, JOB_SQUAD_SPECIALIST, TRUE, TRUE)
diff --git a/code/datums/emergency_calls/emergency_call.dm b/code/datums/emergency_calls/emergency_call.dm
index 99b31ab41f19..885844b6ec2e 100644
--- a/code/datums/emergency_calls/emergency_call.dm
+++ b/code/datums/emergency_calls/emergency_call.dm
@@ -224,11 +224,15 @@
addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/emergency_call, spawn_candidates), quiet_launch, announce_incoming, override_spawn_loc), 30 SECONDS)
+/datum/emergency_call/proc/remove_nonqualifiers(list/datum/mind/candidates_list)
+ return candidates_list //everyone gets selected on 99% of distress beacons.
+
/datum/emergency_call/proc/spawn_candidates(quiet_launch = FALSE, announce_incoming = TRUE, override_spawn_loc)
if(SSticker.mode)
SSticker.mode.picked_calls -= src
SEND_SIGNAL(src, COMSIG_ERT_SETUP)
+ candidates = remove_nonqualifiers(candidates)
if(length(candidates) < mob_min && !spawn_max_amount)
message_admins("Aborting distress beacon, not enough candidates: found [length(candidates)].")
diff --git a/code/datums/emergency_calls/inspection.dm b/code/datums/emergency_calls/inspection.dm
index e473466f4fb8..4a1a8ecb62be 100644
--- a/code/datums/emergency_calls/inspection.dm
+++ b/code/datums/emergency_calls/inspection.dm
@@ -1,6 +1,6 @@
//USCM Provost
/datum/emergency_call/inspection_provost
- name = "Inspection - USCM Provost - ML knowledge required."
+ name = "Inspection - USCM Provost - ML knowledge and MP playtime required."
mob_max = 2
mob_min = 1
probability = 0
@@ -9,6 +9,15 @@
..()
objectives = "Investigate any issues with ML enforcement on the [MAIN_SHIP_NAME]."
+/datum/emergency_call/inspection_provost/remove_nonqualifiers(list/datum/mind/candidates_list)
+ var/list/datum/mind/candidates_clean = list()
+ for(var/datum/mind/single_candidate in candidates_list)
+ if(check_timelock(single_candidate.current?.client, JOB_POLICE, time_required_for_job))
+ candidates_clean.Add(single_candidate)
+ continue
+ if(single_candidate.current)
+ to_chat(single_candidate.current, SPAN_WARNING("You didn't qualify for the ERT beacon because you don't have enough playtime (5 Hours) as military police!"))
+ return candidates_clean
/datum/emergency_call/inspection_provost/create_member(datum/mind/M, turf/override_spawn_loc)
var/turf/T = override_spawn_loc ? override_spawn_loc : get_spawn_point()
diff --git a/code/datums/looping_sounds/misc_sounds.dm b/code/datums/looping_sounds/misc_sounds.dm
index 6411b3f51f4a..318ac7b331b7 100644
--- a/code/datums/looping_sounds/misc_sounds.dm
+++ b/code/datums/looping_sounds/misc_sounds.dm
@@ -1,3 +1,24 @@
/datum/looping_sound/looping_launch_announcement_alarm
mid_sounds = list('sound/vehicles/Dropships/single_alarm_brr_dropship_1.ogg' = 1)
start_sound = list('sound/vehicles/Dropships/single_alarm_brr_dropship_1.ogg' = 1)
+
+/datum/looping_sound/telephone/ring
+ start_sound = 'sound/machines/telephone/dial.ogg'
+ start_length = 3.2 SECONDS
+ mid_sounds = 'sound/machines/telephone/ring_outgoing.ogg'
+ mid_length = 2.1 SECONDS
+ volume = 10
+
+/datum/looping_sound/telephone/busy
+ start_sound = 'sound/voice/callstation_unavailable.ogg'
+ start_length = 5.7 SECONDS
+ mid_sounds = 'sound/machines/telephone/phone_busy.ogg'
+ mid_length = 5 SECONDS
+ volume = 15
+
+/datum/looping_sound/telephone/hangup
+ start_sound = 'sound/machines/telephone/remote_hangup.ogg'
+ start_length = 0.6 SECONDS
+ mid_sounds = 'sound/machines/telephone/phone_busy.ogg'
+ mid_length = 5 SECONDS
+ volume = 15
diff --git a/code/datums/mob_hud.dm b/code/datums/mob_hud.dm
index 603f9a05d702..011dc8e25dba 100644
--- a/code/datums/mob_hud.dm
+++ b/code/datums/mob_hud.dm
@@ -408,7 +408,6 @@ GLOBAL_LIST_INIT_TYPED(huds, /datum/mob_hud, list(
var/revive_enabled = stat == DEAD && check_tod() && is_revivable()
if(stat == DEAD)
revive_enabled = check_tod() && is_revivable()
- var/datum/internal_organ/heart/heart = islist(internal_organs_by_name) ? internal_organs_by_name["heart"] : null
var/holder2_set = 0
if(hivenumber)
@@ -475,7 +474,7 @@ GLOBAL_LIST_INIT_TYPED(huds, /datum/mob_hud, list(
holder3.icon_state = "huddead"
holder2_set = 1
else
- if(heart && (heart.organ_status >= ORGAN_BROKEN && check_tod())) // broken heart icon
+ if(is_heart_broken()) // broken heart icon
holder.icon_state = "huddeadheart"
if(!holder2_set)
holder2.icon_state = "huddeadheart"
@@ -784,7 +783,7 @@ GLOBAL_DATUM(hud_icon_hudfocus, /image)
// Vampire Execute HUD
/mob/living/carbon/human/proc/update_execute_hud()
var/image/execute_holder = hud_list[XENO_EXECUTE]
-
+
execute_holder.icon_state = "hudblank"
execute_holder.overlays.Cut()
diff --git a/code/datums/quadtree.dm b/code/datums/quadtree.dm
index 5e5b27d57330..9056dfd6bd59 100644
--- a/code/datums/quadtree.dm
+++ b/code/datums/quadtree.dm
@@ -49,43 +49,124 @@
..()
return QDEL_HINT_IWILLGC
-/datum/shape //Leaving rectangles as a subtype if anyone decides to add circles later
+/// A simple geometric shape for testing collisions and intersections. This one is a single point.
+/datum/shape
+ /// Horizontal position of the shape's center point.
var/center_x = 0
+ /// Vertical position of the shape's center point.
var/center_y = 0
+ /// Distance from the shape's leftmost to rightmost extent.
+ var/bounds_x = 0
+ /// Distance from the shape's topmost to bottommost extent.
+ var/bounds_y = 0
-/datum/shape/proc/intersects()
- return
-/datum/shape/proc/contains()
- return
+/datum/shape/New(center_x, center_y)
+ set_shape(center_x, center_y)
+/// Assign shape variables.
+/datum/shape/proc/set_shape(center_x, center_y)
+ src.center_x = center_x
+ src.center_y = center_y
+
+/// Returns TRUE if the coordinates x, y are in or on the shape, otherwise FALSE.
+/datum/shape/proc/contains_xy(x, y)
+ return center_x == x && center_y == y
+
+/// Returns TRUE if the coord datum is in or on the shape, otherwise FALSE.
+/datum/shape/proc/contains_coords(datum/coords/coords)
+ return contains_xy(coords.x_pos, coords.y_pos)
+
+/// Returns TRUE if the atom is in or on the shape, otherwise FALSE.
+/datum/shape/proc/contains_atom(atom/atom)
+ return contains_xy(atom.x, atom.y)
+
+/// Returns TRUE if this shape's bounding box intersects the provided shape's bounding box, otherwise FALSE. Generally faster than a full intersection test.
+/datum/shape/proc/intersects_aabb(datum/shape/aabb)
+ return (abs(src.center_x - aabb.center_x) <= (src.bounds_x + aabb.bounds_x) * 0.5) && (abs(src.center_y - aabb.center_y) <= (src.bounds_y + aabb.bounds_y) * 0.5)
+
+/// Returns TRUE if this shape intersects the provided rectangle shape, otherwise FALSE.
+/datum/shape/proc/intersects_rect(datum/shape/rectangle/rect)
+ return rect.contains_xy(src.center_x, src.center_y)
+
+/// A simple geometric shape for testing collisions and intersections. This one is an axis-aligned rectangle.
/datum/shape/rectangle
+ /// Distance from the shape's leftmost to rightmost extent.
+ var/width = 0
+ /// Distance from the shape's topmost to bottommost extent.
+ var/height = 0
+
+/datum/shape/rectangle/New(center_x, center_y, width, height)
+ set_shape(center_x, center_y, width, height)
+
+/datum/shape/rectangle/set_shape(center_x, center_y, width, height)
+ ..()
+ src.bounds_x = width
+ src.bounds_y = height
+ src.width = width
+ src.height = height
+
+/datum/shape/rectangle/contains_xy(x, y)
+ return (abs(center_x - x) <= width * 0.5) && (abs(center_y - y) <= height * 0.5)
+
+/datum/shape/rectangle/intersects_rect(datum/shape/rectangle/rect)
+ return intersects_aabb(rect)
+
+/// A simple geometric shape for testing collisions and intersections. This one is an axis-aligned square.
+/datum/shape/rectangle/square
+ /// Distance between the shape's opposing extents.
+ var/length = 0
+
+/datum/shape/rectangle/square/New(center_x, center_y, length)
+ set_shape(center_x, center_y, length)
+
+/datum/shape/rectangle/square/set_shape(center_x, center_y, length)
+ ..(center_x, center_y, length, length)
+ src.length = length
+
+/// A simple geometric shape for testing collisions and intersections. This one is an axis-aligned ellipse.
+/datum/shape/ellipse
+ /// Distance from the shape's leftmost to rightmost extent.
var/width = 0
+ /// Distance from the shape's topmost to bottommost extent.
var/height = 0
+ VAR_PROTECTED/_axis_x_sq = 0
+ VAR_PROTECTED/_axis_y_sq = 0
+
+/datum/shape/ellipse/New(center_x, center_y, width, height)
+ set_shape(center_x, center_y, width, height)
-/datum/shape/rectangle/New(x, y, w, h)
+/datum/shape/ellipse/set_shape(center_x, center_y, width, height)
..()
- center_x = x
- center_y = y
- width = w
- height = h
-
-/datum/shape/rectangle/intersects(datum/shape/rectangle/range)
- return !(range.center_x + range.width/2 < center_x - width / 2|| \
- range.center_x - range.width/2 > center_x + width / 2|| \
- range.center_y + range.height/2 < center_y - height / 2|| \
- range.center_y - range.height/2 > center_y + height / 2)
-
-/datum/shape/rectangle/contains(datum/coords/coords)
- return (coords.x_pos >= center_x - width / 2 \
- && coords.x_pos <= center_x + width / 2 \
- && coords.y_pos >= center_y - height /2 \
- && coords.y_pos <= center_y + height / 2)
-
-/datum/shape/rectangle/proc/contains_atom(atom/A)
- return (A.x >= center_x - width / 2 \
- && A.x <= center_x + width / 2 \
- && A.y >= center_y - height /2 \
- && A.y <= center_y + height / 2)
+ src.bounds_x = width
+ src.bounds_y = height
+ src.width = width
+ src.height = height
+ src._axis_x_sq = (width * 0.5)**2
+ src._axis_y_sq = (height * 0.5)**2
+
+/datum/shape/ellipse/contains_xy(x, y)
+ return ((center_x - x)**2 / _axis_x_sq + (center_y - y)**2 / _axis_y_sq <= 1)
+
+/datum/shape/ellipse/intersects_rect(datum/shape/rectangle/rect)
+ if(..())
+ return TRUE
+
+ var/nearest_x = clamp(src.center_x, rect.center_x - rect.width * 0.5, rect.center_x + rect.width * 0.5)
+ var/nearest_y = clamp(src.center_y, rect.center_y - rect.height * 0.5, rect.center_y + rect.height * 0.5)
+
+ return src.contains_xy(nearest_x, nearest_y)
+
+/// A simple geometric shape for testing collisions and intersections. This one is a circle.
+/datum/shape/ellipse/circle
+ /// Distance from the shape's center to edge.
+ var/radius = 0
+
+/datum/shape/ellipse/circle/New(center_x, center_y, radius)
+ set_shape(center_x, center_y, radius)
+
+/datum/shape/ellipse/circle/set_shape(center_x, center_y, radius)
+ ..(center_x, center_y, radius * 2, radius * 2)
+ src.radius = radius
/datum/quadtree/proc/subdivide()
//Warning: this might give you eye cancer
@@ -96,7 +177,7 @@
is_divided = TRUE
/datum/quadtree/proc/insert_player(datum/coords/qtplayer/p_coords)
- if(!boundary.contains(p_coords))
+ if(!boundary.contains_coords(p_coords))
return FALSE
if(!player_coords)
@@ -118,11 +199,11 @@
player_coords.Add(p_coords)
return TRUE
-/datum/quadtree/proc/query_range(datum/shape/rectangle/range, list/found_players, flags = 0)
+/datum/quadtree/proc/query_range(datum/shape/range, list/found_players, flags = 0)
if(!found_players)
found_players = list()
. = found_players
- if(!range?.intersects(boundary))
+ if(!range?.intersects_rect(boundary))
return
if(is_divided)
nw_branch.query_range(range, found_players, flags)
@@ -136,7 +217,7 @@
continue
if((flags & QTREE_EXCLUDE_OBSERVER) && P.is_observer)
continue
- if(range.contains(P))
+ if(range.contains_coords(P))
if(flags & QTREE_SCAN_MOBS)
found_players.Add(P.player.mob)
else
diff --git a/code/datums/skills/civilian.dm b/code/datums/skills/civilian.dm
index 0ff13ae67225..ff9cadf02913 100644
--- a/code/datums/skills/civilian.dm
+++ b/code/datums/skills/civilian.dm
@@ -20,7 +20,7 @@ CIVILIAN
SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
SKILL_INTEL = SKILL_INTEL_EXPERT,
)
@@ -31,7 +31,7 @@ CIVILIAN
SKILL_CQC = SKILL_CQC_DEFAULT,
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI, //The ASRS consoles
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED, //The ASRS consoles
SKILL_FIREARMS = SKILL_FIREARMS_CIVILIAN,
SKILL_POLICE = SKILL_POLICE_SKILLED, //The CMB Tradeband Compliance Device
)
@@ -43,7 +43,7 @@ CIVILIAN
SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
@@ -115,7 +115,7 @@ CIVILIAN
SKILL_ENDURANCE = SKILL_ENDURANCE_SURVIVOR,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_POWERLOADER = SKILL_POWERLOADER_MASTER,
)
@@ -131,7 +131,7 @@ CIVILIAN
/datum/skills/civilian/survivor/clf
name = "Survivor CLF"
additional_skills = list(
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
@@ -158,7 +158,7 @@ CIVILIAN
name = "Survivor Miner"
additional_skills = list(
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_POWERLOADER = SKILL_POWERLOADER_MASTER,
SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
)
@@ -167,7 +167,7 @@ CIVILIAN
name = "Survivor Trucker"
additional_skills = list(
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_VEHICLE = SKILL_VEHICLE_CREWMAN,
)
@@ -176,7 +176,7 @@ CIVILIAN
name = "Survivor Engineer"
additional_skills = list(
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_POWERLOADER = SKILL_POWERLOADER_MASTER,
SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
@@ -192,7 +192,7 @@ CIVILIAN
/datum/skills/civilian/survivor/marshal
name = "Survivor Marshal"
skills = list(
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_MELEE_WEAPONS = SKILL_MELEE_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
@@ -201,7 +201,7 @@ CIVILIAN
SKILL_FIREARMS = SKILL_FIREARMS_TRAINED,
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_CQC = SKILL_CQC_SKILLED,
SKILL_FIREARMS = SKILL_FIREARMS_TRAINED,
)
diff --git a/code/datums/skills/clf.dm b/code/datums/skills/clf.dm
index 88aa14a41f79..64a8864d3c51 100644
--- a/code/datums/skills/clf.dm
+++ b/code/datums/skills/clf.dm
@@ -12,7 +12,7 @@ COLONIAL LIBERATION FRONT
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
SKILL_ENDURANCE = SKILL_ENDURANCE_WEAK,
@@ -24,7 +24,7 @@ COLONIAL LIBERATION FRONT
skills = list(
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_POWERLOADER = SKILL_POWERLOADER_TRAINED,
SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
@@ -48,7 +48,7 @@ COLONIAL LIBERATION FRONT
skills = list(
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_CQC = SKILL_CQC_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED, //to use c4 in demo set.
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE, //to use c4 in demo set.
SKILL_LEADERSHIP = SKILL_LEAD_TRAINED,
SKILL_SPEC_WEAPONS = SKILL_SPEC_ALL,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
@@ -60,7 +60,7 @@ COLONIAL LIBERATION FRONT
name = "CLF Leader"
skills = list(
SKILL_FIREARMS = SKILL_FIREARMS_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI, // to use their C4
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED, // to use their C4
SKILL_CQC = SKILL_CQC_SKILLED,
SKILL_LEADERSHIP = SKILL_LEAD_EXPERT,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
@@ -78,7 +78,7 @@ COLONIAL LIBERATION FRONT
name = "CLF Cell Commander"
skills = list(
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CQC = SKILL_CQC_SKILLED,
SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
diff --git a/code/datums/skills/cmb.dm b/code/datums/skills/cmb.dm
index b29a4c314567..8fa7ca4dd892 100644
--- a/code/datums/skills/cmb.dm
+++ b/code/datums/skills/cmb.dm
@@ -26,7 +26,7 @@ COLONIAL MARSHALS
SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_FIREMAN = SKILL_FIREMAN_MASTER,
SKILL_FIREARMS = SKILL_FIREARMS_MAX,
SKILL_MELEE_WEAPONS = SKILL_MELEE_TRAINED,
diff --git a/code/datums/skills/commando.dm b/code/datums/skills/commando.dm
index ed5e5ee086e4..5133cb0e55ea 100644
--- a/code/datums/skills/commando.dm
+++ b/code/datums/skills/commando.dm
@@ -9,7 +9,7 @@ SPEC-OPS
skills = list(
SKILL_CQC = SKILL_CQC_EXPERT,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
@@ -24,7 +24,7 @@ SPEC-OPS
skills = list(
SKILL_CQC = SKILL_CQC_EXPERT,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
@@ -40,7 +40,7 @@ SPEC-OPS
skills = list(
SKILL_CQC = SKILL_CQC_EXPERT,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_LEADERSHIP = SKILL_LEAD_TRAINED,
@@ -56,7 +56,7 @@ SPEC-OPS
skills = list(
SKILL_CQC = SKILL_CQC_MASTER,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
@@ -71,7 +71,7 @@ SPEC-OPS
skills = list(
SKILL_CQC = SKILL_CQC_MASTER,
SKILL_FIREMAN = SKILL_FIREMAN_MASTER,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_LEADERSHIP = SKILL_LEAD_TRAINED,
@@ -87,7 +87,7 @@ SPEC-OPS
skills = list(
SKILL_CQC = SKILL_CQC_MASTER,
SKILL_FIREMAN = SKILL_FIREMAN_MASTER,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_LEADERSHIP = SKILL_LEAD_EXPERT,
@@ -105,7 +105,7 @@ SPEC-OPS
SKILL_CQC = SKILL_CQC_TRAINED,
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_POWERLOADER = SKILL_POWERLOADER_MASTER,
diff --git a/code/datums/skills/contractor.dm b/code/datums/skills/contractor.dm
index 183e95c941f5..5e079e5664d4 100644
--- a/code/datums/skills/contractor.dm
+++ b/code/datums/skills/contractor.dm
@@ -7,7 +7,7 @@ CONTRACTORS
name = "Contractor Standard"
skills = list(
SKILL_CQC = SKILL_CQC_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
SKILL_FIREARMS = SKILL_FIREARMS_MAX,
SKILL_POLICE = SKILL_POLICE_SKILLED,
@@ -22,7 +22,7 @@ CONTRACTORS
/datum/skills/contractor/leader
name = "Contractor Leader"
skills = list(
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_FIREARMS = SKILL_FIREARMS_MAX,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
@@ -45,7 +45,7 @@ CONTRACTORS
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_MEDICAL = SKILL_MEDICAL_DOCTOR,
SKILL_SURGERY = SKILL_SURGERY_TRAINED,
SKILL_VEHICLE = SKILL_VEHICLE_LARGE,
@@ -76,7 +76,7 @@ CONTRACTORS
name = "Contractor Machinegunner"
skills = list(
SKILL_CQC = SKILL_CQC_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
SKILL_FIREARMS = SKILL_FIREARMS_MAX,
SKILL_POLICE = SKILL_POLICE_SKILLED,
diff --git a/code/datums/skills/dutch.dm b/code/datums/skills/dutch.dm
index 4f19233e66d0..ec550f8e2bdf 100644
--- a/code/datums/skills/dutch.dm
+++ b/code/datums/skills/dutch.dm
@@ -4,7 +4,7 @@
SKILL_CQC = SKILL_CQC_MASTER,
SKILL_FIREMAN = SKILL_FIREMAN_MAX,
SKILL_MELEE_WEAPONS = SKILL_MELEE_MAX,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
@@ -20,7 +20,7 @@
name = "Dutch's Dozen Mercenary"
skills = list(
SKILL_CQC = SKILL_CQC_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
@@ -35,7 +35,7 @@
name = "Dutch's Dozen Medic"
skills = list(
SKILL_CQC = SKILL_CQC_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_MEDICAL = SKILL_MEDICAL_DOCTOR,
diff --git a/code/datums/skills/forecon.dm b/code/datums/skills/forecon.dm
index 724a49ee98ca..aef187ce05dd 100644
--- a/code/datums/skills/forecon.dm
+++ b/code/datums/skills/forecon.dm
@@ -8,7 +8,7 @@ MILITARY SURVIVORS
/datum/skills/military/survivor/forecon_standard
name = "Reconnaissance Rifleman"
skills = list(
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_DEFAULT,
SKILL_MELEE_WEAPONS = SKILL_MELEE_TRAINED,
SKILL_CQC = SKILL_CQC_TRAINED,
@@ -24,7 +24,7 @@ MILITARY SURVIVORS
/datum/skills/military/survivor/forecon_techician
name = "Reconnaissance Support Technician"
skills = list(
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_MELEE_WEAPONS = SKILL_MELEE_TRAINED,
SKILL_CQC = SKILL_CQC_TRAINED,
@@ -41,7 +41,7 @@ MILITARY SURVIVORS
/datum/skills/military/survivor/forecon_marksman
name = "Reconnaissance Designated Marksman"
skills = list(
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_DEFAULT,
SKILL_MELEE_WEAPONS = SKILL_MELEE_TRAINED,
SKILL_CQC = SKILL_CQC_TRAINED,
@@ -58,7 +58,7 @@ MILITARY SURVIVORS
/datum/skills/military/survivor/forecon_smartgunner
name = "Reconnaissance Smartgunner"
skills = list(
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_DEFAULT,
SKILL_MELEE_WEAPONS = SKILL_MELEE_TRAINED,
SKILL_CQC = SKILL_CQC_TRAINED,
@@ -75,7 +75,7 @@ MILITARY SURVIVORS
/datum/skills/military/survivor/forecon_sniper
name = "Reconnaissance Sniper"
skills = list(
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_DEFAULT,
SKILL_MELEE_WEAPONS = SKILL_MELEE_TRAINED,
SKILL_CQC = SKILL_CQC_TRAINED,
@@ -92,7 +92,7 @@ MILITARY SURVIVORS
/datum/skills/military/survivor/forecon_squad_leader
name = "Reconnaissance Squad Leader"
skills = list(
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_DEFAULT,
SKILL_MELEE_WEAPONS = SKILL_MELEE_TRAINED,
SKILL_CQC = SKILL_CQC_SKILLED,
diff --git a/code/datums/skills/freelancer.dm b/code/datums/skills/freelancer.dm
index 09df9f32369c..cf7baa15532b 100644
--- a/code/datums/skills/freelancer.dm
+++ b/code/datums/skills/freelancer.dm
@@ -11,7 +11,7 @@ FREELANCERS
skills = list(
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
)
@@ -20,7 +20,7 @@ FREELANCERS
skills = list(
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
SKILL_SURGERY = SKILL_SURGERY_TRAINED,
@@ -31,7 +31,7 @@ FREELANCERS
skills = list(
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
SKILL_CQC = SKILL_CQC_TRAINED,
diff --git a/code/datums/skills/mercenary.dm b/code/datums/skills/mercenary.dm
index 1dc18eaa2fbc..35a6378f51a4 100644
--- a/code/datums/skills/mercenary.dm
+++ b/code/datums/skills/mercenary.dm
@@ -3,7 +3,7 @@
skills = list(
SKILL_CQC = SKILL_CQC_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
@@ -16,7 +16,7 @@
skills = list(
SKILL_CQC = SKILL_CQC_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_MAX,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
@@ -31,7 +31,7 @@
skills = list(
SKILL_CQC = SKILL_CQC_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_MAX,
SKILL_MEDICAL = SKILL_MEDICAL_MASTER,
@@ -62,7 +62,7 @@
skills = list(
SKILL_CQC = SKILL_CQC_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_MAX,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
@@ -78,7 +78,7 @@
skills = list(
SKILL_CQC = SKILL_CQC_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_MAX,
SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
diff --git a/code/datums/skills/misc.dm b/code/datums/skills/misc.dm
index 0f0ca657f995..204890685b91 100644
--- a/code/datums/skills/misc.dm
+++ b/code/datums/skills/misc.dm
@@ -11,7 +11,7 @@ MISCELLANEOUS
SKILL_LEADERSHIP = SKILL_LEAD_EXPERT,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
SKILL_POWERLOADER = SKILL_POWERLOADER_MASTER,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
SKILL_LEADERSHIP = SKILL_LEAD_TRAINED,
SKILL_JTAC = SKILL_JTAC_EXPERT,
@@ -23,7 +23,7 @@ MISCELLANEOUS
SKILL_CQC = SKILL_CQC_MASTER,
SKILL_MELEE_WEAPONS = SKILL_MELEE_SUPER,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
SKILL_SURGERY = SKILL_SURGERY_EXPERT,
@@ -52,7 +52,7 @@ MISCELLANEOUS
name = "Souto Man"
skills = list(
SKILL_CQC = SKILL_CQC_MASTER,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
diff --git a/code/datums/skills/pmc.dm b/code/datums/skills/pmc.dm
index df7027e2a7ab..1860157c0a54 100644
--- a/code/datums/skills/pmc.dm
+++ b/code/datums/skills/pmc.dm
@@ -14,7 +14,7 @@ Private Military Contractors
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
)
@@ -26,7 +26,7 @@ Private Military Contractors
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
SKILL_SURGERY = SKILL_SURGERY_NOVICE,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
@@ -40,7 +40,7 @@ Private Military Contractors
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
SKILL_RESEARCH = SKILL_RESEARCH_TRAINED,
@@ -54,7 +54,7 @@ Private Military Contractors
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_SPEC_WEAPONS = SKILL_SPEC_SMARTGUN,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
SKILL_JTAC = SKILL_JTAC_BEGINNER,
@@ -68,7 +68,7 @@ Private Military Contractors
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CQC = SKILL_CQC_TRAINED,
SKILL_SPEC_WEAPONS = SKILL_SPEC_ALL,
SKILL_MELEE_WEAPONS = SKILL_MELEE_TRAINED,
@@ -83,7 +83,7 @@ Private Military Contractors
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CQC = SKILL_CQC_SKILLED,
SKILL_LEADERSHIP = SKILL_LEAD_TRAINED,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
@@ -99,7 +99,7 @@ Private Military Contractors
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CQC = SKILL_CQC_SKILLED,
SKILL_LEADERSHIP = SKILL_LEAD_TRAINED,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
@@ -116,7 +116,7 @@ Private Military Contractors
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
SKILL_LEADERSHIP = SKILL_LEAD_TRAINED,
SKILL_JTAC = SKILL_JTAC_TRAINED,
@@ -131,7 +131,7 @@ Private Military Contractors
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_MEDICAL = SKILL_MEDICAL_DOCTOR,
SKILL_SURGERY = SKILL_SURGERY_EXPERT,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER, //trained in medicine more than combat
@@ -160,7 +160,7 @@ Private Military Contractors
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
SKILL_CQC = SKILL_CQC_TRAINED,
SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
diff --git a/code/datums/skills/rmc.dm b/code/datums/skills/rmc.dm
index 89aa39b154ad..4385253e9a28 100644
--- a/code/datums/skills/rmc.dm
+++ b/code/datums/skills/rmc.dm
@@ -14,7 +14,7 @@ Royal Marines Commando
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
SKILL_SURGERY = SKILL_SURGERY_NOVICE,
@@ -28,7 +28,7 @@ Royal Marines Commando
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
SKILL_SURGERY = SKILL_SURGERY_NOVICE,
@@ -44,7 +44,7 @@ Royal Marines Commando
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
SKILL_SURGERY = SKILL_SURGERY_NOVICE,
@@ -61,7 +61,7 @@ Royal Marines Commando
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
SKILL_SURGERY = SKILL_SURGERY_NOVICE,
diff --git a/code/datums/skills/synthetic.dm b/code/datums/skills/synthetic.dm
index 3925dd9605b3..c4d7296dee5d 100644
--- a/code/datums/skills/synthetic.dm
+++ b/code/datums/skills/synthetic.dm
@@ -33,7 +33,7 @@ SYNTHETIC
name = SYNTH_COLONY
skills = list(
SKILL_CQC = SKILL_CQC_EXPERT,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_SPEC_WEAPONS = SKILL_SPEC_ALL,
diff --git a/code/datums/skills/upp.dm b/code/datums/skills/upp.dm
index e367372719d6..8ada7ccad124 100644
--- a/code/datums/skills/upp.dm
+++ b/code/datums/skills/upp.dm
@@ -10,7 +10,7 @@ UNITED PROGRESSIVE PEOPLES
name = "UPP Private"
skills = list(
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
SKILL_CQC = SKILL_CQC_DEFAULT,
@@ -22,7 +22,7 @@ UNITED PROGRESSIVE PEOPLES
name = "UPP Sapper"
skills = list(
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
SKILL_CQC = SKILL_CQC_DEFAULT,
@@ -45,7 +45,7 @@ UNITED PROGRESSIVE PEOPLES
name = "UPP Specialist"
skills = list(
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
SKILL_CQC = SKILL_CQC_TRAINED,
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
@@ -60,7 +60,7 @@ UNITED PROGRESSIVE PEOPLES
name = "UPP Squad Leader"
skills = list(
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
SKILL_CQC = SKILL_CQC_TRAINED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
@@ -78,7 +78,7 @@ UNITED PROGRESSIVE PEOPLES
SKILL_FIREMAN = SKILL_FIREMAN_EXPERT,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
)
@@ -93,7 +93,7 @@ UNITED PROGRESSIVE PEOPLES
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_LEADERSHIP = SKILL_LEAD_EXPERT,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
@@ -109,7 +109,7 @@ UNITED PROGRESSIVE PEOPLES
SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
@@ -126,7 +126,7 @@ UNITED PROGRESSIVE PEOPLES
SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_MASTER,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
@@ -147,7 +147,7 @@ UNITED PROGRESSIVE PEOPLES
name = "UPP Private"
skills = list(
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
SKILL_CQC = SKILL_CQC_TRAINED,
@@ -161,7 +161,7 @@ UNITED PROGRESSIVE PEOPLES
name = "UPP Sapper"
skills = list(
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
SKILL_CQC = SKILL_CQC_TRAINED,
@@ -176,7 +176,7 @@ UNITED PROGRESSIVE PEOPLES
name = "UPP Medic"
skills = list(
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_DOCTOR,
SKILL_SURGERY = SKILL_SURGERY_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
@@ -192,7 +192,7 @@ UNITED PROGRESSIVE PEOPLES
name = "UPP Specialist"
skills = list(
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
SKILL_CQC = SKILL_CQC_TRAINED,
@@ -210,7 +210,7 @@ UNITED PROGRESSIVE PEOPLES
name = "UPP Squad Leader"
skills = list(
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
SKILL_SPEC_WEAPONS = SKILL_SPEC_UPP,
SKILL_FIREARMS = SKILL_FIREARMS_TRAINED,
diff --git a/code/datums/skills/uscm.dm b/code/datums/skills/uscm.dm
index f694e8789dcd..1bfb58996b4e 100644
--- a/code/datums/skills/uscm.dm
+++ b/code/datums/skills/uscm.dm
@@ -12,7 +12,7 @@ United States Colonial Marines
name = "Crafty Private"
skills = list(
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
)
/datum/skills/combat_medic
@@ -28,7 +28,7 @@ United States Colonial Marines
name = "Crafty Combat Medic"
skills = list(
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
)
/datum/skills/combat_engineer
@@ -55,7 +55,7 @@ United States Colonial Marines
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
SKILL_CQC = SKILL_CQC_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED, //to use c4 in demo set.
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE, //to use c4 in demo set.
SKILL_SPEC_WEAPONS = SKILL_SPEC_TRAINED,
SKILL_MELEE_WEAPONS = SKILL_MELEE_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
@@ -66,7 +66,7 @@ United States Colonial Marines
name = "Fireteam Leader"
skills = list(
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_JTAC = SKILL_JTAC_EXPERT,
)
@@ -77,7 +77,7 @@ United States Colonial Marines
SKILL_CQC = SKILL_CQC_TRAINED,
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_LEADERSHIP = SKILL_LEAD_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
@@ -90,7 +90,7 @@ United States Colonial Marines
name = "Intelligence Officer"
skills = list(
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_LEADERSHIP = SKILL_LEAD_TRAINED,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
SKILL_CQC = SKILL_CQC_TRAINED,
@@ -157,7 +157,7 @@ MILITARY NONCOMBATANT
SKILL_MEDICAL = SKILL_MEDICAL_MEDIC,
SKILL_SURGERY = SKILL_SURGERY_NOVICE,
SKILL_JTAC = SKILL_JTAC_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
)
/datum/skills/MP
@@ -180,7 +180,7 @@ MILITARY NONCOMBATANT
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
)
/datum/skills/provost
@@ -216,7 +216,7 @@ MILITARY NONCOMBATANT
name = "Mess Technician"
skills = list(
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT, // need to hunt food somehow
- SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
SKILL_FIREMAN = SKILL_FIREMAN_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
SKILL_DOMESTIC = SKILL_DOMESTIC_MASTER
@@ -240,7 +240,7 @@ COMMAND STAFF
name = "General"
skills = list(
SKILL_CQC = SKILL_CQC_TRAINED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
@@ -259,7 +259,7 @@ COMMAND STAFF
/datum/skills/commander
name = "Commanding Officer"
skills = list(
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
@@ -282,13 +282,13 @@ COMMAND STAFF
/datum/skills/XO
name = "Executive Officer"
skills = list(
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI, //to fix CIC apc.
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED, //to fix CIC apc.
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_DOCTOR,
SKILL_SURGERY = SKILL_SURGERY_NOVICE,
- SKILL_POLICE = SKILL_POLICE_FLASH,
+ SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CQC = SKILL_CQC_SKILLED,
@@ -303,7 +303,7 @@ COMMAND STAFF
/datum/skills/SO
name = "Staff Officer"
skills = list(
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_LEADERSHIP = SKILL_LEAD_EXPERT,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
@@ -322,7 +322,7 @@ COMMAND STAFF
name = "Senior Enlisted Advisor"
skills = list(
SKILL_CQC = SKILL_CQC_SKILLED,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_FIREARMS = SKILL_FIREARMS_EXPERT,
SKILL_LEADERSHIP = SKILL_LEAD_EXPERT,
@@ -375,7 +375,7 @@ COMMAND STAFF
SKILL_JTAC = SKILL_JTAC_EXPERT,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_MELEE_WEAPONS = SKILL_MELEE_TRAINED,
SKILL_INTEL = SKILL_INTEL_TRAINED,
)
@@ -392,7 +392,7 @@ COMMAND STAFF
SKILL_JTAC = SKILL_JTAC_EXPERT,
SKILL_INTEL = SKILL_INTEL_EXPERT,
SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_POLICE = SKILL_POLICE_FLASH,
SKILL_NAVIGATIONS = SKILL_NAVIGATIONS_TRAINED,
diff --git a/code/datums/skills/wygoons.dm b/code/datums/skills/wygoons.dm
index 2d2c247bd1ea..73d8da15b976 100644
--- a/code/datums/skills/wygoons.dm
+++ b/code/datums/skills/wygoons.dm
@@ -18,7 +18,7 @@
SKILL_MELEE_WEAPONS = SKILL_MELEE_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
)
/datum/skills/wy_goon_lead
@@ -31,6 +31,6 @@
SKILL_MELEE_WEAPONS = SKILL_MELEE_TRAINED,
SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_LEADERSHIP = SKILL_LEAD_TRAINED,
)
diff --git a/code/datums/soundOutput.dm b/code/datums/soundOutput.dm
index 6ebc32c7e41f..cc7334d2cb98 100644
--- a/code/datums/soundOutput.dm
+++ b/code/datums/soundOutput.dm
@@ -52,10 +52,14 @@
S.y += T.y_s_offset
S.x += T.x_s_offset
S.echo = SOUND_ECHO_REVERB_ON //enable environment reverb for positional sounds
+ for(var/pos = 1 to length(T.echo))
+ if(!T.echo[pos])
+ continue
+ S.echo[pos] = T.echo[pos]
if(owner.mob.ear_deaf > 0)
S.status |= SOUND_MUTE
- sound_to(owner,S)
+ sound_to(owner, S)
/datum/soundOutput/proc/update_ambience(area/target_area, ambience_override, force_update = FALSE)
var/status_flags = SOUND_STREAM
diff --git a/code/datums/statistics/entities/round_stats.dm b/code/datums/statistics/entities/round_stats.dm
index 10ec04c6da0e..79493ca87ef0 100644
--- a/code/datums/statistics/entities/round_stats.dm
+++ b/code/datums/statistics/entities/round_stats.dm
@@ -393,6 +393,7 @@
return TRUE
/datum/action/show_round_statistics/action_activate()
+ . = ..()
if(!can_use_action())
return
diff --git a/code/datums/supply_packs/explosives.dm b/code/datums/supply_packs/explosives.dm
index 032ef047c78a..78f0f3e9251a 100644
--- a/code/datums/supply_packs/explosives.dm
+++ b/code/datums/supply_packs/explosives.dm
@@ -89,6 +89,18 @@
containername = "\improper explosive M40 HEDP grenades crate (WARNING)"
group = "Explosives"
+/datum/supply_packs/explosives_sebb
+ name = "G2 electroshock grenades crate (x6)"
+ contains = list(
+ /obj/item/storage/box/packet/sebb,
+ /obj/item/storage/box/packet/sebb,
+ )
+ cost = 30
+ containertype = /obj/structure/closet/crate/explosives
+ containername = "\improper G2 electroshock grenades crate (WARNING)"
+ group = "Explosives"
+
+
/datum/supply_packs/explosives_hedp
name = "M40 HEDP blast grenade box crate (x25)"
contains = list(
diff --git a/code/datums/supply_packs/weapons.dm b/code/datums/supply_packs/weapons.dm
index 8939b80e52d6..f7802089cbfe 100644
--- a/code/datums/supply_packs/weapons.dm
+++ b/code/datums/supply_packs/weapons.dm
@@ -1,13 +1,3 @@
-/datum/supply_packs/m56b_smartgun
- name = "M56B Smartgun System Package (x1)"
- contains = list(
- /obj/item/storage/box/m56_system,
- )
- cost = 100
- containertype = /obj/structure/closet/crate/weapon
- containername = "M56B Smartgun System Package"
- group = "Weapons"
-
/datum/supply_packs/m56_hmg
name = "M56D Heavy Machine Gun (x1)"
contains = list(
diff --git a/code/datums/tutorial/_tutorial.dm b/code/datums/tutorial/_tutorial.dm
index ddeddddd0407..b7403da3c0a9 100644
--- a/code/datums/tutorial/_tutorial.dm
+++ b/code/datums/tutorial/_tutorial.dm
@@ -4,7 +4,7 @@ GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial)
/datum/tutorial
/// What the tutorial is called, is player facing
var/name = "Base"
- /// Internal ID of the tutorial, kept for save files
+ /// Internal ID of the tutorial, kept for save files. Format is "tutorialtype_specifictutorial_number". So, the first basic xeno tutorial would be "xeno_basic_1", and the 2nd marine medical tutorial would be "marine_medical_2"
var/tutorial_id = "base"
/// A short 1-2 sentence description of the tutorial itself
var/desc = ""
@@ -144,6 +144,8 @@ GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial)
/// Ends the tutorial after a certain amount of time.
/datum/tutorial/proc/tutorial_end_in(time = 5 SECONDS, completed = TRUE)
+ if(completed)
+ mark_completed() // This is done because if you're calling this proc with completed == TRUE, then the tutorial's a done deal. We shouldn't penalize the player if they exit a few seconds before it actually completes.
tutorial_ending = TRUE
addtimer(CALLBACK(src, PROC_REF(end_tutorial), completed), time)
@@ -221,6 +223,7 @@ GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial)
tutorial = WEAKREF(selected_tutorial)
/datum/action/tutorial_end/action_activate()
+ . = ..()
if(!tutorial)
return
diff --git a/code/datums/tutorial/xenomorph/abomination.dm b/code/datums/tutorial/xenomorph/abomination.dm
new file mode 100644
index 000000000000..83ac86b8f09e
--- /dev/null
+++ b/code/datums/tutorial/xenomorph/abomination.dm
@@ -0,0 +1,256 @@
+/datum/tutorial/xenomorph/abomination
+ name = "Xenomorph - Predalien"
+ desc = "A tutorial to teach you how to play the \"Predalien\", also known as Abomination, xenomorph caste. Completing this is required to be able to play an Abomination."
+ icon_state = "predalien"
+ tutorial_id = "xeno_abom_1"
+ tutorial_template = /datum/map_template/tutorial/s7x7
+ starting_xenomorph_type = /mob/living/carbon/xenomorph/predalien/tutorial
+ /// How many marines in the kill_marines stage have been killed
+ var/ending_marines_killed = 0
+
+// START OF SCRITPING
+
+/datum/tutorial/xenomorph/abomination/start_tutorial(mob/starting_mob)
+ . = ..()
+ if(!.)
+ return
+
+ init_mob()
+ xeno.lock_evolve = TRUE
+
+ message_to_player("Welcome to the tutorial for the Abomination xenomorph. As an Abomination, you are a frontline powerhouse whose damage scales with your kill count.")
+ message_to_player("Your kill count scales when you kill humans with your slash attack, up to 10 kills. Ability kills do not count towards this.")
+
+ addtimer(CALLBACK(src, PROC_REF(how_to_be_abom)), 12 SECONDS)
+
+/datum/tutorial/xenomorph/abomination/proc/how_to_be_abom()
+ message_to_player("Be aware that you are kill-on-sight to all Predators forever, and will very likely need to defend yourself against multiple.")
+ message_to_player("Be sure to stick close to other xenomorphs or over-extend. While you may be stronger than many, you don't have enough health or armor to go out on your own.")
+ addtimer(CALLBACK(src, PROC_REF(feral_rush_tutorial)), 10.5 SECONDS)
+
+/datum/tutorial/xenomorph/abomination/proc/feral_rush_tutorial()
+ var/datum/action/rush = give_action(xeno, /datum/action/xeno_action/onclick/feralrush)
+ message_to_player("Your first unique ability is Feral Rush, an ability that temporarily increases your speed and your armor. Use Feral Rush to continue.")
+ update_objective("Use your Feral Rush ability.")
+ add_highlight(rush.button)
+ RegisterSignal(rush, COMSIG_XENO_ACTION_USED, PROC_REF(on_rush_used))
+
+/datum/tutorial/xenomorph/abomination/proc/on_rush_used(datum/action/source, mob/owner)
+ SIGNAL_HANDLER
+
+ UnregisterSignal(source, COMSIG_XENO_ACTION_USED)
+ remove_highlight(source.button)
+ addtimer(CALLBACK(src, PROC_REF(predalien_roar_tutorial_1)), 5 SECONDS)
+
+/datum/tutorial/xenomorph/abomination/proc/predalien_roar_tutorial_1()
+ hide_action(xeno, /datum/action/xeno_action/onclick/feralrush)
+ xeno.cannot_slash = TRUE
+ message_to_player("Your next ability is Roar, a versatile ability that disables any motion detectors or cloaks in a medium radius around you.")
+ message_to_player("Additionally, it gives a slash and speed bonus to any friendly xenomorphs in range.")
+ addtimer(CALLBACK(src, PROC_REF(predalien_roar_tutorial_2)), 8 SECONDS)
+
+/datum/tutorial/xenomorph/abomination/proc/predalien_roar_tutorial_2()
+ var/datum/action/roar = give_action(xeno, /datum/action/xeno_action/onclick/predalien_roar)
+ message_to_player("One of Roar's most useful abilities is uncloaking nearby Predators. Use Roar to uncloak the newly spawned Predator.")
+ update_objective("Use your Roar ability to uncloak the nearby predator.")
+ add_highlight(roar.button)
+ var/mob/living/carbon/human/pred = new(loc_from_corner(3, 3))
+ add_to_tracking_atoms(pred)
+ pred.create_hud()
+ arm_equipment(pred, /datum/equipment_preset/yautja/blooded)
+ var/obj/item/clothing/gloves/yautja/hunter/bracers = locate() in pred
+ if(!bracers)
+ message_to_player("Something has gone wrong. Please make a bug report.")
+ CRASH("predator spawned without bracers in tutorial")
+
+ bracers.cloaker_internal(pred, TRUE, TRUE, TRUE)
+ RegisterSignal(bracers, COMSIG_PRED_BRACER_DECLOAKED, PROC_REF(smash_tutorial_1))
+
+/datum/tutorial/xenomorph/abomination/proc/smash_tutorial_1(datum/source)
+ SIGNAL_HANDLER
+
+ var/datum/action/roar = get_action(xeno, /datum/action/xeno_action/onclick/predalien_roar)
+ remove_highlight(roar.button)
+ update_objective("")
+
+ UnregisterSignal(source, COMSIG_PRED_BRACER_DECLOAKED)
+ addtimer(CALLBACK(src, PROC_REF(smash_tutorial_2)), 2.5 SECONDS)
+
+/datum/tutorial/xenomorph/abomination/proc/smash_tutorial_2()
+ hide_action(xeno, /datum/action/xeno_action/onclick/predalien_roar)
+ message_to_player("Good. Roar will be one of your primary tools for defending against Predators. Your next ability is Feral Smash.")
+ xeno.cannot_slash = FALSE
+
+ TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, pred)
+ remove_from_tracking_atoms(pred)
+ qdel(pred)
+
+ addtimer(CALLBACK(src, PROC_REF(smash_tutorial_3)), 5 SECONDS)
+
+/datum/tutorial/xenomorph/abomination/proc/smash_tutorial_3()
+ var/datum/action/smash = give_action(xeno, /datum/action/xeno_action/activable/feral_smash)
+ RegisterSignal(smash, COMSIG_XENO_PRE_ACTION_USED, PROC_REF(frenzy_tutorial_1))
+ add_highlight(smash.button)
+
+ message_to_player("Feral Smash is a strong lunge with a range of five tiles. It deals decent damage that scales with your kill count.")
+ message_to_player("Use Feral Smash on the marine to continue.")
+ update_objective("Use your Feral Smash ability on the marine.")
+
+ xeno.forceMove(loc_from_corner(0, 2))
+ xeno.anchored = TRUE
+ ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_TUTORIAL)
+
+ var/mob/living/carbon/human/marine = new(loc_from_corner(4, 2))
+ add_to_tracking_atoms(marine)
+ arm_equipment(marine, /datum/equipment_preset/uscm/private_equipped)
+
+/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_1(datum/action/source, mob/owner)
+ SIGNAL_HANDLER
+
+ xeno.anchored = FALSE
+ REMOVE_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_TUTORIAL)
+ RegisterSignal(source, COMSIG_XENO_ACTION_USED, PROC_REF(frenzy_tutorial_2))
+ RegisterSignal(source, COMSIG_XENO_FAILED_ACTION_USED, PROC_REF(frenzy_tutorial_1_fail))
+
+/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_1_fail(datum/action/source, mob/owner)
+ SIGNAL_HANDLER
+
+ xeno.anchored = TRUE
+ ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_TUTORIAL)
+ UnregisterSignal(source, list(COMSIG_XENO_FAILED_ACTION_USED, COMSIG_XENO_ACTION_USED))
+
+/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_2(datum/action/source, mob/owner)
+ SIGNAL_HANDLER
+
+ if(get_turf(xeno) == loc_from_corner(0, 2)) // xeno didn't lunge at the mob
+ xeno.anchored = TRUE
+ UnregisterSignal(source, COMSIG_XENO_ACTION_USED)
+ ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_TUTORIAL)
+ return
+
+ update_objective("")
+ var/datum/action/smash = get_action(xeno, /datum/action/xeno_action/activable/feral_smash)
+ remove_highlight(smash.button)
+ UnregisterSignal(source, list(COMSIG_XENO_ACTION_USED, COMSIG_XENO_PRE_ACTION_USED))
+ addtimer(CALLBACK(src, PROC_REF(frenzy_tutorial_3)), 2 SECONDS)
+
+/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_3()
+ remove_action(xeno, /datum/action/xeno_action/activable/feral_smash)
+ message_to_player("Good. Your final ability is Feral Frenzy, a strong ability that can alternate between hitting a single target or all within a large radius. However, it locks you in place while it winds up.")
+
+ TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine)
+ remove_from_tracking_atoms(marine)
+ qdel(marine)
+
+ addtimer(CALLBACK(src, PROC_REF(frenzy_tutorial_4)), 6 SECONDS)
+
+/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_4()
+ var/mob/living/carbon/human/marine = new(loc_from_corner(4, 2))
+ add_to_tracking_atoms(marine)
+ RegisterSignal(marine, COMSIG_MOB_DEATH, PROC_REF(on_marine_early_death))
+ arm_equipment(marine, /datum/equipment_preset/uscm/private_equipped)
+
+ var/datum/action/frenzy = give_action(xeno, /datum/action/xeno_action/activable/feralfrenzy)
+ add_highlight(frenzy.button)
+ message_to_player("By default, Feral Frenzy is on single-target mode. Use Feral Frenzy on the newly spawned marine.")
+ update_objective("Use Feral Frenzy on the marine.")
+
+ RegisterSignal(frenzy, COMSIG_XENO_ACTION_USED, PROC_REF(frenzy_tutorial_5))
+
+/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_5(datum/action/xeno_action/source, mob/owner)
+ SIGNAL_HANDLER
+
+ TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine)
+ if(get_dist(marine, xeno) > 1)
+ return
+
+ UnregisterSignal(source, COMSIG_XENO_ACTION_USED)
+ var/datum/action/frenzy = get_action(xeno, /datum/action/xeno_action/activable/feralfrenzy)
+ remove_highlight(frenzy.button)
+ var/datum/action/frenzy_toggle = give_action(xeno, /datum/action/xeno_action/onclick/toggle_gut_targeting)
+ add_highlight(frenzy_toggle.button)
+ message_to_player("Good, now toggle Feral Frenzy's AOE mode with the newly available Toggle Gutting Type ability.")
+ update_objective("Use the Toggle Gutting Type ability to change your frenzy mode.")
+
+ RegisterSignal(frenzy_toggle, COMSIG_XENO_ACTION_USED, PROC_REF(frenzy_tutorial_6))
+
+/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_6(datum/action/xeno_action/source, mob/owner)
+ SIGNAL_HANDLER
+
+ UnregisterSignal(source, COMSIG_XENO_ACTION_USED)
+ remove_highlight(source.button)
+ source.plasma_cost = INFINITY // slightly scuffed way of disabling the switch button
+ source.update_button_icon()
+
+ message_to_player("Feral Frenzy has now been changed into AOE mode. Use Feral Frenzy again anywhere within 2 tiles of the marine.")
+ update_objective("Use Feral Frenzy within 2 tiles of the marine.")
+ TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine)
+ marine.rejuvenate()
+ var/datum/action/xeno_action/activable/feralfrenzy/frenzy = get_action(xeno, /datum/action/xeno_action/activable/feralfrenzy)
+ frenzy.targeting = AOETARGETGUT
+ frenzy.reduce_cooldown(frenzy.xeno_cooldown)
+ add_highlight(frenzy.button)
+
+ RegisterSignal(frenzy, COMSIG_XENO_ACTION_USED, PROC_REF(frenzy_tutorial_7))
+
+/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_7(datum/action/source)
+ SIGNAL_HANDLER
+
+ TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine)
+ var/datum/action/xeno_action/activable/feralfrenzy/frenzy = get_action(xeno, /datum/action/xeno_action/activable/feralfrenzy)
+ if(get_dist(xeno, marine) > frenzy.range)
+ // Not close enough to actually hit the marine
+ return
+
+ UnregisterSignal(frenzy, COMSIG_XENO_ACTION_USED)
+ UnregisterSignal(marine, COMSIG_MOB_DEATH)
+ remove_highlight(frenzy.button)
+ message_to_player("Good. As you may have noticed, the AOE version of Feral Frenzy takes longer to wind up, in addition to doing less overall damage.")
+ addtimer(CALLBACK(src, PROC_REF(kill_marines)), 6 SECONDS)
+
+/datum/tutorial/xenomorph/abomination/proc/kill_marines()
+ message_to_player("To finish the tutorial, kill the three newly-spawned marines using any of your attacks or abilities.")
+
+ // Spawn/rejuv the dummies
+ TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine) // we can reuse this one though
+ marine.rejuvenate()
+ marine.forceMove(loc_from_corner(4, 2))
+ RegisterSignal(marine, COMSIG_MOB_DEATH, PROC_REF(kill_marines_2))
+
+ var/mob/living/carbon/human/marine_2 = new(loc_from_corner(2, 2))
+ arm_equipment(marine_2, /datum/equipment_preset/uscm/private_equipped)
+ RegisterSignal(marine_2, COMSIG_MOB_DEATH, PROC_REF(kill_marines_2))
+
+ var/mob/living/carbon/human/marine_3 = new(loc_from_corner(0, 2))
+ arm_equipment(marine_3, /datum/equipment_preset/uscm/private_equipped)
+ RegisterSignal(marine_3, COMSIG_MOB_DEATH, PROC_REF(kill_marines_2))
+
+ // Arrange the actions about how they'd be in an actual game
+ remove_action(xeno, /datum/action/xeno_action/activable/feralfrenzy)
+ remove_action(xeno, /datum/action/xeno_action/onclick/toggle_gut_targeting)
+
+ give_action(xeno, /datum/action/xeno_action/activable/tail_stab)
+ give_action(xeno, /datum/action/xeno_action/onclick/feralrush)
+ give_action(xeno, /datum/action/xeno_action/onclick/predalien_roar)
+ give_action(xeno, /datum/action/xeno_action/activable/feral_smash)
+ give_action(xeno, /datum/action/xeno_action/activable/feralfrenzy)
+ give_action(xeno, /datum/action/xeno_action/onclick/toggle_gut_targeting)
+
+/datum/tutorial/xenomorph/abomination/proc/kill_marines_2(datum/source)
+ SIGNAL_HANDLER
+
+ if(ending_marines_killed < 2)
+ ending_marines_killed++
+ return
+
+ message_to_player("Good work. The tutorial will end shortly.")
+ tutorial_end_in(7 SECONDS, TRUE)
+
+// END OF SCRIPTING
+
+/// In case a marine dies early to prevent softlocks
+/datum/tutorial/xenomorph/abomination/proc/on_marine_early_death(datum/source)
+ SIGNAL_HANDLER
+
+ TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine)
+ marine.rejuvenate()
diff --git a/code/datums/xeno_shields/shield_types/vanguard_shield.dm b/code/datums/xeno_shields/shield_types/vanguard_shield.dm
index 21d9fb12cfd7..cd9e4534e778 100644
--- a/code/datums/xeno_shields/shield_types/vanguard_shield.dm
+++ b/code/datums/xeno_shields/shield_types/vanguard_shield.dm
@@ -42,7 +42,7 @@
return
linked_xeno.overlay_shields()
- var/datum/action/xeno_action/activable/cleave/cAction = get_xeno_action_by_type(linked_xeno, /datum/action/xeno_action/activable/cleave)
+ var/datum/action/xeno_action/activable/cleave/cAction = get_action(linked_xeno, /datum/action/xeno_action/activable/cleave)
if (istype(cAction))
addtimer(CALLBACK(cAction, TYPE_PROC_REF(/datum/action/xeno_action/activable/cleave, remove_buff)), 7, TIMER_UNIQUE)
diff --git a/code/game/area/almayer.dm b/code/game/area/almayer.dm
index b75baccd7353..a065a0b8671f 100644
--- a/code/game/area/almayer.dm
+++ b/code/game/area/almayer.dm
@@ -132,7 +132,7 @@
icon_state = "workshop"
/area/almayer/engineering/lower/workshop/hangar
- name = "\improper Ordnance workshop"
+ name = "\improper Ordnance Workshop"
/area/almayer/engineering/lower/engine_core
name = "\improper Engine Reactor Core Room"
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index be7037295497..db0702200d16 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -27,7 +27,6 @@
var/unique = TRUE
- var/has_gravity = 1
// 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
@@ -381,42 +380,6 @@
if(istype(M))
use_power(-M.calculate_current_power_usage(), M.power_channel)
-/area/proc/gravitychange(gravitystate = 0, area/A)
-
- A.has_gravity = gravitystate
-
- 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
- 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.
- return
-
- if(istype(M,/mob/living/carbon/human/)) // Only humans can wear magboots, so we give them a chance to.
- var/mob/living/carbon/human/H = M
- if((istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags_inventory & NOSLIPPING)))
- return
- H.adjust_effect(5, STUN)
- H.adjust_effect(5, WEAKEN)
-
- to_chat(M, "Gravity!")
-
-
-
-
//atmos related procs
/area/return_air()
diff --git a/code/game/area/space_station_13_areas.dm b/code/game/area/space_station_13_areas.dm
index df5e54a77013..6b3084ba8068 100644
--- a/code/game/area/space_station_13_areas.dm
+++ b/code/game/area/space_station_13_areas.dm
@@ -59,7 +59,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
requires_power = FALSE
static_lighting = FALSE
base_lighting_alpha = 255
- has_gravity = 1
// === end remove
@@ -72,7 +71,7 @@ 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
+ base_lighting_alpha = 255
/area/centcom/control
name = "\improper abandoned Centcom Control"
diff --git a/code/game/camera_manager/camera_manager.dm b/code/game/camera_manager/camera_manager.dm
index 9f111b0f8ec6..90e80ec7037e 100644
--- a/code/game/camera_manager/camera_manager.dm
+++ b/code/game/camera_manager/camera_manager.dm
@@ -6,7 +6,7 @@
/datum/component/camera_manager
var/map_name
var/obj/structure/machinery/camera/current
- var/datum/shape/rectangle/current_area
+ var/datum/shape/current_area
var/atom/movable/screen/map_view/cam_screen
var/atom/movable/screen/background/cam_background
var/list/range_turfs = list()
@@ -86,7 +86,7 @@
RegisterSignal(parent, COMSIG_CAMERA_UNREGISTER_UI, PROC_REF(unregister))
RegisterSignal(parent, COMSIG_CAMERA_SET_NVG, PROC_REF(enable_nvg))
RegisterSignal(parent, COMSIG_CAMERA_CLEAR_NVG, PROC_REF(disable_nvg))
- RegisterSignal(parent, COMSIG_CAMERA_SET_AREA, PROC_REF(set_camera_rect))
+ RegisterSignal(parent, COMSIG_CAMERA_SET_AREA, PROC_REF(set_camera_area))
RegisterSignal(parent, COMSIG_CAMERA_SET_TARGET, PROC_REF(set_camera))
RegisterSignal(parent, COMSIG_CAMERA_CLEAR, PROC_REF(clear_camera))
RegisterSignal(parent, COMSIG_CAMERA_REFRESH, PROC_REF(refresh_camera))
@@ -133,18 +133,18 @@
RegisterSignal(current, COMSIG_PARENT_QDELETING, PROC_REF(show_camera_static))
update_target_camera()
-/datum/component/camera_manager/proc/set_camera_rect(source, x, y, z, w, h)
+/datum/component/camera_manager/proc/set_camera_area(source, datum/shape/new_area, z)
SIGNAL_HANDLER
render_mode = RENDER_MODE_AREA
if(current)
UnregisterSignal(current, COMSIG_PARENT_QDELETING)
current = null
- current_area = RECT(x, y, w, h)
- target_x = x
- target_y = y
+ current_area = new_area
+ target_x = current_area.center_x
+ target_y = current_area.center_y
target_z = z
- target_width = w
- target_height = h
+ target_width = current_area.bounds_x
+ target_height = current_area.bounds_y
update_area_camera()
/datum/component/camera_manager/proc/enable_nvg(source, power, matrixcol)
@@ -221,8 +221,8 @@
// Cameras that get here are moving, and are likely attached to some moving atom such as cyborgs.
last_camera_turf = new_location
- var/x_size = current_area.width
- var/y_size = current_area.height
+ var/x_size = current_area.bounds_x
+ var/y_size = current_area.bounds_y
var/turf/target = locate(current_area.center_x, current_area.center_y, target_z)
var/list/visible_things = isXRay ? range("[x_size]x[y_size]", target) : view("[x_size]x[y_size]", target)
diff --git a/code/game/gamemodes/colonialmarines/whiskey_outpost/skills.dm b/code/game/gamemodes/colonialmarines/whiskey_outpost/skills.dm
index a5126627adaf..746e6ed53c18 100644
--- a/code/game/gamemodes/colonialmarines/whiskey_outpost/skills.dm
+++ b/code/game/gamemodes/colonialmarines/whiskey_outpost/skills.dm
@@ -35,7 +35,7 @@
/datum/skills/honor_guard/lead
name = "Honor Guard Squad Leader"
skills = list(
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI, //to fix CIC apc.
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED, //to fix CIC apc.
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
@@ -49,7 +49,7 @@
/datum/skills/mortar_crew
name = "Mortar Crew"
skills = list(
- SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
+ SKILL_ENGINEER = SKILL_ENGINEER_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_JTAC = SKILL_JTAC_BEGINNER,
SKILL_POWERLOADER = SKILL_POWERLOADER_MASTER,
diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm
index 0af315fc3b9d..640866db8ca2 100644
--- a/code/game/jobs/job/job.dm
+++ b/code/game/jobs/job/job.dm
@@ -155,7 +155,7 @@
if(!gear_preset)
return ""
if(GLOB.gear_path_presets_list[gear_preset])
- return GLOB.gear_path_presets_list[gear_preset].paygrade
+ return GLOB.gear_path_presets_list[gear_preset].paygrades[1]
return ""
/datum/job/proc/get_comm_title()
diff --git a/code/game/jobs/job/marine/squad_info.dm b/code/game/jobs/job/marine/squad_info.dm
index 37db48c3116e..406263115196 100644
--- a/code/game/jobs/job/marine/squad_info.dm
+++ b/code/game/jobs/job/marine/squad_info.dm
@@ -146,7 +146,7 @@
if(skillcheck(H, SKILL_MEDICAL, SKILL_MEDICAL_TRAINED))
Med = TRUE
else
- if(skillcheck(H, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
+ if(skillcheck(H, SKILL_ENGINEER, SKILL_ENGINEER_NOVICE))
Eng = TRUE
ID = H.get_idcard()
squad_info_data["fireteams"][team]["tl"] = list(
@@ -223,7 +223,7 @@
if(skillcheck(H, SKILL_MEDICAL, SKILL_MEDICAL_TRAINED))
Med = TRUE
else
- if(skillcheck(H, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
+ if(skillcheck(H, SKILL_ENGINEER, SKILL_ENGINEER_NOVICE))
Eng = TRUE
mar[H.real_name] = list(
"name" = H.real_name,
@@ -270,7 +270,7 @@
if(skillcheck(H, SKILL_MEDICAL, SKILL_MEDICAL_TRAINED))
Med = TRUE
else
- if(skillcheck(H, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
+ if(skillcheck(H, SKILL_ENGINEER, SKILL_ENGINEER_NOVICE))
Eng = TRUE
mar[H.real_name] = list(
"name" = H.real_name,
diff --git a/code/game/machinery/air_sensor.dm b/code/game/machinery/air_sensor.dm
deleted file mode 100644
index 55963bae979a..000000000000
--- a/code/game/machinery/air_sensor.dm
+++ /dev/null
@@ -1,64 +0,0 @@
-/obj/structure/machinery/air_sensor
- icon = 'icons/obj/structures/props/stationobjs.dmi'
- icon_state = "gsensor1"
- name = "Gas Sensor"
-
- anchored = TRUE
- var/state = 0
-
- var/id_tag
- var/frequency = 1439
-
- var/on = 1
- var/output = 3
- //Flags:
- // 1 for pressure
- // 2 for temperature
- // Output >= 4 includes gas composition
- // 4 for oxygen concentration
- // 8 for phoron concentration
- // 16 for nitrogen concentration
- // 32 for carbon dioxide concentration
-
- var/datum/radio_frequency/radio_connection
-
-/obj/structure/machinery/air_sensor/update_icon()
- icon_state = "gsensor[on]"
-
-/obj/structure/machinery/air_sensor/process()
- if(on)
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.data["tag"] = id_tag
- signal.data["timestamp"] = world.time
-
- var/turf/T = loc
- var/pressure_ = T.return_pressure()
- var/temperature_ = T.return_temperature()
-
- if(output&1)
- signal.data["pressure"] = num2text(round(pressure_,0.1),)
- if(output&2)
- signal.data["temperature"] = round(temperature_,0.1)
-
- if(output>4)
- signal.data["oxygen"] = 0
- signal.data["phoron"] = 0
- signal.data["nitrogen"] = 0
- signal.data["carbon_dioxide"] = 0
- signal.data["sigtype"]="status"
- radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
-
-
-/obj/structure/machinery/air_sensor/proc/set_frequency(new_frequency)
- SSradio.remove_object(src, frequency)
- frequency = new_frequency
- radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
-
-/obj/structure/machinery/air_sensor/Initialize()
- . = ..()
- set_frequency(frequency)
-
-/obj/structure/machinery/air_sensor/Destroy()
- SSradio.remove_object(src, frequency)
- return ..()
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 4150aead979e..4013aec3fb29 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -224,7 +224,7 @@
if("cutwire")
if(!panel_open)
return FALSE
- if(!skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(usr, SPAN_WARNING("You don't understand anything about this wiring..."))
return FALSE
var/obj/item/held_item = usr.get_held_item()
@@ -238,7 +238,7 @@
if("fixwire")
if(!panel_open)
return FALSE
- if(!skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(usr, SPAN_WARNING("You don't understand anything about this wiring..."))
return FALSE
var/obj/item/held_item = usr.get_held_item()
@@ -251,7 +251,7 @@
if("pulsewire")
if(!panel_open)
return FALSE
- if(!skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(usr, SPAN_WARNING("You don't understand anything about this wiring..."))
return FALSE
var/obj/item/held_item = usr.get_held_item()
@@ -269,7 +269,7 @@
/obj/structure/machinery/autolathe/attackby(obj/item/O as obj, mob/user as mob)
if(HAS_TRAIT(O, TRAIT_TOOL_SCREWDRIVER))
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You are not trained to dismantle machines..."))
return
panel_open = !panel_open
@@ -586,7 +586,7 @@
stored_material = list("metal" = 56250, "plastic" = 20000) //15 metal and 10 plastic sheets
/obj/structure/machinery/autolathe/armylathe/attack_hand(mob/user)
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You have no idea how to operate the [name]."))
return FALSE
. = ..()
diff --git a/code/game/machinery/autolathe_datums.dm b/code/game/machinery/autolathe_datums.dm
index 78a8e46b64aa..9c8ee271845d 100644
--- a/code/game/machinery/autolathe_datums.dm
+++ b/code/game/machinery/autolathe_datums.dm
@@ -136,11 +136,6 @@
path = /obj/item/circuitboard/apc
category = AUTOLATHE_CATEGORY_ENGINEERING
-/datum/autolathe/recipe/rcd_ammo
- name = "matter cartridge"
- path = /obj/item/ammo_rcd
- category = AUTOLATHE_CATEGORY_ENGINEERING
-
/datum/autolathe/recipe/table_parts
name = "table parts"
path = /obj/item/frame/table
diff --git a/code/game/machinery/bio-dome_floodlights.dm b/code/game/machinery/bio-dome_floodlights.dm
deleted file mode 100644
index e23dbcc023f4..000000000000
--- a/code/game/machinery/bio-dome_floodlights.dm
+++ /dev/null
@@ -1,169 +0,0 @@
-/obj/structure/machinery/hydro_floodlight_switch
- name = "Biodome Floodlight Switch"
- icon = 'icons/obj/structures/machinery/power.dmi'
- icon_state = "panelnopower"
- desc = "This switch controls the floodlights surrounding the archaeology complex. It only functions when there is power."
- density = FALSE
- anchored = TRUE
- var/ispowered = FALSE
- var/turned_on = 0 //has to be toggled in engineering
- use_power = USE_POWER_IDLE
- unslashable = TRUE
- unacidable = TRUE
- var/list/floodlist = list() // This will save our list of floodlights on the map
-
-/obj/structure/machinery/hydro_floodlight_switch/Initialize(mapload, ...)
- . = ..()
- for(var/obj/structure/machinery/hydro_floodlight/F in GLOB.machines)
- floodlist += F
- F.fswitch = src
- start_processing()
-
-/obj/structure/machinery/hydro_floodlight_switch/Destroy()
- for(var/obj/structure/machinery/hydro_floodlight/floodlight as anything in floodlist)
- floodlight.fswitch = null
- floodlist = null
- return ..()
-
-
-/obj/structure/machinery/hydro_floodlight_switch/process()
- var/lightpower = 0
- for(var/obj/structure/machinery/hydro_floodlight/H in floodlist)
- if(!H.is_lit)
- continue
- lightpower += H.power_tick
- use_power(lightpower)
-
-/obj/structure/machinery/hydro_floodlight_switch/update_icon()
- if(!ispowered)
- icon_state = "panelnopower"
- else if(turned_on)
- icon_state = "panelon"
- else
- icon_state = "paneloff"
-
-/obj/structure/machinery/hydro_floodlight_switch/power_change()
- ..()
- if((stat & NOPOWER))
- if(ispowered && turned_on)
- toggle_lights()
- ispowered = FALSE
- turned_on = 0
- update_icon()
- else
- ispowered = TRUE
- update_icon()
-
-/obj/structure/machinery/hydro_floodlight_switch/proc/toggle_lights()
- for(var/obj/structure/machinery/hydro_floodlight/F in floodlist)
- if(!istype(F) || QDELETED(F) || F.damaged) continue //Missing or damaged, skip it
-
- spawn(rand(0,50))
- if(F.is_lit) //Shut it down
- F.set_light(0)
- else
- F.set_light(F.lum_value)
- F.is_lit = !(F.is_lit)
- F.update_icon()
- return 0
-
-/obj/structure/machinery/hydro_floodlight_switch/attack_hand(mob/user as mob)
- if(!ishuman(user))
- to_chat(user, "Nice try.")
- return 0
- if(!ispowered)
- to_chat(user, "Nothing happens.")
- return 0
- playsound(src,'sound/machines/click.ogg', 15, 1)
- use_power(5)
- toggle_lights()
- turned_on = !(src.turned_on)
- update_icon()
- return 1
-
-/obj/structure/machinery/hydro_floodlight
- name = "Biodome Floodlight"
- icon = 'icons/obj/structures/machinery/big_floodlight.dmi'
- icon_state = "flood_s_off"
- density = TRUE
- anchored = TRUE
- layer = WINDOW_LAYER
- var/damaged = 0 //Can be smashed by xenos
- var/is_lit = 0
- unslashable = TRUE
- unacidable = TRUE
- var/power_tick = 800 // power each floodlight takes up per process
- use_power = USE_POWER_NONE //It's the switch that uses the actual power, not the lights
- var/obj/structure/machinery/hydro_floodlight_switch/fswitch = null //Reverse lookup for power grabbing in area
- var/lum_value = 7
-
-/obj/structure/machinery/hydro_floodlight/Destroy()
- if(fswitch?.floodlist)
- fswitch.floodlist -= src
- fswitch = null
- return ..()
-
-/obj/structure/machinery/hydro_floodlight/update_icon()
- if(damaged)
- icon_state = "flood_s_dmg"
- else if(is_lit)
- icon_state = "flood_s_on"
- else
- icon_state = "flood_s_off"
-
-/obj/structure/machinery/hydro_floodlight/attackby(obj/item/W as obj, mob/user as mob)
- var/obj/item/tool/weldingtool/WT = W
- if(istype(WT))
- if(!damaged) return
- if(!HAS_TRAIT(WT, TRAIT_TOOL_BLOWTORCH))
- to_chat(user, SPAN_WARNING("You need a stronger blowtorch!"))
- return
- if(WT.remove_fuel(0, user))
- playsound(src.loc, 'sound/items/weldingtool_weld.ogg', 25)
- user.visible_message(SPAN_NOTICE("[user] starts welding [src]'s damage."), \
- SPAN_NOTICE("You start welding [src]'s damage."))
- if(do_after(user, 200 * user.get_skill_duration_multiplier(SKILL_ENGINEER), INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
- playsound(get_turf(src), 'sound/items/Welder2.ogg', 25, 1)
- if(!src || !WT.isOn()) return
- damaged = 0
- user.visible_message(SPAN_NOTICE("[user] finishes welding [src]'s damage."), \
- SPAN_NOTICE("You finish welding [src]'s damage."))
- if(is_lit)
- set_light(lum_value)
- update_icon()
- return 1
- else
- to_chat(user, SPAN_WARNING("You need more welding fuel to complete this task."))
- return 0
- ..()
- return 0
-
-/obj/structure/machinery/hydro_floodlight/attack_hand(mob/user as mob)
- if(ishuman(user))
- to_chat(user, SPAN_WARNING("Nothing happens. Looks like it's powered elsewhere."))
- return 0
- else if(!is_lit)
- to_chat(user, SPAN_WARNING("Why bother? It's just some weird metal thing."))
- return 0
- else
- if(damaged)
- to_chat(user, SPAN_WARNING("It's already damaged."))
- return 0
- else
- if(islarva(user))
- return //Larvae can't do shit
- if(user.get_active_hand())
- to_chat(user, SPAN_WARNING("You need your claws empty for this!"))
- return FALSE
- user.visible_message(SPAN_DANGER("[user] starts to slash and claw away at [src]!"),
- SPAN_DANGER("You start slashing and clawing at [src]!"))
- if(do_after(user, 50, INTERRUPT_ALL, BUSY_ICON_HOSTILE) && !damaged) //Not when it's already damaged.
- if(!src) return 0
- damaged = 1
- 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)
- update_icon()
- return 0
- ..()
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 4f6b40968bdb..3b7d824928df 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -263,9 +263,11 @@ GLOBAL_LIST_EMPTY_TYPED(all_cameras, /obj/structure/machinery/camera)
//Return a working camera that can see a given mob
//or null if none
/proc/seen_by_camera(mob/M)
- for(var/obj/structure/machinery/camera/C in oview(4, M))
+ FOR_DOVIEW(var/obj/structure/machinery/camera/C, 4, M, HIDE_INVISIBLE_OBSERVER)
if(C.can_use()) // check if camera disabled
+ FOR_DOVIEW_END
return C
+ FOR_DOVIEW_END
return null
/proc/near_range_camera(mob/M)
diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm
index a1d7f00cf94a..f8ce33eb9911 100644
--- a/code/game/machinery/camera/presets.dm
+++ b/code/game/machinery/camera/presets.dm
@@ -99,6 +99,10 @@
name = "ares core camera"
network = list(CAMERA_NET_ARES)
+/obj/structure/machinery/camera/autoname/almayer/brig
+ name = "brig camera"
+ network = list(CAMERA_NET_BRIG)
+
//used by the landing camera dropship equipment. Do not place them right under where the dropship lands.
//Should place them near each corner of your LZs.
/obj/structure/machinery/camera/autoname/lz_camera
diff --git a/code/game/machinery/colony_floodlights.dm b/code/game/machinery/colony_floodlights.dm
index 0267c7e95487..e8f59ad643d7 100644
--- a/code/game/machinery/colony_floodlights.dm
+++ b/code/game/machinery/colony_floodlights.dm
@@ -125,7 +125,7 @@
/obj/structure/machinery/colony_floodlight/attackby(obj/item/I, mob/user)
if(damaged)
if(HAS_TRAIT(I, TRAIT_TOOL_SCREWDRIVER))
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You have no clue how to repair [src]."))
return FALSE
@@ -160,7 +160,7 @@
return TRUE
else if(HAS_TRAIT(I, TRAIT_TOOL_CROWBAR))
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You have no clue how to repair [src]."))
return FALSE
@@ -183,7 +183,7 @@
return
var/obj/item/tool/weldingtool/welder = I
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You have no clue how to repair [src]."))
return FALSE
@@ -206,7 +206,7 @@
else if(iscoil(I))
var/obj/item/stack/cable_coil/coil = I
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You have no clue how to repair [src]."))
return FALSE
@@ -228,7 +228,7 @@
return TRUE
else if(istype(I, /obj/item/device/lightreplacer))
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You have no clue how to repair [src]."))
return FALSE
@@ -271,7 +271,7 @@
if(ishuman(user))
if(damaged)
. += SPAN_WARNING("It is damaged.")
- if(skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
switch(repair_state)
if(FLOODLIGHT_REPAIR_UNSCREW) . += SPAN_INFO("You must first unscrew its maintenance hatch.")
if(FLOODLIGHT_REPAIR_CROWBAR) . += SPAN_INFO("You must crowbar its lighting assembly out or use a light replacer.")
diff --git a/code/game/machinery/computer/almayer_control.dm b/code/game/machinery/computer/almayer_control.dm
index 3d3c0fdbe4df..e9c9cf91a816 100644
--- a/code/game/machinery/computer/almayer_control.dm
+++ b/code/game/machinery/computer/almayer_control.dm
@@ -184,7 +184,7 @@
to_chat(user, SPAN_WARNING("Arrays are re-cycling. Please stand by."))
return FALSE
var/input = stripped_input(user, "Please choose a message to transmit to USCM. Please be aware that this process is very expensive, and abuse will lead to termination. Transmission does not guarantee a response. There is a small delay before you may send another message. Be clear and concise.", "To abort, send an empty message.", "")
- if(!input || !(user in view(1,src)) || !COOLDOWN_FINISHED(src, cooldown_central))
+ if(!input || !(user in dview(1, src)) || !COOLDOWN_FINISHED(src, cooldown_central))
return FALSE
high_command_announce(input, user)
@@ -211,7 +211,7 @@
to_chat(user, SPAN_WARNING("Please allow at least [COOLDOWN_TIMELEFT(src, cooldown_message)/10] second\s to pass between announcements."))
return FALSE
var/input = stripped_multiline_input(user, "Please write a message to announce to the station crew.", "Priority Announcement", "")
- if(!input || !COOLDOWN_FINISHED(src, cooldown_message) || !(user in view(1,src)))
+ if(!input || !COOLDOWN_FINISHED(src, cooldown_message) || !(user in dview(1, src)))
return FALSE
var/signed = null
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index ff8f3959d64e..4f6f4df4ef08 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -123,7 +123,7 @@
src.temp = "[src.enemy_name] has fallen! Rejoice!"
if(!length(contents))
- var/prizeselect = pickweight(prizes)
+ var/prizeselect = pick_weight(prizes)
new prizeselect(src.loc)
if(istype(prizeselect, /obj/item/toy/gun)) //Ammo comes with the gun
@@ -176,5 +176,5 @@
if(2)
num_of_prizes = rand(0,2)
for(num_of_prizes; num_of_prizes > 0; num_of_prizes--)
- empprize = pickweight(prizes)
+ empprize = pick_weight(prizes)
new empprize(src.loc)
diff --git a/code/game/machinery/computer/camera_console.dm b/code/game/machinery/computer/camera_console.dm
index c818df9fbfb9..e549436669de 100644
--- a/code/game/machinery/computer/camera_console.dm
+++ b/code/game/machinery/computer/camera_console.dm
@@ -352,6 +352,10 @@
/obj/structure/machinery/computer/cameras/almayer_network/vehicle
network = list(CAMERA_NET_ALMAYER, CAMERA_NET_VEHICLE)
+/obj/structure/machinery/computer/cameras/almayer_brig
+ name = "Brig Cameras Console"
+ network = list(CAMERA_NET_BRIG)
+
/obj/structure/machinery/computer/cameras/mortar
name = "Mortar Camera Interface"
alpha = 0
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 2e6922e43a85..8d3f78cb1857 100644
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -134,7 +134,7 @@
to_chat(usr, SPAN_WARNING("Please allow at least [COOLDOWN_COMM_MESSAGE_LONG*0.1] second\s to pass between announcements."))
return FALSE
var/input = stripped_multiline_input(usr, "Please write a message to announce to the station crew.", "Priority Announcement", "")
- if(!input || authenticated != 2 || world.time < cooldown_message + COOLDOWN_COMM_MESSAGE_LONG || !(usr in view(1,src)))
+ if(!input || authenticated != 2 || world.time < cooldown_message + COOLDOWN_COMM_MESSAGE_LONG || !(usr in dview(1, src)))
return FALSE
marine_announcement(input)
@@ -302,7 +302,7 @@
to_chat(usr, SPAN_WARNING("Arrays recycling. Please stand by."))
return FALSE
var/input = stripped_input(usr, "Please choose a message to transmit to USCM. Please be aware that this process is very expensive, and abuse will lead to termination. Transmission does not guarantee a response. There is a small delay before you may send another message. Be clear and concise.", "To abort, send an empty message.", "")
- if(!input || !(usr in view(1,src)) || authenticated != 2 || world.time < cooldown_central + COOLDOWN_COMM_CENTRAL) return FALSE
+ if(!input || !(usr in dview(1, src)) || authenticated != 2 || world.time < cooldown_central + COOLDOWN_COMM_CENTRAL) return FALSE
high_command_announce(input, usr)
to_chat(usr, SPAN_NOTICE("Message transmitted."))
diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm
index bfa64ab174ed..bb434e8ca114 100644
--- a/code/game/machinery/computer/computer.dm
+++ b/code/game/machinery/computer/computer.dm
@@ -99,7 +99,7 @@
if(!deconstructible)
to_chat(user, SPAN_WARNING("You can't figure out how to deconstruct [src]..."))
return
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You don't know how to deconstruct [src]..."))
return
playsound(src.loc, 'sound/items/Screwdriver.ogg', 25, 1)
diff --git a/code/game/machinery/computer/demo_sim.dm b/code/game/machinery/computer/demo_sim.dm
index f633e8f351d4..2b2ca9fda775 100644
--- a/code/game/machinery/computer/demo_sim.dm
+++ b/code/game/machinery/computer/demo_sim.dm
@@ -11,7 +11,7 @@
/obj/structure/machinery/computer/demo_sim/attackby(obj/item/B, mob/living/user)
if(inoperable())
return
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You don't know how to configure [src]."))
return
if(configuration)
diff --git a/code/game/machinery/computer/dropship_weapons.dm b/code/game/machinery/computer/dropship_weapons.dm
index e07b415ed233..7f8f4f2b3850 100644
--- a/code/game/machinery/computer/dropship_weapons.dm
+++ b/code/game/machinery/computer/dropship_weapons.dm
@@ -313,9 +313,8 @@
var/obj/structure/machinery/defenses/sentry/defense = sentry.deployed_turret
if(defense.has_camera)
defense.set_range()
- var/datum/shape/rectangle/current_bb = defense.range_bounds
camera_area_equipment = sentry
- SEND_SIGNAL(src, COMSIG_CAMERA_SET_AREA, current_bb.center_x, current_bb.center_y, defense.loc.z, current_bb.width, current_bb.height)
+ SEND_SIGNAL(src, COMSIG_CAMERA_SET_AREA, defense.range_bounds, defense.loc.z)
return TRUE
if("clear-camera")
diff --git a/code/game/machinery/computer/groundside_operations.dm b/code/game/machinery/computer/groundside_operations.dm
index 591c63a76bee..376357a49174 100644
--- a/code/game/machinery/computer/groundside_operations.dm
+++ b/code/game/machinery/computer/groundside_operations.dm
@@ -235,7 +235,7 @@
to_chat(usr, SPAN_WARNING("Access denied."))
return
var/input = stripped_multiline_input(usr, "Please write a message to announce to the station crew.", "Priority Announcement", "")
- if(!input || !is_announcement_active || !(usr in view(1,src)))
+ if(!input || !is_announcement_active || !(usr in dview(1, src)))
return FALSE
is_announcement_active = FALSE
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index 40b23667636f..ac6de251ab45 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -93,8 +93,12 @@
if ((istype(src.active2, /datum/data/record) && GLOB.data_core.medical.Find(src.active2)))
dat += "
\n
Medical Data
\nBlood Type: [active2.fields["b_type"]]
\n
\nMinor Disabilities: [active2.fields["mi_dis"]]
\nDetails: [active2.fields["mi_dis_d"]]
\n
\nMajor Disabilities: [active2.fields["ma_dis"]]
\nDetails: [active2.fields["ma_dis_d"]]
\n
\nAllergies: [active2.fields["alg"]]
\nDetails: [active2.fields["alg_d"]]
\n
\nCurrent Diseases: [active2.fields["cdi"]] (per disease info placed in log/comment section)
\nDetails: [active2.fields["cdi_d"]]
\n
\nImportant Notes:
\n\t[decode(src.active2.fields["notes"])]
\n
\nComments/Log
"
var/counter = 1
- while(src.active2.fields[text("com_[]", counter)])
- dat += text("[]
Delete Entry
", src.active2.fields[text("com_[]", counter)], src, counter)
+ while(active2.fields[text("com_[]", counter)])
+ var/current_index = text("com_[]", counter)
+ if(findtext(active2.fields[current_index], "
"))
+ dat += text("[]
Delete Entry
", active2.fields[current_index], src, counter)
+ else
+ dat += text("[]
", active2.fields[current_index])
counter++
dat += text("Add Entry
", src)
dat += text("Delete Record (Medical Only)
", src)
@@ -209,142 +213,156 @@
GLOB.data_core.medical -= R
qdel(R)
//Foreach goto(494)
- src.temp = "All records deleted."
+ temp = "All records deleted."
+ msg_admin_niche("[key_name_admin(usr)] deleted all medical records.")
if (href_list["field"])
- var/a1 = src.active1
- var/a2 = src.active2
+ var/a1 = active1
+ var/a2 = active2
switch(href_list["field"])
if("sex")
- if (istype(src.active1, /datum/data/record))
- if (src.active1.fields["sex"] == "Male")
- src.active1.fields["sex"] = "Female"
- else
- src.active1.fields["sex"] = "Male"
+ if (istype(active1, /datum/data/record))
+ var/new_value = "Male"
+ if (active1.fields["sex"] == "Male")
+ new_value = "Female"
+ active1.fields["sex"] = new_value
+ msg_admin_niche("[key_name_admin(usr)] set the medical record sex for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
if("age")
- if (istype(src.active1, /datum/data/record))
- var/t1 = input("Please input age:", "Med. records", src.active1.fields["age"], null) as num
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || src.active1 != a1))
+ if (istype(active1, /datum/data/record))
+ var/new_value = input("Please input age:", "Med. records", active1.fields["age"], null) as num
+ if ((!( new_value ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active1 != a1))
return
- src.active1.fields["age"] = t1
+ active1.fields["age"] = new_value
+ msg_admin_niche("[key_name_admin(usr)] set the medical record age for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
if("mi_dis")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(trim(strip_html(input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text)),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/new_value = copytext(trim(strip_html(input("Please input minor disabilities list:", "Med. records", active2.fields["mi_dis"], null) as text)),1,MAX_MESSAGE_LEN)
+ if ((!( new_value ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active2 != a2))
return
- src.active2.fields["mi_dis"] = t1
+ active2.fields["mi_dis"] = new_value
+ msg_admin_niche("[key_name_admin(usr)] set the medical record minor disabilities list for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
if("mi_dis_d")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(trim(strip_html(input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message)),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/new_value = copytext(trim(strip_html(input("Please summarize minor dis.:", "Med. records", active2.fields["mi_dis_d"], null) as message)),1,MAX_MESSAGE_LEN)
+ if ((!( new_value ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active2 != a2))
return
- src.active2.fields["mi_dis_d"] = t1
+ active2.fields["mi_dis_d"] = new_value
+ msg_admin_niche("[key_name_admin(usr)] set the medical record minor disabilities desc for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
if("ma_dis")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(trim(strip_html(input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text)),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/new_value = copytext(trim(strip_html(input("Please input major diabilities list:", "Med. records", active2.fields["ma_dis"], null) as text)),1,MAX_MESSAGE_LEN)
+ if ((!( new_value ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active2 != a2))
return
- src.active2.fields["ma_dis"] = t1
+ active2.fields["ma_dis"] = new_value
+ msg_admin_niche("[key_name_admin(usr)] set the medical record major disabilities list for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
if("ma_dis_d")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(trim(strip_html(input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message)),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/new_value = copytext(trim(strip_html(input("Please summarize major dis.:", "Med. records", active2.fields["ma_dis_d"], null) as message)),1,MAX_MESSAGE_LEN)
+ if ((!( new_value ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active2 != a2))
return
- src.active2.fields["ma_dis_d"] = t1
+ active2.fields["ma_dis_d"] = new_value
+ msg_admin_niche("[key_name_admin(usr)] set the medical record major disabilities desc for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
if("alg")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(trim(strip_html(input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text)),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/new_value = copytext(trim(strip_html(input("Please state allergies:", "Med. records", active2.fields["alg"], null) as text)),1,MAX_MESSAGE_LEN)
+ if ((!( new_value ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active2 != a2))
return
- src.active2.fields["alg"] = t1
+ active2.fields["alg"] = new_value
+ msg_admin_niche("[key_name_admin(usr)] set the medical record allergies list for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
if("alg_d")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(trim(strip_html(input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message)),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/new_value = copytext(trim(strip_html(input("Please summarize allergies:", "Med. records", active2.fields["alg_d"], null) as message)),1,MAX_MESSAGE_LEN)
+ if ((!( new_value ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active2 != a2))
return
- src.active2.fields["alg_d"] = t1
+ active2.fields["alg_d"] = new_value
+ msg_admin_niche("[key_name_admin(usr)] set the medical record allergies desc for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
if("cdi")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(trim(strip_html(input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text)),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/new_value = copytext(trim(strip_html(input("Please state diseases:", "Med. records", active2.fields["cdi"], null) as text)),1,MAX_MESSAGE_LEN)
+ if ((!( new_value ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active2 != a2))
return
- src.active2.fields["cdi"] = t1
+ active2.fields["cdi"] = new_value
+ msg_admin_niche("[key_name_admin(usr)] set the medical record disabilities list for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
if("cdi_d")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(trim(strip_html(input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message)),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/new_value = copytext(trim(strip_html(input("Please summarize diseases:", "Med. records", active2.fields["cdi_d"], null) as message)),1,MAX_MESSAGE_LEN)
+ if ((!( new_value ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active2 != a2))
return
- src.active2.fields["cdi_d"] = t1
+ active2.fields["cdi_d"] = new_value
+ msg_admin_niche("[key_name_admin(usr)] set the medical record disabilities desc for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
if("notes")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(html_encode(trim(input("Please summarize notes:", "Med. records", html_decode(src.active2.fields["notes"]), null) as message)),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/new_value = copytext(html_encode(trim(input("Please summarize notes:", "Med. records", html_decode(active2.fields["notes"]), null) as message)),1,MAX_MESSAGE_LEN)
+ if ((!( new_value ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active2 != a2))
return
- src.active2.fields["notes"] = t1
+ active2.fields["notes"] = new_value
+ msg_admin_niche("[key_name_admin(usr)] set the medical record notes for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
if("p_stat")
- if (istype(src.active1, /datum/data/record))
- src.temp = text("Physical Condition:
\n\t*Deceased*
\n\t*SSD*
\n\tActive
\n\tPhysically Unfit
\n\tDisabled
", src, src, src, src, src)
+ if (istype(active1, /datum/data/record))
+ temp = text("Physical Condition:
\n\t*Deceased*
\n\t*SSD*
\n\tActive
\n\tPhysically Unfit
\n\tDisabled
", src, src, src, src, src)
if("m_stat")
- if (istype(src.active1, /datum/data/record))
- src.temp = text("Mental Condition:
\n\t*Insane*
\n\t*Unstable*
\n\t*Watch*
\n\tStable
", src, src, src, src)
+ if (istype(active1, /datum/data/record))
+ temp = text("Mental Condition:
\n\t*Insane*
\n\t*Unstable*
\n\t*Watch*
\n\tStable
", src, src, src, src)
if("b_type")
- if (istype(src.active2, /datum/data/record))
- src.temp = text("Blood Type:
\n\tA- A+
\n\tB- B+
\n\tAB- AB+
\n\tO- O+
", src, src, src, src, src, src, src, src)
+ if (istype(active2, /datum/data/record))
+ temp = text("Blood Type:
\n\tA- A+
\n\tB- B+
\n\tAB- AB+
\n\tO- O+
", src, src, src, src, src, src, src, src)
if (href_list["p_stat"])
- if (src.active1)
+ if(istype(active1, /datum/data/record))
switch(href_list["p_stat"])
if("deceased")
- src.active1.fields["p_stat"] = "*Deceased*"
+ active1.fields["p_stat"] = "*Deceased*"
if("ssd")
- src.active1.fields["p_stat"] = "*SSD*"
+ active1.fields["p_stat"] = "*SSD*"
if("active")
- src.active1.fields["p_stat"] = "Active"
+ active1.fields["p_stat"] = "Active"
if("unfit")
- src.active1.fields["p_stat"] = "Physically Unfit"
+ active1.fields["p_stat"] = "Physically Unfit"
if("disabled")
- src.active1.fields["p_stat"] = "Disabled"
+ active1.fields["p_stat"] = "Disabled"
+ msg_admin_niche("[key_name_admin(usr)] set the medical record physical state for [active1.fields["name"]] ([active1.fields["id"]]) to [href_list["p_stat"]].")
if (href_list["m_stat"])
- if (src.active1)
+ if(istype(active1, /datum/data/record))
switch(href_list["m_stat"])
if("insane")
- src.active1.fields["m_stat"] = "*Insane*"
+ active1.fields["m_stat"] = "*Insane*"
if("unstable")
- src.active1.fields["m_stat"] = "*Unstable*"
+ active1.fields["m_stat"] = "*Unstable*"
if("watch")
- src.active1.fields["m_stat"] = "*Watch*"
+ active1.fields["m_stat"] = "*Watch*"
if("stable")
- src.active1.fields["m_stat"] = "Stable"
-
+ active1.fields["m_stat"] = "Stable"
+ msg_admin_niche("[key_name_admin(usr)] set the medical record mental state for [active1.fields["name"]] ([active1.fields["id"]]) to [href_list["m_stat"]].")
if (href_list["b_type"])
- if (src.active2)
+ if(istype(active2, /datum/data/record))
switch(href_list["b_type"])
if("an")
- src.active2.fields["b_type"] = "A-"
+ active2.fields["b_type"] = "A-"
if("bn")
- src.active2.fields["b_type"] = "B-"
+ active2.fields["b_type"] = "B-"
if("abn")
- src.active2.fields["b_type"] = "AB-"
+ active2.fields["b_type"] = "AB-"
if("on")
- src.active2.fields["b_type"] = "O-"
+ active2.fields["b_type"] = "O-"
if("ap")
- src.active2.fields["b_type"] = "A+"
+ active2.fields["b_type"] = "A+"
if("bp")
- src.active2.fields["b_type"] = "B+"
+ active2.fields["b_type"] = "B+"
if("abp")
- src.active2.fields["b_type"] = "AB+"
+ active2.fields["b_type"] = "AB+"
if("op")
- src.active2.fields["b_type"] = "O+"
-
+ active2.fields["b_type"] = "O+"
+ msg_admin_niche("[key_name_admin(usr)] set the medical record blood type for [active1.fields["name"]] ([active1.fields["id"]]) to [active2.fields["b_type"]].")
if (href_list["del_r"])
- if (active2)
- src.temp = text("Are you sure you wish to delete the record (Medical Portion Only)?
\n\tYes
\n\tNo
", src, src)
+ if(istype(active2, /datum/data/record))
+ temp = text("Are you sure you wish to delete the record (Medical Portion Only)?
\n\tYes
\n\tNo
", src, src)
if (href_list["del_r2"])
+ msg_admin_niche("[key_name_admin(usr)] deleted the medical record for [active1.fields["name"]] ([active1.fields["id"]]).")
QDEL_NULL(active2)
if (href_list["d_rec"])
@@ -381,20 +399,22 @@
src.screen = 4
if (href_list["add_c"])
- if (!( istype(src.active2, /datum/data/record) ))
+ if (!( istype(active2, /datum/data/record) ))
return
- var/a2 = src.active2
- var/t1 = copytext(trim(strip_html(input("Add Comment:", "Med. records", null, null) as message)),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || src.active2 != a2))
+ var/a2 = active2
+ var/new_value = copytext(trim(strip_html(input("Add Comment:", "Med. records", null, null) as message)),1,MAX_MESSAGE_LEN)
+ if ((!( new_value ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active2 != a2))
return
var/counter = 1
- while(src.active2.fields[text("com_[]", counter)])
+ while(active2.fields[text("com_[]", counter)])
counter++
- src.active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [GLOB.game_year]
[t1]")
+ active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [GLOB.game_year]
[new_value]")
+ msg_admin_niche("[key_name_admin(usr)] added a medical comment for [active1.fields["name"]] ([active1.fields["id"]]): [new_value].")
if (href_list["del_c"])
- if ((istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])]))
- src.active2.fields[text("com_[]", href_list["del_c"])] = "Deleted"
+ if ((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])]))
+ msg_admin_niche("[key_name_admin(usr)] deleted a medical comment for [active1.fields["name"]] ([active1.fields["id"]]): [active2.fields[text("com_[]", href_list["del_c"])]].")
+ active2.fields[text("com_[]", href_list["del_c"])] = text("Deleted entry by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [GLOB.game_year]")
if (href_list["search"])
var/t1 = stripped_input(usr, "Search String: (Name, DNA, or ID)", "Med. records")
@@ -442,7 +462,7 @@
else
P.info += "Medical Record Lost!
"
P.info += ""
- P.info += text("
This report was printed by [] [].
The [MAIN_SHIP_NAME],[]/[], []
\n",last_user_rank,last_user_name,time2text(world.timeofday, "MM/DD"),GLOB.game_year,worldtime2text())
+ P.info += text("
This report was printed by [] [].
The [MAIN_SHIP_NAME],[]/[], []
\n",rank,authenticated,time2text(world.timeofday, "MM/DD"),GLOB.game_year,worldtime2text())
src.printing = null
if(href_list["print_bs"])//Prints latest body scan
@@ -465,7 +485,7 @@
break
else
P.info += "No scan on record."
- P.info += text("
This report was printed by [] [].
The [MAIN_SHIP_NAME], []/[], []
\n",last_user_rank,last_user_name,time2text(world.timeofday, "MM/DD"),GLOB.game_year,worldtime2text())
+ P.info += text("
This report was printed by [] [].
The [MAIN_SHIP_NAME], []/[], []
\n",rank,authenticated,time2text(world.timeofday, "MM/DD"),GLOB.game_year,worldtime2text())
src.printing = null
@@ -483,20 +503,27 @@
if(prob(10/severity))
switch(rand(1,6))
if(1)
+ msg_admin_niche("The medical record name of [R.fields["name"]] was scrambled!")
R.fields["name"] = "[pick(pick(GLOB.first_names_male), pick(GLOB.first_names_female))] [pick(GLOB.last_names)]"
if(2)
R.fields["sex"] = pick("Male", "Female")
+ msg_admin_niche("The medical record sex of [R.fields["name"]] was scrambled!")
if(3)
R.fields["age"] = rand(5, 85)
+ msg_admin_niche("The medical record age of [R.fields["name"]] was scrambled!")
if(4)
R.fields["b_type"] = pick("A-", "B-", "AB-", "O-", "A+", "B+", "AB+", "O+")
+ msg_admin_niche("The medical record blood type of [R.fields["name"]] was scrambled!")
if(5)
R.fields["p_stat"] = pick("*SSD*", "Active", "Physically Unfit", "Disabled")
+ msg_admin_niche("The medical record physical state of [R.fields["name"]] was scrambled!")
if(6)
R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
+ msg_admin_niche("The medical record mental state of [R.fields["name"]] was scrambled!")
continue
else if(prob(1))
+ msg_admin_niche("The medical record of [R.fields["name"]] was lost!")
GLOB.data_core.medical -= R
qdel(R)
continue
diff --git a/code/game/machinery/computer/research.dm b/code/game/machinery/computer/research.dm
index b51da245844e..de4d3edf927c 100644
--- a/code/game/machinery/computer/research.dm
+++ b/code/game/machinery/computer/research.dm
@@ -59,36 +59,24 @@
GLOB.chemical_data.update_credits(cred.credit_value)
visible_message(SPAN_NOTICE("[user] inserts [cred] in [src], collecting [cred.credit_value] points from sales."))
qdel(cred)
- //Clearance Updating
+ //Clearance Card Updating
if(!istype(B, /obj/item/card/id))
return
var/obj/item/card/id/silver/clearance_badge/card = B
if(!istype(card))
- visible_message(SPAN_NOTICE("[user] swipes their ID card on \the [src], but it is refused."))
+ visible_message(SPAN_NOTICE("[user] swipes their ID card on [src], but it is refused."))
return
- if(card.clearance_access <= GLOB.chemical_data.clearance_level || (card.clearance_access == 6 && GLOB.chemical_data.clearance_level >= 5 && GLOB.chemical_data.clearance_x_access))
- visible_message(SPAN_NOTICE("[user] swipes the clearance card on [src], but nothing happens."))
+ if(!card.check_biometrics(user))
+ visible_message(SPAN_WARNING("WARNING: ILLEGAL CLEARANCE USER DETECTED. ABORTING."))
return
- if(user.real_name != card.registered_name)
- visible_message(SPAN_WARNING("WARNING: ILLEGAL CLEARANCE USER DETECTED. CARD DATA HAS BEEN WIPED."))
- card.clearance_access = 0
- return
-
- var/give_level
- var/give_x = FALSE
- if(card.clearance_access == 6)
- give_level = 5
- give_x = TRUE
- else
- give_level = card.clearance_access
- GLOB.chemical_data.clearance_level = give_level
- if(give_x)
- GLOB.chemical_data.clearance_x_access = TRUE
- GLOB.chemical_data.reached_x_access = TRUE
+ var/credits_to_add = max(card.credits_to_give - GLOB.chemical_data.credits_gained, 0)
+ if(credits_to_add)
+ GLOB.chemical_data.update_credits(credits_to_add)
+ GLOB.chemical_data.credits_gained += credits_to_add
- visible_message(SPAN_NOTICE("[user] swipes their ID card on \the [src], updating the clearance to level [give_level][give_x ? "X" : ""]."))
- msg_admin_niche("[key_name(user)] has updated the research clearance to level [give_level][give_x ? "X" : ""].")
+ visible_message(SPAN_NOTICE("[user] swipes their ID card on [src], granting [credits_to_add] credits."))
+ msg_admin_niche("[key_name(user)] has swiped a clearance card to give [credits_to_add] credits to research.")
return
/obj/structure/machinery/computer/research/ui_state(mob/user)
@@ -181,30 +169,6 @@
if(5)
new /obj/item/paper/research_notes/unique/tier_five/(photocopier.loc)
max_clearance = 5
- if("purchase_document")
- if(!photocopier)
- return
- var/purchase_tier = floor(text2num(params["purchase_document"]))
- if(purchase_tier <= 0 || purchase_tier > 5)
- return
- if(purchase_tier > GLOB.chemical_data.clearance_level)
- return
- var/purchase_cost = base_purchase_cost + purchase_tier * 2
- if(purchase_cost <= GLOB.chemical_data.rsc_credits)
- GLOB.chemical_data.update_credits(purchase_cost * -1)
- var/obj/item/paper/research_notes/unique/N
- switch(purchase_tier)
- if(1)
- N = new /obj/item/paper/research_notes/unique/tier_one/(photocopier.loc)
- if(2)
- N = new /obj/item/paper/research_notes/unique/tier_two/(photocopier.loc)
- if(3)
- N = new /obj/item/paper/research_notes/unique/tier_three/(photocopier.loc)
- if(4)
- N = new /obj/item/paper/research_notes/unique/tier_four/(photocopier.loc)
- else
- N = new /obj/item/paper/research_notes/unique/tier_five/(photocopier.loc)
- visible_message(SPAN_NOTICE("Research report for [N.data.name] has been purchased."))
if("publish_document")
var/print_type = params["print_type"]
var/print_title = params["print_title"]
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index b3892de24413..ae6ddc3d411e 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -355,16 +355,17 @@ What a mess.*/
GLOB.data_core.security -= R
qdel(R)
temp = "All Security records deleted."
+ msg_admin_niche("[key_name_admin(usr)] deleted all security records.")
if ("Add Entry")
if (!(istype(active2, /datum/data/record)))
return
var/a2 = active2
- var/t1 = copytext(trim(strip_html(input("Your name and time will be added to this new comment.", "Add a comment", null, null) as message)),1,MAX_MESSAGE_LEN)
- if((!t1 || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isSilicon(usr))) || active2 != a2))
+ var/new_value = copytext(trim(strip_html(input("Your name and time will be added to this new comment.", "Add a comment", null, null) as message)),1,MAX_MESSAGE_LEN)
+ if((!new_value || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isSilicon(usr))) || active2 != a2))
return
var/created_at = text("[] [] []", time2text(world.realtime, "MMM DD"), time2text(world.time, "[worldtime2text()]:ss"), GLOB.game_year)
- var/new_comment = list("entry" = t1, "created_by" = list("name" = "", "rank" = ""), "deleted_by" = null, "deleted_at" = null, "created_at" = created_at)
+ var/new_comment = list("entry" = new_value, "created_by" = list("name" = "", "rank" = ""), "deleted_by" = null, "deleted_at" = null, "created_at" = created_at)
if(istype(usr,/mob/living/carbon/human))
var/mob/living/carbon/human/U = usr
new_comment["created_by"] = list("name" = U.get_authentification_name(), "rank" = U.get_assignment())
@@ -374,6 +375,7 @@ What a mess.*/
var/new_com_i = length(active2.fields["comments"]) + 1
active2.fields["comments"]["[new_com_i]"] = new_comment
to_chat(usr, text("You have added a new comment to the Security Record of [].", active2.fields["name"]))
+ msg_admin_niche("[key_name_admin(usr)] added a security comment for [active1.fields["name"]] ([active1.fields["id"]]): [new_value].")
if ("Delete Entry")
if(!islist(active2.fields["comments"]))
@@ -406,23 +408,28 @@ What a mess.*/
switch(href_list["field"])
if("name")
if (istype(active1, /datum/data/record))
- var/t1 = reject_bad_name(input(usr, "Please input name:", "Secure. records", active1.fields["name"]) as text|null)
- if (!t1 || active1 != a1)
+ var/new_value = reject_bad_name(input(usr, "Please input name:", "Secure. records", active1.fields["name"]) as text|null)
+ if (!new_value || active1 != a1)
return
- message_admins("[key_name(usr)] has changed the record name of [active1.fields["name"]] to [t1]")
- active1.fields["name"] = t1
+ message_admins("[key_name(usr)] changed the security record name of [active1.fields["name"]] to [new_value]")
+ active1.fields["name"] = new_value
+
if("sex")
if (istype(active1, /datum/data/record))
+ var/new_value = "Male"
if (active1.fields["sex"] == "Male")
- active1.fields["sex"] = "Female"
- else
- active1.fields["sex"] = "Male"
+ new_value = "Female"
+ active1.fields["sex"] = new_value
+ msg_admin_niche("[key_name(usr)] changed the security record sex of [active1.fields["name"]] to [new_value]")
+
if("age")
if (istype(active1, /datum/data/record))
- var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num
- if (!t1 || active1 != a1)
+ var/new_value = input("Please input age:", "Secure. records", active1.fields["age"], null) as num
+ if (!new_value || active1 != a1)
return
- active1.fields["age"] = t1
+ active1.fields["age"] = new_value
+ msg_admin_niche("[key_name(usr)] changed the security record age of [active1.fields["name"]] to [new_value]")
+
if("criminal")
if (istype(active2, /datum/data/record))
temp = "Criminal Status:
"
@@ -434,22 +441,25 @@ What a mess.*/
temp += "Suspect"
temp += "NJP"
temp += ""
+
if("rank")
//This was so silly before the change. Now it actually works without beating your head against the keyboard. /N
if (istype(active1, /datum/data/record) && GLOB.uscm_highcom_paygrades.Find(rank))
temp = "Occupation:
"
temp += ""
for(var/rank in GLOB.joblist)
- temp += "- [rank]
"
+ temp += "- [rank]
"
temp += "
"
else
alert(usr, "You do not have the required rank to do this!")
+
if("species")
if (istype(active1, /datum/data/record))
- var/t1 = copytext(trim(strip_html(input("Please enter race:", "General records", active1.fields["species"], null) as message)),1,MAX_MESSAGE_LEN)
- if (!t1 || active1 != a1)
+ var/new_value = copytext(trim(strip_html(input("Please enter race:", "General records", active1.fields["species"], null) as message)),1,MAX_MESSAGE_LEN)
+ if (!new_value || active1 != a1)
return
- active1.fields["species"] = t1
+ active1.fields["species"] = new_value
+ msg_admin_niche("[key_name(usr)] changed the security record species of [active1.fields["name"]] to [new_value]")
//TEMPORARY MENU FUNCTIONS
@@ -457,14 +467,17 @@ What a mess.*/
temp=null
switch(href_list["choice"])
if ("Change Rank")
- if (active1)
- active1.fields["rank"] = href_list["rank"]
- if(href_list["rank"] in GLOB.joblist)
- active1.fields["real_rank"] = href_list["real_rank"]
+ if(istype(active1, /datum/data/record) && GLOB.uscm_highcom_paygrades.Find(rank))
+ var/new_value = href_list["rank"]
+ active1.fields["rank"] = new_value
+ if(new_value in GLOB.joblist)
+ active1.fields["real_rank"] = new_value
+ message_admins("[key_name(usr)] changed the security record sex of [active1.fields["name"]] to [new_value]")
if ("Change Criminal Status")
- if (active2)
- switch(href_list["criminal2"])
+ if(istype(active2, /datum/data/record))
+ var/new_value = href_list["criminal2"]
+ switch(new_value)
if("none")
active2.fields["criminal"] = "None"
if("arrest")
@@ -481,6 +494,8 @@ What a mess.*/
for(var/mob/living/carbon/human/H in GLOB.human_mob_list)
H.sec_hud_set_security_status()
+ message_admins("[key_name(usr)] changed the security record criminal status of [active1.fields["name"]] to [new_value]")
+
add_fingerprint(usr)
updateUsrDialog()
return
@@ -521,20 +536,27 @@ What a mess.*/
if(prob(10/severity))
switch(rand(1,6))
if(1)
+ msg_admin_niche("The security record name of [R.fields["name"]] was scrambled!")
R.fields["name"] = "[pick(pick(GLOB.first_names_male), pick(GLOB.first_names_female))] [pick(GLOB.last_names)]"
if(2)
R.fields["sex"] = pick("Male", "Female")
+ msg_admin_niche("The security record sex of [R.fields["name"]] was scrambled!")
if(3)
R.fields["age"] = rand(5, 85)
+ msg_admin_niche("The security record age of [R.fields["name"]] was scrambled!")
if(4)
R.fields["criminal"] = pick("None", "*Arrest*", "Incarcerated", "Released", "Suspect", "NJP")
+ msg_admin_niche("The security record criminal status of [R.fields["name"]] was scrambled!")
if(5)
R.fields["p_stat"] = pick("*Unconscious*", "Active", "Physically Unfit")
+ msg_admin_niche("The security record physical state of [R.fields["name"]] was scrambled!")
if(6)
R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
+ msg_admin_niche("The security record mental state of [R.fields["name"]] was scrambled!")
continue
else if(prob(1))
+ msg_admin_niche("The security record of [R.fields["name"]] was lost!")
GLOB.data_core.security -= R
qdel(R)
continue
diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm
index cba8d50791f9..d0ace4d4dfb5 100644
--- a/code/game/machinery/computer/skills.dm
+++ b/code/game/machinery/computer/skills.dm
@@ -259,9 +259,10 @@ What a mess.*/
GLOB.data_core.security -= R
qdel(R)
temp = "All Employment records deleted."
+ msg_admin_niche("[key_name_admin(usr)] deleted all employment records.")
if ("Delete Record (ALL)")
- if (active1)
+ if(istype(active1, /datum/data/record))
temp = "Are you sure you wish to delete the record (ALL)?
"
temp += "Yes
"
temp += "No"
@@ -275,63 +276,75 @@ What a mess.*/
switch(href_list["field"])
if("name")
if (istype(active1, /datum/data/record))
- var/t1 = reject_bad_name(input("Please input name:", "Secure. records", active1.fields["name"], null) as text)
- if ((!( t1 ) || !length(trim(t1)) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr)))) || active1 != a1)
+ var/new_value = reject_bad_name(input("Please input name:", "Secure. records", active1.fields["name"], null) as text)
+ if ((!( new_value ) || !length(trim(new_value)) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr)))) || active1 != a1)
return
- message_admins("[key_name(usr)] has changed the record name of [active1.fields["name"]] to [t1]")
- active1.fields["name"] = t1
+ message_admins("[key_name(usr)] changed the employment record name of [active1.fields["name"]] to [new_value]")
+ active1.fields["name"] = new_value
+
if("id")
if (istype(active1, /datum/data/record))
- var/t1 = copytext(trim(sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text)),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active1 != a1))
+ var/new_value = copytext(trim(sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text)),1,MAX_MESSAGE_LEN)
+ if ((!( new_value ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active1 != a1))
return
- active1.fields["id"] = t1
+ msg_admin_niche("[key_name_admin(usr)] changed the employment record id for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
+ active1.fields["id"] = new_value
if("sex")
if (istype(active1, /datum/data/record))
+ var/new_value = "Male"
if (active1.fields["sex"] == "Male")
- active1.fields["sex"] = "Female"
- else
- active1.fields["sex"] = "Male"
+ new_value = "Female"
+ active1.fields["sex"] = new_value
+ msg_admin_niche("[key_name_admin(usr)] changed the employment record sex for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
+
if("age")
if (istype(active1, /datum/data/record))
- var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num
- if ((!( t1 ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active1 != a1))
+ var/new_value = input("Please input age:", "Secure. records", active1.fields["age"], null) as num
+ if ((!( new_value ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active1 != a1))
return
- active1.fields["age"] = t1
+ active1.fields["age"] = new_value
+ msg_admin_niche("[key_name_admin(usr)] changed the employment record age for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
+
if("rank")
+ if(istype(active1, /datum/data/record))
//This was so silly before the change. Now it actually works without beating your head against the keyboard. /N
- if(istype(active1, /datum/data/record) && GLOB.uscm_highcom_paygrades.Find(rank))
- temp = "Occupation:
"
- temp += ""
- for(var/rank in GLOB.joblist)
- temp += "- [rank]
"
- temp += "
"
- else
- alert(usr, "You do not have the required rank to do this!")
+ if(GLOB.uscm_highcom_paygrades.Find(rank))
+ temp = "Occupation:
"
+ temp += ""
+ for(var/rank in GLOB.joblist)
+ temp += "- [rank]
"
+ temp += "
"
+ else
+ alert(usr, "You do not have the required rank to do this!")
+
if("species")
if (istype(active1, /datum/data/record))
- var/t1 = copytext(trim(sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message)),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active1 != a1))
+ var/new_value = copytext(trim(sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message)),1,MAX_MESSAGE_LEN)
+ if ((!( new_value ) || !( authenticated ) || usr.stat || usr.is_mob_restrained() || (!in_range(src, usr) && (!isRemoteControlling(usr))) || active1 != a1))
return
- active1.fields["species"] = t1
+ active1.fields["species"] = new_value
+ msg_admin_niche("[key_name_admin(usr)] changed the employment record species for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
//TEMPORARY MENU FUNCTIONS
else//To properly clear as per clear screen.
temp=null
switch(href_list["choice"])
if ("Change Rank")
- if (active1)
- active1.fields["rank"] = href_list["rank"]
- if(href_list["rank"] in GLOB.joblist)
- active1.fields["real_rank"] = href_list["real_rank"]
+ if(istype(active1, /datum/data/record) && GLOB.uscm_highcom_paygrades.Find(rank))
+ var/new_value = href_list["rank"]
+ active1.fields["rank"] = new_value
+ if(new_value in GLOB.joblist)
+ active1.fields["real_rank"] = new_value
+ message_admins("[key_name_admin(usr)] changed the employment record rank for [active1.fields["name"]] ([active1.fields["id"]]) to [new_value].")
if ("Delete Record (ALL) Execute")
- if (active1)
+ if(istype(active1, /datum/data/record))
for(var/datum/data/record/R as anything in GLOB.data_core.medical)
if ((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"]))
GLOB.data_core.medical -= R
qdel(R)
+ msg_admin_niche("[key_name_admin(usr)] deleted all employment records for [active1.fields["name"]] ([active1.fields["id"]]).")
QDEL_NULL(active1)
else
temp = "This function does not appear to be working at the moment. Our apologies."
@@ -349,20 +362,27 @@ What a mess.*/
if(prob(10/severity))
switch(rand(1,6))
if(1)
+ msg_admin_niche("The employment record name of [R.fields["name"]] was scrambled!")
R.fields["name"] = "[pick(pick(GLOB.first_names_male), pick(GLOB.first_names_female))] [pick(GLOB.last_names)]"
if(2)
R.fields["sex"] = pick("Male", "Female")
+ msg_admin_niche("The employment record sex of [R.fields["name"]] was scrambled!")
if(3)
R.fields["age"] = rand(5, 85)
+ msg_admin_niche("The employment record age of [R.fields["name"]] was scrambled!")
if(4)
R.fields["criminal"] = pick("None", "*Arrest*", "Incarcerated", "Released")
+ msg_admin_niche("The employment record criminal status of [R.fields["name"]] was scrambled!")
if(5)
R.fields["p_stat"] = pick("*Unconscious*", "Active", "Physically Unfit")
+ msg_admin_niche("The employment record physical state of [R.fields["name"]] was scrambled!")
if(6)
R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
+ msg_admin_niche("The employment record mental state of [R.fields["name"]] was scrambled!")
continue
else if(prob(1))
+ msg_admin_niche("The employment record of [R.fields["name"]] was lost!")
GLOB.data_core.security -= R
qdel(R)
continue
diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index 0c8cc62c3f87..3b7880320da7 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -15,7 +15,7 @@
var/list/req_component_names = null
var/state = CONSTRUCTION_STATE_BEGIN
var/required_skill = SKILL_CONSTRUCTION_ENGI
- var/required_dismantle_skill = SKILL_ENGINEER_ENGI
+ var/required_dismantle_skill = SKILL_ENGINEER_TRAINED
/obj/structure/machinery/constructable_frame/Initialize(mapload, ...)
. = ..()
diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm
index 3f5e78dfc39f..266a58f62023 100644
--- a/code/game/machinery/door_control.dm
+++ b/code/game/machinery/door_control.dm
@@ -61,6 +61,9 @@
var/obj/docking_port/mobile/marine_dropship/shuttle = SSshuttle.getShuttle(ship_id)
if (!istype(shuttle))
return
+ var/obj/structure/machinery/computer/shuttle/dropship/flight/comp = shuttle.getControlConsole()
+ if(comp?.dropship_control_lost)
+ return
if(is_mainship_level(z)) // on the almayer
return
diff --git a/code/game/machinery/door_display/door_display.dm b/code/game/machinery/door_display/door_display.dm
index 4624ba5f1bd2..529ac6f95959 100644
--- a/code/game/machinery/door_display/door_display.dm
+++ b/code/game/machinery/door_display/door_display.dm
@@ -203,7 +203,7 @@
if(F.id == id)
targets += F
if(has_wall_divider)
- for(var/turf/closed/wall/almayer/research/containment/wall/divide/W in orange(src, 8))
+ for(var/turf/closed/wall/almayer/research/containment/wall/divide/W in ORANGE_TURFS(8, src))
targets += W
/obj/structure/machinery/door_display/research_cell/Destroy()
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 84f02f0a5bbd..9ac9765371f3 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -439,7 +439,7 @@ GLOBAL_LIST_INIT(airlock_wire_descriptions, list(
return
if(panel_open)
- if(ishuman(usr) && !skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(ishuman(usr) && !skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(usr, SPAN_WARNING("You look into \the [src]'s access panel and can only see a jumbled mess of colored wires..."))
return FALSE
@@ -483,7 +483,7 @@ GLOBAL_LIST_INIT(airlock_wire_descriptions, list(
add_fingerprint(usr)
if((in_range(src, usr) && istype(loc, /turf)) && panel_open)
- if(ishuman(usr) && !skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(ishuman(usr) && !skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(usr, SPAN_WARNING("You don't understand anything about [src]'s wiring!"))
return FALSE
@@ -649,7 +649,7 @@ GLOBAL_LIST_INIT(airlock_wire_descriptions, list(
else if(attacking_item.pry_capable)
if(attacking_item.pry_capable == IS_PRY_CAPABLE_CROWBAR && panel_open && welded)
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You don't seem to know how to deconstruct machines."))
return
playsound(loc, 'sound/items/Crowbar.ogg', 25, 1)
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 27bb58397956..9ca1fb064568 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -87,10 +87,7 @@
return located_turfs
/obj/structure/machinery/door/proc/borders_space()
- for(var/turf/target in range(1, src))
- if(istype(target, /turf/open/space))
- return TRUE
- return FALSE
+ return !!(locate(/turf/open/space) in range(1, src))
/obj/structure/machinery/door/Collided(atom/movable/AM)
if(panel_open || operating)
diff --git a/code/game/machinery/doors/multi_tile.dm b/code/game/machinery/doors/multi_tile.dm
index f95ef09e812f..6e7f571a0d4e 100644
--- a/code/game/machinery/doors/multi_tile.dm
+++ b/code/game/machinery/doors/multi_tile.dm
@@ -262,14 +262,14 @@
var/datum/door_controller/single/control = linked_dropship.door_control.door_controllers[direction]
if (control.status != SHUTTLE_DOOR_BROKEN)
return ..()
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI) && !skillcheck(user, SKILL_PILOT, SKILL_PILOT_TRAINED))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED) && !skillcheck(user, SKILL_PILOT, SKILL_PILOT_TRAINED))
to_chat(user, SPAN_WARNING("You don't seem to understand how to restore a remote connection to [src]."))
return
if(user.action_busy)
return
to_chat(user, SPAN_WARNING("You begin to restore the remote connection to [src]."))
- if(!do_after(user, (skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI) ? 5 SECONDS : 8 SECONDS), INTERRUPT_ALL, BUSY_ICON_BUILD))
+ if(!do_after(user, (skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED) ? 5 SECONDS : 8 SECONDS), INTERRUPT_ALL, BUSY_ICON_BUILD))
to_chat(user, SPAN_WARNING("You fail to restore a remote connection to [src]."))
return
unlock(TRUE)
diff --git a/code/game/machinery/fusion_engine.dm b/code/game/machinery/fusion_engine.dm
index 72f836717b0f..06ae3321a2c5 100644
--- a/code/game/machinery/fusion_engine.dm
+++ b/code/game/machinery/fusion_engine.dm
@@ -140,7 +140,7 @@
if(overloaded)
. += SPAN_INFO("It is overloaded.")
return
- if(skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
. += SPAN_INFO("You could overload its safeties with a multitool.")
/obj/structure/machinery/power/reactor/power_change()
@@ -344,7 +344,7 @@
if(!is_ship_reactor)
return
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
return
to_chat(user, SPAN_WARNING("You start [overloaded ? "overloading" : "restoring"] the safeties on [src]."))
@@ -446,7 +446,7 @@
var/repair_time = 20 SECONDS
repair_time *= user.get_skill_duration_multiplier(SKILL_ENGINEER)
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
repair_time += 5 SECONDS
to_chat(user, SPAN_NOTICE("You start repairing [src] with [tool]."))
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
deleted file mode 100644
index fe8243704a72..000000000000
--- a/code/game/machinery/hologram.dm
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Holograms!
- * Contains:
- * Hologram
- * Holopad
- * Other stuff
- */
-
-
-
-/*
- * Hologram
- */
-
-/obj/structure/machinery/hologram
- anchored = TRUE
- use_power = USE_POWER_IDLE
- idle_power_usage = 5
- active_power_usage = 100
- var/obj/effect/overlay/hologram //The projection itself. If there is one, the instrument is on, off otherwise.
-
-/obj/structure/machinery/hologram/ex_act(severity)
- switch(severity)
- if(0 to EXPLOSION_THRESHOLD_LOW)
- if (prob(5))
- qdel(src)
- if(EXPLOSION_THRESHOLD_LOW to EXPLOSION_THRESHOLD_MEDIUM)
- if (prob(50))
- qdel(src)
- if(EXPLOSION_THRESHOLD_MEDIUM to INFINITY)
- qdel(src)
-
-/obj/structure/machinery/hologram/Destroy()
- if(hologram)
- clear_holo()
- return ..()
-
-/obj/structure/machinery/hologram/proc/clear_holo()
- if(hologram)
- qdel(hologram)
- hologram = null
-
-
-
-/*
- * Holopad
- */
-
-/obj/structure/machinery/hologram/holopad
- name = "\improper AI holopad"
- desc = "It's a floor-mounted device for projecting holographic images. It is activated remotely."
- icon_state = "holopad0"
-
- layer = TURF_LAYER+0.1 //Preventing mice and drones from sneaking under them.
-/*
- * Other Stuff: Is this even used?
- */
-/obj/structure/machinery/hologram/projector
- name = "hologram projector"
- desc = "It makes a hologram appear...with magnets or something..."
- icon = 'icons/obj/structures/props/stationobjs.dmi'
- icon_state = "holopad0"
diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm
index b71fb51a49de..9e6a2198962e 100644
--- a/code/game/machinery/kitchen/gibber.dm
+++ b/code/game/machinery/kitchen/gibber.dm
@@ -20,37 +20,6 @@
if (PF)
PF.flags_can_pass_all = PASS_HIGH_OVER_ONLY|PASS_AROUND|PASS_OVER_THROW_ITEM
-//auto-gibs anything that bumps into it
-/obj/structure/machinery/gibber/autogibber
- var/turf/input_plate
-
-/obj/structure/machinery/gibber/autogibber/New()
- ..()
- spawn(5)
- for(var/i in GLOB.cardinals)
- var/obj/structure/machinery/mineral/input/input_obj = locate( /obj/structure/machinery/mineral/input, get_step(loc, i) )
- if(input_obj)
- if(isturf(input_obj.loc))
- input_plate = input_obj.loc
- qdel(input_obj)
- break
-
- if(!input_plate)
- log_misc("a [src] didn't find an input plate.")
- return
-
-/obj/structure/machinery/gibber/autogibber/Collided(atom/A)
- if(!input_plate) return
-
- if(ismob(A))
- var/mob/M = A
-
- if(M.loc == input_plate
- )
- M.forceMove(src)
- M.gib()
-
-
/obj/structure/machinery/gibber/New()
..()
overlays += image('icons/obj/structures/machinery/kitchen.dmi', "grjam")
diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm
index 774153316baa..957f6c97eca3 100644
--- a/code/game/machinery/kitchen/smartfridge.dm
+++ b/code/game/machinery/kitchen/smartfridge.dm
@@ -350,7 +350,7 @@
if("cutwire")
if(!panel_open)
return FALSE
- if(!skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(usr, SPAN_WARNING("You don't understand anything about this wiring..."))
return FALSE
var/obj/item/held_item = user.get_held_item()
@@ -364,7 +364,7 @@
if("fixwire")
if(!panel_open)
return FALSE
- if(!skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(usr, SPAN_WARNING("You don't understand anything about this wiring..."))
return FALSE
var/obj/item/held_item = user.get_held_item()
@@ -377,7 +377,7 @@
if("pulsewire")
if(!panel_open)
return FALSE
- if(!skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(usr, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(usr, SPAN_WARNING("You don't understand anything about this wiring..."))
return FALSE
var/obj/item/held_item = user.get_held_item()
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index f835ecaa424c..f7244fb8ce0d 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -171,7 +171,7 @@ Class Procs:
. += "It does not appear to be working."
var/msg = get_repair_move_text(FALSE)
- if(msg && skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(msg && skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
. += SPAN_WARNING("[msg]")
/obj/structure/machinery/emp_act(severity)
diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm
deleted file mode 100644
index f1b0081e3a39..000000000000
--- a/code/game/machinery/mass_driver.dm
+++ /dev/null
@@ -1,10 +0,0 @@
-// Legacy SS13 machinery turned into a prop
-/obj/structure/machinery/mass_driver
- name = "mass driver"
- desc = "Shoots things into space."
- icon = 'icons/obj/structures/props/stationobjs.dmi'
- icon_state = "mass_driver"
- anchored = TRUE
- use_power = USE_POWER_IDLE
- idle_power_usage = 2
- active_power_usage = 50
diff --git a/code/game/machinery/medical_pod/autodoc.dm b/code/game/machinery/medical_pod/autodoc.dm
index ef335c6841e6..b5fd43b35651 100644
--- a/code/game/machinery/medical_pod/autodoc.dm
+++ b/code/game/machinery/medical_pod/autodoc.dm
@@ -238,11 +238,6 @@
surgery_list += create_autodoc_surgery(L,ORGAN_SURGERY,"damage",0,I)
organdamagesurgery++
- if(istype(L,/obj/limb/head))
- var/obj/limb/head/H = L
- if(H.disfigured)
- surgery_list += create_autodoc_surgery(L,LIMB_SURGERY,"facial")
-
if(L.status & LIMB_BROKEN)
surgery_list += create_autodoc_surgery(L,LIMB_SURGERY,"broken")
if(L.status & LIMB_DESTROYED)
@@ -521,20 +516,6 @@
if(!surgery) break
close_incision(H,S.limb_ref)
- if("facial")
- if(prob(30)) visible_message("[icon2html(src, viewers(src))] \The [src] speaks: Beginning Facial Reconstruction Surgery.");
- if(S.unneeded)
- sleep(UNNEEDED_DELAY)
- visible_message("[icon2html(src, viewers(src))] \The [src] speaks: Procedure has been deemed unnecessary.");
- surgery_todo_list -= S
- continue
- if(istype(S.limb_ref, /obj/limb/head))
- var/obj/limb/head/F = S.limb_ref
- sleep(SCALPEL_MAX_DURATION + HEMOSTAT_MAX_DURATION + RETRACTOR_MAX_DURATION + CAUTERY_MAX_DURATION)
- F.remove_all_bleeding(TRUE)
- F.disfigured = 0
- F.owner.name = F.owner.get_visible_name()
-
if("open")
if(prob(30)) visible_message("[icon2html(src, viewers(src))] \The [src]croaks: Closing surgical incision.");
close_encased(H,S.limb_ref)
@@ -753,9 +734,6 @@
if("shrapnel")
surgeryqueue["shrapnel"] = 1
dat += "Shrapnel Removal Surgery"
- if("facial")
- surgeryqueue["facial"] = 1
- dat += "Facial Reconstruction Surgery"
if("open")
surgeryqueue["open"] = 1
dat += "Close Open Incisions"
@@ -902,18 +880,6 @@
N.fields["autodoc_manual"] += create_autodoc_surgery(null,LIMB_SURGERY,"shrapnel",1)
updateUsrDialog()
- if(href_list["facial"])
- for(var/obj/limb/L in connected.occupant.limbs)
- if(L)
- if(istype(L,/obj/limb/head))
- var/obj/limb/head/J = L
- if(J.disfigured)
- N.fields["autodoc_manual"] += create_autodoc_surgery(L,LIMB_SURGERY,"facial")
- else
- N.fields["autodoc_manual"] += create_autodoc_surgery(L,LIMB_SURGERY,"facial",1)
- updateUsrDialog()
- break
-
if(href_list["open"])
for(var/obj/limb/L in connected.occupant.limbs)
if(L)
diff --git a/code/game/machinery/mining.dm b/code/game/machinery/mining.dm
index 0662817174fc..97ba4a804f1d 100644
--- a/code/game/machinery/mining.dm
+++ b/code/game/machinery/mining.dm
@@ -1,25 +1,3 @@
-/obj/structure/machinery/mineral/input
- icon = 'icons/mob/hud/screen1.dmi'
- icon_state = "x2"
- name = "Input area"
- density = FALSE
- anchored = TRUE
-
-/obj/structure/machinery/mineral/input/Initialize(mapload, ...)
- . = ..()
- icon_state = "blank"
-
-/obj/structure/machinery/mineral/output
- icon = 'icons/mob/hud/screen1.dmi'
- icon_state = "x"
- name = "Output area"
- density = FALSE
- anchored = TRUE
-
-/obj/structure/machinery/mineral/output/Initialize(mapload, ...)
- . = ..()
- icon_state = "blank"
-
/obj/structure/machinery/mineral/processing_unit
name = "material processor" //This isn't actually a goddamn furnace, we're in space and it's processing platinum and flammable phoron...
icon = 'icons/obj/structures/machinery/mining_machines.dmi'
diff --git a/code/game/machinery/seed_extractor.dm b/code/game/machinery/seed_extractor.dm
index 0b4574cc9fb4..71caa7a869cf 100644
--- a/code/game/machinery/seed_extractor.dm
+++ b/code/game/machinery/seed_extractor.dm
@@ -6,32 +6,61 @@
density = TRUE
anchored = TRUE
-/obj/structure/machinery/seed_extractor/attackby(obj/item/O as obj, mob/user as mob)
+/obj/structure/machinery/seed_extractor/attackby(obj/item/object as obj, mob/user as mob)
+ // Plant bag and other storage containers.
+ if(istype(object,/obj/item/storage))
+ var/obj/item/storage/container = object
+ if(length(container.contents) == 0)
+ to_chat(user, SPAN_NOTICE("[container] is empty."))
+ return
+
+ to_chat(user, SPAN_NOTICE("You start dumping the contents of [container] into [src]."))
+ if(!do_after(user, 1.5 SECONDS, INTERRUPT_ALL, BUSY_ICON_GENERIC))
+ return
+
+ for(var/obj/item/item as anything in container)
+ if(extract(item, user))
+ // Properly deletes container contents after they've been processed
+ container.remove_from_storage(item)
+ item.moveToNullspace()
+
+ playsound(user.loc, "rustle", 15, 1, 6)
+ else
+ extract(object, user)
+
+
+
+/obj/structure/machinery/seed_extractor/proc/extract(obj/item/object as obj, mob/user as mob)
// Fruits and vegetables.
- if(istype(O, /obj/item/reagent_container/food/snacks/grown) || istype(O, /obj/item/grown))
- if(user.temp_drop_inv_item(O))
+ if(istype(object, /obj/item/reagent_container/food/snacks/grown) || istype(object, /obj/item/grown))
+ if(user.temp_drop_inv_item(object))
var/datum/seed/new_seed_type
- if(istype(O, /obj/item/grown))
- var/obj/item/grown/F = O
- new_seed_type = GLOB.seed_types[F.plantname]
+ if(istype(object, /obj/item/grown))
+ var/obj/item/grown/plant = object
+ new_seed_type = GLOB.seed_types[plant.plantname]
else
- var/obj/item/reagent_container/food/snacks/grown/F = O
- new_seed_type = GLOB.seed_types[F.plantname]
+ var/obj/item/reagent_container/food/snacks/grown/plant = object
+ new_seed_type = GLOB.seed_types[plant.plantname]
if(new_seed_type)
- to_chat(user, SPAN_NOTICE("You extract some seeds from [O]."))
+ to_chat(user, SPAN_NOTICE("You extract some seeds from [object]."))
var/produce = rand(1,4)
for(var/i = 0;i<=produce;i++)
var/obj/item/seeds/seeds = new(get_turf(src))
seeds.seed_type = new_seed_type.name
seeds.update_seed()
else
- to_chat(user, "[O] doesn't seem to have any usable seeds inside it.")
- qdel(O)
+ to_chat(user, "[object] doesn't seem to have any usable seeds inside it.")
+ qdel(object)
+ return TRUE
//Grass.
- else if(istype(O, /obj/item/stack/tile/grass))
- var/obj/item/stack/tile/grass/S = O
- if (S.use(1))
+ else if(istype(object, /obj/item/stack/tile/grass))
+ var/obj/item/stack/tile/grass/grass = object
+ if (grass.use(1))
to_chat(user, SPAN_NOTICE("You extract some seeds from the grass tile."))
new /obj/item/seeds/grassseed(loc)
+ return TRUE
+ else
+ to_chat(user, SPAN_WARNING("Cannot get seeds from [object]."))
+ return FALSE
diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm
index 9bffa8ebe450..31cd2cf94d4e 100644
--- a/code/game/machinery/telecomms/machine_interactions.dm
+++ b/code/game/machinery/telecomms/machine_interactions.dm
@@ -22,7 +22,7 @@
attack_hand(user)
else
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You stare at \the [src] cluelessly..."))
return 0
@@ -103,7 +103,7 @@
// You need a multitool to use this, or be silicon
if(!isSilicon(user))
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You stare at \the [src] cluelessly..."))
return
// istype returns false if the value is null
diff --git a/code/game/machinery/telecomms/portable_comms.dm b/code/game/machinery/telecomms/portable_comms.dm
index c2a9bb1072ac..cf7ef1c1f2ef 100644
--- a/code/game/machinery/telecomms/portable_comms.dm
+++ b/code/game/machinery/telecomms/portable_comms.dm
@@ -3,7 +3,7 @@
desc = "A portable compact TC-4T telecommunications construction kit. Used to set up subspace communications lines between planetary and extra-planetary locations. Needs cabling."
icon = 'icons/obj/structures/machinery/comm_tower2.dmi'
icon_state = "construct_0_0"
- required_skill = SKILL_ENGINEER_ENGI
+ required_skill = SKILL_ENGINEER_TRAINED
required_dismantle_skill = 5
density = TRUE
anchored = FALSE
diff --git a/code/game/machinery/telecomms/presets.dm b/code/game/machinery/telecomms/presets.dm
index 0c9e875534da..de2491126c7c 100644
--- a/code/game/machinery/telecomms/presets.dm
+++ b/code/game/machinery/telecomms/presets.dm
@@ -122,7 +122,7 @@
return
if(user.action_busy)
return
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_NOVICE))
to_chat(user, SPAN_WARNING("You're not trained to repair [src]..."))
return
var/obj/item/tool/weldingtool/WT = I
diff --git a/code/game/machinery/vending/cm_vending.dm b/code/game/machinery/vending/cm_vending.dm
index d4f56504be72..2d15d4c37da8 100644
--- a/code/game/machinery/vending/cm_vending.dm
+++ b/code/game/machinery/vending/cm_vending.dm
@@ -153,7 +153,7 @@ GLOBAL_LIST_EMPTY(vending_products)
/obj/structure/machinery/cm_vending/get_examine_text(mob/living/carbon/human/user)
. = ..()
- if(skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI) && hackable)
+ if(skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED) && hackable)
. += SPAN_NOTICE("You believe you can hack this one to remove the access requirements.")
/obj/structure/machinery/cm_vending/proc/hack_access(mob/user)
@@ -678,7 +678,7 @@ GLOBAL_LIST_EMPTY(vending_products)
to_chat(user, SPAN_WARNING("You need to set [src] back upright first."))
return
if(HAS_TRAIT(W, TRAIT_TOOL_SCREWDRIVER))
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You do not understand how to repair the broken [src]."))
return FALSE
else if(stat & MAINT)
@@ -705,7 +705,7 @@ GLOBAL_LIST_EMPTY(vending_products)
to_chat(user, SPAN_WARNING("[msg]"))
return FALSE
else if(HAS_TRAIT(W, TRAIT_TOOL_WIRECUTTERS))
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You do not understand how to repair the broken [src]."))
return FALSE
else if(stat & REPAIR_STEP_ONE)
@@ -722,7 +722,7 @@ GLOBAL_LIST_EMPTY(vending_products)
to_chat(user, SPAN_WARNING("[msg]"))
return FALSE
else if(iswire(W))
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You do not understand how to repair the broken [src]."))
return FALSE
var/obj/item/stack/cable_coil/CC = W
@@ -745,7 +745,7 @@ GLOBAL_LIST_EMPTY(vending_products)
to_chat(user, SPAN_WARNING("[msg]"))
return
else if(istype(W, /obj/item/stack/sheet/metal))
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You do not understand how to repair the broken [src]."))
return FALSE
var/obj/item/stack/sheet/metal/M = W
@@ -768,7 +768,7 @@ GLOBAL_LIST_EMPTY(vending_products)
else if(HAS_TRAIT(W, TRAIT_TOOL_MULTITOOL))
var/obj/item/device/multitool/MT = W
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI) && !skillcheckexplicit(user, SKILL_ANTAG, SKILL_ANTAG_AGENT))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED) && !skillcheckexplicit(user, SKILL_ANTAG, SKILL_ANTAG_AGENT))
to_chat(user, SPAN_WARNING("You do not understand how tweak access requirements in [src]."))
return FALSE
if(stat != WORKING)
@@ -1307,7 +1307,8 @@ GLOBAL_LIST_INIT(cm_vending_gear_corresponding_types_list, list(
var/obj/item/item_ref = myprod[3]
var/priority = myprod[priority_index]
if(islist(item_ref)) // multi-vending
- item_ref = item_ref[1]
+ var/list/ref_list = item_ref
+ item_ref = ref_list[1]
var/is_category = item_ref == null
diff --git a/code/game/machinery/vending/vending.dm b/code/game/machinery/vending/vending.dm
index a05245e4b185..c6ef6eb7a574 100644
--- a/code/game/machinery/vending/vending.dm
+++ b/code/game/machinery/vending/vending.dm
@@ -207,7 +207,7 @@ GLOBAL_LIST_EMPTY_TYPED(total_vending_machines, /obj/structure/machinery/vending
to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.")
update_icon()
return TRUE
- else if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ else if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You do not understand how to repair the broken [src.name]."))
return FALSE
else if(stat & BROKEN)
@@ -234,7 +234,7 @@ GLOBAL_LIST_EMPTY_TYPED(total_vending_machines, /obj/structure/machinery/vending
to_chat(user, SPAN_WARNING("[msg]"))
return FALSE
else if(HAS_TRAIT(item, TRAIT_TOOL_WIRECUTTERS))
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You do not understand how to repair the broken [src.name]."))
return FALSE
else if(stat == WORKING && panel_open)
@@ -254,7 +254,7 @@ GLOBAL_LIST_EMPTY_TYPED(total_vending_machines, /obj/structure/machinery/vending
to_chat(user, SPAN_WARNING("[msg]"))
return FALSE
else if(istype(item, /obj/item/stack/cable_coil))
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You do not understand how to repair the broken [src.name]."))
return FALSE
var/obj/item/stack/cable_coil/CC = item
@@ -277,7 +277,7 @@ GLOBAL_LIST_EMPTY_TYPED(total_vending_machines, /obj/structure/machinery/vending
to_chat(user, SPAN_WARNING("[msg]"))
return
else if(istype(item, /obj/item/stack/sheet/metal))
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You do not understand how to repair the broken [src.name]."))
return FALSE
var/obj/item/stack/sheet/metal/M = item
diff --git a/code/game/machinery/vending/vendor_types/crew/combat_correspondent.dm b/code/game/machinery/vending/vendor_types/crew/combat_correspondent.dm
index b0894ca2a5a2..81bee126dbc8 100644
--- a/code/game/machinery/vending/vendor_types/crew/combat_correspondent.dm
+++ b/code/game/machinery/vending/vendor_types/crew/combat_correspondent.dm
@@ -3,9 +3,11 @@
GLOBAL_LIST_INIT(cm_vending_clothing_combat_correspondent, list(
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Essential Reporter's Set", 0, /obj/effect/essentials_set/cc, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_MANDATORY),
+ list("Leather Satchel", 0, /obj/item/storage/backpack/satchel, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_REGULAR),
+
+ list("CIVILIAN EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Portable Press Fax Machine", 0, /obj/item/device/fax_backpack, CIVILIAN_CAN_BUY_BACKPACK, VENDOR_ITEM_RECOMMENDED),
list("Press Broadcasting Camera", 0, /obj/item/device/camera/broadcasting, CIVILIAN_CAN_BUY_UTILITY, VENDOR_ITEM_RECOMMENDED),
- list("Leather Satchel", 0, /obj/item/storage/backpack/satchel, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_REGULAR),
list("UNIFORM (CHOOSE 1)", 0, null, null, null),
list("Black Uniform", 0, /obj/item/clothing/under/marine/reporter/black, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm b/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm
index d7d49a8ae044..dd2fc9c4a5b7 100644
--- a/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm
+++ b/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm
@@ -32,6 +32,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_commanding_officer, list(
list("HEDP Grenade Pack", 15, /obj/item/storage/box/packet/high_explosive, null, VENDOR_ITEM_REGULAR),
list("HEFA Grenade Pack", 15, /obj/item/storage/box/packet/hefa, null, VENDOR_ITEM_REGULAR),
list("WP Grenade Pack", 15, /obj/item/storage/box/packet/phosphorus, null, VENDOR_ITEM_REGULAR),
+ list("G2 Electroshock Grenade Packet (x3 grenades)", 15, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR),
list("RAIL ATTACHMENTS", 0, null, null, null),
list("Red-Dot Sight", 15, /obj/item/attachable/reddot, null, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/crew/medical.dm b/code/game/machinery/vending/vendor_types/crew/medical.dm
index fe9b7b06648e..d8e60fdb0026 100644
--- a/code/game/machinery/vending/vendor_types/crew/medical.dm
+++ b/code/game/machinery/vending/vendor_types/crew/medical.dm
@@ -245,6 +245,9 @@ GLOBAL_LIST_INIT(cm_vending_clothing_researcher, list(
/obj/item/tool/surgery/synthgraft,
/obj/item/storage/syringe_case,
/obj/item/storage/surgical_case/regular,
+ /obj/item/clothing/accessory/stethoscope,
+ /obj/item/device/flashlight/pen,
+
)
@@ -255,7 +258,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_researcher, list(
/obj/item/device/healthanalyzer,
/obj/item/tool/surgery/surgical_line,
/obj/item/tool/surgery/synthgraft,
- /obj/item/device/flashlight/pen,
/obj/item/clothing/accessory/stethoscope,
+ /obj/item/device/flashlight/pen,
/obj/item/storage/syringe_case,
)
diff --git a/code/game/machinery/vending/vendor_types/crew/mp.dm b/code/game/machinery/vending/vendor_types/crew/mp.dm
index b63a02248168..5f85060dc96f 100644
--- a/code/game/machinery/vending/vendor_types/crew/mp.dm
+++ b/code/game/machinery/vending/vendor_types/crew/mp.dm
@@ -24,7 +24,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_military_police, list(
list("BELT (CHOOSE 1)", 0, null, null, null),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 General Revolver Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 G8-A General Utility Pouch", 0, /obj/item/storage/backpack/general_belt, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
@@ -82,7 +82,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_military_police_warden, list(
list("BELT (CHOOSE 1)", 0, null, null, null),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 General Revolver Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 G8-A General Utility Pouch", 0, /obj/item/storage/backpack/general_belt, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
diff --git a/code/game/machinery/vending/vendor_types/crew/pilot_officer.dm b/code/game/machinery/vending/vendor_types/crew/pilot_officer.dm
index 8f9ac837cb6a..45ad67d41c74 100644
--- a/code/game/machinery/vending/vendor_types/crew/pilot_officer.dm
+++ b/code/game/machinery/vending/vendor_types/crew/pilot_officer.dm
@@ -80,7 +80,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_pilot_officer, list(
list("M276 Lifesaver Bag (Full)", 0, /obj/item/storage/belt/medical/lifesaver/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 Medical Storage Rig (Full)", 0, /obj/item/storage/belt/medical/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 General Revolver Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
@@ -169,7 +169,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_dropship_crew_chief, list(
list("M276 Lifesaver Bag (Full)", 0, /obj/item/storage/belt/medical/lifesaver/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 Medical Storage Rig (Full)", 0, /obj/item/storage/belt/medical/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 General Revolver Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/crew/senior_officers.dm b/code/game/machinery/vending/vendor_types/crew/senior_officers.dm
index c43d7e730d89..b63a73a90f06 100644
--- a/code/game/machinery/vending/vendor_types/crew/senior_officers.dm
+++ b/code/game/machinery/vending/vendor_types/crew/senior_officers.dm
@@ -54,7 +54,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_military_police_chief, list(
list("BELT (CHOOSE 1)", 0, null, null, null),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 General Revolver Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 G8-A General Utility Pouch", 0, /obj/item/storage/backpack/general_belt, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
@@ -329,19 +329,21 @@ GLOBAL_LIST_INIT(cm_vending_gear_xo, list(
list("Shotgun Slugs", 20, /obj/item/ammo_magazine/shotgun/slugs, null, VENDOR_ITEM_REGULAR),
list("Flechette Shells", 20, /obj/item/ammo_magazine/shotgun/flechette, null, VENDOR_ITEM_REGULAR),
+ list("SPECIALISATION KIT (CHOOSE 1)", 0, null, null, null),
+ list("Essential Engineer Set", 0, /obj/effect/essentials_set/engi, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_RECOMMENDED),
+ list("Essential Medical Set", 0, /obj/effect/essentials_set/medic, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_RECOMMENDED),
+
list("EXPLOSIVES", 0, null, null, null),
list("HEDP Grenade Pack", 15, /obj/item/storage/box/packet/high_explosive, null, VENDOR_ITEM_REGULAR),
list("HEFA Grenade Pack", 15, /obj/item/storage/box/packet/hefa, null, VENDOR_ITEM_REGULAR),
list("WP Grenade Pack", 15, /obj/item/storage/box/packet/phosphorus, null, VENDOR_ITEM_REGULAR),
list("RAIL ATTACHMENTS", 0, null, null, null),
+ list("Magnetic Harness", 12, /obj/item/attachable/magnetic_harness, null, VENDOR_ITEM_RECOMMENDED),
list("Red-Dot Sight", 15, /obj/item/attachable/reddot, null, VENDOR_ITEM_REGULAR),
list("Reflex Sight", 15, /obj/item/attachable/reflex, null, VENDOR_ITEM_REGULAR),
list("S4 2x Telescopic Mini-Scope", 15, /obj/item/attachable/scope/mini, null, VENDOR_ITEM_REGULAR),
- list("Helmet Visors", 0, null, null, null),
- list("Welding Visor", 5, /obj/item/device/helmet_visor/welding_visor, null, VENDOR_ITEM_RECOMMENDED),
-
list("UNDERBARREL ATTACHMENTS", 0, null, null, null),
list("Laser Sight", 15, /obj/item/attachable/lasersight, null, VENDOR_ITEM_REGULAR),
list("Angled Grip", 15, /obj/item/attachable/angledgrip, null, VENDOR_ITEM_REGULAR),
@@ -355,6 +357,22 @@ GLOBAL_LIST_INIT(cm_vending_gear_xo, list(
list("Extended Barrel", 15, /obj/item/attachable/extended_barrel, null, VENDOR_ITEM_REGULAR),
list("Recoil Compensator", 15, /obj/item/attachable/compensator, null, VENDOR_ITEM_REGULAR),
list("Suppressor", 15, /obj/item/attachable/suppressor, null, VENDOR_ITEM_REGULAR),
+
+ list("OTHER SUPPLIES", 0, null, null, null),
+ list("Welding Visor", 5, /obj/item/device/helmet_visor/welding_visor, null, VENDOR_ITEM_REGULAR),
+ list("Insulated Gloves", 3, /obj/item/clothing/gloves/yellow, null, VENDOR_ITEM_REGULAR),
+ list("Entrenching Tool", 1, /obj/item/tool/shovel/etool, null, VENDOR_ITEM_REGULAR),
+ list("Magnetic Harness", 12, /obj/item/attachable/magnetic_harness, null, VENDOR_ITEM_RECOMMENDED),
+ list("Radio Telephone Pack", 15, /obj/item/storage/backpack/marine/satchel/rto, null, VENDOR_ITEM_RECOMMENDED),
+ list("Motion Detector", 5, /obj/item/device/motiondetector, null, VENDOR_ITEM_RECOMMENDED),
+ list("Machete Scabbard (Full)", 5, /obj/item/storage/large_holster/machete/full, null, VENDOR_ITEM_REGULAR),
+ list("Binoculars", 5,/obj/item/device/binoculars, null, VENDOR_ITEM_REGULAR),
+ list("Rangefinder", 8, /obj/item/device/binoculars/range, null, VENDOR_ITEM_REGULAR),
+ list("Laser Designator", 12, /obj/item/device/binoculars/range/designator, null, VENDOR_ITEM_RECOMMENDED),
+ list("Fulton Recovery Device", 5, /obj/item/stack/fulton, null, VENDOR_ITEM_REGULAR),
+ list("Space Cleaner", 2, /obj/item/reagent_container/spray/cleaner, null, VENDOR_ITEM_REGULAR),
+ list("Whistle", 5, /obj/item/device/whistle, null, VENDOR_ITEM_REGULAR),
+ list("Flashlight", 1, /obj/item/device/flashlight, null, VENDOR_ITEM_REGULAR),
))
/obj/effect/essentials_set/xo/shotgunpreset
@@ -377,10 +395,16 @@ GLOBAL_LIST_INIT(cm_vending_gear_xo, list(
//------------UNIFORM/GEAR VENDOR---------------
GLOBAL_LIST_INIT(cm_vending_clothing_xo, list(
+ list("COMBAT EQUIPMENT (TAKE ALL)", 0, null, null, null),
+ list("Officer M3 Armor", 0, /obj/item/clothing/suit/storage/marine/MP/SO, MARINE_CAN_BUY_COMBAT_ARMOR, VENDOR_ITEM_MANDATORY),
+ list("Officer M10 Helmet", 0, /obj/item/clothing/head/helmet/marine/MP/SO, MARINE_CAN_BUY_COMBAT_HELMET, VENDOR_ITEM_MANDATORY),
+ list("Marine Combat Boots", 0, /obj/item/clothing/shoes/marine/knife, MARINE_CAN_BUY_COMBAT_SHOES, VENDOR_ITEM_MANDATORY),
+ list("Marine Combat Gloves", 0, /obj/item/clothing/gloves/marine, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Headset", 0, /obj/item/device/radio/headset/almayer/mcom/cdrcom, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
list("Satchel", 0, /obj/item/storage/backpack/satchel, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY),
+ list("MRE", 0, /obj/item/storage/box/MRE, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
list("UNIFORM (CHOOSE ONE)", 0, null, null, null),
list("Service Uniform", 0, /obj/item/clothing/under/marine/officer/bridge, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_RECOMMENDED),
@@ -393,53 +417,60 @@ GLOBAL_LIST_INIT(cm_vending_clothing_xo, list(
list("Mod 88 Pistol", 0, /obj/item/storage/belt/gun/m4a3/mod88, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_REGULAR),
list("M44 Revolver", 0, /obj/item/storage/belt/gun/m44/mp, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_REGULAR),
- list("BELTS (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_RECOMMENDED),
- list("Military Police Belt", 0, /obj/item/storage/belt/security/MP/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("M276 Medical Storage Rig", 0, /obj/item/storage/belt/medical/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("M276 Holster Toolrig", 0, /obj/item/storage/belt/gun/utility/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
-
- list("COMBAT EQUIPMENT (TAKE ALL)", 0, null, null, null),
- list("Officer M3 Armor", 0, /obj/item/clothing/suit/storage/marine/MP/SO, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
- list("Officer M10 Helmet", 0, /obj/item/clothing/head/helmet/marine/MP/SO, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
- list("Marine Combat Boots", 0, /obj/item/clothing/shoes/marine/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
- list("Marine Combat Gloves", 0, /obj/item/clothing/gloves/marine, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
-
list("EYEWEAR (CHOOSE 1)", 0, null, null, null),
list("Medical HUD Glasses", 0, /obj/item/clothing/glasses/hud/health, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_RECOMMENDED),
list("Security HUD Glasses", 0, /obj/item/clothing/glasses/sunglasses/sechud, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_REGULAR),
list("Bimex Personal Shades", 0, /obj/item/clothing/glasses/sunglasses/big, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_RECOMMENDED),
list("Aviator Shades", 0, /obj/item/clothing/glasses/sunglasses/aviator, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_REGULAR),
+ list("HATS (CHOOSE 1)", 0, null, null, null),
+ list("Officer Beret", 0, /obj/item/clothing/head/beret/marine/chiefofficer, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_REGULAR),
+ list("Service Peaked Cap", 0, /obj/item/clothing/head/marine/peaked/service, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_REGULAR),
+ list("Patrol Cap", 0, /obj/item/clothing/head/cmcap, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_REGULAR),
+ list("Officer Cap", 0, /obj/item/clothing/head/cmcap/bridge, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_REGULAR),
+
list("PATCHES", 0, null, null, null),
- list("Falling Falcons Shoulder Patch", 0, /obj/item/clothing/accessory/patch/falcon, MARINE_CAN_BUY_ATTACHMENT, VENDOR_ITEM_MANDATORY),
- list("USCM Shoulder Patch", 0, /obj/item/clothing/accessory/patch, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
+ list("Falling Falcons Shoulder Patch", 1, /obj/item/clothing/accessory/patch/falcon, null, VENDOR_ITEM_REGULAR),
+ list("USCM Shoulder Patch", 1, /obj/item/clothing/accessory/patch, null, 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),
+ list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("M276 Toolbelt Rig (Full)", 0, /obj/item/storage/belt/utility/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("M276 Holster Toolrig (Full)", 0, /obj/item/storage/belt/gun/utility/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 Lifesaver Bag (Full)", 0, /obj/item/storage/belt/medical/lifesaver/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("M276 Medical Storage Rig (Full)", 0, /obj/item/storage/belt/medical/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M40 Grenade Rig", 0, /obj/item/storage/belt/grenade, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("Military Police Belt", 0, /obj/item/storage/belt/security/MP/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
- list("First-Aid Pouch (Refillable Injectors)", 0, /obj/item/storage/pouch/firstaid/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Autoinjector Pouch", 0, /obj/item/storage/pouch/autoinjector/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
list("First-Aid Pouch (Splints, Gauze, Ointment)", 0, /obj/item/storage/pouch/firstaid/full/alternate, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("First-Aid Pouch (Pill Packets)", 0, /obj/item/storage/pouch/firstaid/full/pills, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
- list("Large General Pouch", 0, /obj/item/storage/pouch/general/large, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Sidearm Pouch", 0, /obj/item/storage/pouch/pistol, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("First-Aid Pouch (Pill Packets)", 0, /obj/item/storage/pouch/firstaid/full/pills, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Large General Pouch", 0, /obj/item/storage/pouch/general/large, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("Large Magazine Pouch", 0, /obj/item/storage/pouch/magazine/large, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("Large Shotgun Shell Pouch", 0, /obj/item/storage/pouch/shotgun/large, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
list("Large Pistol Magazine Pouch", 0, /obj/item/storage/pouch/magazine/pistol/large, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
list("Medical Pouch", 0, /obj/item/storage/pouch/medical, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Document Pouch", 0, /obj/item/storage/pouch/document, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Shotgun Shell Pouch", 0, /obj/item/storage/pouch/shotgun, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Medical Kit Pouch", 0, /obj/item/storage/pouch/medkit, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Pistol Pouch", 0, /obj/item/storage/pouch/pistol, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Sling Pouch", 0, /obj/item/storage/pouch/sling, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Tools Pouch (Full)", 0, /obj/item/storage/pouch/tools/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("Construction Pouch", 0, /obj/item/storage/pouch/construction, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Electronics Pouch (Full)", 0, /obj/item/storage/pouch/electronics/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Flare Pouch (Full)", 0, /obj/item/storage/pouch/flare/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Fuel Tank Strap Pouch", 0, /obj/item/storage/pouch/flamertank, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
list("ACCESSORIES (CHOOSE 1)", 0, null, null, null),
- list("Shoulder Holster", 0, /obj/item/clothing/accessory/storage/holster, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
- list("Black Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
+ list("Black Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_RECOMMENDED),
list("Brown Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest/brown_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
- list("Webbing", 0, /obj/item/clothing/accessory/storage/webbing, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
list("Drop Pouch", 0, /obj/item/clothing/accessory/storage/droppouch, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
-
- list("HATS (CHOOSE 1)", 0, null, null, null),
- list("Officer Beret", 0, /obj/item/clothing/head/beret/marine/chiefofficer, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
- list("Service Peaked Cap", 0, /obj/item/clothing/head/marine/peaked/service, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
- list("Patrol Cap", 0, /obj/item/clothing/head/cmcap, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
- list("Officer Cap", 0, /obj/item/clothing/head/cmcap/bridge, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
+ list("Webbing", 0, /obj/item/clothing/accessory/storage/webbing, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
+ list("Shoulder Holster", 0, /obj/item/clothing/accessory/storage/holster, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
))
@@ -451,7 +482,6 @@ GLOBAL_LIST_INIT(cm_vending_clothing_auxiliary_officer, list(
list("Insulated Gloves", 0, /obj/item/clothing/gloves/yellow, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
list("Officer Uniform", 0, /obj/item/clothing/under/marine/officer/bridge, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY),
list("Headset", 0, /obj/item/device/radio/headset/almayer/qm, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
- list("Patrol Cap", 0, /obj/item/clothing/head/cmcap, MARINE_CAN_BUY_MASK, VENDOR_ITEM_MANDATORY),
list("Auxiliary Support Officer Jacket", 0, /obj/item/clothing/suit/storage/jacket/marine/service/aso, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
list("BAG (CHOOSE 1)", 0, null, null, null),
@@ -463,6 +493,13 @@ GLOBAL_LIST_INIT(cm_vending_clothing_auxiliary_officer, list(
list("Mod 88 Pistol", 0, /obj/item/storage/belt/gun/m4a3/mod88, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_RECOMMENDED),
list("M44 Custom Revolver", 0, /obj/item/storage/belt/gun/m44/custom, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_RECOMMENDED),
+ list("HAT (CHOOSE 1)", 0, null, null, null),
+ list("Beret, Green", 0, /obj/item/clothing/head/beret/cm, MARINE_CAN_BUY_MASK, VENDOR_ITEM_RECOMMENDED),
+ list("Beret, Tan", 0, /obj/item/clothing/head/beret/cm/tan, MARINE_CAN_BUY_MASK, VENDOR_ITEM_RECOMMENDED),
+ list("Patrol Cap", 0, /obj/item/clothing/head/cmcap, MARINE_CAN_BUY_MASK, VENDOR_ITEM_RECOMMENDED),
+ list("Officer Cap", 0, /obj/item/clothing/head/cmcap/bridge, MARINE_CAN_BUY_MASK, VENDOR_ITEM_RECOMMENDED),
+ list("Service Peaked Cap", 0, /obj/item/clothing/head/marine/peaked/service, MARINE_CAN_BUY_MASK, VENDOR_ITEM_RECOMMENDED),
+
list("COMBAT EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Officer M3 Armor", 0, /obj/item/clothing/suit/storage/marine/MP/SO, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("Officer M10 Helmet", 0, /obj/item/clothing/head/helmet/marine/MP/SO, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
diff --git a/code/game/machinery/vending/vendor_types/crew/staff_officer.dm b/code/game/machinery/vending/vendor_types/crew/staff_officer.dm
index 50b83ccdc54f..65fbf2917699 100644
--- a/code/game/machinery/vending/vendor_types/crew/staff_officer.dm
+++ b/code/game/machinery/vending/vendor_types/crew/staff_officer.dm
@@ -7,11 +7,11 @@
/obj/structure/machinery/cm_vending/clothing/staff_officer/get_listed_products(mob/user)
return GLOB.cm_vending_clothing_staff_officer
-//------------GEAR---------------
+//------------CLOTHING---------------
GLOBAL_LIST_INIT(cm_vending_clothing_staff_officer, list(
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
- list("Boots", 0, /obj/item/clothing/shoes/marine/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
+ list("Boots", 0, /obj/item/clothing/shoes/marine/knife, MARINE_CAN_BUY_COMBAT_SHOES, VENDOR_ITEM_MANDATORY),
list("Headset", 0, /obj/item/device/radio/headset/almayer/mcom, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
list("MRE", 0, /obj/item/storage/box/MRE, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
@@ -31,12 +31,24 @@ GLOBAL_LIST_INIT(cm_vending_clothing_staff_officer, list(
list("Officer Cap", 0, /obj/item/clothing/head/cmcap/bridge, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_RECOMMENDED),
list("Service Peaked Cap", 0, /obj/item/clothing/head/marine/peaked/service, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_RECOMMENDED),
+ list("PATCHES", 0, null, null, null),
+ list("Falling Falcons Shoulder Patch", 1, /obj/item/clothing/accessory/patch/falcon, null, VENDOR_ITEM_REGULAR),
+ list("USCM Shoulder Patch", 1, /obj/item/clothing/accessory/patch, null, VENDOR_ITEM_REGULAR),
+
list("PERSONAL SIDEARM (CHOOSE 1)", 0, null, null, null),
list("M44 Revolver", 0, /obj/item/storage/belt/gun/m44/mp, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_RECOMMENDED),
+ list("Mod 88 Pistol", 0, /obj/item/storage/belt/gun/m4a3/mod88, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_RECOMMENDED),
list("M4A3 Pistol", 0, /obj/item/storage/belt/gun/m4a3/commander, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_RECOMMENDED),
list("VP78 Pistol", 0, /obj/item/storage/belt/gun/m4a3/vp78, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_RECOMMENDED),
+ list("ACCESSORIES (CHOOSE 1)", 0, null, null, null),
+ list("Black Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_RECOMMENDED),
+ list("Brown Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest/brown_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
+ list("Drop Pouch", 0, /obj/item/clothing/accessory/storage/droppouch, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
+ list("Webbing", 0, /obj/item/clothing/accessory/storage/webbing, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
+ list("Shoulder Holster", 0, /obj/item/clothing/accessory/storage/holster, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
+
list("BACKPACK (CHOOSE 1)", 0, null, null, null),
list("Backpack", 0, /obj/item/storage/backpack/marine, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_REGULAR),
list("Satchel", 0, /obj/item/storage/backpack/marine/satchel, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_REGULAR),
@@ -46,8 +58,85 @@ GLOBAL_LIST_INIT(cm_vending_clothing_staff_officer, list(
list("Binoculars", 5,/obj/item/device/binoculars, null, VENDOR_ITEM_REGULAR),
list("Rangefinder", 8, /obj/item/device/binoculars/range, null, VENDOR_ITEM_REGULAR),
list("Laser Designator", 12, /obj/item/device/binoculars/range/designator, null, VENDOR_ITEM_RECOMMENDED),
- list("Flashlight", 1, /obj/item/device/flashlight, null, VENDOR_ITEM_RECOMMENDED),
+ list("Flashlight", 1, /obj/item/device/flashlight, null, VENDOR_ITEM_REGULAR),
+ list("Motion Detector", 5, /obj/item/device/motiondetector, null, VENDOR_ITEM_RECOMMENDED),
+ list("Space Cleaner", 2, /obj/item/reagent_container/spray/cleaner, null, VENDOR_ITEM_REGULAR),
+ list("Whistle", 5, /obj/item/device/whistle, null, VENDOR_ITEM_REGULAR),
+ ))
+
+/obj/structure/machinery/cm_vending/gear/staff_officer_armory
+ name = "\improper ColMarTech Staff Officer Armory Equipment Rack"
+ desc = "An automated combat equipment vendor for Staff Officers."
+ req_access = list(ACCESS_MARINE_COMMAND)
+ icon_state = "mar_rack"
+ vendor_role = list(JOB_SO)
+
+/obj/structure/machinery/cm_vending/gear/staff_officer_armory/get_listed_products(mob/user)
+ return GLOB.cm_vending_gear_staff_officer_armory
+
+//------------ARMORY---------------
+
+GLOBAL_LIST_INIT(cm_vending_gear_staff_officer_armory, list(
+ list("COMBAT EQUIPMENT (TAKE ALL)", 0, null, null, null),
+ list("Officer M3 Armor", 0, /obj/item/clothing/suit/storage/marine/MP/SO, MARINE_CAN_BUY_COMBAT_ARMOR, VENDOR_ITEM_MANDATORY),
+ list("Officer M10 Helmet", 0, /obj/item/clothing/head/helmet/marine/MP/SO, MARINE_CAN_BUY_COMBAT_HELMET, VENDOR_ITEM_MANDATORY),
+ list("Marine Combat Boots", 0, /obj/item/clothing/shoes/marine/knife, MARINE_CAN_BUY_COMBAT_SHOES, VENDOR_ITEM_MANDATORY),
+ list("Marine Combat Gloves", 0, /obj/item/clothing/gloves/marine, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
+ list("MRE", 0, /obj/item/storage/box/MRE, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
+ list("Aviator Shades", 0, /obj/item/clothing/glasses/sunglasses/aviator, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_REGULAR),
+ list("Bayonet", 0, /obj/item/attachable/bayonet, MARINE_CAN_BUY_ATTACHMENT, VENDOR_ITEM_REGULAR),
+
+ list("SPECIALISATION KIT (CHOOSE 1)", 0, null, null, null),
+ list("Essential Engineer Set", 0, /obj/effect/essentials_set/engi, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_MANDATORY),
+ list("Essential Medical Set", 0, /obj/effect/essentials_set/medic, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_MANDATORY),
+
+ 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),
+ list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("M276 Toolbelt Rig (Full)", 0, /obj/item/storage/belt/utility/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("M276 Lifesaver Bag (Full)", 0, /obj/item/storage/belt/medical/lifesaver/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("M276 Medical Storage Rig (Full)", 0, /obj/item/storage/belt/medical/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 Holster Toolrig (Full)", 0, /obj/item/storage/belt/gun/utility/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M40 Grenade Rig", 0, /obj/item/storage/belt/grenade, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+
+ list("POUCHES (CHOOSE 2)", 0, null, null, null),
+ list("Autoinjector Pouch", 0, /obj/item/storage/pouch/autoinjector/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("First-Aid Pouch (Splints, Gauze, Ointment)", 0, /obj/item/storage/pouch/firstaid/full/alternate, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("First-Aid Pouch (Pill Packets)", 0, /obj/item/storage/pouch/firstaid/full/pills, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Large General Pouch", 0, /obj/item/storage/pouch/general/large, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("Large Magazine Pouch", 0, /obj/item/storage/pouch/magazine/large, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("Large Shotgun Shell Pouch", 0, /obj/item/storage/pouch/shotgun/large, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("Large Pistol Magazine Pouch", 0, /obj/item/storage/pouch/magazine/pistol/large, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Medical Pouch", 0, /obj/item/storage/pouch/medical, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Medical Kit Pouch", 0, /obj/item/storage/pouch/medkit, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Pistol Pouch", 0, /obj/item/storage/pouch/pistol, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Sling Pouch", 0, /obj/item/storage/pouch/sling, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Tools Pouch (Full)", 0, /obj/item/storage/pouch/tools/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("Construction Pouch", 0, /obj/item/storage/pouch/construction, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Electronics Pouch (Full)", 0, /obj/item/storage/pouch/electronics/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Flare Pouch (Full)", 0, /obj/item/storage/pouch/flare/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Fuel Tank Strap Pouch", 0, /obj/item/storage/pouch/flamertank, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+
+ list("MASK (CHOOSE 1)", 0, null, null, null),
+ list("Gas Mask", 0, /obj/item/clothing/mask/gas, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
+ list("Heat Absorbent Coif", 0, /obj/item/clothing/mask/rebreather/scarf, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
+
+ list("OTHER SUPPLIES", 0, null, null, null),
+ list("Welding Visor", 5, /obj/item/device/helmet_visor/welding_visor, null, VENDOR_ITEM_REGULAR),
+ list("Insulated Gloves", 3, /obj/item/clothing/gloves/yellow, null, VENDOR_ITEM_REGULAR),
+ list("Entrenching Tool", 1, /obj/item/tool/shovel/etool, null, VENDOR_ITEM_REGULAR),
+ list("Magnetic Harness", 12, /obj/item/attachable/magnetic_harness, null, VENDOR_ITEM_RECOMMENDED),
+ list("Radio Telephone Pack", 15, /obj/item/storage/backpack/marine/satchel/rto, null, VENDOR_ITEM_RECOMMENDED),
list("Motion Detector", 5, /obj/item/device/motiondetector, null, VENDOR_ITEM_RECOMMENDED),
+ list("Machete Scabbard (Full)", 5, /obj/item/storage/large_holster/machete/full, null, VENDOR_ITEM_REGULAR),
+ list("Binoculars", 5,/obj/item/device/binoculars, null, VENDOR_ITEM_REGULAR),
+ list("Rangefinder", 8, /obj/item/device/binoculars/range, null, VENDOR_ITEM_REGULAR),
+ list("Laser Designator", 12, /obj/item/device/binoculars/range/designator, null, VENDOR_ITEM_RECOMMENDED),
+ list("Fulton Recovery Device", 5, /obj/item/stack/fulton, null, VENDOR_ITEM_REGULAR),
list("Space Cleaner", 2, /obj/item/reagent_container/spray/cleaner, null, VENDOR_ITEM_REGULAR),
list("Whistle", 5, /obj/item/device/whistle, null, VENDOR_ITEM_REGULAR),
+ list("Flashlight", 1, /obj/item/device/flashlight, null, VENDOR_ITEM_REGULAR),
))
diff --git a/code/game/machinery/vending/vendor_types/crew/staff_officer_armory.dm b/code/game/machinery/vending/vendor_types/crew/staff_officer_armory.dm
deleted file mode 100644
index 1e21f2f7256d..000000000000
--- a/code/game/machinery/vending/vendor_types/crew/staff_officer_armory.dm
+++ /dev/null
@@ -1,89 +0,0 @@
-/obj/structure/machinery/cm_vending/clothing/staff_officer_armory
- name = "\improper ColMarTech Staff Officer Armory Equipment Rack"
- desc = "An automated combat equipment vendor for Staff Officers."
- req_access = list(ACCESS_MARINE_COMMAND)
- icon_state = "mar_rack"
- vendor_role = list(JOB_SO)
-
-/obj/structure/machinery/cm_vending/clothing/staff_officer_armory/get_listed_products(mob/user)
- return GLOB.cm_vending_clothing_staff_officer_armory
-
-//------------GEAR---------------
-
-GLOBAL_LIST_INIT(cm_vending_clothing_staff_officer_armory, list(
- list("COMBAT EQUIPMENT (TAKE ALL)", 0, null, null, null),
- list("Officer M3 Armor", 0, /obj/item/clothing/suit/storage/marine/MP/SO, MARINE_CAN_BUY_COMBAT_ARMOR, VENDOR_ITEM_MANDATORY),
- list("Officer M10 Helmet", 0, /obj/item/clothing/head/helmet/marine/MP/SO, MARINE_CAN_BUY_COMBAT_HELMET, VENDOR_ITEM_MANDATORY),
- list("Marine Combat Boots", 0, /obj/item/clothing/shoes/marine/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
- list("Marine Combat Gloves", 0, /obj/item/clothing/gloves/marine, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
- list("MRE", 0, /obj/item/storage/box/MRE, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
- list("Aviator Shades", 0, /obj/item/clothing/glasses/sunglasses/aviator, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_REGULAR),
- list("Bayonet", 0, /obj/item/attachable/bayonet, null, VENDOR_ITEM_REGULAR),
-
- list("SPECIALISATION KIT (CHOOSE 1)", 0, null, null, null),
- list("Essential Engineer Set", 0, /obj/effect/essentials_set/engi, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_RECOMMENDED),
- list("Essential Medical Set", 0, /obj/effect/essentials_set/medic, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_RECOMMENDED),
-
- 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_RECOMMENDED),
- list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("M276 Toolbelt Rig (Full)", 0, /obj/item/storage/belt/utility/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("M276 Lifesaver Bag (Full)", 0, /obj/item/storage/belt/medical/lifesaver/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 Medical Storage Rig (Full)", 0, /obj/item/storage/belt/medical/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M40 Grenade Rig", 0, /obj/item/storage/belt/grenade, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
-
- list("POUCHES (CHOOSE 2)", 0, null, null, null),
- list("Autoinjector Pouch", 0, /obj/item/storage/pouch/autoinjector, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Construction Pouch", 0, /obj/item/storage/pouch/construction, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Document Pouch", 0, /obj/item/storage/pouch/document, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Electronics Pouch (Full)", 0, /obj/item/storage/pouch/electronics/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("First-Aid Pouch (Refillable Injectors)", 0, /obj/item/storage/pouch/firstaid/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("First-Aid Pouch (Splints, Gauze, Ointment)", 0, /obj/item/storage/pouch/firstaid/full/alternate, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("First-Aid Pouch (Pill Packets)", 0, /obj/item/storage/pouch/firstaid/full/pills, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("First Responder Pouch", 0, /obj/item/storage/pouch/first_responder, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Flare Pouch (Full)", 0, /obj/item/storage/pouch/flare/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Fuel Tank Strap Pouch", 0, /obj/item/storage/pouch/flamertank, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Large General Pouch", 0, /obj/item/storage/pouch/general/large, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
- list("Large Magazine Pouch", 0, /obj/item/storage/pouch/magazine/large, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Large Shotgun Shell Pouch", 0, /obj/item/storage/pouch/shotgun/large, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Large Pistol Magazine Pouch", 0, /obj/item/storage/pouch/magazine/pistol/large, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Medical Pouch", 0, /obj/item/storage/pouch/medical, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Medical Kit Pouch", 0, /obj/item/storage/pouch/medkit, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Pistol Pouch", 0, /obj/item/storage/pouch/pistol, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Sling Pouch", 0, /obj/item/storage/pouch/sling, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("Tools Pouch (Full)", 0, /obj/item/storage/pouch/tools/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
-
- list("ACCESSORIES (CHOOSE 1)", 0, null, null, null),
- list("Black Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
- list("Brown Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest/brown_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_RECOMMENDED),
- list("Drop Pouch", 0, /obj/item/clothing/accessory/storage/droppouch, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
- list("Webbing", 0, /obj/item/clothing/accessory/storage/webbing, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
- list("Shoulder Holster", 0, /obj/item/clothing/accessory/storage/holster, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
-
- list("MASK (CHOOSE 1)", 0, null, null, null),
- list("Gas Mask", 0, /obj/item/clothing/mask/gas, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
- list("Heat Absorbent Coif", 0, /obj/item/clothing/mask/rebreather/scarf, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
-
- list("OTHER SUPPLIES", 0, null, null, null),
- list("Medical Helmet Optic", 5, /obj/item/device/helmet_visor/medical, null, VENDOR_ITEM_REGULAR),
- list("Welding Visor", 5, /obj/item/device/helmet_visor/welding_visor, null, VENDOR_ITEM_REGULAR),
- list("Magnetic Harness", 12, /obj/item/attachable/magnetic_harness, null, VENDOR_ITEM_REGULAR),
- list("Radio Telephone Pack", 15, /obj/item/storage/backpack/marine/satchel/rto, null, VENDOR_ITEM_RECOMMENDED),
- list("Binoculars", 5,/obj/item/device/binoculars, null, VENDOR_ITEM_REGULAR),
- list("Rangefinder", 8, /obj/item/device/binoculars/range, null, VENDOR_ITEM_REGULAR),
- list("Laser Designator", 12, /obj/item/device/binoculars/range/designator, null, VENDOR_ITEM_RECOMMENDED),
- list("Data Detector", 5, /obj/item/device/motiondetector/intel, null, VENDOR_ITEM_REGULAR),
- list("Flashlight", 1, /obj/item/device/flashlight, null, VENDOR_ITEM_RECOMMENDED),
- list("Fulton Recovery Device", 5, /obj/item/stack/fulton, null, VENDOR_ITEM_REGULAR),
- list("Motion Detector", 5, /obj/item/device/motiondetector, null, VENDOR_ITEM_REGULAR),
- list("Space Cleaner", 2, /obj/item/reagent_container/spray/cleaner, null, VENDOR_ITEM_REGULAR),
- list("Blowtorch", 5, /obj/item/tool/weldingtool, null, VENDOR_ITEM_REGULAR),
- list("Wrench", 1, /obj/item/tool/wrench, null, VENDOR_ITEM_REGULAR),
- list("Crowbar", 1, /obj/item/tool/crowbar, null, VENDOR_ITEM_REGULAR),
- list("Entrenching Tool", 1, /obj/item/tool/shovel/etool, null, VENDOR_ITEM_REGULAR),
- list("Whistle", 5, /obj/item/device/whistle, null, VENDOR_ITEM_REGULAR),
- list("Machete Scabbard (Full)", 5, /obj/item/storage/large_holster/machete/full, null, VENDOR_ITEM_REGULAR)
- ))
diff --git a/code/game/machinery/vending/vendor_types/crew/synthetic.dm b/code/game/machinery/vending/vendor_types/crew/synthetic.dm
index 7fbe39480999..9ce15535e2da 100644
--- a/code/game/machinery/vending/vendor_types/crew/synthetic.dm
+++ b/code/game/machinery/vending/vendor_types/crew/synthetic.dm
@@ -188,7 +188,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_synth, list(
GLOBAL_LIST_INIT(cm_vending_clothing_synth_snowflake, list(
list("USCM UNIFORMS", 0, null, null, null),
list("Medical Scrubs, Blue", 12, /obj/item/clothing/under/rank/medical/blue, null, VENDOR_ITEM_REGULAR),
- list("Medical Scrubs, Light Blue", 0, /obj/item/clothing/under/rank/medical/lightblue, null, VENDOR_ITEM_REGULAR),
+ list("Medical Scrubs, Light Blue", 12, /obj/item/clothing/under/rank/medical/lightblue, null, VENDOR_ITEM_REGULAR),
list("Medical Scrubs, Green", 12, /obj/item/clothing/under/rank/medical/green, null, VENDOR_ITEM_REGULAR),
list("Medical Scrubs, Purple", 12, /obj/item/clothing/under/rank/medical/purple, null, VENDOR_ITEM_REGULAR),
list("Medical Scrubs, Olive", 12, /obj/item/clothing/under/rank/medical/olive, null, VENDOR_ITEM_REGULAR),
@@ -349,6 +349,13 @@ GLOBAL_LIST_INIT(cm_vending_clothing_synth_snowflake, list(
list("Purple Armband", 6, /obj/item/clothing/accessory/armband/science, null, VENDOR_ITEM_REGULAR),
list("Yellow Armband", 6, /obj/item/clothing/accessory/armband/engine, null, VENDOR_ITEM_REGULAR),
list("Green Armband", 6, /obj/item/clothing/accessory/armband/medgreen, null, VENDOR_ITEM_REGULAR),
+ list("Blue Tie", 6, /obj/item/clothing/accessory/blue, null, VENDOR_ITEM_REGULAR),
+ list("Green Tie", 6, /obj/item/clothing/accessory/green, null, VENDOR_ITEM_REGULAR),
+ list("Black Tie", 6, /obj/item/clothing/accessory/black, null, VENDOR_ITEM_REGULAR),
+ list("Gold Tie", 6, /obj/item/clothing/accessory/gold, null, VENDOR_ITEM_REGULAR),
+ list("Red Tie", 6, /obj/item/clothing/accessory/red, null, VENDOR_ITEM_REGULAR),
+ list("Purple Tie", 6, /obj/item/clothing/accessory/purple, null, VENDOR_ITEM_REGULAR),
+ list("Stethoscope", 6, /obj/item/clothing/accessory/stethoscope, null, VENDOR_ITEM_REGULAR),
list("Dress Gloves", 6, /obj/item/clothing/gloves/marine/dress, null, VENDOR_ITEM_REGULAR),
))
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 53853f7d4e8b..2dd5bdf2ee68 100644
--- a/code/game/machinery/vending/vendor_types/crew/vehicle_crew.dm
+++ b/code/game/machinery/vending/vendor_types/crew/vehicle_crew.dm
@@ -274,7 +274,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_vehicle_crew, list(
list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 General Revolver Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Toolbelt Rig (Full)", 0, /obj/item/storage/belt/utility/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/engineering.dm b/code/game/machinery/vending/vendor_types/engineering.dm
index 6da719e883ba..3662d447a346 100644
--- a/code/game/machinery/vending/vendor_types/engineering.dm
+++ b/code/game/machinery/vending/vendor_types/engineering.dm
@@ -89,7 +89,7 @@
list("Supply Ordering Console", 2, /obj/item/circuitboard/computer/ordercomp, VENDOR_ITEM_REGULAR),
list("Research Data Terminal", 2, /obj/item/circuitboard/computer/research_terminal, VENDOR_ITEM_REGULAR),
list("P.A.C.M.A.N Generator", 1, /obj/item/circuitboard/machine/pacman, VENDOR_ITEM_REGULAR),
- list("Auxiliar Power Storage Unit", 2, /obj/item/circuitboard/machine/ghettosmes, VENDOR_ITEM_REGULAR),
+ list("Auxiliary Power Storage Unit", 2, /obj/item/circuitboard/machine/ghettosmes, VENDOR_ITEM_REGULAR),
list("Air Alarm Electronics", 2, /obj/item/circuitboard/airalarm, VENDOR_ITEM_REGULAR),
list("Security Camera Monitor", 2, /obj/item/circuitboard/computer/cameras, VENDOR_ITEM_REGULAR),
list("Television Set", 4, /obj/item/circuitboard/computer/cameras/tv, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/intelligence_officer.dm b/code/game/machinery/vending/vendor_types/intelligence_officer.dm
index 73d54cbbffca..63d3e93873d2 100644
--- a/code/game/machinery/vending/vendor_types/intelligence_officer.dm
+++ b/code/game/machinery/vending/vendor_types/intelligence_officer.dm
@@ -96,7 +96,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_intelligence_officer, list(
list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 General Revolver Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Toolbelt Rig (Full)", 0, /obj/item/storage/belt/utility/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
diff --git a/code/game/machinery/vending/vendor_types/requisitions.dm b/code/game/machinery/vending/vendor_types/requisitions.dm
index a8d44a8b5012..a4328bad5ea4 100644
--- a/code/game/machinery/vending/vendor_types/requisitions.dm
+++ b/code/game/machinery/vending/vendor_types/requisitions.dm
@@ -55,6 +55,7 @@
list("M74 AGM-Smoke Airburst Grenade", floor(scale * 4), /obj/item/explosive/grenade/smokebomb/airburst, VENDOR_ITEM_REGULAR),
list("M74 AGM-Star Shell", floor(scale * 2), /obj/item/explosive/grenade/high_explosive/airburst/starshell, VENDOR_ITEM_REGULAR),
list("M74 AGM-Hornet Shell", floor(scale * 4), /obj/item/explosive/grenade/high_explosive/airburst/hornet_shell, VENDOR_ITEM_REGULAR),
+ list("G2 Electroshock Grenade", round(scale * 5), /obj/item/explosive/grenade/sebb, VENDOR_ITEM_REGULAR),
list("M40 HIRR Baton Slug", floor(scale * 8), /obj/item/explosive/grenade/slug/baton, VENDOR_ITEM_REGULAR),
list("M40 MFHS Metal Foam Grenade", floor(scale * 6), /obj/item/explosive/grenade/metal_foam, VENDOR_ITEM_REGULAR),
list("Plastic Explosives", floor(scale * 3), /obj/item/explosive/plastic, VENDOR_ITEM_REGULAR),
@@ -86,7 +87,7 @@
list("M276 Knife Rig", floor(scale * 5), /obj/item/storage/belt/knifepouch, VENDOR_ITEM_REGULAR),
list("M276 M39 Holster Rig", floor(scale * 5), /obj/item/storage/belt/gun/m39, VENDOR_ITEM_REGULAR),
list("M276 M40 Grenade Rig", floor(scale * 2), /obj/item/storage/belt/grenade, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", floor(scale * 5), /obj/item/storage/belt/gun/m44, VENDOR_ITEM_REGULAR),
+ list("M276 General Revolver Holster Rig", floor(scale * 5), /obj/item/storage/belt/gun/m44, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", floor(scale * 2), /obj/item/storage/belt/gun/flaregun, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", floor(scale * 10), /obj/item/storage/belt/shotgun, VENDOR_ITEM_REGULAR),
list("M276 Mortar Operator Belt", floor(scale * 2), /obj/item/storage/belt/gun/mortarbelt, VENDOR_ITEM_REGULAR),
@@ -139,6 +140,7 @@
list("Powerloader Certification", 0.75, /obj/item/pamphlet/skill/powerloader, VENDOR_ITEM_REGULAR),
list("Spare PDT/L Battle Buddy Kit", floor(scale * 4), /obj/item/storage/box/pdt_kit, VENDOR_ITEM_REGULAR),
list("W-Y brand rechargeable mini-battery", floor(scale * 3), /obj/item/cell/crap, VENDOR_ITEM_REGULAR),
+ list("Nailgun Magazine (7x45mm)", floor(scale * 4), /obj/item/ammo_magazine/smg/nailgun, VENDOR_ITEM_REGULAR),
list("EXPLOSIVES BOXES", -1, null, null),
list("M15 Fragmentation Grenade Packet", 0, /obj/item/storage/box/packet/m15, VENDOR_ITEM_REGULAR),
@@ -154,12 +156,14 @@
list("M74 AGM-Airburst Smoke Grenade Packet", 0, /obj/item/storage/box/packet/airburst_smoke, VENDOR_ITEM_REGULAR),
list("M74 AGM-S Star Shell Packet", 0, /obj/item/storage/box/packet/flare, VENDOR_ITEM_REGULAR),
list("M74 AGM-H Hornet Shell Packet", 0, /obj/item/storage/box/packet/hornet, VENDOR_ITEM_REGULAR),
+ list("G2 Electroshock grenade packet", 0, /obj/item/storage/box/packet/sebb, VENDOR_ITEM_REGULAR),
list("M20 mine box", 0, /obj/item/storage/box/explosive_mines, VENDOR_ITEM_REGULAR),
list("OTHER BOXES", -1, null, null),
list("Box of M94 Marking Flare Packs", 0, /obj/item/ammo_box/magazine/misc/flares, VENDOR_ITEM_REGULAR),
list("Box of M89 Signal Flare Packs", 0, /obj/item/ammo_box/magazine/misc/flares/signal, VENDOR_ITEM_REGULAR),
- list("Box of High-Capacity Power Cells", 0, /obj/item/ammo_box/magazine/misc/power_cell, VENDOR_ITEM_REGULAR)
+ list("Box of High-Capacity Power Cells", 0, /obj/item/ammo_box/magazine/misc/power_cell, VENDOR_ITEM_REGULAR),
+ list("Nailgun Magazine Box (7x45mm)", floor(scale * 2), /obj/item/ammo_box/magazine/nailgun, VENDOR_ITEM_REGULAR)
)
/obj/structure/machinery/cm_vending/sorted/cargo_guns/stock(obj/item/item_to_stock, mob/user)
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 aaf134c4a459..74a3d2a6167b 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
@@ -33,8 +33,9 @@ GLOBAL_LIST_INIT(cm_vending_gear_engi, list(
list("M74 AGM-Incendiary Airburst Packet (x3 airburst grenades)", 18, /obj/item/storage/box/packet/airburst_incen, null, VENDOR_ITEM_REGULAR),
list("M74 AGM-Smoke Airburst Packet (x3 airburst grenades)", 10, /obj/item/storage/box/packet/airburst_smoke, null, VENDOR_ITEM_REGULAR),
list("M74 AGM-Hornet Airburst Packet (x3 airburst grenades", 20, /obj/item/storage/box/packet/hornet, null, VENDOR_ITEM_REGULAR),
- list("M20 Mine Box (x4 mines)", 18, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR),
+ list("M20 Mine Box (x5 mines)", 18, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR),
list("M40 MFHS Metal Foam Grenade", 5, /obj/item/explosive/grenade/metal_foam, null, VENDOR_ITEM_REGULAR),
+ list("G2 Electroshock Grenade Packet (x3 grenades)", 16, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR),
list("PRIMARY AMMUNITION", 0, null, null, null),
list("M4RA AP Magazine (10x24mm)", 6, /obj/item/ammo_magazine/rifle/m4ra/ap, null, VENDOR_ITEM_REGULAR),
@@ -131,12 +132,13 @@ GLOBAL_LIST_INIT(cm_vending_clothing_engi, list(
list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 General Revolver Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Mortar Operator Belt", 0, /obj/item/storage/belt/gun/mortarbelt, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Toolbelt Rig (Full)", 0, /obj/item/storage/belt/utility/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_MANDATORY),
list("M276 M40 Grenade Rig", 0, /obj/item/storage/belt/grenade, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M277 Pattern Construction Rig", 0, /obj/item/storage/belt/utility/construction, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
list("Construction Pouch", 0, /obj/item/storage/pouch/construction, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
@@ -152,6 +154,8 @@ GLOBAL_LIST_INIT(cm_vending_clothing_engi, list(
list("Medium General Pouch", 0, /obj/item/storage/pouch/general/medium, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
list("Pistol Pouch", 0, /obj/item/storage/pouch/pistol, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
list("Tools Pouch (Full)", 0, /obj/item/storage/pouch/tools/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Engineer kit Pouch", 0, /obj/item/storage/pouch/engikit, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+
list("ACCESSORIES (CHOOSE 1)", 0, null, null, null),
list("Black Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
@@ -159,6 +163,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_engi, list(
list("Shoulder Holster", 0, /obj/item/clothing/accessory/storage/holster, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
list("Webbing", 0, /obj/item/clothing/accessory/storage/webbing, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
list("Drop Pouch", 0, /obj/item/clothing/accessory/storage/droppouch, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
+ list("Small Tool Webbing (Full)", 0, /obj/item/clothing/accessory/storage/tool_webbing/small/equipped, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
list("MASK (CHOOSE 1)", 0, null, null, null),
list("Gas Mask", 0, /obj/item/clothing/mask/gas, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
@@ -210,4 +215,5 @@ GLOBAL_LIST_INIT(cm_vending_clothing_engi, list(
/obj/item/cell/high,
/obj/item/tool/shovel/etool/folded,
/obj/item/device/lightreplacer,
+ /obj/item/weapon/gun/smg/nailgun/compact/tactical,
)
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 17d3419ac2f8..0055dc2b1375 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
@@ -59,8 +59,9 @@ GLOBAL_LIST_INIT(cm_vending_gear_leader, list(
list("M74 AGM-Incendiary Airburst Packet (x3 airburst grenades)", 20, /obj/item/storage/box/packet/airburst_incen, null, VENDOR_ITEM_REGULAR),
list("M74 AGM-Smoke Airburst Packet (x3 airburst grenades)", 10, /obj/item/storage/box/packet/airburst_smoke, null, VENDOR_ITEM_REGULAR),
list("M74 AGM-Hornet Airburst Packet (x3 airburst grenades", 20, /obj/item/storage/box/packet/hornet, null, VENDOR_ITEM_REGULAR),
- list("M20 Mine Box (x4 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR),
+ list("M20 Mine Box (x5 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR),
list("M40 MFHS Metal Foam Grenade", 5, /obj/item/explosive/grenade/metal_foam, null, VENDOR_ITEM_REGULAR),
+ list("G2 Electroshock Grenade Packet (x3 grenades)", 16, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR),
list("MEDICAL SUPPLIES", 0, null, null, null),
list("Burn Kit", 2, /obj/item/stack/medical/advanced/ointment, null, VENDOR_ITEM_REGULAR),
@@ -143,7 +144,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_leader, list(
list("M276 Lifesaver Bag", 0, /obj/item/storage/belt/medical/lifesaver, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Medical Storage Rig", 0, /obj/item/storage/belt/medical, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 General Revolver Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Toolbelt Rig (Full)", 0, /obj/item/storage/belt/utility/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
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 a73df202d4ef..a8cc8be64bda 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
@@ -56,7 +56,8 @@ GLOBAL_LIST_INIT(cm_vending_gear_medic, list(
list("M74 AGM-Incendiary Airburst Packet (x3 airburst grenades)", 20, /obj/item/storage/box/packet/airburst_incen, null, VENDOR_ITEM_REGULAR),
list("M74 AGM-Smoke Airburst Packet (x3 airburst grenades)", 10, /obj/item/storage/box/packet/airburst_smoke, null, VENDOR_ITEM_REGULAR),
list("M74 AGM-Hornet Airburst Packet (x3 airburst grenades", 20, /obj/item/storage/box/packet/hornet, null, VENDOR_ITEM_REGULAR),
- list("M20 Mine Box (x4 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR),
+ list("M20 Mine Box (x5 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR),
+ list("G2 Electroshock Grenade Packet (x3 grenades)", 16, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR),
list("PRIMARY AMMUNITION", 0, null, null, null),
list("M4RA AP Magazine (10x24mm)", 6, /obj/item/ammo_magazine/rifle/m4ra/ap, null, VENDOR_ITEM_REGULAR),
@@ -151,7 +152,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_medic, list(
list("M276 Lifesaver Bag (Full)", 0, /obj/item/storage/belt/medical/lifesaver/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 Medical Storage Rig (Full)", 0, /obj/item/storage/belt/medical/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 General Revolver Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M40 Grenade Rig", 0, /obj/item/storage/belt/grenade, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
@@ -236,4 +237,6 @@ GLOBAL_LIST_INIT(cm_vending_clothing_medic, list(
/obj/item/storage/surgical_case/regular,
/obj/item/reagent_container/blood/OMinus,
/obj/item/reagent_container/blood/OMinus,
+ /obj/item/device/flashlight/pen,
+ /obj/item/clothing/accessory/stethoscope,
)
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm
index 35b059ac9611..ff43ca68657d 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm
@@ -148,7 +148,7 @@
list("M276 Pattern General Pistol Holster Rig", floor(scale * 15), /obj/item/storage/belt/gun/m4a3, VENDOR_ITEM_REGULAR),
list("M276 Pattern M39 Holster Rig", floor(scale * 15), /obj/item/storage/large_holster/m39, VENDOR_ITEM_REGULAR),
list("M276 Pattern M39 Holster Rig And Pouch", floor(scale * 10), /obj/item/storage/belt/gun/m39, VENDOR_ITEM_REGULAR),
- list("M276 Pattern M44 Holster Rig", floor(scale * 15), /obj/item/storage/belt/gun/m44, VENDOR_ITEM_REGULAR),
+ list("M276 Pattern General Revolver Holster Rig", floor(scale * 15), /obj/item/storage/belt/gun/m44, VENDOR_ITEM_REGULAR),
list("M276 Pattern M82F Holster Rig", floor(scale * 5), /obj/item/storage/belt/gun/flaregun, VENDOR_ITEM_REGULAR),
list("M276 Knife Rig (Full)", floor(scale * 15), /obj/item/storage/belt/knifepouch, VENDOR_ITEM_REGULAR),
list("M276 G8-A General Utility Pouch", floor(scale * 15), /obj/item/storage/backpack/general_belt, VENDOR_ITEM_REGULAR),
@@ -339,7 +339,8 @@
list("Binoculars", floor(scale * 1), /obj/item/device/binoculars, VENDOR_ITEM_REGULAR),
list("MB-6 Folding Barricades (x3)", floor(scale * 2), /obj/item/stack/folding_barricade/three, VENDOR_ITEM_REGULAR),
list("Spare PDT/L Battle Buddy Kit", floor(scale * 3), /obj/item/storage/box/pdt_kit, VENDOR_ITEM_REGULAR),
- list("W-Y brand rechargeable mini-battery", floor(scale * 2.5), /obj/item/cell/crap, VENDOR_ITEM_REGULAR)
+ list("W-Y brand rechargeable mini-battery", floor(scale * 2.5), /obj/item/cell/crap, VENDOR_ITEM_REGULAR),
+ list("Nailgun Magazine (7x45mm)", floor(scale * 4), /obj/item/ammo_magazine/smg/nailgun, VENDOR_ITEM_REGULAR)
)
//--------------SQUAD ATTACHMENTS VENDOR--------------
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 65066731070d..1db378bd1d98 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
@@ -21,7 +21,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_marine, list(
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Knife Rig (Full)", 0, /obj/item/storage/belt/knifepouch, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 General Revolver Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 G8-A General Utility Pouch", 0, /obj/item/storage/backpack/general_belt, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
@@ -65,7 +65,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_marine, list(
list("M74 AGM-Incendiary Airburst Packet (x3 airburst grenades)", 15, /obj/item/storage/box/packet/airburst_incen, null, VENDOR_ITEM_REGULAR),
list("M74 AGM-Smoke Airburst Packet (x3 airburst grenades)", 10, /obj/item/storage/box/packet/airburst_smoke, null, VENDOR_ITEM_REGULAR),
list("M74 AGM-Hornet Airburst Packet (x3 airburst grenades", 15, /obj/item/storage/box/packet/hornet, null, VENDOR_ITEM_REGULAR),
- list("M20 Mine Box (x4 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR),
+ list("M20 Mine Box (x5 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR),
list("PRIMARY AMMUNITION", 0, null, null, null),
list("M4RA AP Magazine (10x24mm)", 10, /obj/item/ammo_magazine/rifle/m4ra/ap, 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 60afed8b984d..962580529eb2 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
@@ -18,7 +18,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_smartgun, list(
list("M74 AGM-Incendiary Airburst Packet (x3 airburst grenades)", 20, /obj/item/storage/box/packet/airburst_incen, null, VENDOR_ITEM_REGULAR),
list("M74 AGM-Smoke Airburst Packet (x3 airburst grenades)", 10, /obj/item/storage/box/packet/airburst_smoke, null, VENDOR_ITEM_REGULAR),
list("M74 AGM-Hornet Airburst Packet (x3 airburst grenades", 20, /obj/item/storage/box/packet/hornet, null, VENDOR_ITEM_REGULAR),
- list("M20 Mine Box (x4 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR),
+ list("M20 Mine Box (x5 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR),
list("SIDEARM AMMUNITION", 0, null, null, null),
list("M44 Heavy Speed Loader (.44)", 10, /obj/item/ammo_magazine/revolver/heavy, null, VENDOR_ITEM_REGULAR),
@@ -33,7 +33,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_smartgun, list(
list("SU-6 Smart Pistol", 15, /obj/item/storage/box/guncase/smartpistol, null, VENDOR_ITEM_REGULAR),
list("CLOTHING ITEMS", 0, null, null, null),
- list("Machete Scabbard (Full)", 6, /obj/item/storage/large_holster/machete/full, null, VENDOR_ITEM_REGULAR),
+ list("Smartgunner Machete Scabbard", 15, /obj/item/storage/large_holster/machete/smartgunner/full, null, VENDOR_ITEM_REGULAR),
list("Fuel Tank Strap Pouch", 5, /obj/item/storage/pouch/flamertank, null, VENDOR_ITEM_REGULAR),
list("Large General Pouch", 6, /obj/item/storage/pouch/general/large, 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 4d14b7b89ccd..a21207a6645c 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
@@ -32,6 +32,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_spec, list(
list("M74 AGM-F Fragmentation Grenades x6", 40, /obj/effect/essentials_set/agmf_6_pack, null, VENDOR_ITEM_REGULAR),
list("M74 AGM-I Incendiary Grenades x6", 40, /obj/effect/essentials_set/agmi_6_pack, null, VENDOR_ITEM_REGULAR),
list("M74 AGM-S Smoke Grenades x6", 20, /obj/effect/essentials_set/agms_6_pack, null, VENDOR_ITEM_REGULAR),
+ list("G2 Electroshock Grenade Pack x6", 40, /obj/effect/essentials_set/sebb_6_pack, null, VENDOR_ITEM_REGULAR),
list("EXTRA FLAMETHROWER TANKS", 0, null, null, null),
list("Large Incinerator Tank", 40, /obj/item/ammo_magazine/flamer_tank/large, null, VENDOR_ITEM_REGULAR),
@@ -71,7 +72,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_specialist, list(
list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 General Revolver Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
@@ -249,3 +250,13 @@ GLOBAL_LIST_INIT(cm_vending_clothing_specialist, list(
/obj/item/explosive/grenade/smokebomb/airburst,
/obj/item/explosive/grenade/smokebomb/airburst,
)
+
+/obj/effect/essentials_set/sebb_6_pack
+ spawned_gear_list = list(
+ /obj/item/explosive/grenade/sebb,
+ /obj/item/explosive/grenade/sebb,
+ /obj/item/explosive/grenade/sebb,
+ /obj/item/explosive/grenade/sebb,
+ /obj/item/explosive/grenade/sebb,
+ /obj/item/explosive/grenade/sebb,
+ )
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 c37dd98ed263..a4535fc7bfb4 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
@@ -10,8 +10,9 @@ GLOBAL_LIST_INIT(cm_vending_gear_tl, list(
list("M74 AGM-Incendiary Airburst Packet (x3 airburst grenades)", 20, /obj/item/storage/box/packet/airburst_incen, null, VENDOR_ITEM_REGULAR),
list("M74 AGM-Smoke Airburst Packet (x3 airburst grenades)", 10, /obj/item/storage/box/packet/airburst_smoke, null, VENDOR_ITEM_REGULAR),
list("M74 AGM-Hornet Airburst Packet (x3 airburst grenades", 20, /obj/item/storage/box/packet/hornet, null, VENDOR_ITEM_REGULAR),
- list("M20 Mine Box (x4 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR),
+ list("M20 Mine Box (x5 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR),
list("M40 MFHS Metal Foam Grenade", 5, /obj/item/explosive/grenade/metal_foam, null, VENDOR_ITEM_REGULAR),
+ list("G2 Electroshock Grenade Packet (x3 grenades)", 16, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR),
list("PRIMARY AMMUNITION", 0, null, null, null),
list("M4RA AP Magazine (10x24mm)", 10, /obj/item/ammo_magazine/rifle/m4ra/ap, null, VENDOR_ITEM_REGULAR),
@@ -101,7 +102,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_tl, list(
list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 General Revolver Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Toolbelt Rig (Full)", 0, /obj/item/storage/belt/utility/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
diff --git a/code/game/machinery/vending/vendor_types/wo_vendors.dm b/code/game/machinery/vending/vendor_types/wo_vendors.dm
index 1d6ad60bb357..1a4c3d3b5bd8 100644
--- a/code/game/machinery/vending/vendor_types/wo_vendors.dm
+++ b/code/game/machinery/vending/vendor_types/wo_vendors.dm
@@ -63,7 +63,7 @@
list("M276 Pattern General Pistol Holster Rig", floor(scale * 10), /obj/item/storage/belt/gun/m4a3, VENDOR_ITEM_REGULAR),
list("M276 Pattern M39 Holster Rig", floor(scale * 10), /obj/item/storage/large_holster/m39, VENDOR_ITEM_REGULAR),
list("M276 Pattern M39 Holster Rig And Pouch", floor(scale * 5), /obj/item/storage/belt/gun/m39, VENDOR_ITEM_REGULAR),
- list("M276 Pattern M44 Holster Rig", floor(scale * 10), /obj/item/storage/belt/gun/m44, VENDOR_ITEM_REGULAR),
+ list("M276 Pattern General Revolver Holster Rig", floor(scale * 10), /obj/item/storage/belt/gun/m44, VENDOR_ITEM_REGULAR),
list("M276 Pattern M82F Holster Rig", floor(scale * 2), /obj/item/storage/belt/gun/flaregun, VENDOR_ITEM_REGULAR),
list("M276 Knife Rig (Full)", floor(scale * 10), /obj/item/storage/belt/knifepouch, VENDOR_ITEM_REGULAR),
list("M276 G8-A General Utility Pouch", floor(scale * 10), /obj/item/storage/backpack/general_belt, VENDOR_ITEM_REGULAR),
diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm
index 10d4e8d098fb..45fbd5d4ba2b 100644
--- a/code/game/objects/effects/aliens.dm
+++ b/code/game/objects/effects/aliens.dm
@@ -125,6 +125,10 @@
var/obj/vehicle/multitile/V = atm
V.handle_acidic_environment(src)
continue
+ if (istype(loc, /turf/open))
+ var/turf/open/scorch_turf_target = loc
+ if(scorch_turf_target.scorchable)
+ scorch_turf_target.scorch(damage_amount)
START_PROCESSING(SSobj, src)
addtimer(CALLBACK(src, PROC_REF(die)), time_to_live)
@@ -148,7 +152,7 @@
..()
if(AM == cause_data.resolve_mob())
return
-
+
if(isliving(AM))
var/mob/living/living_mob = AM
if(living_mob.ally_of_hivenumber(hivenumber))
@@ -597,7 +601,7 @@
total_hits++
- var/datum/action/xeno_action/activable/boiler_trap/trap = get_xeno_action_by_type(linked_xeno, /datum/action/xeno_action/activable/boiler_trap)
+ var/datum/action/xeno_action/activable/boiler_trap/trap = get_action(linked_xeno, /datum/action/xeno_action/activable/boiler_trap)
trap.reduce_cooldown(total_hits*4 SECONDS)
diff --git a/code/game/objects/effects/effect_system/chemsmoke.dm b/code/game/objects/effects/effect_system/chemsmoke.dm
index 1b22ed6054eb..41b58ba39e77 100644
--- a/code/game/objects/effects/effect_system/chemsmoke.dm
+++ b/code/game/objects/effects/effect_system/chemsmoke.dm
@@ -57,10 +57,11 @@
targetTurfs = new()
//build affected area list
- for(var/turf/T in view(range, location))
+ FOR_DVIEW(var/turf/T, range, location, HIDE_INVISIBLE_OBSERVER)
//cull turfs to circle
if(cheap_pythag(T.x - location.x, T.y - location.y) <= range)
targetTurfs += T
+ FOR_DVIEW_END
//make secondary list for reagents that affect walls
if(chemholder.reagents.has_reagent("thermite") || chemholder.reagents.has_reagent("plantbgone"))
diff --git a/code/game/objects/effects/effect_system/particle_effects.dm b/code/game/objects/effects/effect_system/particle_effects.dm
index 972d242bf359..9440c16f2d4e 100644
--- a/code/game/objects/effects/effect_system/particle_effects.dm
+++ b/code/game/objects/effects/effect_system/particle_effects.dm
@@ -8,10 +8,10 @@
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
unacidable = TRUE // So effect are not targeted by alien acid.
-/obj/effect/particle_effect/initialize_pass_flags(datum/pass_flags_container/PF)
+/obj/effect/particle_effect/initialize_pass_flags(datum/pass_flags_container/pass_flags)
..()
- if (PF)
- PF.flags_pass = PASS_OVER|PASS_AROUND|PASS_UNDER|PASS_THROUGH|PASS_MOB_THRU
+ if (pass_flags)
+ pass_flags.flags_pass = PASS_OVER|PASS_AROUND|PASS_UNDER|PASS_THROUGH|PASS_MOB_THRU
//Water
@@ -22,17 +22,14 @@
var/life = 15
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
-/obj/effect/particle_effect/water/initialize_pass_flags(datum/pass_flags_container/PF)
+/obj/effect/particle_effect/water/initialize_pass_flags(datum/pass_flags_container/pass_flags)
..()
- if (PF)
- PF.flags_pass = PASS_THROUGH|PASS_OVER|PASS_MOB_THRU|PASS_UNDER
+ if (pass_flags)
+ pass_flags.flags_pass = PASS_THROUGH|PASS_OVER|PASS_MOB_THRU|PASS_UNDER
/obj/effect/particle_effect/water/Move(turf/newloc)
- //var/turf/T = src.loc
- //if (istype(T, /turf))
- // T.firelevel = 0 //TODO: FIX
- if (--src.life < 1)
- //SN src = null
+ life -= 1
+ if (life < 1)
qdel(src)
if(newloc.density)
return 0
diff --git a/code/game/objects/effects/effect_system/smoke.dm b/code/game/objects/effects/effect_system/smoke.dm
index d4152bdee37e..d0ea5d2ed5ef 100644
--- a/code/game/objects/effects/effect_system/smoke.dm
+++ b/code/game/objects/effects/effect_system/smoke.dm
@@ -731,7 +731,7 @@
location = get_turf(loca)
if(direct)
direction = direct
- if(lifetime)
+ if(smoke_time)
lifetime = smoke_time
radius = min(radius, 10)
amount = radius
diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm
index ce0fd5506cd7..d559137f79b1 100644
--- a/code/game/objects/effects/overlays.dm
+++ b/code/game/objects/effects/overlays.dm
@@ -223,6 +223,7 @@
icon_state = "empdisable"
name = "emp sparks"
effect_duration = 10
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/effect/overlay/temp/emp_sparks/New(loc)
setDir(pick(GLOB.cardinals))
@@ -234,8 +235,12 @@
icon_state = "emppulse"
effect_duration = 20
-
-
+/obj/effect/overlay/temp/elec_arc
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "electricity"
+ name = "electric arc"
+ effect_duration = 3 SECONDS
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
//gib animation
diff --git a/code/game/objects/explosion_recursive.dm b/code/game/objects/explosion_recursive.dm
index 2ec61b0cc1f1..708b3d25e43e 100644
--- a/code/game/objects/explosion_recursive.dm
+++ b/code/game/objects/explosion_recursive.dm
@@ -71,7 +71,9 @@ explosion resistance exactly as much as their health
falloff = max(falloff0, power/100) //prevent explosions with a range larger than 100 tiles
minimum_spread_power = -power * reflection_amplification_limit
- msg_admin_attack("Explosion with Power: [power], Falloff: [falloff] in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z]).", src.loc.x, src.loc.y, src.loc.z)
+ var/obj/causing_obj = explosion_cause_data?.resolve_cause()
+ var/mob/causing_mob = explosion_cause_data?.resolve_mob()
+ msg_admin_attack("Explosion with Power: [power], Falloff: [falloff],[causing_obj ? " from [causing_obj]" : ""][causing_mob ? " by [key_name(causing_mob)]" : ""] in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z]).", loc.x, loc.y, loc.z)
playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(power^2,1))
playsound(epicenter, "explosion", 90, 1, max(round(power,1),7) )
@@ -84,9 +86,7 @@ explosion resistance exactly as much as their health
if(power >= 100) // powerful explosions send out some special effects
epicenter = get_turf(epicenter) // the ex_acts might have changed the epicenter
- create_shrapnel(epicenter, rand(5,9), , ,/datum/ammo/bullet/shrapnel/light/effect/ver1, explosion_cause_data)
- sleep(1)
- create_shrapnel(epicenter, rand(5,9), , ,/datum/ammo/bullet/shrapnel/light/effect/ver2, explosion_cause_data)
+ new /obj/shrapnel_effect(epicenter)
spawn(2) //just in case something goes wrong
if(explosion_in_progress)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 03e1f126e9d8..d8bf3d9d8f79 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -163,6 +163,9 @@
/// How much to offset the item randomly either way alongside Y visually
var/ground_offset_y = 0
+ /// Special storages this item prioritizes
+ var/list/preferred_storage
+
/obj/item/Initialize(mapload, ...)
. = ..()
diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm
index 80044e2fab3e..f90e54ef7854 100644
--- a/code/game/objects/items/cards_ids.dm
+++ b/code/game/objects/items/cards_ids.dm
@@ -171,24 +171,24 @@
name = "corporate doctor badge"
desc = "A corporate holo-badge. It is fingerprint locked with clearance level 3 access. It is commonly held by corporate doctors."
icon_state = "clearance"
- var/clearance_access = 3
+ var/credits_to_give = 15 //gives the equivalent clearance access in credits
/obj/item/card/id/silver/clearance_badge/scientist
name = "corporate scientist badge"
desc = "A corporate holo-badge. It is fingerprint locked with clearance level 4 access. It is commonly held by corporate scientists."
- clearance_access = 4
+ credits_to_give = 27
/obj/item/card/id/silver/clearance_badge/cl
name = "corporate liaison badge"
desc = "A corporate holo-badge in unique corporate orange and white. It is fingerprint locked with clearance level 5 access. It is commonly held by corporate liaisons."
icon_state = "cl"
- clearance_access = 5
+ credits_to_give = 42
/obj/item/card/id/silver/clearance_badge/manager
name = "corporate manager badge"
desc = "A corporate holo-badge in standard corporate orange and white. It has a unique uncapped bottom. It is fingerprint locked with 5-X clearance level. Commonly held by corporate managers."
icon_state = "pmc"
- clearance_access = 6
+ credits_to_give = 47
/obj/item/card/id/pizza
name = "pizza guy badge"
diff --git a/code/game/objects/items/circuitboards/computer.dm b/code/game/objects/items/circuitboards/computer.dm
index 43215faf0fbb..58ff86130cd6 100644
--- a/code/game/objects/items/circuitboards/computer.dm
+++ b/code/game/objects/items/circuitboards/computer.dm
@@ -180,7 +180,7 @@
else if(HAS_TRAIT(tool, TRAIT_TOOL_BLACKMARKET_HACKER))
to_chat(user, SPAN_WARNING("You start messing around with the electronics of [src]..."))
if(do_after(user, 8 SECONDS, INTERRUPT_ALL, BUSY_ICON_FRIENDLY))
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You have no idea what you're doing."))
return
to_chat(user, SPAN_WARNING("Huh? You find a processor bus with the letters 'B.M.' written in white crayon over it. You start fiddling with it."))
diff --git a/code/game/objects/items/devices/RCD.dm b/code/game/objects/items/devices/RCD.dm
deleted file mode 100644
index 00e569800314..000000000000
--- a/code/game/objects/items/devices/RCD.dm
+++ /dev/null
@@ -1,194 +0,0 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
-
-/*
-CONTAINS:
-RCD
-*/
-/obj/item/device/rcd
- name = "rapid-construction-device (RCD)"
- desc = "A device used to rapidly build walls/floor."
- icon = 'icons/obj/items/devices.dmi'
- icon_state = "rcd"
- opacity = FALSE
- density = FALSE
- anchored = FALSE
- flags_atom = FPRINT|CONDUCT
- force = 10
- throwforce = 10
- throw_speed = SPEED_FAST
- throw_range = 5
- w_class = SIZE_MEDIUM
- matter = list("metal" = 50000)
-
- var/datum/effect_system/spark_spread/spark_system
- var/stored_matter = 0
- var/working = 0
- var/mode = 1
- var/canRwall = 0
- var/disabled = 0
-
-
-/obj/item/device/rcd/New()
- desc = "A RCD. It currently holds [stored_matter]/30 matter-units."
- src.spark_system = new /datum/effect_system/spark_spread
- spark_system.set_up(5, 0, src)
- spark_system.attach(src)
- return
-
-/obj/item/device/rcd/Destroy()
- QDEL_NULL(spark_system)
- return ..()
-
-
-/obj/item/device/rcd/attackby(obj/item/W, mob/user)
- ..()
- if(istype(W, /obj/item/ammo_rcd))
- if((stored_matter + 10) > 30)
- to_chat(user, SPAN_NOTICE("The RCD cant hold any more matter-units."))
- return
- user.drop_held_item()
- qdel(W)
- stored_matter += 10
- playsound(src.loc, 'sound/machines/click.ogg', 15, 1)
- to_chat(user, SPAN_NOTICE("The RCD now holds [stored_matter]/30 matter-units."))
- desc = "A RCD. It currently holds [stored_matter]/30 matter-units."
- return
-
-
-/obj/item/device/rcd/attack_self(mob/user)
- ..()
-
- //Change the mode
- playsound(src.loc, 'sound/effects/pop.ogg', 15, 0)
- switch(mode)
- if(1)
- mode = 2
- to_chat(user, SPAN_NOTICE("Changed mode to 'Airlock'"))
- if(prob(20))
- src.spark_system.start()
- return
- if(2)
- mode = 3
- to_chat(user, SPAN_NOTICE("Changed mode to 'Deconstruct'"))
- if(prob(20))
- src.spark_system.start()
- return
- if(3)
- mode = 1
- to_chat(user, SPAN_NOTICE("Changed mode to 'Floor & Walls'"))
- if(prob(20))
- src.spark_system.start()
- return
-
-/obj/item/device/rcd/proc/activate()
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 25, 1)
-
-
-/obj/item/device/rcd/afterattack(atom/A, mob/user, proximity)
- if(!proximity) return
- if(disabled)
- return 0
- if(istype(A,/area/shuttle) || istype(A,/turf/open/space/transit))
- return 0
- if(!(istype(A, /turf) || istype(A, /obj/structure/machinery/door/airlock)))
- return 0
-
- switch(mode)
- if(1)
- if(istype(A, /turf/open/space))
- if(useResource(1, user))
- to_chat(user, "Building Floor...")
- activate()
- A:ChangeTurf(/turf/open/floor/plating/airless)
- return 1
- return 0
-
- if(istype(A, /turf/open/floor))
- if(checkResource(3, user))
- to_chat(user, "Building Wall ...")
- playsound(src.loc, 'sound/machines/click.ogg', 15, 1)
- if(do_after(user, 20, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
- if(!useResource(3, user)) return 0
- activate()
- A:ChangeTurf(/turf/closed/wall)
- return 1
- return 0
-
- if(2)
- if(istype(A, /turf/open/floor))
- if(checkResource(10, user))
- to_chat(user, "Building Airlock...")
- playsound(src.loc, 'sound/machines/click.ogg', 15, 1)
- if(do_after(user, 50, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
- if(!useResource(10, user)) return 0
- activate()
- var/obj/structure/machinery/door/airlock/T = new /obj/structure/machinery/door/airlock( A )
- T.autoclose = 1
- return 1
- return 0
- return 0
-
- if(3)
- if(istype(A, /turf/closed/wall))
- var/turf/closed/wall/WL = A
- if(WL.hull)
- return 0
- if(istype(A, /turf/closed/wall/r_wall) && !canRwall)
- return 0
- if(checkResource(5, user))
- to_chat(user, "Deconstructing Wall...")
- playsound(src.loc, 'sound/machines/click.ogg', 15, 1)
- if(do_after(user, 40, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
- if(!useResource(5, user)) return 0
- activate()
- A:ChangeTurf(/turf/open/floor/plating/airless)
- return 1
- return 0
-
- if(istype(A, /turf/open/floor) && !istype(A, /turf/open/floor/plating))
- if(checkResource(5, user))
- to_chat(user, "Deconstructing Floor...")
- playsound(src.loc, 'sound/machines/click.ogg', 15, 1)
- if(do_after(user, 50, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
- if(!useResource(5, user)) return 0
- activate()
- A:ChangeTurf(/turf/open/floor/plating/airless)
- return 1
- return 0
-
- if(istype(A, /obj/structure/machinery/door/airlock))
- if(checkResource(10, user))
- to_chat(user, "Deconstructing Airlock...")
- playsound(src.loc, 'sound/machines/click.ogg', 15, 1)
- if(do_after(user, 50, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
- if(!useResource(10, user)) return 0
- activate()
- qdel(A)
- return 1
- return 0
- return 0
- else
- to_chat(user, "ERROR: RCD in MODE: [mode] attempted use by [user]. Send this text #coderbus or an admin.")
- return 0
-
-/obj/item/device/rcd/proc/useResource(amount, mob/user)
- if(stored_matter < amount)
- return 0
- stored_matter -= amount
- desc = "A RCD. It currently holds [stored_matter]/30 matter-units."
- return 1
-
-/obj/item/device/rcd/proc/checkResource(amount, mob/user)
- return stored_matter >= amount
-
-/obj/item/ammo_rcd
- name = "compressed matter cartridge"
- desc = "Highly compressed matter for the RCD."
- icon = 'icons/obj/items/weapons/guns/legacy/old_bayguns.dmi'
- icon_state = "rcd"
- item_state = "rcdammo"
- opacity = FALSE
- density = FALSE
- anchored = FALSE
-
- matter = list("metal" = 30000,"glass" = 15000)
diff --git a/code/game/objects/items/devices/RSF.dm b/code/game/objects/items/devices/RSF.dm
deleted file mode 100644
index 29f84c7c6d0c..000000000000
--- a/code/game/objects/items/devices/RSF.dm
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-CONTAINS:
-RSF
-
-*/
-
-/obj/item/device/rsf
- name = "\improper Rapid-Service-Fabricator"
- desc = "A device used to rapidly deploy service items."
- icon = 'icons/obj/items/devices.dmi'
- icon_state = "rcd"
- opacity = FALSE
- density = FALSE
- anchored = FALSE
- var/stored_matter = 30
- var/mode = 1
- w_class = SIZE_MEDIUM
-
-/obj/item/device/rsf/get_examine_text(mob/user)
- . = ..()
- . += "It currently holds [stored_matter]/30 fabrication-units."
-
-/obj/item/device/rsf/attackby(obj/item/W, mob/user)
- ..()
- if (istype(W, /obj/item/ammo_rcd))
-
- if ((stored_matter + 10) > 30)
- to_chat(user, "The RSF can't hold any more matter.")
- return
-
- qdel(W)
-
- stored_matter += 10
- playsound(src.loc, 'sound/machines/click.ogg', 15, 1)
- to_chat(user, "The RSF now holds [stored_matter]/30 fabrication-units.")
- return
-
-/obj/item/device/rsf/attack_self(mob/user)
- ..()
- playsound(src.loc, 'sound/effects/pop.ogg', 15, 0)
- if (mode == 1)
- mode = 2
- to_chat(user, "Changed dispensing mode to 'Drinking Glass'")
- return
- if (mode == 2)
- mode = 3
- to_chat(user, "Changed dispensing mode to 'Paper'")
- return
- if (mode == 3)
- mode = 4
- to_chat(user, "Changed dispensing mode to 'Pen'")
- return
- if (mode == 4)
- mode = 5
- to_chat(user, "Changed dispensing mode to 'Dice Pack'")
- return
- if (mode == 5)
- mode = 6
- to_chat(user, "Changed dispensing mode to 'Cigarette'")
- return
- if (mode == 6)
- mode = 1
- to_chat(user, "Changed dispensing mode to 'Dosh'")
- return
- // Change mode
-
-/obj/item/device/rsf/afterattack(atom/A, mob/user, proximity)
-
- if(!proximity) return
-
- if(stored_matter <= 0)
- return
-
- if(!istype(A, /obj/structure/surface/table) && !istype(A, /turf/open/floor))
- return
-
- playsound(src.loc, 'sound/machines/click.ogg', 25, 1)
- var/obj/product
-
- switch(mode)
- if(1)
- product = new /obj/item/spacecash/c10()
- if(2)
- product = new /obj/item/reagent_container/food/drinks/drinkingglass()
- if(3)
- product = new /obj/item/paper()
- if(4)
- product = new /obj/item/tool/pen()
- if(5)
- product = new /obj/item/storage/pill_bottle/dice()
- if(6)
- product = new /obj/item/clothing/mask/cigarette()
-
- to_chat(user, "Dispensing [product ? product : "product"]...")
- product.forceMove(get_turf(A))
-
- stored_matter--
- to_chat(user, "The RSF now holds [stored_matter]/30 fabrication-units.")
diff --git a/code/game/objects/items/devices/RSP.dm b/code/game/objects/items/devices/RSP.dm
deleted file mode 100644
index cb61de1a77cc..000000000000
--- a/code/game/objects/items/devices/RSP.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-/obj/item/device/rsp
- name = "\improper Rapid-Seed-Producer (RSP)"
- desc = "A device used to rapidly deploy seeds."
- icon = 'icons/obj/items/devices.dmi'
- icon_state = "rsp"
- opacity = FALSE
- density = FALSE
- anchored = FALSE
- var/stored_matter = 0
- var/mode = 1
- w_class = SIZE_MEDIUM
diff --git a/code/game/objects/items/devices/binoculars.dm b/code/game/objects/items/devices/binoculars.dm
index 5da4704e0e78..3248115adfa8 100644
--- a/code/game/objects/items/devices/binoculars.dm
+++ b/code/game/objects/items/devices/binoculars.dm
@@ -403,6 +403,7 @@
COOLDOWN_START(designator, spotting_cooldown, 0)
/datum/action/item_action/specialist/spotter_target/action_activate()
+ . = ..()
if(!ishuman(owner))
return
var/mob/living/carbon/human/human = owner
diff --git a/code/game/objects/items/devices/cictablet.dm b/code/game/objects/items/devices/cictablet.dm
index 597886a0cb85..c53301295fe3 100644
--- a/code/game/objects/items/devices/cictablet.dm
+++ b/code/game/objects/items/devices/cictablet.dm
@@ -104,7 +104,7 @@
return FALSE
var/input = stripped_multiline_input(user, "Please write a message to announce to the [MAIN_SHIP_NAME]'s crew and all groundside personnel.", "Priority Announcement", "")
- if(!input || !COOLDOWN_FINISHED(src, announcement_cooldown) || !(user in view(1, src)))
+ if(!input || !COOLDOWN_FINISHED(src, announcement_cooldown) || !(user in dview(1, src)))
return FALSE
var/signed = null
diff --git a/code/game/objects/items/devices/defibrillator.dm b/code/game/objects/items/devices/defibrillator.dm
index 518fdb1a9591..2debcf82d7d0 100644
--- a/code/game/objects/items/devices/defibrillator.dm
+++ b/code/game/objects/items/devices/defibrillator.dm
@@ -108,13 +108,13 @@
if(ghost && (!check_client || ghost.client) && (!check_can_reenter || ghost.can_reenter_corpse))
return ghost
-/mob/living/carbon/human/proc/is_revivable()
+/mob/living/carbon/human/proc/is_revivable(ignore_heart = FALSE)
if(isnull(internal_organs_by_name) || isnull(internal_organs_by_name["heart"]))
return FALSE
var/datum/internal_organ/heart/heart = internal_organs_by_name["heart"]
var/obj/limb/head = get_limb("head")
- if(chestburst || !head || head.status & LIMB_DESTROYED || !heart || heart.organ_status >= ORGAN_BROKEN || !has_brain() || status_flags & PERMANENTLY_DEAD)
+ if(chestburst || !head || head.status & LIMB_DESTROYED || !ignore_heart && (!heart || heart.organ_status >= ORGAN_BROKEN) || !has_brain() || status_flags & PERMANENTLY_DEAD)
return FALSE
return TRUE
diff --git a/code/game/objects/items/devices/drone_devices.dm b/code/game/objects/items/devices/drone_devices.dm
deleted file mode 100644
index 0e22b64bf67f..000000000000
--- a/code/game/objects/items/devices/drone_devices.dm
+++ /dev/null
@@ -1,241 +0,0 @@
-
-
-//Simple borg hand.
-//Limited use.
-/obj/item/device/gripper
- name = "magnetic gripper"
- desc = "A simple grasping tool for synthetic assets."
- icon_state = "gripper"
-
- //Has a list of items that it can hold.
- var/list/can_hold = list(
- /obj/item/cell,
- /obj/item/circuitboard,
- /obj/item/stock_parts,
- /obj/item/frame,
- /obj/item/tank,
- /obj/item/stock_parts/smes_coil
- )
-
- //Item currently being held.
- var/obj/item/wrapped = null
-
-/obj/item/device/gripper/paperwork
- name = "paperwork gripper"
- desc = "A simple grasping tool for clerical work."
-
- can_hold = list(
- /obj/item/clipboard,
- /obj/item/paper,
- /obj/item/paper_bundle,
- /obj/item/card/id,
- )
-
-/obj/item/device/gripper/attack_self(mob/user as mob)
- ..()
-
- if(wrapped)
- wrapped.attack_self(user)
-
-/obj/item/device/gripper/verb/drop_item()
-
- set name = "Drop Item"
- set desc = "Release an item from your magnetic gripper."
- set category = "Drone"
- set src in usr
- if(!wrapped)
- //There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z
- for(var/obj/item/thing in src.contents)
- thing.forceMove(get_turf(src))
- return
-
- if(wrapped.loc != src)
- wrapped = null
- return
-
- to_chat(src.loc, SPAN_WARNING("You drop \the [wrapped]."))
- wrapped.forceMove(get_turf(src))
- wrapped = null
- //update_icon()
-
-/obj/item/device/gripper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- return
-
-/obj/item/device/gripper/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)
-
- if(!target || !proximity) //Target is invalid or we are not adjacent.
- return
-
- //There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z
- if(!wrapped)
- for(var/obj/item/thing in src.contents)
- wrapped = thing
- break
-
- if(wrapped) //Already have an item.
-
- //Temporary put wrapped into user so target's attackby() checks pass.
- wrapped.forceMove(user)
-
- //Pass the attack on to the target. This might delete/relocate wrapped.
- target.attackby(wrapped,user)
-
- //If wrapped was neither deleted nor put into target, put it back into the gripper.
- if(wrapped && user && (wrapped.loc == user))
- wrapped.forceMove(src)
- else
- wrapped = null
- return
-
- else if(istype(target,/obj/item)) //Check that we're not pocketing a mob.
-
- //...and that the item is not in a container.
- if(!isturf(target.loc))
- return
-
- var/obj/item/I = target
-
- //Check if the item is blacklisted.
- var/grab = 0
- for(var/typepath in can_hold)
- if(istype(I,typepath))
- grab = 1
- break
-
- //We can grab the item, finally.
- if(grab)
- to_chat(user, "You collect \the [I].")
- I.forceMove(src)
- wrapped = I
- return
- else
- to_chat(user, SPAN_DANGER("Your gripper cannot hold \the [target]."))
-
- else if(istype(target,/obj/structure/machinery/power/apc))
- var/obj/structure/machinery/power/apc/A = target
- if(A.opened)
- if(A.cell)
-
- wrapped = A.cell
-
- A.cell.add_fingerprint(user)
- A.cell.update_icon()
- A.cell.forceMove(src)
- A.cell = null
-
- A.charging = 0
- A.update_icon()
-
- user.visible_message(SPAN_DANGER("[user] removes the power cell from [A]!"), "You remove the power cell.")
-
-
-
-
-
-
-
-//TODO: Matter decompiler.
-/obj/item/device/matter_decompiler
- name = "matter decompiler"
- desc = "Eating trash, bits of glass, or other debris will replenish your stores."
- icon_state = "decompiler"
-
- //Metal, glass, wood, plastic.
- var/list/stored_comms = list(
- "metal" = 0,
- "glass" = 0,
- "wood" = 0,
- "plastic" = 0
- )
-
-/obj/item/device/matter_decompiler/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- return
-
-/obj/item/device/matter_decompiler/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)
-
- if(!proximity) return //Not adjacent.
-
- //We only want to deal with using this on turfs. Specific items aren't important.
- var/turf/T = get_turf(target)
- if(!istype(T))
- return
-
- //Used to give the right message.
- var/grabbed_something = 0
-
- for(var/mob/M in T)
- if(istype(M,/mob/living/simple_animal/lizard) || istype(M,/mob/living/simple_animal/mouse))
- src.loc.visible_message(SPAN_DANGER("[src.loc] sucks [M] into its decompiler. There's a horrible crunching noise."),SPAN_DANGER("It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises."))
- new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
- qdel(M)
- stored_comms["wood"]++
- stored_comms["wood"]++
- stored_comms["plastic"]++
- stored_comms["plastic"]++
- return
- else
- continue
-
- for(var/obj/W in T)
- //Different classes of items give different commodities.
- if (istype(W,/obj/item/trash/cigbutt))
- stored_comms["plastic"]++
- else if(istype(W,/obj/effect/spider/spiderling))
- stored_comms["wood"]++
- stored_comms["wood"]++
- stored_comms["plastic"]++
- stored_comms["plastic"]++
- else if(istype(W,/obj/item/light_bulb))
- var/obj/item/light_bulb/L = W
- if(L.status >= 2) //In before someone changes the inexplicably local defines. ~ Z
- stored_comms["metal"]++
- stored_comms["glass"]++
- else
- continue
- else if(istype(W,/obj/effect/decal/remains/robot))
- stored_comms["metal"]++
- stored_comms["metal"]++
- stored_comms["plastic"]++
- stored_comms["plastic"]++
- stored_comms["glass"]++
- else if(istype(W,/obj/item/trash))
- stored_comms["metal"]++
- stored_comms["plastic"]++
- stored_comms["plastic"]++
- stored_comms["plastic"]++
- else if(istype(W,/obj/effect/decal/cleanable/blood/gibs/robot))
- stored_comms["metal"]++
- stored_comms["metal"]++
- stored_comms["glass"]++
- stored_comms["glass"]++
- else if(istype(W,/obj/item/ammo_casing))
- stored_comms["metal"]++
- else if(istype(W,/obj/item/shard/shrapnel))
- stored_comms["metal"]++
- stored_comms["metal"]++
- stored_comms["metal"]++
- else if(istype(W,/obj/item/shard))
- stored_comms["glass"]++
- stored_comms["glass"]++
- stored_comms["glass"]++
- else if(istype(W,/obj/item/reagent_container/food/snacks/grown))
- stored_comms["wood"]++
- stored_comms["wood"]++
- stored_comms["wood"]++
- stored_comms["wood"]++
- else if(istype(W,/obj/item/ammo_magazine))
- var/obj/item/ammo_magazine/AM = W
- if(AM.current_rounds)
- continue
- stored_comms["metal"]++
- else
- continue
-
- qdel(W)
- grabbed_something = 1
-
- if(grabbed_something)
- to_chat(user, SPAN_NOTICE(" You deploy your decompiler and clear out the contents of \the [T]."))
- else
- to_chat(user, SPAN_DANGER("Nothing on \the [T] is useful to you."))
- return
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index 8d5e3cc752ff..de2a328de370 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -15,7 +15,7 @@
ground_offset_x = 2
ground_offset_y = 6
- actions_types = list(/datum/action/item_action)
+ actions_types = list(/datum/action/item_action/toggle)
var/on = FALSE
var/raillight_compatible = TRUE //Can this be turned into a rail light ?
var/toggleable = TRUE
@@ -62,9 +62,9 @@
on = !on
set_light_on(on)
update_icon()
- for(var/X in actions)
- var/datum/action/A = X
- A.update_button_icon()
+ for(var/xman in actions)
+ var/datum/action/active = xman
+ active.update_button_icon()
return TRUE
@@ -73,68 +73,71 @@
on = FALSE
set_light_on(on)
update_icon()
- for(var/X in actions)
- var/datum/action/A = X
- A.update_button_icon()
+ for(var/xman in actions)
+ var/datum/action/active = xman
+ active.update_button_icon()
return 1
return 0
-/obj/item/device/flashlight/attackby(obj/item/I as obj, mob/user as mob)
- if(HAS_TRAIT(I, TRAIT_TOOL_SCREWDRIVER))
+/obj/item/device/flashlight/attackby(obj/item/item as obj, mob/user as mob)
+ if(HAS_TRAIT(item, TRAIT_TOOL_SCREWDRIVER))
if(!raillight_compatible) //No fancy messages, just no
return
if(on)
to_chat(user, SPAN_WARNING("Turn off [src] first."))
return
if(isstorage(loc))
- var/obj/item/storage/S = loc
- S.remove_from_storage(src)
+ var/obj/item/storage/container = loc
+ container.remove_from_storage(src)
if(loc == user)
user.drop_inv_item_on_ground(src) //This part is important to make sure our light sources update, as it calls dropped()
- var/obj/item/attachable/flashlight/F = new(src.loc)
- user.put_in_hands(F) //This proc tries right, left, then drops it all-in-one.
+ var/obj/item/attachable/flashlight/flash = new(src.loc)
+ user.put_in_hands(flash) //This proc tries right, left, then drops it all-in-one.
to_chat(user, SPAN_NOTICE("You modify [src]. It can now be mounted on a weapon."))
- to_chat(user, SPAN_NOTICE("Use a screwdriver on [F] to change it back."))
+ to_chat(user, SPAN_NOTICE("Use a screwdriver on [flash] to change it back."))
qdel(src) //Delete da old flashlight
return
else
..()
-/obj/item/device/flashlight/attack(mob/living/M as mob, mob/living/user as mob)
+/obj/item/device/flashlight/attack(mob/living/carbon/human/being as mob, mob/living/user as mob)
add_fingerprint(user)
if(on && user.zone_selected == "eyes")
if((user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
- if((!ishuman(user) || SSticker) && SSticker.mode.name != "monkey") //don't have dexterity
+ if (!(ishuman(user) || SSticker) && SSticker.mode.name != "monkey") //don't have dexterity
to_chat(user, SPAN_NOTICE("You don't have the dexterity to do this!"))
return
- var/mob/living/carbon/human/H = M //mob has protective eyewear
- if(ishuman(H) && ((H.head && H.head.flags_inventory & COVEREYES) || (H.wear_mask && H.wear_mask.flags_inventory & COVEREYES) || (H.glasses && H.glasses.flags_inventory & COVEREYES)))
- to_chat(user, SPAN_NOTICE("You're going to need to remove that [(H.head && H.head.flags_inventory & COVEREYES) ? "helmet" : (H.wear_mask && H.wear_mask.flags_inventory & COVEREYES) ? "mask": "glasses"] first."))
+ var/mob/living/carbon/human/beingB = being //mob has protective eyewear
+ if(ishuman(beingB) && ((beingB.head && beingB.head.flags_inventory & COVEREYES) || (beingB.wear_mask && beingB.wear_mask.flags_inventory & COVEREYES) || (beingB.glasses && beingB.glasses.flags_inventory & COVEREYES)))
+ to_chat(user, SPAN_NOTICE("You're going to need to remove [(beingB.head && beingB.head.flags_inventory & COVEREYES) ? "that helmet" : (beingB.wear_mask && beingB.wear_mask.flags_inventory & COVEREYES) ? "that mask": "those glasses"] first."))
return
- if(M == user) //they're using it on themselves
- M.flash_eyes()
- M.visible_message(SPAN_NOTICE("[M] directs [src] to \his eyes."), \
- SPAN_NOTICE("You wave the light in front of your eyes! Trippy!"))
+ if(being == user) //they're using it on themselves
+ being.flash_eyes()
+ being.visible_message(SPAN_NOTICE("[being] directs [src] to [being.p_their()] eyes."), \
+ SPAN_NOTICE("You wave the light in front of your eyes! Wow, that's trippy!"))
return
- user.visible_message(SPAN_NOTICE("[user] directs [src] to [M]'s eyes."), \
- SPAN_NOTICE("You direct [src] to [M]'s eyes."))
-
- if(istype(M, /mob/living/carbon/human)) //robots and aliens are unaffected
- if(M.stat == DEAD || M.sdisabilities & DISABILITY_BLIND) //mob is dead or fully blind
- to_chat(user, SPAN_NOTICE("[M] pupils does not react to the light!"))
- else //they're okay!
- M.flash_eyes()
- to_chat(user, SPAN_NOTICE("[M]'s pupils narrow."))
+ user.visible_message(SPAN_NOTICE("[user] directs [src] to [being]'s eyes."), \
+ SPAN_NOTICE("You direct [src] to [being]'s eyes."))
+
+ if(ishuman_strict(being)) //robots and aliens are unaffected
+ var/datum/internal_organ/eyes/eyes = being.internal_organs_by_name["eyes"]
+ var/datum/internal_organ/brain/brain = being.internal_organs_by_name["brain"]
+ if(being.stat == DEAD || being.sdisabilities & DISABILITY_BLIND || eyes.organ_status == ORGAN_BROKEN || brain.organ_status == ORGAN_BROKEN) //mob is dead, fully blind, or their eyes are
+ to_chat(user, SPAN_NOTICE("[being]'s pupils do not react to the light!"))
+ else //they're okay! Well, probably
+ being.flash_eyes()
+ to_chat(user, SPAN_NOTICE("[being]'s pupils narrow."))
+ return
else
return ..()
-/obj/item/device/flashlight/attack_alien(mob/living/carbon/xenomorph/M)
+/obj/item/device/flashlight/attack_alien(mob/living/carbon/xenomorph/being)
. = ..()
if(on && can_be_broken)
@@ -147,14 +150,75 @@
/obj/item/device/flashlight/pen
name = "penlight"
- desc = "A pen-sized light, used by medical staff."
+ desc = "A pen-sized light, used by medical staff to check the condition of eyes, brain, and the overall awareness of patients."
icon_state = "penlight"
item_state = ""
+ flags_equip_slot = SLOT_WAIST|SLOT_EAR|SLOT_SUIT_STORE
flags_atom = FPRINT|CONDUCT
light_range = 2
w_class = SIZE_TINY
+ throw_speed = SPEED_VERY_FAST
+ throw_range = 15
+ matter = list("metal" = 10,"glass" = 5)
raillight_compatible = 0
+/obj/item/device/flashlight/pen/attack(mob/living/carbon/human/being as mob, mob/living/user as mob)
+ add_fingerprint(user)
+ if(user.a_intent == INTENT_HELP)
+ if(on && user.zone_selected == "eyes")
+ if(!ishuman_strict(being)) //robots and aliens are unaffected
+ return
+ var/reaction = null
+ if(isnull(being.internal_organs_by_name))
+ reaction = "discover that indeed [being.p_they()] have nothing to be checked"
+ return // they have no organs somehow
+ if(being == user) //they're using it on themselves
+ being.flash_eyes()
+ being.visible_message(SPAN_NOTICE("[being] directs [src] to [being.p_their()] eyes."), \
+ SPAN_NOTICE("You wave the light in front of your eyes! Wow, that's trippy!"))
+ return
+ if(being.stat == DEAD || (being.status_flags&FAKEDEATH))
+ reaction = "conclude that [being.p_their()] eyes are completely lifeless, [being.p_they()] must have passed away"
+ else
+ var/datum/internal_organ/eyes/eyes = being.internal_organs_by_name["eyes"]
+ var/datum/internal_organ/brain/brain = being.internal_organs_by_name["brain"]
+ if(skillcheck(user, SKILL_MEDICAL, SKILL_MEDICAL_MEDIC))
+ if(eyes)
+ switch(eyes.organ_status)
+ if(ORGAN_LITTLE_BRUISED)
+ being.flash_eyes()
+ reaction = "notice that [being.p_their()] eyes are reacting to the light, but [being.p_their()] pupils seen to react sluggishly and with small delays, [being.p_their()] vision is probably a little impaired"
+ if(ORGAN_BRUISED)
+ being.flash_eyes()
+ reaction = "observe that [being.p_their()] eyes are unrealiably reacting to the light, with [being.p_their()] pupils reacting very sluggishly and with noticeable delays, it is probable that [being.p_their()] vision is remarkably impaired"
+ if(ORGAN_BROKEN)
+ reaction = "notice that [being.p_their()] eyes are not reacting to the light, and the pupils of both eyes are not constricting with the light shine at all, [being.p_they()] is probably blind"
+ else
+ being.flash_eyes()
+ reaction = "perceive that [being.p_their()] eyes and pupils are normally reacting to the light, [being.p_they()] is probably seeing without problems"
+ if(brain)
+ if(reaction)
+ reaction += ". You also "
+ switch(brain.organ_status)
+ if(ORGAN_LITTLE_BRUISED)
+ being.flash_eyes()
+ reaction += "notice that the pupils are consensually constricting with a significant delay when light is separately applied to each eye, meaning that [being.p_they()] possibly have subtle brain damage"
+ if(ORGAN_BRUISED)
+ being.flash_eyes()
+ reaction += "notice that the pupils are not consensually constricting when light is separately applied to each eye, meaning possible brain damage"
+ if(ORGAN_BROKEN)
+ reaction += "notice that the pupils have different sizes and are assymmetric, [being.p_they()] possibly have severe brain damage"
+ else
+ being.flash_eyes()
+ reaction += "notice that the pupils are consensually and normally constricting when light is separately applied to each eye, [being.p_their()] brain is probably fine"
+ else
+ reaction = "can't see anything at all, weirdly enough"
+ else
+ being.flash_eyes()
+ reaction = "don't really know what you are looking for, you don't know anything about medicine"
+ user.visible_message("[user] directs [src] to [being]'s eyes.", "You point [src] to [being.p_their()] eyes to begin analysing them further and... you [reaction].")
+ return ..()
+
/obj/item/device/flashlight/drone
name = "low-power flashlight"
desc = "A miniature lamp, that might be used by small robots."
@@ -364,9 +428,9 @@
user.visible_message(SPAN_NOTICE("[user] activates the flare."), SPAN_NOTICE("You pull the cord on the flare, activating it!"))
playsound(src,'sound/handling/flare_activate_2.ogg', 50, 1) //cool guy sound
turn_on()
- var/mob/living/carbon/U = user
- if(istype(U) && !U.throw_mode)
- U.toggle_throw_mode(THROW_MODE_NORMAL)
+ var/mob/living/carbon/enjoyer = user
+ if(istype(enjoyer) && !enjoyer.throw_mode)
+ enjoyer.toggle_throw_mode(THROW_MODE_NORMAL)
/obj/item/device/flashlight/flare/proc/activate_signal(mob/living/carbon/human/user)
return
diff --git a/code/game/objects/items/devices/helmet_visors.dm b/code/game/objects/items/devices/helmet_visors.dm
index 8f921a62f3f5..e2005a841bc3 100644
--- a/code/game/objects/items/devices/helmet_visors.dm
+++ b/code/game/objects/items/devices/helmet_visors.dm
@@ -146,6 +146,7 @@
return
/datum/action/item_action/view_publications/helmet_visor/action_activate()
+ . = ..()
var/obj/item/device/helmet_visor/medical/advanced/medical_visor = locate() in holder_item
if(!medical_visor)
diff --git a/code/game/objects/items/devices/motion_detector.dm b/code/game/objects/items/devices/motion_detector.dm
index 3551e3a02bef..f68295001f92 100644
--- a/code/game/objects/items/devices/motion_detector.dm
+++ b/code/game/objects/items/devices/motion_detector.dm
@@ -33,9 +33,9 @@
var/long_range_cooldown = 2
var/blip_type = "detector"
var/iff_signal = FACTION_MARINE
- actions_types = list(/datum/action/item_action)
+ actions_types = list(/datum/action/item_action/toggle)
var/scanning = FALSE // controls if MD is in process of scan
- var/datum/shape/rectangle/range_bounds
+ var/datum/shape/rectangle/square/range_bounds
var/long_range_locked = FALSE //only long-range MD
var/ping_overlay
@@ -48,7 +48,7 @@
/obj/item/device/motiondetector/Initialize()
. = ..()
- range_bounds = new //Just creating a rectangle datum
+ range_bounds = new //Just creating a square datum
update_icon()
/obj/item/device/motiondetector/Destroy()
@@ -215,12 +215,7 @@
if(!istype(cur_turf))
return
- if(!range_bounds)
- range_bounds = new/datum/shape/rectangle
- range_bounds.center_x = cur_turf.x
- range_bounds.center_y = cur_turf.y
- range_bounds.width = detector_range * 2
- range_bounds.height = detector_range * 2
+ range_bounds.set_shape(cur_turf.x, cur_turf.y, detector_range * 2)
var/list/ping_candidates = SSquadtree.players_in_range(range_bounds, cur_turf.z, QTREE_EXCLUDE_OBSERVER | QTREE_SCAN_MOBS)
diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm
index a92135b9d7ed..73e5b86a69eb 100644
--- a/code/game/objects/items/devices/multitool.dm
+++ b/code/game/objects/items/devices/multitool.dm
@@ -18,6 +18,7 @@
matter = list("metal" = 50,"glass" = 20)
inherent_traits = list(TRAIT_TOOL_MULTITOOL)
+ preferred_storage = list(/obj/item/clothing/accessory/storage/tool_webbing = WEAR_ACCESSORY)
var/hack_speed = 10 SECONDS // Only used for vendors right now
var/next_scan
@@ -46,7 +47,7 @@
/obj/item/device/multitool/attack_self(mob/user)
..()
- if(world.time < next_scan || !ishuman(user) || !skillcheck(user,SKILL_ENGINEER,SKILL_ENGINEER_TRAINED))
+ if(world.time < next_scan || !ishuman(user) || !skillcheck(user,SKILL_ENGINEER,SKILL_ENGINEER_NOVICE))
return
next_scan = world.time + 15
diff --git a/code/game/objects/items/devices/pinpointer.dm b/code/game/objects/items/devices/pinpointer.dm
index 2f5d9ffe9d5f..3dd9fdaf1253 100644
--- a/code/game/objects/items/devices/pinpointer.dm
+++ b/code/game/objects/items/devices/pinpointer.dm
@@ -126,10 +126,10 @@
mode = 1
var/locationx = tgui_input_real_number(usr, "Please input the x coordinate to search for.", "Location?")
- if(!locationx || !(usr in view(1,src)))
+ if(!locationx || !(usr in dview(1, src)))
return
var/locationy = tgui_input_real_number(usr, "Please input the y coordinate to search for.", "Location?")
- if(!locationy || !(usr in view(1,src)))
+ if(!locationy || !(usr in dview(1, src)))
return
var/turf/Z = get_turf(src)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 309c7ff20f8b..0e7680cd2f7d 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -329,7 +329,7 @@ FORENSIC SCANNER
if(!(istype(user, /mob/living/carbon/human) || SSticker) && SSticker.mode.name != "monkey")
to_chat(user, SPAN_DANGER("You don't have the dexterity to do this!"))
return
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You do not know how to use the [name]."))
return
if(!istype(O))
@@ -340,6 +340,21 @@ FORENSIC SCANNER
ex_potential = 0
int_potential = 0
rad_potential = 0
+
+ if(istype(O, /obj/item/ammo_magazine/flamer_tank))
+ var/obj/item/ammo_magazine/flamer_tank/tank = O
+ if(!length(tank.reagents.reagent_list))
+ to_chat(user, SPAN_NOTICE("No fuel detected in [O]"))
+ return
+ var/result
+ var/datum/reagent/chem = tank.reagents.reagent_list[1]
+ result += SPAN_BLUE("Fuel Statistics:")
+ result += SPAN_BLUE("
Intensity: [min(chem.intensityfire, tank.max_intensity)]")
+ result += SPAN_BLUE("
Duration: [min(chem.durationfire, tank.max_duration)]")
+ result += SPAN_BLUE("
Range: [min(chem.rangefire, tank.max_range)]")
+ to_chat(user, SPAN_NOTICE("[result]"))
+ return
+
if(istype(O,/obj/item/explosive))
var/obj/item/explosive/E = O
if(!E.customizable)
diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm
deleted file mode 100644
index 564b3e41f591..000000000000
--- a/code/game/objects/items/devices/suit_cooling.dm
+++ /dev/null
@@ -1,179 +0,0 @@
-/obj/item/device/suit_cooling_unit
- name = "portable suit cooling unit"
- desc = "A portable heat sink and liquid cooled radiator that can be hooked up to a space suit's existing temperature controls to provide industrial levels of cooling."
- w_class = SIZE_LARGE
- icon_state = "suitcooler0"
- flags_equip_slot = SLOT_BACK //you can carry it on your back if you want, but it won't do anything unless attached to suit storage
-
- //copied from tank.dm
- flags_atom = FPRINT|CONDUCT
- force = 5
- throwforce = 10
- throw_speed = SPEED_FAST
- throw_range = 4
-
-
-
- var/on = 0 //is it turned on?
- var/cover_open = 0 //is the cover open?
- var/obj/item/cell/cell
- var/max_cooling = 12 //in degrees per second - probably don't need to mess with heat capacity here
- var/charge_consumption = 16.6 //charge per second at max_cooling
- var/thermostat = T20C
-
- //TODO: make it heat up the surroundings when not in space
-
-/obj/item/device/suit_cooling_unit/Initialize(mapload, ...)
- . = ..()
-
- START_PROCESSING(SSobj, src)
-
- cell = new/obj/item/cell(src) //comes with the crappy default power cell - high-capacity ones shouldn't be hard to find
-
-/obj/item/device/suit_cooling_unit/Destroy()
- STOP_PROCESSING(SSobj, src)
- return ..()
-
-/obj/item/device/suit_cooling_unit/process()
- if (!on || !cell)
- return
-
- if (!ismob(loc))
- return
-
- if (!attached_to_suit(loc)) //make sure they have a suit and we are attached to it
- return
-
- var/mob/living/carbon/human/H = loc
-
- var/efficiency = 1 - H.get_pressure_weakness() //you need to have a good seal for effective cooling
- var/env_temp = get_environment_temperature() //wont save you from a fire
- var/temp_adj = min(H.bodytemperature - max(thermostat, env_temp), max_cooling)
-
- if (temp_adj < 0.5) //only cools, doesn't heat, also we don't need extreme precision
- return
-
- var/charge_usage = (temp_adj/max_cooling)*charge_consumption
-
- H.bodytemperature -= temp_adj*efficiency
- H.recalculate_move_delay = TRUE
-
- cell.use(charge_usage)
-
- if(cell.charge <= 0)
- turn_off()
-
-/obj/item/device/suit_cooling_unit/proc/get_environment_temperature()
- if (ishuman(loc))
- var/mob/living/carbon/human/H = loc
- return H.return_temperature()
-
- var/turf/T = get_turf(src)
- return T.return_temperature()
-
-/obj/item/device/suit_cooling_unit/proc/attached_to_suit(mob/M)
- if (!ishuman(M))
- return 0
-
- var/mob/living/carbon/human/H = M
-
- if (!H.wear_suit || H.s_store != src)
- return 0
-
- return 1
-
-/obj/item/device/suit_cooling_unit/proc/turn_on()
- if(!cell)
- return
- if(cell.charge <= 0)
- return
-
- on = 1
- updateicon()
-
-/obj/item/device/suit_cooling_unit/proc/turn_off()
- if (ismob(src.loc))
- var/mob/M = src.loc
- M.show_message("\The [src] clicks and whines as it powers down.", SHOW_MESSAGE_AUDIBLE) //let them know in case it's run out of power.
- on = 0
- updateicon()
-
-/obj/item/device/suit_cooling_unit/attack_self(mob/user)
- ..()
-
- if(cover_open && cell)
- if(ishuman(user))
- user.put_in_hands(cell)
- else
- cell.forceMove(get_turf(loc))
-
- cell.add_fingerprint(user)
- cell.update_icon()
-
- to_chat(user, "You remove [cell].")
- src.cell = null
- updateicon()
- return
-
- //TODO use a UI like the air tanks
- if(on)
- turn_off()
- else
- turn_on()
- if (on)
- to_chat(user, "You switch on [src].")
-
-/obj/item/device/suit_cooling_unit/attackby(obj/item/W as obj, mob/user as mob)
- if (HAS_TRAIT(W, TRAIT_TOOL_SCREWDRIVER))
- if(cover_open)
- cover_open = 0
- to_chat(user, "You screw the panel into place.")
- else
- cover_open = 1
- to_chat(user, "You unscrew the panel.")
- updateicon()
- return
-
- if (istype(W, /obj/item/cell))
- if(cover_open)
- if(cell)
- to_chat(user, "There is \a [cell] already installed here.")
- else
- if(user.drop_held_item())
- W.forceMove(src)
- cell = W
- to_chat(user, "You insert [cell].")
- updateicon()
- return
-
- return ..()
-
-/obj/item/device/suit_cooling_unit/proc/updateicon()
- if (cover_open)
- if (cell)
- icon_state = "suitcooler1"
- else
- icon_state = "suitcooler2"
- else
- icon_state = "suitcooler0"
-
-/obj/item/device/suit_cooling_unit/get_examine_text(mob/user)
- . = ..()
- if (on)
- if (attached_to_suit(src.loc))
- . += "It's switched on and running."
- else
- . += "It's switched on, but not attached to anything."
- else
- . += "It is switched off."
-
- if (cover_open)
- if(cell)
- . += "The panel is open, exposing [cell]."
- else
- . += "The panel is open."
-
- if (cell)
- . += "The charge meter reads [floor(cell.percent())]%."
- else
- . += "It doesn't have a power cell installed."
diff --git a/code/game/objects/items/devices/teleportation.dm b/code/game/objects/items/devices/teleportation.dm
index d64e717a3095..003f3152800d 100644
--- a/code/game/objects/items/devices/teleportation.dm
+++ b/code/game/objects/items/devices/teleportation.dm
@@ -152,7 +152,7 @@
else
L["[com.id] (Inactive)"] = com.locked
var/list/turfs = list( )
- for(var/turf/T in orange(10))
+ for(var/turf/T as anything in ORANGE_TURFS(10, src))
if(T.x>world.maxx-8 || T.x<8) continue //putting them at the edge is dumb
if(T.y>world.maxy-8 || T.y<8) continue
turfs += T
diff --git a/code/game/objects/items/devices/walkman.dm b/code/game/objects/items/devices/walkman.dm
index 42c03d757dbd..bef8e8f5ff79 100644
--- a/code/game/objects/items/devices/walkman.dm
+++ b/code/game/objects/items/devices/walkman.dm
@@ -269,6 +269,7 @@
button.name = name
/datum/action/item_action/walkman/play_pause/action_activate()
+ . = ..()
if(target)
var/obj/item/device/walkman/WM = target
WM.attack_self(owner)
@@ -282,6 +283,7 @@
button.name = name
/datum/action/item_action/walkman/next_song/action_activate()
+ . = ..()
if(target)
var/obj/item/device/walkman/WM = target
WM.next_song(owner)
@@ -295,6 +297,7 @@
button.name = name
/datum/action/item_action/walkman/restart_song/action_activate()
+ . = ..()
if(target)
var/obj/item/device/walkman/WM = target
WM.restart_song(owner)
diff --git a/code/game/objects/items/devices/whistle.dm b/code/game/objects/items/devices/whistle.dm
index 331df3ffa006..07196a3e1bb9 100644
--- a/code/game/objects/items/devices/whistle.dm
+++ b/code/game/objects/items/devices/whistle.dm
@@ -5,7 +5,7 @@
w_class = SIZE_TINY
flags_atom = FPRINT|CONDUCT
flags_equip_slot = SLOT_FACE
- actions_types = list(/datum/action/item_action)
+ actions_types = list(/datum/action/item_action/toggle/use)
var/volume = 60
var/spam_cooldown_time = 10 SECONDS
@@ -51,7 +51,6 @@
usr.put_in_l_hand(src)
add_fingerprint(usr)
-
/obj/item/device/hailer
name = "hailer"
desc = "Used by obese officers to save their breath for running."
diff --git a/code/game/objects/items/explosives/explosive.dm b/code/game/objects/items/explosives/explosive.dm
index 1bd6985bc015..0be81ba8a0ed 100644
--- a/code/game/objects/items/explosives/explosive.dm
+++ b/code/game/objects/items/explosives/explosive.dm
@@ -259,7 +259,7 @@
to_chat(usr, SPAN_DANGER("This is beyond your understanding..."))
return
- if(!skillcheck(H, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(H, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(usr, SPAN_DANGER("You have no idea how to use this..."))
return
diff --git a/code/game/objects/items/explosives/grenades/marines.dm b/code/game/objects/items/explosives/grenades/marines.dm
index 1cd3e1577c57..fef62ab6a835 100644
--- a/code/game/objects/items/explosives/grenades/marines.dm
+++ b/code/game/objects/items/explosives/grenades/marines.dm
@@ -97,6 +97,8 @@
falloff_mode = EXPLOSION_FALLOFF_SHAPE_LINEAR
/obj/item/explosive/grenade/high_explosive/frag/toy
+ AUTOWIKI_SKIP(TRUE)
+
name = "toy HEFA grenade"
desc = "High-Explosive Fragmenting-Antipersonnel. A small, but deceptively strong fragmentation grenade that has been phasing out the M15 fragmentation grenades alongside the M40 HEDP. Capable of being loaded in the M92 Launcher, or thrown by hand. Wait, the labeling on the side indicates this is a toy, what the hell?"
explosion_power = 0
@@ -465,6 +467,187 @@
icon_state = "grenade_phos_clf"
item_state = "grenade_phos_clf"
+/obj/item/explosive/grenade/sebb
+ name = "\improper G2 Electroshock grenade"
+ desc = "This is a G2 Electroshock Grenade. Produced by Armat Battlefield Systems, it's sometimes referred to as the Sonic Electric Ball Breaker, \
+ after a rash of incidents where the intense 1.2 gV sonic payload caused... rupturing. \
+ A bounding landmine mode is available for this weapon which activates a small drill to self-bury itself when planted. Simply plant it at your feet and walk away."
+ icon_state = "grenade_sebb"
+ item_state = "grenade_sebb"
+ det_time = 3 SECONDS
+ underslug_launchable = TRUE
+ /// Maximum range of effect
+ var/range = 5
+ /// Maximum possible damage before falloff.
+ var/damage = 110
+ /// Factor to mutiply the effect range has on damage.
+ var/falloff_dam_reduction_mult = 20
+ /// Post falloff calc damage is divided by this to get xeno slowdown
+ var/xeno_slowdown_numerator = 12
+ /// Post falloff calc damage is multipled by this to get human stamina damage
+ var/human_stam_dam_factor = 0.9
+
+/obj/item/explosive/grenade/sebb/get_examine_text(mob/user)
+ . = ..()
+ . += SPAN_NOTICE("To put into mine mode, plant at feet.")
+
+/obj/item/explosive/grenade/sebb/afterattack(atom/target, mob/user, proximity)
+ var/turf/user_turf = get_turf(user)
+ if(active)
+ return
+
+ if(!isturf(target))
+ return
+
+ if(user.action_busy)
+ return
+
+ if(target != get_turf(user))
+ return
+
+ if(locate(/obj/item/explosive/mine) in get_turf(src))
+ to_chat(user, SPAN_WARNING("There already is a mine at this position!"))
+ return
+
+ if(antigrief_protection && user.faction == FACTION_MARINE && explosive_antigrief_check(src, user))
+ to_chat(user, SPAN_WARNING("\The [name]'s safe-area accident inhibitor prevents you from planting!"))
+ msg_admin_niche("[key_name(user)] attempted to plant \a [name] in [get_area(src)] [ADMIN_JMP(src.loc)]")
+ return
+
+ if(ishuman(user))
+ var/mob/living/carbon/human/human = user
+ if(!human.allow_gun_usage)
+ to_chat(user, SPAN_WARNING("Your programming prevents you from using this!"))
+ return
+
+ if(user_turf && (user_turf.density || locate(/obj/structure/fence) in user_turf))
+ to_chat(user, SPAN_WARNING("You can't plant a mine here."))
+ return
+
+ if(Adjacent(/obj/item/explosive/mine)) // bit more strict on this than normal mines
+ to_chat(user, SPAN_WARNING("Too close to another mine! Plant it somewhere less obvious."))
+ return
+
+ user.visible_message(SPAN_NOTICE("[user] starts deploying [src]."),
+ SPAN_NOTICE("You switch [src] into landmine mode and start placing it..."))
+ playsound(user.loc, 'sound/effects/thud.ogg', 40)
+ if(!do_after(user, 5 SECONDS * user.get_skill_duration_multiplier(SKILL_CONSTRUCTION), INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
+ to_chat(user, SPAN_NOTICE("You stop planting."))
+ return
+
+ user.visible_message(SPAN_NOTICE("[user] finishes deploying [src]."),
+ SPAN_NOTICE("You finish deploying [src]."))
+ var/obj/item/explosive/mine/sebb/planted = new /obj/item/explosive/mine/sebb(get_turf(user))
+ planted.activate_sensors()
+ planted.iff_signal = user.faction // assuring IFF is set
+ planted.pixel_x += rand(-5, 5)
+ planted.pixel_y += rand(-5, 5)
+ qdel(src)
+
+/obj/item/explosive/grenade/sebb/activate()
+ ..()
+ var/beeplen = 6 // Actual length of the sound rounded up to nearest decisecond
+ var/soundtime = det_time - beeplen
+ if(det_time < beeplen) // just play sound if detonation shorter than the sound
+ playsound(loc, 'sound/effects/sebb_explode.ogg', 90, 0, 10)
+ else
+ addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(playsound), loc, 'sound/effects/sebb_beep.ogg', 60, 0, 10), soundtime)
+
+
+
+/obj/item/explosive/grenade/sebb/prime()
+ var/datum/effect_system/spark_spread/sparka = new
+ var/turf/sebb_turf = get_turf(src)
+ var/list/full_range = oview(range, src) // Fill a list of stuff in the range so we won't have to spam oview
+ new /obj/effect/overlay/temp/sebb(sebb_turf)
+
+ playsound(src.loc, 'sound/effects/sebb_explode.ogg', 90, 0, 10)
+
+ for(var/obj/structure/machinery/defenses/sentry/sentry_stun in full_range)
+ sentry_stun.sentry_range = 0 // Temporarily "disable" the sentry by killing its range then setting it back.
+ new /obj/effect/overlay/temp/elec_arc(get_turf(sentry_stun)) // sprites are meh but we need visual indication that the sentry was messed up
+ addtimer(VARSET_CALLBACK(sentry_stun, sentry_range, initial(sentry_stun.sentry_range)), 5 SECONDS) // assure to set it back
+ sentry_stun.visible_message(SPAN_DANGER("[src]'s screen flickes violently as it's shocked!"))
+ sentry_stun.visible_message(SPAN_DANGER("[src] says \"ERROR: Fire control system resetting due to critical voltage flucuation!\""))
+ sparka.set_up(1, 1, sentry_stun)
+ sparka.start()
+
+ for(var/turf/turf in full_range)
+ if(prob(8))
+ var/datum/effect_system/spark_spread/sparkTurf = new //using a different spike system because the spark system doesn't like when you reuse it for differant things
+ sparkTurf.set_up(1, 1, turf)
+ sparkTurf.start()
+ if(prob(10))
+ new /obj/effect/overlay/temp/emp_sparks(turf)
+
+ for(var/mob/living/carbon/mob in full_range) // no legacy mob support
+
+ var/mob_dist = get_dist(src, mob) // Distance from mob
+
+ /**
+ * Damage equation: damage - (mob distance * falloff_dam_reduction_mult)
+ * Example: A marine is 3 tiles out, the distance (3) is multiplied by falloff_dam_reduction_mult to get falloff.
+ * The raw damage is minused by falloff to get actual damage
+ */
+
+ var/falloff = mob_dist * falloff_dam_reduction_mult
+ var/damage_applied = damage - falloff // Final damage applied after falloff calc
+ sparka.set_up(1, 1, mob)
+ sparka.start()
+ shake_camera(mob, 1, 1)
+ if(ishuman(mob))
+ var/mob/living/carbon/human/shocked_human = mob
+ if(isspeciessynth(shocked_human)) // Massive overvoltage to ungrounded robots is pretty bad
+ shocked_human.Stun(1 + (damage_applied/40))
+ damage_applied *= 1.5
+ new /obj/effect/overlay/temp/elec_arc(get_turf(shocked_human))
+ to_chat(mob, SPAN_HIGHDANGER("All of your systems jam up as your main bus is overvolted by [damage_applied*2] volts."))
+ mob.visible_message(SPAN_WARNING("[mob] seizes up from the elctric shock"))
+ shocked_human.take_overall_armored_damage(damage_applied, ARMOR_ENERGY, BURN, 90) // 90% chance to be on additional limbs
+ shocked_human.make_dizzy(damage_applied)
+ mob.apply_stamina_damage(damage_applied*human_stam_dam_factor) // Stamina damage
+ shocked_human.emote("pain")
+ else //nonhuman damage + slow
+ mob.apply_damage(damage_applied, BURN)
+ if((mob_dist < (range-3))) // 2 tiles around small superslow
+ mob.Superslow(2)
+ mob.Slow(damage_applied/11)
+
+ if(mob_dist < 1) // Range based stuff, standing ontop of the equivalent of a canned lighting bolt should mess you up.
+ mob.Superslow(3) // Note that humans will likely be in stamcrit so it's always worse for them when ontop of it and we can just balancing it on xenos.
+ mob.eye_blurry = damage_applied/4
+ mob.Daze(1)
+ else if((mob_dist < (range-1)) && (mob.mob_size < MOB_SIZE_XENO_VERY_SMALL)) // Flicker stun humans that are closer to the grenade and larvas too.
+ mob.apply_effect(1 + (damage_applied/100),WEAKEN) // 1 + damage/40
+ mob.eye_blurry = damage_applied/8
+
+ else
+ to_chat(mob, SPAN_HIGHDANGER("Your entire body seizes up as a powerful shock courses through it!"))
+
+
+ new /obj/effect/overlay/temp/emp_sparks(mob)
+ mob.make_jittery(damage_applied*2)
+ empulse(src, 1, 2) // mini EMP
+ qdel(src)
+
+
+/obj/item/explosive/grenade/sebb/primed
+ desc = "A G2 Electroshock Grenade, looks like it's quite angry! Oh shit!"
+ det_time = 7 // 0.7 seconds to blow up. We want them to get caught if they go through.
+
+/obj/item/explosive/grenade/sebb/primed/Initialize()
+ . = ..()
+ src.visible_message(SPAN_HIGHDANGER("[src] pops out of the ground!"))
+ activate()
+
+/obj/effect/overlay/temp/sebb
+ icon = 'icons/effects/sebb.dmi'
+ icon_state = "sebb_explode"
+ layer = ABOVE_LIGHTING_PLANE
+ pixel_x = -175 // We need these offsets to force center the sprite because BYOND is dumb
+ pixel_y = -175
+ appearance_flags = RESET_COLOR
+
/*
//================================================
Nerve Gas Grenades
@@ -684,6 +867,8 @@
return
/obj/item/explosive/grenade/high_explosive/holy_hand_grenade
+ AUTOWIKI_SKIP(TRUE)
+
name = "\improper Holy Hand Grenade of Antioch"
desc = "And Saint Attila raised the hand grenade up on high, saying, \"O LORD, bless this Thy hand grenade that with it Thou mayest blow Thine enemies to tiny bits, in Thy mercy.\" And the LORD did grin and the people did feast upon the lambs and sloths and carp and anchovies... And the LORD spake, saying, \"First shalt thou take out the Holy Pin, then shalt thou count to three, no more, no less. Three shall be the number thou shalt count, and the number of the counting shall be three. Four shalt thou not count, neither count thou two, excepting that thou then proceed to three. Five is right out. Once the number three, being the third number, be reached, then lobbest thou thy Holy Hand Grenade of Antioch towards thy foe, who, being naughty in My sight, shall snuff it.\""
icon_state = "grenade_antioch"
diff --git a/code/game/objects/items/explosives/mine.dm b/code/game/objects/items/explosives/mine.dm
index 45065a2de1de..6e7aa2bdccc3 100644
--- a/code/game/objects/items/explosives/mine.dm
+++ b/code/game/objects/items/explosives/mine.dm
@@ -14,6 +14,7 @@
throw_speed = SPEED_VERY_FAST
unacidable = TRUE
flags_atom = FPRINT|CONDUCT
+ antigrief_protection = TRUE
allowed_sensors = list(/obj/item/device/assembly/prox_sensor)
max_container_volume = 120
reaction_limits = list( "max_ex_power" = 105, "base_ex_falloff" = 60, "max_ex_shards" = 32,
@@ -71,7 +72,12 @@
if(active || user.action_busy)
return
- user.visible_message(SPAN_NOTICE("[user] starts deploying [src]."), \
+ if(antigrief_protection && user.faction == FACTION_MARINE && explosive_antigrief_check(src, user))
+ to_chat(user, SPAN_WARNING("\The [name]'s safe-area accident inhibitor prevents you from planting!"))
+ msg_admin_niche("[key_name(user)] attempted to plant \a [name] in [get_area(src)] [ADMIN_JMP(src.loc)]")
+ return
+
+ user.visible_message(SPAN_NOTICE("[user] starts deploying [src]."),
SPAN_NOTICE("You start deploying [src]."))
if(!do_after(user, 40, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE))
user.visible_message(SPAN_NOTICE("[user] stops deploying [src]."), \
@@ -317,3 +323,19 @@
customizable = TRUE
matter = list("metal" = 3750)
has_blast_wave_dampener = TRUE
+
+/obj/item/explosive/mine/sebb
+ name = "\improper G2 Electroshock grenade"
+ icon_state = "grenade_sebb_planted"
+ desc = "A G2 electroshock grenade planted as a landmine."
+ pixel_y = -5
+ anchored = TRUE // this is supposed to be planeted already when spawned
+
+/obj/item/explosive/mine/sebb/disarm()
+ . = ..()
+ new /obj/item/explosive/grenade/sebb(get_turf(src))
+ qdel(src)
+
+/obj/item/explosive/mine/sebb/prime()
+ new /obj/item/explosive/grenade/sebb/primed(get_turf(src))
+ qdel(src)
diff --git a/code/game/objects/items/explosives/plastic.dm b/code/game/objects/items/explosives/plastic.dm
index 58cbca9a5ab3..c6a3dfaed5f9 100644
--- a/code/game/objects/items/explosives/plastic.dm
+++ b/code/game/objects/items/explosives/plastic.dm
@@ -25,7 +25,7 @@
antigrief_protection = TRUE //Should it be checked by antigrief?
var/req_skill = SKILL_ENGINEER
- var/req_skill_level = SKILL_ENGINEER_TRAINED
+ var/req_skill_level = SKILL_ENGINEER_NOVICE
/obj/item/explosive/plastic/Destroy()
disarm()
@@ -46,7 +46,7 @@
. = ..()
/obj/item/explosive/plastic/attack_self(mob/user)
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_NOVICE))
to_chat(user, SPAN_WARNING("You don't seem to know how to use [src]..."))
return
diff --git a/code/game/objects/items/frames/table_rack.dm b/code/game/objects/items/frames/table_rack.dm
index eda9b9c5749b..95ab43869774 100644
--- a/code/game/objects/items/frames/table_rack.dm
+++ b/code/game/objects/items/frames/table_rack.dm
@@ -59,7 +59,10 @@
if(istype(get_area(loc), /area/shuttle)) //HANGAR/SHUTTLE BUILDING
to_chat(user, SPAN_WARNING("No. This area is needed for the dropship."))
return
-
+ for(var/obj/object in OT)
+ if(object.density)
+ to_chat(user, SPAN_WARNING("[object] is blocking you from constructing [src]!"))
+ return
if(!do_after(user, 3 SECONDS, INTERRUPT_ALL, BUSY_ICON_BUILD))
to_chat(user, SPAN_WARNING("Hold still while you're constructing a table!"))
return
diff --git a/code/game/objects/items/hoverpack.dm b/code/game/objects/items/hoverpack.dm
index 02a2d4be779a..65406eb15dc6 100644
--- a/code/game/objects/items/hoverpack.dm
+++ b/code/game/objects/items/hoverpack.dm
@@ -208,6 +208,7 @@
return TRUE
/datum/action/item_action/hover/action_activate()
+ . = ..()
var/mob/living/carbon/human/H = owner
if(H.selected_ability == src)
to_chat(H, "You will no longer use [name] with \
diff --git a/code/game/objects/items/implants/implant.dm b/code/game/objects/items/implants/implant.dm
index e7ebe0391fae..6584186f576a 100644
--- a/code/game/objects/items/implants/implant.dm
+++ b/code/game/objects/items/implants/implant.dm
@@ -140,6 +140,7 @@ Implant Specifics:
"}
var/elevel = "Localized Limb"
var/phrase = "supercalifragilisticexpialidocious"
icon_state = "implant_evil"
+ flags_atom = USES_HEARING
/obj/item/implant/explosive/get_data()
var/dat = {"
diff --git a/code/game/objects/items/props/helmetgarb.dm b/code/game/objects/items/props/helmetgarb.dm
index 5b9b81804311..9da509d16c5a 100644
--- a/code/game/objects/items/props/helmetgarb.dm
+++ b/code/game/objects/items/props/helmetgarb.dm
@@ -176,12 +176,12 @@
if(src != user.get_inactive_hand())
to_chat(user, SPAN_WARNING("You need to hold \the [src] in hand in order to repair them."))
return
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED)) // level 2 is enough to repair damaged NVG
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_NOVICE)) // level 2 is enough to repair damaged NVG
to_chat(user, SPAN_WARNING("You are not trained to repair electronics..."))
return
if(shape == NVG_SHAPE_BROKEN)
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI)) // level 3 is needed to repair broken NVG
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED)) // level 3 is needed to repair broken NVG
to_chat(user, SPAN_WARNING("Repair of this complexity is too difficult for you, find someone more trained."))
return
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 55ed8c8d34f0..7f05128c7e1b 100644
--- a/code/game/objects/items/reagent_containers/food/snacks/grown.dm
+++ b/code/game/objects/items/reagent_containers/food/snacks/grown.dm
@@ -584,19 +584,14 @@
src.visible_message(SPAN_NOTICE("The [src.name] has been squashed."),SPAN_MODERATE("You hear a smack."))
qdel(src)
return
- for(var/turf/T in orange(M,outer_teleport_radius))
- if(T in orange(M,inner_teleport_radius)) continue
+ for(var/turf/T as anything in (RANGE_TURFS(outer_teleport_radius, M) - RANGE_TURFS(inner_teleport_radius, M)))
if(istype(T,/turf/open/space)) continue
if(T.density) continue
if(T.x>world.maxx-outer_teleport_radius || T.xworld.maxy-outer_teleport_radius || T.y[user] plants [newflag] firmly in the ground.")
src.use(1)
+
+
+/// PLANTABLE FLAG
+
+/obj/structure/flag/plantable
+ name = "flag"
+ desc = "A flag of something. This one looks like you could dismantle it."
+ icon = 'icons/obj/structures/plantable_flag.dmi'
+ pixel_x = 9 // All flags need to be offset to the right by 9 to be centered.
+ layer = ABOVE_XENO_LAYER
+ health = 150
+ unacidable = TRUE
+
+ /// The typepath for the flag item that gets spawned when the flag is taken down.
+ var/flag_type = /obj/item/flag/plantable
+ /// Used to limit the spam of the warcry_extra_sound
+ COOLDOWN_DECLARE(warcry_cooldown_struc)
+
+/obj/structure/flag/plantable/attack_hand(mob/user)
+ ..()
+ disassemble(user, flag_type)
+
+/// Proc for dismantling the flag into an item that can be picked up.
+/obj/structure/flag/plantable/proc/disassemble(mob/user, flag_type)
+ if(user.action_busy)
+ return
+
+ user.visible_message(SPAN_NOTICE("[user] starts taking [src] down..."), SPAN_NOTICE("You start taking [src] down..."))
+
+ playsound(loc, 'sound/effects/flag_raising.ogg', 30)
+ if(!do_after(user, 6 SECONDS, INTERRUPT_ALL, BUSY_ICON_GENERIC) || QDELETED(src))
+ return
+
+ playsound(loc, 'sound/effects/flag_raised.ogg', 30)
+ user.visible_message(SPAN_NOTICE("[user] starts takes [src] down!"), SPAN_NOTICE("You take [src] down!"))
+ var/obj/item/flag/plantable/flag_item = new flag_type(loc)
+ user.put_in_hands(flag_item)
+ COOLDOWN_START(flag_item, warcry_cooldown_item, COOLDOWN_TIMELEFT(src, warcry_cooldown_struc))
+ qdel(src)
+
+/// Proc for when the flag gets forcefully dismantled (due to general damage, explosions, etc.)
+/obj/structure/flag/plantable/proc/demolish(flag_type)
+ playsound(loc, 'sound/effects/flag_raised.ogg', 30)
+ visible_message(SPAN_WARNING("[src] crumples to the ground!"))
+ var/obj/item/flag/plantable/flag_item = new flag_type(loc)
+ COOLDOWN_START(flag_item, warcry_cooldown_item, COOLDOWN_TIMELEFT(src, warcry_cooldown_struc))
+ qdel(src)
+
+// Procs for handling damage.
+/obj/structure/flag/plantable/update_health(damage)
+ if(damage)
+ health -= damage
+ if(health <= 0)
+ demolish(flag_type)
+
+/obj/structure/flag/plantable/ex_act(severity)
+ if(health <= 0)
+ return
+ update_health(severity)
+
+/obj/structure/flag/plantable/attack_alien(mob/living/carbon/xenomorph/xeno)
+ if(xeno.a_intent == INTENT_HARM)
+ if(unslashable)
+ return
+ xeno.animation_attack_on(src)
+ playsound(loc, 'sound/effects/metalhit.ogg', 25, 1)
+ xeno.visible_message(SPAN_DANGER("[xeno] slashes [src]!"), SPAN_DANGER("We slash [src]!"), null, 5, CHAT_TYPE_XENO_COMBAT)
+ update_health(rand(xeno.melee_damage_lower, xeno.melee_damage_upper))
+ return XENO_ATTACK_ACTION
+ else
+ to_chat(xeno, SPAN_WARNING("We stare at [src] cluelessly."))
+ return XENO_NONCOMBAT_ACTION
+
+/obj/structure/flag/plantable/bullet_act(obj/projectile/bullet)
+ bullet_ping(bullet)
+ visible_message(SPAN_DANGER("[src] is hit by [bullet]!"), null, 4, CHAT_TYPE_TAKING_HIT)
+ update_health(bullet.damage)
+ return TRUE
+
+/obj/structure/flag/plantable/attackby(obj/item/weapon, mob/living/user)
+ if(!indestructible)
+ visible_message(SPAN_DANGER("[src] has been hit by [user] with [weapon]!"), null, 5, CHAT_TYPE_MELEE_HIT)
+ user.animation_attack_on(src)
+ playsound(loc, 'sound/effects/metalhit.ogg', 25, 1)
+ update_health(weapon.force * weapon.demolition_mod)
+
+/obj/item/flag/plantable
+ name = "plantable flag"
+ desc = "A flag of something. This one looks ready to be planted into the ground."
+ w_class = SIZE_LARGE
+ throw_range = 2
+ icon = 'icons/obj/structures/plantable_flag.dmi'
+ inhand_x_dimension = 64
+ inhand_y_dimension = 64
+ force = 15
+ throwforce = 5
+ hitsound = "swing_hit"
+ unacidable = TRUE
+ indestructible = TRUE
+ item_icons = list(
+ WEAR_L_HAND = 'icons/mob/humans/onmob/items_lefthand_64.dmi',
+ WEAR_R_HAND = 'icons/mob/humans/onmob/items_righthand_64.dmi'
+ )
+
+ /// The typepath of the flag structure that gets spawned when the flag is planted.
+ var/flag_type = /obj/structure/flag/plantable
+ /// Used to check if nearby mobs belong to a faction when calculating for the stronger warcry.
+ var/faction
+ /// Does the flag play a unique warcry when planted? (Only while on harm intent.)
+ var/play_warcry = FALSE
+ /// The warcry's sound path.
+ var/warcry_sound
+ /// When there are more than 14 allies nearby, play this stronger warcry.
+ var/warcry_extra_sound
+ /// How many nearby allies do we need for the stronger warcry to be played?
+ var/allies_required = 14
+ /// Used to limit the spam of the warcry_extra_sound
+ COOLDOWN_DECLARE(warcry_cooldown_item)
+
+/obj/item/flag/plantable/get_examine_text(mob/user)
+ . = ..()
+ if(play_warcry && user.faction == faction)
+ . += SPAN_NOTICE("Planting the flag while in HARM intent will cause you to bellow out a rallying warcry!")
+
+/// Proc for turning the flag item into a structure.
+/obj/item/flag/plantable/proc/plant_flag(mob/living/user, play_warcry = FALSE, warcry_sound, warcry_extra_sound, faction)
+ if(user.action_busy)
+ return
+
+ if(SSinterior.in_interior(user))
+ to_chat(usr, SPAN_WARNING("There's no way to plant [src] in here!"))
+ return
+
+ var/turf/turf_to_plant = get_step(user, user.dir)
+ if(istype(turf_to_plant, /turf/open))
+ var/turf/open/floor = turf_to_plant
+ if(!floor.allow_construction || istype(floor, /turf/open/space))
+ to_chat(user, SPAN_WARNING("You cannot deploy [src] here, find a more secure surface!"))
+ return
+ else
+ to_chat(user, SPAN_WARNING("[turf_to_plant] is blocking you from deploying [src]!"))
+ return
+
+ for(var/obj/object in turf_to_plant)
+ if(object.density)
+ to_chat(usr, SPAN_WARNING("You need a clear, open area to plant [src], something is blocking the way in front of you!"))
+ return
+
+ user.visible_message(SPAN_NOTICE("[user] starts planting [src] into the ground..."), SPAN_NOTICE("You start planting [src] into the ground..."))
+ playsound(user, 'sound/effects/flag_raising.ogg', 30)
+ if(!do_after(user, 6 SECONDS, INTERRUPT_ALL, BUSY_ICON_GENERIC))
+ return
+
+ user.visible_message(SPAN_NOTICE("[user] plants [src] into the ground!"), SPAN_NOTICE("You plant [src] into the ground!"))
+ var/obj/structure/flag/plantable/planted_flag = new flag_type(turf_to_plant)
+
+ // If there are more than 14 allies nearby, play a stronger rallying cry.
+ // Otherwise, play the default warcry sound if there is one. If not, play a generic flag raising sfx.
+ if(play_warcry && user.faction == faction && user.a_intent == INTENT_HARM)
+ var/allies_nearby = 0
+ if(COOLDOWN_FINISHED(src, warcry_cooldown_item))
+ for(var/mob/living/carbon/human in orange(planted_flag, 7))
+ if(human.is_dead() || human.faction != faction)
+ continue
+ allies_nearby++
+
+ user.show_speech_bubble("warcry")
+ if(allies_nearby >= allies_required)
+ playsound(user, warcry_extra_sound, 40)
+ // Start a cooldown on the flag structure. This way we can keep track of the cooldown when the flag is hoisted and taken down.
+ COOLDOWN_START(planted_flag, warcry_cooldown_struc, 90 SECONDS)
+ user.manual_emote("shouts an invigorating rallying cry!")
+ else
+ playsound(user, warcry_sound, 30)
+ user.manual_emote("shouts an inspiring cry!")
+ // Ditto. If the cooldown isn't finished we have to transfer the leftover time to the structure.
+ COOLDOWN_START(planted_flag, warcry_cooldown_struc, COOLDOWN_TIMELEFT(src, warcry_cooldown_item))
+ else
+ playsound(loc, 'sound/effects/flag_raised.ogg', 30)
+
+ qdel(src)
+
+/obj/item/flag/plantable/attack_self(mob/user)
+ ..()
+ plant_flag(user, play_warcry, warcry_sound, warcry_extra_sound, faction)
+
+// UNITED AMERICAS FLAG //
+//////////////////////////
+
+/obj/item/flag/plantable/ua
+ name = "\improper United Americas flag"
+ desc = "The flag of the United Americas. This one looks ready to be planted into the ground."
+ icon = 'icons/obj/structures/plantable_flag.dmi'
+ icon_state = "flag_ua"
+ flag_type = /obj/structure/flag/plantable/ua
+ faction = FACTION_MARINE
+ play_warcry = TRUE
+ warcry_sound = 'sound/effects/flag_warcry_ua.ogg'
+ warcry_extra_sound = 'sound/effects/flag_warcry_ua_extra.ogg'
+
+/obj/structure/flag/plantable/ua
+ name = "\improper United Americas flag"
+ desc = "The flag of the United Americas. Semper fi."
+ icon_state = "flag_ua_planted"
+ flag_type = /obj/item/flag/plantable/ua
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 5f72e4a75567..3856aebd7971 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -197,6 +197,12 @@ Also change the icon to reflect the amount of sheets, if possible.*/
to_chat(usr, SPAN_WARNING("The [R.title] cannot be constructed on a tunnel!"))
return
+ if(R.one_per_turf != ONE_TYPE_PER_BORDER) //all barricade-esque structures utilize this define and have their own check for object density. checking twice is unneeded.
+ for(var/obj/object in usr.loc)
+ if(object.density || istype(object, /obj/structure/machinery/door))
+ to_chat(usr, SPAN_WARNING("[object] is blocking you from constructing \the [R.title]!"))
+ return
+
if((R.flags & RESULT_REQUIRES_SNOW) && !(istype(usr.loc, /turf/open/snow) || istype(usr.loc, /turf/open/auto_turf/snow)))
to_chat(usr, SPAN_WARNING("The [R.title] must be built on snow!"))
return
diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm
index baa91db19396..9ed53236789d 100644
--- a/code/game/objects/items/storage/backpack.dm
+++ b/code/game/objects/items/storage/backpack.dm
@@ -15,7 +15,7 @@
cant_hold = list(/obj/item/storage/firstaid, /obj/item/storage/toolkit)
can_hold_skill = list(
/obj/item/storage/firstaid = list(SKILL_MEDICAL, SKILL_MEDICAL_MEDIC),
- /obj/item/storage/toolkit = list(SKILL_ENGINEER, SKILL_ENGINEER_ENGI),
+ /obj/item/storage/toolkit = list(SKILL_ENGINEER, SKILL_ENGINEER_TRAINED),
)
drop_sound = "armorequip"
var/worn_accessible = FALSE //whether you can access its content while worn on the back
@@ -268,6 +268,7 @@
return TRUE
/datum/action/item_action/specialist/santabag/action_activate()
+ . = ..()
var/obj/item/storage/backpack/santabag/santa_bag = holder_item
santa_bag.refill_santa_bag(owner)
update_button_icon()
@@ -537,6 +538,7 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r
button.overlays += IMG
/datum/action/item_action/rto_pack/use_phone/action_activate()
+ . = ..()
for(var/obj/item/storage/backpack/marine/satchel/rto/radio_backpack in owner)
radio_backpack.use_phone(owner)
return
@@ -870,6 +872,7 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r
return TRUE
/datum/action/item_action/specialist/toggle_cloak/action_activate()
+ . = ..()
var/obj/item/storage/backpack/marine/satchel/scout_cloak/SC = holder_item
SC.camouflage()
diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm
index d16602e04aaa..14961c69eaf5 100644
--- a/code/game/objects/items/storage/belt.dm
+++ b/code/game/objects/items/storage/belt.dm
@@ -117,7 +117,6 @@
)
storage_slots = 10
-
/obj/item/storage/belt/utility/full/fill_preset_inventory()
new /obj/item/tool/screwdriver(src)
new /obj/item/tool/wrench(src)
@@ -136,6 +135,50 @@
new /obj/item/tool/wirecutters(src)
new /obj/item/device/t_scanner(src)
+/obj/item/storage/belt/utility/construction
+ name = "\improper M277 pattern construction rig"
+ desc = "The M277 is a common rig used by Combat Technicians to carry around materials and other supplies. It consists of a modular belt with various clips. This version sarafices storage space for specialized material loading clips."
+ storage_slots = 6
+ can_hold = list(
+ /obj/item/tool/crowbar,
+ /obj/item/tool/screwdriver,
+ /obj/item/tool/weldingtool,
+ /obj/item/tool/wirecutters,
+ /obj/item/tool/wrench,
+ /obj/item/tool/extinguisher/mini,
+ /obj/item/tool/shovel/etool,
+ /obj/item/stack/cable_coil,
+ /obj/item/weapon/gun/smg/nailgun/compact,
+ /obj/item/cell,
+ /obj/item/circuitboard,
+ /obj/item/stock_parts,
+ /obj/item/device/demo_scanner,
+ /obj/item/device/reagent_scanner,
+ /obj/item/device/assembly,
+ /obj/item/device/multitool,
+ /obj/item/device/flashlight,
+ /obj/item/device/t_scanner,
+ /obj/item/device/analyzer,
+ /obj/item/explosive/plastic,
+ /obj/item/device/lightreplacer,
+ /obj/item/stack/sheet,
+ /obj/item/stack/sandbags_empty,
+ /obj/item/stack/sandbags,
+ /obj/item/stack/barbed_wire,
+ /obj/item/defenses/handheld/sentry,
+ /obj/item/stack/rods,
+ /obj/item/stack/tile,
+ )
+
+ bypass_w_limit = list(
+ /obj/item/tool/shovel/etool,
+ /obj/item/device/lightreplacer,
+ /obj/item/stack/sheet,
+ /obj/item/stack/sandbags_empty,
+ /obj/item/stack/sandbags,
+ /obj/item/defenses/handheld/sentry,
+ )
+
/obj/item/storage/belt/utility/full/pred
name = "\improper Yautja toolbelt"
desc = "A modular belt with various clips. This version lacks any hunting functionality, and is commonly used by engineers to transport important tools."
@@ -1296,12 +1339,12 @@
#undef MAXIMUM_MAGAZINE_COUNT
/obj/item/storage/belt/gun/m44
- name = "\improper M276 pattern M44 holster rig"
- desc = "The M276 is the standard load-bearing equipment of the USCM. It consists of a modular belt with various clips. This version is for the M44 magnum revolver, along with six small pouches for speedloaders. It smells faintly of hay."
+ name = "\improper M276 pattern general revoler holster rig"
+ desc = "The M276 is the standard load-bearing equipment of the USCM. It consists of a modular belt with various clips. This version is universal and adjustable for different revolvers, along with six small pouches for speedloaders. It smells faintly of hay."
icon_state = "m44r_holster"
storage_slots = 7
can_hold = list(
- /obj/item/weapon/gun/revolver/m44,
+ /obj/item/weapon/gun/revolver,
/obj/item/ammo_magazine/revolver,
)
has_gamemode_skin = TRUE
@@ -1413,7 +1456,7 @@
desc = "The M276 is the standard load-bearing equipment of the USCM. It consists of a modular belt with various clips. This version is for the powerful Mateba magnum revolver, along with five small pouches for speedloaders. This one is aging poorly, and seems to be surplus equipment. It's stamped '3rd 'Dust Raiders' Battalion'."
icon_state = "s_cmateba_holster"
item_state = "s_marinebelt"
- storage_slots = 6
+ storage_slots = 7
max_w_class = SIZE_MEDIUM
can_hold = list(
/obj/item/weapon/gun/revolver/mateba,
@@ -1697,7 +1740,7 @@
/obj/item/device/flashlight/flare,
/obj/item/weapon/gun/flare,
/obj/item/weapon/gun/pistol,
- /obj/item/weapon/gun/revolver/m44,
+ /obj/item/weapon/gun/revolver,
/obj/item/ammo_magazine/revolver,
/obj/item/ammo_magazine/pistol,
/obj/item/ammo_magazine/smartgun,
@@ -1717,8 +1760,7 @@
/obj/item/device/flashlight/flare,
/obj/item/weapon/gun/flare,
/obj/item/weapon/gun/pistol,
- /obj/item/weapon/gun/revolver/m44,
- /obj/item/weapon/gun/revolver/mateba,
+ /obj/item/weapon/gun/revolver,
/obj/item/ammo_magazine/revolver,
/obj/item/ammo_magazine/revolver/mateba,
/obj/item/ammo_magazine/pistol,
@@ -1740,8 +1782,7 @@
/obj/item/device/flashlight/flare,
/obj/item/weapon/gun/flare,
/obj/item/weapon/gun/pistol,
- /obj/item/weapon/gun/revolver/m44,
- /obj/item/weapon/gun/revolver/mateba,
+ /obj/item/weapon/gun/revolver,
/obj/item/ammo_magazine/revolver,
/obj/item/ammo_magazine/revolver/mateba,
/obj/item/ammo_magazine/pistol,
@@ -1763,8 +1804,7 @@
/obj/item/device/flashlight/flare,
/obj/item/weapon/gun/flare,
/obj/item/weapon/gun/pistol,
- /obj/item/weapon/gun/revolver/m44,
- /obj/item/weapon/gun/revolver/mateba,
+ /obj/item/weapon/gun/revolver,
/obj/item/ammo_magazine/revolver,
/obj/item/ammo_magazine/revolver/mateba,
/obj/item/ammo_magazine/pistol,
diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm
index ab221b89bfe2..e385d4b5c17d 100644
--- a/code/game/objects/items/storage/boxes.dm
+++ b/code/game/objects/items/storage/boxes.dm
@@ -470,6 +470,7 @@
item_state = "zippo"
w_class = SIZE_TINY
flags_equip_slot = SLOT_WAIST
+ flags_obj = parent_type::flags_obj|OBJ_IS_HELMET_GARB
can_hold = list(/obj/item/tool/match)
/obj/item/storage/box/matches/fill_preset_inventory()
diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm
index 5d7aecbc03db..79d38603dc7e 100644
--- a/code/game/objects/items/storage/fancy.dm
+++ b/code/game/objects/items/storage/fancy.dm
@@ -126,6 +126,7 @@
w_class = SIZE_TINY
throwforce = 2
flags_equip_slot = SLOT_WAIST
+ flags_obj = parent_type::flags_obj|OBJ_IS_HELMET_GARB
max_w_class = SIZE_TINY
storage_slots = 20
can_hold = list(
diff --git a/code/game/objects/items/storage/large_holster.dm b/code/game/objects/items/storage/large_holster.dm
index 02983e1552ed..ddf6060b355c 100644
--- a/code/game/objects/items/storage/large_holster.dm
+++ b/code/game/objects/items/storage/large_holster.dm
@@ -91,6 +91,28 @@
/obj/item/storage/large_holster/machete/arnold/full/fill_preset_inventory()
new /obj/item/weapon/sword/machete/arnold(src)
+/obj/item/storage/large_holster/machete/smartgunner
+ name = "\improper M56 harness machete scabbard"
+ desc = "A scabbard that connects to the M56 combat harness for carrying a M2132 machete."
+ icon_state = "smartgun_machete_holster"
+ flags_equip_slot = SLOT_BACK
+ flags_item = SMARTGUNNER_BACKPACK_OVERRIDE
+
+/obj/item/storage/large_holster/machete/smartgunner/mob_can_equip(mob/equipping_mob, slot, disable_warning)
+ . = ..()
+
+ var/mob/living/carbon/human/user = equipping_mob
+ if(!ishuman(user))
+ return FALSE
+
+ if(!user.wear_suit || !(user.wear_suit.flags_inventory & SMARTGUN_HARNESS))
+ if(!disable_warning)
+ to_chat(equipping_mob, SPAN_WARNING("You can't equip [src] without a harness."))
+ return FALSE
+
+/obj/item/storage/large_holster/machete/smartgunner/full/fill_preset_inventory()
+ new /obj/item/weapon/sword/machete(src)
+
/obj/item/storage/large_holster/katana
name = "\improper katana scabbard"
desc = "A large, vibrantly colored katana scabbard used to carry a Japanese sword. It can be strapped to the back or worn at the belt. Because of the sturdy wood casing of the scabbard, it makes an okay defensive weapon in a pinch."
@@ -375,6 +397,7 @@
return TRUE
/datum/action/item_action/specialist/toggle_fuel/action_activate()
+ . = ..()
var/obj/item/storage/large_holster/fuelpack/FP = holder_item
if (!istype(FP))
return
diff --git a/code/game/objects/items/storage/pouch.dm b/code/game/objects/items/storage/pouch.dm
index 63516ac20aa0..9c8c7080bdc3 100644
--- a/code/game/objects/items/storage/pouch.dm
+++ b/code/game/objects/items/storage/pouch.dm
@@ -802,6 +802,28 @@
for(var/i = 1 to storage_slots)
new /obj/item/reagent_container/syringe(src)
+/obj/item/storage/pouch/engikit
+ name = "engineer kit pouch"
+ storage_flags = STORAGE_FLAGS_POUCH
+ icon_state = "construction"
+ desc = "It's specifically made to hold engineering items. Requires engineering skills to use effectively."
+ storage_slots = 6
+ can_hold_skill = list(
+ /obj/item/circuitboard = list(SKILL_ENGINEER, SKILL_ENGINEER_TRAINED),
+ /obj/item/device/flashlight = list(SKILL_ENGINEER, SKILL_ENGINEER_TRAINED),
+ /obj/item/clothing/glasses/welding = list(SKILL_ENGINEER, SKILL_ENGINEER_TRAINED),
+ /obj/item/device/analyzer = list(SKILL_ENGINEER, SKILL_ENGINEER_TRAINED),
+ /obj/item/device/demo_scanner = list(SKILL_ENGINEER, SKILL_ENGINEER_TRAINED),
+ /obj/item/device/reagent_scanner = list(SKILL_ENGINEER, SKILL_ENGINEER_TRAINED),
+ /obj/item/device/t_scanner = list(SKILL_ENGINEER, SKILL_ENGINEER_TRAINED),
+ /obj/item/stack/cable_coil = list(SKILL_ENGINEER, SKILL_ENGINEER_TRAINED),
+ /obj/item/cell = list(SKILL_ENGINEER, SKILL_ENGINEER_TRAINED),
+ /obj/item/device/assembly = list(SKILL_ENGINEER, SKILL_ENGINEER_TRAINED),
+ /obj/item/stock_parts = list(SKILL_ENGINEER, SKILL_ENGINEER_TRAINED),
+ /obj/item/explosive/plastic = list(SKILL_ENGINEER, SKILL_ENGINEER_TRAINED),
+ )
+ can_hold_skill_only = TRUE
+
/obj/item/storage/pouch/medkit
name = "medical kit pouch"
storage_flags = STORAGE_FLAGS_POUCH
diff --git a/code/game/objects/items/storage/toolkit.dm b/code/game/objects/items/storage/toolkit.dm
index e3171eca40f6..cccca19c241c 100644
--- a/code/game/objects/items/storage/toolkit.dm
+++ b/code/game/objects/items/storage/toolkit.dm
@@ -23,7 +23,7 @@
)
storage_flags = STORAGE_FLAGS_BOX
required_skill_for_nest_opening = SKILL_ENGINEER
- required_skill_level_for_nest_opening = SKILL_ENGINEER_ENGI
+ required_skill_level_for_nest_opening = SKILL_ENGINEER_TRAINED
///icon state to use when kit is full
var/icon_full
diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm
deleted file mode 100644
index 3a5afef6cf1e..000000000000
--- a/code/game/objects/items/tanks/jetpack.dm
+++ /dev/null
@@ -1,85 +0,0 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
-
-/obj/item/tank/jetpack
- name = "Jetpack (Empty)"
- desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution."
- icon_state = "jetpack"
- w_class = SIZE_LARGE
- item_state = "jetpack"
- distribute_pressure = ONE_ATMOSPHERE*O2STANDARD
- var/datum/effect_system/ion_trail_follow/ion_trail
- var/on = 0
- var/stabilization_on = 0
- var/volume_rate = 500 //Needed for borg jetpack transfer
- actions_types = list(/datum/action/item_action)
-
-/obj/item/tank/jetpack/Initialize()
- . = ..()
- src.ion_trail = new /datum/effect_system/ion_trail_follow()
- src.ion_trail.set_up(src)
-
-/obj/item/tank/jetpack/Destroy()
- QDEL_NULL(ion_trail)
- return ..()
-
-
-/obj/item/tank/jetpack/verb/toggle_rockets()
- set name = "Toggle Jetpack Stabilization"
- set category = "Object"
- set src in usr
- src.stabilization_on = !( src.stabilization_on )
- to_chat(usr, "You toggle the stabilization [stabilization_on? "on":"off"].")
-
-/obj/item/tank/jetpack/verb/toggle()
- set name = "Toggle Jetpack"
- set category = "Object"
- set src in usr
- on = !on
- if(on)
- icon_state = "[icon_state]-on"
- ion_trail.start()
- else
- icon_state = initial(icon_state)
- ion_trail.stop()
-
- if (ismob(usr))
- var/mob/M = usr
- M.update_inv_back()
-
- for(var/X in actions)
- var/datum/action/A = X
- A.update_button_icon()
-
-/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user)
- if(!(src.on))
- return 0
-
- if(pressure > 5)
- return 1
- else
- ion_trail.stop()
- return 0
-
-
-/obj/item/tank/jetpack/ui_action_click()
- toggle()
-
-
-/obj/item/tank/jetpack/void
- name = "Void Jetpack (Oxygen)"
- desc = "It works well in a void."
- icon_state = "jetpack-void"
- item_state = "jetpack-void"
-
-/obj/item/tank/jetpack/oxygen
- name = "Jetpack (Oxygen)"
- desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas. Use with caution."
- icon_state = "jetpack"
- item_state = "jetpack"
-
-/obj/item/tank/jetpack/carbondioxide
- name = "Jetpack (Carbon Dioxide)"
- desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals."
- distribute_pressure = 0
- icon_state = "jetpack-black"
- item_state = "jetpack-black"
diff --git a/code/game/objects/items/tools/cleaning_tools.dm b/code/game/objects/items/tools/cleaning_tools.dm
index f392f096bcf6..9fab254a7153 100644
--- a/code/game/objects/items/tools/cleaning_tools.dm
+++ b/code/game/objects/items/tools/cleaning_tools.dm
@@ -99,13 +99,15 @@
desc = "This cone is trying to warn you of something!"
icon_state = "cone"
icon = 'icons/obj/janitor.dmi'
+ item_icons = 'icons/mob/humans/onmob/head_0.dmi'
force = 1
throwforce = 3
throw_speed = SPEED_FAST
throw_range = 5
w_class = SIZE_SMALL
attack_verb = list("warned", "cautioned", "smashed")
-
+ flags_equip_slot = SLOT_HEAD
+ flags_inv_hide = HIDEEARS|HIDETOPHAIR
@@ -150,7 +152,7 @@
return
..()
-/obj/item/tool/soap/nanotrasen
+/obj/item/tool/soap/weyland_yutani
desc = "A Weyland-Yutani brand bar of soap. Smells of phoron."
icon_state = "soapnt"
diff --git a/code/game/objects/items/tools/extinguisher.dm b/code/game/objects/items/tools/extinguisher.dm
index 723d34c64f7e..75987116b290 100644
--- a/code/game/objects/items/tools/extinguisher.dm
+++ b/code/game/objects/items/tools/extinguisher.dm
@@ -159,7 +159,7 @@
unpicked_targets -= TT
INVOKE_ASYNC(src, PROC_REF(release_liquid), TT, user)
- if(istype(user.loc, /turf/open/space) || (user.lastarea && user.lastarea.has_gravity == 0))
+ if(istype(user.loc, /turf/open/space))
user.inertia_dir = get_dir(target, user)
step(user, user.inertia_dir)
return
diff --git a/code/game/objects/items/tools/flame_tools.dm b/code/game/objects/items/tools/flame_tools.dm
index d5cd708f29b3..8af7d15e0ff3 100644
--- a/code/game/objects/items/tools/flame_tools.dm
+++ b/code/game/objects/items/tools/flame_tools.dm
@@ -177,6 +177,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
w_class = SIZE_TINY
flags_armor_protection = 0
flags_equip_slot = SLOT_EAR | SLOT_FACE
+ flags_obj = parent_type::flags_obj|OBJ_IS_HELMET_GARB
flags_atom = CAN_BE_SYRINGED
attack_verb = list("burnt", "singed")
blood_overlay_type = ""
@@ -693,6 +694,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
throwforce = 4
flags_atom = FPRINT|CONDUCT
flags_equip_slot = SLOT_WAIST
+ flags_obj = parent_type::flags_obj|OBJ_IS_HELMET_GARB
attack_verb = list("burnt", "singed")
/obj/item/tool/lighter/zippo
diff --git a/code/game/objects/items/tools/kitchen_tools.dm b/code/game/objects/items/tools/kitchen_tools.dm
index d6473b156a67..a4c4925fba2c 100644
--- a/code/game/objects/items/tools/kitchen_tools.dm
+++ b/code/game/objects/items/tools/kitchen_tools.dm
@@ -48,7 +48,7 @@
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 ..()
+ 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 8febff63ee5d..f45953040a07 100644
--- a/code/game/objects/items/tools/maintenance_tools.dm
+++ b/code/game/objects/items/tools/maintenance_tools.dm
@@ -29,6 +29,7 @@
matter = list("metal" = 150)
attack_verb = list("bashed", "battered", "bludgeoned", "whacked")
inherent_traits = list(TRAIT_TOOL_WRENCH)
+ preferred_storage = list(/obj/item/clothing/accessory/storage/tool_webbing = WEAR_ACCESSORY)
/*
@@ -52,7 +53,7 @@
attack_verb = list("stabbed")
flags_item = CAN_DIG_SHRAPNEL
inherent_traits = list(TRAIT_TOOL_SCREWDRIVER)
-
+ preferred_storage = list(/obj/item/clothing/accessory/storage/tool_webbing = WEAR_ACCESSORY)
/obj/item/tool/screwdriver/Initialize()
@@ -135,6 +136,7 @@
sharp = IS_SHARP_ITEM_SIMPLE
edge = 1
inherent_traits = list(TRAIT_TOOL_WIRECUTTERS)
+ preferred_storage = list(/obj/item/clothing/accessory/storage/tool_webbing = WEAR_ACCESSORY)
/obj/item/tool/wirecutters/tactical
name = "tactical wirecutters"
@@ -189,6 +191,7 @@
/// Used to slowly deplete the fuel when the tool is left on.
var/weld_tick = 0
var/has_welding_screen = FALSE
+ preferred_storage = list(/obj/item/clothing/accessory/storage/tool_webbing = WEAR_ACCESSORY)
/obj/item/tool/weldingtool/Initialize()
. = ..()
@@ -472,6 +475,7 @@
attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked")
inherent_traits = list(TRAIT_TOOL_CROWBAR)
pry_capable = IS_PRY_CAPABLE_CROWBAR
+ preferred_storage = list(/obj/item/clothing/accessory/storage/tool_webbing = WEAR_ACCESSORY)
/obj/item/tool/crowbar/red
icon = 'icons/obj/items/items.dmi'
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index f93f2dab0984..77b15e22d055 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -277,7 +277,11 @@
//trying to buckle a mob
/obj/proc/buckle_mob(mob/M, mob/user)
- if (!ismob(M) || (get_dist(src, user) > 1) || user.is_mob_restrained() || user.stat || buckled_mob || M.buckled || !isturf(user.loc))
+ if (!ismob(M) || (get_dist(src, user) > 1) || user.stat || buckled_mob || M.buckled || !isturf(user.loc))
+ return
+
+ if (user.is_mob_incapacitated() || HAS_TRAIT(user, TRAIT_IMMOBILIZED) || HAS_TRAIT(user, TRAIT_FLOORED))
+ to_chat(user, SPAN_WARNING("You can't do this right now."))
return
if (isxeno(user) && !HAS_TRAIT(user, TRAIT_OPPOSABLE_THUMBS))
@@ -286,11 +290,6 @@
if (iszombie(user))
return
- // mobs that become immobilized should not be able to buckle themselves.
- if(M == user && HAS_TRAIT(user, TRAIT_IMMOBILIZED))
- to_chat(user, SPAN_WARNING("You are unable to do this in your current state."))
- return
-
if(density)
density = FALSE
if(!step(M, get_dir(M, src)) && loc != M.loc)
@@ -416,7 +415,7 @@
var/offset_x = worn_x_dimension
var/offset_y = worn_y_dimension
- if(inhands)
+ if(inhands == 1 || inhands == 0)
offset_x = inhand_x_dimension
offset_y = inhand_y_dimension
diff --git a/code/game/objects/prop.dm b/code/game/objects/prop.dm
index cc941b19ed97..9e256236e7d6 100644
--- a/code/game/objects/prop.dm
+++ b/code/game/objects/prop.dm
@@ -169,6 +169,18 @@
icon_state = "game_kit"
icon = 'icons/obj/items/items.dmi'
+/obj/item/prop/gripper
+ name = "magnetic gripper"
+ desc = "A simple grasping tool for synthetic assets."
+ icon_state = "gripper"
+ icon = 'icons/obj/items/devices.dmi'
+
+/obj/item/prop/matter_decompiler
+ name = "matter decompiler"
+ desc = "Eating trash, bits of glass, or other debris will replenish your stores."
+ icon_state = "decompiler"
+ icon = 'icons/obj/items/devices.dmi'
+
/// Xeno-specific props
/obj/item/prop/alien/hugger
diff --git a/code/game/objects/structures/airlock_assembly.dm b/code/game/objects/structures/airlock_assembly.dm
index d9e55e868016..01fca4a68783 100644
--- a/code/game/objects/structures/airlock_assembly.dm
+++ b/code/game/objects/structures/airlock_assembly.dm
@@ -111,6 +111,11 @@
qdel(src)
return
+ for(var/obj/object in loc)
+ if(object.density && object != src)
+ to_chat(user, SPAN_WARNING("[object] is blocking you from interacting with [src]!"))
+ return
+
switch(state)
if(STATE_STANDARD)
if(HAS_TRAIT(attacking_item, TRAIT_TOOL_WRENCH))
diff --git a/code/game/objects/structures/barricade/barricade.dm b/code/game/objects/structures/barricade/barricade.dm
index 28036f92d018..31c2f0ed1b48 100644
--- a/code/game/objects/structures/barricade/barricade.dm
+++ b/code/game/objects/structures/barricade/barricade.dm
@@ -453,6 +453,10 @@
to_chat(user, SPAN_WARNING("You'll need some adequate repair material in your other hand to patch up [src]!"))
return FALSE
+ if(material.amount < nailgun.material_per_repair)
+ to_chat(user, SPAN_WARNING("You'll need more adequate repair material in your other hand to patch up [src]!"))
+ return FALSE
+
var/repair_value = 0
for(var/validSheetType in repair_materials)
if(validSheetType == material.sheettype)
@@ -469,7 +473,7 @@
return FALSE
if(!material || (material != user.l_hand && material != user.r_hand) || material.amount <= 0)
- to_chat(user, SPAN_WARNING("You seems to have misplaced the repair material!"))
+ to_chat(user, SPAN_WARNING("You seem to have misplaced the repair material!"))
return FALSE
if(!nailgun.in_chamber || !nailgun.current_mag || nailgun.current_mag.current_rounds < 3)
@@ -479,7 +483,7 @@
update_health(-repair_value*maxhealth)
to_chat(user, SPAN_WARNING("You nail [material] to [src], restoring some of its integrity!"))
update_damage_state()
- material.use(1)
+ material.use(nailgun.material_per_repair)
nailgun.current_mag.current_rounds -= 3
nailgun.in_chamber = null
nailgun.load_into_chamber()
diff --git a/code/game/objects/structures/barricade/deployable.dm b/code/game/objects/structures/barricade/deployable.dm
index e53c917dc2bb..ad559f2e13bd 100644
--- a/code/game/objects/structures/barricade/deployable.dm
+++ b/code/game/objects/structures/barricade/deployable.dm
@@ -31,7 +31,7 @@
if(HAS_TRAIT(item, TRAIT_TOOL_CROWBAR))
if(user.action_busy)
return
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_NOVICE))
to_chat(user, SPAN_WARNING("You do not know how to collapse [src] using a crowbar..."))
return
user.visible_message(SPAN_NOTICE("[user] starts collapsing [src]."), \
@@ -95,6 +95,7 @@
w_class = SIZE_LARGE
flags_equip_slot = SLOT_BACK|SLOT_SUIT_STORE
+ flags_item = SMARTGUNNER_BACKPACK_OVERRIDE
icon_state = "folding-1"
item_state = "folding"
item_state_slots = list(
diff --git a/code/game/objects/structures/barricade/metal.dm b/code/game/objects/structures/barricade/metal.dm
index 3e79af2e21e1..f16e6851341b 100644
--- a/code/game/objects/structures/barricade/metal.dm
+++ b/code/game/objects/structures/barricade/metal.dm
@@ -48,7 +48,7 @@
if(!..())
return FALSE
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_NOVICE))
if(!silent)
to_chat(user, SPAN_WARNING("You're not trained to repair [src]..."))
return FALSE
diff --git a/code/game/objects/structures/barricade/plasteel.dm b/code/game/objects/structures/barricade/plasteel.dm
index 1acedae9997d..fb5a08954a5d 100644
--- a/code/game/objects/structures/barricade/plasteel.dm
+++ b/code/game/objects/structures/barricade/plasteel.dm
@@ -69,7 +69,7 @@
if(!..())
return FALSE
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_NOVICE))
if(!silent)
to_chat(user, SPAN_WARNING("You're not trained to repair [src]..."))
return FALSE
@@ -95,7 +95,7 @@
if(busy || tool_cooldown > world.time)
return
tool_cooldown = world.time + 10
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You are not trained to assemble [src]..."))
return
@@ -112,7 +112,7 @@
return
if(HAS_TRAIT(item, TRAIT_TOOL_CROWBAR))
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You are not trained to modify [src]..."))
return
playsound(src.loc, 'sound/items/Crowbar.ogg', 25, 1)
@@ -136,7 +136,7 @@
if(busy || tool_cooldown > world.time)
return
tool_cooldown = world.time + 10
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You are not trained to assemble [src]..."))
return
if(!do_after(user, 10, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD, src))
@@ -151,7 +151,7 @@
if(busy || tool_cooldown > world.time)
return
tool_cooldown = world.time + 10
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You are not trained to assemble [src]..."))
return
if(!do_after(user, 10, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD, src))
@@ -169,7 +169,7 @@
if(busy || tool_cooldown > world.time)
return
tool_cooldown = world.time + 10
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You are not trained to assemble [src]..."))
return
var/turf/open/T = loc
@@ -190,7 +190,7 @@
if(busy || tool_cooldown > world.time)
return
tool_cooldown = world.time + 10
- if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You are not trained to assemble [src]..."))
return
user.visible_message(SPAN_NOTICE("[user] starts unseating [src]'s panels."),
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 93fe78e63d98..77da397b7b0a 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -127,6 +127,8 @@
var/obj/item/explosive/plastic/P = I
if(P.active)
continue
+ if(istype(I, /obj/item/phone))
+ continue
var/item_size = ceil(I.w_class / 2)
if(stored_units + item_size > storage_capacity)
continue
diff --git a/code/game/objects/structures/crates_lockers/closets/malfunction.dm b/code/game/objects/structures/crates_lockers/closets/malfunction.dm
deleted file mode 100644
index 704e2c79157a..000000000000
--- a/code/game/objects/structures/crates_lockers/closets/malfunction.dm
+++ /dev/null
@@ -1,16 +0,0 @@
-
-/obj/structure/closet/malf/suits
- desc = "It's a storage unit for operational gear."
- icon_state = "syndicate"
- icon_closed = "syndicate"
- icon_opened = "syndicate_open"
-
-/obj/structure/closet/malf/suits/Initialize()
- . = ..()
- new /obj/item/tank/jetpack/void(src)
- new /obj/item/clothing/mask/breath(src)
- new /obj/item/clothing/head/helmet/space/uscm(src)
- new /obj/item/clothing/suit/space/uscm(src)
- new /obj/item/tool/crowbar(src)
- new /obj/item/cell(src)
- new /obj/item/device/multitool(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm
index b000fd5733a2..0bf39322d107 100644
--- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm
@@ -23,7 +23,7 @@
. = ..()
#ifndef UNIT_TESTS
- switch (pickweight(list("small" = 55, "aid" = 25, "tank" = 10, "both" = 10, "nothing" = 0, "delete" = 0)))
+ switch (pick_weight(list("small" = 55, "aid" = 25, "tank" = 10, "both" = 10, "nothing" = 1, "delete" = 1)))
#else
var/test = "both"
switch (test) // We don't want randomness in tests
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index d891119a8404..59e74100cb5c 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -90,6 +90,8 @@
var/obj/structure/bed/B = O
if(B.buckled_mob)
continue
+ if(istype(O, /obj/item/phone))
+ continue
O.forceMove(src)
itemcount++
@@ -277,13 +279,6 @@
name = "RCD crate"
desc = "A crate for the storage of the RCD."
-/obj/structure/closet/crate/rcd/Initialize()
- . = ..()
- new /obj/item/ammo_rcd(src)
- new /obj/item/ammo_rcd(src)
- new /obj/item/ammo_rcd(src)
- new /obj/item/device/rcd(src)
-
/obj/structure/closet/crate/freezer/rations //Fpr use in the escape shuttle
desc = "A crate of emergency rations."
name = "Emergency Rations"
diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm
deleted file mode 100644
index 239df3c05973..000000000000
--- a/code/game/objects/structures/electricchair.dm
+++ /dev/null
@@ -1,47 +0,0 @@
-/obj/structure/bed/chair/e_chair
- name = "electric chair"
- desc = "Looks absolutely SHOCKING!"
- icon_state = "echair1"
- var/last_time = 1
-
-/obj/structure/bed/chair/e_chair/New()
- ..()
- overlays += image('icons/obj/objects.dmi', src, "echair_over", MOB_LAYER + 1, dir)
-
-
-/obj/structure/bed/chair/e_chair/rotate()
- ..()
- overlays.Cut()
- overlays += image('icons/obj/objects.dmi', src, "echair_over", MOB_LAYER + 1, dir) //there's probably a better way of handling this, but eh. -Pete
- return
-
-/obj/structure/bed/chair/e_chair/proc/shock()
- if(last_time + 50 > world.time)
- return
- last_time = world.time
-
- // special power handling
- var/area/A = get_area(src)
- if(!isarea(A))
- return
- if(!A.powered(POWER_CHANNEL_EQUIP))
- return
- A.use_power(5000)
- var/light = A.power_light
- A.updateicon()
-
- flick("echair1", src)
- var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
- s.set_up(12, 1, src)
- s.start()
- if(buckled_mob)
- buckled_mob.burn_skin(85)
- to_chat(buckled_mob, SPAN_DANGER("You feel a deep shock course through your body!"))
- sleep(1)
- buckled_mob.burn_skin(85)
- buckled_mob.apply_effect(600, STUN)
- visible_message(SPAN_DANGER("The electric chair went off!"), SPAN_DANGER("You hear a deep sharp shock!"))
-
- A.power_light = light
- A.updateicon()
- return
diff --git a/code/game/objects/structures/fence.dm b/code/game/objects/structures/fence.dm
index 7c602c34380f..93d9d7727e5d 100644
--- a/code/game/objects/structures/fence.dm
+++ b/code/game/objects/structures/fence.dm
@@ -153,6 +153,10 @@
M.apply_damage(20)
health -= 50
+ M.attack_log += text("\[[time_stamp()]\] was slammed against [src] by [key_name(user)]")
+ user.attack_log += text("\[[time_stamp()]\] slammed [key_name(M)] against [src]")
+ msg_admin_attack("[key_name(user)] slammed [key_name(M)] against [src] at [get_area_name(M)]", M.loc.x, M.loc.y, M.loc.z)
+
healthcheck(1, 1, M) //The person thrown into the window literally shattered it
return
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index 01e0e1b717cc..325af12c814b 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -110,6 +110,10 @@
if(!HAS_TRAIT(W, TRAIT_TOOL_BLOWTORCH))
to_chat(user, SPAN_WARNING("You need a stronger blowtorch!"))
return
+ for(var/obj/object in loc)
+ if(object.density)
+ to_chat(user, SPAN_WARNING("[object] is blocking you from welding [src] together!"))
+ return
if(do_after(user,30, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
if(QDELETED(src))
return
@@ -334,7 +338,6 @@
else
dmg = floor(P.damage * 0.5)
if(dmg)
- health -= dmg
take_damage(dmg)
bullet_ping(P)
if(health <= 0)
@@ -342,7 +345,9 @@
return TRUE
/obj/structure/girder/proc/take_damage(damage)
- health = max(health - damage, 0)
+ health -= damage
+ if(health <= -100)
+ qdel(src)
if(health <= 0)
update_state()
@@ -356,10 +361,11 @@
update_state()
/obj/structure/girder/proc/update_state()
- if (health <= 0)
+ if(health <= 0 && density)
icon_state = "[icon_state]_damaged"
density = FALSE
- else
+
+ else if(health > 0 && !density)
var/underscore_position = findtext(icon_state,"_")
var/new_state = copytext(icon_state, 1, underscore_position)
icon_state = new_state
diff --git a/code/game/objects/structures/pipes/standard/standard_misc.dm b/code/game/objects/structures/pipes/standard/standard_misc.dm
index dc52da57c750..d0028ce862cb 100644
--- a/code/game/objects/structures/pipes/standard/standard_misc.dm
+++ b/code/game/objects/structures/pipes/standard/standard_misc.dm
@@ -120,6 +120,7 @@
dir = SOUTH
valid_directions = list(SOUTH)
density = TRUE
+ layer = OBJ_LAYER
var/actual_icon_state = "air"
/obj/structure/pipes/standard/tank/New()
diff --git a/code/game/objects/structures/roof.dm b/code/game/objects/structures/roof.dm
new file mode 100644
index 000000000000..e302133f0c9a
--- /dev/null
+++ b/code/game/objects/structures/roof.dm
@@ -0,0 +1,165 @@
+/obj/structure/roof
+ name = "roof"
+ desc = "A roof"
+ icon = 'icons/turf/almayer.dmi'
+ icon_state = "plating_catwalk"
+ density = FALSE
+ layer = ABOVE_XENO_LAYER
+ health = 6000
+ var/image/under_image //immage that is used when there is mob on connected node, displayed only to mobs under it not others
+ var/image/normal_image
+ var/datum/roof_master_node/linked_master
+ var/lazy_nodes = TRUE //if roof should create nodes that watch around it on spawn
+
+
+/obj/structure/roof/Initialize()
+ . = ..()
+ under_image = image(icon, src, icon_state, layer = layer)
+ under_image.alpha = 127
+
+ normal_image = image(icon, src, icon_state, layer = layer)
+
+ icon_state = null
+
+ RegisterSignal(SSdcs, COMSIG_GLOB_MOB_LOGGED_IN, PROC_REF(add_default_image))
+
+ for(var/icon in GLOB.player_list)
+ add_default_image(SSdcs, icon)
+ if(lazy_nodes) //creates new node on each surounding tile if there is not one already
+ var/obj/effect/roof_node/neighbor = locate() in loc
+ if(!neighbor)
+ neighbor = new(loc)
+ for(var/direction in CARDINAL_ALL_DIRS)
+ var/adjacent_loc = get_step(src, direction)
+ neighbor = locate() in adjacent_loc
+ if(!neighbor)
+ neighbor = new(adjacent_loc)
+ return INITIALIZE_HINT_LATELOAD
+
+/obj/structure/roof/LateInitialize() //we use late init to allow for lazy nodes to spawn first on mapload
+ . = ..()
+ if(linked_master)
+ return
+ for(var/direction in CARDINAL_ALL_DIRS) //this searches if there is lattice with master already, to work with runtime creation
+ for(var/obj/structure/roof/roof in get_step(src,direction))
+ if(roof.linked_master)
+ roof.linked_master.connect(loc)
+ return
+ var/datum/roof_master_node/roof_master_node = new(loc) //no master and no lattice to connect to, create new master
+ roof_master_node.connect(loc)
+
+/obj/structure/roof/Destroy(force, ...)
+ if(linked_master)
+ linked_master.remove_roof(src)
+ for(var/icon in GLOB.player_list)
+ var/mob/mob = icon
+ mob.client.images -= normal_image
+ return ..()
+
+/obj/structure/roof/proc/add_default_image(subsystem, mob/mob)
+ SIGNAL_HANDLER
+ mob.client.images += normal_image
+
+/obj/structure/roof/proc/link_master(datum/roof_master_node/master) //performs bfs and connects to master
+ if(linked_master != null)
+ return
+ master.connected_roof += src
+ linked_master = master
+ for(var/direction in CARDINAL_ALL_DIRS)
+ for(var/obj/structure/roof/roof in get_step(src,direction))
+ roof.link_master(master)
+
+
+/obj/effect/roof_node //used for observing if mob is near the roof
+ name = "roof_node"
+ anchored = TRUE
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ invisibility = 101
+ unacidable = TRUE
+ var/datum/roof_master_node/linked_master
+
+/obj/effect/roof_node/Crossed(atom/movable/mover, target_dir)
+ if(!linked_master)
+ return
+ if(isliving(mover))
+ var/mob/living/mob = mover
+ linked_master.add_under_roof(mob)
+
+/obj/effect/roof_node/Destroy(force, ...)
+ if(linked_master)
+ if(linked_master.connected_nodes)
+ linked_master.connected_nodes -= src
+ return ..()
+
+/obj/effect/roof_node/proc/link_master(datum/roof_master_node/master) //performs bfs and connects to master
+ if(linked_master)
+ return
+ master.connected_nodes += src
+ linked_master = master
+ for(var/direction in CARDINAL_ALL_DIRS)
+ for(var/obj/effect/roof_node/node in get_step(src,direction))
+ node.link_master(master)
+
+
+/datum/roof_master_node //maintains one block of roof
+ var/list/connected_nodes = list()
+ var/list/connected_roof = list()
+ var/list/mobs_under = list()
+ var/location
+
+/datum/roof_master_node/Destroy(force, ...)
+ if(connected_nodes)
+ for(var/obj/effect/roof_node/roof_node in connected_nodes)
+ qdel(roof_node)
+ if(connected_nodes)
+ for(var/obj/structure/roof/roof in connected_roof)
+ qdel(roof)
+ return ..()
+
+/datum/roof_master_node/proc/add_under_roof(mob/living/living) //mob crossed connected node
+ if(living in mobs_under)
+ return
+ mobs_under += living
+ RegisterSignal(living, COMSIG_PARENT_QDELETING, PROC_REF(remove_under_roof))
+ RegisterSignal(living, COMSIG_MOB_LOGGED_IN, PROC_REF(add_client))
+ RegisterSignal(living, COMSIG_MOVABLE_MOVED, PROC_REF(check_under_roof))
+
+ if(living.client)
+ add_client(living)
+
+/datum/roof_master_node/proc/add_client(mob/living/mob)
+ SIGNAL_HANDLER
+ for(var/obj/structure/roof/roof in connected_roof)
+ mob.client.images -= roof.normal_image
+ mob.client.images += roof.under_image
+
+/datum/roof_master_node/proc/remove_under_roof(mob/living/living) //mob is no longer under roof
+ SIGNAL_HANDLER
+ if(living.client)
+ for(var/obj/structure/roof/roof in connected_roof)
+ living.client.images -= roof.under_image
+ roof.add_default_image(SSdcs, living)
+ mobs_under -= living
+ UnregisterSignal(living, list(
+ COMSIG_PARENT_QDELETING,
+ COMSIG_MOB_LOGGED_IN,
+ COMSIG_MOVABLE_MOVED,
+ ))
+
+/datum/roof_master_node/proc/check_under_roof(mob/living/living) //check if the mob is under connected roof
+ SIGNAL_HANDLER
+ for(var/obj/effect/roof_node/roof in connected_nodes)
+ if(living.loc == roof.loc)
+ return
+ remove_under_roof(living)
+
+/datum/roof_master_node/proc/connect(location)
+ for(var/obj/effect/roof_node/node in location)
+ node.link_master(src)
+ for(var/obj/structure/roof/roof in location)
+ roof.link_master(src)
+
+/datum/roof_master_node/proc/remove_roof(obj/structure/roof/roof) //roof tile got removed
+ connected_roof -= roof
+ if(!length(connected_roof))
+ qdel(src)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
index 986ae99739aa..f71882374518 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
@@ -36,12 +36,12 @@
move_delay += 4 //harder to move a wheelchair with a single hand
working_hands--
else if((left_hand.status & LIMB_BROKEN) && !(left_hand.status & LIMB_SPLINTED))
- move_delay++
+ move_delay ++
if(!right_hand || (right_hand.status & LIMB_DESTROYED))
move_delay += 4
working_hands--
else if((right_hand.status & LIMB_BROKEN) && !(right_hand.status & LIMB_SPLINTED))
- move_delay += 2
+ move_delay++
if(!working_hands)
return // No hands to drive your chair? Tough luck!
if(driver.pulling && driver.pulling.drag_delay && driver.get_pull_miltiplier()) //Dragging stuff can slow you down a bit.
diff --git a/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm b/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm
index c3f0b97e509a..68b899f78f15 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm
@@ -245,6 +245,7 @@
do_buckle(mob, user)
ADD_TRAIT(mob, TRAIT_NESTED, TRAIT_SOURCE_BUCKLE)
+ ADD_TRAIT(mob, TRAIT_NO_STRAY, TRAIT_SOURCE_BUCKLE)
SEND_SIGNAL(mob, COMSIG_MOB_NESTED, user)
if(!human)
@@ -275,6 +276,7 @@
buckled_mob.pixel_y = 0
buckled_mob.old_y = 0
REMOVE_TRAIT(buckled_mob, TRAIT_NESTED, TRAIT_SOURCE_BUCKLE)
+ REMOVE_TRAIT(buckled_mob, TRAIT_NO_STRAY, TRAIT_SOURCE_BUCKLE)
var/mob/living/carbon/human/buckled_human = buckled_mob
var/mob/dead/observer/G = ghost_of_buckled_mob
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index a1542f7baf75..760633348b81 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -385,9 +385,11 @@
to_chat(usr, SPAN_WARNING("You have moved a table too recently."))
return FALSE
- for(var/mob/living/mob_behind_table in oview(src, 0))
+ FOR_DOVIEW(var/mob/living/mob_behind_table, 0, src, HIDE_INVISIBLE_OBSERVER)
to_chat(usr, SPAN_WARNING("[mob_behind_table] is in the way of [src]."))
+ FOR_DVIEW_END
return FALSE
+ FOR_DVIEW_END
var/list/directions = list()
if(direction)
diff --git a/code/game/objects/structures/vulture_spotter.dm b/code/game/objects/structures/vulture_spotter.dm
index dc341edf0446..dcbfd88c9c08 100644
--- a/code/game/objects/structures/vulture_spotter.dm
+++ b/code/game/objects/structures/vulture_spotter.dm
@@ -313,6 +313,7 @@
tripod = WEAKREF(spotting_tripod)
/datum/action/vulture_tripod_unscope/action_activate()
+ . = ..()
if(!tripod)
return
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 154cc43d4af2..14e15de24691 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -247,6 +247,10 @@
if(!not_damageable) //Impossible to destroy
health -= 50
+ M.attack_log += text("\[[time_stamp()]\] was slammed against [src] by [key_name(user)]")
+ user.attack_log += text("\[[time_stamp()]\] slammed [key_name(M)] against [src]")
+ msg_admin_attack("[key_name(user)] slammed [key_name(M)] against [src] at [get_area_name(M)]", M.loc.x, M.loc.y, M.loc.z)
+
healthcheck(1, 1, 1, M) //The person thrown into the window literally shattered it
return
diff --git a/code/game/sound.dm b/code/game/sound.dm
index 1ab8fc42f41a..6f721d9725e5 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -13,6 +13,7 @@
var/falloff = 1
var/volume_cat = VOLUME_SFX
var/range = 0
+ var/list/echo = new /list(18)
var/x //Map coordinates, not sound coordinates
var/y
var/z
@@ -36,114 +37,127 @@
//status: the regular 4 sound flags
//falloff: max range till sound volume starts dropping as distance increases
-/proc/playsound(atom/source, soundin, vol = 100, vary = FALSE, sound_range, vol_cat = VOLUME_SFX, channel = 0, status , falloff = 1, y_s_offset,x_s_offset)
+/proc/playsound(atom/source, sound/soundin, vol = 100, vary = FALSE, sound_range, vol_cat = VOLUME_SFX, channel = 0, status, falloff = 1, list/echo, y_s_offset, x_s_offset)
if(isarea(source))
error("[source] is an area and is trying to make the sound: [soundin]")
return FALSE
- var/datum/sound_template/S = new()
- var/sound/SD = soundin
- if(istype(SD))
- S.file = SD.file
- S.wait = SD.wait
- S.repeat = SD.repeat
+ var/datum/sound_template/template = new()
+ if(istype(soundin))
+ template.file = soundin.file
+ template.wait = soundin.wait
+ template.repeat = soundin.repeat
else
- S.file = get_sfx(soundin)
- S.channel = channel ? channel : get_free_channel()
- S.status = status
- S.falloff = falloff
- S.volume = vol
- S.volume_cat = vol_cat
- S.y_s_offset = y_s_offset
- S.x_s_offset = x_s_offset
+ template.file = get_sfx(soundin)
+ template.channel = channel ? channel : get_free_channel()
+ template.status = status
+ template.falloff = falloff
+ template.volume = vol
+ template.volume_cat = vol_cat
+ for(var/pos = 1 to length(echo))
+ if(!echo[pos])
+ continue
+ template.echo[pos] = echo[pos]
+ template.y_s_offset = y_s_offset
+ template.x_s_offset = x_s_offset
if(vary != FALSE)
if(vary > 1)
- S.frequency = vary
+ template.frequency = vary
else
- S.frequency = GET_RANDOM_FREQ // Same frequency for everybody
+ template.frequency = GET_RANDOM_FREQ // Same frequency for everybody
if(!sound_range)
sound_range = floor(0.25*vol) //if no specific range, the max range is equal to a quarter of the volume.
- S.range = sound_range
+ template.range = sound_range
var/turf/turf_source = get_turf(source)
if(!turf_source || !turf_source.z)
return FALSE
- S.x = turf_source.x
- S.y = turf_source.y
- S.z = turf_source.z
+ template.x = turf_source.x
+ template.y = turf_source.y
+ template.z = turf_source.z
if(!SSinterior)
- SSsound.queue(S)
- return S.channel
+ SSsound.queue(template)
+ return template.channel
var/list/datum/interior/extra_interiors = list()
// If we're in an interior, range the chunk, then adjust to do so from outside instead
if(SSinterior.in_interior(turf_source))
- var/datum/interior/VI = SSinterior.get_interior_by_coords(turf_source.x, turf_source.y, turf_source.z)
- if(VI?.ready)
- extra_interiors |= VI
- if(VI.exterior)
- var/turf/new_turf_source = get_turf(VI.exterior)
- S.x = new_turf_source.x
- S.y = new_turf_source.y
- S.z = new_turf_source.z
+ var/datum/interior/vehicle_interior = SSinterior.get_interior_by_coords(turf_source.x, turf_source.y, turf_source.z)
+ if(vehicle_interior?.ready)
+ extra_interiors |= vehicle_interior
+ if(vehicle_interior.exterior)
+ var/turf/new_turf_source = get_turf(vehicle_interior.exterior)
+ template.x = new_turf_source.x
+ template.y = new_turf_source.y
+ template.z = new_turf_source.z
else sound_range = 0
// Range for 'nearby interiors' aswell
- for(var/datum/interior/VI in SSinterior.interiors)
- if(VI?.ready && VI.exterior?.z == turf_source.z && get_dist(VI.exterior, turf_source) <= sound_range)
- extra_interiors |= VI
+ for(var/datum/interior/vehicle_interior in SSinterior.interiors)
+ if(vehicle_interior?.ready && vehicle_interior.exterior?.z == turf_source.z && get_dist(vehicle_interior.exterior, turf_source) <= sound_range)
+ extra_interiors |= vehicle_interior
- SSsound.queue(S, null, extra_interiors)
- return S.channel
+ SSsound.queue(template, null, extra_interiors)
+ return template.channel
//This is the replacement for playsound_local. Use this for sending sounds directly to a client
-/proc/playsound_client(client/client, soundin, atom/origin, vol = 100, random_freq, vol_cat = VOLUME_SFX, channel = 0, status, y_s_offset, x_s_offset)
- if(!istype(client) || !client.soundOutput) return FALSE
- var/datum/sound_template/S = new()
+/proc/playsound_client(client/client, sound/soundin, atom/origin, vol = 100, random_freq, vol_cat = VOLUME_SFX, channel = 0, status, list/echo, y_s_offset, x_s_offset)
+ if(!istype(client) || !client.soundOutput)
+ return FALSE
+
+ var/datum/sound_template/template = new()
if(origin)
var/turf/T = get_turf(origin)
if(T)
- S.x = T.x
- S.y = T.y
- S.z = T.z
- var/sound/SD = soundin
- if(istype(SD))
- S.file = SD.file
- S.wait = SD.wait
- S.repeat = SD.repeat
+ template.x = T.x
+ template.y = T.y
+ template.z = T.z
+ if(istype(soundin))
+ template.file = soundin.file
+ template.wait = soundin.wait
+ template.repeat = soundin.repeat
else
- S.file = get_sfx(soundin)
+ template.file = get_sfx(soundin)
if(random_freq)
- S.frequency = GET_RANDOM_FREQ
- S.volume = vol
- S.volume_cat = vol_cat
- S.channel = channel
- S.status = status
- S.y_s_offset = y_s_offset
- S.x_s_offset = x_s_offset
- SSsound.queue(S, list(client))
+ template.frequency = GET_RANDOM_FREQ
+ template.volume = vol
+ template.volume_cat = vol_cat
+ template.channel = channel
+ template.status = status
+ for(var/pos = 1 to length(echo))
+ if(!echo[pos])
+ continue
+ template.echo[pos] = echo[pos]
+ template.y_s_offset = y_s_offset
+ template.x_s_offset = x_s_offset
+ SSsound.queue(template, list(client))
/// Plays sound to all mobs that are map-level contents of an area
/proc/playsound_area(area/A, soundin, vol = 100, channel = 0, status, vol_cat = VOLUME_SFX, list/echo, y_s_offset, x_s_offset)
if(!isarea(A))
return FALSE
- var/datum/sound_template/S = new()
- S.file = soundin
- S.volume = vol
- S.channel = channel
- S.status = status
- S.volume_cat = vol_cat
+
+ var/datum/sound_template/template = new()
+ template.file = soundin
+ template.volume = vol
+ template.channel = channel
+ template.status = status
+ template.volume_cat = vol_cat
+ for(var/pos = 1 to length(echo))
+ if(!echo[pos])
+ continue
+ template.echo[pos] = echo[pos]
var/list/hearers = list()
for(var/mob/living/M in A.contents)
if(!M || !M.client || !M.client.soundOutput)
continue
hearers += M.client
- SSsound.queue(S, hearers)
+ SSsound.queue(template, hearers)
/client/proc/playtitlemusic()
if(!SSticker?.login_music)
@@ -153,230 +167,238 @@
/// Play sound for all on-map clients on a given Z-level. Good for ambient sounds.
-/proc/playsound_z(z, soundin, volume = 100, vol_cat = VOLUME_SFX, y_s_offset, x_s_offset)
- var/datum/sound_template/S = new()
- S.file = soundin
- S.volume = volume
- S.channel = SOUND_CHANNEL_Z
- S.volume_cat = vol_cat
- S.y_s_offset = y_s_offset
- S.x_s_offset = x_s_offset
+/proc/playsound_z(z, soundin, volume = 100, vol_cat = VOLUME_SFX, echo, y_s_offset, x_s_offset)
+ var/datum/sound_template/template = new()
+ template.file = soundin
+ template.volume = volume
+ template.channel = SOUND_CHANNEL_Z
+ template.volume_cat = vol_cat
+ for(var/pos = 1 to length(echo))
+ if(!echo[pos])
+ continue
+ template.echo[pos] = echo[pos]
+ template.y_s_offset = y_s_offset
+ template.x_s_offset = x_s_offset
var/list/hearers = list()
for(var/mob/M in GLOB.player_list)
if((M.z in z) && M.client.soundOutput)
hearers += M.client
- SSsound.queue(S, hearers)
+ SSsound.queue(template, hearers)
// The pick() proc has a built-in chance that can be added to any option by adding ,X; to the end of an option, where X is the % chance it will play.
-/proc/get_sfx(S)
- if(istext(S))
- switch(S)
+/proc/get_sfx(sound)
+ if(istext(sound))
+ switch(sound)
// General effects
if("shatter")
- S = pick('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg')
+ sound = pick('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg')
if("windowshatter") //meaty window shattering sound
- S = pick('sound/effects/window_shatter1.ogg','sound/effects/window_shatter2.ogg','sound/effects/window_shatter3.ogg')
+ sound = pick('sound/effects/window_shatter1.ogg','sound/effects/window_shatter2.ogg','sound/effects/window_shatter3.ogg')
if("glassbreak") //small breaks for bottles/etc.
- S = pick('sound/effects/glassbreak1.ogg','sound/effects/glassbreak2.ogg','sound/effects/glassbreak3.ogg','sound/effects/glassbreak4.ogg')
+ sound = pick('sound/effects/glassbreak1.ogg','sound/effects/glassbreak2.ogg','sound/effects/glassbreak3.ogg','sound/effects/glassbreak4.ogg')
if("explosion")
- S = pick('sound/effects/explosion1.ogg','sound/effects/explosion2.ogg','sound/effects/explosion3.ogg','sound/effects/explosion4.ogg','sound/effects/explosion5.ogg')
+ sound = pick('sound/effects/explosion1.ogg','sound/effects/explosion2.ogg','sound/effects/explosion3.ogg','sound/effects/explosion4.ogg','sound/effects/explosion5.ogg')
if("bigboom")
- S = pick('sound/effects/bigboom1.ogg','sound/effects/bigboom2.ogg','sound/effects/bigboom3.ogg','sound/effects/bigboom4.ogg')
+ sound = pick('sound/effects/bigboom1.ogg','sound/effects/bigboom2.ogg','sound/effects/bigboom3.ogg','sound/effects/bigboom4.ogg')
if("sparks")
- S = pick('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks4.ogg')
+ sound = pick('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks4.ogg')
if("rustle")
- S = pick('sound/effects/rustle1.ogg','sound/effects/rustle2.ogg','sound/effects/rustle3.ogg','sound/effects/rustle4.ogg','sound/effects/rustle5.ogg')
+ sound = pick('sound/effects/rustle1.ogg','sound/effects/rustle2.ogg','sound/effects/rustle3.ogg','sound/effects/rustle4.ogg','sound/effects/rustle5.ogg')
if("toolbox")
- S = pick('sound/effects/toolbox.ogg')
+ sound = pick('sound/effects/toolbox.ogg')
if("pillbottle")
- S = pick('sound/effects/pillbottle.ogg')
+ sound = pick('sound/effects/pillbottle.ogg')
if("rip")
- S = pick('sound/effects/rip1.ogg','sound/effects/rip2.ogg')
+ sound = pick('sound/effects/rip1.ogg','sound/effects/rip2.ogg')
if("lighter")
- S = pick('sound/effects/lighter1.ogg','sound/effects/lighter2.ogg','sound/effects/lighter3.ogg')
+ sound = pick('sound/effects/lighter1.ogg','sound/effects/lighter2.ogg','sound/effects/lighter3.ogg')
if("zippo_open")
- S = pick('sound/effects/zippo_open.ogg')
+ sound = pick('sound/effects/zippo_open.ogg')
if("zippo_close")
- S = pick('sound/effects/zippo_close.ogg')
+ sound = pick('sound/effects/zippo_close.ogg')
if("bonk") //somewhat quiet, increase volume
- S = pick('sound/machines/bonk.ogg')
+ sound = pick('sound/machines/bonk.ogg')
if("cane_step")
- S = pick('sound/items/cane_step_1.ogg', 'sound/items/cane_step_2.ogg', 'sound/items/cane_step_3.ogg', 'sound/items/cane_step_4.ogg', 'sound/items/cane_step_5.ogg', )
+ sound = pick('sound/items/cane_step_1.ogg', 'sound/items/cane_step_2.ogg', 'sound/items/cane_step_3.ogg', 'sound/items/cane_step_4.ogg', 'sound/items/cane_step_5.ogg', )
if("match")
- S = pick('sound/effects/match.ogg')
+ sound = pick('sound/effects/match.ogg')
+ if("throwing")
+ sound = pick('sound/effects/throwing/swoosh1.ogg', 'sound/effects/throwing/swoosh2.ogg', 'sound/effects/throwing/swoosh3.ogg', 'sound/effects/throwing/swoosh4.ogg')
if("punch")
- S = pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg')
+ sound = pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg')
if("swing_hit")
- S = pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg')
+ sound = pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg')
if("clan_sword_hit")
- S = pick('sound/weapons/clan_sword_hit_1.ogg', 'sound/weapons/clan_sword_hit_2.ogg')
+ sound = pick('sound/weapons/clan_sword_hit_1.ogg', 'sound/weapons/clan_sword_hit_2.ogg')
if("slam")
- S = pick('sound/effects/slam1.ogg','sound/effects/slam2.ogg','sound/effects/slam3.ogg', 0.1;'sound/effects/slam_rare_1.ogg')
+ sound = pick('sound/effects/slam1.ogg','sound/effects/slam2.ogg','sound/effects/slam3.ogg', 0.1;'sound/effects/slam_rare_1.ogg')
if("pageturn")
- S = pick('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg')
+ sound = pick('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg')
if("terminal_button")
- S = pick('sound/machines/terminal_button01.ogg', 'sound/machines/terminal_button02.ogg', 'sound/machines/terminal_button03.ogg','sound/machines/terminal_button04.ogg', 'sound/machines/terminal_button05.ogg', 'sound/machines/terminal_button06.ogg', 'sound/machines/terminal_button07.ogg', 'sound/machines/terminal_button08.ogg')
+ sound = pick('sound/machines/terminal_button01.ogg', 'sound/machines/terminal_button02.ogg', 'sound/machines/terminal_button03.ogg','sound/machines/terminal_button04.ogg', 'sound/machines/terminal_button05.ogg', 'sound/machines/terminal_button06.ogg', 'sound/machines/terminal_button07.ogg', 'sound/machines/terminal_button08.ogg')
if("keyboard")
- S = pick('sound/machines/keyboard1.ogg', 'sound/machines/keyboard2.ogg','sound/machines/keyboard3.ogg')
+ sound = pick('sound/machines/keyboard1.ogg', 'sound/machines/keyboard2.ogg','sound/machines/keyboard3.ogg')
if("keyboard_alt")
- S = pick('sound/machines/computer_typing4.ogg', 'sound/machines/computer_typing5.ogg', 'sound/machines/computer_typing6.ogg')
+ sound = pick('sound/machines/computer_typing4.ogg', 'sound/machines/computer_typing5.ogg', 'sound/machines/computer_typing6.ogg')
if("gunrustle")
- S = pick('sound/effects/gunrustle1.ogg', 'sound/effects/gunrustle2.ogg','sound/effects/gunrustle3.ogg')
+ sound = pick('sound/effects/gunrustle1.ogg', 'sound/effects/gunrustle2.ogg','sound/effects/gunrustle3.ogg')
if("gunequip")
- S = pick('sound/handling/gunequip1.ogg','sound/handling/gunequip2.ogg','sound/handling/gunequip3.ogg')
+ sound = pick('sound/handling/gunequip1.ogg','sound/handling/gunequip2.ogg','sound/handling/gunequip3.ogg')
if("shotgunpump")
- S = pick('sound/weapons/shotgunpump1.ogg','sound/weapons/shotgunpump2.ogg')
+ sound = pick('sound/weapons/shotgunpump1.ogg','sound/weapons/shotgunpump2.ogg')
if("clothingrustle")
- S = pick('sound/handling/clothingrustle1.ogg', 'sound/handling/clothingrustle2.ogg','sound/handling/clothingrustle3.ogg','sound/handling/clothingrustle4.ogg','sound/handling/clothingrustle5.ogg')
+ sound = pick('sound/handling/clothingrustle1.ogg', 'sound/handling/clothingrustle2.ogg','sound/handling/clothingrustle3.ogg','sound/handling/clothingrustle4.ogg','sound/handling/clothingrustle5.ogg')
if("armorequip")
- S = pick('sound/handling/armorequip_1.ogg','sound/handling/armorequip_2.ogg')
+ sound = pick('sound/handling/armorequip_1.ogg','sound/handling/armorequip_2.ogg')
if("pry")
- S = pick('sound/effects/pry1.ogg', 'sound/effects/pry2.ogg','sound/effects/pry3.ogg','sound/effects/pry4.ogg')
+ sound = pick('sound/effects/pry1.ogg', 'sound/effects/pry2.ogg','sound/effects/pry3.ogg','sound/effects/pry4.ogg')
if("metalbang")
- S = pick('sound/effects/thud1.ogg','sound/effects/thud2.ogg','sound/effects/thud3.ogg')
+ sound = pick('sound/effects/thud1.ogg','sound/effects/thud2.ogg','sound/effects/thud3.ogg')
if("paper_writing")
- S = pick('sound/items/writing_noises/paper_writing_1.wav', 'sound/items/writing_noises/paper_writing_2.wav', 'sound/items/writing_noises/paper_writing_3.wav', 'sound/items/writing_noises/paper_writing_4.ogg')
+ sound = pick('sound/items/writing_noises/paper_writing_1.wav', 'sound/items/writing_noises/paper_writing_2.wav', 'sound/items/writing_noises/paper_writing_3.wav', 'sound/items/writing_noises/paper_writing_4.ogg')
// Weapons/bullets
if("shell_load")
- S = pick('sound/weapons/shell_load1.ogg','sound/weapons/shell_load2.ogg','sound/weapons/shell_load3.ogg','sound/weapons/shell_load4.ogg')
+ sound = pick('sound/weapons/shell_load1.ogg','sound/weapons/shell_load2.ogg','sound/weapons/shell_load3.ogg','sound/weapons/shell_load4.ogg')
if("ballistic_hit")
- S = pick('sound/bullets/bullet_impact1.ogg','sound/bullets/bullet_impact2.ogg','sound/bullets/bullet_impact1.ogg','sound/bullets/impact_flesh_1.ogg','sound/bullets/impact_flesh_2.ogg','sound/bullets/impact_flesh_3.ogg','sound/bullets/impact_flesh_4.ogg')
+ sound = pick('sound/bullets/bullet_impact1.ogg','sound/bullets/bullet_impact2.ogg','sound/bullets/bullet_impact1.ogg','sound/bullets/impact_flesh_1.ogg','sound/bullets/impact_flesh_2.ogg','sound/bullets/impact_flesh_3.ogg','sound/bullets/impact_flesh_4.ogg')
if("ballistic_armor")
- S = pick('sound/bullets/bullet_armor1.ogg','sound/bullets/bullet_armor2.ogg','sound/bullets/bullet_armor3.ogg','sound/bullets/bullet_armor4.ogg')
+ sound = pick('sound/bullets/bullet_armor1.ogg','sound/bullets/bullet_armor2.ogg','sound/bullets/bullet_armor3.ogg','sound/bullets/bullet_armor4.ogg')
if("ballistic_miss")
- S = pick('sound/bullets/bullet_miss1.ogg','sound/bullets/bullet_miss2.ogg','sound/bullets/bullet_miss3.ogg','sound/bullets/bullet_miss4.ogg')
+ sound = pick('sound/bullets/bullet_miss1.ogg','sound/bullets/bullet_miss2.ogg','sound/bullets/bullet_miss3.ogg','sound/bullets/bullet_miss4.ogg')
if("ballistic_bounce")
- S = pick('sound/bullets/bullet_ricochet1.ogg','sound/bullets/bullet_ricochet2.ogg','sound/bullets/bullet_ricochet3.ogg','sound/bullets/bullet_ricochet4.ogg','sound/bullets/bullet_ricochet5.ogg','sound/bullets/bullet_ricochet6.ogg','sound/bullets/bullet_ricochet7.ogg','sound/bullets/bullet_ricochet8.ogg')
+ sound = pick('sound/bullets/bullet_ricochet1.ogg','sound/bullets/bullet_ricochet2.ogg','sound/bullets/bullet_ricochet3.ogg','sound/bullets/bullet_ricochet4.ogg','sound/bullets/bullet_ricochet5.ogg','sound/bullets/bullet_ricochet6.ogg','sound/bullets/bullet_ricochet7.ogg','sound/bullets/bullet_ricochet8.ogg')
if("ballistic_shield_hit")
- S = pick('sound/bullets/shield_impact_c1.ogg','sound/bullets/shield_impact_c2.ogg','sound/bullets/shield_impact_c3.ogg','sound/bullets/shield_impact_c4.ogg')
+ sound = pick('sound/bullets/shield_impact_c1.ogg','sound/bullets/shield_impact_c2.ogg','sound/bullets/shield_impact_c3.ogg','sound/bullets/shield_impact_c4.ogg')
if("shield_shatter")
- S = pick('sound/bullets/shield_break_c1.ogg')
+ sound = pick('sound/bullets/shield_break_c1.ogg')
if("rocket_bounce")
- S = pick('sound/bullets/rocket_ricochet1.ogg','sound/bullets/rocket_ricochet2.ogg','sound/bullets/rocket_ricochet3.ogg')
+ sound = pick('sound/bullets/rocket_ricochet1.ogg','sound/bullets/rocket_ricochet2.ogg','sound/bullets/rocket_ricochet3.ogg')
if("energy_hit")
- S = pick('sound/bullets/energy_impact1.ogg')
+ sound = pick('sound/bullets/energy_impact1.ogg')
if("energy_miss")
- S = pick('sound/bullets/energy_miss1.ogg')
+ sound = pick('sound/bullets/energy_miss1.ogg')
if("energy_bounce")
- S = pick('sound/bullets/energy_ricochet1.ogg')
+ sound = pick('sound/bullets/energy_ricochet1.ogg')
if("alloy_hit")
- S = pick('sound/bullets/spear_impact1.ogg')
+ sound = pick('sound/bullets/spear_impact1.ogg')
if("alloy_armor")
- S = pick('sound/bullets/spear_armor1.ogg')
+ sound = pick('sound/bullets/spear_armor1.ogg')
if("alloy_bounce")
- S = pick('sound/bullets/spear_ricochet1.ogg','sound/bullets/spear_ricochet2.ogg')
+ sound = pick('sound/bullets/spear_ricochet1.ogg','sound/bullets/spear_ricochet2.ogg')
if("gun_silenced")
- S = pick('sound/weapons/gun_silenced_shot1.ogg','sound/weapons/gun_silenced_shot2.ogg')
+ sound = pick('sound/weapons/gun_silenced_shot1.ogg','sound/weapons/gun_silenced_shot2.ogg')
if("gun_pulse")
- S = pick('sound/weapons/gun_m41a_1.ogg','sound/weapons/gun_m41a_2.ogg','sound/weapons/gun_m41a_3.ogg','sound/weapons/gun_m41a_4.ogg','sound/weapons/gun_m41a_5.ogg','sound/weapons/gun_m41a_6.ogg')
+ sound = pick('sound/weapons/gun_m41a_1.ogg','sound/weapons/gun_m41a_2.ogg','sound/weapons/gun_m41a_3.ogg','sound/weapons/gun_m41a_4.ogg','sound/weapons/gun_m41a_5.ogg','sound/weapons/gun_m41a_6.ogg')
if("gun_smartgun")
- S = pick('sound/weapons/gun_smartgun1.ogg', 'sound/weapons/gun_smartgun2.ogg', 'sound/weapons/gun_smartgun3.ogg', 'sound/weapons/gun_smartgun4.ogg')
+ sound = pick('sound/weapons/gun_smartgun1.ogg', 'sound/weapons/gun_smartgun2.ogg', 'sound/weapons/gun_smartgun3.ogg', 'sound/weapons/gun_smartgun4.ogg')
if("gun_smartgun_rattle")
- S = pick('sound/weapons/gun_smartgun1_rattle.ogg', 'sound/weapons/gun_smartgun2_rattle.ogg', 'sound/weapons/gun_smartgun3_rattle.ogg', 'sound/weapons/gun_smartgun4_rattle.ogg')
+ sound = pick('sound/weapons/gun_smartgun1_rattle.ogg', 'sound/weapons/gun_smartgun2_rattle.ogg', 'sound/weapons/gun_smartgun3_rattle.ogg', 'sound/weapons/gun_smartgun4_rattle.ogg')
if("gun_jam_rack")
- S = pick('sound/weapons/handling/gun_jam_rack_1.ogg', 'sound/weapons/handling/gun_jam_rack_2.ogg', 'sound/weapons/handling/gun_jam_rack_3.ogg')
+ sound = pick('sound/weapons/handling/gun_jam_rack_1.ogg', 'sound/weapons/handling/gun_jam_rack_2.ogg', 'sound/weapons/handling/gun_jam_rack_3.ogg')
//A:CM gun sounds
if("gun_shotgun_tactical")
- S = pick('sound/weapons/gun_shotgun_tactical_1.ogg','sound/weapons/gun_shotgun_tactical_2.ogg','sound/weapons/gun_shotgun_tactical_3.ogg','sound/weapons/gun_shotgun_tactical_4.ogg')
+ sound = pick('sound/weapons/gun_shotgun_tactical_1.ogg','sound/weapons/gun_shotgun_tactical_2.ogg','sound/weapons/gun_shotgun_tactical_3.ogg','sound/weapons/gun_shotgun_tactical_4.ogg')
if("m4a3")
- S = pick('sound/weapons/gun_m4a3_1.ogg','sound/weapons/gun_m4a3_2.ogg','sound/weapons/gun_m4a3_3.ogg','sound/weapons/gun_m4a3_4.ogg','sound/weapons/gun_m4a3_5.ogg')
+ sound = pick('sound/weapons/gun_m4a3_1.ogg','sound/weapons/gun_m4a3_2.ogg','sound/weapons/gun_m4a3_3.ogg','sound/weapons/gun_m4a3_4.ogg','sound/weapons/gun_m4a3_5.ogg')
if("88m4")
- S = pick('sound/weapons/gun_88m4_v7.ogg')
+ sound = pick('sound/weapons/gun_88m4_v7.ogg')
if("gun_casing_shotgun")
- S = pick ('sound/bullets/bulletcasing_shotgun_fall1.ogg')
+ sound = pick ('sound/bullets/bulletcasing_shotgun_fall1.ogg')
if("gun_nsg23")
- S = pick('sound/weapons/gun_nsg23_1.ogg','sound/weapons/gun_nsg23_2.ogg')
+ sound = pick('sound/weapons/gun_nsg23_1.ogg','sound/weapons/gun_nsg23_2.ogg')
if("gun_pkd")
- S = pick('sound/weapons/gun_pkd_fire01.ogg','sound/weapons/gun_pkd_fire02.ogg','sound/weapons/gun_pkd_fire03.ogg')
+ sound = pick('sound/weapons/gun_pkd_fire01.ogg','sound/weapons/gun_pkd_fire02.ogg','sound/weapons/gun_pkd_fire03.ogg')
// Xeno
if("acid_hit")
- S = pick('sound/bullets/acid_impact1.ogg')
+ sound = pick('sound/bullets/acid_impact1.ogg')
if("acid_strike")
- S = pick('sound/weapons/alien_acidstrike1.ogg','sound/weapons/alien_acidstrike2.ogg')
+ sound = pick('sound/weapons/alien_acidstrike1.ogg','sound/weapons/alien_acidstrike2.ogg')
if("acid_spit")
- S = pick('sound/voice/alien_spitacid.ogg','sound/voice/alien_spitacid2.ogg')
+ sound = pick('sound/voice/alien_spitacid.ogg','sound/voice/alien_spitacid2.ogg')
if("acid_sizzle")
- S = pick('sound/effects/acid_sizzle1.ogg','sound/effects/acid_sizzle2.ogg','sound/effects/acid_sizzle3.ogg','sound/effects/acid_sizzle4.ogg')
+ sound = pick('sound/effects/acid_sizzle1.ogg','sound/effects/acid_sizzle2.ogg','sound/effects/acid_sizzle3.ogg','sound/effects/acid_sizzle4.ogg')
if("alien_doorpry")
- S = pick('sound/effects/alien_doorpry1.ogg','sound/effects/alien_doorpry2.ogg')
+ sound = pick('sound/effects/alien_doorpry1.ogg','sound/effects/alien_doorpry2.ogg')
if("acid_bounce")
- S = pick('sound/bullets/acid_impact1.ogg')
+ sound = pick('sound/bullets/acid_impact1.ogg')
if("alien_claw_flesh")
- S = pick('sound/weapons/alien_claw_flesh1.ogg','sound/weapons/alien_claw_flesh2.ogg','sound/weapons/alien_claw_flesh3.ogg','sound/weapons/alien_claw_flesh4.ogg','sound/weapons/alien_claw_flesh5.ogg','sound/weapons/alien_claw_flesh6.ogg')
+ sound = pick('sound/weapons/alien_claw_flesh1.ogg','sound/weapons/alien_claw_flesh2.ogg','sound/weapons/alien_claw_flesh3.ogg','sound/weapons/alien_claw_flesh4.ogg','sound/weapons/alien_claw_flesh5.ogg','sound/weapons/alien_claw_flesh6.ogg')
if("alien_claw_metal")
- S = pick('sound/weapons/alien_claw_metal1.ogg','sound/weapons/alien_claw_metal2.ogg','sound/weapons/alien_claw_metal3.ogg')
+ sound = pick('sound/weapons/alien_claw_metal1.ogg','sound/weapons/alien_claw_metal2.ogg','sound/weapons/alien_claw_metal3.ogg')
if("alien_bite")
- S = pick('sound/weapons/alien_bite1.ogg','sound/weapons/alien_bite2.ogg')
+ sound = pick('sound/weapons/alien_bite1.ogg','sound/weapons/alien_bite2.ogg')
if("alien_footstep_large")
- S = pick('sound/effects/alien_footstep_large1.ogg','sound/effects/alien_footstep_large2.ogg','sound/effects/alien_footstep_large3.ogg')
+ sound = pick('sound/effects/alien_footstep_large1.ogg','sound/effects/alien_footstep_large2.ogg','sound/effects/alien_footstep_large3.ogg')
if("alien_footstep_medium")
- S = pick('sound/effects/alien_footstep_medium1.ogg','sound/effects/alien_footstep_medium2.ogg','sound/effects/alien_footstep_medium3.ogg')
+ sound = pick('sound/effects/alien_footstep_medium1.ogg','sound/effects/alien_footstep_medium2.ogg','sound/effects/alien_footstep_medium3.ogg')
if("alien_charge")
- S = pick('sound/effects/alien_footstep_charge1.ogg','sound/effects/alien_footstep_charge2.ogg','sound/effects/alien_footstep_charge3.ogg')
+ sound = pick('sound/effects/alien_footstep_charge1.ogg','sound/effects/alien_footstep_charge2.ogg','sound/effects/alien_footstep_charge3.ogg')
if("alien_resin_build")
- S = pick('sound/effects/alien_resin_build1.ogg','sound/effects/alien_resin_build2.ogg','sound/effects/alien_resin_build3.ogg')
+ sound = pick('sound/effects/alien_resin_build1.ogg','sound/effects/alien_resin_build2.ogg','sound/effects/alien_resin_build3.ogg')
if("alien_resin_break")
- S = pick('sound/effects/alien_resin_break1.ogg','sound/effects/alien_resin_break2.ogg','sound/effects/alien_resin_break3.ogg')
+ sound = pick('sound/effects/alien_resin_break1.ogg','sound/effects/alien_resin_break2.ogg','sound/effects/alien_resin_break3.ogg')
if("alien_resin_move")
- S = pick('sound/effects/alien_resin_move1.ogg','sound/effects/alien_resin_move2.ogg')
+ sound = pick('sound/effects/alien_resin_move1.ogg','sound/effects/alien_resin_move2.ogg')
if("alien_talk")
- S = pick('sound/voice/alien_talk.ogg','sound/voice/alien_talk2.ogg','sound/voice/alien_talk3.ogg')
+ sound = pick('sound/voice/alien_talk.ogg','sound/voice/alien_talk2.ogg','sound/voice/alien_talk3.ogg')
if("larva_talk")
- S = pick('sound/voice/larva_talk1.ogg','sound/voice/larva_talk2.ogg','sound/voice/larva_talk3.ogg','sound/voice/larva_talk4.ogg')
+ sound = pick('sound/voice/larva_talk1.ogg','sound/voice/larva_talk2.ogg','sound/voice/larva_talk3.ogg','sound/voice/larva_talk4.ogg')
if("hiss_talk")
- S = pick('sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg')
+ sound = pick('sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg')
if("alien_growl")
- S = pick('sound/voice/alien_growl1.ogg','sound/voice/alien_growl2.ogg','sound/voice/alien_growl3.ogg')
+ sound = pick('sound/voice/alien_growl1.ogg','sound/voice/alien_growl2.ogg','sound/voice/alien_growl3.ogg')
if("alien_hiss")
- S = pick('sound/voice/alien_hiss1.ogg','sound/voice/alien_hiss2.ogg','sound/voice/alien_hiss3.ogg')
+ sound = pick('sound/voice/alien_hiss1.ogg','sound/voice/alien_hiss2.ogg','sound/voice/alien_hiss3.ogg')
if("alien_tail_swipe")
- S = pick('sound/effects/alien_tail_swipe1.ogg','sound/effects/alien_tail_swipe2.ogg','sound/effects/alien_tail_swipe3.ogg')
+ sound = pick('sound/effects/alien_tail_swipe1.ogg','sound/effects/alien_tail_swipe2.ogg','sound/effects/alien_tail_swipe3.ogg')
if("alien_help")
- S = pick('sound/voice/alien_help1.ogg','sound/voice/alien_help2.ogg','sound/voice/alien_help3.ogg')
+ sound = pick('sound/voice/alien_help1.ogg','sound/voice/alien_help2.ogg','sound/voice/alien_help3.ogg')
if("alien_drool")
- S = pick('sound/voice/alien_drool1.ogg','sound/voice/alien_drool2.ogg')
+ sound = pick('sound/voice/alien_drool1.ogg','sound/voice/alien_drool2.ogg')
if("alien_roar")
- S = pick('sound/voice/alien_roar1.ogg','sound/voice/alien_roar2.ogg','sound/voice/alien_roar3.ogg','sound/voice/alien_roar4.ogg','sound/voice/alien_roar5.ogg','sound/voice/alien_roar6.ogg')
+ sound = pick('sound/voice/alien_roar1.ogg','sound/voice/alien_roar2.ogg','sound/voice/alien_roar3.ogg','sound/voice/alien_roar4.ogg','sound/voice/alien_roar5.ogg','sound/voice/alien_roar6.ogg')
if("alien_roar_larva")
- S = pick('sound/voice/alien_roar_larva1.ogg','sound/voice/alien_roar_larva2.ogg')
+ sound = pick('sound/voice/alien_roar_larva1.ogg','sound/voice/alien_roar_larva2.ogg')
if("queen")
- S = pick('sound/voice/alien_queen_command.ogg','sound/voice/alien_queen_command2.ogg','sound/voice/alien_queen_command3.ogg')
+ sound = pick('sound/voice/alien_queen_command.ogg','sound/voice/alien_queen_command2.ogg','sound/voice/alien_queen_command3.ogg')
// Human
if("male_scream")
- S = pick('sound/voice/human_male_scream_1.ogg','sound/voice/human_male_scream_2.ogg','sound/voice/human_male_scream_3.ogg','sound/voice/human_male_scream_4.ogg',5;'sound/voice/human_male_scream_5.ogg',5;'sound/voice/human_jackson_scream.ogg',5;'sound/voice/human_ack_scream.ogg','sound/voice/human_male_scream_6.ogg')
+ sound = pick('sound/voice/human_male_scream_1.ogg','sound/voice/human_male_scream_2.ogg','sound/voice/human_male_scream_3.ogg','sound/voice/human_male_scream_4.ogg',5;'sound/voice/human_male_scream_5.ogg',5;'sound/voice/human_jackson_scream.ogg',5;'sound/voice/human_ack_scream.ogg','sound/voice/human_male_scream_6.ogg')
if("male_pain")
- S = pick('sound/voice/human_male_pain_1.ogg','sound/voice/human_male_pain_2.ogg','sound/voice/human_male_pain_3.ogg',5;'sound/voice/tomscream.ogg',5;'sound/voice/human_bobby_pain.ogg',5;'sound/voice/human_tantrum_scream.ogg', 5;'sound/voice/human_male_pain_rare_1.ogg')
+ sound = pick('sound/voice/human_male_pain_1.ogg','sound/voice/human_male_pain_2.ogg','sound/voice/human_male_pain_3.ogg',5;'sound/voice/tomscream.ogg',5;'sound/voice/human_bobby_pain.ogg',5;'sound/voice/human_tantrum_scream.ogg', 5;'sound/voice/human_male_pain_rare_1.ogg')
if("male_fragout")
- S = pick('sound/voice/human_male_grenadethrow_1.ogg', 'sound/voice/human_male_grenadethrow_2.ogg', 'sound/voice/human_male_grenadethrow_3.ogg')
+ sound = pick('sound/voice/human_male_grenadethrow_1.ogg', 'sound/voice/human_male_grenadethrow_2.ogg', 'sound/voice/human_male_grenadethrow_3.ogg')
if("male_warcry")
- S = pick('sound/voice/warcry/male_go.ogg', 'sound/voice/warcry/male_attack.ogg', 'sound/voice/warcry/male_charge.ogg', 'sound/voice/warcry/male_charge2.ogg', 'sound/voice/warcry/warcry_male_1.ogg', 'sound/voice/warcry/warcry_male_2.ogg', 'sound/voice/warcry/warcry_male_3.ogg', 'sound/voice/warcry/warcry_male_4.ogg', 'sound/voice/warcry/warcry_male_5.ogg', 'sound/voice/warcry/warcry_male_6.ogg', 'sound/voice/warcry/warcry_male_7.ogg', 'sound/voice/warcry/warcry_male_8.ogg', 'sound/voice/warcry/warcry_male_9.ogg', 'sound/voice/warcry/warcry_male_10.ogg', 'sound/voice/warcry/warcry_male_11.ogg', 'sound/voice/warcry/warcry_male_12.ogg', 'sound/voice/warcry/warcry_male_13.ogg', 'sound/voice/warcry/warcry_male_14.ogg', 'sound/voice/warcry/warcry_male_15.ogg', 'sound/voice/warcry/warcry_male_16.ogg', 'sound/voice/warcry/warcry_male_17.ogg', 'sound/voice/warcry/warcry_male_18.ogg', 'sound/voice/warcry/warcry_male_19.ogg', 'sound/voice/warcry/warcry_male_20.ogg', 'sound/voice/warcry/warcry_male_21.ogg', 'sound/voice/warcry/warcry_male_22.ogg', 'sound/voice/warcry/warcry_male_23.ogg', 'sound/voice/warcry/warcry_male_24.ogg', 'sound/voice/warcry/warcry_male_25.ogg', 'sound/voice/warcry/warcry_male_26.ogg', 'sound/voice/warcry/warcry_male_27.ogg', 'sound/voice/warcry/warcry_male_28.ogg', 'sound/voice/warcry/warcry_male_29.ogg', 'sound/voice/warcry/warcry_male_30.ogg', 'sound/voice/warcry/warcry_male_31.ogg', 'sound/voice/warcry/warcry_male_32.ogg', 'sound/voice/warcry/warcry_male_33.ogg', 'sound/voice/warcry/warcry_male_34.ogg', 'sound/voice/warcry/warcry_male_35.ogg', 5;'sound/voice/warcry/warcry_male_rare_1.ogg', 5;'sound/voice/warcry/warcry_male_rare_2.ogg', 5;'sound/voice/warcry/warcry_male_rare_3.ogg', 5;'sound/voice/warcry/warcry_male_rare_4.ogg', 5;'sound/voice/warcry/warcry_male_rare_5.ogg')
+ sound = pick('sound/voice/warcry/male_go.ogg', 'sound/voice/warcry/male_attack.ogg', 'sound/voice/warcry/male_charge.ogg', 'sound/voice/warcry/male_charge2.ogg', 'sound/voice/warcry/warcry_male_1.ogg', 'sound/voice/warcry/warcry_male_2.ogg', 'sound/voice/warcry/warcry_male_3.ogg', 'sound/voice/warcry/warcry_male_4.ogg', 'sound/voice/warcry/warcry_male_5.ogg', 'sound/voice/warcry/warcry_male_6.ogg', 'sound/voice/warcry/warcry_male_7.ogg', 'sound/voice/warcry/warcry_male_8.ogg', 'sound/voice/warcry/warcry_male_9.ogg', 'sound/voice/warcry/warcry_male_10.ogg', 'sound/voice/warcry/warcry_male_11.ogg', 'sound/voice/warcry/warcry_male_12.ogg', 'sound/voice/warcry/warcry_male_13.ogg', 'sound/voice/warcry/warcry_male_14.ogg', 'sound/voice/warcry/warcry_male_15.ogg', 'sound/voice/warcry/warcry_male_16.ogg', 'sound/voice/warcry/warcry_male_17.ogg', 'sound/voice/warcry/warcry_male_18.ogg', 'sound/voice/warcry/warcry_male_19.ogg', 'sound/voice/warcry/warcry_male_20.ogg', 'sound/voice/warcry/warcry_male_21.ogg', 'sound/voice/warcry/warcry_male_22.ogg', 'sound/voice/warcry/warcry_male_23.ogg', 'sound/voice/warcry/warcry_male_24.ogg', 'sound/voice/warcry/warcry_male_25.ogg', 'sound/voice/warcry/warcry_male_26.ogg', 'sound/voice/warcry/warcry_male_27.ogg', 'sound/voice/warcry/warcry_male_28.ogg', 'sound/voice/warcry/warcry_male_29.ogg', 'sound/voice/warcry/warcry_male_30.ogg', 'sound/voice/warcry/warcry_male_31.ogg', 'sound/voice/warcry/warcry_male_32.ogg', 'sound/voice/warcry/warcry_male_33.ogg', 'sound/voice/warcry/warcry_male_34.ogg', 'sound/voice/warcry/warcry_male_35.ogg', 5;'sound/voice/warcry/warcry_male_rare_1.ogg', 5;'sound/voice/warcry/warcry_male_rare_2.ogg', 5;'sound/voice/warcry/warcry_male_rare_3.ogg', 5;'sound/voice/warcry/warcry_male_rare_4.ogg', 5;'sound/voice/warcry/warcry_male_rare_5.ogg')
if("male_upp_warcry")
- S = pick('sound/voice/upp_warcry/warcry_male_1.ogg', 'sound/voice/upp_warcry/warcry_male_2.ogg')
+ sound = pick('sound/voice/upp_warcry/warcry_male_1.ogg', 'sound/voice/upp_warcry/warcry_male_2.ogg')
if("female_scream")
- S = pick('sound/voice/human_female_scream_1.ogg','sound/voice/human_female_scream_2.ogg','sound/voice/human_female_scream_3.ogg','sound/voice/human_female_scream_4.ogg',5;'sound/voice/human_female_scream_5.ogg')
+ sound = pick('sound/voice/human_female_scream_1.ogg','sound/voice/human_female_scream_2.ogg','sound/voice/human_female_scream_3.ogg','sound/voice/human_female_scream_4.ogg',5;'sound/voice/human_female_scream_5.ogg')
if("female_pain")
- S = pick('sound/voice/human_female_pain_1.ogg','sound/voice/human_female_pain_2.ogg','sound/voice/human_female_pain_3.ogg')
+ sound = pick('sound/voice/human_female_pain_1.ogg','sound/voice/human_female_pain_2.ogg','sound/voice/human_female_pain_3.ogg')
if("female_fragout")
- S = pick("sound/voice/human_female_grenadethrow_1.ogg", 'sound/voice/human_female_grenadethrow_2.ogg', 'sound/voice/human_female_grenadethrow_3.ogg')
+ sound = pick("sound/voice/human_female_grenadethrow_1.ogg", 'sound/voice/human_female_grenadethrow_2.ogg', 'sound/voice/human_female_grenadethrow_3.ogg')
if("female_warcry")
- S = pick('sound/voice/warcry/female_charge.ogg', 'sound/voice/warcry/female_yell1.ogg', 'sound/voice/warcry/warcry_female_1.ogg', 'sound/voice/warcry/warcry_female_2.ogg', 'sound/voice/warcry/warcry_female_3.ogg', 'sound/voice/warcry/warcry_female_4.ogg', 'sound/voice/warcry/warcry_female_5.ogg', 'sound/voice/warcry/warcry_female_6.ogg', 'sound/voice/warcry/warcry_female_7.ogg', 'sound/voice/warcry/warcry_female_8.ogg', 'sound/voice/warcry/warcry_female_9.ogg', 'sound/voice/warcry/warcry_female_10.ogg', 'sound/voice/warcry/warcry_female_11.ogg', 'sound/voice/warcry/warcry_female_12.ogg', 'sound/voice/warcry/warcry_female_13.ogg', 'sound/voice/warcry/warcry_female_14.ogg', 'sound/voice/warcry/warcry_female_15.ogg', 'sound/voice/warcry/warcry_female_16.ogg', 'sound/voice/warcry/warcry_female_17.ogg', 'sound/voice/warcry/warcry_female_18.ogg', 'sound/voice/warcry/warcry_female_19.ogg', 'sound/voice/warcry/warcry_female_20.ogg')
+ sound = pick('sound/voice/warcry/female_charge.ogg', 'sound/voice/warcry/female_yell1.ogg', 'sound/voice/warcry/warcry_female_1.ogg', 'sound/voice/warcry/warcry_female_2.ogg', 'sound/voice/warcry/warcry_female_3.ogg', 'sound/voice/warcry/warcry_female_4.ogg', 'sound/voice/warcry/warcry_female_5.ogg', 'sound/voice/warcry/warcry_female_6.ogg', 'sound/voice/warcry/warcry_female_7.ogg', 'sound/voice/warcry/warcry_female_8.ogg', 'sound/voice/warcry/warcry_female_9.ogg', 'sound/voice/warcry/warcry_female_10.ogg', 'sound/voice/warcry/warcry_female_11.ogg', 'sound/voice/warcry/warcry_female_12.ogg', 'sound/voice/warcry/warcry_female_13.ogg', 'sound/voice/warcry/warcry_female_14.ogg', 'sound/voice/warcry/warcry_female_15.ogg', 'sound/voice/warcry/warcry_female_16.ogg', 'sound/voice/warcry/warcry_female_17.ogg', 'sound/voice/warcry/warcry_female_18.ogg', 'sound/voice/warcry/warcry_female_19.ogg', 'sound/voice/warcry/warcry_female_20.ogg')
if("female_upp_warcry")
- S = pick('sound/voice/upp_warcry/warcry_female_1.ogg', 'sound/voice/upp_warcry/warcry_female_2.ogg')
+ sound = pick('sound/voice/upp_warcry/warcry_female_1.ogg', 'sound/voice/upp_warcry/warcry_female_2.ogg')
if("rtb_handset")
- S = pick('sound/machines/telephone/rtb_handset_1.ogg', 'sound/machines/telephone/rtb_handset_2.ogg', 'sound/machines/telephone/rtb_handset_3.ogg', 'sound/machines/telephone/rtb_handset_4.ogg', 'sound/machines/telephone/rtb_handset_5.ogg')
+ sound = pick('sound/machines/telephone/rtb_handset_1.ogg', 'sound/machines/telephone/rtb_handset_2.ogg', 'sound/machines/telephone/rtb_handset_3.ogg', 'sound/machines/telephone/rtb_handset_4.ogg', 'sound/machines/telephone/rtb_handset_5.ogg')
+ if("talk_phone")
+ sound = pick('sound/machines/telephone/talk_phone1.ogg', 'sound/machines/telephone/talk_phone2.ogg', 'sound/machines/telephone/talk_phone3.ogg', 'sound/machines/telephone/talk_phone4.ogg', 'sound/machines/telephone/talk_phone5.ogg', 'sound/machines/telephone/talk_phone6.ogg', 'sound/machines/telephone/talk_phone7.ogg')
if("bone_break")
- S = pick('sound/effects/bone_break1.ogg','sound/effects/bone_break2.ogg','sound/effects/bone_break3.ogg','sound/effects/bone_break4.ogg','sound/effects/bone_break5.ogg','sound/effects/bone_break6.ogg','sound/effects/bone_break7.ogg')
+ sound = pick('sound/effects/bone_break1.ogg','sound/effects/bone_break2.ogg','sound/effects/bone_break3.ogg','sound/effects/bone_break4.ogg','sound/effects/bone_break5.ogg','sound/effects/bone_break6.ogg','sound/effects/bone_break7.ogg')
if("plush")
- S = pick('sound/items/plush1.ogg', 'sound/items/plush2.ogg', 'sound/items/plush3.ogg')
+ sound = pick('sound/items/plush1.ogg', 'sound/items/plush2.ogg', 'sound/items/plush3.ogg')
//misc mobs
if("cat_meow")
- S = pick('sound/voice/cat_meow_1.ogg','sound/voice/cat_meow_2.ogg','sound/voice/cat_meow_3.ogg','sound/voice/cat_meow_4.ogg','sound/voice/cat_meow_5.ogg','sound/voice/cat_meow_6.ogg','sound/voice/cat_meow_7.ogg')
+ sound = pick('sound/voice/cat_meow_1.ogg','sound/voice/cat_meow_2.ogg','sound/voice/cat_meow_3.ogg','sound/voice/cat_meow_4.ogg','sound/voice/cat_meow_5.ogg','sound/voice/cat_meow_6.ogg','sound/voice/cat_meow_7.ogg')
if("pred_pain")
- S = pick('sound/voice/pred_pain1.ogg','sound/voice/pred_pain2.ogg','sound/voice/pred_pain3.ogg','sound/voice/pred_pain4.ogg','sound/voice/pred_pain5.ogg',5;'sound/voice/pred_pain_rare1.ogg')
+ sound = pick('sound/voice/pred_pain1.ogg','sound/voice/pred_pain2.ogg','sound/voice/pred_pain3.ogg','sound/voice/pred_pain4.ogg','sound/voice/pred_pain5.ogg',5;'sound/voice/pred_pain_rare1.ogg')
if("clownstep")
- S = pick('sound/effects/clownstep1.ogg', 'sound/effects/clownstep2.ogg')
- return S
+ sound = pick('sound/effects/clownstep1.ogg', 'sound/effects/clownstep2.ogg')
+ return sound
/client/proc/generate_sound_queues()
set name = "Queue sounds"
@@ -388,21 +410,21 @@
var/x = tgui_input_number(usr, "Center X")
var/y = tgui_input_number(usr, "Center Y")
var/z = tgui_input_number(usr, "Z level")
- var/datum/sound_template/S
+ var/datum/sound_template/template
for(var/i = 1, i <= ammount, i++)
- S = new
- S.file = get_sfx("male_warcry") // warcry has variable length, lots of variations
- S.channel = get_free_channel() // i'm convinced this is bad, but it's here to mirror playsound() behaviour
- S.range = range
- S.x = x
- S.y = y
- S.z = z
- SSsound.queue(S)
+ template = new
+ template.file = get_sfx("male_warcry") // warcry has variable length, lots of variations
+ template.channel = get_free_channel() // i'm convinced this is bad, but it's here to mirror playsound() behaviour
+ template.range = range
+ template.x = x
+ template.y = y
+ template.z = z
+ SSsound.queue(template)
/client/proc/sound_debug_query()
set name = "Dump Playing Client Sounds"
set desc = "dumps info about locally, playing sounds"
set category = "Debug"
- for(var/sound/S in SoundQuery())
- UNLINT(to_chat(src, "channel#[S.channel]: [S.status] - [S.file] - len=[length(S)], wait=[S.wait], offset=[S.offset], repeat=[S.repeat]")) // unlint until spacemandmm suite-1.7
+ for(var/sound/soundin in SoundQuery())
+ UNLINT(to_chat(src, "channel#[soundin.channel]: [soundin.status] - [soundin.file] - len=[length(soundin)], wait=[soundin.wait], offset=[soundin.offset], repeat=[soundin.repeat]")) // unlint until spacemandmm suite-1.7
diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm
index c5a675b531d2..8974eb36187f 100644
--- a/code/game/supplyshuttle.dm
+++ b/code/game/supplyshuttle.dm
@@ -532,7 +532,7 @@ GLOBAL_DATUM_INIT(supply_controller, /datum/controller/supply, new())
for(var/datum/supply_packs_asrs/crate in cratelist)
var/weight = (floor(10000/crate.cost))
weighted_crate_list[crate] = weight
- return pickweight(weighted_crate_list)
+ return pick_weight(weighted_crate_list)
//To stop things being sent to centcomm which should not be sent to centcomm. Recursively checks for these types.
/datum/controller/supply/proc/forbidden_atoms_check(atom/A)
@@ -1115,7 +1115,7 @@ GLOBAL_DATUM_INIT(supply_controller, /datum/controller/supply, new())
else if (href_list["rreq"])
var/ordernum = text2num(href_list["rreq"])
temp = "Invalid Request.
"
- for(var/i=1, length(i<=GLOB.supply_controller.requestlist), i++)
+ for(var/i=1, i<=length(GLOB.supply_controller.requestlist), i++)
var/datum/supply_order/SO = GLOB.supply_controller.requestlist[i]
if(SO.ordernum == ordernum)
GLOB.supply_controller.requestlist.Cut(i,i+1)
diff --git a/code/game/turfs/transit.dm b/code/game/turfs/transit.dm
index 00175ac5e365..5b4645805d3b 100644
--- a/code/game/turfs/transit.dm
+++ b/code/game/turfs/transit.dm
@@ -138,6 +138,12 @@
clear_active_explosives()
ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_DROPSHIP_INTERACTION)
ADD_TRAIT(src, TRAIT_UNDENSE, TRAIT_SOURCE_DROPSHIP_INTERACTION)
+ ADD_TRAIT(src, TRAIT_NO_STRAY, TRAIT_SOURCE_DROPSHIP_INTERACTION)
+ RegisterSignal(src, COMSIG_MOVABLE_FORCEMOVE_PRE_CROSSED, PROC_REF(cancel_cross))
+ RegisterSignal(src, list(
+ COMSIG_LIVING_FLAMER_FLAMED,
+ COMSIG_LIVING_PREIGNITION
+ ), PROC_REF(cancel_fire))
var/image/cables = image('icons/obj/structures/droppod_32x64.dmi', src, "chute_cables_static")
overlays += cables
var/image/chute = image('icons/obj/structures/droppod_64x64.dmi', src, "chute_static")
@@ -163,8 +169,18 @@
return
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_DROPSHIP_INTERACTION)
REMOVE_TRAIT(src, TRAIT_UNDENSE, TRAIT_SOURCE_DROPSHIP_INTERACTION)
+ REMOVE_TRAIT(src, TRAIT_NO_STRAY, TRAIT_SOURCE_DROPSHIP_INTERACTION)
+ UnregisterSignal(src, list(
+ COMSIG_MOVABLE_FORCEMOVE_PRE_CROSSED,
+ COMSIG_LIVING_FLAMER_FLAMED,
+ COMSIG_LIVING_PREIGNITION
+ ))
overlays -= cables
overlays -= chute
+ for(var/atom/movable/atom in loc)
+ if(atom == src)
+ continue
+ atom.Cross(src)
/atom/movable/proc/clear_active_explosives()
for(var/obj/item/explosive/explosive in contents)
@@ -232,6 +248,13 @@
death(last_damage_data)
status_flags |= PERMANENTLY_DEAD
+/atom/movable/proc/cancel_cross()
+ SIGNAL_HANDLER
+ return COMPONENT_IGNORE_CROSS
+
+/atom/movable/proc/cancel_fire()
+ SIGNAL_HANDLER
+ return COMPONENT_NO_BURN
/turf/open/space/transit/dropship/alamo
shuttle_tag = DROPSHIP_ALAMO
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 59a9d6d69315..0082cb6ae0ae 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -478,18 +478,20 @@
/turf/proc/AdjacentTurfs()
var/L[] = new()
- for(var/turf/t in oview(src,1))
+ FOR_DOVIEW(var/turf/t, 1, src, HIDE_INVISIBLE_OBSERVER)
if(!t.density)
if(!LinkBlocked(src, t) && !TurfBlockedNonWindow(t))
L.Add(t)
+ FOR_DOVIEW_END
return L
/turf/proc/AdjacentTurfsSpace()
var/L[] = new()
- for(var/turf/t in oview(src,1))
+ FOR_DOVIEW(var/turf/t, 1, src, HIDE_INVISIBLE_OBSERVER)
if(!t.density)
if(!LinkBlocked(src, t) && !TurfBlockedNonWindow(t))
L.Add(t)
+ FOR_DOVIEW_END
return L
/turf/proc/Distance(turf/t)
diff --git a/code/game/turfs/walls/wall_types.dm b/code/game/turfs/walls/wall_types.dm
index 21839d35af03..6db61002c2fe 100644
--- a/code/game/turfs/walls/wall_types.dm
+++ b/code/game/turfs/walls/wall_types.dm
@@ -297,11 +297,10 @@ INITIALIZE_IMMEDIATE(/turf/closed/wall/indestructible/splashscreen)
/turf/closed/wall/indestructible/splashscreen
name = "Lobby Art"
desc = "Assorted artworks."
- icon = 'icons/lobby/title.dmi'
- icon_state = ""
-// icon_state = "title_holiday"
+ icon = 'icons/lobby/title_loading.dmi'
+ icon_state = "title"
layer = FLY_LAYER
- special_icon = 1
+ special_icon = TRUE
/turf/closed/wall/indestructible/splashscreen/Initialize()
. = ..()
@@ -309,16 +308,19 @@ INITIALIZE_IMMEDIATE(/turf/closed/wall/indestructible/splashscreen)
/proc/force_lobby_art(art_id)
GLOB.displayed_lobby_art = art_id
- var/turf/closed/wall/indestructible/splashscreen/SS = locate("LOBBYART")
+ var/turf/closed/wall/indestructible/splashscreen/lobby_art = locate("LOBBYART")
var/list/lobby_arts = CONFIG_GET(str_list/lobby_art_images)
var/list/lobby_authors = CONFIG_GET(str_list/lobby_art_authors)
- SS.icon_state = lobby_arts[GLOB.displayed_lobby_art]
- SS.desc = "Artwork by [lobby_authors[GLOB.displayed_lobby_art]]"
- for(var/client/C in GLOB.clients)
+ lobby_art.icon = 'icons/lobby/title.dmi'
+ lobby_art.icon_state = lobby_arts[GLOB.displayed_lobby_art]
+ lobby_art.desc = "Artwork by [lobby_authors[GLOB.displayed_lobby_art]]"
+ lobby_art.pixel_x = -288
+ lobby_art.pixel_y = -288
+ for(var/client/player in GLOB.clients)
if(GLOB.displayed_lobby_art != -1)
var/author = lobby_authors[GLOB.displayed_lobby_art]
if(author != "Unknown")
- to_chat_forced(C, SPAN_ROUNDBODY("
This round's lobby art is brought to you by [author]
"))
+ to_chat_forced(player, SPAN_ROUNDBODY("
This round's lobby art is brought to you by [author]
"))
/turf/closed/wall/indestructible/other
icon_state = "r_wall"
diff --git a/code/game/turfs/walls/walls.dm b/code/game/turfs/walls/walls.dm
index bb1694359b98..f82ba6ddadaf 100644
--- a/code/game/turfs/walls/walls.dm
+++ b/code/game/turfs/walls/walls.dm
@@ -566,7 +566,7 @@
// Check again for presence of objects
if(!material || (material != user.l_hand && material != user.r_hand) || material.amount <= 0)
- to_chat(user, SPAN_WARNING("You seems to have misplaced the repair material!"))
+ to_chat(user, SPAN_WARNING("You seem to have misplaced the repair material!"))
return FALSE
if(!NG.in_chamber || !NG.current_mag || NG.current_mag.current_rounds < (4*amount_needed-1))
diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm
deleted file mode 100644
index 3a9274dbec62..000000000000
--- a/code/game/verbs/who.dm
+++ /dev/null
@@ -1,209 +0,0 @@
-/client/verb/who()//likely don't touch any... this is easy can die. (:troll_fale:)
- set name = "Who"
- set category = "OOC"
-
- var/list/counted_humanoids = list(
- "Observers" = 0,
- "Admin observers" = 0,
- "Humans" = 0,
- "Infected humans" = 0,
- FACTION_MARINE = 0,
- "USCM Marines" = 0,
- "Lobby" = 0,
-
- FACTION_YAUTJA = 0,
- "Infected preds" = 0,
-
- FACTION_PMC = 0,
- FACTION_CLF = 0,
- FACTION_UPP = 0,
- FACTION_TWE = 0,
- FACTION_FREELANCER = 0,
- FACTION_SURVIVOR = 0,
- FACTION_WY_DEATHSQUAD = 0,
- FACTION_COLONIST = 0,
- FACTION_MERCENARY = 0,
- FACTION_DUTCH = 0,
- FACTION_HEFA = 0,
- FACTION_GLADIATOR = 0,
- FACTION_PIRATE = 0,
- FACTION_PIZZA = 0,
- FACTION_SOUTO = 0,
-
- FACTION_NEUTRAL = 0,
-
- FACTION_ZOMBIE = 0
- )
-
- var/list/counted_xenos = list()
-
- var/players = length(GLOB.clients)
-
- var/dat = "Current Players:
"
- var/list/Lines = list()
- if(admin_holder && ((R_ADMIN & admin_holder.rights) || (R_MOD & admin_holder.rights)))
- for(var/client/C in GLOB.clients)
- if(!CLIENT_HAS_RIGHTS(src, R_STEALTH) && (CLIENT_IS_STEALTHED(C)))
- continue
- var/entry = "[C.key]"
- if(C.mob) //Juuuust in case
- if(istype(C.mob, /mob/new_player))
- entry += " - In Lobby"
- counted_humanoids["Lobby"]++
- else
- entry += " - Playing as [C.mob.real_name]"
-
- if(isobserver(C.mob))
- counted_humanoids["Observers"]++
- if(C.admin_holder?.rights & R_MOD)
- counted_humanoids["Admin observers"]++
- counted_humanoids["Observers"]--
- var/mob/dead/observer/O = C.mob
- if(O.started_as_observer)
- entry += " - Observing"
- else
- entry += " - DEAD"
- else
- switch(C.mob.stat)
- if(UNCONSCIOUS)
- entry += " - Unconscious"
- if(DEAD)
- entry += " - DEAD"
-
- if(C.mob && C.mob.stat != DEAD)
- if(ishuman(C.mob))
- if(C.mob.faction == FACTION_ZOMBIE)
- counted_humanoids[FACTION_ZOMBIE]++
- entry += " - Zombie"
- else if(C.mob.faction == FACTION_YAUTJA)
- counted_humanoids[FACTION_YAUTJA]++
- entry += " - Predator"
- if(C.mob.status_flags & XENO_HOST)
- counted_humanoids["Infected preds"]++
- else
- counted_humanoids["Humans"]++
- if(C.mob.status_flags & XENO_HOST)
- counted_humanoids["Infected humans"]++
- if(C.mob.faction == FACTION_MARINE)
- counted_humanoids[FACTION_MARINE]++
- if(C.mob.job in (GLOB.ROLES_MARINES))
- counted_humanoids["USCM Marines"]++
- else
- counted_humanoids[C.mob.faction]++
- else if(isxeno(C.mob))
- var/mob/living/carbon/xenomorph/X = C.mob
- counted_xenos[X.hivenumber]++
- if(X.faction == FACTION_PREDALIEN)
- counted_xenos[FACTION_PREDALIEN]++
- entry += " - Xenomorph"
- entry += " (?)"
- Lines += entry
-
- for(var/line in sortList(Lines))
- dat += "[line]
"
- dat += "Total Players: [players]"
- dat += "
In Lobby: [counted_humanoids["Lobby"]]"
- dat += "
Observers: [counted_humanoids["Observers"]] players and [counted_humanoids["Admin observers"]] staff members"
- dat += "
Humans: [counted_humanoids["Humans"]] (Infected: [counted_humanoids["Infected humans"]])"
- if(counted_humanoids[FACTION_MARINE])
- dat += "
USCM personnel: [counted_humanoids[FACTION_MARINE]] (Marines: [counted_humanoids["USCM Marines"]])"
- if(counted_humanoids[FACTION_YAUTJA])
- dat += "
Predators: [counted_humanoids[FACTION_YAUTJA]] [counted_humanoids["Infected preds"] ? "(Infected: [counted_humanoids["Infected preds"]])" : ""]"
- if(counted_humanoids[FACTION_ZOMBIE])
- dat += "
Zombies: [counted_humanoids[FACTION_ZOMBIE]]"
-
- var/show_fact = TRUE
- for(var/i in 10 to LAZYLEN(counted_humanoids) - 2)
- if(counted_humanoids[counted_humanoids[i]])
- if(show_fact)
- dat += "
Other factions:"
- show_fact = FALSE
- dat += "
[counted_humanoids[i]]: [counted_humanoids[counted_humanoids[i]]]"
- if(counted_humanoids[FACTION_NEUTRAL])
- dat += "
[FACTION_NEUTRAL] Humans: [counted_humanoids[FACTION_NEUTRAL]]"
-
- show_fact = TRUE
- var/datum/hive_status/hive
- for(var/hivenumber in counted_xenos)
- // Print predalien counts last
- if(hivenumber == FACTION_PREDALIEN)
- continue
- if(show_fact)
- dat += "
Xenomorphs:"
- show_fact = FALSE
- hive = GLOB.hive_datum[hivenumber]
- if(hive)
- dat += "
[hive.name]: [counted_xenos[hivenumber]] (Queen: [hive.living_xeno_queen ? "Alive" : "Dead"])"
- else
- dat += "
Error: no hive datum detected for [hivenumber]."
- hive = null
- if(counted_xenos[FACTION_PREDALIEN])
- dat += "
Predaliens: [counted_xenos[FACTION_PREDALIEN]]"
-
- else
- for(var/client/C in GLOB.clients)
- if((C.admin_holder && C.admin_holder.fakekey) || (CLIENT_IS_STEALTHED(C)))
- continue
-
- Lines += C.key
- for(var/line in sortList(Lines))
- dat += "[line]
"
- dat += "Total Players: [players]
"
-
- dat += ""
- show_browser(usr, dat, "Who", "who", "size=600x800")
-
-
-/client/verb/staffwho()
- set name = "Staffwho"
- set category = "Admin"
-
- var/dat = ""
- var/list/mappings
- if(CONFIG_GET(flag/show_manager))
- LAZYSET(mappings, "Management", R_PERMISSIONS)
- if(CONFIG_GET(flag/show_devs))
- LAZYSET(mappings, "Maintainers", R_PROFILER)
- LAZYSET(mappings, "Admins", R_ADMIN)
- if(CONFIG_GET(flag/show_mods))
- LAZYSET(mappings, "Moderators", R_MOD)
- if(CONFIG_GET(flag/show_mentors))
- LAZYSET(mappings, "Mentors", R_MENTOR)
-
- var/list/listings
- for(var/category in mappings)
- LAZYSET(listings, category, list())
-
- for(var/client/C in GLOB.admins)
- if(CLIENT_IS_STEALTHED(C) && !CLIENT_HAS_RIGHTS(src, R_STEALTH))
- continue
- if(C.admin_holder?.fakekey && !CLIENT_IS_STAFF(src))
- continue
- for(var/category in mappings)
- if(CLIENT_HAS_RIGHTS(C, mappings[category]))
- LAZYADD(listings[category], C)
- break
-
- for(var/category in listings)
- dat += "
Current [category] ([length(listings[category])]):
\n"
- for(var/client/entry in listings[category])
- dat += "\t[entry.key] is \a [entry.admin_holder.rank]"
- if(LAZYLEN(entry.admin_holder.extra_titles))
- for(var/srank in entry.admin_holder.extra_titles)
- dat += " & [srank]"
- if(CLIENT_IS_STAFF(src))
- if(CLIENT_IS_STEALTHED(entry))
- dat += " (STEALTHED)"
- else if(entry.admin_holder?.fakekey)
- dat += " (HIDDEN)"
- if(istype(entry.mob, /mob/dead/observer))
- dat += " - Observing"
- else if(istype(entry.mob, /mob/new_player))
- dat += " - Lobby"
- else
- dat += " - Playing"
- if(entry.is_afk())
- dat += " (AFK)"
- dat += "
"
- dat += "