diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9be0d787a1..638ef4d2f3 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -47,7 +47,7 @@ jobs:
~/dreamchecker > ${GITHUB_WORKSPACE}/output-annotations.txt 2>&1
- name: Annotate Linter
- uses: yogstation13/DreamAnnotate@v1
+ uses: yogstation13/DreamAnnotate@v2
if: always()
with:
outputFile: output-annotations.txt
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index 44a97bb39d..63db36395e 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -313,6 +313,8 @@ var/global/list/##LIST_NAME = list();\
#define send_link(target, url) target << link(url)
+#define SPAN_ITALIC(X) "[X]"
+
#define SPAN_NOTICE(X) "[X]"
#define SPAN_WARNING(X) "[X]"
diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm
index b3b8924a17..978414c464 100644
--- a/code/__defines/mobs.dm
+++ b/code/__defines/mobs.dm
@@ -452,3 +452,14 @@
/// Used by human/get_visible_gender(user, force) to return the mob's biological gender
#define VISIBLE_GENDER_FORCE_BIOLOGICAL 3
+
+
+// Dexterity levels for mob/proc/check_dexterity
+#define MOB_DEXTERITY_NONE 0
+#define MOB_DEXTERITY_SIMPLE_MACHINES 10
+#define MOB_DEXTERITY_KEYBOARDS 20
+#define MOB_DEXTERITY_TOUCHSCREENS 30
+#define MOB_DEXTERITY_GRIP 40
+#define MOB_DEXTERITY_WEAPONS 50
+#define MOB_DEXTERITY_COMPLEX_TOOLS 60
+#define MOB_DEXTERITY_FULL 70
diff --git a/code/_helpers/type2type.dm b/code/_helpers/type2type.dm
index 34237faad1..0cc3327b68 100644
--- a/code/_helpers/type2type.dm
+++ b/code/_helpers/type2type.dm
@@ -349,21 +349,22 @@
last_found = found + delim_len
while (found)
+
/proc/type2parent(child)
var/string_type = "[child]"
var/last_slash = findlasttext(string_type, "/")
- if(last_slash == 1)
- switch(child)
- if(/datum)
- return null
- if(/obj || /mob)
- return /atom/movable
- if(/area || /turf)
- return /atom
- else
- return /datum
+ if (last_slash != 1)
+ return text2path(copytext(string_type, 1, last_slash))
+ switch (child)
+ if (/datum)
+ return null
+ if (/obj, /mob)
+ return /atom/movable
+ if (/area, /turf)
+ return /atom
+ else
+ return /datum
- return text2path(copytext(string_type, 1, last_slash))
//checks if a file exists and contains text
//returns text as a string if these conditions are met
diff --git a/code/datums/chat_message.dm b/code/datums/chat_message.dm
index 41cd3e756a..b8ad0797b8 100644
--- a/code/datums/chat_message.dm
+++ b/code/datums/chat_message.dm
@@ -17,6 +17,8 @@
#define CHAT_RUNE_EMOTE 0x1
#define CHAT_RUNE_RADIO 0x2
+#define CHAT_MESSAGE_DEFAULT_ACTION "👁"
+
/**
* # Chat Message Overlay
*
diff --git a/code/datums/outfits/costumes/halloween.dm b/code/datums/outfits/costumes/halloween.dm
index 278b452cd2..92302660d7 100644
--- a/code/datums/outfits/costumes/halloween.dm
+++ b/code/datums/outfits/costumes/halloween.dm
@@ -77,9 +77,9 @@
name = OUTFIT_COSTUME("Firefighter")
uniform = /obj/item/clothing/under/pants
shoes = /obj/item/clothing/shoes/boots/workboots
- head = /obj/item/clothing/head/hardhat/red
+ head = /obj/item/clothing/head/hardhat/red/firefighter
gloves = /obj/item/clothing/gloves/black
- suit = /obj/item/clothing/suit/fire/firefighter
+ suit = /obj/item/clothing/suit/fire
mask = /obj/item/clothing/mask/gas
/decl/hierarchy/outfit/costume/highlander
@@ -127,4 +127,4 @@
shoes = /obj/item/clothing/shoes/brown
head = /obj/item/clothing/head/marine
suit = /obj/item/clothing/suit/marine
- r_hand = /obj/item/gun/projectile/revolver/toy/sawnoff
\ No newline at end of file
+ r_hand = /obj/item/gun/projectile/revolver/toy/sawnoff
diff --git a/code/datums/uplink/ammunition.dm b/code/datums/uplink/ammunition.dm
index b086e656c4..e82763671e 100644
--- a/code/datums/uplink/ammunition.dm
+++ b/code/datums/uplink/ammunition.dm
@@ -27,6 +27,10 @@
name = "Pistol Magazine (.45)"
path = /obj/item/ammo_magazine/m45
+/datum/uplink_item/item/ammo/c45mcompact
+ name = "Pistol Magazine (.45 Compact)"
+ path = /obj/item/ammo_magazine/m45/compact
+
/datum/uplink_item/item/ammo/c45map
name = "Pistol Magazine (.45 AP)"
path = /obj/item/ammo_magazine/m45/ap
@@ -130,4 +134,4 @@
/datum/uplink_item/item/ammo/cell
name = "weapon cell"
- path = /obj/item/cell/device/weapon
\ No newline at end of file
+ path = /obj/item/cell/device/weapon
diff --git a/code/datums/uplink/visible_weapons.dm b/code/datums/uplink/visible_weapons.dm
index 5752328a62..6449a53465 100644
--- a/code/datums/uplink/visible_weapons.dm
+++ b/code/datums/uplink/visible_weapons.dm
@@ -138,7 +138,7 @@
name = "Combat Shotgun"
item_cost = 75
path = /obj/item/gun/projectile/shotgun/pump/combat
-
+
/datum/uplink_item/item/visible_weapons/semishotgun
name = "Semi-Automatic Shotgun"
item_cost = 100
@@ -154,6 +154,11 @@
item_cost = 30
path = /obj/item/gun/energy/gun/compact
+/datum/uplink_item/item/visible_weapons/compact_45
+ name = "Compact .45 pistol"
+ item_cost = 40
+ path = /obj/item/gun/projectile/compact_45
+
/datum/uplink_item/item/visible_weapons/lasercannon
name = "Laser Cannon"
item_cost = 60
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 6e38890a7f..caba1e7578 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -498,7 +498,7 @@ var/global/list/pre_init_created_atoms // atom creation ordering means some stuf
// Use for objects performing visible actions
// message is output to anyone who can see, e.g. "The [src] does something!"
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
-/atom/proc/visible_message(var/message, var/blind_message, var/list/exclude_mobs, var/range = world.view, var/runemessage = "👁")
+/atom/proc/visible_message(var/message, var/blind_message, var/list/exclude_mobs, var/range = world.view, var/runemessage = CHAT_MESSAGE_DEFAULT_ACTION)
var/list/see = get_mobs_and_objs_in_view_fast(get_turf(src), range, remote_ghosts = FALSE)
diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm
index 99681495ed..aa66899d88 100644
--- a/code/game/machinery/buttons.dm
+++ b/code/game/machinery/buttons.dm
@@ -10,9 +10,10 @@
use_power = USE_POWER_IDLE
idle_power_usage = 2
active_power_usage = 4
+ required_dexterity = MOB_DEXTERITY_SIMPLE_MACHINES
-/obj/machinery/button/attack_ai(mob/user as mob)
+/obj/machinery/button/attack_ai(mob/user)
return attack_hand(user)
-/obj/machinery/button/attackby(obj/item/W, mob/user as mob)
- return attack_hand(user)
\ No newline at end of file
+/obj/machinery/button/attackby(obj/item/item, mob/user)
+ return attack_hand(user)
diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm
index 0c2904a3f1..6f28092ffa 100644
--- a/code/game/machinery/doors/airlock_control.dm
+++ b/code/game/machinery/doors/airlock_control.dm
@@ -228,6 +228,8 @@
anchored = 1
power_channel = ENVIRON
+ required_dexterity = MOB_DEXTERITY_SIMPLE_MACHINES
+
var/master_tag
var/frequency = 1449
var/command = "cycle"
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 105f05a9c3..2d433f6b7d 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -35,10 +35,12 @@
dir = EAST
var/width = 1
+ required_dexterity = MOB_DEXTERITY_SIMPLE_MACHINES
+
// turf animation
var/atom/movable/overlay/c_animation = null
-/obj/machinery/door/attack_generic(var/mob/user, var/damage)
+/obj/machinery/door/attack_generic(mob/user, damage)
if(isanimal(user))
var/mob/living/simple_mob/S = user
if(S.a_intent == I_HURT && damage >= STRUCTURE_MIN_DAMAGE_THRESHOLD)
@@ -46,10 +48,13 @@
playsound(src, S.attack_sound, 75, 1)
take_damage(damage)
else if(user.a_intent == I_HELP)
+ if (S.scratch_sound)
+ playsound(src, S.scratch_sound, 75, TRUE)
user.visible_message(SPAN_NOTICE("\The [user] scratches at the bottom of \the [src]."))
else
visible_message(SPAN_NOTICE("\The [user] bonks \the [src] harmlessly."))
user.do_attack_animation(src)
+ user.setClickCooldown(user.get_attack_speed())
return
..()
diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm
index 8a20818fb8..998fcff419 100644
--- a/code/game/machinery/doors/unpowered.dm
+++ b/code/game/machinery/doors/unpowered.dm
@@ -2,6 +2,8 @@
autoclose = 0
var/locked = 0
+ required_dexterity = MOB_DEXTERITY_NONE
+
/obj/machinery/door/unpowered/Bumped(atom/AM)
if(src.locked)
return
diff --git a/code/game/machinery/floor_light.dm b/code/game/machinery/floor_light.dm
index f18b3cb021..fe6929fba6 100644
--- a/code/game/machinery/floor_light.dm
+++ b/code/game/machinery/floor_light.dm
@@ -13,6 +13,8 @@ var/global/list/floor_light_cache = list()
power_channel = LIGHT
matter = list(DEFAULT_WALL_MATERIAL = 2500, "glass" = 2750)
+ required_dexterity = MOB_DEXTERITY_SIMPLE_MACHINES
+
var/on
var/damaged
var/default_light_range = 4
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 043a877eaa..268692ce8d 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -114,6 +114,9 @@ Class Procs:
var/speed_process = FALSE //If false, SSmachines. If true, SSfastprocess.
+ required_dexterity = MOB_DEXTERITY_TOUCHSCREENS
+
+
/obj/machinery/Initialize(var/ml, d=0)
. = ..()
if(d)
@@ -233,14 +236,14 @@ Class Procs:
else
return attack_hand(user)
+
/obj/machinery/attack_hand(mob/user as mob)
if(inoperable(MAINT))
return 1
if(user.lying || user.stat)
return 1
- if(!(istype(user, /mob/living/carbon/human) || istype(user, /mob/living/silicon)))
- to_chat(user, "You don't have the dexterity to do this!")
+ if (!user.check_dexterity(required_dexterity, src))
return 1
if(ishuman(user))
var/mob/living/carbon/human/H = user
diff --git a/code/game/machinery/wishgranter.dm b/code/game/machinery/wishgranter.dm
index 81c720bacd..37ffc694dd 100644
--- a/code/game/machinery/wishgranter.dm
+++ b/code/game/machinery/wishgranter.dm
@@ -6,6 +6,7 @@
use_power = USE_POWER_OFF
anchored = 1
density = 1
+ required_dexterity = MOB_DEXTERITY_SIMPLE_MACHINES
var/charges = 1
var/insisting = 0
@@ -66,4 +67,4 @@
show_objectives(user.mind)
to_chat(user, "You have a very bad feeling about this.")
- return
\ No newline at end of file
+ return
diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm
index d1a7dfc1cd..4dab1c99a7 100644
--- a/code/game/objects/items/weapons/storage/storage.dm
+++ b/code/game/objects/items/weapons/storage/storage.dm
@@ -419,7 +419,7 @@
return 1
//This proc is called when you want to place an item into the storage item.
-/obj/item/storage/attackby(obj/item/W as obj, mob/user as mob)
+/obj/item/storage/attackby(obj/item/W as obj, mob/user as mob, silent)
..()
if(isrobot(user))
@@ -437,7 +437,8 @@
remove_from_storage(L, T)
qdel(L)
if(amt_inserted)
- to_chat(user, "You inserted [amt_inserted] light\s into \the [LP.name]. You have [LP.uses] light\s remaining.")
+ if (!silent)
+ to_chat(user, "You inserted [amt_inserted] light\s into \the [LP.name]. You have [LP.uses] light\s remaining.")
return
if(!can_be_inserted(W))
@@ -447,17 +448,19 @@
var/obj/item/tray/T = W
if(T.calc_carry() > 0)
if(prob(85))
- to_chat(user, "The tray won't fit in [src].")
+ if (!silent)
+ to_chat(user, "The tray won't fit in [src].")
return
else
W.forceMove(get_turf(user))
if ((user.client && user.s_active != src))
user.client.screen -= W
W.dropped(user)
- to_chat(user, "God damn it!")
+ if (!silent)
+ to_chat(user, "God damn it!")
W.add_fingerprint(user)
- return handle_item_insertion(W)
+ return handle_item_insertion(W, silent)
/obj/item/storage/dropped(mob/user as mob)
return
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 9442f762e5..26ecba1c6f 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -20,6 +20,10 @@
var/show_examine = TRUE // Does this pop up on a mob when the mob is examined?
+ /// One of MOB_DEXTERITY_* - the dexterity level required to use this object, if any.
+ var/required_dexterity = MOB_DEXTERITY_NONE
+
+
/obj/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
diff --git a/code/game/objects/random/guns_and_ammo.dm b/code/game/objects/random/guns_and_ammo.dm
index 6ef99fc8a0..df8d4b3460 100644
--- a/code/game/objects/random/guns_and_ammo.dm
+++ b/code/game/objects/random/guns_and_ammo.dm
@@ -26,11 +26,14 @@
prob(2);/obj/item/gun/energy/ionrifle,
prob(2);/obj/item/gun/energy/ionrifle/pistol,
prob(3);/obj/item/gun/energy/toxgun,
- prob(3);/obj/item/gun/energy/taser,
+ prob(1);/obj/item/gun/energy/taser,
+ prob(1);/obj/item/gun/energy/taser/disabler,
prob(2);/obj/item/gun/energy/crossbow/largecrossbow,
prob(3);/obj/item/gun/energy/stunrevolver,
prob(2);/obj/item/gun/energy/stunrevolver/vintage,
- prob(3);/obj/item/gun/energy/gun/compact)
+ prob(3);/obj/item/gun/energy/gun/compact,
+ prob(2);/obj/item/gun/energy/gun/pocket
+ )
/obj/random/energy/highend
name = "Random Energy Weapon"
@@ -48,7 +51,10 @@
prob(3);/obj/item/gun/energy/xray,
prob(1);/obj/item/gun/energy/sniperrifle,
prob(2);/obj/item/gun/energy/crossbow/largecrossbow,
- prob(3);/obj/item/gun/energy/gun/compact)
+ prob(3);/obj/item/gun/energy/gun/compact,
+ prob(2);/obj/item/gun/energy/gun/pocket,
+ prob(1);/obj/item/gun/energy/monorifle,
+ prob(1);/obj/item/gun/energy/lasershotgun)
/obj/random/energy/sec
name = "Random Security Energy Weapon"
@@ -72,6 +78,8 @@
prob(2);/obj/item/gun/projectile/automatic/sts35,
prob(2);/obj/item/gun/projectile/automatic/z8,
prob(2);/obj/item/gun/projectile/automatic/combatsmg,
+ prob(2);/obj/item/gun/projectile/automatic/pearlshield,
+ prob(2);/obj/item/gun/projectile/automatic/p90,
prob(4);/obj/item/gun/projectile/colt,
prob(2);/obj/item/gun/projectile/deagle,
prob(1);/obj/item/gun/projectile/deagle/camo,
@@ -84,7 +92,8 @@
prob(3);/obj/item/gun/projectile/sec/wood,
prob(4);/obj/item/gun/projectile/p92x,
prob(3);/obj/item/gun/projectile/p92x/brown,
- prob(4);/obj/item/gun/projectile/pistol,
+ prob(2);/obj/item/gun/projectile/pistol,
+ prob(2);/obj/item/gun/projectile/pistol/alt,
prob(5);/obj/item/gun/projectile/pirate,
prob(2);/obj/item/gun/projectile/revolver,
prob(4);/obj/item/gun/projectile/revolver/deckard,
@@ -92,12 +101,16 @@
prob(2);/obj/item/gun/projectile/revolver/judge,
prob(3);/obj/item/gun/projectile/revolver/lemat,
prob(2);/obj/item/gun/projectile/revolver/mateba,
+ prob(2);/obj/item/gun/projectile/revolver/webley,
+ prob(2);/obj/item/gun/projectile/revolver/webley/large,
prob(4);/obj/item/gun/projectile/shotgun/doublebarrel,
prob(3);/obj/item/gun/projectile/shotgun/doublebarrel/sawn,
prob(3);/obj/item/gun/projectile/shotgun/pump,
prob(2);/obj/item/gun/projectile/shotgun/pump/combat,
prob(4);/obj/item/gun/projectile/shotgun/pump/rifle,
+ prob(1);/obj/item/gun/projectile/shotgun/pump/rifle/antique,
prob(3);/obj/item/gun/projectile/shotgun/pump/rifle/lever,
+ prob(3);/obj/item/gun/projectile/shotgun/pump/rifle/lever/brushgun,
prob(2);/obj/item/gun/projectile/shotgun/semi,
prob(2);/obj/item/gun/projectile/silenced)
@@ -123,10 +136,19 @@
prob(1);/obj/item/gun/projectile/shotgun/pump/combat,
prob(1);/obj/item/gun/projectile/shotgun/semi)
+/obj/random/sidearm
+ name = "Random Sidearm"
+ desc = "This is a random one-handed sidearm of any type."
+ icon_state = "gun"
+
+/obj/random/sidearm/item_to_spawn()
+ return pick(prob(5);/obj/random/handgun,
+ prob(5);/obj/random/revolver,
+ prob(5);/obj/random/energy_pistol)
+
/obj/random/handgun
- name = "Random Handgun"
- desc = "This is a random sidearm."
- icon = 'icons/obj/gun.dmi'
+ name = "Random Pistol"
+ desc = "This is a random semi-auto sidearm."
icon_state = "gun"
/obj/random/handgun/item_to_spawn()
@@ -136,10 +158,38 @@
prob(3);/obj/item/gun/projectile/p92x/brown,
prob(3);/obj/item/gun/projectile/colt,
prob(2);/obj/item/gun/projectile/luger,
- prob(2);/obj/item/gun/energy/gun,
prob(2);/obj/item/gun/projectile/pistol,
+ prob(2);/obj/item/gun/projectile/pistol/alt,
+ prob(2);/obj/item/gun/projectile/luger/brown,
+ prob(1);/obj/item/gun/projectile/compact_45)
+
+/obj/random/energy_pistol
+ name = "Random Energy Pistol"
+ desc = "This is a random energy sidearm."
+ icon_state = "gun_energy"
+/obj/random/energy_pistol/item_to_spawn()
+ return pick(prob(2);/obj/item/gun/energy/gun,
prob(1);/obj/item/gun/energy/retro,
- prob(1);/obj/item/gun/projectile/luger/brown)
+ prob(1);/obj/item/gun/energy/gun/compact,
+ prob(1);/obj/item/gun/energy/gun/pocket)
+
+/obj/random/revolver
+ name = "Random Revolver"
+ desc = "This is a random revolver."
+ icon_state = "gun"
+
+/obj/random/revolver/item_to_spawn()
+ return pick(prob(4);/obj/item/gun/projectile/revolver,
+ prob(4);/obj/item/gun/projectile/revolver/mateba,
+ prob(3);/obj/item/gun/projectile/revolver/detective,
+ prob(3);/obj/item/gun/projectile/revolver/detective45,
+ prob(3);/obj/item/gun/projectile/revolver/deckard,
+ prob(2);/obj/item/gun/projectile/revolver/judge,
+ prob(2);/obj/item/gun/projectile/revolver/lemat,
+ prob(2);/obj/item/gun/projectile/revolver/webley,
+ prob(1);/obj/item/gun/projectile/revolver/webley/auto,
+ prob(1);/obj/item/gun/projectile/revolver/webley/magnetic,
+ prob(1);/obj/item/gun/projectile/revolver/webley/large)
/obj/random/handgun/sec
name = "Random Security Handgun"
@@ -239,7 +289,6 @@
/obj/random/projectile/random
name = "Random Projectile Weapon"
desc = "This is a random projectile weapon."
- icon = 'icons/obj/gun.dmi'
icon_state = "gun_2"
/obj/random/projectile/random/item_to_spawn()
@@ -283,6 +332,11 @@
/obj/item/gun/projectile/automatic/combatsmg,
/obj/item/ammo_magazine/m9mmt,
/obj/item/ammo_magazine/m9mmt
+ ),
+ prob(2);list(
+ /obj/item/gun/projectile/automatic/pearlshield,
+ /obj/item/ammo_magazine/m9mmt,
+ /obj/item/ammo_magazine/m9mmt
)
)
@@ -291,8 +345,6 @@
desc = "Loot for PoIs."
icon_state = "gun_rifle"
-//Concerns about the bullpup, but currently seems to be only a slightly stronger z8. But we shall see.
-
/obj/random/multiple/gun/projectile/rifle/item_to_spawn()
return pick(
prob(2);list(
@@ -365,9 +417,9 @@
/obj/item/ammo_magazine/m44
),
prob(1);list(
- /obj/item/gun/projectile/deagle/camo,
- /obj/item/ammo_magazine/m44,
- /obj/item/ammo_magazine/m44
+ /obj/item/gun/projectile/compact_45,
+ /obj/item/ammo_magazine/m45/compact,
+ /obj/item/ammo_magazine/m45/compact
),
prob(1);list(
/obj/item/gun/projectile/deagle/gold,
@@ -465,6 +517,11 @@
/obj/item/gun/projectile/revolver/webley/auto,
/obj/item/ammo_magazine/s44,
/obj/item/ammo_magazine/s44
+ ),
+ prob(1);list(
+ /obj/item/gun/projectile/revolver/webley/magnetic,
+ /obj/item/ammo_magazine/s44,
+ /obj/item/ammo_magazine/s44
)
)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
index 4857fa184f..c96a536531 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
@@ -41,7 +41,7 @@
/obj/item/radio/headset/headset_cargo/alt,
/obj/item/clothing/gloves/black,
/obj/item/clothing/gloves/fingerless,
- /obj/item/clothing/suit/fire/firefighter,
+ /obj/item/clothing/suit/fire,
/obj/item/tank/emergency/oxygen,
/obj/item/clothing/mask/gas,
/obj/item/clothing/glasses/meson,
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
index 86023fb959..1d4869ad97 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
@@ -20,6 +20,8 @@
/obj/item/radio/headset/heads/ce/alt,
/obj/item/storage/toolbox/mechanical,
/obj/item/clothing/suit/storage/hazardvest,
+ /obj/item/clothing/head/hardhat/firefighter/chief,
+ /obj/item/clothing/suit/fire/atmos,
/obj/item/clothing/mask/gas,
/obj/item/multitool,
/obj/item/storage/belt/utility/chief/full,
@@ -100,8 +102,8 @@
starts_with = list(
/obj/item/clothing/accessory/storage/brown_vest,
- /obj/item/clothing/suit/fire/firefighter,
- /obj/item/clothing/head/hardhat/red,
+ /obj/item/clothing/suit/fire/atmos,
+ /obj/item/clothing/head/hardhat/firefighter,
/obj/item/flashlight,
/obj/item/extinguisher,
/obj/item/clamp,
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 a582f343ee..01eed45b50 100644
--- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm
@@ -62,29 +62,29 @@
closet_appearance = /decl/closet_appearance/oxygen/fire
starts_with = list(
- /obj/item/clothing/suit/fire/firefighter,
+ /obj/item/clothing/suit/fire,
/obj/item/clothing/mask/gas,
/obj/item/tank/oxygen/red,
/obj/item/extinguisher,
- /obj/item/clothing/head/hardhat/red)
+ /obj/item/clothing/head/hardhat/firefighter)
/obj/structure/closet/firecloset/full
starts_with = list(
- /obj/item/clothing/suit/fire/firefighter,
+ /obj/item/clothing/suit/fire,
/obj/item/clothing/mask/gas,
/obj/item/flashlight,
/obj/item/tank/oxygen/red,
/obj/item/extinguisher,
- /obj/item/clothing/head/hardhat/red)
+ /obj/item/clothing/head/hardhat/firefighter)
/obj/structure/closet/firecloset/full/double
starts_with = list(
- /obj/item/clothing/suit/fire/firefighter = 2,
+ /obj/item/clothing/suit/fire = 2,
/obj/item/clothing/mask/gas = 2,
/obj/item/flashlight = 2,
/obj/item/tank/oxygen/red = 2,
/obj/item/extinguisher = 2,
- /obj/item/clothing/head/hardhat/red = 2)
+ /obj/item/clothing/head/hardhat/firefighter = 2)
/*
* Tool Closet
@@ -189,12 +189,12 @@
door_anim_time = 0 // Unsupported
starts_with = list(
- /obj/item/clothing/suit/fire/firefighter,
+ /obj/item/clothing/suit/fire,
/obj/item/clothing/mask/gas,
/obj/item/flashlight,
/obj/item/tank/oxygen/red,
/obj/item/extinguisher,
- /obj/item/clothing/head/hardhat/red)
+ /obj/item/clothing/head/hardhat/firefighter)
/*
* First Aid
diff --git a/code/game/objects/structures/crates_lockers/closets/walllocker.dm b/code/game/objects/structures/crates_lockers/closets/walllocker.dm
index 5e02716e92..698f3ee954 100644
--- a/code/game/objects/structures/crates_lockers/closets/walllocker.dm
+++ b/code/game/objects/structures/crates_lockers/closets/walllocker.dm
@@ -140,12 +140,12 @@
density = 0
starts_with = list(
- /obj/item/clothing/suit/fire/firefighter,
+ /obj/item/clothing/suit/fire,
/obj/item/clothing/mask/gas,
/obj/item/flashlight,
/obj/item/tank/oxygen/red,
/obj/item/extinguisher,
- /obj/item/clothing/head/hardhat/red)
+ /obj/item/clothing/head/hardhat/firefighter)
/obj/structure/closet/walllocker_double/hydrant/north
pixel_y = 32
@@ -161,4 +161,4 @@
/obj/structure/closet/walllocker_double/hydrant/east
pixel_x = 32
- dir = EAST
\ No newline at end of file
+ dir = EAST
diff --git a/code/game/shuttle_engines.dm b/code/game/shuttle_engines.dm
index 579b6f6aea..193652d307 100644
--- a/code/game/shuttle_engines.dm
+++ b/code/game/shuttle_engines.dm
@@ -78,3 +78,18 @@
/obj/structure/shuttle/engine/router
name = "router"
icon_state = "router"
+
+/obj/structure/shuttle/falsewall_no_join //For faking the appearance of joinable walls when joinable walls won't behave correctly on specific shuttle tiles.
+ name = "shuttle wall"
+ icon = 'icons/turf/shuttle_white.dmi'
+ icon_state = "light" //Should be switched out as needed
+ layer = TURF_LAYER
+ density = 1
+ anchored = 1
+ can_atmos_pass = ATMOS_PASS_NO
+
+/obj/structure/shuttle/falsewall_no_join/window
+ name = "shuttle window"
+ icon = 'icons/obj/podwindows.dmi'
+ icon_state = "0_0"
+ opacity = 0
diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories.dm b/code/modules/client/preference_setup/loadout/loadout_accessories.dm
index 7e1951e954..97f880063c 100644
--- a/code/modules/client/preference_setup/loadout/loadout_accessories.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_accessories.dm
@@ -166,6 +166,7 @@
/datum/gear/accessory/webbing_simple
display_name = "webbing, simple"
path = /obj/item/clothing/accessory/storage/webbing
+ cost = 2
/datum/gear/accessory/drop_pouches
display_name = "drop pouches selection (Engineering, Security, Medical)"
diff --git a/code/modules/client/preference_setup/loadout/loadout_suit.dm b/code/modules/client/preference_setup/loadout/loadout_suit.dm
index 50028a6c8b..d5a63ce717 100644
--- a/code/modules/client/preference_setup/loadout/loadout_suit.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_suit.dm
@@ -34,6 +34,7 @@
/datum/gear/suit/bomber
display_name = "jacket, bomber selection"
+ description = "A selection of jackets styled on early aviation gear."
path = /obj/item/clothing/suit/storage/toggle/bomber
cost = 2
@@ -47,6 +48,7 @@
/datum/gear/suit/leather_jacket
display_name = "jacket, leather selection"
+ description = "A selection of leather jackets in various styles."
path = /obj/item/clothing/suit/storage/toggle/leather_jacket
/datum/gear/suit/leather_jacket/New()
@@ -61,6 +63,7 @@
/datum/gear/suit/leather_vest
display_name = "jacket, leather vest selection"
+ description = "A selection of sleeveless leather jackets in various styles."
path = /obj/item/clothing/suit/storage/toggle/leather_jacket/sleeveless
/datum/gear/suit/leather_vest/New()
@@ -74,6 +77,7 @@
/datum/gear/suit/mil
display_name = "military jacket selection"
+ description = "A selection of jackets resembling vintage military gear."
path = /obj/item/clothing/suit/storage/miljacket
/datum/gear/suit/mil/New()
@@ -90,6 +94,7 @@
/datum/gear/suit/trenchcoat
display_name = "trenchcoat selection"
+ description = "A selection of long raincoats."
path = /obj/item/clothing/suit/storage/trench
/datum/gear/suit/trenchcoat/New()
@@ -121,6 +126,7 @@
/datum/gear/suit/hoodie
display_name = "hoodie selection"
+ description = "A selection of hooded sweatshirts."
path = /obj/item/clothing/suit/storage/toggle/hoodie
cost = 2
@@ -134,6 +140,7 @@
/datum/gear/suit/labcoat
display_name = "labcoat, colored selection"
+ description = "A selection of labcoats in standard, and non-standard colours."
path = /obj/item/clothing/suit/storage/toggle/labcoat
cost = 2
@@ -177,6 +184,7 @@
/datum/gear/suit/poncho
display_name = "poncho selection"
+ description = "A selection of ponchos in basic and departmental colours."
path = /obj/item/clothing/accessory/poncho
/datum/gear/suit/poncho/New()
@@ -187,11 +195,12 @@
ponchos[initial(poncho.name)] = poncho
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(ponchos))
-/datum/gear/suit/cloak
+/datum/gear/suit/cloak_department
display_name = "cloak, departmental selection"
+ description = "A selection of cloaks in departmental colours."
path = /obj/item/clothing/accessory/poncho/roles/cloak/cargo
-/datum/gear/suit/cloak/New()
+/datum/gear/suit/cloak_department/New()
..()
var/list/cloaks = list()
for(var/cloak_style in (typesof(/obj/item/clothing/accessory/poncho/roles/cloak)))
@@ -203,7 +212,7 @@
display_name = "cloak (colorable)"
path = /obj/item/clothing/accessory/poncho/roles/cloak/custom
-/datum/gear/suit/roles/poncho/cloak/custom/New()
+/datum/gear/suit/cloak_custom/New()
..()
gear_tweaks += gear_tweak_free_color_choice
@@ -212,7 +221,8 @@
path = /obj/item/clothing/suit/unathi/robe
/datum/gear/suit/suit_jackets
- display_name = "suit jacket selection"
+ display_name = "jacket, suit selection"
+ description = "A selection of stylish suit jackets."
path = /obj/item/clothing/suit/storage/toggle/internalaffairs
/datum/gear/suit/suit_jackets/New()
@@ -229,6 +239,7 @@
/datum/gear/suit/forensics
display_name = "jacket, forensics selection (Detective)"
+ description = "A selection of windbreakers in security colours."
path = /obj/item/clothing/suit/storage/forensics/red/long
allowed_roles = list("Detective")
@@ -243,6 +254,7 @@
/datum/gear/suit/wintercoat
display_name = "winter coat selection"
+ description = "A selection of heavy winter coats to keep you toasty in extreme weather."
path = /obj/item/clothing/suit/storage/hooded/wintercoat
cost = 2
@@ -256,6 +268,7 @@
/datum/gear/suit/varsity
display_name = "jacket, varsity selection"
+ description = "A selection of two-tone cotton jackets."
path = /obj/item/clothing/suit/varsity
/datum/gear/suit/varsity/New()
@@ -268,6 +281,7 @@
/datum/gear/suit/track
display_name = "jacket, track selection"
+ description = "A selection of lightweight sports jackets."
path = /obj/item/clothing/suit/storage/toggle/track
/datum/gear/suit/track/New()
@@ -280,6 +294,7 @@
/datum/gear/suit/flannel
display_name = "flannel selection"
+ description = "A selection of comfortable plaid shirts."
path = /obj/item/clothing/suit/storage/flannel
/datum/gear/suit/flannel/New()
@@ -292,6 +307,7 @@
/datum/gear/suit/denim_jacket
display_name = "jacket, denim selection"
+ description = "A selection of denim jackets in a variety of styles."
path = /obj/item/clothing/suit/storage/toggle/denim_jacket
/datum/gear/suit/denim_jacket/New()
@@ -312,6 +328,7 @@
/datum/gear/suit/dep_jacket
display_name = "jacket, departmental selection"
+ description = "A selection of light jackets in departmental colours."
path = /obj/item/clothing/suit/storage/toggle/sec_dep_jacket
/datum/gear/suit/dep_jacket/New()
@@ -326,6 +343,7 @@
/datum/gear/suit/light_jacket
display_name = "jacket, light selection"
+ description = "A selection of lightweight outdoor jackets."
path = /obj/item/clothing/suit/storage/toggle/light_jacket
/datum/gear/suit/light_jacket/New()
@@ -350,6 +368,7 @@
/datum/gear/suit/insulated
display_name = "jacket, insulated selection"
+ description = "A selection of jackets made to keep you nice and toasty on cold winter days. Or at least alive."
path = /obj/item/clothing/suit/storage/insulated
cost = 2
diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform.dm b/code/modules/client/preference_setup/loadout/loadout_uniform.dm
index 8e2087bd19..7c6f11ef0c 100644
--- a/code/modules/client/preference_setup/loadout/loadout_uniform.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_uniform.dm
@@ -12,6 +12,7 @@
/datum/gear/uniform/cheongsam
description = "Various color variations of an old earth dress style. They are pretty close fitting around the waist."
display_name = "cheongsam selection"
+ path = /obj/item/clothing/under/cheongsam
/datum/gear/uniform/cheongsam/New()
..()
@@ -24,6 +25,7 @@
/datum/gear/uniform/croptop
description = "Light shirts which shows the midsection of the wearer."
display_name = "croptop selection"
+ path = /obj/item/clothing/under/croptop
/datum/gear/uniform/croptop/New()
..()
@@ -42,15 +44,20 @@
path = /obj/item/clothing/under/kilt
/datum/gear/uniform/cuttop
- display_name = "cut top, grey"
+ display_name = "cut top selection"
+ description = "Loose, low-cut shirts with matching shorts."
path = /obj/item/clothing/under/cuttop
-/datum/gear/uniform/cuttop/red
- display_name = "cut top, red"
- path = /obj/item/clothing/under/cuttop/red
+/datum/gear/uniform/cuttop/New()
+ ..()
+ var/cuttoptype = list()
+ cuttoptype["cut top, grey"] = /obj/item/clothing/under/cuttop
+ cuttoptype["cut top, red"] = /obj/item/clothing/under/cuttop/red
+ gear_tweaks += new/datum/gear_tweak/path(cuttoptype)
/datum/gear/uniform/jumpsuit
display_name = "jumpclothes selection"
+ description = "Basic solid-colour durable jumpsuits."
path = /obj/item/clothing/under/color/grey
/datum/gear/uniform/jumpsuit/New()
@@ -63,6 +70,7 @@
/datum/gear/uniform/colorable_jumpsuit
display_name = "jumpsuit, colorable"
+ description = "A durable jumpsuit, in any colour."
path = /obj/item/clothing/under/colorable
/datum/gear/uniform/colorable_jumpsuit/New()
@@ -87,6 +95,7 @@
/datum/gear/uniform/skirt
display_name = "skirt, selection"
+ description = "Skirts to cover your lower body, in various styles."
path = /obj/item/clothing/under/skirt
/datum/gear/uniform/skirt/New()
@@ -99,6 +108,7 @@
/datum/gear/uniform/pants
display_name = "pants, selection"
+ description = "A variety of pants, jeans, chaps, and other long-legged lower body apparel."
path = /obj/item/clothing/under/pants/white
/datum/gear/uniform/pants/New()
@@ -111,6 +121,7 @@
/datum/gear/uniform/shorts
display_name = "shorts, selection"
+ description = "A variety of shorts, jorts, and other short-legged lower body apparel."
path = /obj/item/clothing/under/shorts/jeans
/datum/gear/uniform/shorts/New()
@@ -144,6 +155,7 @@
/datum/gear/uniform/job_turtle
display_name = "turtleneck, departmental selection"
+ description = "High-necked sweaters in a variety of departmental colours."
path = /obj/item/clothing/under/rank/scientist/turtleneck
/datum/gear/uniform/job_turtle/New()
@@ -177,6 +189,7 @@
/datum/gear/uniform/suit_lawyer
display_name = "suit, one-piece selection"
+ description = "A selection of suits without removable jackets."
path = /obj/item/clothing/under/lawyer
/datum/gear/uniform/suit_lawyer/New()
@@ -189,6 +202,7 @@
/datum/gear/uniform/suit_jacket
display_name = "suit, modular selection"
+ description = "A selection of suits with removable jackets, waistcoats, etc."
path = /obj/item/clothing/under/suit_jacket
/datum/gear/uniform/suit_jacket/New()
@@ -221,6 +235,7 @@
/datum/gear/uniform/scrub
display_name = "scrubs selection"
+ description = "Medical gear made of a special fiber that provides minor protection against biohazards."
path = /obj/item/clothing/under/rank/medical/scrubs
/datum/gear/uniform/scrub/New()
@@ -262,6 +277,7 @@
/datum/gear/uniform/uniform_security
display_name = "uniform, security selection"
+ description = "A selection of standard uniforms for security officers and detectives."
path = /obj/item/clothing/under/rank/security/corp
allowed_roles = list("Security Officer","Head of Security","Warden", "Detective")
@@ -277,6 +293,7 @@
/datum/gear/uniform/uniform_warden
display_name = "uniform, warden selection"
+ description = "A selection of standard uniforms for security wardens."
path = /obj/item/clothing/under/rank/warden/corp
allowed_roles = list("Head of Security","Warden")
@@ -290,6 +307,7 @@
/datum/gear/uniform/uniform_hos
display_name = "uniform, head of security selection"
+ description = "A selection of standard uniforms for heads of security."
path = /obj/item/clothing/under/rank/security/corp
allowed_roles = list("Head of Security")
@@ -303,6 +321,7 @@
/datum/gear/uniform/uniform_hop
display_name = "uniform, head of personnel selection"
+ description = "A selection of formal uniforms for the Head of Personnel."
path = /obj/item/clothing/under/rank/security/corp
allowed_roles = list("Head of Personnel")
@@ -355,6 +374,7 @@
/datum/gear/uniform/dresses/maid
display_name = "uniform, maid selection"
+ description = "A variety of maid uniform styles."
path = /obj/item/clothing/under/dress/maid
/datum/gear/uniform/dresses/maid/New()
@@ -367,6 +387,7 @@
/datum/gear/uniform/utility
display_name = "jumpsuit, utility selection"
+ description = "A selection of especially hard-wearing jumpclothes for heavy duties."
path = /obj/item/clothing/under/utility
/datum/gear/uniform/utility/New()
@@ -392,12 +413,13 @@
/datum/gear/uniform/brandsuit
display_name = "jumpsuit/uniform, corporate selection"
+ description = "Liveried durable jumpclothes and other Trans-Stellar corporate uniforms."
path = /obj/item/clothing/under/corp/aether
/datum/gear/uniform/brandsuit/New()
..()
var/list/brandsuits = list()
- for(var/brandsuit in typesof(/obj/item/clothing/under/corp, /obj/item/clothing/under/hedbergtech))
+ for(var/brandsuit in typesof(/obj/item/clothing/under/corp, /obj/item/clothing/under/hedbergtech) - /obj/item/clothing/under/corp)
var/obj/item/clothing/under/corp/brandsuit_type = brandsuit
brandsuits[initial(brandsuit_type.name)] = brandsuit_type
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(brandsuits))
@@ -462,11 +484,11 @@
path = /obj/item/clothing/under/dress/sari/green
/datum/gear/uniform/wrappedcoat
- display_name = "modern wrapped coat"
+ display_name = "outfit, modern wrapped coat"
path = /obj/item/clothing/under/moderncoat
/datum/gear/uniform/ascetic
- display_name = "plain ascetic garb"
+ display_name = "outfit, plain ascetic garb"
path = /obj/item/clothing/under/ascetic
/datum/gear/uniform/pleated
@@ -518,7 +540,7 @@
path =/obj/item/clothing/under/dress/goldwrap
/datum/gear/uniform/pinktutu
- display_name = "pink tutu"
+ display_name = "skirt, pink tutu"
path = /obj/item/clothing/under/dress/pinktutu
/datum/gear/uniform/festivedress
@@ -562,7 +584,7 @@
path = /obj/item/clothing/under/cyberpunkharness
/datum/gear/uniform/cyberpunkpants
- display_name = "cyberpunk split-side ensemble"
+ display_name = "outfit, cyberpunk split-side ensemble"
path = /obj/item/clothing/under/cyberpunkpants
/datum/gear/uniform/whitegown
diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm
index c78749f6f8..66a32925c4 100644
--- a/code/modules/clothing/head/hardhat.dm
+++ b/code/modules/clothing/head/hardhat.dm
@@ -37,3 +37,39 @@
/obj/item/clothing/head/hardhat/dblue
name = "blue hard hat"
icon_state = "hardhat0_dblue"
+
+/obj/item/clothing/head/hardhat/red/firefighter
+ name = "atmospheric firefighter helmet"
+ desc = "An atmospheric firefighter's helmet, able to keep the user protected from heat and fire in normal atmospheric conditions."
+ max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE + 15000
+ min_pressure_protection = 0.5 * ONE_ATMOSPHERE
+ max_pressure_protection = 20 * ONE_ATMOSPHERE
+ icon_state = "atmos_fire"
+ sprite_sheets = list(
+ SPECIES_TAJARAN = 'icons/mob/species/tajaran/helmet.dmi',
+ SPECIES_UNATHI = 'icons/mob/species/unathi/helmet.dmi'
+ )
+
+/obj/item/clothing/head/hardhat/firefighter
+ name = "firefighter helmet"
+ desc = "A complete, face covering helmet specially designed for firefighting. It is airtight and has a port for internals."
+ icon_state = "helmet_firefighter"
+ item_flags = THICKMATERIAL | AIRTIGHT
+ permeability_coefficient = 0
+ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|BLOCKHAIR
+ max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE + 15000
+ min_pressure_protection = 0.5 * ONE_ATMOSPHERE
+ max_pressure_protection = 20 * ONE_ATMOSPHERE
+ body_parts_covered = HEAD|FACE|EYES
+ cold_protection = HEAD
+ min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE
+ flash_protection = FLASH_PROTECTION_MODERATE
+ sprite_sheets = list(
+ SPECIES_TAJARAN = 'icons/mob/species/tajaran/helmet.dmi',
+ SPECIES_UNATHI = 'icons/mob/species/unathi/helmet.dmi'
+ )
+
+/obj/item/clothing/head/hardhat/firefighter/chief
+ name = "chief firefighter helmet"
+ desc = "A complete, face covering helmet specially designed for firefighting. This one is in the colors of the Chief Engineer. It is airtight and has a port for internals."
+ icon_state = "helmet_firefighter_ce"
diff --git a/code/modules/clothing/spacesuits/void/station.dm b/code/modules/clothing/spacesuits/void/station.dm
index 6068dc2f92..4ec8028112 100644
--- a/code/modules/clothing/spacesuits/void/station.dm
+++ b/code/modules/clothing/spacesuits/void/station.dm
@@ -329,7 +329,7 @@
icon_state = "rig0-atmos"
item_state_slots = list(slot_r_hand_str = "atmos_helm", slot_l_hand_str = "atmos_helm")
armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 50)
- max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
+ max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE + 10000
light_overlay = "helmet_light_dual"
min_pressure_protection = 0 * ONE_ATMOSPHERE
max_pressure_protection = 20* ONE_ATMOSPHERE
@@ -340,7 +340,7 @@
icon_state = "rig-atmos"
item_state_slots = list(slot_r_hand_str = "atmos_voidsuit", slot_l_hand_str = "atmos_voidsuit")
armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 50)
- max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE
+ max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE + 10000
min_pressure_protection = 0 * ONE_ATMOSPHERE
max_pressure_protection = 20* ONE_ATMOSPHERE
breach_threshold = 16 //Extra Thicc
@@ -442,4 +442,4 @@
/obj/item/clothing/suit/space/void/pilot/alt
desc = "An atmos resistant voidsuit for space."
icon_state = "rig-pilot2"
- item_state = "rig-pilot2"
\ No newline at end of file
+ item_state = "rig-pilot2"
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index b9806e9aee..e23a11c42c 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -313,7 +313,7 @@
/obj/item/clothing/suit/storage/greyjacket
name = "grey jacket"
- desc = "A fancy twead grey jacket."
+ desc = "A fancy tweed grey jacket."
icon_state = "gentlecoat"
item_state_slots = list(slot_r_hand_str = "leather_jacket", slot_l_hand_str = "leather_jacket")
flags_inv = HIDEHOLSTER
@@ -776,7 +776,7 @@
//Flannels
/obj/item/clothing/suit/storage/flannel
- name = "Flannel shirt"
+ name = "grey flannel shirt"
desc = "A comfy, grey flannel shirt. Unleash your inner hipster."
icon_state = "flannel"
item_state_slots = list(slot_r_hand_str = "black_labcoat", slot_l_hand_str = "black_labcoat")
@@ -848,16 +848,19 @@
update_clothing_icon()
/obj/item/clothing/suit/storage/flannel/red
+ name = "red flannel shirt"
desc = "A comfy, red flannel shirt. Unleash your inner hipster."
icon_state = "flannel_red"
item_state_slots = list(slot_r_hand_str = "red_labcoat", slot_l_hand_str = "red_labcoat")
/obj/item/clothing/suit/storage/flannel/aqua
+ name = "aqua flannel shirt"
desc = "A comfy, aqua flannel shirt. Unleash your inner hipster."
icon_state = "flannel_aqua"
item_state_slots = list(slot_r_hand_str = "blue_labcoat", slot_l_hand_str = "blue_labcoat")
/obj/item/clothing/suit/storage/flannel/brown
+ name = "brown flannel shirt"
desc = "A comfy, brown flannel shirt. Unleash your inner hipster."
icon_state = "flannel_brown"
item_state_slots = list(slot_r_hand_str = "johnny", slot_l_hand_str = "johnny")
diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm
index a53a5cb036..eda3702ea2 100644
--- a/code/modules/clothing/suits/utility.dm
+++ b/code/modules/clothing/suits/utility.dm
@@ -12,13 +12,14 @@
/obj/item/clothing/suit/fire
name = "firesuit"
desc = "A suit that protects against fire and heat."
- icon_state = "fire"
+ icon_state = "firesuit"
w_class = ITEMSIZE_LARGE//bulky item
gas_transfer_coefficient = 0.90
permeability_coefficient = 0.50
+ siemens_coefficient = 0.5
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
allowed = list(/obj/item/flashlight,/obj/item/tank/emergency/oxygen,/obj/item/extinguisher)
- slowdown = 1.0
+ slowdown = 0.8 //Slightly better than a voidsuit
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER
item_flags = 0
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
@@ -27,17 +28,13 @@
min_pressure_protection = 0.2 * ONE_ATMOSPHERE
max_pressure_protection = 20 * ONE_ATMOSPHERE
-
-/obj/item/clothing/suit/fire/firefighter
- icon_state = "firesuit"
-
-/obj/item/clothing/suit/fire/heavy //Is this even used?? -S2-
- name = "firesuit"
- desc = "A suit that protects against extreme fire and heat."
- //icon_state = "thermal"
- item_state_slots = list(slot_r_hand_str = "black_suit", slot_l_hand_str = "black_suit")
- w_class = ITEMSIZE_LARGE//bulky item
- slowdown = 1.5
+/obj/item/clothing/suit/fire/atmos
+ name = "atmospheric technician firesuit"
+ desc = "A suit that protects against fire and heat, this one is designed for atmospheric technicians."
+ siemens_coefficient = 0.35
+ max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE + 15000
+ icon_state = "atmos_firesuit"
+ item_state = "atmos_firesuit"
/*
* Bomb protection
@@ -114,4 +111,4 @@
icon = 'icons/obj/clothing/species/teshari/hats.dmi'
icon_override = 'icons/mob/species/teshari/head.dmi'
icon_state = "rad_fitted"
- species_restricted = list(SPECIES_TESHARI)
\ No newline at end of file
+ species_restricted = list(SPECIES_TESHARI)
diff --git a/code/modules/fishing/fishing.dm b/code/modules/fishing/fishing.dm
index 6780fa9e62..532c9a086b 100644
--- a/code/modules/fishing/fishing.dm
+++ b/code/modules/fishing/fishing.dm
@@ -191,7 +191,7 @@ GLOBAL_LIST_INIT(generic_fishing_chance_list, list(FISHING_RARE = 5, FISHING_UNC
/obj/random/tool/powermaint = 5,
/obj/random/unidentified_medicine/combat_medicine = 1,
/obj/random/tool/alien = 1,
- /obj/random/handgun = 1,
+ /obj/random/sidearm = 1,
/mob/living/simple_mob/animal/sif/hooligan_crab = 1
))
diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm
index 35dbb36d38..8cc4a3911b 100644
--- a/code/modules/holodeck/HolodeckObjects.dm
+++ b/code/modules/holodeck/HolodeckObjects.dm
@@ -415,6 +415,8 @@
active_power_usage = 6
power_channel = ENVIRON
+ required_dexterity = MOB_DEXTERITY_SIMPLE_MACHINES
+
/obj/machinery/readybutton/attack_ai(mob/user as mob)
to_chat(user, "The station AI is not to interact with these devices!")
return
diff --git a/code/modules/hydroponics/trays/tray_tools.dm b/code/modules/hydroponics/trays/tray_tools.dm
index 5e7d99b6b0..92434cdc31 100644
--- a/code/modules/hydroponics/trays/tray_tools.dm
+++ b/code/modules/hydroponics/trays/tray_tools.dm
@@ -5,11 +5,12 @@
desc = "A tool used to take samples from plants."
/obj/item/tool/wirecutters/clippers/trimmers
- name = "hedgetrimmers"
- desc = "An old pair of trimmers with a pretty dull blade. You would probably have a hard time cutting anything but plants with it."
- icon_state = "hedget"
- item_state = "hedget"
- force = 7 //One point extra than standard wire cutters.
+ name = "hedgetrimmers"
+ desc = "An old pair of trimmers with a pretty dull blade. You would probably have a hard time cutting anything but plants with it."
+ icon_state = "hedget"
+ item_state = "hedget"
+ random_color = FALSE
+ force = 7 //One point extra than standard wire cutters.
/obj/item/analyzer/plant_analyzer
name = "plant analyzer"
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index accd565145..8e7649f451 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -232,7 +232,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
response = alert(src, "Are you -sure- you want to ghost?\n(You are alive, or otherwise have the potential to become alive. If you ghost, you won't be able to play this round until you respawn as a new character! You can't change your mind so choose wisely!)", "Are you sure you want to ghost?", "Ghost", "Stay in body")
if(response != "Ghost")
return
- resting = 1
+ if(!resting)
+ lay_down()
var/turf/location = get_turf(src)
var/special_role = check_special_role()
if(!istype(loc,/obj/machinery/cryopod))
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index da389510bf..17101ea86e 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1117,6 +1117,8 @@
//icon_state = lowertext(species.name) //Necessary?
+ dexterity = species.dexterity
+
species.create_organs(src)
species.handle_post_spawn(src)
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index d2315f1c79..47864b7058 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -154,3 +154,5 @@
// Custom Species Name
var/custom_species
+
+ dexterity = MOB_DEXTERITY_FULL
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index 06ff9983e9..92d8c6facd 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -274,6 +274,9 @@
var/icon_height = 32
var/agility = 20 //prob() to do agile things
+ /// One of MOB_DEXTERITY_* - the dexterity level of this species for using objects.
+ var/dexterity = MOB_DEXTERITY_FULL
+
/datum/species/proc/update_attack_types()
unarmed_attacks = list()
for(var/u_type in unarmed_types)
diff --git a/code/modules/mob/living/carbon/human/species/station/monkey.dm b/code/modules/mob/living/carbon/human/species/station/monkey.dm
index 6290b5ee1b..b8ff42ccc7 100644
--- a/code/modules/mob/living/carbon/human/species/station/monkey.dm
+++ b/code/modules/mob/living/carbon/human/species/station/monkey.dm
@@ -54,6 +54,8 @@
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
)
+ dexterity = MOB_DEXTERITY_KEYBOARDS
+
/datum/species/monkey/handle_npc(var/mob/living/carbon/human/H)
if(H.stat != CONSCIOUS)
return
diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm
index 8f0f899a5b..e20ac6bc22 100644
--- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm
+++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm
@@ -79,6 +79,9 @@
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right/unseverable/xeno)
)
+ dexterity = MOB_DEXTERITY_NONE
+
+
/datum/species/xenos/get_bodytype()
return SPECIES_XENO
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 15136d16cf..70f3e35325 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -27,6 +27,8 @@
var/hudmode = null
+ dexterity = MOB_DEXTERITY_FULL
+
/mob/living/silicon/Initialize()
silicon_mob_list |= src
. = ..()
@@ -419,4 +421,4 @@
return 0 //NOT REAL EYES
/mob/living/silicon/can_feed()
- return FALSE
\ No newline at end of file
+ return FALSE
diff --git a/code/modules/mob/living/simple_mob/simple_mob.dm b/code/modules/mob/living/simple_mob/simple_mob.dm
index 74ae0ca991..fb09b33dab 100644
--- a/code/modules/mob/living/simple_mob/simple_mob.dm
+++ b/code/modules/mob/living/simple_mob/simple_mob.dm
@@ -101,6 +101,7 @@
var/list/attacktext = list("attacked") // "You are [attacktext] by the mob!"
var/list/friendly = list("nuzzles") // "The mob [friendly] the person."
var/attack_sound = null // Sound to play when I attack
+ var/scratch_sound //! Sound to play when I scratch at a door
var/melee_miss_chance = 0 // percent chance to miss a melee attack.
var/attack_armor_type = "melee" // What armor does this check?
var/attack_armor_pen = 0 // How much armor pen this attack has.
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/grafadreka_harness.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/grafadreka_harness.dm
index 22740ebaa0..f9b426a3c2 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/grafadreka_harness.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/grafadreka_harness.dm
@@ -37,47 +37,48 @@
QDEL_NULL(attached_radio)
QDEL_NULL(attached_gps)
QDEL_NULL(attached_plate)
- . = ..()
+ return ..()
-/obj/item/storage/internal/animal_harness/attackby(obj/item/W, mob/user)
- // Sanity check for some stuff below.
- if(!istype(loc, /mob/living/simple_mob/animal/sif/grafadreka/trained))
+/obj/item/storage/internal/animal_harness/attackby(obj/item/W, mob/user, silent)
+ if (user == loc) // Drakes can't attach stuff to themselves, only shove it in their storage.
return ..()
-
- // Attach a tracker.
- if(istype(W, /obj/item/gps))
- if(attached_gps)
- to_chat(user, SPAN_WARNING("There is already \a [attached_gps] attached to \the [loc]'s harness."))
- else if(user.unEquip(W))
+ if (!istype(loc, /mob/living/simple_mob/animal/sif/grafadreka/trained)) // Only allow attaching behaviors when worn by an appropriate subject.
+ return ..()
+ if (istype(W, /obj/item/gps)) // Attach a tracker.
+ if (attached_gps)
+ if (!silent)
+ to_chat(user, SPAN_WARNING("There is already \a [attached_gps] attached to \the [loc]'s harness."))
+ else if (user.unEquip(W))
W.forceMove(loc)
- user.visible_message(SPAN_NOTICE("\The [user] attaches \the [W] to \the [loc]'s harness."))
+ if (!silent)
+ user.visible_message(SPAN_NOTICE("\The [user] attaches \the [W] to \the [loc]'s harness."))
attached_gps = W
return TRUE
-
- // Attach a radio.
- if(istype(W, /obj/item/radio))
- if(attached_radio)
- to_chat(user, SPAN_WARNING("There is already \a [attached_radio] attached to \the [loc]'s harness."))
- else if(user.unEquip(W))
+ if (istype(W, /obj/item/radio)) // Attach a radio.
+ if (attached_radio)
+ if (!silent)
+ to_chat(user, SPAN_WARNING("There is already \a [attached_radio] attached to \the [loc]'s harness."))
+ else if (user.unEquip(W))
W.forceMove(loc)
- user.visible_message(SPAN_NOTICE("\The [user] attaches \the [W] to \the [loc]'s harness."))
+ if (!silent)
+ user.visible_message(SPAN_NOTICE("\The [user] attaches \the [W] to \the [loc]'s harness."))
attached_radio = W
return TRUE
-
- // Attach an armor plate.
- if(istype(W, /obj/item/clothing/accessory/armor) || istype(W, /obj/item/clothing/accessory/material/makeshift))
- if(attached_plate)
- to_chat(user, SPAN_WARNING("There is already \a [attached_plate] inside \the [loc]'s harness."))
- else if(user.unEquip(W))
+ if (istype(W, /obj/item/clothing/accessory/armor) || istype(W, /obj/item/clothing/accessory/material/makeshift)) // Attach an armor plate.
+ if (attached_plate)
+ if (!silent)
+ to_chat(user, SPAN_WARNING("There is already \a [attached_plate] inside \the [loc]'s harness."))
+ else if (user.unEquip(W))
W.forceMove(loc)
- user.visible_message(SPAN_NOTICE("\The [user] secures \the [W] inside \the [loc]'s harness."))
+ if (!silent)
+ user.visible_message(SPAN_NOTICE("\The [user] secures \the [W] inside \the [loc]'s harness."))
attached_plate = W
var/mob/living/simple_mob/animal/sif/grafadreka/trained/drake = loc
drake.recalculate_armor()
return TRUE
+ return ..()
- . = ..()
/mob/living/simple_mob/animal/sif/grafadreka/trained/proc/recalculate_armor()
armor = list()
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/grafadreka_trained.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/grafadreka_trained.dm
index f2ed6b342f..bfc405b387 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/grafadreka_trained.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/grafadreka_trained.dm
@@ -2,117 +2,297 @@
desc = "A large, sleek snow drake with heavy claws, powerful jaws and many pale spines along its body. This one is wearing some kind of harness; maybe it belongs to someone."
player_msg = "You are a large Sivian pack predator in symbiosis with the local bioluminescent bacteria. You can eat glowing \
tree fruit to fuel your ranged spitting attack and poisonous bite (on harm intent), as well as healing saliva \
- (on help intent).
Unlike your wild kin, you are trained and work happily with your two-legged packmates."
+ (on help intent).
Using grab intent you can pick up and drop items on by clicking them or yourself, \
+ and can interact with some simple machines like buttons and levers.
Unlike your wild kin, you are trained and work happily with your two-legged packmates."
faction = "station"
ai_holder_type = null // These guys should not exist without players.
gender = PLURAL // Will take gender from prefs = set to non-NEUTER here to avoid randomizing in Initialize().
+ movement_cooldown = 1.5 // ~Red~ trained ones go faster.
+ dexterity = MOB_DEXTERITY_SIMPLE_MACHINES
+
+ /// If a valid harness path, the harness this drake will be wearing on Initialize.
var/obj/item/storage/internal/animal_harness/harness = /obj/item/storage/internal/animal_harness
-/mob/living/simple_mob/animal/sif/grafadreka/trained/Initialize()
- if(ispath(harness))
- harness = new harness(src)
- harness.attached_radio = new /obj/item/radio(src)
- regenerate_harness_verbs()
- . = ..()
+ /// On clicking with an item, stuff that should use behaviors instead of being placed in storage.
+ var/static/list/allow_type_to_pass = list(
+ /obj/item/healthanalyzer,
+ /obj/item/stack/medical,
+ /obj/item/reagent_containers/syringe
+ )
+
+ /// A type path -> proc path mapping for objects that drakes can use.
+ var/static/list/interactable_objects = list(
+ /obj/machinery/button = /mob/living/simple_mob/animal/sif/grafadreka/trained/proc/InteractButtonBasic,
+ /obj/machinery/access_button = /mob/living/simple_mob/animal/sif/grafadreka/trained/proc/InteractButtonAccess,
+ /obj/machinery/firealarm = /mob/living/simple_mob/animal/sif/grafadreka/trained/proc/InteractFireAlarm,
+ /obj/machinery/conveyor_switch = /mob/living/simple_mob/animal/sif/grafadreka/trained/proc/InteractConveyorSwitch
+ )
+
/mob/living/simple_mob/animal/sif/grafadreka/trained/Destroy()
- if(istype(harness))
+ if (istype(harness))
QDEL_NULL(harness)
return ..()
+
+/mob/living/simple_mob/animal/sif/grafadreka/trained/Initialize()
+ . = ..()
+ if (ispath(harness, /obj/item/storage/internal/animal_harness))
+ harness = new harness(src)
+ harness.attached_radio = new /obj/item/radio(src)
+ regenerate_harness_verbs()
+ else
+ if (harness)
+ log_error("[type] initialized with an invalid harness [harness]")
+ harness = null
+
+
/mob/living/simple_mob/animal/sif/grafadreka/trained/examine(mob/living/user)
. = ..()
- if(harness)
+ if (harness)
. += "\The [src] is wearing \a [harness]."
- for(var/obj/item/thing in list(harness.attached_gps, harness.attached_plate, harness.attached_radio))
+ for (var/obj/item/thing in list(harness.attached_gps, harness.attached_plate, harness.attached_radio))
. += "There is \a [thing] attached."
+
/mob/living/simple_mob/animal/sif/grafadreka/trained/add_glow()
. = ..()
- if(. && harness)
+ if (. && harness)
var/image/I = .
I.icon_state = "[I.icon_state]-pannier"
+
/mob/living/simple_mob/animal/sif/grafadreka/trained/Logout()
..()
- if(stat != DEAD)
+ if (stat != DEAD)
lying = TRUE
resting = TRUE
sitting = FALSE
Sleeping(2)
update_icon()
+
/mob/living/simple_mob/animal/sif/grafadreka/trained/Login()
..()
SetSleeping(0)
update_icon()
-/mob/living/simple_mob/animal/sif/grafadreka/trained/attack_hand(mob/living/L)
+
+/mob/living/simple_mob/animal/sif/grafadreka/trained/attack_hand(mob/living/user)
// Permit headpats/smacks
- if(!harness || L.a_intent == I_HURT || (L.a_intent == I_HELP && L.zone_sel?.selecting == BP_HEAD))
+ if (!harness || user.a_intent == I_HURT || (user.a_intent == I_HELP && user.zone_sel?.selecting == BP_HEAD))
return ..()
- return harness.handle_attack_hand(L)
+ return harness.handle_attack_hand(user)
+
// universal_understand is buggy and produces double lines, so we'll just do this hack instead.
-/mob/living/simple_mob/animal/sif/grafadreka/trained/say_understands(var/mob/other, var/datum/language/speaking = null)
- if(!speaking || speaking.name == LANGUAGE_GALCOM)
+/mob/living/simple_mob/animal/sif/grafadreka/trained/say_understands(mob/other, datum/language/speaking)
+ if (!speaking || speaking.name == LANGUAGE_GALCOM)
return TRUE
return ..()
+
/mob/living/simple_mob/animal/sif/grafadreka/trained/update_icon()
. = ..()
- if(harness)
+ if (harness)
var/image/I = image(icon, "[current_icon_state]-pannier")
I.color = harness.color
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE|KEEP_APART)
- if(offset_compiled_icon)
+ if (offset_compiled_icon)
I.pixel_x = offset_compiled_icon
add_overlay(I)
-/mob/living/simple_mob/animal/sif/grafadreka/trained/attackby(obj/item/O, mob/user)
+/mob/living/simple_mob/animal/sif/grafadreka/trained/attackby(obj/item/item, mob/user)
// bonk
- if(user.a_intent == I_HURT)
+ if (user.a_intent == I_HURT)
return ..()
-
- // Pass some items down to heal or run injection etc.
- var/static/list/allow_type_to_pass = list(
- /obj/item/healthanalyzer,
- /obj/item/stack/medical,
- /obj/item/reagent_containers/syringe
- )
- if(user.a_intent == I_HELP)
- for(var/pass_type in allow_type_to_pass)
- if(istype(O, pass_type))
+ if (user.a_intent == I_HELP)
+ for (var/pass_type in allow_type_to_pass)
+ if (istype(item, pass_type))
return ..()
-
// Open our storage, if we have it.
- if(harness?.attackby(O, user))
+ if (harness?.attackby(item, user))
regenerate_harness_verbs()
return TRUE
-
return ..()
+
/mob/living/simple_mob/animal/sif/grafadreka/trained/proc/regenerate_harness_verbs()
- if(!harness)
+ if (!harness)
verbs -= list(
/mob/living/simple_mob/animal/sif/grafadreka/trained/proc/remove_attached_gps,
/mob/living/simple_mob/animal/sif/grafadreka/trained/proc/remove_attached_plate,
/mob/living/simple_mob/animal/sif/grafadreka/trained/proc/remove_attached_radio
)
return
-
- if(harness.attached_gps)
+ if (harness.attached_gps)
verbs |= /mob/living/simple_mob/animal/sif/grafadreka/trained/proc/remove_attached_gps
else
verbs -= /mob/living/simple_mob/animal/sif/grafadreka/trained/proc/remove_attached_gps
-
- if(harness.attached_plate)
+ if (harness.attached_plate)
verbs |= /mob/living/simple_mob/animal/sif/grafadreka/trained/proc/remove_attached_plate
else
verbs -= /mob/living/simple_mob/animal/sif/grafadreka/trained/proc/remove_attached_plate
-
- if(harness.attached_radio)
+ if (harness.attached_radio)
verbs |= /mob/living/simple_mob/animal/sif/grafadreka/trained/proc/remove_attached_radio
else
verbs -= /mob/living/simple_mob/animal/sif/grafadreka/trained/proc/remove_attached_radio
+
+
+/mob/living/simple_mob/animal/sif/grafadreka/trained/attack_target(atom/atom)
+ if (a_intent == I_GRAB)
+ if (atom == src)
+ return DropItem()
+ if (isobj(atom))
+ var/interact_outcome = AttemptInteract(atom)
+ if (!isnull(interact_outcome))
+ return interact_outcome
+ if (isitem(atom))
+ return CollectItem(atom)
+ return ..()
+
+
+/mob/living/simple_mob/animal/sif/grafadreka/trained/proc/DropItem()
+ if (!length(harness?.contents))
+ to_chat(src, SPAN_WARNING("You have nothing to drop."))
+ return ATTACK_FAILED
+ var/list/attached = list(harness.attached_gps, harness.attached_radio, harness.attached_plate)
+ var/obj/item/response = input(src, "Select an item to drop:") as null | anything in attached + harness.contents
+ if (!response)
+ return ATTACK_FAILED
+ var/datum/gender/gender = gender_datums[get_visible_gender()]
+ var/is_special = (response in attached)
+ if (is_special)
+ visible_message(
+ SPAN_ITALIC("\The [src] begins tugging at \the [response] on [gender.his] harness."),
+ SPAN_ITALIC("You begin tugging \the [response] off your harness."),
+ SPAN_ITALIC("You hear something rustling."),
+ runemessage = CHAT_MESSAGE_DEFAULT_ACTION
+ )
+ else
+ visible_message(
+ SPAN_ITALIC("\The [src] begins rooting around in the pouch on [gender.his] harness."),
+ SPAN_ITALIC("You begin working \the [response] out of your harness pouch."),
+ SPAN_ITALIC("You hear something rustling."),
+ runemessage = CHAT_MESSAGE_DEFAULT_ACTION
+ )
+ if (!do_after(src, 5 SECONDS, ignore_movement = TRUE))
+ return ATTACK_FAILED
+ if (is_special)
+ if (!(response in src))
+ to_chat(src, SPAN_WARNING("\The [response] is already gone!"))
+ return ATTACK_FAILED
+ if (response == harness.attached_gps)
+ harness.attached_gps = null
+ else if (response == harness.attached_radio)
+ harness.attached_radio = null
+ else if (response == harness.attached_plate)
+ harness.attached_plate = null
+ response.dropInto(loc)
+ regenerate_harness_verbs()
+ else
+ harness.remove_from_storage(response, loc)
+ visible_message(
+ SPAN_ITALIC("\The [src] pulls \a [response] from [gender.his] harness and drops it."),
+ SPAN_NOTICE("You pull \the [response] from your harness and drop it."),
+ SPAN_WARNING("Clank!"),
+ runemessage = CHAT_MESSAGE_DEFAULT_ACTION
+ )
+ return ATTACK_SUCCESSFUL
+
+
+/mob/living/simple_mob/animal/sif/grafadreka/trained/proc/CollectItem(obj/item/item)
+ if (!item.simulated || item.abstract || !item.Adjacent(src))
+ return ATTACK_FAILED
+ if (!harness)
+ to_chat(src, SPAN_WARNING("Your harness is missing; you cannot store \the [item]."))
+ return ATTACK_FAILED
+ if (item.anchored)
+ to_chat(src, SPAN_WARNING("\The [item] is securely anchored; you can't take it."))
+ return ATTACK_FAILED
+ face_atom(item)
+ if (!do_after(src, 5 SECONDS, item))
+ return ATTACK_FAILED
+ var/datum/gender/gender = gender_datums[get_visible_gender()]
+ if (harness?.attackby(item, src, TRUE))
+ visible_message(
+ SPAN_ITALIC("\The [src] grabs \a [item] in [gender.his] teeth and noses it into [gender.his] harness pouch."),
+ SPAN_NOTICE("You grab \the [item] in your teeth and push it into your harness pouch."),
+ SPAN_ITALIC("You hear something rustling."),
+ runemessage = CHAT_MESSAGE_DEFAULT_ACTION
+ )
+ return ATTACK_SUCCESSFUL
+ to_chat(src, SPAN_WARNING("There's not enough space in your harness pouch for \the [item] to fit!"))
+ return ATTACK_FAILED
+
+
+/mob/living/simple_mob/animal/sif/grafadreka/trained/proc/AttemptInteract(obj/obj)
+ if (!obj.Adjacent(src))
+ return
+ var/handler
+ for (var/type in interactable_objects)
+ if (ispath(obj.type, type))
+ handler = interactable_objects[type]
+ break
+ if (!handler)
+ return
+ return call(src, handler)(obj)
+
+
+/mob/living/simple_mob/animal/sif/grafadreka/trained/proc/InteractButtonBasic(obj/machinery/button/button)
+ var/datum/gender/gender = gender_datums[get_visible_gender()]
+ visible_message(
+ SPAN_ITALIC("\The [src] stands up awkwardly on [gender.his] hind legs and paws at \a [button]."),
+ SPAN_ITALIC("You rear up, attempting to push \the [button] with your foreclaws."),
+ SPAN_WARNING("You hear something scratching and scrabbling."),
+ runemessage = CHAT_MESSAGE_DEFAULT_ACTION
+ )
+ if (!do_after(src, 5 SECONDS, button))
+ return ATTACK_FAILED
+ to_chat(src, SPAN_NOTICE("After some effort, you manage to push \the [button]."))
+ button.attack_hand(src)
+ return ATTACK_SUCCESSFUL
+
+
+/mob/living/simple_mob/animal/sif/grafadreka/trained/proc/InteractButtonAccess(obj/machinery/access_button/button)
+ var/datum/gender/gender = gender_datums[get_visible_gender()]
+ visible_message(
+ SPAN_ITALIC("\The [src] stands up awkwardly on [gender.his] hind legs and paws at \a [button]."),
+ SPAN_ITALIC("You rear up, attempting to push \the [button] with your foreclaws."),
+ SPAN_WARNING("You hear something scratching and scrabbling."),
+ runemessage = CHAT_MESSAGE_DEFAULT_ACTION
+ )
+ if (!do_after(src, 5 SECONDS, button))
+ return ATTACK_FAILED
+ to_chat(src, SPAN_NOTICE("After some effort, you manage to push \the [button]."))
+ button.attack_hand(src)
+ return ATTACK_SUCCESSFUL
+
+
+/mob/living/simple_mob/animal/sif/grafadreka/trained/proc/InteractFireAlarm(obj/machinery/firealarm/alarm)
+ var/datum/gender/gender = gender_datums[get_visible_gender()]
+ visible_message(
+ SPAN_ITALIC("\The [src] stands up awkwardly on [gender.his] hind legs and paws at \a [alarm]."),
+ SPAN_ITALIC("You rear up, attempting to push \the [alarm] with your foreclaws."),
+ SPAN_WARNING("You hear something scratching and scrabbling."),
+ runemessage = CHAT_MESSAGE_DEFAULT_ACTION
+ )
+ if (!do_after(src, 5 SECONDS, alarm))
+ return ATTACK_FAILED
+ to_chat(src, SPAN_NOTICE("After some effort, you manage to push \the [alarm]."))
+ alarm.attack_hand(src)
+ return ATTACK_SUCCESSFUL
+
+
+/mob/living/simple_mob/animal/sif/grafadreka/trained/proc/InteractConveyorSwitch(obj/machinery/conveyor_switch/lever)
+ visible_message(
+ SPAN_ITALIC("\The [src] pushes bodily against \a [lever]."),
+ SPAN_ITALIC("You press your shoulder into \the [lever], trying to change its direction."),
+ runemessage = CHAT_MESSAGE_DEFAULT_ACTION
+ )
+ if (!do_after(src, 2 SECONDS, lever))
+ return ATTACK_FAILED
+ to_chat(src, SPAN_NOTICE("After some effort, you manage to push \the [lever]."))
+ lever.attack_hand(src)
+ return ATTACK_SUCCESSFUL
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 19d6fb9bcb..0a501f6d11 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -83,7 +83,9 @@
exclude_mobs |= src
else
exclude_mobs = list(src)
- src.show_message(self_message, 1, blind_message, 2)
+ show_message(self_message, 1, blind_message, 2)
+ if (runemessage)
+ create_chat_message(src, "[runemessage]", FALSE, list("emote"), audible = FALSE)
// Transfer messages about what we are doing to upstairs
if(shadow)
shadow.visible_message(message, self_message, blind_message, exclude_mobs, range)
@@ -1194,4 +1196,13 @@
/mob/proc/handle_reagent_transfer(var/datum/reagents/holder, var/amount = 1, var/chem_type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0)
var/datum/reagents/R = new /datum/reagents(amount)
. = holder.trans_to_holder(R, amount, multiplier, copy)
- R.touch_mob(src)
\ No newline at end of file
+ R.touch_mob(src)
+
+
+/// Check the mob's dexterity var against a required level from MOB_DEXTERITY_*, optionally sending a message with optional target specificity.
+/mob/proc/check_dexterity(required_level, atom/target, silent)
+ if (dexterity < required_level)
+ if (!silent)
+ to_chat(src, SPAN_WARNING("You aren't dextrous enough to [target ? "use \the [target]" : "do that"]."))
+ return FALSE
+ return TRUE
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 29b8987d6f..95c1362fb3 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -223,4 +223,7 @@
var/registered_z
var/in_enclosed_vehicle = 0 //For mechs and fighters ambiance. Can be used in other cases.
- var/datum/focus //What receives our keyboard inputs. src by default
\ No newline at end of file
+ var/datum/focus //What receives our keyboard inputs. src by default
+
+ /// One of MOB_DEXTERITY_*, permitting various levels of machine and item interaction.
+ var/dexterity = MOB_DEXTERITY_NONE
diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm
index 8e74081045..b9012df920 100644
--- a/code/modules/projectiles/ammunition/magazines.dm
+++ b/code/modules/projectiles/ammunition/magazines.dm
@@ -135,6 +135,11 @@
name = "magazine (.45 BB)"
ammo_type = /obj/item/ammo_casing/a45/bb
+/obj/item/ammo_magazine/m45/compact
+ name = "compact pistol magazine (.45)"
+ matter = list(MAT_STEEL = 375) //metal costs are very roughly based around 1 .45 casing = 75 metal
+ max_ammo = 5
+
/obj/item/ammo_magazine/m45uzi
name = "stick magazine (.45)"
icon_state = "uzi45"
@@ -857,4 +862,4 @@
ammo_type = /obj/item/ammo_casing/cap
matter = list(MAT_STEEL = 600)
max_ammo = 7
- multiple_sprites = 1
\ No newline at end of file
+ multiple_sprites = 1
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index b65ea5a7fb..10f5ac03d7 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -172,7 +172,7 @@
flux in a nuclear reactor core. This incredible technology may help YOU achieve high excitation rates with small laser volumes!"
icon_state = "lasercannon"
item_state = null
- wielded_item_state = "mhdhowitzer-wielded" //Placeholder
+ wielded_item_state = "laser" //Placeholder
origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_POWER = 3)
slot_flags = SLOT_BELT|SLOT_BACK
projectile_type = /obj/item/projectile/beam/heavylaser/cannon
@@ -240,7 +240,6 @@
name = "antique mono-rifle"
desc = "An old laser rifle. This one can only fire once before requiring recharging."
description_fluff = "Modeled after ancient hunting rifles, this rifle was dubbed the 'Rainy Day Special' by some, due to its use as some barmens' fight-stopper of choice. One shot is all it takes, or so they say."
- icon = 'icons/obj/energygun.dmi'
icon_state = "mono"
item_state = "shotgun"
origin_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 4, TECH_POWER = 3)
@@ -317,9 +316,8 @@
/obj/item/gun/energy/lasershotgun
name = "laser scattergun"
icon = 'icons/obj/energygun.dmi'
- item_state = "laser"
icon_state = "scatter"
+ item_state = null
desc = "A strange Almachi weapon, utilizing a refracting prism to turn a single laser blast into a diverging cluster."
origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 1, TECH_MATERIAL = 4)
-
- projectile_type = /obj/item/projectile/scatter/laser
\ No newline at end of file
+ projectile_type = /obj/item/projectile/scatter/laser
diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm
index aa442cb862..0af15366f7 100644
--- a/code/modules/projectiles/guns/energy/nuclear.dm
+++ b/code/modules/projectiles/guns/energy/nuclear.dm
@@ -21,12 +21,11 @@
self_recharge = 1
use_external_power = 1
-
/obj/item/gun/energy/gun/burst
name = "burst laser"
desc = "The Lawson Arms FM-2t is a versatile energy based weapon, capable of switching between stun or kill with a three round burst option for both settings."
description_fluff = "Lawson Arms is Hephaestus Industries’ main personal-energy-weapon branding, often sold alongside MarsTech projectile weapons to security and law enforcement agencies."
- icon_state = "fm-2tstun100" //May resprite this to be more rifley
+ icon_state = "riflestun100"
item_state = null //so the human update icon uses the icon_state instead.
charge_cost = 100
force = 8
@@ -35,16 +34,16 @@
projectile_type = /obj/item/projectile/beam/stun/weak
origin_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 2, TECH_ILLEGAL = 3)
- modifystate = "fm-2tstun"
+ modifystate = "riflestun"
// requires_two_hands = 1
// one_handed_penalty = 30
firemodes = list(
- list(mode_name="stun", burst=1, projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="fm-2tstun", charge_cost = 100),
- list(mode_name="stun burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="fm-2tstun"),
- list(mode_name="lethal", burst=1, projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="fm-2tkill", charge_cost = 200),
- list(mode_name="lethal burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="fm-2tkill"),
+ list(mode_name="stun", burst=1, projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="riflestun", charge_cost = 100),
+ list(mode_name="stun burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="riflestun"),
+ list(mode_name="lethal", burst=1, projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="riflekill", charge_cost = 200),
+ list(mode_name="lethal burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="riflekill"),
)
/obj/item/gun/energy/gun/nuclear
@@ -83,4 +82,19 @@
firemodes = list(
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/med, modifystate="PDWstun", charge_cost = 240),
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="PDWkill", charge_cost = 480),
- )
\ No newline at end of file
+ )
+
+//What if we went smaller?
+/obj/item/gun/energy/gun/pocket
+ name = "subcompact energy gun"
+ desc = "The LAEP90-S Perunika is a subcompact variant of the versatile Perun energy sidearm, for use by plainclothes security personnel with a desire for concealability."
+ description_fluff = "Lawson Arms is Hephaestus Industries’ main personal-energy-weapon branding, often sold alongside MarsTech projectile weapons to security and law enforcement agencies."
+ w_class = ITEMSIZE_SMALL
+ icon_state = "egunstun100"
+ item_state = "energystun"
+
+ modifystate = "egunstun"
+ firemodes = list(
+ list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/med, modifystate="egunstun", charge_cost = 240),
+ list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="egunkill", charge_cost = 480),
+ )
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index 214e90edd1..677c9e6ded 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -23,6 +23,13 @@
charge_cost = 400
recharge_time = 7 //Time it takes for shots to recharge (in ticks)
+/obj/item/gun/energy/taser/disabler
+ name = "disabler"
+ desc = "The RayZar S500 Disabler is a high-powered derivative of the same Mk30 taser design used by NanoTrasen security, and is capable of overloading prosthetic energy cells. It's use is heavily regulated due to potential for long-term effects on the body."
+ icon_state = "disabler"
+ projectile_type = /obj/item/projectile/beam/stun/disabler
+ charge_cost = 480
+
/obj/item/gun/energy/taser/mounted/cyborg/swarm
name = "disabler"
desc = "An archaic device which attacks the target's nervous-system or control circuits."
@@ -110,4 +117,4 @@
icon_state = "snubstunrevolver"
item_state = "stunrevolver"
w_class = ITEMSIZE_SMALL
- origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
\ No newline at end of file
+ origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm
index e9c5fedd76..00621840ee 100644
--- a/code/modules/projectiles/guns/projectile/automatic.dm
+++ b/code/modules/projectiles/guns/projectile/automatic.dm
@@ -1,7 +1,7 @@
/obj/item/gun/projectile/automatic //This should never be spawned in, it is just here because of code necessities.
name = "daka SMG"
desc = "A small SMG. You really shouldn't be able to get this gun. Uses 9mm rounds."
- icon_state = "c05r" //Used because it's not used anywhere else
+ icon_state = "smg" //Used because it's not used anywhere else
load_method = SPEEDLOADER
ammo_type = /obj/item/ammo_casing/a9mm
projectile_type = /obj/item/projectile/bullet/pistol
@@ -370,6 +370,27 @@
/obj/item/gun/projectile/automatic/p90/update_icon()
icon_state = "p90smg-[ammo_magazine ? round(ammo_magazine.stored_ammo.len, 6) : "empty"]"
+/obj/item/gun/projectile/automatic/pearlshield
+ name = "\improper Tajaran PDW"
+ desc = "A century old Rhemazar military weapon adapted to use human-standard cartridges, the PCA-A9 Karik has been the standard submachine gun of the Pearlshield military since 2549. Uses 9mm rounds."
+ description_fluff = "Pearlshield Consolidated Armories are far from the most cutting edge firearm manufacturer, but the Tajaran’s long tradition of war is rivaled only by humanity, \
+ and the introduction of human technology to the Tajaran arms market has resulted in something of a revolution in finding new ways to kill each other at long distances with bullets. \
+ Usually made with mass-production in mind, PCA weapons combine an eye for design with a great desire to make people dead."
+ icon_state = "pdw"
+ item_state = "c20r"
+ w_class = ITEMSIZE_NORMAL
+ caliber = "9mm"
+ origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 2)
+ slot_flags = SLOT_BELT
+ load_method = MAGAZINE
+ magazine_type = /obj/item/ammo_magazine/m9mmt
+ allowed_magazines = list(/obj/item/ammo_magazine/m9mm, /obj/item/ammo_magazine/m9mmt)
+
+ firemodes = list(
+ list(mode_name="semiauto", burst=1, fire_delay=0),
+ list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=6, burst_accuracy=list(0,-15,-30), dispersion=list(0.0, 0.6, 0.6))
+ )
+
/obj/item/gun/projectile/automatic/tommygun
name = "\improper Tommy Gun"
desc = "This weapon was made famous by gangsters in the 20th century. Cybersun Industries is currently reproducing these for a target market of historic gun collectors and classy criminals. Uses .45 rounds."
@@ -452,4 +473,4 @@
if(ammo_magazine)
icon_state = "combatsmg"
else
- icon_state = "combatsmg-empty"
\ No newline at end of file
+ icon_state = "combatsmg-empty"
diff --git a/code/modules/projectiles/guns/projectile/boltaction.dm b/code/modules/projectiles/guns/projectile/boltaction.dm
index c376eb1f8f..02a75b20ff 100644
--- a/code/modules/projectiles/guns/projectile/boltaction.dm
+++ b/code/modules/projectiles/guns/projectile/boltaction.dm
@@ -17,6 +17,17 @@
action_sound = 'sound/weapons/riflebolt.ogg'
pump_animation = "boltaction-cycling"
+//////Antique Variant//////
+/obj/item/gun/projectile/shotgun/pump/rifle/antique
+ name = "antique bolt-action rifle"
+ desc = "A cheaply produced rifle dating from at least the late 21st century, if not before. Hand loaded. Uses 7.62mm rounds."
+ description_fluff = "These faux-wood plastic unbranded bolt-action rifles were mass produced in the millions to equip early Icarus Front supporters during staged revolutions in the 2090s,\
+ though the design had circulated on the internet for at least fifty years prior. Surviving examples are relatively common, but generally unreliable as weapons due to their advanced age."
+ icon_state = "surplus"
+ item_state = "boltaction_c"
+ load_method = SINGLE_CASING
+ max_shells = 7
+
////////Practice Rifle////////
/obj/item/gun/projectile/shotgun/pump/rifle/practice // For target practice
name = "practice bolt-action rifle"
@@ -76,6 +87,22 @@
/obj/item/gun/projectile/shotgun/pump/rifle/lever/vintage
name = "vintage repeater"
desc = "An iconic manually operated lever action rifle, offering adequate stopping power due to it's still powerful cartridge while at the same time having a rather respectable firing rate due to it's mechanism. It is very probable this is a replica instead of a museum piece, but rifles of this pattern still see usage as colonist guns in some far off regions. Uses 7.62mm rounds."
+ description_fluff = null
item_state = "levercarbine"
icon_state = "levercarbine"
pump_animation = "levercarbine-cycling"
+
+/obj/item/gun/projectile/shotgun/pump/rifle/lever/brushgun
+ name = "brush gun"
+ desc = "The Hedberg-Hammarstrom Myrkvidhr is a high-caliber lever-action hunting rifle designed specifically for tackling the hardy and often armoured wildlife of Sif."
+ icon_state = "brushgun"
+ pump_animation = "brushgun-cycling"
+ max_shells = 8
+ ammo_type = /obj/item/ammo_casing/a44/rifle
+ caliber = ".44"
+
+/obj/item/gun/projectile/shotgun/pump/rifle/lever/brushgun/Initialize()
+ if(prob(50))
+ icon_state = "trailgun"
+ pump_animation = "trailgun_cycling"
+ . = ..()
diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm
index 5454853d71..d22cb1e514 100644
--- a/code/modules/projectiles/guns/projectile/pistol.dm
+++ b/code/modules/projectiles/guns/projectile/pistol.dm
@@ -55,7 +55,7 @@
options["NT Mk. 58"] = "secguncomp"
options["NT Mk. 58 Custom"] = "secgundark"
options["MarsTech P11 Spur"] = "colt"
- options["MarsTech P59 Massif"] = "fnseven"
+ options["MarsTech P59 Massif"] = "civil"
options["ProTek YC9"] = "usp"
options["ProTek Minx"] = "VP78"
options["Jindal T15 Chooha"] = "p08"
@@ -232,9 +232,22 @@
/obj/item/gun/projectile/pistol/update_icon()
..()
if(silenced)
- icon_state = "pistol-silencer"
+ if(ammo_magazine)
+ icon_state = "[initial(icon_state)]-silencer"
+ else
+ icon_state = "[initial(icon_state)]-silencer-e"
else
- icon_state = "pistol"
+ if(ammo_magazine)
+ icon_state = "[initial(icon_state)]"
+ else
+ icon_state = "[initial(icon_state)]-e"
+
+/obj/item/gun/projectile/pistol/alt
+ name = "compact government pistol"
+ desc = "The Jindal PF. A compact, easily concealable gun, though it's only compatible with compact magazines. Uses 9mm rounds."
+ description_fluff = "The Jindal Arms PF was the company's first entry into the compact pistols market, and has served as the standard issue firearm \
+ of Tau Ceti government security forces since their consolidation in 2332."
+ icon_state = "compact"
/obj/item/silencer
name = "silencer"
@@ -246,7 +259,7 @@
/obj/item/gun/projectile/pirate
name = "zip gun"
desc = "Little more than a barrel, handle, and firing mechanism, cheap makeshift firearms like this one are not uncommon in frontier systems."
- icon_state = "sawnshotgun"
+ icon_state = "zipgun"
item_state = "sawnshotgun"
handle_casings = CYCLE_CASINGS //player has to take the old casing out manually before reloading
load_method = SINGLE_CASING
@@ -339,4 +352,28 @@
icon_state = "p92x-brown"
/obj/item/gun/projectile/p92x/large
- magazine_type = /obj/item/ammo_magazine/m9mm/large // Spawns with illegal magazines.
\ No newline at end of file
+ magazine_type = /obj/item/ammo_magazine/m9mm/large // Spawns with illegal magazines.
+
+/obj/item/gun/projectile/compact_45
+ name = "compact .45 pistol"
+ desc = "A compact and easily concealable gun with surprising firepower, though it's only compatible with compact magazines. Uses .45 rounds."
+ description_fluff = "The MarsTech Ecureuil is the company's most popular compact .45 model. Perhaps best known as the official service pistol of the Free Relan Federation, despite a notoriously low magazine capacity."
+ icon_state = "ecureuil"
+ item_state = null
+ w_class = ITEMSIZE_SMALL
+ magazine_type = /obj/item/ammo_magazine/m45/compact
+ allowed_magazines = list(/obj/item/ammo_magazine/m45/compact)
+ projectile_type = /obj/item/projectile/bullet/pistol/medium
+ caliber = ".45"
+ origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3)
+ load_method = MAGAZINE
+
+/obj/item/gun/projectile/compact_45/update_icon()
+ ..()
+ if(ammo_magazine)
+ icon_state = "[initial(icon_state)]"
+ else
+ icon_state = "[initial(icon_state)]-e"
+
+/obj/item/gun/projectile/compact_45/tactical
+ icon_state = "tac_ecureuil"
diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm
index 127ba14a39..aad53b698b 100644
--- a/code/modules/projectiles/guns/projectile/revolver.dm
+++ b/code/modules/projectiles/guns/projectile/revolver.dm
@@ -42,7 +42,7 @@
name = "mateba"
desc = "This unique looking handgun is named after an Italian company famous for the original manufacture of these revolvers, and pasta kneading machines. Uses .357 rounds." // Yes I'm serious. -Spades
icon_state = "mateba"
- origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
+
/obj/item/gun/projectile/revolver/detective
name = "revolver"
@@ -71,6 +71,14 @@
to_chat(M, "You name the gun [input]. Say hello to your new friend.")
return 1
+/obj/item/gun/projectile/revolver/gold
+ name = "trophy revolver"
+ desc = "A prestigious engraved version of the MarsTech R1 Snubnose, mass-produced for presentation to long-serving law enforcement personnel upon retirement. Uses .38-Special rounds."
+ icon_state = "detective_gold"
+ origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 4)
+ caliber = ".38"
+ ammo_type = /obj/item/ammo_casing/a38
+
/obj/item/gun/projectile/revolver/detective45
name = ".45 revolver"
desc = "A basic revolver, popular among some law enforcement agencies for its simple, long-lasting construction, modified for .45 rounds and a seven-shot cylinder."
@@ -80,7 +88,6 @@
ammo_type = /obj/item/ammo_casing/a45/rubber
max_shells = 7
-
/obj/item/gun/projectile/revolver/detective45/verb/rename_gun()
set name = "Name Gun"
set category = "Object"
@@ -108,12 +115,14 @@
var/mob/M = usr
var/list/options = list()
options["MarsTech R1 Snubnose"] = "detective"
- options["ProTek Cowboy"] = "GP100"
options["MarsTech Frontiersman Classic"] = "detective_peacemaker"
options["MarsTech Frontiersman Shadow"] = "detective_peacemaker_dark"
options["MarsTech Panther"] = "detective_panther"
- options["Jindal Duke"] = "lemat_old"
+ options["ProTek Cowboy"] = "GP100"
+ options["Jindal Duke"] = "lombardi_police"
+ options["Jindal Viscount Snub"] = "detective_black"
options["H-H Sindri"] = "webley"
+ options["H-H Brokkr"] = "nagant"
options["Lombardi Buzzard"] = "detective_buzzard"
options["Lombardi Constable Deluxe 2502"] = "detective_constable"
var/choice = input(M,"Choose your sprite!","Resprite Gun") in options
@@ -151,8 +160,8 @@
/obj/item/gun/projectile/revolver/capgun
name = "cap gun"
desc = "Looks almost like the real thing! Ages 8 and up."
- icon_state = "revolver"
- item_state = "revolver"
+ icon_state = "detective_fitz"
+ item_state = "detective_fitz"
caliber = "caps"
origin_tech = list(TECH_COMBAT = 1, TECH_MATERIAL = 1)
handle_casings = CYCLE_CASINGS
@@ -176,7 +185,7 @@
// ToDo: Remove accuracy debuf in exchange for slightly injuring your hand every time you fire it.
/obj/item/gun/projectile/revolver/lemat
- name = "Mako Revolver"
+ name = "Mako revolver"
desc = "The Bishamonten P100 Mako is a 9 shot revolver with a secondary firing barrel loading shotgun shells. For when you really need something dead. A rare yet deadly collector's item. Uses .38-Special and 12g rounds depending on the barrel."
description_fluff = "The Bishamonten Company operated from roughly 2150-2280 - the height of the first extrasolar colonisation boom - before filing for bankruptcy and selling off its assets to various companies that would go on to become today’s TSCs. \
Focused on sleek ‘futurist’ designs which have largely fallen out of fashion but remain popular with collectors and people hoping to make some quick thalers from replica weapons. \
@@ -269,8 +278,6 @@
else
. += "It has a secondary barrel that is empty."
-
-//Ported from Bay
/obj/item/gun/projectile/revolver/webley
name = "patrol revolver"
desc = "A rugged top break revolver commonly issued to members of the SifGuard. Uses .44 magnum rounds."
@@ -288,6 +295,31 @@
name = "autorevolver"
icon_state = "mosley"
desc = "A shiny Fosbery Autococker automatic revolver, with black accents. Marketed as the 'Revolver for the Modern Era'. Uses .44 magnum rounds."
+ description_fluff = null
fire_delay = 5.7 //Autorevolver. Also synced with the animation
fire_anim = "mosley_fire"
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2)
+
+/obj/item/gun/projectile/revolver/webley/large
+ name = "heavy revolver"
+ desc = "A high-capacity magnum revolver, polished to a mirror shine. Uses .44 magnum rounds."
+ description_fluff = "The Hedberg-Hammarstrom Wyrm was designed as a SifGuard sidearm, but the prototype was rejected in favour of the lighter Althing. \
+ Introduced to the consumer market by popular demand a few years later, the Wyrm has been a hit with collectors ever since."
+ icon_state = "revolver_stainless"
+ max_shells = 8
+
+/obj/item/gun/projectile/revolver/webley/magnetic
+ name = "Auditor revolver"
+ desc = "A high-powered revolver with a electromagnetically assisted firing mechanism for enhanced armor-piercing capability using standard ammunition. Uses .44 magnum rounds."
+ description_fluff = "The Lawson Arms LAM-2 Auditor is an experimental hybrid design using an electronic firing mechanism to propel standard ballistic ammunition at absurd velocities. \
+ Though prohibitively expensive to both obtain and maintain, the Auditor is a favourite with those particular gunmen with near unlimited budgets."
+ icon_state = "inspector"
+ projectile_type = /obj/item/projectile/bullet/pistol/strong/ap
+ origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_MAGNET = 2)
+
+/obj/item/gun/projectile/revolver/webley/magnetic/update_icon()
+ cut_overlays()
+ if(loaded.len==0)
+ add_overlay("inspector_off")
+ else
+ add_overlay("inspector_on")
diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm
index a412e705b6..66769687fc 100644
--- a/code/modules/projectiles/guns/projectile/shotgun.dm
+++ b/code/modules/projectiles/guns/projectile/shotgun.dm
@@ -90,7 +90,7 @@
/obj/item/gun/projectile/shotgun/doublebarrel
name = "double-barreled shotgun"
- desc = "A truely classic weapon. No need to change what works. Uses 12g rounds."
+ desc = "A truly classic weapon. No need to change what works. Uses 12g rounds."
icon_state = "dshotgun"
item_state = "dshotgun"
//SPEEDLOADER because rapid unloading.
@@ -104,6 +104,7 @@
caliber = "12g"
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 1)
ammo_type = /obj/item/ammo_casing/a12g/beanbag
+ var/sawn_off = FALSE
burst_delay = 0
firemodes = list(
@@ -117,6 +118,7 @@
/obj/item/gun/projectile/shotgun/doublebarrel/flare
name = "signal shotgun"
desc = "A double-barreled shotgun meant to fire signal flash shells. Uses 12g rounds."
+ icon_state = "dshotgun_g"
ammo_type = /obj/item/ammo_casing/a12g/flash
/obj/item/gun/projectile/shotgun/doublebarrel/unload_ammo(user, allow_dump)
@@ -135,7 +137,9 @@
burst = burstsetting
return
if(do_after(user, 30)) //SHIT IS STEALTHY EYYYYY
- icon_state = "sawnshotgun"
+ if(sawn_off)
+ return
+ icon_state = "[initial(icon_state)]-sawn"
item_state = "sawnshotgun"
w_class = ITEMSIZE_NORMAL
force = 5
@@ -144,18 +148,20 @@
name = "sawn-off shotgun"
desc = "Omar's coming!"
to_chat(user, "You shorten the barrel of \the [src]!")
+ sawn_off = TRUE
else
..()
/obj/item/gun/projectile/shotgun/doublebarrel/sawn
name = "sawn-off shotgun"
desc = "Omar's coming!" // I'm not gonna add "Uses 12g rounds." to this one. I'll just let this reference go undisturbed.
- icon_state = "sawnshotgun"
+ icon_state = "dshotgun-sawn"
item_state = "sawnshotgun"
slot_flags = SLOT_BELT|SLOT_HOLSTER
ammo_type = /obj/item/ammo_casing/a12g/pellet
w_class = ITEMSIZE_NORMAL
force = 5
+ sawn_off = TRUE
//Sjorgen Inertial Shotgun
/obj/item/gun/projectile/shotgun/semi
@@ -171,4 +177,3 @@
load_method = SINGLE_CASING
max_shells = 5
ammo_type = /obj/item/ammo_casing/a12g/beanbag
-
\ No newline at end of file
diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm
index c59cfb980a..7a121fbcb7 100644
--- a/code/modules/projectiles/projectile/bullets.dm
+++ b/code/modules/projectiles/projectile/bullets.dm
@@ -131,6 +131,9 @@
damage = 60
hud_state = "pistol_heavy"
+/obj/item/projectile/bullet/pistol/strong/ap
+ armor_penetration = 15
+
/obj/item/projectile/bullet/pistol/rubber/strong // "Rubber" bullets for high power pistols.
fire_sound = 'sound/weapons/gunshot3.ogg' // Rubber shots have less powder, but these still have more punch than normal rubber shot.
damage = 10
diff --git a/code/modules/reagents/machinery/dispenser/reagent_tank.dm b/code/modules/reagents/machinery/dispenser/reagent_tank.dm
index 098938a901..04281884b2 100644
--- a/code/modules/reagents/machinery/dispenser/reagent_tank.dm
+++ b/code/modules/reagents/machinery/dispenser/reagent_tank.dm
@@ -82,7 +82,7 @@
//Dispensers
/obj/structure/reagent_dispensers/watertank
- name = "watertank"
+ name = "water tank"
desc = "A watertank."
icon = 'icons/obj/objects.dmi'
icon_state = "watertank"
@@ -403,7 +403,7 @@
/obj/structure/reagent_dispensers/acid/Initialize()
. = ..()
reagents.add_reagent("sacid", 1000)
-
+
//Cooking oil refill tank
/obj/structure/reagent_dispensers/cookingoil
name = "cooking oil tank"
@@ -437,4 +437,4 @@
/obj/structure/reagent_dispenser/he3/Initialize()
..()
- reagents.add_reagent("helium3",1000)
\ No newline at end of file
+ reagents.add_reagent("helium3",1000)
diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm
index e34a331cef..334cb29628 100644
--- a/code/modules/recycling/conveyor2.dm
+++ b/code/modules/recycling/conveyor2.dm
@@ -200,6 +200,7 @@
anchored = 1
var/speed_active = FALSE // are the linked conveyors on SSfastprocess?
+ required_dexterity = MOB_DEXTERITY_SIMPLE_MACHINES
/obj/machinery/conveyor_switch/Initialize()
diff --git a/code/modules/xenobio/items/weapons.dm b/code/modules/xenobio/items/weapons.dm
index 0304bff0b7..e91bbd7ae8 100644
--- a/code/modules/xenobio/items/weapons.dm
+++ b/code/modules/xenobio/items/weapons.dm
@@ -45,7 +45,7 @@
name = "xeno taser gun"
desc = "Straight out of NT's testing laboratories, this small gun is used to subdue non-humanoid xeno life forms. \
While marketed towards handling slimes, it may be useful for other creatures."
- icon_state = "taserold"
+ icon_state = "taserblueold"
fire_sound = 'sound/weapons/taser2.ogg'
charge_cost = 120 // Twice as many shots.
projectile_type = /obj/item/projectile/beam/stun/xeno
diff --git a/code/stylesheet.dm b/code/stylesheet.dm
index 2875eaf330..3ff515e67a 100644
--- a/code/stylesheet.dm
+++ b/code/stylesheet.dm
@@ -79,6 +79,7 @@ h1.alert, h2.alert {color: #000000;}
.critical {color: #ff0000; font-weight: bold; font-size: 150%;}
.danger {color: #ff0000; font-weight: bold;}
.warning {color: #ff0000; font-style: italic;}
+.italic {font-style: italic;}
.rose {color: #ff5050;}
.info {color: #0000CC;}
.notice {color: #000099;}
diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi
index e0cc8433d6..d54d49e8c6 100644
Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ
diff --git a/icons/mob/belt_mirror.dmi b/icons/mob/belt_mirror.dmi
index 3881b1c746..7b27432ccb 100644
Binary files a/icons/mob/belt_mirror.dmi and b/icons/mob/belt_mirror.dmi differ
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index bdf147ff60..d3f8e33bac 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/mob/items/lefthand_guns.dmi b/icons/mob/items/lefthand_guns.dmi
index 904a70a4bd..7690273a89 100644
Binary files a/icons/mob/items/lefthand_guns.dmi and b/icons/mob/items/lefthand_guns.dmi differ
diff --git a/icons/mob/items/righthand_guns.dmi b/icons/mob/items/righthand_guns.dmi
index 9fbef51dab..42aaeeb73a 100644
Binary files a/icons/mob/items/righthand_guns.dmi and b/icons/mob/items/righthand_guns.dmi differ
diff --git a/icons/mob/species/tajaran/helmet.dmi b/icons/mob/species/tajaran/helmet.dmi
index 513092f900..7ea29916bc 100644
Binary files a/icons/mob/species/tajaran/helmet.dmi and b/icons/mob/species/tajaran/helmet.dmi differ
diff --git a/icons/mob/species/unathi/helmet.dmi b/icons/mob/species/unathi/helmet.dmi
index 4f90c5a779..d92ec19353 100644
Binary files a/icons/mob/species/unathi/helmet.dmi and b/icons/mob/species/unathi/helmet.dmi differ
diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi
index 73c59d73db..a72af16f2b 100644
Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index 5e0d177313..0c0ef6a175 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi
index f0c5ecdfb2..327c59d686 100644
Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ
diff --git a/icons/obj/energygun.dmi b/icons/obj/energygun.dmi
index 73c39449bb..41377839fd 100644
Binary files a/icons/obj/energygun.dmi and b/icons/obj/energygun.dmi differ
diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi
index 8f26ffad37..afeaaf47e1 100644
Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ
diff --git a/icons/obj/gun2.dmi b/icons/obj/gun2.dmi
index 6b81e46b90..e802e3a85f 100644
Binary files a/icons/obj/gun2.dmi and b/icons/obj/gun2.dmi differ
diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi
index b8fdc59688..c6810e9fb4 100644
Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ
diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi
index c75aa65d5a..f7abfefcf4 100644
Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ
diff --git a/maps/cynosure/cynosure-6.dmm b/maps/cynosure/cynosure-6.dmm
index a69a487e07..fb7ed670f2 100644
--- a/maps/cynosure/cynosure-6.dmm
+++ b/maps/cynosure/cynosure-6.dmm
@@ -968,6 +968,14 @@
icon_state = "dark"
},
/area/centcom/specops)
+"bcL" = (
+/obj/structure/shuttle/falsewall_no_join,
+/obj/structure/shuttle/falsewall_no_join{
+ icon = 'icons/turf/wall_masks_tgmc.dmi';
+ icon_state = "white1"
+ },
+/turf/simulated/floor/plating,
+/area/shuttle/escape/centcom)
"bcT" = (
/obj/machinery/sleep_console,
/turf/unsimulated/floor{
@@ -1157,7 +1165,11 @@
/turf/simulated/shuttle/floor/white,
/area/skipjack_station/start)
"boo" = (
-/turf/simulated/wall/tgmc/whitewall,
+/obj/structure/shuttle/falsewall_no_join{
+ icon = 'icons/turf/wall_masks_tgmc.dmi';
+ icon_state = "white2"
+ },
+/turf/simulated/floor/plating,
/area/shuttle/escape/centcom)
"bos" = (
/obj/effect/floor_decal/techfloor{
@@ -1793,10 +1805,18 @@
/turf/simulated/floor/holofloor/bmarble,
/area/holodeck/source_chess)
"caf" = (
-/turf/simulated/wall/tgmc/window/white,
+/obj/structure/shuttle/falsewall_no_join/window{
+ icon = 'icons/turf/wall_masks_tgmc_win.dmi';
+ icon_state = "white_window2"
+ },
+/turf/simulated/floor/tiled/milspec/dark,
/area/shuttle/arrival/pre_game)
"cbu" = (
-/turf/simulated/wall/tgmc/window/white/reinf,
+/obj/structure/shuttle/falsewall_no_join/window{
+ icon = 'icons/turf/wall_masks_tgmc_win.dmi';
+ icon_state = "white_rwindow2"
+ },
+/turf/simulated/floor/tiled/milspec/dark,
/area/shuttle/arrival/pre_game)
"cbv" = (
/obj/structure/closet/crate/freezer,
@@ -2774,6 +2794,13 @@
icon_state = "steel"
},
/area/shuttle/trade)
+"dmu" = (
+/obj/structure/shuttle/falsewall_no_join/window{
+ icon = 'icons/turf/wall_masks_tgmc_win.dmi';
+ icon_state = "white_window1"
+ },
+/turf/simulated/floor/tiled/milspec/dark,
+/area/shuttle/arrival/pre_game)
"dmM" = (
/obj/structure/table/rack,
/obj/item/clothing/under/color/green,
@@ -5006,6 +5033,13 @@
icon_state = "dark"
},
/area/centcom/main_hall)
+"fJP" = (
+/obj/structure/shuttle/falsewall_no_join/window{
+ icon = 'icons/turf/wall_masks_tgmc_win.dmi';
+ icon_state = "white_rwindow1"
+ },
+/turf/simulated/wall/tgmc/window/white/reinf,
+/area/shuttle/escape/centcom)
"fKy" = (
/obj/effect/floor_decal/industrial/warning{
dir = 1
@@ -7873,6 +7907,13 @@
/obj/random/energy,
/turf/simulated/shuttle/plating,
/area/skipjack_station/start)
+"iQX" = (
+/obj/structure/shuttle/falsewall_no_join{
+ icon = 'icons/turf/wall_masks_tgmc.dmi';
+ icon_state = "white1"
+ },
+/turf/simulated/wall/tgmc/whitewall,
+/area/shuttle/escape/centcom)
"iRf" = (
/obj/machinery/floodlight,
/turf/simulated/shuttle/plating,
@@ -8167,6 +8208,13 @@
icon_state = "dark"
},
/area/wizard_station)
+"jfW" = (
+/obj/structure/shuttle/falsewall_no_join{
+ icon = 'icons/turf/wall_masks_tgmc.dmi';
+ icon_state = "white1"
+ },
+/turf/simulated/floor/tiled/milspec/dark,
+/area/shuttle/arrival/pre_game)
"jgo" = (
/obj/item/ore,
/turf/unsimulated/floor{
@@ -11019,7 +11067,11 @@
},
/area/centcom/main_hall)
"mhh" = (
-/turf/simulated/wall/tgmc/window/white/reinf,
+/obj/structure/shuttle/falsewall_no_join/window{
+ icon = 'icons/turf/wall_masks_tgmc_win.dmi';
+ icon_state = "white_rwindow2"
+ },
+/turf/simulated/floor/plating,
/area/shuttle/escape/centcom)
"mhv" = (
/obj/structure/flora/ausbushes/sparsegrass,
@@ -11613,6 +11665,13 @@
/obj/structure/window/reinforced/full,
/turf/simulated/shuttle/plating,
/area/shuttle/merchant/home)
+"mPt" = (
+/obj/structure/shuttle/falsewall_no_join{
+ icon = 'icons/turf/wall_masks_tgmc.dmi';
+ icon_state = "white2"
+ },
+/turf/simulated/wall/tgmc/whitewall,
+/area/shuttle/escape/centcom)
"mQd" = (
/obj/structure/table/marble,
/obj/effect/floor_decal/corner/white/diagonal,
@@ -13596,7 +13655,11 @@
},
/area/centcom/main_hall)
"pia" = (
-/turf/simulated/wall/tgmc/whitewall,
+/obj/structure/shuttle/falsewall_no_join{
+ icon = 'icons/turf/wall_masks_tgmc.dmi';
+ icon_state = "white2"
+ },
+/turf/simulated/floor/tiled/milspec/dark,
/area/shuttle/arrival/pre_game)
"piF" = (
/turf/unsimulated/floor{
@@ -16635,6 +16698,13 @@
name = "plating"
},
/area/wizard_station)
+"seQ" = (
+/obj/structure/shuttle/falsewall_no_join/window{
+ icon = 'icons/turf/wall_masks_tgmc_win.dmi';
+ icon_state = "white_rwindow1"
+ },
+/turf/simulated/floor/tiled/milspec/dark,
+/area/shuttle/arrival/pre_game)
"sfb" = (
/obj/item/reagent_containers/food/drinks/cans/cola,
/obj/item/reagent_containers/food/drinks/cans/cola,
@@ -18181,6 +18251,13 @@
/obj/effect/floor_decal/sign/small_f,
/turf/simulated/floor/holofloor/wood,
/area/holodeck/source_chess)
+"tPd" = (
+/obj/structure/shuttle/falsewall_no_join/window{
+ icon = 'icons/turf/wall_masks_tgmc_win.dmi';
+ icon_state = "white_rwindow2"
+ },
+/turf/simulated/wall/tgmc/window/white/reinf,
+/area/shuttle/escape/centcom)
"tPB" = (
/obj/effect/floor_decal/industrial/warning/corner{
dir = 4
@@ -19018,6 +19095,19 @@
},
/turf/simulated/shuttle/plating,
/area/skipjack_station/start)
+"uGT" = (
+/obj/structure/bed/chair/shuttle{
+ dir = 4
+ },
+/obj/effect/landmark{
+ name = "JoinLate"
+ },
+/obj/structure/closet/walllocker/emerglocker{
+ pixel_x = -32
+ },
+/obj/effect/floor_decal/milspec/color/white,
+/turf/simulated/floor/tiled/milspec/sterile,
+/area/shuttle/arrival/pre_game)
"uHS" = (
/obj/structure/bed/chair/comfy/red{
dir = 4
@@ -20196,6 +20286,13 @@
icon_state = "dark"
},
/area/centcom/specops)
+"vXp" = (
+/obj/structure/shuttle/falsewall_no_join/window{
+ icon = 'icons/turf/wall_masks_tgmc_win.dmi';
+ icon_state = "white_rwindow1"
+ },
+/turf/simulated/floor/plating,
+/area/shuttle/escape/centcom)
"vYZ" = (
/obj/effect/floor_decal/borderfloorwhite{
dir = 8
@@ -21413,6 +21510,13 @@
/obj/structure/window/reinforced,
/turf/simulated/shuttle/floor/white,
/area/centcom/evac)
+"xib" = (
+/obj/structure/shuttle/falsewall_no_join/window{
+ icon = 'icons/turf/wall_masks_tgmc_win.dmi';
+ icon_state = "white_window3"
+ },
+/turf/simulated/floor/tiled/milspec/dark,
+/area/shuttle/arrival/pre_game)
"xid" = (
/obj/machinery/dna_scannernew,
/obj/effect/floor_decal/borderfloorwhite{
@@ -29971,8 +30075,8 @@ lqf
lqf
pia
cbu
-cbu
-pia
+seQ
+jfW
lqf
lqf
tQa
@@ -30229,7 +30333,7 @@ cSk
rBk
bAY
bAY
-rBk
+uGT
cSk
cSk
thM
@@ -30998,9 +31102,9 @@ tgY
pNX
dZT
caf
-caf
-caf
-caf
+xib
+xib
+dmu
nol
pNU
jbe
@@ -32027,8 +32131,8 @@ qzL
qzL
pia
cbu
-cbu
-pia
+seQ
+jfW
qzL
qzL
tQa
@@ -36306,8 +36410,8 @@ gOt
gOt
boo
mhh
-mhh
-boo
+vXp
+bcL
gnm
gnm
eVJ
@@ -38874,10 +38978,10 @@ eVJ
eVJ
kuN
nmf
-boo
-mhh
-mhh
-boo
+mPt
+tPd
+fJP
+iQX
kuN
kuN
eVJ
diff --git a/maps/cynosure/cynosure_jobs.dm b/maps/cynosure/cynosure_jobs.dm
index 81a55c91c9..77dfacfd3f 100644
--- a/maps/cynosure/cynosure_jobs.dm
+++ b/maps/cynosure/cynosure_jobs.dm
@@ -202,6 +202,7 @@ var/global/const/access_explorer = 43
continue
chosen_template.load(T, centered = TRUE)
admin_notice("Crash survivor placed \"[chosen_template.name]\" at ([T.x], [T.y], [T.z])\n", R_DEBUG)
+ break
// Rebuild the spawn point list now that one has been spawned.
existing_points = get_existing_spawn_points()
diff --git a/maps/cynosure/loadout/loadout_suit.dm b/maps/cynosure/loadout/loadout_suit.dm
index 4701d23491..5df1b8eab7 100644
--- a/maps/cynosure/loadout/loadout_suit.dm
+++ b/maps/cynosure/loadout/loadout_suit.dm
@@ -1,4 +1,14 @@
-/datum/gear/suit/bomber_pilot
- display_name = "bomber jacket, pilot"
- path = /obj/item/clothing/suit/storage/toggle/bomber/pilot
+/datum/gear/suit/bomber // Override version of bomber jacket selection incorporating map-specific jacket.
+ display_name = "jacket, bomber selection"
+ description = "A selection of jackets styled after early aviation gear."
+ path = /obj/item/clothing/suit/storage/toggle/bomber
cost = 2
+
+/datum/gear/suit/bomber/New()
+ ..()
+ var/bombertype = list()
+ bombertype["bomber jacket"] = /obj/item/clothing/suit/storage/toggle/bomber
+ bombertype["bomber jacket, alternate"] = /obj/item/clothing/suit/storage/bomber/alt
+ bombertype["bomber jacket, retro"] = /obj/item/clothing/suit/storage/toggle/bomber/retro
+ bombertype["bomber jacket, pilot blue"] = /obj/item/clothing/suit/storage/toggle/bomber/pilot
+ gear_tweaks += new/datum/gear_tweak/path(bombertype)
diff --git a/maps/northern_star/polaris-1.dmm b/maps/northern_star/polaris-1.dmm
index e3138398b1..9938fccff1 100644
--- a/maps/northern_star/polaris-1.dmm
+++ b/maps/northern_star/polaris-1.dmm
@@ -500,7 +500,7 @@
"ajF" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/landmark{name = "lightsout"},/turf/simulated/floor/carpet,/area/library)
"ajG" = (/obj/structure/bed/chair/comfy/green{dir = 8},/turf/simulated/floor/carpet,/area/library)
"ajH" = (/obj/machinery/space_heater,/turf/simulated/floor,/area/storage/emergency_storage/emergency4)
-"ajI" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire/firefighter,/obj/item/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/clothing/glasses/meson,/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/storage/emergency_storage/emergency4)
+"ajI" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire,/obj/item/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/extinguisher,/obj/item/clothing/head/hardhat/firefighter,/obj/item/clothing/glasses/meson,/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/storage/emergency_storage/emergency4)
"ajJ" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/tank/oxygen,/obj/item/tank/oxygen,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/flashlight,/obj/item/flashlight,/obj/item/storage/box/lights/mixed,/obj/item/extinguisher,/obj/machinery/alarm{dir = 8; pixel_x = 25; pixel_y = 0},/turf/simulated/floor/plating,/area/storage/emergency_storage/emergency4)
"ajK" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/hallway/secondary/civilian_hallway_fore)
"ajL" = (/obj/structure/disposalpipe/segment,/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor/tiled,/area/hallway/secondary/civilian_hallway_fore)
@@ -6142,7 +6142,7 @@
"cof" = (/obj/structure/table/standard,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/machinery/cell_charger,/turf/simulated/floor/tiled,/area/storage/primary)
"cog" = (/obj/machinery/vending/tool,/turf/simulated/floor/tiled,/area/storage/primary)
"coh" = (/obj/machinery/floodlight,/turf/simulated/floor,/area/storage/emergency_storage/emergency6)
-"coi" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire/firefighter,/obj/item/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/clothing/glasses/meson,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plating,/area/storage/emergency_storage/emergency6)
+"coi" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire,/obj/item/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/extinguisher,/obj/item/clothing/head/hardhat/firefighter,/obj/item/clothing/glasses/meson,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plating,/area/storage/emergency_storage/emergency6)
"coj" = (/obj/machinery/portable_atmospherics/powered/pump/filled,/turf/simulated/floor/plating,/area/storage/emergency_storage/emergency6)
"cok" = (/obj/structure/closet/wardrobe/grey,/obj/item/storage/backpack,/obj/item/storage/backpack,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/turf/simulated/floor/plating,/area/maintenance/cargo)
"col" = (/obj/structure/table/rack,/obj/item/bodybag/cryobag,/obj/effect/floor_decal/corner/paleblue/full{dir = 8},/obj/item/storage/toolbox/emergency,/obj/item/storage/firstaid/regular,/obj/random/medical/lite,/turf/simulated/floor/tiled/white,/area/medical/first_aid_station)
@@ -8037,7 +8037,7 @@
"cYC" = (/obj/machinery/portable_atmospherics/canister/air/airlock,/obj/effect/floor_decal/industrial/outline/yellow,/obj/machinery/atmospherics/portables_connector{dir = 4},/turf/simulated/floor/plating,/area/maintenance/arrivals)
"cYD" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/maintenance/arrivals)
"cYE" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/secondary/entry/starboard)
-"cYF" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire/firefighter,/obj/item/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/clothing/glasses/meson,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plating,/area/storage/emergency_storage/emergency5)
+"cYF" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire,/obj/item/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/extinguisher,/obj/item/clothing/head/hardhat/firefighter,/obj/item/clothing/glasses/meson,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plating,/area/storage/emergency_storage/emergency5)
"cYG" = (/obj/machinery/portable_atmospherics/powered/pump/filled,/turf/simulated/floor/plating,/area/storage/emergency_storage/emergency5)
"cYH" = (/obj/structure/bed/chair{dir = 4},/obj/effect/floor_decal/corner/white{dir = 8},/obj/effect/floor_decal/corner/blue/diagonal,/turf/simulated/floor/tiled,/area/crew_quarters/visitor_dining)
"cYI" = (/obj/structure/table/standard,/obj/effect/floor_decal/corner/white{dir = 8},/obj/effect/floor_decal/corner/blue,/turf/simulated/floor/tiled,/area/crew_quarters/visitor_dining)
@@ -8473,7 +8473,7 @@
"dgW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/engineering/engine_eva)
"dgX" = (/obj/machinery/door/airlock/glass_engineeringatmos{name = "Engineering EVA Storage"; req_one_access = list(11,24)},/obj/machinery/door/firedoor/glass,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/engineering/engine_eva)
"dgY" = (/obj/machinery/door/airlock/glass_engineeringatmos{name = "Engineering EVA Storage"; req_one_access = list(11,24)},/obj/machinery/door/firedoor/glass,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled,/area/engineering/engine_eva)
-"dgZ" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire/firefighter,/obj/item/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/clothing/glasses/meson,/obj/random/maintenance/engineering,/obj/random/maintenance/clean,/turf/simulated/floor/plating,/area/maintenance/engineering)
+"dgZ" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire,/obj/item/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/extinguisher,/obj/item/clothing/head/hardhat/firefighter,/obj/item/clothing/glasses/meson,/obj/random/maintenance/engineering,/obj/random/maintenance/clean,/turf/simulated/floor/plating,/area/maintenance/engineering)
"dha" = (/turf/simulated/floor/plating,/area/maintenance/engineering)
"dhb" = (/obj/item/t_scanner,/obj/structure/table/steel,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/maintenance/engineering)
"dhc" = (/obj/machinery/light/small{dir = 8},/obj/effect/floor_decal/industrial/warning{dir = 10},/turf/simulated/floor,/area/hallway/secondary/escape/dock_escape_pod_hallway_port)
@@ -9196,7 +9196,7 @@
"duR" = (/obj/machinery/atmospherics/portables_connector,/obj/effect/floor_decal/industrial/outline/yellow,/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/tiled,/area/engineering/aft_hallway)
"duS" = (/obj/machinery/computer/shuttle_control/engineering{name = "engineering elevator control console"},/turf/simulated/floor/tiled,/area/engineering/aft_hallway)
"duT" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/engineering/aft_hallway)
-"duU" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire/firefighter,/obj/item/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/clothing/glasses/meson,/obj/effect/floor_decal/industrial/warning/corner,/turf/simulated/floor/tiled,/area/engineering/aft_hallway)
+"duU" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire,/obj/item/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/extinguisher,/obj/item/clothing/head/hardhat/firefighter,/obj/item/clothing/glasses/meson,/obj/effect/floor_decal/industrial/warning/corner,/turf/simulated/floor/tiled,/area/engineering/aft_hallway)
"duV" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/tiled,/area/engineering/aft_hallway)
"duW" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled,/area/engineering/aft_hallway)
"duX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled,/area/engineering/aft_hallway)
diff --git a/maps/southern_cross/southern_cross-1.dmm b/maps/southern_cross/southern_cross-1.dmm
index dc71f08563..762bef8e66 100644
--- a/maps/southern_cross/southern_cross-1.dmm
+++ b/maps/southern_cross/southern_cross-1.dmm
@@ -44149,7 +44149,7 @@
/obj/structure/table/rack{
dir = 1
},
-/obj/item/clothing/suit/fire/firefighter,
+/obj/item/clothing/suit/fire,
/obj/item/tank/oxygen,
/obj/item/clothing/mask/gas,
/obj/item/extinguisher,
@@ -58448,7 +58448,7 @@
/obj/structure/table/rack{
dir = 1
},
-/obj/item/clothing/suit/fire/firefighter,
+/obj/item/clothing/suit/fire,
/obj/item/tank/oxygen,
/obj/item/clothing/mask/gas,
/obj/item/extinguisher,
@@ -65655,7 +65655,7 @@
/obj/structure/table/rack{
dir = 1
},
-/obj/item/clothing/suit/fire/firefighter,
+/obj/item/clothing/suit/fire,
/obj/item/tank/oxygen,
/obj/item/clothing/mask/gas,
/obj/item/extinguisher,
@@ -70188,7 +70188,7 @@
/obj/structure/table/rack{
dir = 1
},
-/obj/item/clothing/suit/fire/firefighter,
+/obj/item/clothing/suit/fire,
/obj/item/tank/oxygen,
/obj/item/clothing/mask/gas,
/obj/item/extinguisher,
@@ -93813,7 +93813,7 @@
/obj/structure/table/rack{
dir = 1
},
-/obj/item/clothing/suit/fire/firefighter,
+/obj/item/clothing/suit/fire,
/obj/item/tank/oxygen,
/obj/item/clothing/mask/gas,
/obj/item/extinguisher,
diff --git a/maps/submaps/surface_submaps/mountains/deadspy.dmm b/maps/submaps/surface_submaps/mountains/deadspy.dmm
index df4dfcc5f0..54fbde84e4 100644
--- a/maps/submaps/surface_submaps/mountains/deadspy.dmm
+++ b/maps/submaps/surface_submaps/mountains/deadspy.dmm
@@ -1,4 +1,4 @@
-"a" = (/obj/effect/decal/remains/xeno,/obj/item/clothing/mask/gas,/obj/item/clothing/suit/fire/firefighter,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/deadspy)
+"a" = (/obj/effect/decal/remains/xeno,/obj/item/clothing/mask/gas,/obj/item/clothing/suit/fire/atmos,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/deadspy)
"b" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/deadspy)
"c" = (/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel,/obj/effect/decal/cleanable/molten_item,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/deadspy)
"d" = (/obj/item/flamethrower,/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/deadspy)
diff --git a/maps/submaps/surface_submaps/mountains/vault5.dmm b/maps/submaps/surface_submaps/mountains/vault5.dmm
index 254093aae9..d5a4ecbe62 100644
--- a/maps/submaps/surface_submaps/mountains/vault5.dmm
+++ b/maps/submaps/surface_submaps/mountains/vault5.dmm
@@ -14,7 +14,7 @@
"d" = (
/obj/effect/alien/weeds,
/obj/structure/bed/nest,
-/obj/random/handgun,
+/obj/random/sidearm,
/turf/simulated/mineral/floor/ignore_mapgen,
/area/submap/cave/vault5)
"e" = (