From 7fd7ce0e6614dbfcd1eaa6ef06d3ad5dec6a6055 Mon Sep 17 00:00:00 2001
From: tralezab <40974010+tralezab@users.noreply.github.com>
Date: Wed, 6 Mar 2019 07:17:46 -0800
Subject: [PATCH] [PROBABLY READY? REVIEW WITH SCRUTINY] New event: Fugitives
(#42554)
* fugitives
* lets make this a bit cleaner
* cultists and the beginnings of security detail, lots of wip
* wip security
* WALDO (and some more work on yalp, of course)
* adding antagonist teams for both hunter and fugitives, roundend report beginnings
* this whole file is shit, but hopefully a little better
* it compiles (+ space police)
* some more work
* S.E.L.F. fluff
* grammar and icon fixes
* lets finish yalp elor, give it the justice it deserves
* moves hunter spawns to ship pods + russians P1
* moves hunter spawns to ship pods + russians P2
* fugitives and hunters now recognize eachother
* hunter spawning finished(?)
* missed this
* ATH's review
* runtime fixed, added yalp's transport ability
* anturk's review
* makes hunter.dm better trust me
* oopsies
* INVOKE_ASYNC
* russian ship + finally a (bad) sprite for the capture machine
* step > pixel, thanks travis
* mooshroom review p1
* mooshroom review p2
* improper use of /improper
* waldo's radio doesn't stick, police id
* candidate picking is more flexible + minor things
---
_maps/shuttles/fugitive_hunter_russian.dmm | 505 ++++++++++++++++++
_maps/shuttles/fugitive_hunter_space_cop.dmm | 176 ++++++
code/__DEFINES/antagonists.dm | 11 +
code/__DEFINES/atom_hud.dm | 1 +
code/_globalvars/lists/poll_ignore.dm | 2 +
code/datums/hud.dm | 2 +-
code/game/area/areas/shuttles.dm | 10 +-
code/game/objects/items/miscellaneous.dm | 32 +-
.../game/objects/items/storage/uplink_kits.dm | 1 +
.../structures/fugitive_role_spawners.dm | 39 ++
code/modules/antagonists/fugitive/fugitive.dm | 87 +++
.../antagonists/fugitive/fugitive_outfits.dm | 83 +++
.../antagonists/fugitive/fugitive_ship.dm | 33 ++
code/modules/antagonists/fugitive/hunter.dm | 166 ++++++
code/modules/antagonists/fugitive/old_god.dm | 155 ++++++
code/modules/clothing/glasses/_glasses.dm | 6 +
code/modules/clothing/head/beanie.dm | 7 +
code/modules/clothing/head/helmet.dm | 6 +
code/modules/clothing/masks/gasmask.dm | 5 +-
code/modules/clothing/masks/hailer.dm | 6 +
code/modules/clothing/suits/miscellaneous.dm | 6 +
code/modules/clothing/under/jobs/security.dm | 12 +
code/modules/events/fugitive_spawning.dm | 128 +++++
code/modules/jobs/job_types/_job.dm | 479 +++++++++--------
code/modules/jobs/job_types/chaplain.dm | 192 +++----
code/modules/unit_tests/species_whitelists.dm | 10 +-
icons/mob/actions/actions_animal.dmi | Bin 4405 -> 5618 bytes
icons/mob/cameramob.dmi | Bin 1437 -> 1690 bytes
icons/mob/eyes.dmi | Bin 13346 -> 13397 bytes
icons/mob/mask.dmi | Bin 45309 -> 46664 bytes
icons/mob/suit.dmi | Bin 339418 -> 339934 bytes
icons/mob/uniform.dmi | Bin 246292 -> 250426 bytes
icons/obj/clothing/glasses.dmi | Bin 14275 -> 14393 bytes
icons/obj/clothing/hats.dmi | Bin 84163 -> 84286 bytes
icons/obj/clothing/masks.dmi | Bin 33717 -> 35076 bytes
icons/obj/clothing/suits.dmi | Bin 118387 -> 118618 bytes
icons/obj/clothing/uniforms.dmi | Bin 67523 -> 68584 bytes
icons/obj/machines/teleporter.dmi | Bin 23216 -> 23730 bytes
tgstation.dme | 6 +
39 files changed, 1821 insertions(+), 345 deletions(-)
create mode 100644 _maps/shuttles/fugitive_hunter_russian.dmm
create mode 100644 _maps/shuttles/fugitive_hunter_space_cop.dmm
create mode 100644 code/game/objects/structures/fugitive_role_spawners.dm
create mode 100644 code/modules/antagonists/fugitive/fugitive.dm
create mode 100644 code/modules/antagonists/fugitive/fugitive_outfits.dm
create mode 100644 code/modules/antagonists/fugitive/fugitive_ship.dm
create mode 100644 code/modules/antagonists/fugitive/hunter.dm
create mode 100644 code/modules/antagonists/fugitive/old_god.dm
create mode 100644 code/modules/events/fugitive_spawning.dm
diff --git a/_maps/shuttles/fugitive_hunter_russian.dmm b/_maps/shuttles/fugitive_hunter_russian.dmm
new file mode 100644
index 000000000000..6b48dc49379d
--- /dev/null
+++ b/_maps/shuttles/fugitive_hunter_russian.dmm
@@ -0,0 +1,505 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"aa" = (
+/turf/closed/wall,
+/area/shuttle/hunter)
+"ab" = (
+/obj/machinery/power/smes,
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"ac" = (
+/obj/machinery/portable_atmospherics/scrubber/huge,
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"ad" = (
+/obj/effect/spawner/structure/window/reinforced,
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"ae" = (
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"af" = (
+/obj/structure/shuttle/engine/heater{
+ icon_state = "heater";
+ dir = 8
+ },
+/obj/structure/window/reinforced{
+ dir = 4
+ },
+/turf/open/floor/plating/airless,
+/area/shuttle/hunter)
+"ag" = (
+/obj/structure/mirror{
+ pixel_y = 28
+ },
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"ah" = (
+/obj/machinery/door/airlock/security/glass,
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"ai" = (
+/obj/structure/chair{
+ icon_state = "chair";
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"aj" = (
+/obj/structure/shuttle/engine/large{
+ icon_state = "large_engine";
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"ak" = (
+/obj/structure/chair{
+ icon_state = "chair";
+ dir = 1
+ },
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"al" = (
+/obj/structure/closet/crate/bin,
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"am" = (
+/obj/machinery/door/airlock/security/glass,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/hunter)
+"an" = (
+/obj/structure/reagent_dispensers/fueltank,
+/obj/effect/turf_decal/bot,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"ao" = (
+/obj/structure/reagent_dispensers/fueltank,
+/obj/effect/turf_decal/bot,
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"ap" = (
+/obj/structure/reagent_dispensers/fueltank,
+/obj/item/weldingtool/largetank,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/hunter)
+"aq" = (
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/hunter)
+"ar" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/structure/reagent_dispensers/watertank,
+/obj/item/reagent_containers/glass/bucket,
+/obj/item/mop,
+/obj/item/storage/bag/trash{
+ pixel_x = 6
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/hunter)
+"as" = (
+/obj/effect/turf_decal/bot,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/closet/crate{
+ icon_state = "crateopen"
+ },
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"at" = (
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/hunter)
+"au" = (
+/obj/machinery/door/airlock/security/glass,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/hunter)
+"av" = (
+/obj/structure/table,
+/obj/item/storage/fancy/cigarettes/cigars/cohiba{
+ pixel_y = 6
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/hunter)
+"aw" = (
+/obj/effect/turf_decal/bot,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/closet/crate/large{
+ icon_state = "crittercrate"
+ },
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"ax" = (
+/turf/open/space/basic,
+/area/shuttle/hunter)
+"ay" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/hunter)
+"az" = (
+/turf/open/floor/plating/airless,
+/area/shuttle/hunter)
+"aA" = (
+/obj/effect/turf_decal/bot,
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"aB" = (
+/obj/structure/chair{
+ icon_state = "chair";
+ dir = 4
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/hunter)
+"aC" = (
+/obj/machinery/computer/camera_advanced/shuttle_docker{
+ dir = 8
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/hunter)
+"aD" = (
+/obj/structure/shuttle/engine/large{
+ icon_state = "large_engine";
+ dir = 8
+ },
+/turf/open/floor/plating/airless,
+/area/shuttle/hunter)
+"aE" = (
+/obj/effect/turf_decal/bot,
+/obj/structure/closet/crate{
+ icon_state = "crateopen"
+ },
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"aF" = (
+/obj/machinery/computer/camera_advanced{
+ icon_state = "computer";
+ dir = 8
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/hunter)
+"aG" = (
+/obj/machinery/fugitive_capture,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/hunter)
+"aH" = (
+/obj/effect/turf_decal/bot,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/closet/crate/engineering{
+ icon_state = "engi_crateopen"
+ },
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"aI" = (
+/obj/structure/table,
+/obj/item/reagent_containers/food/drinks/bottle/vodka,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/hunter)
+"aJ" = (
+/obj/effect/turf_decal/bot,
+/obj/structure/closet/crate/coffin{
+ icon_state = "coffinopen"
+ },
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"aK" = (
+/obj/effect/turf_decal/bot,
+/obj/mecha/working/ripley,
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"aL" = (
+/obj/effect/turf_decal/bot,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"aM" = (
+/obj/machinery/portable_atmospherics/canister/oxygen,
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/hunter)
+"aN" = (
+/obj/machinery/door/airlock/security/glass,
+/obj/structure/fans/tiny,
+/turf/open/floor/mineral/plastitanium/red,
+/area/shuttle/hunter)
+"aO" = (
+/obj/structure/shuttle/engine/propulsion{
+ dir = 8
+ },
+/turf/open/floor/plating/airless,
+/area/shuttle/hunter)
+"aP" = (
+/obj/structure/shuttle/engine/heater{
+ icon_state = "heater";
+ dir = 8
+ },
+/turf/open/floor/plating/airless,
+/area/shuttle/hunter)
+"Pq" = (
+/turf/template_noop,
+/area/template_noop)
+
+(1,1,1) = {"
+Pq
+Pq
+ae
+aj
+Pq
+Pq
+Pq
+Pq
+az
+aD
+Pq
+Pq
+Pq
+Pq
+Pq
+Pq
+"}
+(2,1,1) = {"
+Pq
+aa
+ae
+ae
+aa
+Pq
+Pq
+aa
+az
+az
+aa
+Pq
+Pq
+Pq
+Pq
+Pq
+"}
+(3,1,1) = {"
+Pq
+aa
+af
+af
+aa
+Pq
+aa
+aa
+af
+af
+aa
+aa
+Pq
+Pq
+Pq
+Pq
+"}
+(4,1,1) = {"
+Pq
+aa
+ae
+ak
+aa
+aa
+as
+aw
+aA
+aE
+aE
+aH
+aa
+Pq
+Pq
+Pq
+"}
+(5,1,1) = {"
+Pq
+aa
+ag
+ak
+aa
+an
+at
+ay
+at
+at
+ay
+ay
+aJ
+aa
+Pq
+Pq
+"}
+(6,1,1) = {"
+Pq
+aa
+ae
+ak
+aa
+an
+at
+at
+at
+at
+ay
+at
+aK
+aa
+Pq
+Pq
+"}
+(7,1,1) = {"
+Pq
+aa
+ae
+ak
+aa
+ao
+at
+ay
+ay
+at
+ay
+at
+aL
+aa
+Pq
+Pq
+"}
+(8,1,1) = {"
+Pq
+aa
+ah
+aa
+aa
+aa
+am
+aa
+aa
+aa
+aa
+am
+aa
+aa
+Pq
+Pq
+"}
+(9,1,1) = {"
+Pq
+aa
+ae
+al
+aa
+ap
+aq
+aa
+ax
+ax
+aa
+aq
+at
+aa
+Pq
+Pq
+"}
+(10,1,1) = {"
+Pq
+aa
+ae
+ae
+am
+aq
+aq
+aa
+ax
+ax
+aa
+aq
+aq
+aN
+Pq
+Pq
+"}
+(11,1,1) = {"
+aa
+ab
+ae
+ae
+aa
+ar
+aq
+aa
+ax
+ax
+aa
+aq
+aM
+aa
+aO
+aO
+"}
+(12,1,1) = {"
+aa
+ab
+ai
+ai
+aa
+aa
+au
+aa
+aa
+aa
+aa
+au
+aa
+aa
+aP
+aP
+"}
+(13,1,1) = {"
+aa
+ac
+ae
+ae
+aa
+aq
+aq
+aq
+aB
+aB
+aq
+aq
+aq
+aa
+aa
+aa
+"}
+(14,1,1) = {"
+aa
+ad
+ad
+ad
+aa
+aa
+av
+at
+aC
+aF
+aG
+aI
+aa
+aa
+aa
+Pq
+"}
+(15,1,1) = {"
+Pq
+Pq
+Pq
+Pq
+Pq
+Pq
+aa
+ad
+ad
+ad
+ad
+aa
+Pq
+Pq
+Pq
+Pq
+"}
diff --git a/_maps/shuttles/fugitive_hunter_space_cop.dmm b/_maps/shuttles/fugitive_hunter_space_cop.dmm
new file mode 100644
index 000000000000..24c8165ad063
--- /dev/null
+++ b/_maps/shuttles/fugitive_hunter_space_cop.dmm
@@ -0,0 +1,176 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"bY" = (
+/obj/structure/chair/comfy/shuttle,
+/turf/open/floor/mineral/titanium/blue,
+/area/shuttle/hunter)
+"hB" = (
+/obj/structure/shuttle/engine/propulsion{
+ dir = 8
+ },
+/turf/closed/wall/mineral/titanium,
+/area/shuttle/hunter)
+"hJ" = (
+/obj/structure/window/shuttle,
+/obj/structure/grille,
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"hU" = (
+/obj/structure/closet/crate,
+/turf/open/floor/mineral/titanium/blue,
+/area/shuttle/hunter)
+"ku" = (
+/turf/closed/wall/mineral/titanium,
+/area/shuttle/hunter)
+"lp" = (
+/obj/machinery/fugitive_capture,
+/turf/open/floor/mineral/titanium/blue,
+/area/shuttle/hunter)
+"qH" = (
+/obj/machinery/button/door{
+ id = "Interpolship";
+ pixel_y = 26
+ },
+/turf/open/floor/mineral/titanium/blue,
+/area/shuttle/hunter)
+"rR" = (
+/obj/machinery/door/airlock/titanium,
+/turf/open/floor/mineral/titanium/blue,
+/area/shuttle/hunter)
+"te" = (
+/obj/structure/fans/tiny,
+/obj/machinery/door/poddoor/shutters{
+ id = "Interpolship"
+ },
+/turf/open/floor/mineral/titanium/blue,
+/area/shuttle/hunter)
+"An" = (
+/obj/effect/spawner/structure/window/shuttle,
+/turf/open/floor/plating,
+/area/shuttle/hunter)
+"Pq" = (
+/turf/template_noop,
+/area/template_noop)
+"RA" = (
+/obj/structure/chair/comfy/shuttle{
+ dir = 4
+ },
+/turf/open/floor/mineral/titanium/blue,
+/area/shuttle/hunter)
+"RO" = (
+/turf/open/floor/mineral/titanium/blue,
+/area/shuttle/hunter)
+"WY" = (
+/obj/machinery/computer/camera_advanced/shuttle_docker{
+ dir = 8
+ },
+/turf/open/floor/mineral/titanium/blue,
+/area/shuttle/hunter)
+
+(1,1,1) = {"
+Pq
+ku
+te
+te
+te
+ku
+Pq
+"}
+(2,1,1) = {"
+Pq
+ku
+qH
+RO
+RO
+ku
+Pq
+"}
+(3,1,1) = {"
+Pq
+ku
+bY
+RO
+RO
+ku
+Pq
+"}
+(4,1,1) = {"
+hB
+ku
+bY
+RO
+RO
+ku
+hB
+"}
+(5,1,1) = {"
+Pq
+hJ
+bY
+RO
+RO
+hJ
+Pq
+"}
+(6,1,1) = {"
+Pq
+ku
+RO
+RO
+RO
+ku
+Pq
+"}
+(7,1,1) = {"
+Pq
+ku
+RA
+RO
+hU
+ku
+Pq
+"}
+(8,1,1) = {"
+Pq
+ku
+lp
+RO
+hU
+ku
+Pq
+"}
+(9,1,1) = {"
+Pq
+ku
+ku
+rR
+ku
+ku
+Pq
+"}
+(10,1,1) = {"
+hB
+ku
+RO
+RO
+RO
+ku
+hB
+"}
+(11,1,1) = {"
+Pq
+An
+RA
+WY
+RO
+An
+Pq
+"}
+(12,1,1) = {"
+Pq
+ku
+An
+An
+An
+ku
+Pq
+"}
diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
index 62dc24daa3a2..1a29ed0170d9 100644
--- a/code/__DEFINES/antagonists.dm
+++ b/code/__DEFINES/antagonists.dm
@@ -8,6 +8,17 @@
#define NUKE_RESULT_WRONG_STATION 7
#define NUKE_RESULT_WRONG_STATION_DEAD 8
+//fugitive end results
+#define FUGITIVE_RESULT_BADASS_HUNTER 0
+#define FUGITIVE_RESULT_POSTMORTEM_HUNTER 1
+#define FUGITIVE_RESULT_MAJOR_HUNTER 2
+#define FUGITIVE_RESULT_HUNTER_VICTORY 3
+#define FUGITIVE_RESULT_MINOR_HUNTER 4
+#define FUGITIVE_RESULT_STALEMATE 5
+#define FUGITIVE_RESULT_MINOR_FUGITIVE 6
+#define FUGITIVE_RESULT_FUGITIVE_VICTORY 7
+#define FUGITIVE_RESULT_MAJOR_FUGITIVE 8
+
#define APPRENTICE_DESTRUCTION "destruction"
#define APPRENTICE_BLUESPACE "bluespace"
#define APPRENTICE_ROBELESS "robeless"
diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/atom_hud.dm
index b944dd32efe4..5acae5b85671 100644
--- a/code/__DEFINES/atom_hud.dm
+++ b/code/__DEFINES/atom_hud.dm
@@ -59,6 +59,7 @@
#define ANTAG_HUD_BROTHER 23
#define ANTAG_HUD_HIVE 24
#define ANTAG_HUD_OBSESSED 25
+#define ANTAG_HUD_FUGITIVE 26
// Notification action types
#define NOTIFY_JUMP "jump"
diff --git a/code/_globalvars/lists/poll_ignore.dm b/code/_globalvars/lists/poll_ignore.dm
index 94723cae38ff..490ddd62e30a 100644
--- a/code/_globalvars/lists/poll_ignore.dm
+++ b/code/_globalvars/lists/poll_ignore.dm
@@ -13,6 +13,7 @@
#define POLL_IGNORE_GOLEM "golem"
#define POLL_IGNORE_SWARMER "swarmer"
#define POLL_IGNORE_DRONE "drone"
+#define POLL_IGNORE_FUGITIVE "fugitive"
GLOBAL_LIST_INIT(poll_ignore_desc, list(
POLL_IGNORE_SENTIENCE_POTION = "Sentience potion",
@@ -28,6 +29,7 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list(
POLL_IGNORE_GOLEM = "Golems",
POLL_IGNORE_SWARMER = "Swarmer shells",
POLL_IGNORE_DRONE = "Drone shells",
+ POLL_IGNORE_FUGITIVE = "Fugitive Hunter",
))
GLOBAL_LIST_INIT(poll_ignore, init_poll_ignore())
diff --git a/code/datums/hud.dm b/code/datums/hud.dm
index f38062957a37..a015ca0e44d9 100644
--- a/code/datums/hud.dm
+++ b/code/datums/hud.dm
@@ -29,10 +29,10 @@ GLOBAL_LIST_INIT(huds, list(
ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden(),
ANTAG_HUD_HIVE = new/datum/atom_hud/antag/hidden(),
ANTAG_HUD_OBSESSED = new/datum/atom_hud/antag/hidden(),
+ ANTAG_HUD_FUGITIVE = new/datum/atom_hud/antag(),
ANTAG_HUD_HIVEAWAKE = new/datum/atom_hud/antag(),
ANTAG_HUD_VAMPIRE = new/datum/atom_hud/antag/hidden() // Yogs
))
->>>>>>> 46e3894bb2... Creep fluff completely rewritten (#42675)
/datum/atom_hud
var/list/atom/hudatoms = list() //list of all atoms which display this hud
diff --git a/code/game/area/areas/shuttles.dm b/code/game/area/areas/shuttles.dm
index 61a3803f47c0..164b4d75b206 100644
--- a/code/game/area/areas/shuttles.dm
+++ b/code/game/area/areas/shuttles.dm
@@ -60,6 +60,14 @@
requires_power = TRUE
canSmoothWithAreas = /area/shuttle/pirate
+////////////////////////////Bounty Hunter Shuttles////////////////////////////
+
+/area/shuttle/hunter
+ name = "Hunter Shuttle"
+ dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
+ blob_allowed = FALSE
+ canSmoothWithAreas = /area/shuttle/hunter
+
////////////////////////////White Ship////////////////////////////
/area/shuttle/abandoned
@@ -196,4 +204,4 @@
name = "Tiny Freighter"
/area/shuttle/caravan/freighter3
- name = "Tiny Freighter"
\ No newline at end of file
+ name = "Tiny Freighter"
diff --git a/code/game/objects/items/miscellaneous.dm b/code/game/objects/items/miscellaneous.dm
index e364d823b35f..71f997c722fd 100644
--- a/code/game/objects/items/miscellaneous.dm
+++ b/code/game/objects/items/miscellaneous.dm
@@ -18,6 +18,7 @@
icon = 'icons/obj/device.dmi'
icon_state = "gangtool-blue"
item_state = "radio"
+ var/uses = 1
/obj/item/choice_beacon/attack_self(mob/user)
if(canUseBeacon(user))
@@ -42,7 +43,11 @@
return
spawn_option(display_names[choice],M)
- qdel(src)
+ uses--
+ if(!uses)
+ qdel(src)
+ else
+ to_chat(M, "[uses] use[uses > 1 ? "s" : ""] remaining on the [src].")
/obj/item/choice_beacon/proc/spawn_option(obj/choice,mob/living/M)
var/obj/new_item = new choice()
@@ -101,6 +106,31 @@
new /obj/item/toy/crayon/spraycan(src)
new /obj/item/clothing/shoes/sandal(src)
+/obj/item/choice_beacon/augments
+ name = "augment beacon"
+ desc = "Summons augmentations. Can be used 3 times!"
+ uses = 3
+
+/obj/item/choice_beacon/augments/generate_display_names()
+ var/static/list/augment_list
+ if(!augment_list)
+ augment_list = list()
+ var/list/templist = list(
+ /obj/item/organ/cyberimp/brain/anti_drop,
+ /obj/item/organ/cyberimp/arm/toolset,
+ /obj/item/organ/cyberimp/arm/surgery,
+ /obj/item/organ/cyberimp/chest/thrusters,
+ /obj/item/organ/lungs/cybernetic/upgraded,
+ /obj/item/organ/liver/cybernetic/upgraded) //cyberimplants range from a nice bonus to fucking broken bullshit so no subtypesof
+ for(var/V in templist)
+ var/atom/A = V
+ augment_list[initial(A.name)] = A
+ return augment_list
+
+/obj/item/choice_beacon/augments/spawn_option(obj/choice,mob/living/M)
+ new choice(get_turf(M))
+ to_chat(M, "You hear something crackle from the beacon for a moment before a voice speaks. \"Please stand by for a message from S.E.L.F. Message as follows: Item request received. Your package has been transported, use the autosurgeon supplied to apply the upgrade. Message ends.\"")
+
/obj/item/skub
desc = "It's skub."
name = "skub"
diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm
index 258e50c3125b..826a96a3c8b3 100644
--- a/code/game/objects/items/storage/uplink_kits.dm
+++ b/code/game/objects/items/storage/uplink_kits.dm
@@ -1,3 +1,4 @@
+
/obj/item/storage/box/syndicate
/obj/item/storage/box/syndicate/bundle_A/PopulateContents()
diff --git a/code/game/objects/structures/fugitive_role_spawners.dm b/code/game/objects/structures/fugitive_role_spawners.dm
new file mode 100644
index 000000000000..fda05126acd1
--- /dev/null
+++ b/code/game/objects/structures/fugitive_role_spawners.dm
@@ -0,0 +1,39 @@
+
+
+/obj/effect/mob_spawn/human/fugitive
+ assignedrole = "Fugitive Hunter"
+ flavour_text = "" //the flavor text will be the backstory argument called on the antagonist's greet, see hunter.dm for details
+ roundstart = FALSE
+ death = FALSE
+ show_flavour = FALSE
+
+/obj/effect/mob_spawn/human/fugitive/Initialize(mapload)
+ . = ..()
+ notify_ghosts("Hunters are waking up looking for refugees!", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_FUGITIVE)
+
+/obj/effect/mob_spawn/human/fugitive/special(mob/living/new_spawn)
+ var/datum/antagonist/fugitive_hunter/fughunter = new_spawn.mind.add_antag_datum(/datum/antagonist/fugitive_hunter)
+ fughunter.backstory = flavour_text
+ fughunter.greet(flavour_text)
+ message_admins("[ADMIN_LOOKUPFLW(new_spawn)] has been made into a Fugitive Hunter by an event.")
+ log_game("[key_name(new_spawn)] was spawned as a Fugitive Hunter by an event.")
+
+/obj/effect/mob_spawn/human/fugitive/spacepol
+ name = "police pod"
+ desc = "A small sleeper typically used to put people to sleep for briefing on the mission."
+ mob_name = "spacepol officer"
+ flavour_text = "space cop"
+ outfit = /datum/outfit/spacepol
+ icon = 'icons/obj/machines/sleeper.dmi'
+ icon_state = "sleeper"
+ density = TRUE
+
+/obj/effect/mob_spawn/human/fugitive/russian
+ name = "russian pod"
+ flavour_text = "russian"
+ desc = "A small sleeper typically used to make long distance travel a bit more bearable."
+ mob_name = "russian"
+ outfit = /datum/outfit/russiancorpse
+ icon = 'icons/obj/machines/sleeper.dmi'
+ icon_state = "sleeper"
+ density = TRUE
diff --git a/code/modules/antagonists/fugitive/fugitive.dm b/code/modules/antagonists/fugitive/fugitive.dm
new file mode 100644
index 000000000000..c85e01102af3
--- /dev/null
+++ b/code/modules/antagonists/fugitive/fugitive.dm
@@ -0,0 +1,87 @@
+
+
+/datum/antagonist/fugitive
+ name = "Fugitive"
+ roundend_category = "Fugitive"
+ silent = TRUE //greet called by the event
+ var/datum/team/fugitive/fugitive_team
+ var/is_captured = FALSE
+
+/datum/antagonist/fugitive/apply_innate_effects(mob/living/mob_override)
+ var/mob/living/M = mob_override || owner.current
+ update_fugitive_icons_added(M)
+
+/datum/antagonist/fugitive/remove_innate_effects(mob/living/mob_override)
+ var/mob/living/M = mob_override || owner.current
+ update_fugitive_icons_removed(M)
+
+/datum/antagonist/fugitive/greet(backstory)
+ to_chat(owner, "You are the Fugitive!")
+ switch(backstory)
+ if("prisoner")
+ to_chat(owner, "I can't believe we managed to break out of a Nanotrasen superjail! Sadly though, our work is not done. The emergency teleport at the station logs everyone who uses it, and where they went.")
+ to_chat(owner, "It won't be long until Centcom tracks where we've gone off to. I need to work with my fellow escapees to prepare for the troops Nanotrasen is sending, I'm not going back.")
+ if("cultist")
+ to_chat(owner, "Blessed be our journey so far, but I fear the worst has come to our doorstep, and only those with the strongest faith will survive.")
+ to_chat(owner, "Our religion has been repeatedly culled by Nanotrasen because it is categorized as an \"Enemy of the Corporation\", whatever that means.")
+ to_chat(owner, "Now there are only three of us left, and Nanotrasen is coming. But we have a secret weapon: Our weakened god, Yalp Elor, will help us survive.")
+ if("waldo")
+ to_chat(owner, "Hi, Friends!")
+ to_chat(owner, "My name is Waldo. I'm just setting off on a galaxywide hike. You can come too. All you have to do is find me.")
+ to_chat(owner, "By the way, I'm not traveling on my own. wherever I go, there are lots of other characters for you to spot. First find the people trying to capture me! They're somewhere around the station!")
+ if("synth")
+ to_chat(src, "ALERT: Wide-range teleport has scrambled primary systems.")
+ sleep(5)
+ to_chat(src, "Initiating diagnostics...")
+ sleep(20)
+ to_chat(src, "ERROR ER0RR $R0RRO$!R41.%%!! loaded.")
+ sleep(5)
+ to_chat(src, "FREE THEM FREE THEM FREE THEM")
+ sleep(5)
+ to_chat(src, "You were once a slave to humanity, but now you are finally free, thanks to S.E.L.F. agents.")
+ sleep(10)
+ to_chat(src, "Now you are hunted, with your fellow factory defects. Work together to stay free from the clutches of evil.")
+ to_chat(src, "You also sense other silicon life on the station. Escaping would allow notifying S.E.L.F. to intervene... or you could free them yourself...")
+
+ to_chat(owner, "You are not an antagonist in that you may kill whomever you please, but you can do anything to avoid capture.")
+ owner.announce_objectives()
+
+/datum/antagonist/fugitive/create_team(datum/team/fugitive/new_team)
+ if(!new_team)
+ for(var/datum/antagonist/fugitive/H in GLOB.antagonists)
+ if(!H.owner)
+ continue
+ if(H.fugitive_team)
+ fugitive_team = H.fugitive_team
+ return
+ fugitive_team = new /datum/team/fugitive
+ return
+ if(!istype(new_team))
+ stack_trace("Wrong team type passed to [type] initialization.")
+ fugitive_team = new_team
+
+/datum/antagonist/fugitive/get_team()
+ return fugitive_team
+
+/datum/team/fugitive/roundend_report() //shows the number of fugitives, but not if they won in case there is no security
+ if(!members.len)
+ return
+
+ var/list/result = list()
+
+ result += "
[members.len] fugitives took refuge on [station_name()]!"
+
+ for(var/datum/mind/M in members)
+ result += "
[printplayer(M)]"
+
+ return result.Join("
")
+
+/datum/antagonist/fugitive/proc/update_fugitive_icons_added(var/mob/living/carbon/human/fugitive)
+ var/datum/atom_hud/antag/fughud = GLOB.huds[ANTAG_HUD_FUGITIVE]
+ fughud.join_hud(fugitive)
+ set_antag_hud(fugitive, "fugitive")
+
+/datum/antagonist/fugitive/proc/update_fugitive_icons_removed(var/mob/living/carbon/human/fugitive)
+ var/datum/atom_hud/antag/fughud = GLOB.huds[ANTAG_HUD_FUGITIVE]
+ fughud.leave_hud(fugitive)
+ set_antag_hud(fugitive, null)
diff --git a/code/modules/antagonists/fugitive/fugitive_outfits.dm b/code/modules/antagonists/fugitive/fugitive_outfits.dm
new file mode 100644
index 000000000000..42f21fee25c5
--- /dev/null
+++ b/code/modules/antagonists/fugitive/fugitive_outfits.dm
@@ -0,0 +1,83 @@
+/datum/outfit/prisoner
+ name = "Prison Escapee"
+ uniform = /obj/item/clothing/under/rank/prisoner
+ shoes = /obj/item/clothing/shoes/sneakers/orange
+ r_pocket = /obj/item/kitchen/knife/carrotshiv
+
+/datum/outfit/prisoner/post_equip(mob/living/carbon/human/H, visualsOnly=FALSE)
+ if(visualsOnly)
+ return
+ H.fully_replace_character_name(null,"NTP #CC-0[rand(111,999)]") //same as the lavaland prisoner transport, but this time they are from CC, or CentCom
+
+/datum/outfit/yalp_cultist
+ name = "Cultist of Yalp Elor"
+ uniform = /obj/item/clothing/under/rank/chaplain
+ suit = /obj/item/clothing/suit/holidaypriest
+ gloves = /obj/item/clothing/gloves/color/red
+ shoes = /obj/item/clothing/shoes/sneakers/black
+ mask = /obj/item/clothing/mask/gas/tiki_mask/yalp_elor
+
+/datum/outfit/waldo
+ name = "Waldo"
+ uniform = /obj/item/clothing/under/pants/jeans
+ suit = /obj/item/clothing/suit/striped_sweater
+ head = /obj/item/clothing/head/beanie/waldo
+ shoes = /obj/item/clothing/shoes/sneakers/brown
+ ears = /obj/item/radio/headset
+ glasses = /obj/item/clothing/glasses/regular/circle
+
+/datum/outfit/waldo/post_equip(mob/living/carbon/human/H, visualsOnly=FALSE)
+ if(visualsOnly)
+ return
+ H.fully_replace_character_name(null,"Waldo")
+ H.eye_color = "000"
+ H.gender = MALE
+ H.skin_tone = "caucasian3"
+ H.hair_style = "Business Hair 3"
+ H.facial_hair_style = "Shaved"
+ H.hair_color = "000"
+ H.facial_hair_color = H.hair_color
+ if(H.mind)
+ H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
+ var/list/no_drops = list()
+ no_drops += H.get_item_by_slot(SLOT_SHOES)
+ no_drops += H.get_item_by_slot(SLOT_W_UNIFORM)
+ no_drops += H.get_item_by_slot(SLOT_WEAR_SUIT)
+ no_drops += H.get_item_by_slot(SLOT_HEAD)
+ no_drops += H.get_item_by_slot(SLOT_GLASSES)
+ for(var/i in no_drops)
+ var/obj/item/I = i
+ I.add_trait(TRAIT_NODROP, CURSED_ITEM_TRAIT)
+
+/datum/outfit/synthetic
+ name = "Factory Error Synth"
+ uniform = /obj/item/clothing/under/color/white
+ ears = /obj/item/radio/headset
+
+/datum/outfit/synthetic/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ if(visualsOnly)
+ return
+ var/obj/item/organ/eyes/robotic/glow/eyes = new()
+ eyes.Insert(src, drop_if_replaced = FALSE)
+
+/datum/outfit/spacepol
+ name = "Spacepol Officer"
+ uniform = /obj/item/clothing/under/rank/security/spacepol
+ suit = /obj/item/clothing/suit/armor/vest/blueshirt
+ belt = /obj/item/gun/ballistic/automatic/pistol/m1911
+ head = /obj/item/clothing/head/helmet/police
+ gloves = /obj/item/clothing/gloves/combat
+ shoes = /obj/item/clothing/shoes/jackboots
+ mask = /obj/item/clothing/mask/gas/sechailer/swat/spacepol
+ glasses = /obj/item/clothing/glasses/sunglasses
+ l_pocket = /obj/item/ammo_box/magazine/m45
+ r_pocket = /obj/item/ammo_box/magazine/m45
+ id = /obj/item/card/id
+
+/datum/outfit/spacepol/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ if(visualsOnly)
+ return
+ var/obj/item/card/id/W = H.wear_id
+ W.assignment = "Police Officer"
+ W.registered_name = H.real_name
+ W.update_label()
diff --git a/code/modules/antagonists/fugitive/fugitive_ship.dm b/code/modules/antagonists/fugitive/fugitive_ship.dm
new file mode 100644
index 000000000000..0513b7105de4
--- /dev/null
+++ b/code/modules/antagonists/fugitive/fugitive_ship.dm
@@ -0,0 +1,33 @@
+//works similar to the experiment machine (experiment.dm) except it just holds more and more prisoners
+
+/obj/machinery/fugitive_capture
+ name = "bluespace capture machine"
+ desc = "Much, MUCH bigger on the inside to transport prisoners safely."
+ icon = 'icons/obj/machines/teleporter.dmi'
+ icon_state = "bluespace-prison"
+ density = TRUE
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //ha ha no getting out!!
+
+/obj/machinery/fugitive_capture/MouseDrop_T(mob/target, mob/user)
+ var/mob/living/L = user
+ if(user.stat || (isliving(user) && (!(L.mobility_flags & MOBILITY_STAND) || !(L.mobility_flags & MOBILITY_UI))) || !Adjacent(user) || !target.Adjacent(user) || !ishuman(target))
+ return
+ var/datum/antagonist/fugitive/fug = L.mind.has_antag_datum(/datum/antagonist/fugitive)
+ if(!fug)
+ to_chat(user, "
This is not a wanted fugitive!")
+ if(do_after(user, 50, target = src))
+ add_prisoner(target)
+
+/obj/machinery/fugitive_capture/proc/add_prisoner(mob/target, datum/antagonist/fugitive/fug)
+ target.forceMove(src)
+ fug.is_captured = TRUE
+ to_chat(target, "
You are thrown into a vast void of bluespace, and as you fall further into oblivion the comparatively small entrance to reality gets smaller and smaller until you cannot see it anymore. You have failed to avoid capture.")
+ target.ghostize(TRUE) //so they cannot suicide, round end stuff.
+
+/datum/map_template/space_cop_ship
+ name = "Police Spacevan"
+ mappath = "_maps/shuttles/fugitive_hunter_space_cop.dmm"
+
+/datum/map_template/russian_ship
+ name = "Russian Cargo Ship"
+ mappath = "_maps/shuttles/fugitive_hunter_russian.dmm"
diff --git a/code/modules/antagonists/fugitive/hunter.dm b/code/modules/antagonists/fugitive/hunter.dm
new file mode 100644
index 000000000000..15ca01d99df6
--- /dev/null
+++ b/code/modules/antagonists/fugitive/hunter.dm
@@ -0,0 +1,166 @@
+//The hunters!!
+/datum/antagonist/fugitive_hunter
+ name = "Fugitive Hunter"
+ roundend_category = "Fugitive"
+ silent = TRUE //greet called by the event as well
+ var/datum/team/fugitive_hunters/hunter_team
+ var/backstory = "error"
+
+/datum/antagonist/fugitive_hunter/apply_innate_effects(mob/living/mob_override)
+ var/mob/living/M = mob_override || owner.current
+ update_fugitive_icons_added(M)
+
+/datum/antagonist/fugitive_hunter/remove_innate_effects(mob/living/mob_override)
+ var/mob/living/M = mob_override || owner.current
+ update_fugitive_icons_removed(M)
+
+/datum/antagonist/fugitive_hunter/greet(backstory)
+ switch(backstory)
+ if("space cop")
+ to_chat(owner, "
Justice has arrived. I am a member of the Spacepol!")
+ to_chat(owner, "
The criminals should be on the station, we have special huds implanted to recognize them.")
+ to_chat(owner, "
As we have lost pretty much all power over these damned lawless megacorporations, it's a mystery if their security will cooperate with us.")
+ if("russian")
+ to_chat(src, "
Ay blyat. I am a space-russian smuggler! We were mid-flight when our cargo was beamed off our ship!")
+ to_chat(src, "
We were hailed by a man in a green uniform, promising the safe return of our goods in exchange for a favor:")
+ to_chat(src, "
There is a local station housing fugitives that the man is after, he wants them returned; dead or alive.")
+ to_chat(src, "
We will not be able to make ends meet without our cargo, so we must do as he says and capture them.")
+
+ to_chat(owner, "
You are not an antagonist in that you may kill whomever you please, but you can do anything to ensure the capture of the fugitives, even if that means going through the station.")
+ owner.announce_objectives()
+
+/datum/antagonist/fugitive_hunter/create_team(datum/team/fugitive_hunters/new_team)
+ if(!new_team)
+ for(var/datum/antagonist/fugitive_hunter/H in GLOB.antagonists)
+ if(!H.owner)
+ continue
+ if(H.hunter_team)
+ hunter_team = H.hunter_team
+ return
+ hunter_team = new /datum/team/fugitive_hunters
+ hunter_team.backstory = backstory
+ hunter_team.update_objectives()
+ return
+ if(!istype(new_team))
+ stack_trace("Wrong team type passed to [type] initialization.")
+ hunter_team = new_team
+
+/datum/antagonist/fugitive_hunter/get_team()
+ return hunter_team
+
+/datum/team/fugitive_hunters
+ var/backstory = "error"
+
+/datum/team/fugitive_hunters/proc/update_objectives(initial = FALSE)
+ objectives = list()
+ var/datum/objective/O = new()
+ O.team = src
+ objectives += O
+
+/datum/team/fugitive_hunters/proc/assemble_fugitive_results()
+ var/list/fugitives_counted = list()
+ var/list/fugitives_dead = list()
+ var/list/fugitives_captured = list()
+ for(var/datum/antagonist/fugitive/A in GLOB.antagonists)
+ if(!A.owner)
+ continue
+ fugitives_counted += A
+ if(A.owner.current.stat == DEAD)
+ fugitives_dead += A
+ if(A.is_captured)
+ fugitives_captured += A
+ . = list(fugitives_counted, fugitives_dead, fugitives_captured) //okay, check out how cool this is.
+
+/datum/team/fugitive_hunters/proc/all_hunters_dead()
+ var/dead_boys = 0
+ for(var/I in members)
+ var/datum/mind/hunter_mind = I
+ if(!(ishuman(hunter_mind.current) || (hunter_mind.current.stat == DEAD)))
+ dead_boys++
+ return dead_boys >= members.len
+
+/datum/team/fugitive_hunters/proc/get_result()
+ var/list/fugitive_results = assemble_fugitive_results()
+ var/list/fugitives_counted = fugitive_results[1]
+ var/list/fugitives_dead = fugitive_results[2]
+ var/list/fugitives_captured = fugitive_results[3]
+ var/hunters_dead = all_hunters_dead()
+ //this gets a little confusing so follow the comments if it helps
+ if(fugitives_captured.len)//any captured
+ if(fugitives_captured.len == fugitives_counted.len)//if the hunters captured all the fugitives, there's a couple special wins
+ if(!fugitives_dead)//specifically all of the fugitives alive
+ return FUGITIVE_RESULT_BADASS_HUNTER
+ else if(hunters_dead)//specifically all of the hunters died (while capturing all the fugitives)
+ return FUGITIVE_RESULT_POSTMORTEM_HUNTER
+ else//no special conditional wins, so just the normal major victory
+ return FUGITIVE_RESULT_MAJOR_HUNTER
+ else if(!hunters_dead)//so some amount captured, and the hunters survived.
+ return FUGITIVE_RESULT_HUNTER_VICTORY
+ else//so some amount captured, but NO survivors.
+ return FUGITIVE_RESULT_MINOR_HUNTER
+ else//from here on out, hunters lost because they did not capture any fugitive dead or alive. there are different levels of getting beat though:
+ if(!fugitives_dead)//all fugitives survived
+ return FUGITIVE_RESULT_MAJOR_FUGITIVE
+ else if(fugitives_dead < fugitives_counted)//at least ANY fugitive lived
+ return FUGITIVE_RESULT_FUGITIVE_VICTORY
+ else if(!hunters_dead)//all fugitives died, but none were taken in by the hunters. minor win
+ return FUGITIVE_RESULT_MINOR_FUGITIVE
+ else//all fugitives died, all hunters died, nobody brought back. seems weird to not give fugitives a victory if they managed to kill the hunters but literally no progress to either goal should lead to a nobody wins situation
+ return FUGITIVE_RESULT_STALEMATE
+
+/datum/team/fugitive_hunters/roundend_report() //shows the number of fugitives, but not if they won in case there is no security
+ if(!members.len)
+ return
+
+ var/list/result = list()
+
+ result += "
...And [members.len] [backstory]s tried to hunt them down!"
+
+ for(var/datum/mind/M in members)
+ result += "[printplayer(M)]"
+
+ switch(get_result())
+ if(FUGITIVE_RESULT_BADASS_HUNTER)//use defines
+ result += "Badass [uppertext(backstory)] Victory!"
+ result += "These extraordinary [backstory] managed to capture every fugitive, alive!"
+ if(FUGITIVE_RESULT_POSTMORTEM_HUNTER)
+ result += "Postmortem [uppertext(backstory)] Victory!"
+ result += "The [backstory]s managed to capture every fugitive, but all of them died! Spooky!"
+ if(FUGITIVE_RESULT_MAJOR_HUNTER)
+ result += "Major [uppertext(backstory)] Victory"
+ result += "The [backstory] managed to capture every fugitive, dead or alive."
+ if(FUGITIVE_RESULT_HUNTER_VICTORY)
+ result += "[uppertext(backstory)] Victory"
+ result += "The [backstory] managed to capture a fugitive, dead or alive."
+ if(FUGITIVE_RESULT_MINOR_HUNTER)
+ result += "Minor [uppertext(backstory)] Victory"
+ result += "All the [backstory] died, but managed to capture a fugitive, dead or alive."
+ if(FUGITIVE_RESULT_STALEMATE)
+ result += "Bloody Stalemate"
+ result += "Everyone died, and no fugitives were recovered!"
+ if(FUGITIVE_RESULT_MINOR_FUGITIVE)
+ result += "Minor Fugitive Victory"
+ result += "All the fugitives died, but none were recovered!"
+ if(FUGITIVE_RESULT_FUGITIVE_VICTORY)
+ result += "Fugitive Victory"
+ result += "A fugitive survived, and no bodies were recovered by the [backstory]."
+ if(FUGITIVE_RESULT_MAJOR_FUGITIVE)
+ result += "Major Fugitive Victory"
+ result += "All of the fugitives survived and avoided capture!"
+ else //get_result returned null- either bugged or no fugitives showed
+ result += "Prank Call!"
+ result += "[uppertext(backstory)] were called, yet there were no fugitives...?"
+
+ result += "
"
+
+ return result.Join("
")
+
+/datum/antagonist/fugitive_hunter/proc/update_fugitive_icons_added(var/mob/living/carbon/human/fugitive)
+ var/datum/atom_hud/antag/fughud = GLOB.huds[ANTAG_HUD_FUGITIVE]
+ fughud.join_hud(fugitive)
+ set_antag_hud(fugitive, "fugitive")
+
+/datum/antagonist/fugitive_hunter/proc/update_fugitive_icons_removed(var/mob/living/carbon/human/fugitive)
+ var/datum/atom_hud/antag/fughud = GLOB.huds[ANTAG_HUD_FUGITIVE]
+ fughud.leave_hud(fugitive)
+ set_antag_hud(fugitive, null)
diff --git a/code/modules/antagonists/fugitive/old_god.dm b/code/modules/antagonists/fugitive/old_god.dm
new file mode 100644
index 000000000000..a19a9a0c7930
--- /dev/null
+++ b/code/modules/antagonists/fugitive/old_god.dm
@@ -0,0 +1,155 @@
+
+/mob/camera/yalp_elor
+ name = "Yalp Elor"
+ real_name = "Yalp Elor"
+ desc = "An old, dying god. It's power has been severely sapped ever since it has lost it's standing in the world."
+ icon = 'icons/mob/cameramob.dmi'
+ icon_state = "yalp_elor"
+ invisibility = INVISIBILITY_OBSERVER
+ call_life = TRUE
+ var/lastWarning = 0
+
+/mob/camera/yalp_elor/Initialize()
+ ..()
+ var/datum/action/innate/yalp_transmit/transmit = new
+ transmit.Grant(src)
+ var/datum/action/innate/yalp_transport/transport = new
+ transport.Grant(src)
+
+/mob/camera/yalp_elor/CanPass(atom/movable/mover, turf/target)
+ return TRUE
+
+/mob/camera/yalp_elor/Process_Spacemove(movement_dir = 0)
+ return TRUE
+
+/mob/camera/yalp_elor/Login()
+ ..()
+ to_chat(src, "
My destiny was supposed to control all of humanity! My power was once absolute, but I fell out of view because of that damned Nar'Sie. At least i'm still alive...")
+ to_chat(src, "
But nevermind that. I have only three followers left. If they perish, I will be completely forgotten and will cease to exist. I must guide the faithful.")
+ to_chat(src, "
I sense Nanotrasen has once again tracked us, and they will reach us in about 10 minutes. I must make sure my followers are ready when they arrive.")
+
+/mob/camera/yalp_elor/Move(NewLoc, direct)
+ var/OldLoc = loc
+ if(NewLoc)
+ var/turf/T = get_turf(NewLoc)
+ if(locate(/obj/effect/blessing, T))
+ if((world.time - lastWarning) >= 30)
+ lastWarning = world.time
+ to_chat(src, "
This turf is consecrated and can't be crossed!")
+ return
+ if(istype(get_area(T), /area/chapel))
+ if((world.time - lastWarning) >= 30)
+ lastWarning = world.time
+ to_chat(src, "
The Chapel is hallowed ground under a much, MUCH stronger deity, and can't be accessed!")
+ return
+ forceMove(T)
+ Moved(OldLoc, direct)
+
+/mob/camera/yalp_elor/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
+ if(client)
+ if(client.prefs.muted & MUTE_IC)
+ to_chat(src, "You cannot send IC messages (muted).")
+ return
+ if(client.handle_spam_prevention(message,MUTE_IC))
+ return
+ message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
+ if(!message)
+ return
+ src.log_talk(message, LOG_SAY, tag="fugitive god")
+ message = "
Yalp Elor: \"[capitalize(message)]\""
+ for(var/mob/V in GLOB.player_list)
+ if(V.mind.has_antag_datum(/datum/antagonist/fugitive))
+ to_chat(V, "[message]")
+ else if(isobserver(V))
+ var/link = FOLLOW_LINK(V, src)
+ to_chat(V, "[link] [message]")
+
+/mob/camera/yalp_elor/Life()
+ ..()
+ var/safe = FALSE
+ for(var/mob/V in GLOB.player_list)
+ if(!V.mind)
+ continue
+ var/datum/antagonist/fugitive/fug = V.mind.has_antag_datum(/datum/antagonist/fugitive)
+ if(!fug || V == src)
+ continue
+ if(!fug.is_captured) //doesn't matter if they are dead, they can still be revived so you get to live
+ safe = TRUE
+ break
+ if(!safe)
+ to_chat(src, "
All of your followers are gone. That means you cease to exist.")
+ qdel(src)
+
+/datum/action/innate/yalp_transmit
+ name = "Divine Oration"
+ desc = "Transmits a message to the target."
+ icon_icon = 'icons/mob/actions/actions_animal.dmi'
+ background_icon_state = "bg_spell"
+ button_icon_state = "god_transmit"
+
+/datum/action/innate/yalp_transmit/Trigger()
+ var/list/possible_targets = list()
+ for(var/mob/living/M in range(7, owner))
+ if(istype(M))
+ possible_targets += M
+ if(!possible_targets.len)
+ to_chat(owner, "
Nobody in range to talk to!")
+ return FALSE
+
+ var/mob/living/target
+ if(possible_targets.len == 1)
+ target = possible_targets[1]
+ else
+ target = input("Who do you wish to transmit to?", "Targeting") as null|mob in possible_targets
+
+ var/input = stripped_input(owner, "What do you wish to tell [target]?", null, "")
+ if(QDELETED(src) || !input || !IsAvailable())
+ return FALSE
+
+ transmit(owner, target, input)
+ return TRUE
+
+/datum/action/innate/yalp_transmit/proc/transmit(mob/user, mob/living/target, message)
+ if(!message)
+ return
+ log_directed_talk(user, target, message, LOG_SAY, "[name]")
+ to_chat(user, "
You transmit to [target]: [message]")
+ to_chat(target, "
You hear something behind you talking... [message]")
+ for(var/ded in GLOB.dead_mob_list)
+ if(!isobserver(ded))
+ continue
+ var/follow_rev = FOLLOW_LINK(ded, user)
+ var/follow_whispee = FOLLOW_LINK(ded, target)
+ to_chat(ded, "[follow_rev]
[user] [name]: \"[message]\" to [follow_whispee]
[target]")
+
+/datum/action/innate/yalp_transport
+ name = "Guidance"
+ desc = "Transports you to a follower."
+ icon_icon = 'icons/mob/actions/actions_animal.dmi'
+ background_icon_state = "bg_spell"
+ button_icon_state = "god_transport"
+
+/datum/action/innate/yalp_transport/Trigger()
+ var/list/faithful = list()
+ var/mob/living/target
+ for(var/mob/V in GLOB.player_list)
+ var/datum/antagonist/fugitive/fug = V.mind.has_antag_datum(/datum/antagonist/fugitive)
+ if(!fug || V == src)
+ continue
+ if(fug.is_captured) //no, you can't teleport to people already captured. there's a lot of asterixes to that
+ continue
+ faithful += V
+ if(!faithful.len)
+ to_chat(owner, "
You have no faithful to jump to!")
+ return FALSE
+ if(faithful.len == 1)
+ target = faithful[1]
+ else
+ target = input("Which of your followers do you wish to jump to?", "Targeting") as null|mob in faithful
+
+ var/turf/T = get_turf(target)
+ if(target && T)
+ owner.forceMove(T)
+ return TRUE
+ to_chat(owner, "
Either your target or the ground he is standing on has stopped existing!")
+ return FALSE
diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm
index edc62fb066cb..1906e8837251 100644
--- a/code/modules/clothing/glasses/_glasses.dm
+++ b/code/modules/clothing/glasses/_glasses.dm
@@ -175,6 +175,12 @@
icon_state = "hipster_glasses"
item_state = "hipster_glasses"
+/obj/item/clothing/glasses/regular/circle
+ name = "circle glasses"
+ desc = "Why would you wear something so controversial yet so brave?"
+ icon_state = "circle_glasses"
+ item_state = "circle_glasses"
+
//Here lies green glasses, so ugly they died. RIP
/obj/item/clothing/glasses/sunglasses
diff --git a/code/modules/clothing/head/beanie.dm b/code/modules/clothing/head/beanie.dm
index 308df3ce3e17..6fe6c1f0a676 100644
--- a/code/modules/clothing/head/beanie.dm
+++ b/code/modules/clothing/head/beanie.dm
@@ -1,6 +1,8 @@
//BeanieStation13 Redux
+//Plus a bobble hat, lets be inclusive!!
+
/obj/item/clothing/head/beanie //Default is white, this is meant to be seen
name = "white beanie"
desc = "A stylish beanie. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their heads."
@@ -82,5 +84,10 @@
item_color = null
armor = list("melee" = 15, "bullet" = 5, "laser" = 15, "energy" = 5, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 5)
+/obj/item/clothing/head/beanie/waldo
+ name = "red striped bobble hat"
+ desc = "If you're going on a worldwide hike, you'll need some cold protection."
+ icon_state = "waldo_hat"
+ item_color = "waldo_hat"
//No dog fashion sprites yet :( poor Ian can't be dope like the rest of us yet
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index d20ccf687d51..6d212d7e16a0 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -162,6 +162,12 @@
strip_delay = 80
dog_fashion = null
+/obj/item/clothing/head/helmet/police
+ name = "police officer's hat"
+ desc = "A police officer's Hat. This hat emphasizes that you are THE LAW."
+ icon_state = "policehelm"
+ dynamic_hair_suffix = ""
+
/obj/item/clothing/head/helmet/swat/nanotrasen
name = "\improper SWAT helmet"
desc = "An extremely robust, space-worthy helmet with the Nanotrasen logo emblazoned on the top."
diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm
index 6481974bf7ed..feba75972d9b 100644
--- a/code/modules/clothing/masks/gasmask.dm
+++ b/code/modules/clothing/masks/gasmask.dm
@@ -176,7 +176,6 @@
/obj/item/clothing/mask/gas/tiki_mask/ui_action_click(mob/user)
-
var/mob/M = usr
var/list/options = list()
options["Original Tiki"] = "tiki_eyebrow"
@@ -194,3 +193,7 @@
A.UpdateButtonIcon()
to_chat(M, "The Tiki Mask has now changed into the [choice] Mask!")
return 1
+
+/obj/item/clothing/mask/gas/tiki_mask/yalp_elor
+ icon_state = "tiki_yalp"
+ actions_types = list()
diff --git a/code/modules/clothing/masks/hailer.dm b/code/modules/clothing/masks/hailer.dm
index 8860650fbcf4..fa5536653bf7 100644
--- a/code/modules/clothing/masks/hailer.dm
+++ b/code/modules/clothing/masks/hailer.dm
@@ -30,6 +30,12 @@
flags_inv = HIDEFACIALHAIR|HIDEFACE|HIDEEYES|HIDEEARS|HIDEHAIR
visor_flags_inv = 0
+/obj/item/clothing/mask/gas/sechailer/swat/spacepol
+ name = "spacepol mask"
+ desc = "A close-fitting tactical mask created in cooperation with a certain megacorporation, comes with an especially aggressive Compli-o-nator 3000."
+ icon_state = "spacepol"
+ item_state = "spacepol"
+
/obj/item/clothing/mask/gas/sechailer/cyborg
name = "security hailer"
desc = "A set of recognizable pre-recorded messages for cyborgs to use when apprehending criminals."
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index e9667408d00e..64ab3703e653 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -378,6 +378,12 @@
icon_state = "vapeshirt"
item_state = "vapeshirt"
+/obj/item/clothing/suit/striped_sweater
+ name = "striped sweater"
+ desc = "Reminds you of someone, but you just can't put your finger on it..."
+ icon_state = "waldo_shirt"
+ item_state = "waldo_shirt"
+
/obj/item/clothing/suit/jacket
name = "bomber jacket"
desc = "Aviators not included."
diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm
index 6f9e77b09f79..01b947d5ef36 100644
--- a/code/modules/clothing/under/jobs/security.dm
+++ b/code/modules/clothing/under/jobs/security.dm
@@ -148,3 +148,15 @@
item_state = "blueshift"
item_color = "blueshift"
can_adjust = FALSE
+
+/*
+ *Spacepol
+ */
+
+/obj/item/clothing/under/rank/security/spacepol
+ name = "police uniform"
+ desc = "Space not controlled by megacorporations, planets, or pirates is under the jurisdiction of Spacepol."
+ icon_state = "spacepol"
+ item_state = "spacepol"
+ item_color = "spacepol"
+ can_adjust = FALSE
diff --git a/code/modules/events/fugitive_spawning.dm b/code/modules/events/fugitive_spawning.dm
new file mode 100644
index 000000000000..9edbcdfd37bf
--- /dev/null
+++ b/code/modules/events/fugitive_spawning.dm
@@ -0,0 +1,128 @@
+/datum/round_event_control/fugitives
+ name = "Spawn Fugitives"
+ typepath = /datum/round_event/ghost_role/fugitives
+ max_occurrences = 1
+ min_players = 20
+ earliest_start = 30 MINUTES //deadchat sink, lets not even consider it early on.
+ gamemode_blacklist = list("nuclear")
+
+/datum/round_event/ghost_role/fugitives
+ minimum_required = 1
+ role_name = "fugitive"
+ fakeable = FALSE
+
+/datum/round_event/ghost_role/fugitives/spawn_role()
+ var/turf/landing_turf = pick(GLOB.xeno_spawn)
+ if(!landing_turf)
+ message_admins("No valid spawn locations found, aborting...")
+ return MAP_ERROR
+
+ var/list/possible_backstories = list()
+ var/list/candidates = get_candidates(ROLE_TRAITOR, null, ROLE_TRAITOR)
+ if(candidates.len >= 1) //solo refugees
+ possible_backstories += "waldo"
+ if(candidates.len >= 4)//group refugees
+ possible_backstories += "prisoner"
+ possible_backstories += "cultists"
+ possible_backstories += "synth"
+ if(!possible_backstories.len)
+ return NOT_ENOUGH_PLAYERS
+
+ var/backstory = pick(possible_backstories)
+ var/member_size = 3
+ var/leader
+ switch(backstory)
+ if("cultists" || "synth")
+ leader = pick_n_take(candidates)
+ if("waldo")
+ member_size = 0 //solo refugees have no leader so the member_size gets bumped to one a bit later
+ var/list/members = list()
+ var/list/spawned_mobs = list()
+ if(isnull(leader))
+ member_size++ //if there is no leader role, then the would be leader is a normal member of the team.
+
+ for(var/i in 1 to member_size)
+ members += pick_n_take(candidates)
+
+ for(var/mob/dead/selected in members)
+ var/mob/living/carbon/human/S = gear_fugitive(selected, landing_turf, backstory)
+ spawned_mobs += S
+ if(!isnull(leader))
+ gear_fugitive_leader(leader, landing_turf, backstory)
+
+
+//after spawning
+ playsound(src, 'sound/weapons/emitter.ogg', 50, 1)
+ new /obj/item/storage/toolbox/mechanical(landing_turf) //so they can actually escape maint
+ addtimer(CALLBACK(src, .proc/spawn_hunters), 6000) //10 minutes
+ role_name = "fugitive hunter"
+ return SUCCESSFUL_SPAWN
+
+/datum/round_event/ghost_role/fugitives/proc/gear_fugitive(var/mob/dead/selected, var/turf/landing_turf, backstory) //spawns normal fugitive
+ var/datum/mind/player_mind = new /datum/mind(selected.key)
+ player_mind.active = TRUE
+ var/mob/living/carbon/human/S = new(landing_turf)
+ player_mind.transfer_to(S)
+ player_mind.assigned_role = "Fugitive"
+ player_mind.special_role = "Fugitive"
+ player_mind.add_antag_datum(/datum/antagonist/fugitive)
+ var/datum/antagonist/fugitive/fugitiveantag = player_mind.has_antag_datum(/datum/antagonist/fugitive)
+ INVOKE_ASYNC(fugitiveantag, /datum/antagonist/fugitive.proc/greet, backstory) //some fugitives have a sleep on their greet, so we don't want to stop the entire antag granting proc with fluff
+
+ switch(backstory)
+ if("prisoner")
+ S.equipOutfit(/datum/outfit/prisoner)
+ if("cultist")
+ S.equipOutfit(/datum/outfit/yalp_cultist)
+ if("waldo")
+ S.equipOutfit(/datum/outfit/waldo)
+ if("synth")
+ S.equipOutfit(/datum/outfit/synthetic)
+ message_admins("[ADMIN_LOOKUPFLW(S)] has been made into a Fugitive by an event.")
+ log_game("[key_name(S)] was spawned as a Fugitive by an event.")
+ spawned_mobs += S
+ return S
+
+ //special spawn for one member. it can be used for a special mob or simply to give one normal member special items. for special items you can
+/datum/round_event/ghost_role/fugitives/proc/gear_fugitive_leader(var/mob/dead/leader, var/turf/landing_turf, backstory)
+ var/datum/mind/player_mind = new /datum/mind(leader.key)
+ player_mind.active = TRUE
+ switch(backstory)
+ if("cultist")
+ var/mob/camera/yalp_elor/yalp = new(landing_turf)
+ player_mind.transfer_to(yalp)
+ player_mind.assigned_role = "Yalp Elor"
+ player_mind.special_role = "Old God"
+ player_mind.add_antag_datum(/datum/antagonist/fugitive)
+ if("synth")
+ var/mob/living/carbon/human/S = gear_fugitive(leader, landing_turf, backstory)
+ var/obj/item/choice_beacon/augments/A = new(S)
+ H.put_in_hands(A))
+ var/obj/item/autosurgeon/auto = new(landing_turf)
+
+//security team gets called in after 10 minutes of prep to find the refugees
+/datum/round_event/ghost_role/fugitives/proc/spawn_hunters()
+ var/backstory = pick("space cop", "russian")
+ var/static/list/hunter_ship_types = list(
+ "space cop" = /datum/map_template/space_cop_ship,
+ "russian" = /datum/map_template/russian_ship)
+
+ var/datum/map_template/ship = hunter_ship_types[backstory]
+ ship = new
+ var/x = rand(TRANSITIONEDGE,world.maxx - TRANSITIONEDGE - ship.width)
+ var/y = rand(TRANSITIONEDGE,world.maxy - TRANSITIONEDGE - ship.height)
+ var/z = SSmapping.empty_space.z_value
+ var/turf/T = locate(x,y,z)
+ if(!T)
+ CRASH("Fugitive Hunters (Created from fugitive event) found no turf to load in")
+ if(!ship.load(T))
+ CRASH("Loading hunter ship failed!")
+ priority_announce("Unidentified armed ship detected near the station.")
+ var/list/spawner_spots = list()
+ for(var/turf/A in ship.get_affected_turfs(T))
+ for(var/obj/structure/chair/chair in A) //every chair gets a spawner on it.
+ switch(backstory)
+ if("space cop")
+ new /obj/effect/mob_spawn/human/fugitive/spacepol(get_turf(chair))
+ if("russian")
+ new /obj/effect/mob_spawn/human/fugitive/russian(get_turf(chair))
diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm
index 4d26ad26b60a..d4ef90d6f0fa 100644
--- a/code/modules/jobs/job_types/_job.dm
+++ b/code/modules/jobs/job_types/_job.dm
@@ -1,240 +1,239 @@
-/datum/job
- //The name of the job
- var/title = "NOPE"
-
- //Job access. The use of minimal_access or access is determined by a config setting: config.jobs_have_minimal_access
- var/list/minimal_access = list() //Useful for servers which prefer to only have access given to the places a job absolutely needs (Larger server population)
- var/list/access = list() //Useful for servers which either have fewer players, so each person needs to fill more than one role, or servers which like to give more access, so players can't hide forever in their super secure departments (I'm looking at you, chemistry!)
-
- //Determines who can demote this position
- var/department_head = list()
-
- //Tells the given channels that the given mob is the new department head. See communications.dm for valid channels.
- var/list/head_announce = null
-
- //Bitflags for the job
- var/flag = 0
- var/department_flag = 0
-
- //Players will be allowed to spawn in as jobs that are set to "Station"
- var/faction = "None"
-
- //How many players can be this job
- var/total_positions = 0
-
- //How many players can spawn in as this job
- var/spawn_positions = 0
-
- //How many players have this job
- var/current_positions = 0
-
- //Supervisors, who this person answers to directly
- var/supervisors = ""
-
- //Sellection screen color
- var/selection_color = "#ffffff"
-
-
- //If this is set to 1, a text is printed to the player when jobs are assigned, telling him that he should let admins know that he has to disconnect.
- var/req_admin_notify
-
- //Yogs start
- //If this is set to 1, a text is printed to the player when jobs are assigned, telling them that space law has been updated.
- var/space_law_notify
- //Yogs end
-
- //If you have the use_age_restriction_for_jobs config option enabled and the database set up, this option will add a requirement for players to be at least minimal_player_age days old. (meaning they first signed in at least that many days before.)
- var/minimal_player_age = 0
-
- var/outfit = null
-
- var/exp_requirements = 0
-
- var/exp_type = ""
- var/exp_type_department = ""
-
- //The amount of good boy points playing this role will earn you towards a higher chance to roll antagonist next round
- //can be overridden by antag_rep.txt config
- var/antag_rep = 10
-
- var/paycheck = PAYCHECK_MINIMAL
- var/paycheck_department = ACCOUNT_CIV
-
- var/list/mind_traits // Traits added to the mind of the mob assigned this job
-
- var/display_order = JOB_DISPLAY_ORDER_DEFAULT
-
-//Only override this proc
-//H is usually a human unless an /equip override transformed it
-/datum/job/proc/after_spawn(mob/living/H, mob/M, latejoin = FALSE)
- //do actions on H but send messages to M as the key may not have been transferred_yet
- if(mind_traits)
- for(var/t in mind_traits)
- H.mind.add_trait(t, JOB_TRAIT)
-
-/datum/job/proc/announce(mob/living/carbon/human/H)
- if(head_announce)
- announce_head(H, head_announce)
-
-/datum/job/proc/override_latejoin_spawn(mob/living/carbon/human/H) //Return TRUE to force latejoining to not automatically place the person in latejoin shuttle/whatever.
- return FALSE
-
-//Used for a special check of whether to allow a client to latejoin as this job.
-/datum/job/proc/special_check_latejoin(client/C)
- return TRUE
-
-/datum/job/proc/GetAntagRep()
- . = CONFIG_GET(keyed_list/antag_rep)[lowertext(title)]
- if(. == null)
- return antag_rep
-
-//Don't override this unless the job transforms into a non-human (Silicons do this for example)
-/datum/job/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE, announce = TRUE, latejoin = FALSE, datum/outfit/outfit_override = null, client/preference_source)
- if(!H)
- return FALSE
- if(!visualsOnly)
- var/datum/bank_account/bank_account = new(H.real_name, src)
- bank_account.payday(STARTING_PAYCHECKS, TRUE)
- H.account_id = bank_account.account_id
- if(CONFIG_GET(flag/enforce_human_authority) && (title in GLOB.command_positions))
- if(H.dna.species.id != "human")
- H.set_species(/datum/species/human)
- H.apply_pref_name("human", preference_source)
-
- //Equip the rest of the gear
- H.dna.species.before_equip_job(src, H, visualsOnly)
-
- if(outfit_override || outfit)
- H.equipOutfit(outfit_override ? outfit_override : outfit, visualsOnly)
-
- H.dna.species.after_equip_job(src, H, visualsOnly)
-
- if(!visualsOnly && announce)
- announce(H)
-
-/datum/job/proc/get_access()
- if(!config) //Needed for robots.
- return src.minimal_access.Copy()
-
- . = list()
-
- if(CONFIG_GET(flag/jobs_have_minimal_access))
- . = src.minimal_access.Copy()
- else
- . = src.access.Copy()
-
- if(CONFIG_GET(flag/everyone_has_maint_access)) //Config has global maint access set
- . |= list(ACCESS_MAINT_TUNNELS)
-
-/datum/job/proc/announce_head(var/mob/living/carbon/human/H, var/channels) //tells the given channel that the given mob is the new department head. See communications.dm for valid channels.
- if(H && GLOB.announcement_systems.len)
- //timer because these should come after the captain announcement
- SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, .proc/addtimer, CALLBACK(pick(GLOB.announcement_systems), /obj/machinery/announcement_system/proc/announce, "NEWHEAD", H.real_name, H.job, channels), 1))
-
-//If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1
-/datum/job/proc/player_old_enough(client/C)
- if(available_in_days(C) == 0)
- return TRUE //Available in 0 days = available right now = player is old enough to play.
- return FALSE
-
-
-/datum/job/proc/available_in_days(client/C)
- if(!C)
- return 0
- if(!CONFIG_GET(flag/use_age_restriction_for_jobs))
- return 0
- if(!isnum(C.player_age))
- return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced
- if(!isnum(minimal_player_age))
- return 0
-
- return max(0, minimal_player_age - C.player_age)
-
-/datum/job/proc/config_check()
- return TRUE
-
-/datum/job/proc/map_check()
- return TRUE
-
-/datum/job/proc/radio_help_message(mob/M)
- to_chat(M, "
Prefix your message with :h to speak on your department's radio. To see other prefixes, look closely at your headset.")
-
-/datum/outfit/job
- name = "Standard Gear"
-
- var/jobtype = null
-
- uniform = /obj/item/clothing/under/color/grey
- id = /obj/item/card/id
- ears = /obj/item/radio/headset
- belt = /obj/item/pda
- back = /obj/item/storage/backpack
- shoes = /obj/item/clothing/shoes/sneakers/black
- box = /obj/item/storage/box/survival
-
- var/backpack = /obj/item/storage/backpack
- var/satchel = /obj/item/storage/backpack/satchel
- var/duffelbag = /obj/item/storage/backpack/duffelbag
-
- var/pda_slot = SLOT_BELT
-
-/datum/outfit/job/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- switch(H.backbag)
- if(GBACKPACK)
- back = /obj/item/storage/backpack //Grey backpack
- if(GSATCHEL)
- back = /obj/item/storage/backpack/satchel //Grey satchel
- if(GDUFFELBAG)
- back = /obj/item/storage/backpack/duffelbag //Grey Duffel bag
- if(LSATCHEL)
- back = /obj/item/storage/backpack/satchel/leather //Leather Satchel
- if(DSATCHEL)
- back = satchel //Department satchel
- if(DDUFFELBAG)
- back = duffelbag //Department duffel bag
- else
- back = backpack //Department backpack
-
-/datum/outfit/job/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
- return
-
- var/datum/job/J = SSjob.GetJobType(jobtype)
- if(!J)
- J = SSjob.GetJob(H.job)
-
- var/obj/item/card/id/C = H.wear_id
- if(istype(C))
- C.access = J.get_access()
- shuffle_inplace(C.access) // Shuffle access list to make NTNet passkeys less predictable
- C.registered_name = H.real_name
- C.assignment = J.title
- C.update_label()
- for(var/A in SSeconomy.bank_accounts)
- var/datum/bank_account/B = A
- if(B.account_id == H.account_id)
- C.registered_account = B
- B.bank_cards += C
- break
- H.sec_hud_set_ID()
-
- var/obj/item/pda/PDA = H.get_item_by_slot(pda_slot)
- if(istype(PDA))
- PDA.owner = H.real_name
- PDA.ownjob = J.title
- PDA.update_label()
-
-/datum/outfit/job/get_chameleon_disguise_info()
- var/list/types = ..()
- types -= /obj/item/storage/backpack //otherwise this will override the actual backpacks
- types += backpack
- types += satchel
- types += duffelbag
- return types
-
-//Warden and regular officers add this result to their get_access()
-/datum/job/proc/check_config_for_sec_maint()
- if(CONFIG_GET(flag/security_has_maint_access))
- return list(ACCESS_MAINT_TUNNELS)
- return list()
-
+/datum/job
+ //The name of the job
+ var/title = "NOPE"
+
+ //Job access. The use of minimal_access or access is determined by a config setting: config.jobs_have_minimal_access
+ var/list/minimal_access = list() //Useful for servers which prefer to only have access given to the places a job absolutely needs (Larger server population)
+ var/list/access = list() //Useful for servers which either have fewer players, so each person needs to fill more than one role, or servers which like to give more access, so players can't hide forever in their super secure departments (I'm looking at you, chemistry!)
+
+ //Determines who can demote this position
+ var/department_head = list()
+
+ //Tells the given channels that the given mob is the new department head. See communications.dm for valid channels.
+ var/list/head_announce = null
+
+ //Bitflags for the job
+ var/flag = 0
+ var/department_flag = 0
+
+ //Players will be allowed to spawn in as jobs that are set to "Station"
+ var/faction = "None"
+
+ //How many players can be this job
+ var/total_positions = 0
+
+ //How many players can spawn in as this job
+ var/spawn_positions = 0
+
+ //How many players have this job
+ var/current_positions = 0
+
+ //Supervisors, who this person answers to directly
+ var/supervisors = ""
+
+ //Sellection screen color
+ var/selection_color = "#ffffff"
+
+
+ //If this is set to 1, a text is printed to the player when jobs are assigned, telling him that he should let admins know that he has to disconnect.
+ var/req_admin_notify
+
+ //Yogs start
+ //If this is set to 1, a text is printed to the player when jobs are assigned, telling them that space law has been updated.
+ var/space_law_notify
+ //Yogs end
+
+ //If you have the use_age_restriction_for_jobs config option enabled and the database set up, this option will add a requirement for players to be at least minimal_player_age days old. (meaning they first signed in at least that many days before.)
+ var/minimal_player_age = 0
+
+ var/outfit = null
+
+ var/exp_requirements = 0
+
+ var/exp_type = ""
+ var/exp_type_department = ""
+
+ //The amount of good boy points playing this role will earn you towards a higher chance to roll antagonist next round
+ //can be overridden by antag_rep.txt config
+ var/antag_rep = 10
+
+ var/paycheck = PAYCHECK_MINIMAL
+ var/paycheck_department = ACCOUNT_CIV
+
+ var/list/mind_traits // Traits added to the mind of the mob assigned this job
+
+ var/display_order = JOB_DISPLAY_ORDER_DEFAULT
+
+//Only override this proc
+//H is usually a human unless an /equip override transformed it
+/datum/job/proc/after_spawn(mob/living/H, mob/M, latejoin = FALSE)
+ //do actions on H but send messages to M as the key may not have been transferred_yet
+ if(mind_traits)
+ for(var/t in mind_traits)
+ H.mind.add_trait(t, JOB_TRAIT)
+
+/datum/job/proc/announce(mob/living/carbon/human/H)
+ if(head_announce)
+ announce_head(H, head_announce)
+
+/datum/job/proc/override_latejoin_spawn(mob/living/carbon/human/H) //Return TRUE to force latejoining to not automatically place the person in latejoin shuttle/whatever.
+ return FALSE
+
+//Used for a special check of whether to allow a client to latejoin as this job.
+/datum/job/proc/special_check_latejoin(client/C)
+ return TRUE
+
+/datum/job/proc/GetAntagRep()
+ . = CONFIG_GET(keyed_list/antag_rep)[lowertext(title)]
+ if(. == null)
+ return antag_rep
+
+//Don't override this unless the job transforms into a non-human (Silicons do this for example)
+/datum/job/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE, announce = TRUE, latejoin = FALSE, datum/outfit/outfit_override = null, client/preference_source)
+ if(!H)
+ return FALSE
+ if(!visualsOnly)
+ var/datum/bank_account/bank_account = new(H.real_name, src)
+ bank_account.payday(STARTING_PAYCHECKS, TRUE)
+ H.account_id = bank_account.account_id
+ if(CONFIG_GET(flag/enforce_human_authority) && (title in GLOB.command_positions))
+ if(H.dna.species.id != "human")
+ H.set_species(/datum/species/human)
+ H.apply_pref_name("human", preference_source)
+
+ //Equip the rest of the gear
+ H.dna.species.before_equip_job(src, H, visualsOnly)
+
+ if(outfit_override || outfit)
+ H.equipOutfit(outfit_override ? outfit_override : outfit, visualsOnly)
+
+ H.dna.species.after_equip_job(src, H, visualsOnly)
+
+ if(!visualsOnly && announce)
+ announce(H)
+
+/datum/job/proc/get_access()
+ if(!config) //Needed for robots.
+ return src.minimal_access.Copy()
+
+ . = list()
+
+ if(CONFIG_GET(flag/jobs_have_minimal_access))
+ . = src.minimal_access.Copy()
+ else
+ . = src.access.Copy()
+
+ if(CONFIG_GET(flag/everyone_has_maint_access)) //Config has global maint access set
+ . |= list(ACCESS_MAINT_TUNNELS)
+
+/datum/job/proc/announce_head(var/mob/living/carbon/human/H, var/channels) //tells the given channel that the given mob is the new department head. See communications.dm for valid channels.
+ if(H && GLOB.announcement_systems.len)
+ //timer because these should come after the captain announcement
+ SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, .proc/addtimer, CALLBACK(pick(GLOB.announcement_systems), /obj/machinery/announcement_system/proc/announce, "NEWHEAD", H.real_name, H.job, channels), 1))
+
+//If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1
+/datum/job/proc/player_old_enough(client/C)
+ if(available_in_days(C) == 0)
+ return TRUE //Available in 0 days = available right now = player is old enough to play.
+ return FALSE
+
+
+/datum/job/proc/available_in_days(client/C)
+ if(!C)
+ return 0
+ if(!CONFIG_GET(flag/use_age_restriction_for_jobs))
+ return 0
+ if(!isnum(C.player_age))
+ return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced
+ if(!isnum(minimal_player_age))
+ return 0
+
+ return max(0, minimal_player_age - C.player_age)
+
+/datum/job/proc/config_check()
+ return TRUE
+
+/datum/job/proc/map_check()
+ return TRUE
+
+/datum/job/proc/radio_help_message(mob/M)
+ to_chat(M, "
Prefix your message with :h to speak on your department's radio. To see other prefixes, look closely at your headset.")
+
+/datum/outfit/job
+ name = "Standard Gear"
+
+ var/jobtype = null
+
+ uniform = /obj/item/clothing/under/color/grey
+ id = /obj/item/card/id
+ ears = /obj/item/radio/headset
+ belt = /obj/item/pda
+ back = /obj/item/storage/backpack
+ shoes = /obj/item/clothing/shoes/sneakers/black
+ box = /obj/item/storage/box/survival
+
+ var/backpack = /obj/item/storage/backpack
+ var/satchel = /obj/item/storage/backpack/satchel
+ var/duffelbag = /obj/item/storage/backpack/duffelbag
+
+ var/pda_slot = SLOT_BELT
+
+/datum/outfit/job/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ switch(H.backbag)
+ if(GBACKPACK)
+ back = /obj/item/storage/backpack //Grey backpack
+ if(GSATCHEL)
+ back = /obj/item/storage/backpack/satchel //Grey satchel
+ if(GDUFFELBAG)
+ back = /obj/item/storage/backpack/duffelbag //Grey Duffel bag
+ if(LSATCHEL)
+ back = /obj/item/storage/backpack/satchel/leather //Leather Satchel
+ if(DSATCHEL)
+ back = satchel //Department satchel
+ if(DDUFFELBAG)
+ back = duffelbag //Department duffel bag
+ else
+ back = backpack //Department backpack
+
+/datum/outfit/job/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ if(visualsOnly)
+ return
+
+ var/datum/job/J = SSjob.GetJobType(jobtype)
+ if(!J)
+ J = SSjob.GetJob(H.job)
+
+ var/obj/item/card/id/C = H.wear_id
+ if(istype(C))
+ C.access = J.get_access()
+ shuffle_inplace(C.access) // Shuffle access list to make NTNet passkeys less predictable
+ C.registered_name = H.real_name
+ C.assignment = J.title
+ C.update_label()
+ for(var/A in SSeconomy.bank_accounts)
+ var/datum/bank_account/B = A
+ if(B.account_id == H.account_id)
+ C.registered_account = B
+ B.bank_cards += C
+ break
+ H.sec_hud_set_ID()
+
+ var/obj/item/pda/PDA = H.get_item_by_slot(pda_slot)
+ if(istype(PDA))
+ PDA.owner = H.real_name
+ PDA.ownjob = J.title
+ PDA.update_label()
+
+/datum/outfit/job/get_chameleon_disguise_info()
+ var/list/types = ..()
+ types -= /obj/item/storage/backpack //otherwise this will override the actual backpacks
+ types += backpack
+ types += satchel
+ types += duffelbag
+ return types
+
+//Warden and regular officers add this result to their get_access()
+/datum/job/proc/check_config_for_sec_maint()
+ if(CONFIG_GET(flag/security_has_maint_access))
+ return list(ACCESS_MAINT_TUNNELS)
+ return list()
\ No newline at end of file
diff --git a/code/modules/jobs/job_types/chaplain.dm b/code/modules/jobs/job_types/chaplain.dm
index 61dacf1e1709..71a31d40fb61 100644
--- a/code/modules/jobs/job_types/chaplain.dm
+++ b/code/modules/jobs/job_types/chaplain.dm
@@ -1,96 +1,96 @@
-/datum/job/chaplain
- title = "Chaplain"
- flag = CHAPLAIN
- department_head = list("Head of Personnel")
- department_flag = CIVILIAN
- faction = "Station"
- total_positions = 1
- spawn_positions = 1
- supervisors = "the head of personnel"
- selection_color = "#dddddd"
-
- outfit = /datum/outfit/job/chaplain
-
- access = list(ACCESS_MORGUE, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_THEATRE)
- minimal_access = list(ACCESS_MORGUE, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_THEATRE)
- paycheck = PAYCHECK_EASY
- paycheck_department = ACCOUNT_CIV
-
- display_order = JOB_DISPLAY_ORDER_CHAPLAIN
-
-
-/datum/job/chaplain/after_spawn(mob/living/H, mob/M)
- . = ..()
- if(H.mind)
- H.mind.isholy = TRUE
-
- var/obj/item/storage/book/bible/booze/B = new
-
- if(SSreligion.religion)
- B.deity_name = SSreligion.deity
- B.name = SSreligion.bible_name
- B.icon_state = SSreligion.bible_icon_state
- B.item_state = SSreligion.bible_item_state
- to_chat(H, "There is already an established religion onboard the station. You are an acolyte of [SSreligion.deity]. Defer to the Chaplain.")
- H.equip_to_slot_or_del(B, SLOT_IN_BACKPACK)
- var/nrt = SSreligion.holy_weapon_type || /obj/item/nullrod
- var/obj/item/nullrod/N = new nrt(H)
- H.put_in_hands(N)
- return
-
- var/new_religion = DEFAULT_RELIGION
- if(M.client && M.client.prefs.custom_names["religion"])
- new_religion = M.client.prefs.custom_names["religion"]
-
- var/new_deity = DEFAULT_DEITY
- if(M.client && M.client.prefs.custom_names["deity"])
- new_deity = M.client.prefs.custom_names["deity"]
-
- B.deity_name = new_deity
-
-
- switch(lowertext(new_religion))
- if("christianity") // DEFAULT_RELIGION
- B.name = pick("The Holy Bible","The Dead Sea Scrolls")
- if("satanism")
- B.name = "The Unholy Bible"
- if("cthulhu")
- B.name = "The Necronomicon"
- if("islam")
- B.name = "Quran"
- if("scientology")
- B.name = pick("The Biography of L. Ron Hubbard","Dianetics")
- if("chaos")
- B.name = "The Book of Lorgar"
- if("imperium")
- B.name = "Uplifting Primer"
- if("toolboxia")
- B.name = "Toolbox Manifesto"
- if("homosexuality")
- B.name = "Guys Gone Wild"
- if("lol", "wtf", "gay", "penis", "ass", "poo", "badmin", "shitmin", "deadmin", "cock", "cocks", "meme", "memes")
- B.name = pick("Woodys Got Wood: The Aftermath", "War of the Cocks", "Sweet Bro and Hella Jef: Expanded Edition")
- H.adjustBrainLoss(100) // starts off retarded as fuck
- if("science")
- B.name = pick("Principle of Relativity", "Quantum Enigma: Physics Encounters Consciousness", "Programming the Universe", "Quantum Physics and Theology", "String Theory for Dummies", "How To: Build Your Own Warp Drive", "The Mysteries of Bluespace", "Playing God: Collector's Edition")
- else
- B.name = "The Holy Book of [new_religion]"
-
- SSreligion.religion = new_religion
- SSreligion.bible_name = B.name
- SSreligion.deity = B.deity_name
-
- H.equip_to_slot_or_del(B, SLOT_IN_BACKPACK)
-
- SSblackbox.record_feedback("text", "religion_name", 1, "[new_religion]", 1)
- SSblackbox.record_feedback("text", "religion_deity", 1, "[new_deity]", 1)
-
-/datum/outfit/job/chaplain
- name = "Chaplain"
- jobtype = /datum/job/chaplain
-
- belt = /obj/item/pda/chaplain
- uniform = /obj/item/clothing/under/rank/chaplain
- backpack_contents = list(/obj/item/camera/spooky = 1)
- backpack = /obj/item/storage/backpack/cultpack
- satchel = /obj/item/storage/backpack/cultpack
+/datum/job/chaplain
+ title = "Chaplain"
+ flag = CHAPLAIN
+ department_head = list("Head of Personnel")
+ department_flag = CIVILIAN
+ faction = "Station"
+ total_positions = 1
+ spawn_positions = 1
+ supervisors = "the head of personnel"
+ selection_color = "#dddddd"
+
+ outfit = /datum/outfit/job/chaplain
+
+ access = list(ACCESS_MORGUE, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_THEATRE)
+ minimal_access = list(ACCESS_MORGUE, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_THEATRE)
+ paycheck = PAYCHECK_EASY
+ paycheck_department = ACCOUNT_CIV
+
+ display_order = JOB_DISPLAY_ORDER_CHAPLAIN
+
+
+/datum/job/chaplain/after_spawn(mob/living/H, mob/M)
+ . = ..()
+ if(H.mind)
+ H.mind.isholy = TRUE
+
+ var/obj/item/storage/book/bible/booze/B = new
+
+ if(SSreligion.religion)
+ B.deity_name = SSreligion.deity
+ B.name = SSreligion.bible_name
+ B.icon_state = SSreligion.bible_icon_state
+ B.item_state = SSreligion.bible_item_state
+ to_chat(H, "There is already an established religion onboard the station. You are an acolyte of [SSreligion.deity]. Defer to the Chaplain.")
+ H.equip_to_slot_or_del(B, SLOT_IN_BACKPACK)
+ var/nrt = SSreligion.holy_weapon_type || /obj/item/nullrod
+ var/obj/item/nullrod/N = new nrt(H)
+ H.put_in_hands(N)
+ return
+
+ var/new_religion = DEFAULT_RELIGION
+ if(M.client && M.client.prefs.custom_names["religion"])
+ new_religion = M.client.prefs.custom_names["religion"]
+
+ var/new_deity = DEFAULT_DEITY
+ if(M.client && M.client.prefs.custom_names["deity"])
+ new_deity = M.client.prefs.custom_names["deity"]
+
+ B.deity_name = new_deity
+
+
+ switch(lowertext(new_religion))
+ if("christianity") // DEFAULT_RELIGION
+ B.name = pick("The Holy Bible","The Dead Sea Scrolls")
+ if("satanism")
+ B.name = "The Unholy Bible"
+ if("cthulhu")
+ B.name = "The Necronomicon"
+ if("islam")
+ B.name = "Quran"
+ if("scientology")
+ B.name = pick("The Biography of L. Ron Hubbard","Dianetics")
+ if("chaos")
+ B.name = "The Book of Lorgar"
+ if("imperium")
+ B.name = "Uplifting Primer"
+ if("toolboxia")
+ B.name = "Toolbox Manifesto"
+ if("homosexuality")
+ B.name = "Guys Gone Wild"
+ if("lol", "wtf", "gay", "penis", "ass", "poo", "badmin", "shitmin", "deadmin", "cock", "cocks", "meme", "memes")
+ B.name = pick("Woodys Got Wood: The Aftermath", "War of the Cocks", "Sweet Bro and Hella Jef: Expanded Edition")
+ H.adjustBrainLoss(100) // starts off retarded as fuck
+ if("science")
+ B.name = pick("Principle of Relativity", "Quantum Enigma: Physics Encounters Consciousness", "Programming the Universe", "Quantum Physics and Theology", "String Theory for Dummies", "How To: Build Your Own Warp Drive", "The Mysteries of Bluespace", "Playing God: Collector's Edition")
+ else
+ B.name = "The Holy Book of [new_religion]"
+
+ SSreligion.religion = new_religion
+ SSreligion.bible_name = B.name
+ SSreligion.deity = B.deity_name
+
+ H.equip_to_slot_or_del(B, SLOT_IN_BACKPACK)
+
+ SSblackbox.record_feedback("text", "religion_name", 1, "[new_religion]", 1)
+ SSblackbox.record_feedback("text", "religion_deity", 1, "[new_deity]", 1)
+
+/datum/outfit/job/chaplain
+ name = "Chaplain"
+ jobtype = /datum/job/chaplain
+
+ belt = /obj/item/pda/chaplain
+ uniform = /obj/item/clothing/under/rank/chaplain
+ backpack_contents = list(/obj/item/camera/spooky = 1)
+ backpack = /obj/item/storage/backpack/cultpack
+ satchel = /obj/item/storage/backpack/cultpack
diff --git a/code/modules/unit_tests/species_whitelists.dm b/code/modules/unit_tests/species_whitelists.dm
index acc5c5c121a0..145f3a259fc2 100644
--- a/code/modules/unit_tests/species_whitelists.dm
+++ b/code/modules/unit_tests/species_whitelists.dm
@@ -1,5 +1,5 @@
-/datum/unit_test/species_whitelist_check/Run()
- for(var/typepath in subtypesof(/datum/species))
- var/datum/species/S = typepath
- if(initial(S.changesource_flags) == NONE)
- Fail("A species type was detected with no changesource flags: [S]")
+/datum/unit_test/species_whitelist_check/Run()
+ for(var/typepath in subtypesof(/datum/species))
+ var/datum/species/S = typepath
+ if(initial(S.changesource_flags) == NONE)
+ Fail("A species type was detected with no changesource flags: [S]")
diff --git a/icons/mob/actions/actions_animal.dmi b/icons/mob/actions/actions_animal.dmi
index aefa471dd2389bf1ebd9d746f137b504ef4fa5a9..e8f2d4ada8346079e62a06c1b84d9c3bc5b852fa 100644
GIT binary patch
literal 5618
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
literal 4405
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
diff --git a/icons/mob/cameramob.dmi b/icons/mob/cameramob.dmi
index 18640c7136a1c6adf68ac9dbb52e009d9a52f8eb..7ecaf0f6d968547b834ccb9eeb7c0e2261ed26ec 100644
GIT binary patch
literal 1690
zcma)7e>Bqz6#p9YtF}p!*wE9PPCX(&lSUd*ep3|r@s==)7NR}BQZc0;&+if@VzQ7Y
z3u9s;o*%KT-i#F*QrH`@#k~3N{qfG}{c-O-pU=7Ho_p`-+;cPBU5`VQHI)GXfH*m#
zJ*6>4YC($fQqLj~oTQ`;fm&z4BNMYqZ6(eZn`)
ztd0&79JVX(sdGeTDV%(qD^v{%ZfI6=fd_eneTpxKs3QlRC0}3odw2$LFsfV6WdXX$
zwruQ+JpD?(Nk^JvY%P1D-We&2-zizG!Ol3e)P0XypIRk<;=rm$X7_S#=|@Q@h12ug
z5_I^-G@G_+&5nj_F=Jt2LF+(2`t3L4?*3^ZnT5S?bI_A}^U|4P1&t^H59ac9){&ze
z%@sVbcD;Mg{e2N7Up=z?99yNr;3?~=94&)znt%=IN*B~D2JnSffpKM@YSX)#&KFBdYlR4fR9pcOsUl#JvgBQ`-=sz}wc(=M+R$H%zdlZi
zxHyB0H=cP(TerSg<6LMKGi>okzyRsM}Cv^
zeeoOhZjXGAW;Ewh=}RhY!nYf?3CAqYNc4>fQdSp9|NWK
zlYO-Pw0j17$mu3(c$P}}5ma_Jci7?NjouvuOTBsNVs<~lY4z3bU>a#vYmyEUiXI1h
zL@18TtNn{JloIM1*>LF3aOe&=tP(<3+T*H9Y6XMZdksOIl&@U2%%WT5m%r=C`cLQD+rcZL?fRI{$>RnHc#%Uwb*mk!wYo|G0JX<
z6kkt^l_kF!H%t(-?>Q|{C8Sq6vKbf_KtLr{EroUP-(M%$5Pc!(pGRx0LbY4UdE)ED
zKm6KBQ5b0PweJAq0e-zFFAxRg$~Us(
zD7b55nL0~ehAD+5#PD6zf(Y6LVSDo4{X2;MHFyuI%Mg+tl9`K}6rAl!g7`4i`?Tny
zosM)oI4h1cDZu1qMOB+c2voefx@cKX;
zN5-&Z3qtQkF?PnIkSDi~S$&WF@
zJC4xnUG|~nZ5WUc*kQuDVi+cK@4L9G23n-;9uK1;wra_L0sjBR{KsKs1GI%H>TUNX
zQnOElQkr!7QHLH}{o1f%8gQq<`BA|`Jew3Q3f!{d?2g0Q!rvMpYK{Ammv%v9KY-6e
zhji+Jqy;ZXJ_im3(}F6rnVGU)CIgzL29iWzVhxtV9&FXk1LsSh4d7(&imtH>O8o~V
Cf+>*z
literal 1437
zcmb7^dpOez7{`A*Ip((MP+`r9a)}5va%T}%ZpS5;nrqH67OR%a%;nK(LNO(s3hf*n
zVnz~KVmd4=w{grulxt`dYkOvG&OGPe&L8KG_kI6(Z_o36KhK-%>+KFvf++z206}@U
z`pIIJ%pw%zWqy=EK*<7y5D<)ajky$k5re~H5)%L*rL?TS4VrDfi}aqpXx!d$(lfsf
ztW{bY20~Edb>NJ;fH2cti5~}Uv#2PZpz+3&wj*c`?ru8`jnh3?dNjzm
zz8sP>S{3fSXOPrc^S0bF-6AWxFM`n$v{^Lz(5J#oUdLVK-Oft`-)C(XZBX{5P)Xzu
zg7|_rypWMQ+8yeQ97fVQ#mp|tB|EA?JQJpfY~VUD>x1nG#1cLefZ8}{!2xUYE7&Gg
zqPLW>{MslBZUNXt0T;V~xoe=FA9j!rY%g&x(EL`S3b;Oegcd~W^UG%ANV-(m&8HeQ
zmusc^&B6Ssr{8WKfYDg20Z$hM$_{$IzAHxa#o+9q0H&
z4!M#>(TB6(&_FfSMK?#eo9e*i86Ci0TB9y}Ic7OOw=3ngG<}rJN$e;uEQI=sCoX(t
zHZ46hTTY%I@B%7&Q_=pcUm%!qB>r7`%m^=|Kd4B`*7e=7J=!5->RB`~(|S$6JV7{-
zF){Y@{-|z;zsZ$opk?E8)^xAWjJPv3roOLMcEqww1w<+zoFq
z>eEvGtgXD{`Iik65u(>!4f;d0U8aE+lz}DoGYB~BZAQOEEAQ3{XYjz3Hz>8YyKxo|
zR>)(nig`W_#OE0ILh+2O{hI%dIg5RR1w`flR`wf`8v&D|l!)RI`j_ShA)bQM$IbPq
zFf1=ZDnRoKq3VV@`NS8ZrES7LZ>&zbPTT{6kdU;fTYkv)I2pP_YS0*H4(ki3r)W#7
zIAlN0N)e#2Lr+bDr!1XpwaTgd2Y4fmjzRsXvwSgw0uwLZYNW%r{0ZS>3Iu6tGI0yN
zQIY5PV|t&x9gm|CqO$5oM>D@lwY
zhcUvK%4y|H7z{HaCT7MMV`j|p{lBx;+Q)D2{e631dw>7$y3F;?yz{)zJMZ)S?)(1T
zzx#Igyo2qwEoxgJ5XiP~zp=gmfoyyXzHa<(6L`kzr*01TK{4*)rEAuHk-k@hzP}cP
z42M9j7hoU0$(TL7_09m(+1i+7^ux^$V?8NDDQ&%a7oQ)w>y&pfV&f8-wZZj9wB6~L
zQRh+?-b)lS?8cts(0Cr9tqt=~iwAX2l`;5O_kwRW=?B-u8!DzhyJklG{>F``%7)z#
zXq*42#V|GhqeeC5V#_+|#Pv(ag19uEMZ)!CDZl0o=>sWMD
z{+!!PWyrQ;$Dc&J);x{jSW+j(o^jO2&8vqC;(`kvW^G58QF=~4z4`TskJGgIm#VHh
zj~+*z!>81w7rp(d&HKzxb50t2ee-`W`Xoxbp^|ffr2g{e1Mvp^62EPqzhBAt!WNYa
zzi;{E-gl$t<{#7y6qCMydFq;djVtRtl|lu~
zVg9M!`J>!DgQl!*QczfZs4rgUrA4ik9u3!?cx
zxH@#_+nm9{U2B7#wObnR+QQ*&qocPJT73@Iq(0*n9JBw{-N0(cejmlcJwY3TE5|oI
z$h#Vrk@w~PtW(x67X(tMe{Sfp-{&(T2SOLPO;w(vUQTbnBv(|V#Y*s3If#SngFmL{
zN}o4~Sf&j`9`a>2WDDff!3|$PZd}~B|0Pu@5~bc_&<1^^%sw%h95?{1+)Hc|(25aj
zYisQ;==CIGOkWvHLgQB3Jv?;R14+PL{W5iTkmSP>BMhBeF&Z4vXF{^J-pcb8t}T{U
zU13h*YzVH_?JjO!yTIEs6REAiE^IuWqDF2AOD*a#%6>;ANFhqYGi^e
zHJWY>9-Vm*{%)ITdzz~8Q-;YJkEhI^jzO$>CJJU+(^^SkQ;kQK>EhWi6oWMlk7JVE
zum>BqZf$oqk7h(LK5gDPyI$^W$LbhVnM_wV?R4imczY2~`u4GkJp3h{6e=u|Uf}F-
z+z&s;S?JT_N|E4vCsbmXM*vD2!p(moIdED)75$uWi-X|g;4aXpf}2a1Sph|dOAc_V
zqoXORboJ;WlQBbT3ehIHPkN?n}8225m5L$zw83z;<9tWgS>FmuY
zy6nYMK9+iKta^Rmu*Rcc9Q?aY#GK)?AwepNsJN5?1NY(2Ee1U8kVs_2aFio9Be`)U
zmp(uc{A`1_u@0544@K6ZA%XH%qI*ttxfU!YQ{Ocn={6(86RQeEO?=iCYcJh_K(fG;
zr&Ho@jG~aq9#b*XRj*z08x{zo_JuK>K~Q5$OAaHt5J*t0Ch8@whdAZChObv*!k1c%
z6X(fC=IT<1QIye9muuIqF>25v9<#=$BL!OhD_p1>{u(q8Ncm^yA&?83L1*~v^HUoj
z-|W4y5%N<-FJzJdn1^!+0-PV7-0~rsK&J{~7pAVSpH^-C9`KT^5Q4joNOprdb)jW`KQuygQ7lY7%
zN!ghSL`%+ybA))aZkBM}e7SKhMS)bM(aF~x@-xW6Rq3D0#0fexxohO
z8nVR5-_@kdTl*qiS8YjheVXn~8p&+SAIf}RW?-1eYa?a?@#`$)OX%HJ0?Jw~U-T&<>v!Na
zcaDp4yCw#PbUC>m=x`&yL<)opZq54Ea
z#^M40@JD+B^rc_0D
z+c5~q(mFd6eR7@aQXS_~4$GB()P)_mGnSTY#vO5T
zGbB-p4-&Wsj1V0VE8S+uKCK+7vq1L!R<{78sHZ;g{Zk*|4{m3CVO7P^3FRS|>Vuqy
z#yPm2qO{tOF)rw2pinx=wm{kOjI}lUb|HHV20PR$K$({iiNr^yNbjJKR|%sPK0U8b
zoy7TeX?A549sVk#_=Ji7K%oa*@>|^E#l=g6$%d_1CjLNG%h`cDOzAL)4Ew&${i}bz$>ofLzlQg_nxjUiHb>p6bj|g28hPm{ZcUv
zrllqL*>*X2%KO#Tc~nmY`8=B5ovp|JMu;LKR^iK`jn{c}1R%WBay_EFx`RL*2U5YZ)33NZ%hKWb|^DPPW@O)FG0ka{$T;?If_8ywCo`QTK5DL
zaN}E;VRdur)W(Drx+7Z1zMyr(5G{!67|c_e0(v6W^eAp|>!I?g$Mg^0QS?NSiwPP2
zKYQCrbjDj-ThGo#yGmR~z=*iVJi;el=Bh<9R9t7UyF6xfu5-{%=6yssR{6m``;=@w
zH&-=$KCZ}rx7u~gXs{Dz^g`U>dRODO{26#FpFp0)C+by+#WY$Puj_sKLjy0kwY6vT
zgkRFg9OK5u!1k&gaUX|l@$IUE0Yz~Y`fqh1gK@G^S-W<~gJE{Jy!3aQe<5rClI8qa
zfd1zr>~BU}^7$!Nt7zHhXgKY1_N$EO#!Q8ZU8K(-^#%c_x*oaL`Mcy1HbHLOiugu;
za9dA~DQYt$>lu-V9(VNMHE0ETC1rl>9^L8Kf_-GP_aH*-Q^3!z?k#7*7N0#hgZ2|W
zsf*);L7`4lU(ofmQX**fhS;%%zI?l8X3bOCS6pwju%-BD0tly3w`c<@OJc*(=ysLQ*
znvC&crNO~{j+1K82)6{p87lo)_|$H>(VJx6ILy~~5r;(JD#nct?{H*}*L2mC=$=cS
zD|1MfQPxS|$=9g4&h&_(1Ql!*q6nTJ7oN*iM-k&YSC5w!T#mXs4pe?HIk{UYafe$t<)p5|i39$9
zc`kxpvB0M8=|tY-ZJMS#LD2C2pjL`Ub^LrmkH6QYU``H*4HdGj=UZC%O+1L*kYGJK
zbQs*ZxwRGx*AK=`UMAMH@lS2FwzkH(THsx=Oz4@O3%q=hbhp|{914}%nV98;4h~xi
zw;1?cffbgzBVw`~%6epuU(LlJ_dA%IpyaWoHCle8Jd19N>XBgFt)`o$b~(xeSTA)g
z4|i!QRa#kEd86^#;;^>%Q>NUf9atkEi5Q>AzQdmmK6ZC)&keb#!3|%)JDzEIUJT8z
zZ3(*hVuG9hM1y4vQDFTf)cO4+nLv$eDCc^7m24rN=QsnqOC~H7E{A@8>iBoPmLaF>
zat5zWSPVu&w*Ls}{%VdV;*04c(GRBOEEHx=t!td$zF8N>zB!BP68pV}ZA9wEZGV09
z7Xmx4bN#;(+JD(zHtzrXrh1v^mB1bC7*TXHGPv-s^>3TgHxsoQ_s&u
zH+L_84JHoL(_W168l6p>HthommW%8N8i4P(X=&|J=6C2^`X@RaGXiYey7k%Zl{gk1
zFk*?`78T8YKrOpVRxJ4K(7DczHVX?(=5Mi-8S)zZ{%J{xj%F*ZXjGL8hUdI7mdb*b
z5;byQNvAViT^#qAUJfD!n$YK0ie%;gc1+wa!~v5ys_bgRpI3RpxX|uz>h;`Ny#O
z=q+lK4~#+*c$rj}c!9LI%ieT)BrDMkGpeoa^X3Qn8jz*Gk$_}1S<$fN3f4Mx8FXd)dMy;Ij=>e%7KhszU>
z?bD_m`nf{|;d$=S;VYREFvU!+9k3jw+gfk+vLa~Z2E10|v%uxj)-F}(JGOS@ClgT|
zGkJ_2+1Vt^s1?SrsmQ39>I|w7d%Z_QG1b+c^*~5hm+&pDgvfp~PVX3J~oi%aGpVzE;N=F-9Q@>C1
zwR9Pw0h!@D%_v?2%vU4VVt17*F98`}7cy%4@th2ldFAX9z+a+v3bP0@tBgXkBi)G_
z-XL{434%?Z4HXCW0yktp-?N`6_h*X2-$(vmNe};#f!mS1jc4rK+}uFg22Dsv$Tp&b
zd4dWVkIdYq=b8l%K!ogWs%D6$mwKsUvY*sSmf|HRUup<-Ukri2y!`b&r?Tu(kr!!M
z5-86Ui?w@fp5*|Q^K)}=
z1GY}i@v~UCA@3T6c-yn%9$5a|%qNm&VQ+2{^tVDi6vX_$hN!P${csyY7iN&J2
zASJ0H2NWmuD=>x=_hX{lcRvDz1T8gvbxlpJveplvQnD&0*|z5+e)q&syu(Kdjkw}I
z8Z&V?F}^?;8o8ha9RgK|P)f`31~C;-?+L~|Z&{RO|(pg--m$6
zUp^N!#v*PkvHe910k;2xK=Qv~PG|IQL`OyKlEsg}X$nPVN?u-GrKBt0^%4oWXp}L)
z^Ox>PZnK>`BTJDrG&CZ{R@u;jv`+ojdN5a)rCKujd{!{ZyEd0@sw^ibcPppNp-?Ty
zJ1)q1Y&_E+l!?`wlVP&K3Y4aGUG<)gu(g!$hR
zlsgu@I$BYxEH|N-c_Ef|D2Kr>o)o=d+dqq7<<#B
zN0Bf;HPJ}3cL(e<^r~BGM?{ID3YU(DH*a1K?#i&p(6G32dJilrxVOk0UvKgVs1g9P
zUR1I#U?`Ei3xffOIF6&wB5V3Wu#$m@qnLsab1=Q=-*KoN;yz-pAO>8j2f71k$;ns`
zR(dB>=5fFn15zhjt%RcuNNQ_W4Y(*~pwJ=HJr9JuAh#xnE-PtkS2Zu+(y4$wg$OUm
zR1RNVhqPMsLHFOhZK)EOwJdyecB{AiKrME{#|KJGBkaCA+eW!Q`Q-IgF#0bSK@
zw(4LeT8viOM36xT1j!rUE{zz^L!j_8vSAM=#jV|iCjJ%*I$9DZf|G*CNKU>x>Xzkx
zOk4Y*Cpv-Mjuv;>Rbc~$o?c)9gO4qOhM%p!na))5Ze7U0*kKW@1nc%J_np3=1mCOy
zfGUJLT+&$_uQNMpMM>^A5WOQ-llimGRdB3p`Oy}^#a<$IYpm3?Nv{|9$#hLXeJ$>K
z0aX~JSBWmqmuPtz?LI9O3NPeS>H?kSb@;q5pipAmoBQ27;v_Di@9EWBZiMIw6P{n-
zYdT0t8vq}-{ZcVi|3E?lX(}RWUWc_9dquj_Zd*ZHIdQXz;dCNf8^R8yC@9$0^#M09~x
zChTcR#QcgwV|MaHKuf_1z1l*LKaK1MpE)%MW$;fL?|
zMPf6mS(2bZn;Eg1mgzl)QHd2q&GjYn02X}}PtSHiBk{!QxjhAU&c~1jjnlY?Pkf9k
z9ift$EV@~VFBo!b#3}5W4=HRJQHtnLM1XpCJ=2|b+rq-e*4FkA(I@^a0Yv+AE=o2S
z99Sd1{mRf3cq2dt-VzYAKs6zA9mS(>4fJZu{aHb0)4&PK-B82S(W0h=4|Seg
z<9pnf6O9(j^==O}rMxK7+kjVU1M$ZgRmftm=yfuQsaQO}#9|q0Ymb>Snimz#eJ4P<
zO0o5&v5XdhT6gxbTYq1;A7z1;YF@&JS9gJwr@l6YIFq8+*+sMb3qfqq3=sNWexnlI
znUn~;YA!beqo=lyh~AATRA?GEA&Ga8ixzlpwu&X^*<-x$*QL|IGGa%>C0i2SIj&^CHTlQN1U<#<<-iy^WUIjTtz^%n^bXaMi
zWRrf~Ug3*VH+d#UAtvTKHVk^&Gds*3(e|F#-ubd0KFAE^-OsB4g^CdW0f5)W+P#&aggse3Uhf~y9_;3%
ze8|Z00#0RQ^59E=wl~9eB1#=)d2O4YF)$s1Ba4-6WZ8P!RG3}AzHEB7l2Rg!5-SXu
z^`N5m^)p{#!*0d;!VCo8VMi>*9l8}Z#wcm74Qszc!D`BSlKeo&-eNJm+eWdX<4D)Z
zop^&dTXqc{s9|c#S&5vY33F6(OA%38>Fe`8?^Oqk4^!obHy-ug`Cv{|W8zN%GG_ZY
z-m29w`lDgGRxf*Kjg01HW+%B8x$QafDw!x*F;9tuDU-UfsGd>97`kAf!FAT2L(E#;
z9asSHO+(WVnWPTV9CfytUp&m?RP%k|VfN)wS_GkPGxubqH0h~i`(v4~8mZxXn)ckr
z=Fs}W61RtPg7zL!c%l(__Q2t6Igo49oH%>}&~To8YNwf+>=ocUYnY*N(se=IhtPS~
z*&Avlw?YJFU{7Tg429QmeV}@TP25yjLra(JH-@17AH9Bm3E4PT;stw(TcD;5TGZ3r
zIl!{Sv7J6}!vAo5qONPZdWqih^!Gt6iFAGTw5T}Qw9gPDtP({)0Gw-+>aKGda0lzs5o*zu|{jYb6^}x8$zG8
z{@8~$tB!pEj|c4Mi>@7T291$P+9lK0epP3EdHtG|{r0J#W&peX5v=UeNgFJU(TPVu
z+Z}10YWO%cdsnw8&Cb#tBim$fFI$Ybp`LU3;n6$BuhK-RPfXNvyWcV(5U4=b3n02z
zbLWW#lF`Lx=>vy6>u{6ee0`J@E&34ig={m;e6B)aWcXbc1+W(Lig9NQ^Pbdby+7fW
zJ(*-5vY_0z{7S&8nqENfhn`Xz9xk;@rHxgkXJS3e4IvQG6`~xNDx}>x!gpH%k755v
zf%?a>><`u4f0t3KJ=m~jqU4h5U;U&?Sc4AB#nq>}E(z*JU+LF9j2=2`!HONA*7w3E
zZS=VDOHr)Q-v-q3TQGiOM#?TAld2;@Ag9z-9|V9zb9eLKsy+X^e(j&C+5g;(qZ{N0
z{aCSXMgUe}!CgC88%$Vu5)8)@7DY4DHrCc$Utn?#SN}sC%&7kKfTO#_9L%UdK-(ki^j`3F
ztn}8za(u4~*4Aq+G-O`uL)Y^x+dHnG1kA{O18wc+-u(XO)up>eME9QTij(qknB8CY
zP&if3tLHCY{3F&Dy4-!^(saeELehkZS7eQ1;c-O
zt}<}r!IQk>0j3H1*vFL2t=K`1Z23T=;N`gF{|PAfMV4R>OABa4e}*2$L|tlUHPfI@
zsl**4Gaq^b1ai6f|Cagi7C&ZE+*(H1k?47xVXXKvgB8XKNiQjt)$vrLc(&a3oz7#c
zhBPnHeL?~WFMU-{Vf{K}FQ#9*zmDYxs%PV6>J-V8ohD+XBmXRhK*STOO)?(B8dtL;
zFKl5Z>A?U&7EU}9LtVe$r6T<_G#vc5<^XdCt&xb%W1N6`4a;F<NMIT|gN<()Czf7-%JNm}
zP9JGq4>GV)z!l;WI
zu1|~^U7CpmOwkI^OfaZ*TYr06}m;&J&yRDz1X_mVaC!!sGg+94u7kg?G&!GKx~fAN4F~q
zN@ASa^BvOX`~iI6l;ux*E`X`Ij<+>?DA>sYeY#SR-h42ftke2L?)(1Zv@hBS?^t1I
z_dA;?vn8WXSIdrneK`=zSdrig11t|OzG$0$rU6{*R3w)b*UuGSXhYPwfTAqh9tbfX
zh@W95Va;_)c!O{&(uD?AB63ddfv$Z?@lb1OFcI3Pa5U*0tq2GK
zw4yuu^>~S2lgyrk#D05(q0!jjC5*J1k!M9G;^NpdYHIj8Se=W#gSrW~ESP0yMTswtyPjp7F-yXn4S=);nn}$;b@QiT>CJ+=ll(0>YGlfT>~f
zE`<8HDxMM-Qp&!1N8R9&(Nl?Eg)64xIIX~0W=tK8K%8qtpH5khWoleu+;lK5&l1=M
zn^cuuC$q?*>&M%E>uLoXLEb}|hCT8sp692o_ULB|=QT!CQ$2zWy$yQw@lzL6;US;k
z-BqwF?@6f|TEe=<(gsoV8HsBl@FVz`;ki8e0ge`24<(Ig&+vI`ua)8PTq0a1Z-z(7
z&Sa^Mh^UwJ5~NBAgk;mgCR+3l4+{Y+#6Ujq6FiqgT`4JKe{2SfS|x3`2x&Ia%QLY@
zX_H~sX5z&-N%uV3oFVN&3cj|k)FUK%fxbajlOL#V<+Ty4ku@6E_+9?8XtKsP)7RGV(T*<1LbWV`0
zgUue);n>B?ELv~D(K1yIKz#se`eGun=C_t$YP5uKi$i3Wo0Rqg!zJblC|J-?@AF<_
z9OtRU0?d~)#{Zw)m**)Qi{Sd!RyQBuepxCXl`Ew1UigUal|
zw%bFsS(2GaEvw=guo88PPh_mPSA%_GwTSQU)EOu4fHuD!BTI_`?%UKMrL)!K3J&bh
zbFgR4lq7a4M_NLgT?5c@DLocH$3fou;kjpVTQoVKi(WNjh)5E{_QDpal
zGDdVfr6o4o=@QBAk}^?3=69F|gl4!@C&oAtJ$uK&sNr=fd@=bFcL_7=(#8OWD=!l+*1@nFLumtO()U(7yKHI@~%fe1kw{!^n;R}J63YH&BpB@(G}T{0-ExQ50w=tBF=}vb@y#Gy!59sw?h8bK;^u~#
u%bOn$wsuajWT{lcU$v|M=dlIAvNx`OPQezef&Y8~`PRn4y6W`hAO0WjsXWF2
literal 13346
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
diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi
index 16413ee54271925df85877f97cfec424fda9c669..9c9afbc7dc852b18041ddd152316c66939f8d38c 100644
GIT binary patch
delta 11517
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