diff --git a/SQL/migrate/V025__cargo_approval.sql b/SQL/migrate/V025__cargo_approval.sql
new file mode 100644
index 00000000000..b82e219982c
--- /dev/null
+++ b/SQL/migrate/V025__cargo_approval.sql
@@ -0,0 +1,9 @@
+--
+-- Combines the ss13_admin and ss13_player table
+--
+ALTER TABLE `ss13_cargo_items`
+ ADD COLUMN `created_by` VARCHAR(50) NULL DEFAULT NULL AFTER `order_by`,
+ ADD COLUMN `approved_by` VARCHAR(50) NULL DEFAULT NULL AFTER `created_by`,
+ ADD COLUMN `approved_at` DATETIME NULL DEFAULT NULL AFTER `created_at`;
+
+UPDATE ss13_cargo_items SET approved_at = NOW()
\ No newline at end of file
diff --git a/SQL/migrate/V026__law_database.sql b/SQL/migrate/V026__law_database.sql
new file mode 100644
index 00000000000..b6c3a18faaa
--- /dev/null
+++ b/SQL/migrate/V026__law_database.sql
@@ -0,0 +1,21 @@
+--
+-- Adds a new table to load the regulations ("laws") from
+--
+CREATE TABLE `ss13_law` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `law_id` VARCHAR(4) NOT NULL,
+ `name` VARCHAR(50) NOT NULL,
+ `description` VARCHAR(500) NOT NULL,
+ `min_fine` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `max_fine` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `min_brig_time` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `max_brig_time` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `severity` INT(10) UNSIGNED NULL DEFAULT '0',
+ `felony` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `deleted_at` DATETIME NULL DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE INDEX `UNIQUE LAW` (`law_id`)
+)
+ENGINE=InnoDB;
\ No newline at end of file
diff --git a/SQL/migrate/V027__newscaster_static_news.sql b/SQL/migrate/V027__newscaster_static_news.sql
new file mode 100644
index 00000000000..329c799a4b5
--- /dev/null
+++ b/SQL/migrate/V027__newscaster_static_news.sql
@@ -0,0 +1,35 @@
+--
+-- Adds a new table to load news from
+--
+CREATE TABLE `ss13_news_channels` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `name` VARCHAR(50) NOT NULL,
+ `author` VARCHAR(50) NOT NULL,
+ `locked` TINYINT(3) UNSIGNED NOT NULL DEFAULT '1',
+ `is_admin_channel` TINYINT(3) UNSIGNED NOT NULL DEFAULT '1',
+ `announcement` VARCHAR(200) NOT NULL,
+ `created_by` VARCHAR(50) NOT NULL,
+ `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `deleted_at` DATETIME NULL DEFAULT NULL,
+ PRIMARY KEY (`id`)
+)
+ENGINE=InnoDB;
+
+CREATE TABLE `ss13_news_stories` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `channel_id` INT(11) NOT NULL,
+ `author` VARCHAR(50) NOT NULL,
+ `body` TEXT NOT NULL,
+ `message_type` VARCHAR(50) NOT NULL DEFAULT 'Story',
+ `is_admin_message` TINYINT(3) UNSIGNED NOT NULL DEFAULT '1',
+ `time_stamp` DATETIME NULL DEFAULT NULL,
+ `created_by` VARCHAR(50) NOT NULL,
+ `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `deleted_at` DATETIME NULL DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ INDEX `FK_ss13_news_stories_ss13_news_channels` (`channel_id`),
+ CONSTRAINT `FK_ss13_news_stories_ss13_news_channels` FOREIGN KEY (`channel_id`) REFERENCES `ss13_news_channels` (`id`)
+)
+ENGINE=InnoDB;
\ No newline at end of file
diff --git a/aurorastation.dme b/aurorastation.dme
index 67db7cab5a6..2f02b8d563c 100644
--- a/aurorastation.dme
+++ b/aurorastation.dme
@@ -170,6 +170,7 @@
#include "code\controllers\subsystems\machinery.dm"
#include "code\controllers\subsystems\mob.dm"
#include "code\controllers\subsystems\mob_ai.dm"
+#include "code\controllers\subsystems\news.dm"
#include "code\controllers\subsystems\night_lighting.dm"
#include "code\controllers\subsystems\orbit.dm"
#include "code\controllers\subsystems\overlays.dm"
@@ -190,8 +191,8 @@
#include "code\controllers\subsystems\zcopy.dm"
#include "code\controllers\subsystems\initialization\atlas.dm"
#include "code\controllers\subsystems\initialization\atoms.dm"
+#include "code\controllers\subsystems\initialization\holomap.dm"
#include "code\controllers\subsystems\initialization\map_finalization.dm"
-#include "code\controllers\subsystems\initialization\minimap.dm"
#include "code\controllers\subsystems\initialization\misc_early.dm"
#include "code\controllers\subsystems\initialization\misc_late.dm"
#include "code\controllers\subsystems\initialization\xenoarch.dm"
@@ -370,7 +371,6 @@
#include "code\game\antagonist\antagonist_update.dm"
#include "code\game\antagonist\alien\borer.dm"
#include "code\game\antagonist\alien\xenomorph.dm"
-#include "code\game\antagonist\outsider\actors.dm"
#include "code\game\antagonist\outsider\commando.dm"
#include "code\game\antagonist\outsider\deathsquad.dm"
#include "code\game\antagonist\outsider\ert.dm"
@@ -745,6 +745,7 @@
#include "code\game\objects\items\devices\megaphone.dm"
#include "code\game\objects\items\devices\modkit.dm"
#include "code\game\objects\items\devices\multitool.dm"
+#include "code\game\objects\items\devices\oxycandle.dm"
#include "code\game\objects\items\devices\paicard.dm"
#include "code\game\objects\items\devices\pipe_painter.dm"
#include "code\game\objects\items\devices\powersink.dm"
@@ -1254,6 +1255,7 @@
#include "code\modules\clothing\under\color.dm"
#include "code\modules\clothing\under\miscellaneous.dm"
#include "code\modules\clothing\under\shorts.dm"
+#include "code\modules\clothing\under\skirts.dm"
#include "code\modules\clothing\under\syndicate.dm"
#include "code\modules\clothing\under\accessories\accessory.dm"
#include "code\modules\clothing\under\accessories\armband.dm"
@@ -1266,6 +1268,7 @@
#include "code\modules\clothing\under\jobs\medsci.dm"
#include "code\modules\clothing\under\jobs\security.dm"
#include "code\modules\clothing\under\xenos\resomi.dm"
+#include "code\modules\clothing\under\xenos\tajara.dm"
#include "code\modules\customitems\item_defines.dm"
#include "code\modules\customitems\item_spawning.dm"
#include "code\modules\detectivework\footprints.dm"
@@ -2058,6 +2061,8 @@
#include "code\modules\reagents\reagent_containers\food.dm"
#include "code\modules\reagents\reagent_containers\glass.dm"
#include "code\modules\reagents\reagent_containers\hypospray.dm"
+#include "code\modules\reagents\reagent_containers\inhaler.dm"
+#include "code\modules\reagents\reagent_containers\inhaler_advanced.dm"
#include "code\modules\reagents\reagent_containers\pill.dm"
#include "code\modules\reagents\reagent_containers\spray.dm"
#include "code\modules\reagents\reagent_containers\syringes.dm"
diff --git a/code/ATMOSPHERICS/components/binary_devices/circulator.dm b/code/ATMOSPHERICS/components/binary_devices/circulator.dm
index 66f4083a42c..d903908f89f 100644
--- a/code/ATMOSPHERICS/components/binary_devices/circulator.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/circulator.dm
@@ -1,8 +1,6 @@
//node1, air1, network1 correspond to input
//node2, air2, network2 correspond to output
-#define ADIABATIC_EXPONENT 0.667 //Actually adiabatic exponent - 1.
-
/obj/machinery/atmospherics/binary/circulator
name = "circulator"
desc = "A gas circulator turbine and heat exchanger."
diff --git a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm
index ea9da5b8a0a..d70c09d2753 100644
--- a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm
@@ -1,5 +1,3 @@
-#define ADIABATIC_EXPONENT 0.667 //Actually adiabatic exponent - 1.
-
/obj/machinery/atmospherics/pipeturbine
name = "turbine"
desc = "A gas turbine. Converting pressure into energy since 1884."
diff --git a/code/__defines/_layers.dm b/code/__defines/_layers.dm
index 90b8952c6a8..41124dc4736 100644
--- a/code/__defines/_layers.dm
+++ b/code/__defines/_layers.dm
@@ -3,13 +3,16 @@
#define PLANE_SPACE_DUST (PLANE_SPACE_PARALLAX + 1) // -96
#define PLANE_ABOVE_PARALLAX (PLANE_SPACE_BACKGROUND + 3) // -95
-// Custom layer definitions, supplementing the default TURF_LAYER, MOB_LAYER, etc.
+
+#define LOWER_ON_TURF_LAYER (TURF_LAYER + 0.05) // under the below
+#define ON_TURF_LAYER (TURF_LAYER + 0.1) // sitting on the turf - should be preferred over direct use of TURF_LAYER
+#define AO_LAYER (ON_TURF_LAYER + 0.1)
#define DOOR_OPEN_LAYER 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
#define UNDERDOOR 3.09 //Just barely under a closed door.
#define DOOR_CLOSED_LAYER 3.1 //Above most items if closed
#define BELOW_MOB_LAYER 3.7
#define ABOVE_MOB_LAYER 4.1
#define LIGHTING_LAYER 11
-#define OBFUSCATION_LAYER 21 //Where images covering the view for eyes are put
#define HUD_LAYER 20 //Above lighting, but below obfuscation. For in-game HUD effects (whereas SCREEN_LAYER is for abstract/OOC things like inventory slots)
+#define OBFUSCATION_LAYER 21 //Where images covering the view for eyes are put
#define SCREEN_LAYER 22 //Mob HUD/effects layer
diff --git a/code/__defines/_macros.dm b/code/__defines/_macros.dm
index d45d6b25fe9..1dba4b5b9c9 100644
--- a/code/__defines/_macros.dm
+++ b/code/__defines/_macros.dm
@@ -1,4 +1,4 @@
-#define Clamp(x, y, z) (x <= y ? y : (x >= z ? z : x))
+#define Clamp(x, low, high) max(low, min(high, x))
#define CLAMP01(x) (Clamp(x, 0, 1))
#define span(class, text) ("[text]")
diff --git a/code/__defines/atmos.dm b/code/__defines/atmos.dm
index dcc5dae90f0..7f1d870746d 100644
--- a/code/__defines/atmos.dm
+++ b/code/__defines/atmos.dm
@@ -95,3 +95,5 @@
#define ATMOSTANK_CO2 25000 // CO2 and PH are not critically important for station, only for toxins and alternative coolants, no need to store a lot of those.
#define ATMOSTANK_PHORON 25000
#define ATMOSTANK_NITROUSOXIDE 10000 // N2O doesn't have a real useful use, i guess it's on station just to allow refilling of sec's riot control canisters?
+
+#define ADIABATIC_EXPONENT 0.667 //Actually adiabatic exponent - 1.
diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm
index 42c6ea303dc..ab44ee8387a 100644
--- a/code/__defines/chemistry.dm
+++ b/code/__defines/chemistry.dm
@@ -39,3 +39,25 @@ var/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglyce
var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_drugs", "stoxin") // Decrease heart rate.
var/list/heartstopper = list("potassium_chlorophoride", "zombie_powder") // This stops the heart.
var/list/cheartstopper = list("potassium_chloride") // This stops the heart when overdose is met. -- c = conditional
+
+//Alcohol
+#define INTOX_BUZZED 0.01
+#define INTOX_JUDGEIMP 0.03
+#define INTOX_MUSCLEIMP 0.08
+#define INTOX_REACTION 0.10
+#define INTOX_VOMIT 0.12
+#define INTOX_BALANCE 0.15
+#define INTOX_BLACKOUT 0.20
+#define INTOX_CONSCIOUS 0.30
+#define INTOX_DEATH 0.45
+
+//How many units of intoxication to remove per second
+#define INTOX_FILTER_HEALTHY 0.015
+#define INTOX_FILTER_BRUISED 0.010
+#define INTOX_FILTER_DAMAGED 0.05
+
+#define BASE_DIZZY 50 //Base dizziness from getting drunk.
+#define DIZZY_ADD_SCALE 15 //Amount added for every 0.01 percent over the JUDGEIMP limit
+
+#define BASE_VOMIT_CHANCE 10 //Base chance
+#define VOMIT_CHANCE_SCALE 2.5 //Percent change added for every 0.01 percent over the VOMIT limit
diff --git a/code/__defines/gamemode.dm b/code/__defines/gamemode.dm
index b1707e9b8c0..c43bb0922a6 100644
--- a/code/__defines/gamemode.dm
+++ b/code/__defines/gamemode.dm
@@ -26,6 +26,7 @@
#define ANTAG_RANDSPAWN 0x100 // Potentially randomly spawns due to events.
#define ANTAG_VOTABLE 0x200 // Can be voted as an additional antagonist before roundstart.
#define ANTAG_SET_APPEARANCE 0x400 // Causes antagonists to use an appearance modifier on spawn.
+#define ANTAG_RANDOM_EXCEPTED 0x800 // If a game mode randomly selects antag types, antag types with this flag should be excluded.
// Mode/antag template macros.
#define MODE_BORER "borer"
@@ -35,7 +36,6 @@
#define MODE_COMMANDO "commando"
#define MODE_DEATHSQUAD "deathsquad"
#define MODE_ERT "ert"
-#define MODE_ACTOR "actor"
#define MODE_MERCENARY "mercenary"
#define MODE_NINJA "ninja"
#define MODE_RAIDER "raider"
@@ -46,7 +46,6 @@
#define MODE_MONKEY "monkey"
#define MODE_RENEGADE "renegade"
#define MODE_REVOLUTIONARY "revolutionary"
-#define MODE_LOYALIST "loyalist"
#define MODE_MALFUNCTION "malf"
#define MODE_TRAITOR "traitor"
#define MODE_VAMPIRE "vampire"
diff --git a/code/__defines/lighting.dm b/code/__defines/lighting.dm
index 0b4096636c8..d4097da3e59 100644
--- a/code/__defines/lighting.dm
+++ b/code/__defines/lighting.dm
@@ -16,6 +16,13 @@
// If defined, instant updates will be used whenever server load permits. Otherwise queued updates are always used.
#define USE_INTELLIGENT_LIGHTING_UPDATES
+// If defined, lighting corners will 'bleed' luminosity to corners above them to simulate cross-Z lighting upwards. Downwards Z-lighting will continue to work with this disabled.
+#define USE_CORNER_ZBLEED
+
+#define TURF_IS_DYNAMICALLY_LIT(T) (isturf(T) && T:dynamic_lighting && T:loc:dynamic_lighting)
+// mostly identical to above, but doesn't make sure T is valid first. Should only be used by lighting code.
+#define TURF_IS_DYNAMICALLY_LIT_UNSAFE(T) (T:dynamic_lighting && T:loc:dynamic_lighting)
+
// If I were you I'd leave this alone.
#define LIGHTING_BASE_MATRIX \
list \
diff --git a/code/__defines/math_physics.dm b/code/__defines/math_physics.dm
index 80f8798bc75..98e0d8751b2 100644
--- a/code/__defines/math_physics.dm
+++ b/code/__defines/math_physics.dm
@@ -19,7 +19,6 @@
#define T20C 293.15 // 20.0 degrees celcius
#define TCMB 2.7 // -270.3 degrees celcius
-#define CLAMP01(x) max(0, min(1, x))
#define QUANTIZE(variable) (round(variable,0.0001))
#define INFINITY 1.#INF
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index dcc78c3ed81..736daff97b7 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -250,16 +250,10 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define CAPTURE_MODE_ALL 1 //Admin camera mode
#define CAPTURE_MODE_PARTIAL 3 //Simular to regular mode, but does not do dummy check
-//Sound effects toggles
-#define ASFX_AMBIENCE 1
-#define ASFX_FOOTSTEPS 2
-#define ASFX_VOTE 4
-
//Cargo random stock vars
//These are used in randomstock.dm
//And also for generating random loot crates in crates.dm
-#define TOTAL_STOCK 80//The total number of items we'll spawn in cargo stock
-
+#define TOTAL_STOCK 100//The total number of items we'll spawn in cargo stock
#define STOCK_UNCOMMON_PROB 23
//The probability, as a percentage for each item, that we'll choose from the uncommon spawns list
@@ -270,7 +264,6 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
//If an item is not rare or uncommon, it will be chosen from the common spawns list.
//So the probability of a common item is 100 - (uncommon + rare)
-
#define STOCK_LARGE_PROB 75
//Large items are spawned on predetermined locations.
//For each large spawn marker, this is the chance that we will spawn there
@@ -278,8 +271,6 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
// Law settings
#define PERMABRIG_SENTENCE 90 // Measured in minutes
-//#define PERMAPRISON_SENTENCE 60 // Measured in IC days
-#define FELONY_LEVEL 2.0 // What is the minimum law severity that counts as a felony?
#define LAYER_TABLE 2.8
#define LAYER_UNDER_TABLE 2.79
@@ -456,3 +447,13 @@ Define for getting a bitfield of adjacent turfs that meet a condition.
#define MAX_SOUND_Z_TRAVERSAL 2
#define Z_ALL_TURFS(Z) block(locate(1, 1, Z), locate(world.maxx, world.maxy, Z))
+
+
+// Z-controller stuff - see basic.dm to see why the fuck this is the way it is.
+#define IS_VALID_ZINDEX(z) !((z) > world.maxz || z > 17 || z < 2)
+
+#define HAS_ABOVE(z) (IS_VALID_ZINDEX(z) && z_levels & (1 << (z - 1)))
+#define HAS_BELOW(z) (IS_VALID_ZINDEX(z) && z_levels & (1 << (z - 2)))
+
+#define GET_ABOVE(A) (HAS_ABOVE(A:z) ? get_step(A, UP) : null)
+#define GET_BELOW(A) (HAS_BELOW(A:z) ? get_step(A, DOWN) : null)
diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm
index 342cf78a0f0..814b577a368 100644
--- a/code/__defines/mobs.dm
+++ b/code/__defines/mobs.dm
@@ -100,9 +100,7 @@
#define INV_R_HAND_DEF_ICON 'icons/mob/items/righthand.dmi'
#define INV_W_UNIFORM_DEF_ICON 'icons/mob/uniform.dmi'
#define INV_ACCESSORIES_DEF_ICON 'icons/mob/ties.dmi'
-#define INV_SUIT_DEF_ICON 'icons/mob/ties.dmi'
#define INV_SUIT_DEF_ICON 'icons/mob/suit.dmi'
-#define MAX_SUPPLIED_LAW_NUMBER 50
// NT's alignment towards the character
#define COMPANY_LOYAL "Loyal"
diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm
index fd4c172afac..a93974d13e4 100644
--- a/code/__defines/species_languages.dm
+++ b/code/__defines/species_languages.dm
@@ -40,6 +40,7 @@
#define LANGUAGE_SIIK_TAJR "Siik'tajr"
#define LANGUAGE_SIGN_TAJARA "Nal'rasan"
#define LANGUAGE_YA_SSA "Ya'ssa"
+#define LANGUAGE_DELVAHII "Delvahhi"
#define LANGUAGE_SKRELLIAN "Nral'Malic"
#define LANGUAGE_RESOMI "Resomi"
#define LANGUAGE_ROOTSONG "Rootsong"
diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm
index fbd6411c4e7..60e35567e19 100644
--- a/code/_helpers/logging.dm
+++ b/code/_helpers/logging.dm
@@ -5,13 +5,13 @@
// will get logs that are one big line if the system is Linux and they are using notepad. This solves it by adding CR to every line ending
// in the logs. ascii character 13 = CR
-#define SEVERITY_ALERT 1
-#define SEVERITY_CRITICAL 2
-#define SEVERITY_ERROR 3
-#define SEVERITY_WARNING 4
-#define SEVERITY_NOTICE 5
-#define SEVERITY_INFO 6
-#define SEVERITY_DEBUG 7
+#define SEVERITY_ALERT 1 //Alert: action must be taken immediately
+#define SEVERITY_CRITICAL 2 //Critical: critical conditions
+#define SEVERITY_ERROR 3 //Error: error conditions
+#define SEVERITY_WARNING 4 //Warning: warning conditions
+#define SEVERITY_NOTICE 5 //Notice: normal but significant condition
+#define SEVERITY_INFO 6 //Informational: informational messages
+#define SEVERITY_DEBUG 7 //Debug: debug-level messages
/var/global/log_end = world.system_type == UNIX ? ascii2text(13) : ""
@@ -39,6 +39,9 @@
/proc/log_debug(text,level = SEVERITY_DEBUG)
if (config.log_debug)
game_log("DEBUG", text)
+
+ if (level == SEVERITY_ERROR) // Errors are always logged
+ error(text)
for(var/client/C in admins)
if(!C.prefs) //This is to avoid null.toggles runtime error while still initialyzing players preferences
@@ -51,7 +54,7 @@
if (config.log_game)
game_log("GAME", text)
send_gelf_log(
- short_message = text,
+ short_message = text,
long_message = "[time_stamp()]: [text]",
level = level,
category = "GAME",
@@ -92,8 +95,8 @@
if (config.log_attack)
game_log("ATTACK", text)
send_gelf_log(
- short_message = text,
- long_message = "[time_stamp()]: [text]",
+ short_message = text,
+ long_message = "[time_stamp()]: [text]",
level = level,
category="ATTACK",
additional_data = list("_ckey" = html_encode(ckey), "_ckey_target" = html_encode(ckey_target))
@@ -108,7 +111,7 @@
if (config.log_pda)
game_log("PDA", text)
send_gelf_log(
- short_message = text,
+ short_message = text,
long_message = "[time_stamp()]: [text]",
level = level,
category="PDA",
@@ -119,9 +122,9 @@
if (config.log_pda)
game_log("NTIRC", text)
send_gelf_log(
- short_message = text,
- long_message="[time_stamp()]: [text]",
- level = level,
+ short_message = text,
+ long_message="[time_stamp()]: [text]",
+ level = level,
category = "NTIRC",
additional_data = list("_ckey" = html_encode(ckey), "_ntirc_conversation" = html_encode(conversation))
)
@@ -187,7 +190,7 @@
return english_list(comps, nothing_text="0", and_text="|", comma_text="|")
//more or less a logging utility
-/proc/key_name(var/whom, var/include_link = null, var/include_name = 1, var/highlight_special = 0, var/datum/ticket/ticket = null)
+/proc/key_name(var/whom, var/include_link = null, var/include_name = 1, var/highlight_special = 0, var/datum/ticket/ticket = null)
var/mob/M
var/client/C
var/key
@@ -217,7 +220,7 @@
if(key)
if(include_link && C)
- . += ""
+ . += ""
if(C && C.holder && C.holder.fakekey && !include_name)
. += "Administrator"
diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm
index 12b20e6111f..eb2a137c078 100644
--- a/code/_onclick/hud/parallax.dm
+++ b/code/_onclick/hud/parallax.dm
@@ -259,6 +259,7 @@
LAZYCLEARLIST(parallax)
LAZYCLEARLIST(parallax_movable)
+#undef GRID_WIDTH
#undef PARALLAX4_ICON_NUMBER
#undef PARALLAX3_ICON_NUMBER
#undef PARALLAX2_ICON_NUMBER
diff --git a/code/controllers/subsystems/garbage-debug.dm b/code/controllers/subsystems/garbage-debug.dm
index 4d9c6832c5a..cfe1a429159 100644
--- a/code/controllers/subsystems/garbage-debug.dm
+++ b/code/controllers/subsystems/garbage-debug.dm
@@ -603,7 +603,7 @@
SearchVar(floor_light_cache)
SearchVar(HOLOPAD_MODE)
SearchVar(navbeacons)
- SearchVar(news_network)
+ SearchVar(SSnews)
SearchVar(allCasters)
SearchVar(bomb_set)
SearchVar(req_console_assistance)
@@ -829,7 +829,7 @@
SearchVar(lunchables_snacks_)
SearchVar(lunchables_drinks_)
SearchVar(lunchables_drink_reagents_)
- SearchVar(lunchables_ethanol_reagents_)
+ SearchVar(lunchables_alcohol_reagents_)
SearchVar(message_servers)
SearchVar(blackbox)
SearchVar(responsive_carriers)
diff --git a/code/controllers/subsystems/initialization/minimap.dm b/code/controllers/subsystems/initialization/holomap.dm
similarity index 91%
rename from code/controllers/subsystems/initialization/minimap.dm
rename to code/controllers/subsystems/initialization/holomap.dm
index 667674becaf..7ed0b996db4 100644
--- a/code/controllers/subsystems/initialization/minimap.dm
+++ b/code/controllers/subsystems/initialization/holomap.dm
@@ -1,9 +1,9 @@
// Minimap generation system adapted from vorestation, adapted from /vg/.
// Seems to be much simpler/saner than /vg/'s implementation.
-/var/datum/controller/subsystem/minimap/SSminimap
+/var/datum/controller/subsystem/holomap/SSholomap
-/datum/controller/subsystem/minimap
+/datum/controller/subsystem/holomap
name = "Holomap"
flags = SS_NO_FIRE
init_order = SS_INIT_HOLOMAP
@@ -12,15 +12,15 @@
var/list/extra_minimaps = list()
var/list/station_holomaps = list()
-/datum/controller/subsystem/minimap/New()
- NEW_SS_GLOBAL(SSminimap)
+/datum/controller/subsystem/holomap/New()
+ NEW_SS_GLOBAL(SSholomap)
-/datum/controller/subsystem/minimap/Initialize()
+/datum/controller/subsystem/holomap/Initialize()
holo_minimaps.len = world.maxz
for (var/z in 1 to world.maxz)
holo_minimaps[z] = generateHoloMinimap(z)
- log_debug("SSminimap: [holo_minimaps.len] maps.")
+ log_debug("SSholomap: [holo_minimaps.len] maps.")
for (var/z in current_map.station_levels)
generateStationMinimap(z)
@@ -29,7 +29,7 @@
// Generates the "base" holomap for one z-level, showing only the physical structure of walls and paths.
-/datum/controller/subsystem/minimap/proc/generateHoloMinimap(zlevel = 1)
+/datum/controller/subsystem/holomap/proc/generateHoloMinimap(zlevel = 1)
// Save these values now to avoid a bazillion array lookups
var/offset_x = HOLOMAP_PIXEL_OFFSET_X(zlevel)
var/offset_y = HOLOMAP_PIXEL_OFFSET_Y(zlevel)
@@ -77,7 +77,7 @@
return canvas
-/datum/controller/subsystem/minimap/proc/generateStationMinimap(zlevel)
+/datum/controller/subsystem/holomap/proc/generateStationMinimap(zlevel)
// Save these values now to avoid a bazillion array lookups
var/offset_x = HOLOMAP_PIXEL_OFFSET_X(zlevel)
var/offset_y = HOLOMAP_PIXEL_OFFSET_Y(zlevel)
diff --git a/code/controllers/subsystems/law.dm b/code/controllers/subsystems/law.dm
index a54d67df741..9f1e0fec00d 100644
--- a/code/controllers/subsystems/law.dm
+++ b/code/controllers/subsystems/law.dm
@@ -13,6 +13,12 @@
NEW_SS_GLOBAL(SSlaw)
/datum/controller/subsystem/law/Initialize(timeofday)
+ if(config.sql_enabled)
+ load_from_sql()
+ else
+ load_from_code()
+
+/datum/controller/subsystem/law/proc/load_from_code()
for (var/L in subtypesof(/datum/law/low_severity))
low_severity += new L
@@ -23,3 +29,64 @@
high_severity += new L
laws = low_severity + med_severity + high_severity
+
+/datum/controller/subsystem/law/proc/load_from_sql()
+ if(!establish_db_connection(dbcon))
+ log_debug("SSlaw: SQL ERROR - Failed to connect.")
+ return load_from_code()
+
+ var/DBQuery/law_query = dbcon.NewQuery("SELECT law_id, name, description, min_fine, max_fine, min_brig_time, max_brig_time, severity, felony FROM ss13_law WHERE deleted_at IS NULL ORDER BY law_id ASC")
+ law_query.Execute()
+ while(law_query.NextRow())
+ CHECK_TICK
+ try
+ var/datum/law/L = new
+ L.id = law_query.item[1]
+ L.name = law_query.item[2]
+ L.desc = law_query.item[3]
+ L.min_fine = text2num(law_query.item[4])
+ L.max_fine = text2num(law_query.item[5])
+ L.min_brig_time = text2num(law_query.item[6])
+ L.max_brig_time = text2num(law_query.item[7])
+ L.severity = text2num(law_query.item[8])
+ L.felony = text2num(law_query.item[9])
+
+ if(L.severity == 1)
+ low_severity += L
+ else if(L.severity == 2)
+ med_severity += L
+ else if(L.severity == 3)
+ high_severity += L
+ else
+ throw("Law with id: [L.id] deleted due to invalid severity: [L.severity]")
+ qdel(L)
+ catch(var/exception/el)
+ log_debug("SSlaw: Error when loading law: [el]")
+
+ laws = low_severity + med_severity + high_severity
+ if(!laws.len)
+ log_debug("SSlaw: No laws loaded. Loading from code and migrating to SQL")
+ load_from_code()
+ migrate_to_sql()
+
+/datum/controller/subsystem/law/proc/migrate_to_sql()
+ for(var/datum/law/L in laws)
+ log_debug("SSlaw: Migrating law [L.id] to SQL")
+ var/DBQuery/law_update_query = dbcon.NewQuery({"
+ INSERT IGNORE INTO ss13_law
+ (law_id, name, description, min_fine, max_fine, min_brig_time, max_brig_time, severity, felony)
+ VALUES
+ (:law_id:, :name:, :desc:, :min_fine:, :max_fine:, :min_brig_time:, :max_brig_time:, :severity:, :felony:)
+ "})
+ law_update_query.Execute(list(
+ "law_id"=L.id,
+ "name"=L.name,
+ "desc"=L.desc,
+ "min_fine"=L.min_fine,
+ "max_fine"=L.max_fine,
+ "min_brig_time"=L.min_brig_time,
+ "max_brig_time"=L.max_brig_time,
+ "severity"=L.severity,
+ "felony"=L.felony
+ ))
+ return
\ No newline at end of file
diff --git a/code/controllers/subsystems/news.dm b/code/controllers/subsystems/news.dm
new file mode 100644
index 00000000000..619ac15ca58
--- /dev/null
+++ b/code/controllers/subsystems/news.dm
@@ -0,0 +1,163 @@
+/var/datum/controller/subsystem/news/SSnews
+
+/datum/controller/subsystem/news
+ name = "News"
+ flags = SS_NO_FIRE
+ var/list/datum/feed_channel/network_channels = list()
+ var/datum/feed_message/wanted_issue
+
+/datum/controller/subsystem/news/Recover()
+ src.network_channels = SSnews.network_channels
+ src.wanted_issue = SSnews.wanted_issue
+
+/datum/controller/subsystem/news/New()
+ NEW_SS_GLOBAL(SSnews)
+
+/datum/controller/subsystem/news/Initialize(timeofday)
+ CreateFeedChannel("Station Announcements", "Automatic Announcement System", 1, 1, "New Station Announcement Available")
+ CreateFeedChannel("Tau Ceti Daily", "CentComm Minister of Information", 1, 1)
+ CreateFeedChannel("The Gibson Gazette", "Editor Carl Ritz", 1, 1)
+ if(config.sql_enabled)
+ load_from_sql()
+ ..()
+
+/datum/controller/subsystem/news/proc/load_from_sql()
+ if(!establish_db_connection(dbcon))
+ log_debug("SSnews: SQL ERROR - Failed to connect.")
+ return
+ var/DBQuery/channel_query = dbcon.NewQuery("SELECT id, name, author, locked, is_admin_channel, announcement FROM ss13_news_channels WHERE deleted_at IS NULL ORDER BY name ASC")
+ channel_query.Execute()
+ while(channel_query.NextRow())
+ CHECK_TICK
+ var/datum/feed_channel/channel = null
+ try
+ channel = CreateFeedChannel(
+ channel_query.item[2],
+ channel_query.item[3],
+ text2num(channel_query.item[4]),
+ text2num(channel_query.item[5]),
+ channel_query.item[6])
+ catch(var/exception/ec)
+ log_debug("SSnews: Error when loading channel: [ec]")
+ continue
+ var/DBQuery/news_query = dbcon.NewQuery("SELECT body, author, is_admin_message, message_type, time_stamp FROM ss13_news_stories WHERE deleted_at IS NULL AND channel_id = :channel_id: ORDER BY created_at DESC")
+ news_query.Execute(list("channel_id" = channel_query.item[1]))
+ while(news_query.NextRow())
+ CHECK_TICK
+ try
+ SubmitArticle(news_query.item[1], news_query.item[2], channel, null, text2num(news_query.item[3]), news_query.item[4], news_query.item[5])
+ catch(var/exception/en)
+ log_debug("SSnews: Error when loading news: [en]")
+
+/datum/controller/subsystem/news/proc/GetFeedChannel(var/channel_name)
+ if(network_channels[channel_name])
+ return network_channels[channel_name]
+ return null
+
+/datum/controller/subsystem/news/proc/CreateFeedChannel(var/channel_name, var/author, var/locked, var/adminChannel = 0, var/announcement_message)
+ var/datum/feed_channel/newChannel = new /datum/feed_channel
+ newChannel.channel_name = channel_name
+ newChannel.author = author
+ newChannel.locked = locked
+ newChannel.is_admin_channel = adminChannel
+ if(announcement_message)
+ newChannel.announcement = announcement_message
+ else
+ newChannel.announcement = "Breaking news from [channel_name]!"
+ network_channels[channel_name] = newChannel
+ return newChannel
+
+/datum/controller/subsystem/news/proc/SubmitArticle(var/msg, var/author, var/datum/feed_channel/channel, var/obj/item/weapon/photo/photo, var/adminMessage = 0, var/message_type = "", var/time_stamp)
+ if(!channel)
+ log_debug("SSnews: Attempted to submit a article from [author] without a proper channel",SEVERITY_ERROR)
+ return
+
+ var/datum/feed_message/newMsg = new /datum/feed_message
+ newMsg.author = author
+ newMsg.body = msg
+ if(time_stamp)
+ newMsg.time_stamp = time_stamp
+ else
+ newMsg.time_stamp = "[worldtime2text()]"
+ newMsg.is_admin_message = adminMessage
+ if(message_type)
+ newMsg.message_type = message_type
+ if(photo)
+ newMsg.img = photo.img
+ newMsg.caption = photo.scribble
+ insert_message_in_channel(channel, newMsg) //Adding message to the network's appropriate feed_channel
+
+/datum/controller/subsystem/news/proc/insert_message_in_channel(var/datum/feed_channel/FC, var/datum/feed_message/newMsg)
+ FC.messages += newMsg
+ newMsg.parent_channel = FC
+ FC.update()
+ alert_readers(FC.announcement)
+
+/datum/controller/subsystem/news/proc/alert_readers(var/annoncement)
+ set waitfor = FALSE
+ for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
+ NEWSCASTER.newsAlert(annoncement)
+ NEWSCASTER.update_icon()
+
+ var/list/receiving_pdas = new
+ for (var/obj/item/device/pda/P in PDAs)
+ if (!P.owner)
+ continue
+ if (P.toff)
+ continue
+ receiving_pdas += P
+
+ for(var/obj/item/device/pda/PDA in receiving_pdas)
+ PDA.new_news(annoncement)
+
+
+/datum/feed_message
+ var/author =""
+ var/body =""
+ var/message_type ="Story"
+ var/datum/feed_channel/parent_channel
+ var/is_admin_message = 0
+ var/icon/img = null
+ var/icon/caption = ""
+ var/time_stamp = ""
+ var/backup_body = ""
+ var/backup_author = ""
+ var/icon/backup_img = null
+ var/icon/backup_caption = ""
+
+/datum/feed_message/proc/clear()
+ src.author = ""
+ src.body = ""
+ src.caption = ""
+ src.img = null
+ src.time_stamp = ""
+ src.backup_body = ""
+ src.backup_author = ""
+ src.backup_caption = ""
+ src.backup_img = null
+ parent_channel.update()
+
+/datum/feed_channel
+ var/channel_name=""
+ var/list/datum/feed_message/messages = list()
+ var/locked=0 //If public stories are accepted
+ var/author=""
+ var/backup_author=""
+ var/censored=0
+ var/is_admin_channel=0 //If it can be censored, ...
+ var/updated = 0
+ var/announcement = "" //The text that should be broadcasted when a new story is posted
+
+/datum/feed_channel/proc/update()
+ updated = world.time
+
+/datum/feed_channel/proc/clear()
+ src.channel_name = ""
+ src.messages = list()
+ src.locked = 0
+ src.author = ""
+ src.backup_author = ""
+ src.censored = 0
+ src.is_admin_channel = 0
+ src.announcement = ""
+ update()
diff --git a/code/controllers/subsystems/supply.dm b/code/controllers/subsystems/supply.dm
index a7fcbc7f270..b5e7a68e288 100644
--- a/code/controllers/subsystems/supply.dm
+++ b/code/controllers/subsystems/supply.dm
@@ -1,6 +1,6 @@
//Config stuff
-#define SUPPLY_DOCKZ 2 //Z-level of the Dock.
-#define SUPPLY_STATIONZ 1 //Z-level of the Station.
+#define SUPPLY_DOCKZ 1 //Z-level of the Dock.
+#define SUPPLY_STATIONZ 6 //Z-level of the Station.
#define SUPPLY_STATION_AREATYPE /area/supply/station //Type of the supply shuttle area for station
#define SUPPLY_DOCK_AREATYPE /area/supply/dock //Type of the supply shuttle area for dock
@@ -182,7 +182,7 @@ var/datum/controller/subsystem/cargo/SScargo
catch(var/exception/es)
log_debug("SScargo: Error when loading supplier: [es]")
//Load the items
- var/DBQuery/item_query = dbcon.NewQuery("SELECT id, name, supplier, description, categories, price, items, access, container_type, groupable, item_mul FROM ss13_cargo_items WHERE deleted_at is NULL AND supplier IS NOT NULL ORDER BY order_by ASC, name ASC, supplier ASC")
+ var/DBQuery/item_query = dbcon.NewQuery("SELECT id, name, supplier, description, categories, price, items, access, container_type, groupable, item_mul FROM ss13_cargo_items WHERE deleted_at IS NULL AND approved_at IS NOT NULL AND supplier IS NOT NULL ORDER BY order_by ASC, name ASC, supplier ASC")
item_query.Execute()
while(item_query.NextRow())
CHECK_TICK
@@ -257,7 +257,7 @@ var/datum/controller/subsystem/cargo/SScargo
cargoconfig["items"][item]["access"],
cargoconfig["items"][item]["container_type"],
cargoconfig["items"][item]["groupable"],
- cargoconfig["items"][item]["item_mul"])
+ cargoconfig["items"][item]["item_mul"])
catch(var/exception/ei)
log_debug("SScargo: Error when loading supplier: [ei]")
return 1
@@ -292,7 +292,7 @@ var/datum/controller/subsystem/cargo/SScargo
//Add a new item to the cargo subsystem, the categories and the items need to be a list and CAN NOT be passed as a json string.
//Decoding of the string MUST take place before
-/datum/controller/subsystem/cargo/proc/add_item(var/id=null,var/name,var/supplier="nt",var/description,var/list/categories,var/price,var/list/items,var/access=0,var/container_type=CARGO_CONTAINER_CRATE,var/groupable=1,var/item_mul=1)
+/datum/controller/subsystem/cargo/proc/add_item(var/id=null,var/name,var/supplier="nt",var/description,var/list/categories,var/price,var/list/items,var/access=0,var/container_type=CARGO_CONTAINER_CRATE,var/groupable=1,var/item_mul=1)
//TODO-CARGO: Maybe add the option to specify access as string instead of number
//If no item ID is supplied generate one ourselfs (use the next free id)
@@ -303,7 +303,7 @@ var/datum/controller/subsystem/cargo/SScargo
id = text2num(id)
if(id > last_item_id)
last_item_id = id
-
+
var/datum/cargo_item/ci = new()
try
ci.id = id
@@ -322,7 +322,7 @@ var/datum/controller/subsystem/cargo/SScargo
log_debug("SScargo: Error when loading item: [e]")
qdel(ci)
return
-
+
for(var/item in ci.items)
var/itempath = text2path(ci.items[item]["path"])
if(!ispath(itempath))
@@ -341,7 +341,7 @@ var/datum/controller/subsystem/cargo/SScargo
log_debug("SScargo: [ci.supplier] is not a valid supplier for item [ci.name].")
QDEL_NULL(ci)
return
-
+
//Setting the supplier
ci.supplier_datum = cs
@@ -362,7 +362,7 @@ var/datum/controller/subsystem/cargo/SScargo
cc.items.Add(ci)
else
log_debug("SScargo: Warning - Attempted to add [ci.name] item to category [category] that does not exist.")
-
+
return ci
/*
diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm
index 68469cb6ed3..858b814c2b6 100644
--- a/code/controllers/subsystems/ticker.dm
+++ b/code/controllers/subsystems/ticker.dm
@@ -387,6 +387,12 @@ var/datum/controller/subsystem/ticker/SSticker
SSjobs.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly.
if(!src.mode.can_start())
+ var/list/voted_not_ready = list()
+ for(var/mob/abstract/new_player/player in player_list)
+ if((player.client)&&(!player.ready))
+ voted_not_ready += player.ckey
+ message_admins("The following players voted for [mode.name], but did not ready up: [jointext(voted_not_ready, ", ")]")
+ log_game("Ticker: Players voted for [mode.name], but did not ready up: [jointext(voted_not_ready, ", ")]")
world << "Unable to start [mode.name]. Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby."
current_state = GAME_STATE_PREGAME
mode.fail_setup()
diff --git a/code/controllers/subsystems/vote.dm b/code/controllers/subsystems/vote.dm
index a5f8297d050..c2362e37a56 100644
--- a/code/controllers/subsystems/vote.dm
+++ b/code/controllers/subsystems/vote.dm
@@ -259,6 +259,7 @@ var/datum/controller/subsystem/vote/SSvote
if("restart")
choices.Add("Restart Round","Continue Playing")
if("gamemode")
+ round_voters.Cut() //Delete the old list, since we are having a new gamemode vote
if(SSticker.current_state >= 2)
return 0
choices.Add(config.votable_modes)
diff --git a/code/controllers/subsystems/zcopy.dm b/code/controllers/subsystems/zcopy.dm
index 710538ad598..d42617a2e39 100644
--- a/code/controllers/subsystems/zcopy.dm
+++ b/code/controllers/subsystems/zcopy.dm
@@ -1,7 +1,7 @@
#define OPENTURF_MAX_PLANE -71
#define OPENTURF_CAP_PLANE -70 // The multiplier goes here so it'll be on top of every other overlay.
#define OPENTURF_MAX_DEPTH 10 // The maxiumum number of planes deep we'll go before we just dump everything on the same plane.
-#define SHADOWER_DARKENING_FACTOR 0.4 // The multiplication factor for openturf shadower darkness. Lighting will be multiplied by this.
+#define SHADOWER_DARKENING_FACTOR 0.85 // The multiplication factor for openturf shadower darkness. Lighting will be multiplied by this.
/var/datum/controller/subsystem/zcopy/SSzcopy
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index 392e407bd2a..3d2cefdbbc6 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -47,7 +47,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
name = "Illegal weapons crate"
num_contained = 2
contains = list(/obj/item/weapon/gun/projectile/automatic/mini_uzi,
- /obj/item/weapon/gun/projectile/boltaction,
+ /obj/item/weapon/gun/projectile/shotgun/pump/rifle,
/obj/item/weapon/gun/projectile/silenced,
/obj/item/weapon/gun/projectile/pirate,
/obj/item/weapon/gun/projectile/revolver/derringer,
diff --git a/code/datums/trading/ai.dm b/code/datums/trading/ai.dm
index 830ec2c28d6..9269b42c798 100644
--- a/code/datums/trading/ai.dm
+++ b/code/datums/trading/ai.dm
@@ -128,6 +128,7 @@ They sell generic supplies and ask for generic supplies.
/obj/item/weapon/storage/pill_bottle = TRADER_SUBTYPES_ONLY,
/obj/item/weapon/reagent_containers/hypospray = TRADER_ALL,
/obj/item/device/healthanalyzer = TRADER_THIS_TYPE,
+ /obj/item/device/breath_analyzer = TRADER_THIS_TYPE,
/obj/item/stack/medical/bruise_pack = TRADER_THIS_TYPE,
/obj/item/stack/medical/ointment = TRADER_THIS_TYPE,
/obj/item/stack/medical/advanced = TRADER_SUBTYPES_ONLY,
diff --git a/code/datums/trading/goods.dm b/code/datums/trading/goods.dm
index ab12192fff2..4e46687815e 100644
--- a/code/datums/trading/goods.dm
+++ b/code/datums/trading/goods.dm
@@ -223,6 +223,7 @@ Sells devices, odds and ends, and medical stuff
/obj/item/device/paicard = TRADER_THIS_TYPE,
/obj/item/device/pipe_painter = TRADER_THIS_TYPE,
/obj/item/device/healthanalyzer = TRADER_THIS_TYPE,
+ /obj/item/device/breath_analyzer = TRADER_THIS_TYPE,
/obj/item/device/analyzer = TRADER_ALL,
/obj/item/device/mass_spectrometer = TRADER_ALL,
/obj/item/device/reagent_scanner = TRADER_ALL,
diff --git a/code/datums/trading/weaponry.dm b/code/datums/trading/weaponry.dm
index 4bd36cf81b7..687f89bea87 100644
--- a/code/datums/trading/weaponry.dm
+++ b/code/datums/trading/weaponry.dm
@@ -88,7 +88,7 @@
)
possible_trading_items = list(
- /obj/item/weapon/gun/projectile/boltaction = TRADER_ALL,
+ /obj/item/weapon/gun/projectile/shotgun/pump/rifle = TRADER_ALL,
/obj/item/weapon/gun/projectile/dragunov = TRADER_THIS_TYPE,
/obj/item/weapon/gun/projectile/silenced = TRADER_THIS_TYPE,
/obj/item/weapon/gun/projectile/automatic/tommygun = TRADER_THIS_TYPE,
@@ -100,7 +100,7 @@
/obj/item/weapon/gun/projectile/pirate = TRADER_THIS_TYPE,
/obj/item/weapon/gun/projectile/contender = TRADER_THIS_TYPE,
/obj/item/weapon/gun/projectile/revolver/lemat = TRADER_THIS_TYPE,
- /obj/item/weapon/gun/projectile/boltaction/vintage = TRADER_THIS_TYPE
+ /obj/item/weapon/gun/projectile/shotgun/pump/rifle/vintage = TRADER_THIS_TYPE
)
@@ -142,4 +142,4 @@
/obj/item/clothing/mask/gas/tactical = TRADER_THIS_TYPE,
/obj/item/weapon/shield/riot/tact = TRADER_THIS_TYPE,
/obj/item/weapon/storage/belt/security/tactical = TRADER_THIS_TYPE
- )
\ No newline at end of file
+ )
diff --git a/code/datums/uplink/medical.dm b/code/datums/uplink/medical.dm
index 6baf9b9b32f..2dfc50d9397 100644
--- a/code/datums/uplink/medical.dm
+++ b/code/datums/uplink/medical.dm
@@ -24,7 +24,10 @@
item_cost = 12
path = /obj/item/weapon/storage/firstaid/combat
-/datum/uplink_item/item/medical/trisyndicotin
- name = "Mind-freeing pills"
- item_cost = 3
- path = /obj/item/weapon/storage/pill_bottle/trisyndicotin
+/datum/uplink_item/item/medical/stimulants
+ name = "Box of Combat Stimulants"
+ item_cost = 6
+ path = /obj/item/weapon/storage/box/syndie_kit/stimulants
+
+
+
diff --git a/code/datums/wires/vending.dm b/code/datums/wires/vending.dm
index 7f9c4ed10a7..c5c513d404b 100644
--- a/code/datums/wires/vending.dm
+++ b/code/datums/wires/vending.dm
@@ -45,7 +45,7 @@ var/const/VENDING_WIRE_IDSCAN = 8
if(VENDING_WIRE_THROW)
V.shoot_inventory = !mended
if(VENDING_WIRE_CONTRABAND)
- V.categories &= ~CAT_HIDDEN
+ V.categories &= ~CAT_HIDDEN
if(VENDING_WIRE_ELECTRIFY)
if(mended)
V.seconds_electrified = 0
diff --git a/code/defines/procs/dbcore.dm b/code/defines/procs/dbcore.dm
index 9c51134667a..541bf6aeae5 100644
--- a/code/defines/procs/dbcore.dm
+++ b/code/defines/procs/dbcore.dm
@@ -128,7 +128,7 @@ DBQuery/proc/Execute(var/list/argument_list = null, var/pass_not_found = 0, sql_
var/error = ErrorMsg()
if (error)
- error("SQL Error: '[error]'")
+ log_debug("SQL Error: '[error]'",SEVERITY_ERROR)
// This is hacky and should probably be changed
if (error == "MySQL server has gone away")
log_game("MySQL connection drop detected, attempting to reconnect.")
diff --git a/code/defines/procs/radio.dm b/code/defines/procs/radio.dm
index 128b01fffb8..90638792079 100644
--- a/code/defines/procs/radio.dm
+++ b/code/defines/procs/radio.dm
@@ -74,20 +74,4 @@
reception.telecomms_reception |= get_receiver_reception(receiver, signal)
reception.message = signal && signal.data["compression"] > 0 ? Gibberish(message, signal.data["compression"] + 50) : message
- return reception
-
-/proc/get_receptions(var/atom/sender, var/list/atom/receivers, var/do_sleep = 1)
- var/datum/receptions/receptions = new
- receptions.message_server = get_message_server()
-
- var/datum/signal/signal
- if(sender)
- signal = sender.telecomms_process(do_sleep)
- receptions.sender_reception = get_sender_reception(sender, signal)
-
- for(var/atom/receiver in receivers)
- if(!signal)
- signal = receiver.telecomms_process()
- receptions.receiver_reception[receiver] = get_receiver_reception(receiver, signal)
-
- return receptions
+ return reception
\ No newline at end of file
diff --git a/code/game/antagonist/_antagonist_setup.dm b/code/game/antagonist/_antagonist_setup.dm
index 92ee06e7a3d..f1eeb41e124 100644
--- a/code/game/antagonist/_antagonist_setup.dm
+++ b/code/game/antagonist/_antagonist_setup.dm
@@ -14,20 +14,6 @@
- To skip equipping with appropriate gear, supply a positive third argument.
*/
-// Antagonist datum flags.
-#define ANTAG_OVERRIDE_JOB 1 // Assigned job is set to MODE when spawning.
-#define ANTAG_OVERRIDE_MOB 2 // Mob is recreated from datum mob_type var when spawning.
-#define ANTAG_CLEAR_EQUIPMENT 4 // All preexisting equipment is purged.
-#define ANTAG_CHOOSE_NAME 8 // Antagonists are prompted to enter a name.
-#define ANTAG_IMPLANT_IMMUNE 16 // Cannot be loyalty implanted.
-#define ANTAG_SUSPICIOUS 32 // Shows up on roundstart report.
-#define ANTAG_HAS_LEADER 64 // Generates a leader antagonist.
-#define ANTAG_HAS_NUKE 128 // Will spawn a nuke at supplied location.
-#define ANTAG_RANDSPAWN 256 // Potentially randomly spawns due to events.
-#define ANTAG_VOTABLE 512 // Can be voted as an additional antagonist before roundstart.
-#define ANTAG_SET_APPEARANCE 1024 // Causes antagonists to use an appearance modifier on spawn.
-#define ANTAG_RANDOM_EXCEPTED 2048 // If a game mode randomly selects antag types, antag types with this flag should be excluded.
-
// Globals.
var/global/list/all_antag_types = list()
var/global/list/all_antag_spawnpoints = list()
diff --git a/code/game/antagonist/outsider/actors.dm b/code/game/antagonist/outsider/actors.dm
deleted file mode 100644
index 152419dcfed..00000000000
--- a/code/game/antagonist/outsider/actors.dm
+++ /dev/null
@@ -1,62 +0,0 @@
-var/datum/antagonist/actor/actor
-
-/datum/antagonist/actor
- id = MODE_ACTOR
- bantype = "actor"
- role_text = "NanoTrasen Actor"
- role_text_plural = "NanoTrasen Actors"
- welcome_text = "You've been hired to entertain people through the power of television!"
- landmark_id = "ActorSpawn"
- id_type = /obj/item/weapon/card/id/syndicate
-
- flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE | ANTAG_CHOOSE_NAME
-
- hard_cap = 7
- hard_cap_round = 10
- initial_spawn_req = 1
- initial_spawn_target = 1
-
-/datum/antagonist/actor/New()
- ..()
- actor = src
-
-/datum/antagonist/actor/greet(var/datum/mind/player)
- if(!..())
- return
-
- player.current.show_message("You work for [current_map.company_name], tasked with the production and broadcasting of entertainment to all of its assets.")
- player.current.show_message("Entertain the crew! Try not to disrupt them from their work too much and remind them how great [current_map.company_name] is!")
-
-/datum/antagonist/actor/equip(var/mob/living/carbon/human/player)
- player.equip_to_slot_or_del(new /obj/item/clothing/under/chameleon(src), slot_w_uniform)
- player.equip_to_slot_or_del(new /obj/item/clothing/shoes/chameleon(src), slot_shoes)
- player.equip_to_slot_or_del(new /obj/item/device/radio/headset/entertainment(src), slot_l_ear)
- var/obj/item/weapon/card/id/centcom/ERT/C = new(player.loc)
- C.assignment = "Actor"
- player.set_id_info(C)
- player.equip_to_slot_or_del(C,slot_wear_id)
-
- return 1
-
-/*
-/client/verb/join_as_actor()
- set category = "IC"
- set name = "Join as Actor"
- set desc = "Join as an Actor to entertain the crew through television!"
-
- if(!MayRespawn(1))
- return
-
- var/choice = alert("Are you sure you'd like to join as an actor?", "Confirmation","Yes", "No")
- if(choice != "Yes")
- return
-
- if(istype(usr,/mob/abstract/observer) || istype(usr,/mob/abstract/new_player))
- if(actor.current_antagonists.len >= actor.hard_cap)
- usr << "No more actors may spawn at the current time."
- return
- actor.create_default(usr)
- return
-
- usr << "You must be observing or be a new player to spawn as an actor."
- */
diff --git a/code/game/antagonist/outsider/commando.dm b/code/game/antagonist/outsider/commando.dm
index 7b3a58af44f..b122c07173d 100644
--- a/code/game/antagonist/outsider/commando.dm
+++ b/code/game/antagonist/outsider/commando.dm
@@ -6,7 +6,7 @@ var/datum/antagonist/deathsquad/mercenary/commandos
role_text = "Syndicate Commando"
role_text_plural = "Commandos"
welcome_text = "You are in the employ of a criminal syndicate hostile to corporate interests."
- id_type = /obj/item/weapon/card/id/centcom/ERT
+ id_type = /obj/item/weapon/card/id/ert
hard_cap = 4
hard_cap_round = 8
diff --git a/code/game/antagonist/outsider/ert.dm b/code/game/antagonist/outsider/ert.dm
index 5f221c9d40a..68038b1dccd 100644
--- a/code/game/antagonist/outsider/ert.dm
+++ b/code/game/antagonist/outsider/ert.dm
@@ -8,9 +8,9 @@ var/datum/antagonist/ert/ert
welcome_text = "As member of the Emergency Response Team, you answer only to your leader and CentComm officials."
leader_welcome_text = "As leader of the Emergency Response Team, you answer only to CentComm, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however."
landmark_id = "Response Team"
-
- id_type = /obj/item/weapon/card/id/centcom/ERT
-
+
+ id_type = /obj/item/weapon/card/id/ert
+
flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER | ANTAG_CHOOSE_NAME | ANTAG_RANDOM_EXCEPTED
antaghud_indicator = "hudloyalist"
diff --git a/code/game/antagonist/outsider/raider.dm b/code/game/antagonist/outsider/raider.dm
index 47e701e74c4..27f465096df 100644
--- a/code/game/antagonist/outsider/raider.dm
+++ b/code/game/antagonist/outsider/raider.dm
@@ -91,7 +91,7 @@ var/datum/antagonist/raider/raiders
/obj/item/weapon/gun/projectile/shotgun/doublebarrel,
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/pellet,
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn,
- /obj/item/weapon/gun/projectile/boltaction,
+ /obj/item/weapon/gun/projectile/shotgun/pump/rifle,
/obj/item/weapon/gun/projectile/colt,
/obj/item/weapon/gun/projectile/sec,
/obj/item/weapon/gun/projectile/pistol,
@@ -103,7 +103,7 @@ var/datum/antagonist/raider/raiders
/obj/item/weapon/gun/projectile/contender,
/obj/item/weapon/gun/projectile/pirate,
/obj/item/weapon/gun/projectile/tanto,
- /obj/item/weapon/gun/projectile/boltaction/vintage
+ /obj/item/weapon/gun/projectile/shotgun/pump/rifle/vintage
)
diff --git a/code/game/antagonist/station/cultist.dm b/code/game/antagonist/station/cultist.dm
index f103b2a8859..9c076ae901a 100644
--- a/code/game/antagonist/station/cultist.dm
+++ b/code/game/antagonist/station/cultist.dm
@@ -35,6 +35,16 @@ var/datum/antagonist/cultist/cult
faction = "cult"
+ restricted_species = list(
+ "Baseline Frame",
+ "Shell Frame",
+ "Hephaestus G1 Industrial Frame",
+ "Hephaestus G2 Industrial Frame",
+ "Xion Industrial Frame",
+ "Zeng-Hu Mobility Frame",
+ "Bishop Accessory Frame"
+ )
+
var/allow_narsie = 1
var/datum/mind/sacrifice_target
var/list/allwords = list("travel","self","see","hell","blood","join","tech","destroy", "other", "hide")
diff --git a/code/game/antagonist/station/loyalist.dm b/code/game/antagonist/station/loyalist.dm
index 7d73b02af6d..adf62d50e72 100644
--- a/code/game/antagonist/station/loyalist.dm
+++ b/code/game/antagonist/station/loyalist.dm
@@ -45,7 +45,6 @@ var/datum/antagonist/loyalists/loyalists
loyal_obj.explanation_text = "Protect [player.real_name], the [player.mind.assigned_role]."
global_objectives += loyal_obj
-
/datum/antagonist/loyalists/equip(var/mob/living/carbon/human/player)
if(!..())
diff --git a/code/game/antagonist/station/renegade.dm b/code/game/antagonist/station/renegade.dm
index 3c141d309c4..9389d4165d8 100644
--- a/code/game/antagonist/station/renegade.dm
+++ b/code/game/antagonist/station/renegade.dm
@@ -26,7 +26,7 @@ var/datum/antagonist/renegade/renegades
/obj/item/weapon/gun/projectile/deagle/camo,
/obj/item/weapon/gun/projectile/pistol,
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn,
- /obj/item/weapon/gun/projectile/boltaction/obrez,
+ /obj/item/weapon/gun/projectile/shotgun/pump/rifle/obrez,
/obj/item/weapon/gun/projectile/automatic,
/obj/item/weapon/gun/projectile/automatic/c20r,
/obj/item/weapon/gun/projectile/automatic/tommygun,
diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm
index 506426c76a1..3c98e41b07a 100644
--- a/code/game/dna/dna2.dm
+++ b/code/game/dna/dna2.dm
@@ -58,10 +58,6 @@ var/global/list/datum/dna/gene/dna_genes[0]
// Used for genes that check for value rather than a binary on/off.
#define GENE_ALWAYS_ACTIVATE 1
-// Skip checking if it's already active.
-// Used for genes that check for value rather than a binary on/off.
-#define GENE_ALWAYS_ACTIVATE 1
-
/datum/dna
// READ-ONLY, GETS OVERWRITTEN
// DO NOT FUCK WITH THESE OR BYOND WILL EAT YOUR FACE
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 5e20a6b052b..69261101f69 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -133,6 +133,11 @@ var/list/sacrificed = list()
target.hallucination = min(target.hallucination, 500)
return 0
+ //If you dont have blood, blood magic doesnt work on you
+ if(target.is_mechanical())
+ attacker << "You sense that your powers can not effect them."
+ return 0
+
target.take_overall_damage(0, rand(5, 20)) // You dirty resister cannot handle the damage to your mind. Easily. - even cultists who accept right away should experience some effects
// Resist messages go!
if(initial_message) //don't do this stuff right away, only if they resist or hesitate.
diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm
index dd3aee3a915..537a1714360 100644
--- a/code/game/gamemodes/vampire/vampire_powers.dm
+++ b/code/game/gamemodes/vampire/vampire_powers.dm
@@ -213,7 +213,7 @@
to_chat(src, "Your powers are not capable of taking you that far.")
return
- if (!T.dynamic_lighting || T.get_lumcount() > 0.1)
+ if (T.get_lumcount() > 0.1)
// Too bright, cannot jump into.
to_chat(src, "The destination is too bright.")
return
diff --git a/code/game/jobs/access_datum.dm b/code/game/jobs/access_datum.dm
index 296a9ee31a3..20c4bef8852 100644
--- a/code/game/jobs/access_datum.dm
+++ b/code/game/jobs/access_datum.dm
@@ -401,6 +401,12 @@
desc = "Detective Equipment"
region = ACCESS_REGION_SECURITY
+/var/const/access_weapons = 69
+/datum/access/access_weapons
+ id = access_weapons
+ desc = "Weaponry Permission"
+ region = ACCESS_REGION_SECURITY
+
/******************
* Central Command *
******************/
diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm
index b2b5215d3eb..47428e8bc01 100644
--- a/code/game/jobs/job/captain.dm
+++ b/code/game/jobs/job/captain.dm
@@ -77,13 +77,13 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
access = list(access_sec_doors, access_medical, access_engine, access_change_ids, access_eva, access_heads,
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction,
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics,
- access_chapel_office, access_library, access_research, access_mining, access_mining_station,
- access_hop, access_RC_announce, access_keycard_auth, access_gateway)
+ access_chapel_office, access_library, access_research, access_mining, access_mining_station, access_janitor,
+ access_hop, access_RC_announce, access_keycard_auth, access_gateway, access_weapons)
minimal_access = list(access_sec_doors, access_medical, access_engine, access_change_ids, access_eva, access_heads,
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction,
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics,
- access_chapel_office, access_library, access_research, access_mining, access_mining_station,
- access_hop, access_RC_announce, access_keycard_auth, access_gateway)
+ access_chapel_office, access_library, access_research, access_mining, access_mining_station, access_janitor,
+ access_hop, access_RC_announce, access_keycard_auth, access_gateway, access_weapons)
equip(var/mob/living/carbon/human/H)
diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm
index 836e5deb9f7..b3589cd092e 100644
--- a/code/game/jobs/job/civilian.dm
+++ b/code/game/jobs/job/civilian.dm
@@ -186,6 +186,36 @@
H.species.equip_survival_gear(H,1)
return TRUE
+//Not engineers, just the mop boys
+/datum/job/janitor
+ title = "Janitor"
+ flag = JANITOR
+ department = "Civilian"
+ department_flag = CIVILIAN
+ faction = "Station"
+ total_positions = 2
+ spawn_positions = 2
+ supervisors = "the head of personnel"
+ selection_color = "#dddddd"
+ access = list(access_janitor, access_maint_tunnels, access_engine, access_research, access_sec_doors, access_medical)
+ minimal_access = list(access_janitor, access_maint_tunnels, access_engine, access_research, access_sec_doors, access_medical)
+
+ bag_type = /obj/item/weapon/storage/backpack
+ satchel_type = /obj/item/weapon/storage/backpack/satchel_norm
+ duffel_type = /obj/item/weapon/storage/backpack/satchel
+ messenger_bag_type = /obj/item/weapon/storage/backpack/duffel
+
+
+ equip(var/mob/living/carbon/human/H)
+ if(!H)
+ return FALSE
+ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_service(H), slot_l_ear)
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/janitor(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), slot_shoes)
+ H.equip_to_slot_or_del(new /obj/item/device/pda/janitor(H), slot_belt)
+ return TRUE
+
+
//More or less assistants
/datum/job/librarian
title = "Librarian"
diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm
index 153225bf0f8..29229bd0679 100644
--- a/code/game/jobs/job/engineering.dm
+++ b/code/game/jobs/job/engineering.dm
@@ -18,11 +18,11 @@
access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
- access_heads, access_construction, access_sec_doors, access_research, access_medical, access_janitor,
+ access_heads, access_construction, access_sec_doors, access_research, access_medical,
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload)
minimal_access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
- access_heads, access_construction, access_sec_doors, access_research, access_medical, access_janitor,
+ access_heads, access_construction, access_sec_doors, access_research, access_medical,
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload)
minimal_player_age = 7
@@ -133,32 +133,4 @@
if(!H)
return FALSE
H.species.equip_survival_gear(H,1)
- return TRUE
-
-/datum/job/janitor
- title = "Janitor"
- flag = JANITOR
- department = "Engineering"
- department_flag = ENGSEC
- faction = "Station"
- total_positions = 2
- spawn_positions = 2
- supervisors = "the chief engineer"
- selection_color = "#fff5cc"
- access = list(access_janitor, access_maint_tunnels, access_engine, access_research, access_sec_doors, access_medical)
- minimal_access = list(access_janitor, access_maint_tunnels, access_engine, access_research, access_sec_doors, access_medical)
-
- bag_type = /obj/item/weapon/storage/backpack
- satchel_type = /obj/item/weapon/storage/backpack/satchel_norm
- duffel_type = /obj/item/weapon/storage/backpack/satchel
- messenger_bag_type = /obj/item/weapon/storage/backpack/duffel
-
-
- equip(var/mob/living/carbon/human/H)
- if(!H)
- return FALSE
- H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_eng(H), slot_l_ear)
- H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/janitor(H), slot_w_uniform)
- H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), slot_shoes)
- H.equip_to_slot_or_del(new /obj/item/device/pda/janitor(H), slot_belt)
- return TRUE
+ return TRUE
\ No newline at end of file
diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm
index ac3fc1b9810..be1ae67f9ce 100644
--- a/code/game/jobs/job/security.dm
+++ b/code/game/jobs/job/security.dm
@@ -16,12 +16,12 @@
access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers,
access_research, access_engine, access_mining, access_medical, access_construction, access_mailsorting,
access_heads, access_hos, access_RC_announce, access_keycard_auth, access_gateway, access_external_airlocks,
- access_detective)
+ access_detective, access_weapons)
minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory,
access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers,
access_research, access_engine, access_mining, access_medical, access_construction, access_mailsorting,
access_heads, access_hos, access_RC_announce, access_keycard_auth, access_gateway, access_external_airlocks,
- access_detective)
+ access_detective, access_weapons)
minimal_player_age = 14
bag_type = /obj/item/weapon/storage/backpack/security
@@ -62,8 +62,8 @@
supervisors = "the head of security"
selection_color = "#ffeeee"
economic_modifier = 5
- access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_maint_tunnels, access_morgue, access_external_airlocks)
- minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_maint_tunnels, access_external_airlocks)
+ access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_maint_tunnels, access_morgue, access_external_airlocks, access_weapons)
+ minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_maint_tunnels, access_external_airlocks, access_weapons)
minimal_player_age = 7
bag_type = /obj/item/weapon/storage/backpack/security
@@ -107,8 +107,8 @@
supervisors = "the head of security"
selection_color = "#ffeeee"
economic_modifier = 5
- access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_detective)
- minimal_access = list(access_security, access_sec_doors, access_morgue, access_maint_tunnels, access_detective)
+ access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_detective, access_weapons)
+ minimal_access = list(access_security, access_sec_doors, access_morgue, access_maint_tunnels, access_detective, access_weapons)
minimal_player_age = 7
@@ -143,8 +143,8 @@
supervisors = "the head of security"
selection_color = "#ffeeee"
economic_modifier = 5
- access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels)
- minimal_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels)
+ access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_weapons)
+ minimal_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_weapons)
alt_titles = list("Crime Scene Investigator")
minimal_player_age = 3
@@ -185,8 +185,8 @@
selection_color = "#ffeeee"
// alt_titles = list("Junior Officer") //aurora already has security cadets
economic_modifier = 4
- access = list(access_security, access_eva, access_sec_doors, access_brig, access_maint_tunnels, access_morgue, access_external_airlocks)
- minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_maint_tunnels, access_external_airlocks)
+ access = list(access_security, access_eva, access_sec_doors, access_brig, access_maint_tunnels, access_morgue, access_external_airlocks, access_weapons)
+ minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_maint_tunnels, access_external_airlocks, access_weapons)
minimal_player_age = 7
bag_type = /obj/item/weapon/storage/backpack/security
diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm
index c031290d947..3ca49d261ae 100644
--- a/code/game/jobs/jobs.dm
+++ b/code/game/jobs/jobs.dm
@@ -14,7 +14,6 @@ var/const/CYBORG =(1<<9)
var/const/INTERN_SEC =(1<<10)
var/const/INTERN_ENG =(1<<11)
var/const/FORENSICS =(1<<12)
-var/const/JANITOR =(1<<13)
var/const/MEDSCI =(1<<1)
@@ -39,16 +38,17 @@ var/const/HOP =(1<<0)
var/const/BARTENDER =(1<<1)
var/const/BOTANIST =(1<<2)
var/const/CHEF =(1<<3)
-var/const/LIBRARIAN =(1<<4)
-var/const/QUARTERMASTER =(1<<5)
-var/const/CARGOTECH =(1<<6)
-var/const/MINER =(1<<7)
-var/const/LAWYER =(1<<8)
-var/const/CHAPLAIN =(1<<9)
-var/const/CLOWN =(1<<10)
-var/const/MIME =(1<<11)
-var/const/MERCHANT =(1<<12)
-var/const/ASSISTANT =(1<<13)
+var/const/JANITOR =(1<<4)
+var/const/LIBRARIAN =(1<<5)
+var/const/QUARTERMASTER =(1<<6)
+var/const/CARGOTECH =(1<<7)
+var/const/MINER =(1<<8)
+var/const/LAWYER =(1<<9)
+var/const/CHAPLAIN =(1<<10)
+var/const/CLOWN =(1<<11)
+var/const/MIME =(1<<12)
+var/const/MERCHANT =(1<<13)
+var/const/ASSISTANT =(1<<14)
var/list/assistant_occupations = list() //Leaving this on one line stops Travis complaining ~Scopes
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 50dd2461e4f..0a1f45d800a 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -2,45 +2,8 @@
name = "random arcade"
desc = "random arcade machine"
icon_state = "arcade"
-
icon_screen = "invaders"
- var/list/prizes = list( /obj/item/weapon/storage/box/snappops = 11,
- /obj/item/clothing/under/syndicate/tacticool = 5,
- /obj/item/toy/sword = 22,
- /obj/item/weapon/gun/projectile/revolver/capgun = 11,
- /obj/item/toy/crossbow = 11,
- /obj/item/weapon/storage/fancy/crayons = 11,
- /obj/item/toy/spinningtoy = 11,
- /obj/item/toy/prize/ripley = 1,
- /obj/item/toy/prize/fireripley = 1,
- /obj/item/toy/prize/deathripley = 1,
- /obj/item/toy/prize/gygax = 1,
- /obj/item/toy/prize/durand = 1,
- /obj/item/toy/prize/honk = 1,
- /obj/item/toy/prize/marauder = 1,
- /obj/item/toy/prize/seraph = 1,
- /obj/item/toy/prize/mauler = 1,
- /obj/item/toy/prize/odysseus = 1,
- /obj/item/toy/prize/phazon = 1,
- /obj/item/toy/waterflower = 5,
- /obj/random/action_figure = 11,
- /obj/random/plushie = 44,
- /obj/item/toy/cultsword = 5,
- /obj/item/toy/syndicateballoon = 5,
- /obj/item/toy/nanotrasenballoon = 5,
- /obj/item/toy/katana = 11,
- /obj/item/toy/bosunwhistle = 5,
- /obj/item/weapon/storage/belt/champion = 11,
- /obj/item/weapon/pen/invisible = 5,
- /obj/item/weapon/grenade/fake = 1,
- /obj/item/weapon/bikehorn = 11,
- /obj/item/clothing/mask/fakemoustache = 11,
- /obj/item/clothing/mask/gas/clown_hat = 11,
- /obj/item/clothing/mask/gas/mime = 11,
- /obj/item/weapon/gun/energy/wand/toy = 5,
- /obj/item/device/binoculars = 11,
- /obj/item/device/megaphone = 11
- )
+ var/prize = /obj/random/arcade
/obj/machinery/computer/arcade/Initialize()
. = ..()
@@ -55,21 +18,18 @@
/obj/machinery/computer/arcade/proc/prizevend()
if(!contents.len)
- var/prizeselect = pickweight(prizes)
- new prizeselect(src.loc)
+ new prize(src.loc)
else
- var/atom/movable/prize = pick(contents)
- prize.loc = src.loc
+ var/atom/movable/chosen_prize = pick(contents)
+ chosen_prize.forceMove(src.loc)
/obj/machinery/computer/arcade/attack_ai(mob/user as mob)
return src.attack_hand(user)
-
/obj/machinery/computer/arcade/emp_act(severity)
if(stat & (NOPOWER|BROKEN))
..(severity)
return
- var/empprize = null
var/num_of_prizes = 0
switch(severity)
if(1)
@@ -77,8 +37,7 @@
if(2)
num_of_prizes = rand(0,2)
for(num_of_prizes; num_of_prizes > 0; num_of_prizes--)
- empprize = pickweight(prizes)
- new empprize(src.loc)
+ new prize(src.loc)
..(severity)
diff --git a/code/game/machinery/computer/sentencing.dm b/code/game/machinery/computer/sentencing.dm
index 72e9ff48529..c3845c05642 100644
--- a/code/game/machinery/computer/sentencing.dm
+++ b/code/game/machinery/computer/sentencing.dm
@@ -162,7 +162,7 @@
. += "
"
. += ""
. += " "
@@ -398,8 +398,8 @@
. += "[L.name] "
. += "[L.desc] "
- . += "[L.min_brig_time] - [L.max_brig_time] minutes "
- . += "[L.min_fine]-[L.max_fine]cR "
+ . += "[L.get_brig_time_string()] "
+ . += "[L.get_fine_string()] "
. += "Charge "
. += ""
. += " "
@@ -427,7 +427,7 @@
. += "[L.name] "
. += "[L.desc] "
- . += "[L.min_brig_time] - [L.max_brig_time] minutes "
- . += "[L.min_fine]-[L.max_fine]cR "
+ . += "[L.get_brig_time_string()] "
+ . += "[L.get_fine_string()] "
. += "Charge "
. += ""
. += " "
@@ -457,38 +457,66 @@
user << "[error]"
return
- incident.renderGuilty( user )
+ print_incident_overview(incident.renderGuilty(user, 0))
var/obj/item/weapon/card/id/card = incident.card.resolve()
if( incident.brig_sentence < PERMABRIG_SENTENCE)
- ping( "\The [src] pings, \"[card] has been found guilty of their crimes!\"" )
+ ping( "\The [src] pings, \"[card.registered_name] has been found guilty of their crimes!\"" )
else
- pingx3( "\The [src] pings, \"[card] has been found guilty of their crimes and earned a HuT Sentence\"" )
+ pingx3( "\The [src] pings, \"[card.registered_name] has been found guilty of their crimes and earned a HuT Sentence\"" )
incident = null
menu_screen = "main_menu"
-// /obj/machinery/computer/sentencing/proc/render_guilty_fine( var/mob/living/user, var/obj/item/weapon/card/id/C )
-// if( !incident )
-// user << "There is no active case!"
-// return
-//
-// if( !istype( user ))
-// return
-//
-// var/error = print_incident_report()
-//
-// if( error )
-// user << "[error]"
-// return
-//
-// //TODO: Try to charge the criminal if not return and print error message
-//
-// incident.renderGuilty( user )
-//
-// ping( "\The [src] pings, \"[incident.card] has been fined for their crimes!\"" )
-//
-// incident = null
-// menu_screen = "main_menu"
+/obj/machinery/computer/sentencing/proc/render_guilty_fine( var/mob/living/user )
+ if(!incident)
+ user << "There is no active case!"
+ return
+
+ if(!istype(user))
+ return
+
+ if(incident.fine <= 0)
+ buzz("\The [src] buzzes, \"No fine has been entered!\"")
+ return
+
+ //Lets check if there is a felony amongst the crimes
+ for(var/datum/law/L in incident.charges)
+ if(L.felony)
+ buzz("\The [src] buzzes, \"The crimes are too severe to apply a fine!\"")
+ if(!L.can_fine())
+ buzz("\The [src] buzzes, \"It is not possible to fine for [L.name]\"")
+ return
+
+ //Try to resole the security account first
+ var/datum/money_account/security_account = department_accounts["Security"]
+ if(!security_account)
+ buzz("\The [src] buzzes, \"Could not get security account!\"")
+ return
+
+ var/obj/item/weapon/card/id/card = incident.card.resolve()
+ //Let´s get the account of the suspect and verify they have enough money
+ var/datum/money_account/suspect_account = get_account(card.associated_account_number)
+ if(!suspect_account)
+ buzz("\The [src] buzzes, \"Could not get suspect account!\"")
+ return
+
+ if(suspect_account.money < incident.fine)
+ buzz("\The [src] buzzes, \"There is not enough money in the account to pay the fine!\"")
+ return
+
+ charge_to_account(suspect_account.account_number,security_account.owner_name,"Incident: [incident.UID]","Sentencing Console",-incident.fine)
+ charge_to_account(security_account.account_number,suspect_account.owner_name,"Incident: [incident.UID]Fine","Sentencing Console",incident.fine)
+ print_incident_overview(incident.renderGuilty(user,1))
+
+ ping("\The [src] pings, \"[card.registered_name] has been fined for their crimes!\"")
+
+ incident = null
+ menu_screen = "main_menu"
+
+/obj/machinery/computer/sentencing/proc/print_incident_overview(var/text)
+ var/obj/item/weapon/paper/P = new /obj/item/weapon/paper
+ P.set_content_unsafe("Incident Summary",text)
+ print(P)
/obj/machinery/computer/sentencing/proc/print_incident_report( var/sentence = 1 )
var/error = incident.missingSentenceReq()
@@ -636,20 +664,13 @@
if( alert("No incident notes were added. Adding a short description of the incident is highly recommended. Do you still want to continue with the print?",,"Yes","No") == "No" )
return
render_guilty( usr )
- // if( "render_guilty_fine")
- // //Check for the notes
- // if( !incident.notes )
- // if( alert("No incident notes were added. Adding a short description of the incident is highly recommended. Do you still want to continue with the print?",,"Yes","No") == "No" )
- // return
- // //Get the ID Card
- // var/obj/item/weapon/card/id/C = usr.get_active_hand()
- // if( istype( C ))
- // if( incident && C.mob )
- // render_guilty_fine( usr, C)
- // else
- // usr << "\The [src] buzzes, \"ID card not tied to a NanoTrasen Employee!\""
- // else
- // usr << "\The [src] buzzes, \"The suspects ID is required to fine them\""
+ if( "render_guilty_fine" )
+ //Check for the notes
+ if( !incident.notes )
+ if( alert("No incident notes were added. Adding a short description of the incident is highly recommended. Do you still want to continue with the print?",,"Yes","No") == "No" )
+ return
+ //Get the ID Card
+ render_guilty_fine( usr )
add_fingerprint(usr)
updateUsrDialog()
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index bd6941952ff..97f31919a7e 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -296,6 +296,13 @@ Class Procs:
state(text, "blue")
playsound(src.loc, 'sound/machines/pingx3.ogg', 50, 0)
+/obj/machinery/proc/buzz(text=null)
+ if (!text)
+ text = "\The [src] buzzes."
+
+ state(text, "blue")
+ playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) //TODO: Check if that one is the correct sound
+
/obj/machinery/proc/shock(mob/user, prb)
if(inoperable())
return 0
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index c99f748c6dd..9ed344c1c4b 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -2,126 +2,8 @@
//################### NEWSCASTERS BE HERE! ####
//###-Agouri###################################
-/datum/feed_message
- var/author =""
- var/body =""
- var/message_type ="Story"
- var/datum/feed_channel/parent_channel
- var/is_admin_message = 0
- var/icon/img = null
- var/icon/caption = ""
- var/time_stamp = ""
- var/backup_body = ""
- var/backup_author = ""
- var/icon/backup_img = null
- var/icon/backup_caption = ""
-
-/datum/feed_channel
- var/channel_name=""
- var/list/datum/feed_message/messages = list()
- var/locked=0
- var/author=""
- var/backup_author=""
- var/censored=0
- var/is_admin_channel=0
- var/updated = 0
- var/announcement = ""
-
-/datum/feed_message/proc/clear()
- src.author = ""
- src.body = ""
- src.caption = ""
- src.img = null
- src.time_stamp = ""
- src.backup_body = ""
- src.backup_author = ""
- src.backup_caption = ""
- src.backup_img = null
- parent_channel.update()
-
-/datum/feed_channel/proc/update()
- updated = world.time
-
-/datum/feed_channel/proc/clear()
- src.channel_name = ""
- src.messages = list()
- src.locked = 0
- src.author = ""
- src.backup_author = ""
- src.censored = 0
- src.is_admin_channel = 0
- src.announcement = ""
- update()
-
-/datum/feed_network
- var/list/datum/feed_channel/network_channels = list()
- var/datum/feed_message/wanted_issue
-
-/datum/feed_network/New()
- CreateFeedChannel("Station Announcements", "SS13", 1, 1, "New Station Announcement Available")
-
-/datum/feed_network/proc/CreateFeedChannel(var/channel_name, var/author, var/locked, var/adminChannel = 0, var/announcement_message)
- var/datum/feed_channel/newChannel = new /datum/feed_channel
- newChannel.channel_name = channel_name
- newChannel.author = author
- newChannel.locked = locked
- newChannel.is_admin_channel = adminChannel
- if(announcement_message)
- newChannel.announcement = announcement_message
- else
- newChannel.announcement = "Breaking news from [channel_name]!"
- network_channels += newChannel
-
-/datum/feed_network/proc/SubmitArticle(var/msg, var/author, var/channel_name, var/obj/item/weapon/photo/photo, var/adminMessage = 0, var/message_type = "")
- var/datum/feed_message/newMsg = new /datum/feed_message
- newMsg.author = author
- newMsg.body = msg
- newMsg.time_stamp = "[worldtime2text()]"
- newMsg.is_admin_message = adminMessage
- if(message_type)
- newMsg.message_type = message_type
- if(photo)
- newMsg.img = photo.img
- newMsg.caption = photo.scribble
- for(var/datum/feed_channel/FC in network_channels)
- if(FC.channel_name == channel_name)
- insert_message_in_channel(FC, newMsg) //Adding message to the network's appropriate feed_channel
- break
-
-/datum/feed_network/proc/insert_message_in_channel(var/datum/feed_channel/FC, var/datum/feed_message/newMsg)
- FC.messages += newMsg
- newMsg.parent_channel = FC
- FC.update()
- alert_readers(FC.announcement)
-
-/datum/feed_network/proc/alert_readers(var/annoncement)
- // get_receptions sleeps further down the line, spawn of elsewhere
- set waitfor = FALSE
- for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
- NEWSCASTER.newsAlert(annoncement)
- NEWSCASTER.update_icon()
-
- var/list/receiving_pdas = new
- for (var/obj/item/device/pda/P in PDAs)
- if (!P.owner)
- continue
- if (P.toff)
- continue
- receiving_pdas += P
-
- var/datum/receptions/receptions = get_receptions(null, receiving_pdas) // datums are not atoms, thus we have to assume the newscast network always has reception
-
- for(var/obj/item/device/pda/PDA in receiving_pdas)
- if(!(receptions.receiver_reception[PDA] & TELECOMMS_RECEPTION_RECEIVER))
- continue
-
- PDA.new_news(annoncement)
-
-var/datum/feed_network/news_network = new /datum/feed_network //The global news-network, which is coincidentally a global list.
-
var/list/obj/machinery/newscaster/allCasters = list() //Global list that will contain reference to all newscasters in existence.
-
/obj/machinery/newscaster
name = "newscaster"
desc = "A standard newsfeed handler for use on commercial space stations. All the news you absolutely have no use for, in one place!"
@@ -194,7 +76,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
cut_overlays() //reset overlays
- if(news_network.wanted_issue) //wanted icon state, there can be no overlays on it as it's a priority message
+ if(SSnews.wanted_issue) //wanted icon state, there can be no overlays on it as it's a priority message
icon_state = "newscaster_wanted"
return
@@ -262,7 +144,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
if(0)
dat += "Welcome to Newscasting Unit #[src.unit_no].[L.name] "
. += "[L.desc] "
- . += "[L.min_brig_time] - [L.max_brig_time] minutes "
+ . += "[L.get_brig_time_string()] "
. += "Charge "
. += "
Interface & News networks Operational."
dat += "
Property of Nanotransen Inc"
- if(news_network.wanted_issue)
+ if(SSnews.wanted_issue)
dat+= "
Read Wanted Issue"
dat+= "
"
else
dat+="None"
@@ -509,14 +397,16 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
else if(href_list["submit_new_channel"])
//var/list/existing_channels = list() //OBSOLETE
var/list/existing_authors = list()
- for(var/datum/feed_channel/FC in news_network.network_channels)
+ for(var/channel in SSnews.network_channels)
+ var/datum/feed_channel/FC = SSnews.GetFeedChannel(channel)
//existing_channels += FC.channel_name
if(FC.author == "\[REDACTED\]")
existing_authors += FC.backup_author
else
existing_authors +=FC.author
var/check = 0
- for(var/datum/feed_channel/FC in news_network.network_channels)
+ for(var/channel in SSnews.network_channels)
+ var/datum/feed_channel/FC = SSnews.GetFeedChannel(channel)
if(FC.channel_name == src.channel_name)
check = 1
break
@@ -525,7 +415,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
else
var/choice = alert("Please confirm Feed channel creation","Network Channel Handler","Confirm","Cancel")
if(choice=="Confirm")
- news_network.CreateFeedChannel(src.channel_name, src.scanned_user, c_locked)
+ SSnews.CreateFeedChannel(src.channel_name, src.scanned_user, c_locked)
src.screen=5
src.updateUsrDialog()
//src.update_icon()
@@ -533,9 +423,10 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
else if(href_list["set_channel_receiving"])
//var/list/datum/feed_channel/available_channels = list()
var/list/available_channels = list()
- for(var/datum/feed_channel/F in news_network.network_channels)
- if( (!F.locked || F.author == scanned_user) && !F.censored)
- available_channels += F.channel_name
+ for(var/channel in SSnews.network_channels)
+ var/datum/feed_channel/FC = SSnews.GetFeedChannel(channel)
+ if( (!FC.locked || FC.author == scanned_user) && !FC.censored)
+ available_channels += FC.channel_name
src.channel_name = input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels
src.updateUsrDialog()
@@ -553,7 +444,8 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
else
var/image = photo_data ? photo_data.photo : null
feedback_inc("newscaster_stories",1)
- news_network.SubmitArticle(src.msg, src.scanned_user, src.channel_name, image, 0)
+ var/datum/feed_channel/ch = SSnews.GetFeedChannel(src.channel_name)
+ SSnews.SubmitArticle(src.msg, src.scanned_user, ch, image, 0)
src.screen=4
src.updateUsrDialog()
@@ -587,12 +479,12 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
else if(href_list["menu_wanted"])
var/already_wanted = 0
- if(news_network.wanted_issue)
+ if(SSnews.wanted_issue)
already_wanted = 1
if(already_wanted)
- src.channel_name = news_network.wanted_issue.author
- src.msg = news_network.wanted_issue.body
+ src.channel_name = SSnews.wanted_issue.author
+ src.msg = SSnews.wanted_issue.body
src.screen = 14
src.updateUsrDialog()
@@ -618,29 +510,29 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
WANTED.backup_author = src.scanned_user //I know, a bit wacky
if(photo_data)
WANTED.img = photo_data.photo.img
- news_network.wanted_issue = WANTED
- news_network.alert_readers()
+ SSnews.wanted_issue = WANTED
+ SSnews.alert_readers()
src.screen = 15
else
- if(news_network.wanted_issue.is_admin_message)
+ if(SSnews.wanted_issue.is_admin_message)
alert("The wanted issue has been distributed by a [current_map.company_name] higherup. You cannot edit it.","Ok")
return
- news_network.wanted_issue.author = src.channel_name
- news_network.wanted_issue.body = src.msg
- news_network.wanted_issue.backup_author = src.scanned_user
+ SSnews.wanted_issue.author = src.channel_name
+ SSnews.wanted_issue.body = src.msg
+ SSnews.wanted_issue.backup_author = src.scanned_user
if(photo_data)
- news_network.wanted_issue.img = photo_data.photo.img
+ SSnews.wanted_issue.img = photo_data.photo.img
src.screen = 19
src.updateUsrDialog()
else if(href_list["cancel_wanted"])
- if(news_network.wanted_issue.is_admin_message)
+ if(SSnews.wanted_issue.is_admin_message)
alert("The wanted issue has been distributed by a [current_map.company_name] higherup. You cannot take it down.","Ok")
return
var/choice = alert("Please confirm Wanted Issue removal","Network Security Handler","Confirm","Cancel")
if(choice=="Confirm")
- news_network.wanted_issue = null
+ SSnews.wanted_issue = null
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
NEWSCASTER.update_icon()
src.screen=17
@@ -652,7 +544,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
else if(href_list["censor_channel_author"])
var/datum/feed_channel/FC = locate(href_list["censor_channel_author"])
if(FC.is_admin_channel)
- alert("This channel was created by a [current_map.company_name] Officer. You cannot censor it.","Ok")
+ alert("This channel was created by a [current_map.company_name] Officer or a external news agency. You cannot censor it.","Ok")
return
if(FC.author != "\[REDACTED\]")
FC.backup_author = FC.author
@@ -665,7 +557,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
else if(href_list["censor_channel_story_author"])
var/datum/feed_message/MSG = locate(href_list["censor_channel_story_author"])
if(MSG.is_admin_message)
- alert("This message was created by a [current_map.company_name] Officer. You cannot censor its author.","Ok")
+ alert("This message was created by a [current_map.company_name] Officer or a external news agency. You cannot censor its author.","Ok")
return
if(MSG.author != "\[REDACTED\]")
MSG.backup_author = MSG.author
@@ -678,7 +570,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
else if(href_list["censor_channel_story_body"])
var/datum/feed_message/MSG = locate(href_list["censor_channel_story_body"])
if(MSG.is_admin_message)
- alert("This channel was created by a [current_map.company_name] Officer. You cannot censor it.","Ok")
+ alert("This channel was created by a [current_map.company_name] Officer or a external news agency. You cannot censor it.","Ok")
return
if(MSG.body != "\[REDACTED\]")
MSG.backup_body = MSG.body
@@ -704,7 +596,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
else if(href_list["toggle_d_notice"])
var/datum/feed_channel/FC = locate(href_list["toggle_d_notice"])
if(FC.is_admin_channel)
- alert("This channel was created by a [current_map.company_name] Officer. You cannot place a D-Notice upon it.","Ok")
+ alert("This channel was created by a [current_map.company_name] Officer or a external news agency. You cannot place a D-Notice upon it.","Ok")
return
FC.censored = !FC.censored
FC.update()
@@ -978,10 +870,11 @@ obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user as mob)
/obj/machinery/newscaster/proc/print_paper()
feedback_inc("newscaster_newspapers_printed",1)
var/obj/item/weapon/newspaper/NEWSPAPER = new /obj/item/weapon/newspaper
- for(var/datum/feed_channel/FC in news_network.network_channels)
+ for(var/channel in SSnews.network_channels)
+ var/datum/feed_channel/FC = SSnews.GetFeedChannel(channel)
NEWSPAPER.news_content += FC
- if(news_network.wanted_issue)
- NEWSPAPER.important_message = news_network.wanted_issue
+ if(SSnews.wanted_issue)
+ NEWSPAPER.important_message = SSnews.wanted_issue
NEWSPAPER.loc = get_turf(src)
src.paper_remaining--
return
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index 0ae64ab9f6e..f90b70348a6 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -208,101 +208,101 @@ Buildable meters
/obj/item/pipe/proc/update()
var/list/nlist = list(
"pipe",
- "bent pipe",
+ "bent pipe",
"h/e pipe",
"bent h/e pipe",
"connector",
- "manifold",
- "junction",
- "uvent",
- "mvalve",
- "pump",
- "scrubber",
- "insulated pipe",
- "bent insulated pipe",
- "gas filter",
- "gas mixer",
- "pressure regulator",
- "high power pump",
- "heat exchanger",
- "t-valve",
- "4-way manifold",
- "pipe cap",
+ "manifold",
+ "junction",
+ "uvent",
+ "mvalve",
+ "pump",
+ "scrubber",
+ "insulated pipe",
+ "bent insulated pipe",
+ "gas filter",
+ "gas mixer",
+ "pressure regulator",
+ "high power pump",
+ "heat exchanger",
+ "t-valve",
+ "4-way manifold",
+ "pipe cap",
///// Z-Level stuff
- "pipe up",
- "pipe down",
+ "pipe up",
+ "pipe down",
///// Z-Level stuff
- "gas filter m",
- "gas mixer t",
- "gas mixer m",
- "omni mixer",
- "omni filter",
+ "gas filter m",
+ "gas mixer t",
+ "gas mixer m",
+ "omni mixer",
+ "omni filter",
///// Supply and scrubbers pipes
- "universal pipe adapter",
- "supply pipe",
- "bent supply pipe",
- "scrubbers pipe",
- "bent scrubbers pipe",
- "supply manifold",
- "scrubbers manifold",
- "supply 4-way manifold",
- "scrubbers 4-way manifold",
- "supply pipe up",
- "scrubbers pipe up",
- "supply pipe down",
- "scrubbers pipe down",
- "supply pipe cap",
- "scrubbers pipe cap",
+ "universal pipe adapter",
+ "supply pipe",
+ "bent supply pipe",
+ "scrubbers pipe",
+ "bent scrubbers pipe",
+ "supply manifold",
+ "scrubbers manifold",
+ "supply 4-way manifold",
+ "scrubbers 4-way manifold",
+ "supply pipe up",
+ "scrubbers pipe up",
+ "supply pipe down",
+ "scrubbers pipe down",
+ "supply pipe cap",
+ "scrubbers pipe cap",
"t-valve m"
)
name = nlist[pipe_type+1] + " fitting"
- var/list/islist = list(
- "simple",
- "simple",
- "he",
- "he",
- "connector",
- "manifold",
- "junction",
- "uvent",
- "mvalve",
- "pump",
- "scrubber",
- "insulated",
- "insulated",
- "filter",
- "mixer",
- "passivegate",
- "volumepump",
- "heunary",
- "mtvalve",
- "manifold4w",
- "cap",
+ var/list/islist = list(
+ "simple",
+ "simple",
+ "he",
+ "he",
+ "connector",
+ "manifold",
+ "junction",
+ "uvent",
+ "mvalve",
+ "pump",
+ "scrubber",
+ "insulated",
+ "insulated",
+ "filter",
+ "mixer",
+ "passivegate",
+ "volumepump",
+ "heunary",
+ "mtvalve",
+ "manifold4w",
+ "cap",
///// Z-Level stuff
- "cap",
- "cap",
+ "cap",
+ "cap",
///// Z-Level stuff
- "m_filter",
- "t_mixer",
- "m_mixer",
- "omni_mixer",
- "omni_filter",
+ "m_filter",
+ "t_mixer",
+ "m_mixer",
+ "omni_mixer",
+ "omni_filter",
///// Supply and scrubbers pipes
- "universal",
- "simple",
- "simple",
- "simple",
- "simple",
- "manifold",
- "manifold",
- "manifold4w",
- "manifold4w",
- "cap",
- "cap",
- "cap",
- "cap",
- "cap",
- "cap",
+ "universal",
+ "simple",
+ "simple",
+ "simple",
+ "simple",
+ "manifold",
+ "manifold",
+ "manifold4w",
+ "manifold4w",
+ "cap",
+ "cap",
+ "cap",
+ "cap",
+ "cap",
+ "cap",
"mtvalvem"
)
icon_state = islist[pipe_type + 1]
@@ -359,16 +359,16 @@ Buildable meters
var/acw = turn(dir, 90)
switch(pipe_type)
- if( PIPE_SIMPLE_STRAIGHT,
+ if( PIPE_SIMPLE_STRAIGHT,
PIPE_INSULATED_STRAIGHT,
- PIPE_HE_STRAIGHT,
+ PIPE_HE_STRAIGHT,
PIPE_JUNCTION ,
PIPE_PUMP ,
PIPE_VOLUME_PUMP ,
PIPE_PASSIVE_GATE ,
- PIPE_MVALVE,
- PIPE_SUPPLY_STRAIGHT,
- PIPE_SCRUBBERS_STRAIGHT,
+ PIPE_MVALVE,
+ PIPE_SUPPLY_STRAIGHT,
+ PIPE_SCRUBBERS_STRAIGHT,
PIPE_UNIVERSAL
)
return dir|flip
@@ -457,7 +457,7 @@ Buildable meters
else
user << "You can not change this pipe!"
return
-
+
else if(pipe_type in list (PIPE_SIMPLE_STRAIGHT, PIPE_SIMPLE_BENT, PIPE_SCRUBBERS_STRAIGHT, PIPE_SCRUBBERS_BENT, PIPE_SUPPLY_BENT, PIPE_SUPPLY_STRAIGHT))
if(pipe_type in list(PIPE_SIMPLE_BENT, PIPE_SIMPLE_STRAIGHT))
if(PIPE_SIMPLE_BENT)
@@ -475,7 +475,7 @@ Buildable meters
else
pipe_type = PIPE_SIMPLE_STRAIGHT
update()
-
+
if (!isturf(src.loc))
return 1
if (pipe_type in list (PIPE_SIMPLE_STRAIGHT, PIPE_SUPPLY_STRAIGHT, PIPE_SCRUBBERS_STRAIGHT, PIPE_HE_STRAIGHT, PIPE_INSULATED_STRAIGHT, PIPE_MVALVE))
@@ -1234,7 +1234,6 @@ Buildable meters
#undef PIPE_GAS_MIXER
#undef PIPE_PASSIVE_GATE
#undef PIPE_VOLUME_PUMP
-#undef PIPE_OUTLET_INJECT
#undef PIPE_MTVALVE
#undef PIPE_MTVALVEM
#undef PIPE_GAS_FILTER_M
diff --git a/code/game/machinery/station_holomap.dm b/code/game/machinery/station_holomap.dm
index 2bc2f3e2643..f360f5dd56a 100644
--- a/code/game/machinery/station_holomap.dm
+++ b/code/game/machinery/station_holomap.dm
@@ -29,7 +29,7 @@
var/datum/station_holomap/holomap_datum
/obj/machinery/station_map/Destroy()
- SSminimap.station_holomaps -= src
+ SSholomap.station_holomaps -= src
stopWatching()
QDEL_NULL(holomap_datum)
return ..()
@@ -38,12 +38,12 @@
. = ..()
holomap_datum = new()
original_zLevel = loc.z
- SSminimap.station_holomaps += src
+ SSholomap.station_holomaps += src
flags |= ON_BORDER // Why? It doesn't help if its not density
bogus = FALSE
var/turf/T = get_turf(src)
original_zLevel = T.z
- if(!("[HOLOMAP_EXTRA_STATIONMAP]_[original_zLevel]" in SSminimap.extra_minimaps))
+ if(!("[HOLOMAP_EXTRA_STATIONMAP]_[original_zLevel]" in SSholomap.extra_minimaps))
bogus = TRUE
holomap_datum.initialize_holomap_bogus()
update_icon()
@@ -51,11 +51,12 @@
holomap_datum.initialize_holomap(T, reinit = TRUE)
- small_station_map = image(SSminimap.extra_minimaps["[HOLOMAP_EXTRA_STATIONMAPSMALL]_[original_zLevel]"], dir = dir)
+ small_station_map = image(SSholomap.extra_minimaps["[HOLOMAP_EXTRA_STATIONMAPSMALL]_[original_zLevel]"], dir = dir)
small_station_map.layer = LIGHTING_LAYER + 0.1
floor_markings = image('icons/obj/machines/stationmap.dmi', "decal_station_map")
floor_markings.dir = src.dir
+ floor_markings.layer = ON_TURF_LAYER
update_icon()
/obj/machinery/station_map/attack_hand(var/mob/user)
@@ -153,7 +154,7 @@
if(bogus)
holomap_datum.initialize_holomap_bogus()
else
- small_station_map.icon = SSminimap.extra_minimaps["[HOLOMAP_EXTRA_STATIONMAPSMALL]_[original_zLevel]"]
+ small_station_map.icon = SSholomap.extra_minimaps["[HOLOMAP_EXTRA_STATIONMAPSMALL]_[original_zLevel]"]
add_overlay(small_station_map)
holomap_datum.initialize_holomap(get_turf(src))
@@ -200,7 +201,7 @@
/datum/station_holomap/proc/initialize_holomap(turf/T, isAI = null, mob/user = null, reinit = FALSE)
if(!station_map || reinit)
- station_map = image(SSminimap.extra_minimaps["[HOLOMAP_EXTRA_STATIONMAP]_[T.z]"])
+ station_map = image(SSholomap.extra_minimaps["[HOLOMAP_EXTRA_STATIONMAP]_[T.z]"])
if(!cursor || reinit)
cursor = image('icons/misc/holomap_markers.dmi', "you")
if(!legend || reinit)
diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm
index 660eccf0acb..abe0e544393 100644
--- a/code/game/machinery/status_display.dm
+++ b/code/game/machinery/status_display.dm
@@ -238,8 +238,7 @@
mode = STATUS_DISPLAY_TIME
update()
-#undef CHARS_PER_LINE
-#undef FOND_SIZE
+#undef FONT_SIZE
#undef FONT_COLOR
#undef FONT_STYLE
#undef SCROLL_SPEED
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 33af2876cc9..36f411d1521 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -98,7 +98,8 @@
var/datum/wires/vending/wires = null
var/can_move = 1 //if you can wrench the machine out of place
- var/vend_id = "generic"
+ var/vend_id = "generic" //Id of the refill cartridge that has to be used
+ var/restock_items = 0 //If items can be restocked into the vending machine
/obj/machinery/vending/Initialize()
. = ..()
@@ -270,7 +271,7 @@
else if(!is_borg_item(W))
for(var/datum/data/vending_product/R in product_records)
- if(istype(W, R.product_path))
+ if(istype(W, R.product_path) && restock_items)
stock(R, user)
qdel(W)
return
diff --git a/code/game/machinery/vending_types.dm b/code/game/machinery/vending_types.dm
index f7621057ecc..871ab1b80e6 100644
--- a/code/game/machinery/vending_types.dm
+++ b/code/game/machinery/vending_types.dm
@@ -265,6 +265,7 @@
/obj/item/weapon/reagent_containers/syringe/antiviral = 4,
/obj/item/weapon/reagent_containers/syringe = 12,
/obj/item/device/healthanalyzer = 5,
+ /obj/item/device/breath_analyzer = 2,
/obj/item/weapon/reagent_containers/glass/beaker = 4,
/obj/item/weapon/reagent_containers/dropper = 2,
/obj/item/stack/medical/advanced/bruise_pack = 3,
@@ -308,7 +309,8 @@
/obj/item/stack/medical/bruise_pack = 2,
/obj/item/stack/medical/ointment = 2,
/obj/item/weapon/reagent_containers/hypospray/autoinjector = 4,
- /obj/item/device/healthanalyzer = 1
+ /obj/item/device/healthanalyzer = 1,
+ /obj/item/device/breath_analyzer = 1
)
contraband = list(
/obj/item/weapon/reagent_containers/syringe/antitoxin = 4,
@@ -392,88 +394,91 @@
product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!"
icon_state = "seeds"
vend_id = "seeds"
-
products = list(
+ /obj/item/seeds/appleseed = 3,
/obj/item/seeds/bananaseed = 3,
/obj/item/seeds/berryseed = 3,
+ /obj/item/seeds/blueberryseed = 3,
+ /obj/item/seeds/cabbageseed = 3,
/obj/item/seeds/carrotseed = 3,
/obj/item/seeds/chantermycelium = 3,
+ /obj/item/seeds/cherryseed = 3,
/obj/item/seeds/chiliseed = 3,
+ /obj/item/seeds/cocoapodseed = 3,
/obj/item/seeds/cornseed = 3,
/obj/item/seeds/eggplantseed = 3,
+ /obj/item/seeds/grapeseed = 3,
+ /obj/item/seeds/grassseed = 3,
+ /obj/item/seeds/greengrapeseed = 3,
+ /obj/item/seeds/harebell = 3,
+ /obj/item/seeds/lemonseed = 3,
+ /obj/item/seeds/limeseed = 3,
+ /obj/item/seeds/mtearseed = 3,
+ /obj/item/seeds/orangeseed = 3,
+ /obj/item/seeds/peanutseed = 3,
+ /obj/item/seeds/plumpmycelium = 3,
+ /obj/item/seeds/poppyseed = 3,
/obj/item/seeds/potatoseed = 3,
+ /obj/item/seeds/pumpkinseed = 3,
/obj/item/seeds/replicapod = 3,
+ /obj/item/seeds/riceseed = 3,
+ /obj/item/seeds/shandseed = 3,
/obj/item/seeds/soyaseed = 3,
+ /obj/item/seeds/sugarcaneseed = 3,
/obj/item/seeds/sunflowerseed = 3,
/obj/item/seeds/tomatoseed = 3,
/obj/item/seeds/towermycelium = 3,
- /obj/item/seeds/wheatseed = 3,
- /obj/item/seeds/appleseed = 3,
- /obj/item/seeds/poppyseed = 3,
- /obj/item/seeds/sugarcaneseed = 3,
- /obj/item/seeds/peanutseed = 3,
- /obj/item/seeds/whitebeetseed = 3,
/obj/item/seeds/watermelonseed = 3,
- /obj/item/seeds/limeseed = 3,
- /obj/item/seeds/lemonseed = 3,
- /obj/item/seeds/orangeseed = 3,
- /obj/item/seeds/grassseed = 3,
- /obj/item/seeds/cocoapodseed = 3,
- /obj/item/seeds/plumpmycelium = 2,
- /obj/item/seeds/cabbageseed = 3,
- /obj/item/seeds/grapeseed = 3,
- /obj/item/seeds/pumpkinseed = 3,
- /obj/item/seeds/cherryseed = 3,
- /obj/item/seeds/plastiseed = 3,
- /obj/item/seeds/riceseed = 3
+ /obj/item/seeds/wheatseed = 3,
+ /obj/item/seeds/whitebeetseed = 3
)
contraband = list(
- /obj/item/seeds/amanitamycelium = 2,
- /obj/item/seeds/glowshroom = 2,
- /obj/item/seeds/libertymycelium = 2,
- /obj/item/seeds/mtearseed = 2,
- /obj/item/seeds/nettleseed = 2,
- /obj/item/seeds/reishimycelium = 2,
- /obj/item/seeds/reishimycelium = 2,
- /obj/item/seeds/shandseed = 2,
- /obj/item/seeds/ambrosiavulgarisseed = 3
- )
- premium = list(
- /obj/item/toy/waterflower = 1
+ /obj/item/seeds/amanitamycelium = 3,
+ /obj/item/seeds/ambrosiadeusseed = 3,
+ /obj/item/seeds/ambrosiavulgarisseed = 3,
+ /obj/item/seeds/glowshroom = 3,
+ /obj/item/seeds/libertymycelium = 3,
+ /obj/item/seeds/nettleseed = 3,
+ /obj/item/seeds/plastiseed = 3,
+ /obj/item/seeds/reishimycelium = 3
)
prices = list(
- /obj/item/seeds/bananaseed = 30,
- /obj/item/seeds/berryseed = 15,
- /obj/item/seeds/carrotseed = 15,
- /obj/item/seeds/chantermycelium = 5,
- /obj/item/seeds/chiliseed = 10,
- /obj/item/seeds/cornseed = 15,
- /obj/item/seeds/eggplantseed = 10,
- /obj/item/seeds/potatoseed = 10,
- /obj/item/seeds/replicapod = 175,
- /obj/item/seeds/soyaseed = 10,
- /obj/item/seeds/sunflowerseed = 5,
- /obj/item/seeds/tomatoseed = 15,
- /obj/item/seeds/towermycelium = 5,
- /obj/item/seeds/wheatseed = 5,
- /obj/item/seeds/appleseed = 15,
- /obj/item/seeds/poppyseed = 20,
- /obj/item/seeds/sugarcaneseed = 12,
- /obj/item/seeds/peanutseed = 25,
- /obj/item/seeds/whitebeetseed = 20,
- /obj/item/seeds/watermelonseed = 15,
- /obj/item/seeds/limeseed = 15,
- /obj/item/seeds/lemonseed = 15,
- /obj/item/seeds/orangeseed = 15,
- /obj/item/seeds/grassseed = 2,
- /obj/item/seeds/cocoapodseed = 25,
- /obj/item/seeds/plumpmycelium = 30,
- /obj/item/seeds/cabbageseed = 15,
- /obj/item/seeds/grapeseed = 15,
- /obj/item/seeds/pumpkinseed = 25,
- /obj/item/seeds/cherryseed = 25,
- /obj/item/seeds/plastiseed = 25,
- /obj/item/seeds/riceseed = 25
+ /obj/item/seeds/appleseed = 50,
+ /obj/item/seeds/bananaseed = 60,
+ /obj/item/seeds/berryseed = 40,
+ /obj/item/seeds/blueberryseed = 30,
+ /obj/item/seeds/cabbageseed = 40,
+ /obj/item/seeds/carrotseed = 20,
+ /obj/item/seeds/chantermycelium = 20,
+ /obj/item/seeds/cherryseed = 40,
+ /obj/item/seeds/chiliseed = 50,
+ /obj/item/seeds/cocoapodseed = 50,
+ /obj/item/seeds/cornseed = 30,
+ /obj/item/seeds/eggplantseed = 30,
+ /obj/item/seeds/grapeseed = 40,
+ /obj/item/seeds/grassseed = 40,
+ /obj/item/seeds/greengrapeseed = 40,
+ /obj/item/seeds/harebell = 10,
+ /obj/item/seeds/lemonseed = 40,
+ /obj/item/seeds/limeseed = 50,
+ /obj/item/seeds/mtearseed = 60,
+ /obj/item/seeds/orangeseed = 40,
+ /obj/item/seeds/peanutseed = 30,
+ /obj/item/seeds/plumpmycelium = 20,
+ /obj/item/seeds/poppyseed = 10,
+ /obj/item/seeds/potatoseed = 30,
+ /obj/item/seeds/pumpkinseed = 40,
+ /obj/item/seeds/replicapod = 200,
+ /obj/item/seeds/riceseed = 20,
+ /obj/item/seeds/shandseed = 60,
+ /obj/item/seeds/soyaseed = 40,
+ /obj/item/seeds/sugarcaneseed = 20,
+ /obj/item/seeds/sunflowerseed = 20,
+ /obj/item/seeds/tomatoseed = 30,
+ /obj/item/seeds/towermycelium = 20,
+ /obj/item/seeds/watermelonseed = 30,
+ /obj/item/seeds/wheatseed = 20,
+ /obj/item/seeds/whitebeetseed = 20
)
/**
@@ -721,36 +726,6 @@
)
//everything after the power cell had no amounts, I improvised. -Sayu
-//FOR ACTORS GUILD - mainly props that cannot be spawned otherwise
-/obj/machinery/vending/props
- name = "prop dispenser"
- desc = "All the props an actor could need. Probably."
- icon_state = "Theater"
- vend_id = "baygay"
- products = list(
- /obj/structure/flora/pottedplant = 2,
- /obj/item/device/flashlight/lamp = 2,
- /obj/item/device/flashlight/lamp/green = 2,
- /obj/item/weapon/reagent_containers/food/drinks/jar = 1,
- /obj/item/weapon/nullrod = 1,
- /obj/item/toy/cultsword = 4,
- /obj/item/toy/katana = 2,
- /obj/item/weapon/phone = 3
- )
-
-//FOR ACTORS GUILD - Containers
-/obj/machinery/vending/containers
- name = "container dispenser"
- desc = "A container that dispenses containers."
- icon_state = "robotics"
- vend_id = "baygay"
- products = list(
- /obj/structure/closet/crate/freezer = 2,
- /obj/structure/closet = 3,
- /obj/structure/closet/crate = 3
- )
-
-
//RECURSION
/obj/machinery/vending/vendors
name = "Omni-Vendor"
diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm
index 3b98de2ab07..60e59c20803 100644
--- a/code/game/objects/effects/landmarks.dm
+++ b/code/game/objects/effects/landmarks.dm
@@ -144,7 +144,7 @@
delete_me = 1
/obj/effect/landmark/costume/maid/New()
- new /obj/item/clothing/under/blackskirt(src.loc)
+ new /obj/item/clothing/under/skirt/(src.loc)
var/CHOICE = pick( /obj/item/clothing/head/beret , /obj/item/clothing/head/rabbitears )
new CHOICE(src.loc)
new /obj/item/clothing/glasses/sunglasses/blindfold(src.loc)
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index b03b65c0d9c..ea55f23dd5f 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -427,10 +427,6 @@ var/global/list/obj/item/device/pda/PDAs = list()
data["new_Message"] = new_message
data["new_News"] = new_news
- var/datum/reception/reception = get_reception(src, do_sleep = 0)
- var/has_reception = reception.telecomms_reception & TELECOMMS_RECEPTION_SENDER
- data["reception"] = has_reception
-
if(mode==2)
var/convopdas[0]
var/pdas[0]
@@ -453,7 +449,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(P.icon_state == "pda-hos"||P.icon_state == "pda-warden"||P.icon_state == "pda-det"||P.icon_state == "pda-sec"||P.icon_state == "pda-s")
pdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "0")))
if(4) //eng
- if(P.icon_state == "pda-ce"||P.icon_state == "pda-e"||P.icon_state == "pda-atmo"||P.icon_state == "pda-j")
+ if(P.icon_state == "pda-ce"||P.icon_state == "pda-e"||P.icon_state == "pda-atmo")
pdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "0")))
if(5) //sci
if(P.icon_state == "pda-rd"||P.icon_state == "pda-tox"||P.icon_state == "pda-v"||P.icon_state == "pda-robot")
@@ -462,7 +458,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(P.icon_state == "pda-hop"||P.icon_state == "pda-cargo"||P.icon_state == "pda-q"||P.icon_state == "pda-miner")
pdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "0")))
if(7) //service
- if(P.icon_state == "pda-hop"||P.icon_state == "pda-bar"||P.icon_state == "pda-holy"||P.icon_state == "pda-lawyer"||P.icon_state == "pda-libb"||P.icon_state == "pda-hydro"||P.icon_state == "pda-chef")
+ if(P.icon_state == "pda-hop"||P.icon_state == "pda-bar"||P.icon_state == "pda-holy"||P.icon_state == "pda-lawyer"||P.icon_state == "pda-libb"||P.icon_state == "pda-hydro"||P.icon_state == "pda-chef"||P.icon_state == "pda-j")
pdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "0")))
if(8) //medical
if(P.icon_state == "pda-cmo"||P.icon_state == "pda-v"||P.icon_state == "pda-m"||P.icon_state == "pda-chem")
@@ -518,16 +514,13 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(isnull(data["aircontents"]))
data["aircontents"] = list("reading" = 0)
if(mode==6)
- if(has_reception)
- feeds.Cut()
- for(var/datum/feed_channel/channel in news_network.network_channels)
- feeds[++feeds.len] = list("name" = channel.channel_name, "censored" = channel.censored)
+ feeds.Cut()
+ for(var/channel in SSnews.network_channels)
+ var/datum/feed_channel/FC = SSnews.GetFeedChannel(channel)
+ feeds[++feeds.len] = list("name" = FC.channel_name, "censored" = FC.censored)
data["feedChannels"] = feeds
if(mode==61)
- var/datum/feed_channel/FC
- for(FC in news_network.network_channels)
- if(FC.channel_name == active_feed["name"])
- break
+ var/datum/feed_channel/FC = SSnews.GetFeedChannel(active_feed["name"])
var/list/feed = feed_info[active_feed]
if(!feed)
@@ -538,7 +531,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
feed["updated"] = -1
feed_info[active_feed] = feed
- if(FC.updated > feed["updated"] && has_reception)
+ if(FC.updated > feed["updated"])
feed["author"] = FC.author
feed["updated"] = FC.updated
feed["censored"] = FC.censored
@@ -910,65 +903,56 @@ var/global/list/obj/item/device/pda/PDAs = list()
/obj/item/device/pda/proc/detonate_act(var/obj/item/device/pda/P)
//TODO: sometimes these attacks show up on the message server
- var/i = rand(1,100)
- var/j = rand(0,1) //Possibility of losing the PDA after the detonation
+ var/effect = pick("explosion", "burn", "emp", "smoke", "stun", "spark")
var/message = ""
var/mob/living/M = null
if(ismob(P.loc))
M = P.loc
- //switch(i) //Yes, the overlapping cases are intended.
- if(i<=10) //The traditional explosion
- P.explode()
- j=1
- message += "Your [P] suddenly explodes!"
- if(i>=10 && i<= 20) //The PDA burns a hole in the holder.
- j=1
- if(M && isliving(M))
- M.apply_damage( rand(30,60) , BURN)
- message += "You feel a searing heat! Your [P] is burning!"
- if(i>=20 && i<=25) //EMP
- empulse(P.loc, 3, 6, 1)
- message += "Your [P] emits a wave of electromagnetic energy!"
- if(i>=25 && i<=40) //Smoke
- var/datum/effect/effect/system/smoke_spread/chem/S = new /datum/effect/effect/system/smoke_spread/chem
- S.attach(P.loc)
- S.set_up(P, 10, 0, P.loc, 60)
- playsound(P.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
- S.start()
- message += "Large clouds of smoke billow forth from your [P]!"
- if(i>=40 && i<=45) //Bad smoke
- var/datum/effect/effect/system/smoke_spread/bad/B = new /datum/effect/effect/system/smoke_spread/bad
- B.attach(P.loc)
- B.set_up(P, 10, 0, P.loc)
- playsound(P.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
- B.start()
- message += "Large clouds of noxious smoke billow forth from your [P]!"
- if(i>=65 && i<=75) //Weaken
- if(M && isliving(M))
- M.apply_effects(weaken = 1)
- message += "Your [P] flashes with a blinding white light! You feel weaker."
- if(i>=75 && i<=85) //Stun and stutter
- if(M && isliving(M))
- M.apply_effects(stun = 1, stutter = 1)
- message += "Your [P] flashes with a blinding white light! You feel weaker."
- if(i>=85) //Sparks
- spark(P.loc, 2)
- message += "Your [P] begins to spark violently!"
- if(i>45 && i<65 && prob(50)) //Nothing happens
- message += "Your [P] bleeps loudly."
- j = prob(10)
+ switch(effect)
- if(j) //This kills the PDA
- qdel(P)
- if(message)
- message += "It melts in a puddle of plastic."
- else
- message += "Your [P] shatters in a thousand pieces!"
+ if("explosion")
+ P.explode()
+ message += "Your [P] suddenly explodes!"
+
+ if("burn")
+ if(M && isliving(M))
+ M.apply_damage( rand(30,60) , BURN)
+ message += "You feel a searing heat! Your [P] is burning!"
+
+ if("emp")
+ empulse(P.loc, 3, 6, 1)
+
+ if("smoke")
+ var/datum/effect/effect/system/smoke_spread/bad/S = new /datum/effect/effect/system/smoke_spread/bad
+ S.set_up(P, 10, 0, P.loc, 60)
+ S.attach(P.loc)
+ S.start()
+ playsound(P.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
+ message += "Large clouds of smoke billow forth from your [P]!"
+
+ if("stun")
+ if(M && isliving(M))
+ M.apply_effect(5, WEAKEN)
+ flick("flash", M.flash)
+ message += "Your [P] flashes with a blinding white light!"
+
+ if("spark")
+ spark(P.loc, 2)
+ message += "Your [P] begins to spark violently!"
+
+ if(message)
+ message += " "
+
+ if(effect == "explosion")
+ message += "Your [P] shatters in a thousand pieces!"
+ else
+ message += "\The [P] melts in a puddle of plastic."
if(M && isliving(M))
- message = "[message]"
- M.show_message(message, 1)
+ to_chat(M, "[message]")
+
+ qdel(P)
/obj/item/device/pda/proc/remove_id()
if (id)
@@ -1473,20 +1457,20 @@ var/global/list/obj/item/device/pda/PDAs = list()
icon = 'icons/obj/pda.dmi'
icon_state = "pdabox"
- New()
- ..()
- new /obj/item/device/pda(src)
- new /obj/item/device/pda(src)
- new /obj/item/device/pda(src)
- new /obj/item/device/pda(src)
- new /obj/item/weapon/cartridge/head(src)
+/obj/item/weapon/storage/box/PDAs/fill()
+ ..()
+ new /obj/item/device/pda(src)
+ new /obj/item/device/pda(src)
+ new /obj/item/device/pda(src)
+ new /obj/item/device/pda(src)
+ new /obj/item/weapon/cartridge/head(src)
- var/newcart = pick( /obj/item/weapon/cartridge/engineering,
- /obj/item/weapon/cartridge/security,
- /obj/item/weapon/cartridge/medical,
- /obj/item/weapon/cartridge/signal/science,
- /obj/item/weapon/cartridge/quartermaster)
- new newcart(src)
+ var/newcart = pick( /obj/item/weapon/cartridge/engineering,
+ /obj/item/weapon/cartridge/security,
+ /obj/item/weapon/cartridge/medical,
+ /obj/item/weapon/cartridge/signal/science,
+ /obj/item/weapon/cartridge/quartermaster)
+ new newcart(src)
// Pass along the pulse to atoms in contents, largely added so pAIs are vulnerable to EMP
/obj/item/device/pda/emp_act(severity)
diff --git a/code/game/objects/items/devices/oxycandle.dm b/code/game/objects/items/devices/oxycandle.dm
new file mode 100644
index 00000000000..229346dbb1b
--- /dev/null
+++ b/code/game/objects/items/devices/oxycandle.dm
@@ -0,0 +1,73 @@
+/obj/item/device/oxycandle
+ name = "oxygen candle"
+ desc = "A steel tube with the words 'OXYGEN - PULL CORD TO IGNITE' stamped on the side. A small label warns against using the device underwater"
+ icon = 'icons/obj/device.dmi'
+ icon_state = "oxycandle"
+ item_state = "oxycandle"
+ w_class = ITEMSIZE_SMALL // Should fit into internal's box or maybe pocket
+ var/target_pressure = ONE_ATMOSPHERE
+ var/datum/gas_mixture/air_contents = null
+ var/volume = 5600 // One tile has 2500 volume of air, so two tiles plus a bit extra
+ var/on = FALSE
+ var/activation_sound = 'sound/items/flare.ogg'
+ light_color = LIGHT_COLOR_FLARE
+ uv_intensity = 50
+ var/brightness_on = 2 // Moderate bright.
+ light_power = 2
+ action_button_name = null
+
+/obj/item/device/oxycandle/attack_self(mob/user)
+ if(!on)
+ user << "You pull the cord and [src] ignites."
+ light_range = brightness_on
+ on = TRUE
+ update_icon()
+ playsound(src.loc, activation_sound, 75, 1)
+ air_contents = new /datum/gas_mixture()
+ air_contents.volume = 200 //liters
+ air_contents.temperature = T20C
+ var/list/air_mix = list("oxygen" = O2STANDARD * (target_pressure * air_contents.volume) / (R_IDEAL_GAS_EQUATION * air_contents.temperature),
+ "nitrogen" = N2STANDARD * (target_pressure * air_contents.volume) / (R_IDEAL_GAS_EQUATION * air_contents.temperature))
+ air_contents.adjust_multi("oxygen", air_mix["oxygen"], "nitrogen", air_mix["nitrogen"])
+ START_PROCESSING(SSprocessing, src)
+
+// Process of Oxygen candles releasing air. Makes 200 volume of oxygen and nitrogen mix
+/obj/item/device/oxycandle/process()
+ if(!loc)
+ return
+ var/turf/pos = get_turf(src)
+ if(volume <= 0 || istype(pos, /turf/simulated/floor/beach/water) || istype(pos, /turf/unsimulated/beach/water))
+ STOP_PROCESSING(SSprocessing, src)
+ icon_state = "oxycandle_burnt"
+ item_state = icon_state
+ set_light(0)
+ update_held_icon()
+ name = "burnt oxygen candle"
+ desc += "This tube has exhausted its chemicals."
+ return
+ if(pos)
+ pos.hotspot_expose(1500, 5)
+ var/datum/gas_mixture/environment = loc.return_air()
+ var/pressure_delta = target_pressure - environment.return_pressure()
+ var/output_volume = environment.volume * environment.group_multiplier
+ var/air_temperature = air_contents.temperature? air_contents.temperature : environment.temperature
+ var/transfer_moles = pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION)
+ var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
+ if (!removed) //Just in case
+ return
+ environment.merge(removed)
+ volume -= 200
+ var/list/air_mix = list("oxygen" = O2STANDARD * (target_pressure * air_contents.volume) / (R_IDEAL_GAS_EQUATION * air_contents.temperature),
+ "nitrogen" = N2STANDARD * (target_pressure * air_contents.volume) / (R_IDEAL_GAS_EQUATION * air_contents.temperature))
+ air_contents.adjust_multi("oxygen", air_mix["oxygen"], "nitrogen", air_mix["nitrogen"])
+
+/obj/item/device/oxycandle/update_icon()
+ if(on)
+ icon_state = "oxycandle_on"
+ item_state = icon_state
+ set_light(brightness_on)
+ else
+ icon_state = "oxycandle"
+ item_state = icon_state
+ set_light(0)
+ update_held_icon()
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index e6bfd0b2bc6..a282e3c0a0f 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -226,13 +226,6 @@
item_state = "headset"
ks2type = /obj/item/device/encryptionkey/heads/hos
-/obj/item/device/radio/headset/entertainment
- name = "actor's radio headset"
- desc = "specially made to make you sound less cheesy."
- icon_state = "com_headset"
- item_state = "headset"
- ks2type = /obj/item/device/encryptionkey/entertainment
-
/obj/item/device/radio/headset/attackby(obj/item/weapon/W as obj, mob/user as mob)
// ..()
user.set_machine(src)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 0c5aaae72df..54754b5cb97 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -4,6 +4,7 @@ HEALTH ANALYZER
GAS ANALYZER
MASS SPECTROMETER
REAGENT SCANNER
+BREATH ANALYZER
*/
/obj/item/device/healthanalyzer
@@ -19,8 +20,7 @@ REAGENT SCANNER
throw_range = 10
matter = list(DEFAULT_WALL_MATERIAL = 200)
origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 1)
- var/mode = 1;
-
+ var/mode = 1
/obj/item/device/healthanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
if ( ((CLUMSY in user.mutations) || (DUMB in user.mutations)) && prob(50))
@@ -112,15 +112,6 @@ REAGENT SCANNER
++unknown
if(unknown)
user << "Non-medical reagent[(unknown > 1)?"s":""] found in subject's stomach."
- if(C.breathing && C.breathing.total_volume)
- var/unknown = 0
- for(var/datum/reagent/R in C.breathing.reagent_list)
- if(R.scannable)
- user << "[R.name] found in subject's respitory system."
- else
- ++unknown
- if(unknown)
- user << "Non-medical reagent[(unknown > 1)?"s":""] found in subject's respitory system."
if(C.virus2.len)
for (var/ID in C.virus2)
if (ID in virusDB)
@@ -402,4 +393,93 @@ REAGENT SCANNER
var/value = get_value(target)
user.visible_message("\The [user] scans \the [target] with \the [src]")
- user.show_message("Price estimation of \the [target]: [value ? value : "N/A"] Credits")
\ No newline at end of file
+ user.show_message("Price estimation of \the [target]: [value ? value : "N/A"] Credits")
+
+
+/obj/item/device/breath_analyzer
+ name = "breath analyzer"
+ desc = "A hand-held breath analyzer that provides a robust amount of information about the subject's repository system."
+ icon_state = "breath_analyzer"
+ item_state = "analyzer"
+ w_class = 2.0
+ flags = CONDUCT
+ slot_flags = SLOT_BELT
+ throwforce = 5
+ throw_speed = 4
+ throw_range = 20
+ matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 20)
+ origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
+
+/obj/item/device/breath_analyzer/attack(mob/living/carbon/human/H as mob, mob/living/user as mob)
+
+ if (!istype(H))
+ to_chat(user,"You can't find a way to use the [src] on [H]!")
+ return
+
+ if ( ((CLUMSY in user.mutations) || (DUMB in user.mutations)) && prob(20))
+ to_chat(user,"Your hand slips from clumsiness!")
+ eyestab(H,user)
+ to_chat(user,"Alert: No breathing detected.")
+ return
+
+ if (!user.IsAdvancedToolUser())
+ to_chat(user,"You don't have the dexterity to do this!")
+ return
+
+ if(user == H && !H.can_eat(src))
+ return
+ else if(!H.can_force_feed(user, src))
+ return
+
+ user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
+ user.do_attack_animation(H)
+
+ user.visible_message("[user] is trying to take a breath sample from [H].","You gently insert the [src] into [H]'s mouth.")
+
+ if (!LAZYLEN(src.other_DNA))
+ LAZYADD(src.other_DNA, H.dna.unique_enzymes)
+ src.other_DNA_type = "saliva"
+
+ if (!do_after(user, 2 SECONDS, act_target = H))
+ to_chat(user,"You and the target need to be standing still in order to take a breath sample.")
+ return
+
+ user.visible_message("[user] takes a breath sample from [H].","The [src] clicks as it finishes reading [H]'s breath sample.")
+
+ to_chat(user,"Breath Sample Results:")
+
+ if(H.stat == DEAD || H.losebreath || !H.breathing)
+ to_chat(user,"Alert: No breathing detected.")
+ return
+
+ to_chat(user,H.getOxyLoss() > 50 ? "Severe oxygen deprivation detected." : "Subject oxygen levels normal.")
+ var/obj/item/organ/L = H.internal_organs_by_name["lungs"]
+ if(istype(L))
+ to_chat(user,L.is_bruised() ? "Ruptured lung detected." : "Subject lung health normal.")
+ else
+ to_chat(user,"Subject lung health unknown.")
+
+ var/additional_string = "\[NORMAL\]"
+ var/bac = H.get_blood_alcohol()
+ switch(bac)
+ if(INTOX_JUDGEIMP to INTOX_MUSCLEIMP)
+ additional_string = "\[LIGHTLY INTOXICATED\]"
+ if(INTOX_MUSCLEIMP to INTOX_VOMIT)
+ additional_string = "\[MODERATELY INTOXICATED\]"
+ if(INTOX_VOMIT to INTOX_BALANCE)
+ additional_string = "\[HEAVILY INTOXICATED\]"
+ if(INTOX_BALANCE to INTOX_DEATH)
+ additional_string = "\[ALCOHOL POISONING LIKELY\]"
+ if(INTOX_DEATH to INFINITY)
+ additional_string = "\[DEATH IMMINENT\]"
+ to_chat(user,"Blood Alcohol Content: [round(bac,0.01)] [additional_string]")
+
+ if(H.breathing && H.breathing.total_volume)
+ var/unknown = 0
+ for(var/datum/reagent/R in H.breathing.reagent_list)
+ if(R.scannable)
+ to_chat(user,"[R.name] found in subject's respitory system.")
+ else
+ ++unknown
+ if(unknown)
+ to_chat(user,"Non-medical reagent[(unknown > 1)?"s":""] found in subject's respitory system.")
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 932e625b824..cf474fbe798 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -9,6 +9,7 @@
throw_range = 20
var/heal_brute = 0
var/heal_burn = 0
+ var/apply_sounds
/obj/item/stack/medical/attack(mob/living/M as mob, mob/user as mob)
if (!istype(M) || istype(M, /mob/living/silicon) || istype(M, /mob/living/simple_animal/spiderbot))
@@ -65,6 +66,7 @@
origin_tech = list(TECH_BIO = 1)
heal_brute = 4
icon_has_variants = TRUE
+ apply_sounds = list('sound/items/rip1.ogg','sound/items/rip2.ogg')
/obj/item/stack/medical/bruise_pack/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
@@ -104,6 +106,7 @@
user.visible_message("\The [user] places a bandaid over \a [W.desc] on [M]'s [affecting.name].", \
"You place a bandaid over \a [W.desc] on [M]'s [affecting.name]." )
W.bandage()
+ playsound(src, pick(apply_sounds), 25)
used++
affecting.update_damages()
if(used == amount)
@@ -128,6 +131,7 @@
heal_burn = 4
origin_tech = list(TECH_BIO = 1)
icon_has_variants = TRUE
+ apply_sounds = list('sound/items/ointment.ogg')
/obj/item/stack/medical/ointment/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
@@ -145,6 +149,7 @@
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
user.visible_message("\The [user] starts salving wounds on [M]'s [affecting.name].", \
"You start salving the wounds on [M]'s [affecting.name]." )
+ playsound(src, pick(apply_sounds), 25)
if(!do_mob(user, M, 10))
user << "You must stand still to salve wounds."
return 1
@@ -166,6 +171,7 @@
icon_state = "traumakit"
heal_brute = 8
origin_tech = list(TECH_BIO = 1)
+ apply_sounds = list('sound/items/rip1.ogg','sound/items/rip2.ogg','sound/items/tape.ogg')
/obj/item/stack/medical/advanced/bruise_pack/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
@@ -204,6 +210,7 @@
else
user.visible_message("\The [user] smears some bioglue over \a [W.desc] on [M]'s [affecting.name].", \
"You smear some bioglue over \a [W.desc] on [M]'s [affecting.name]." )
+ playsound(src, pick(apply_sounds), 25)
W.bandage()
W.disinfect()
W.heal_damage(heal_brute)
@@ -229,7 +236,7 @@
icon_state = "burnkit"
heal_burn = 8
origin_tech = list(TECH_BIO = 1)
-
+ apply_sounds = list('sound/items/ointment.ogg')
/obj/item/stack/medical/advanced/ointment/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
@@ -247,6 +254,7 @@
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
user.visible_message("\The [user] starts salving wounds on [M]'s [affecting.name].", \
"You start salving the wounds on [M]'s [affecting.name]." )
+ playsound(src, pick(apply_sounds), 25)
if(!do_mob(user, M, 10))
user << "You must stand still to salve wounds."
return 1
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 18f261231cd..19f50e7af2e 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -349,18 +349,19 @@ var/const/NO_EMAG_ACT = -50
icon_state = "centcom"
registered_name = "Central Command"
assignment = "General"
- New()
- access = get_all_centcom_access()
- ..()
-/obj/item/weapon/card/id/centcom/ERT
+/obj/item/weapon/card/id/centcom/New()
+ access = get_all_centcom_access()
+ ..()
+
+/obj/item/weapon/card/id/ert
name = "\improper Emergency Response Team ID"
icon_state = "centcom"
assignment = "Emergency Response Team"
-obj/item/weapon/card/id/centcom/ERT/New()
+obj/item/weapon/card/id/ert/New()
+ access = get_all_station_access() + get_centcom_access("Emergency Response Team")
..()
- access = get_all_accesses() + get_centcom_access("Emergency Response Team")
/obj/item/weapon/card/id/all_access
name = "\improper Administrator's spare ID"
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index 82909d19447..440eb235ccd 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -184,7 +184,7 @@
invisibility = INVISIBILITY_MAXIMUM //Why am i doing this?
//To make sure all reagents can work
//correctly before deleting the grenade.
- QDEL_IN(src, 50)
+ QDEL_IN(src, 50)
/obj/item/weapon/grenade/chem_grenade/large
name = "large chem grenade"
@@ -283,6 +283,7 @@
beakers += B1
beakers += B2
icon_state = initial(icon_state) +"_locked"
+
/obj/item/weapon/grenade/chem_grenade/cleaner
name = "cleaner grenade"
desc = "BLAM!-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas."
@@ -304,6 +305,28 @@
beakers += B2
icon_state = initial(icon_state) +"_locked"
+/obj/item/weapon/grenade/chem_grenade/large/phoroncleaner
+ name = "large cardox grenade"
+ desc = "A large smoke grenade containing a heavy amount of cardox. Use in case of phoron leaks. Warning: Harmful to Vaurca health."
+ stage = 2
+ path = 1
+
+ Initialize()
+ . = ..()
+ var/obj/item/weapon/reagent_containers/glass/beaker/large/B1 = new(src)
+ var/obj/item/weapon/reagent_containers/glass/beaker/large/B2 = new(src)
+
+ B1.reagents.add_reagent("water", 60)
+ B1.reagents.add_reagent("cardox", 60)
+ B2.reagents.add_reagent("surfactant", 60)
+ B2.reagents.add_reagent("cardox", 60)
+
+ detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
+
+ beakers += B1
+ beakers += B2
+ icon_state = initial(icon_state) +"_locked"
+
/obj/item/weapon/grenade/chem_grenade/teargas
name = "tear gas grenade"
desc = "Concentrated Capsaicin. Contents under pressure. Use with caution."
diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm
index 49249241755..3440c0dd1f0 100644
--- a/code/game/objects/items/weapons/manuals.dm
+++ b/code/game/objects/items/weapons/manuals.dm
@@ -1368,3 +1368,34 @@