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 @@ . += "

" . += "
" . += "Render Guilty" - // . += "Render Guilty - Fine" + . += "Render Guilty - Fine" . += "
" return . @@ -368,8 +368,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" . += "" @@ -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.get_brig_time_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].
Interface & News networks Operational." dat += "
Property of Nanotransen Inc" - if(news_network.wanted_issue) + if(SSnews.wanted_issue) dat+= "
Read Wanted Issue" dat+= "

Create Feed Channel" dat+= "
View Feed Channels" @@ -272,7 +154,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co dat+= "

Exit" if(src.securityCaster) var/wanted_already = 0 - if(news_network.wanted_issue) + if(SSnews.wanted_issue) wanted_already = 1 dat+="
Feed Security functions:
" @@ -282,14 +164,15 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co dat+="

The newscaster recognises you as: [src.scanned_user]" if(1) dat+= "Station Feed Channels
" - if( isemptylist(news_network.network_channels) ) + if( isemptylist(SSnews.network_channels) ) dat+="No active channels found..." else - for(var/datum/feed_channel/CHANNEL in news_network.network_channels) - if(CHANNEL.is_admin_channel) - dat+="[CHANNEL.channel_name]
" + for(var/channel in SSnews.network_channels) + var/datum/feed_channel/FC = SSnews.GetFeedChannel(channel) + if(FC.is_admin_channel) + dat+="[FC.channel_name]
" else - dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
" + dat+="[FC.channel_name] [(FC.censored) ? ("***") : ()]
" dat+="

Refresh" dat+="
Back" if(2) @@ -324,7 +207,8 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co if(7) dat+="ERROR: Could not submit Feed Channel to Network.

" 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) if(FC.author == "\[REDACTED\]") existing_authors += FC.backup_author else @@ -334,7 +218,8 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co if(src.channel_name=="" || src.channel_name == "\[REDACTED\]") dat+="�Invalid channel name.
" 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 @@ -344,10 +229,11 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co dat+="�Channel author unverified.
" dat+="
Return
" if(8) - var/total_num=length(news_network.network_channels) + var/total_num=length(SSnews.network_channels) var/active_num=total_num var/message_num=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.censored) message_num += length(FC.messages) //Dont forget, datum/feed_channel's var messages is a list of datum/feed_message else @@ -383,22 +269,24 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co dat+="NOTE: Due to the nature of news Feeds, total deletion of a Feed Story is not possible.
" dat+="Keep in mind that users attempting to view a censored feed will instead see the \[REDACTED\] tag above it.
" dat+="
Select Feed channel to get Stories from:
" - if(isemptylist(news_network.network_channels)) + if(isemptylist(SSnews.network_channels)) dat+="No feed channels found active...
" else - for(var/datum/feed_channel/CHANNEL in news_network.network_channels) - dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
" + for(var/channel in SSnews.network_channels) + var/datum/feed_channel/FC = SSnews.GetFeedChannel(channel) + dat+="[FC.channel_name] [(FC.censored) ? ("***") : ()]
" dat+="
Cancel" if(11) dat+="[current_map.company_name] D-Notice Handler
" dat+="A D-Notice is to be bestowed upon the channel if the handling Authority deems it as harmful for the station's" dat+="morale, integrity or disciplinary behaviour. A D-Notice will render a channel unable to be updated by anyone, without deleting any feed" dat+="stories it might contain at the time. You can lift a D-Notice if you have the required access at any time.
" - if(isemptylist(news_network.network_channels)) + if(isemptylist(SSnews.network_channels)) dat+="No feed channels found active...
" else - for(var/datum/feed_channel/CHANNEL in news_network.network_channels) - dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
" + for(var/channel in SSnews.network_channels) + var/datum/feed_channel/FC = SSnews.GetFeedChannel(channel) + dat+="[FC.channel_name] [(FC.censored) ? ("***") : ()]
" dat+="
Back" if(12) @@ -431,7 +319,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co dat+="Wanted Issue Handler:" var/wanted_already = 0 var/end_param = 1 - if(news_network.wanted_issue) + if(SSnews.wanted_issue) wanted_already = 1 end_param = 2 @@ -442,7 +330,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co dat+="Description: [src.msg]
" dat+="Attach Photo: [(src.photo_data ? "Photo Attached" : "No Photo")]
" if(wanted_already) - dat+="Wanted Issue created by: [news_network.wanted_issue.backup_author]
" + dat+="Wanted Issue created by: [SSnews.wanted_issue.backup_author]
" else dat+="Wanted Issue will be created under prosecutor: [src.scanned_user]
" dat+="
[(wanted_already) ? ("Edit Issue") : ("Submit")]" @@ -465,12 +353,12 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co dat+="Wanted Issue successfully deleted from Circulation
" dat+="
Return
" if(18) - dat+="-- STATIONWIDE WANTED ISSUE --
\[Submitted by: [news_network.wanted_issue.backup_author]\]
" - dat+="Criminal: [news_network.wanted_issue.author]
" - dat+="Description: [news_network.wanted_issue.body]
" + dat+="-- STATIONWIDE WANTED ISSUE --
\[Submitted by: [SSnews.wanted_issue.backup_author]\]
" + dat+="Criminal: [SSnews.wanted_issue.author]
" + dat+="Description: [SSnews.wanted_issue.body]
" dat+="Photo:: " - if(news_network.wanted_issue.img) - usr << browse_rsc(news_network.wanted_issue.img, "tmp_photow.png") + if(SSnews.wanted_issue.img) + usr << browse_rsc(SSnews.wanted_issue.img, "tmp_photow.png") 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 @@ "} + +/obj/item/weapon/book/manual/brainwashing + name = "Disloyal to Loyal: The Legality of Brainwashing" + icon_state ="rulebook" + author = "Dr. Fredrick Richards" + title = "Disloyal to Loyal: The Legality of Brainwashing" + dat = {" + + + + +

Disloyal to Loyal: The Legality of Brainwashing

+

by Doctor Fredrick Richards with help from the NanoTrasen Legal Department

+ + While it may be tempting as a Captain, Head of Security, or sometimes an officer to go around distributing anti-psychotics to maintain the peace, there are a few Corporate regulations and rules that must be kept in mind before even considering obtaining the medication.

+ +

Pre-injection

+ Generally, anti-psychotic medications should only be given out to criminals who have been charged with crimes that typically have Hold until Transfer, Cyborgification, and Loyalty Implant sentences, however some exceptions may apply. It is important to note that when using medicine to rehabilitate a criminal, the criminal in question is now legally considered a medical patient. In Tau Ceti space, it is illegal to prescribe, consume, or force a patient to consume anti-psychotic medication as a non-medical professional. As such, a non-medical personnel who injects or feeds prisoners with anti-psychotics may be charged with Suspicious Conduct, Excessive Use of Force In Detainment, Mistreatment of Prisoners, Neglect of Duty, Assault, Exceeding Official Powers, Mistreatment of Prisoners, and/or Gross Negligence. A trained and licensed medical professional are legally required to perform an evaluation first, and must be the one to perform the injection.

+ +

Post-injection

+ It is your duty as a member of the security department to oversee the health and well-being of prisoners and parolees. Those who have been giving anti-psychotic medication must be carefully monitored for their behaviour. Prisoners who skip doses, or overdose, are a threat to themselves and the people near them. If in the case of an overdose occurs, or a dose is missed, medical personnel should be contacted immediately and the situation dealt with appropriately. Failure to do so may result in Gross Negligence charges and potential demotion. + + + "} diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 129a4675a64..825709f6b51 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -83,6 +83,7 @@ icon_state = "medicalbelt" item_state = "medical" can_hold = list( + /obj/item/device/breath_analyzer, /obj/item/device/healthanalyzer, /obj/item/weapon/dnainjector, /obj/item/weapon/reagent_containers/dropper, diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index ef32360f709..5f4efe54e78 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -764,6 +764,8 @@ W.damtype = "burn" W.icon_state = "match_lit" START_PROCESSING(SSprocessing, W) + playsound(src.loc, 'sound/items/match.ogg', 60, 1, -4) + user.visible_message("[user] strikes the match on the matchbox.") W.update_icon() return @@ -980,3 +982,27 @@ /obj/item/weapon/storage/box/stims/fill() for(var/i in 1 to 4) new /obj/item/weapon/reagent_containers/hypospray/autoinjector/stimpack(src) + +/obj/item/weapon/storage/box/inhalers + name = "inhaler kit" + desc = "A box filled with several inhalers and empty inhaler cartridges." + icon_state = "box_inhalers" + +/obj/item/weapon/storage/box/inhalers/fill() + for(var/i in 1 to 2) + new /obj/item/weapon/personal_inhaler(src) + + for(var/i in 1 to 6) + new /obj/item/weapon/reagent_containers/personal_inhaler_cartridge(src) + +/obj/item/weapon/storage/box/inhalers_large + name = "combat inhaler kit" + desc = "A box filled with a combat inhaler and several large empty inhaler cartridges." + icon_state = "box_inhalers" + +/obj/item/weapon/storage/box/inhalers_large/fill() + + new /obj/item/weapon/personal_inhaler/combat(src) + + for(var/i in 1 to 6) + new /obj/item/weapon/reagent_containers/personal_inhaler_cartridge/large(src) \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/briefcase.dm b/code/game/objects/items/weapons/storage/briefcase.dm index ff3d60aec8a..d9445e2a46e 100644 --- a/code/game/objects/items/weapons/storage/briefcase.dm +++ b/code/game/objects/items/weapons/storage/briefcase.dm @@ -10,3 +10,4 @@ w_class = 4 max_w_class = 3 max_storage_space = 16 + use_sound = 'sound/items/storage/briefcase.ogg' \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 6db5a72bbc4..11cccfbcfe7 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -295,3 +295,18 @@ /obj/item/weapon/storage/lockbox/vials/attackby(obj/item/weapon/W as obj, mob/user as mob) ..() update_icon() + +/obj/item/weapon/storage/fancy/chocolate_box + icon = 'icons/obj/chocolate.dmi' + icon_state = "chocolatebox" + icon_type = "chocolatebox" + name = "chocolate box" + storage_slots = 8 + can_hold = list( + /obj/item/weapon/reagent_containers/food/snacks + ) + +/obj/item/weapon/storage/fancy/chocolate_box/fill() + for(var/i=1; i <= storage_slots; i++) + new /obj/item/weapon/reagent_containers/food/snacks/random(src) + diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm index 53a4458c33c..3f394ad0a71 100644 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ b/code/game/objects/items/weapons/storage/firstaid.dm @@ -25,16 +25,14 @@ fill() ..() if (empty) return - icon_state = pick("ointment","firefirstaid") - + new /obj/item/weapon/reagent_containers/pill/kelotane( src ) + new /obj/item/weapon/reagent_containers/pill/kelotane( src ) + new /obj/item/weapon/reagent_containers/pill/kelotane( src ) + new /obj/item/stack/medical/ointment( src ) + new /obj/item/stack/medical/ointment( src ) new /obj/item/device/healthanalyzer( src ) new /obj/item/weapon/reagent_containers/hypospray/autoinjector( src ) - new /obj/item/stack/medical/ointment( src ) - new /obj/item/stack/medical/ointment( src ) - new /obj/item/weapon/reagent_containers/pill/kelotane( src ) - new /obj/item/weapon/reagent_containers/pill/kelotane( src ) - new /obj/item/weapon/reagent_containers/pill/kelotane( src ) //Replaced ointment with these since they actually work --Errorage return @@ -55,16 +53,14 @@ /obj/item/weapon/storage/firstaid/toxin name = "toxin first aid" - desc = "Used to treat when you have a high amoutn of toxins in your body." + desc = "Used to treat when you have a high amount of toxins in your body." icon_state = "antitoxin" item_state = "firstaid-toxin" fill() ..() if (empty) return - icon_state = pick("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3") - new /obj/item/weapon/reagent_containers/syringe/antitoxin( src ) new /obj/item/weapon/reagent_containers/syringe/antitoxin( src ) new /obj/item/weapon/reagent_containers/syringe/antitoxin( src ) @@ -75,21 +71,21 @@ return /obj/item/weapon/storage/firstaid/o2 - name = "oxygen deprivation first aid" - desc = "A box full of oxygen goodies." + name = "oxygen deprivation kit" + desc = "A box full of oxygen related goodies." icon_state = "o2" item_state = "firstaid-o2" fill() ..() if (empty) return - new /obj/item/weapon/reagent_containers/pill/dexalin( src ) - new /obj/item/weapon/reagent_containers/pill/dexalin( src ) - new /obj/item/weapon/reagent_containers/pill/dexalin( src ) - new /obj/item/weapon/reagent_containers/pill/dexalin( src ) + new /obj/item/weapon/reagent_containers/inhaler/dexalin( src ) + new /obj/item/weapon/reagent_containers/inhaler/dexalin( src ) + new /obj/item/weapon/reagent_containers/inhaler/dexalin( src ) + new /obj/item/weapon/reagent_containers/inhaler/dexalin( src ) new /obj/item/weapon/reagent_containers/hypospray/autoinjector( src ) - new /obj/item/weapon/reagent_containers/syringe/inaprovaline( src ) - new /obj/item/device/healthanalyzer( src ) + new /obj/item/weapon/reagent_containers/hypospray/autoinjector( src ) + new /obj/item/device/breath_analyzer( src ) return /obj/item/weapon/storage/firstaid/adv @@ -124,7 +120,7 @@ new /obj/item/weapon/storage/pill_bottle/dexalin_plus(src) new /obj/item/weapon/storage/pill_bottle/dylovene(src) new /obj/item/weapon/storage/pill_bottle/tramadol(src) - new /obj/item/weapon/storage/pill_bottle/spaceacillin(src) + new /obj/item/weapon/reagent_containers/inhaler/hyperzine(src) new /obj/item/stack/medical/splint(src) return @@ -133,6 +129,7 @@ desc = "Contains tools for surgery. Has precise foam fitting for safe transport." icon_state = "purplefirstaid" item_state = "firstaid-advanced" + use_sound = 'sound/items/storage/briefcase.ogg' /obj/item/weapon/storage/firstaid/surgery/fill() ..() @@ -147,7 +144,8 @@ new /obj/item/weapon/bonegel(src) new /obj/item/weapon/FixOVein(src) new /obj/item/stack/medical/advanced/bruise_pack(src) - + new /obj/item/weapon/reagent_containers/inhaler/soporific(src) + new /obj/item/weapon/reagent_containers/inhaler/soporific(src) make_exact_fit() /obj/item/weapon/storage/firstaid/brute @@ -179,7 +177,7 @@ can_hold = list(/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/dice,/obj/item/weapon/paper) allow_quick_gather = 1 use_to_pickup = 1 - use_sound = null + use_sound = 'sound/items/storage/pillbottle.ogg' max_storage_space = 16 /obj/item/weapon/storage/pill_bottle/antitox @@ -321,31 +319,3 @@ new /obj/item/weapon/reagent_containers/pill/escitalopram( src ) new /obj/item/weapon/reagent_containers/pill/escitalopram( src ) new /obj/item/weapon/reagent_containers/pill/escitalopram( src ) - -/obj/item/weapon/storage/pill_bottle/trisyndicotin - name = "bottle of Trisyndicotin pills" - desc = "Used to free one's mind from the oppression of NanoTrasen." - - fill() - ..() - new /obj/item/weapon/reagent_containers/pill/trisyndicotin( src ) - new /obj/item/weapon/reagent_containers/pill/trisyndicotin( src ) - new /obj/item/weapon/reagent_containers/pill/trisyndicotin( src ) - new /obj/item/weapon/reagent_containers/pill/trisyndicotin( src ) - new /obj/item/weapon/reagent_containers/pill/trisyndicotin( src ) - new /obj/item/weapon/reagent_containers/pill/trisyndicotin( src ) - new /obj/item/weapon/reagent_containers/pill/trisyndicotin( src ) - -/obj/item/weapon/storage/pill_bottle/hextrasenil - name = "bottle of Hextrasenil pills" - desc = "Pacification through medication." - - fill() - ..() - new /obj/item/weapon/reagent_containers/pill/hextrasenil( src ) - new /obj/item/weapon/reagent_containers/pill/hextrasenil( src ) - new /obj/item/weapon/reagent_containers/pill/hextrasenil( src ) - new /obj/item/weapon/reagent_containers/pill/hextrasenil( src ) - new /obj/item/weapon/reagent_containers/pill/hextrasenil( src ) - new /obj/item/weapon/reagent_containers/pill/hextrasenil( src ) - new /obj/item/weapon/reagent_containers/pill/hextrasenil( src ) diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm index b3c2403fd64..e2915bdd4f8 100644 --- a/code/game/objects/items/weapons/storage/lockbox.dm +++ b/code/game/objects/items/weapons/storage/lockbox.dm @@ -81,7 +81,6 @@ new /obj/item/weapon/implantcase/loyalty(src) new /obj/item/weapon/implanter/loyalty(src) - /obj/item/weapon/storage/lockbox/clusterbang name = "lockbox of clusterbangs" desc = "You have a bad feeling about opening this." diff --git a/code/game/objects/items/weapons/storage/misc.dm b/code/game/objects/items/weapons/storage/misc.dm index 74aba58cca2..bfa1dfa5a5a 100644 --- a/code/game/objects/items/weapons/storage/misc.dm +++ b/code/game/objects/items/weapons/storage/misc.dm @@ -49,3 +49,15 @@ /obj/item/weapon/storage/box/donut/empty startswith = 0 + +/obj/item/weapon/storage/box/pineapple + icon = 'icons/obj/storage.dmi' + icon_state = "pineapple_rings" + name = "can of pineapple rings" + var/startswith = 6 + can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/pineapple_ring) + +/obj/item/weapon/storage/box/pineapple/fill() + for(var/i=1; i <= startswith; i++) + new /obj/item/weapon/reagent_containers/food/snacks/pineapple_ring(src) + update_icon() diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm index f8675288777..4449825d3e5 100644 --- a/code/game/objects/items/weapons/storage/secure.dm +++ b/code/game/objects/items/weapons/storage/secure.dm @@ -26,6 +26,7 @@ w_class = 3 max_w_class = 2 max_storage_space = 14 + use_sound = 'sound/items/storage/briefcase.ogg' examine(mob/user) if(..(user, 1)) diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index fdc7a53fc57..63fba26cc5b 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -139,7 +139,7 @@ /obj/item/weapon/storage/proc/open(mob/user as mob) if (use_sound) - playsound(src.loc, src.use_sound, 50, 1, -5) + playsound(src.loc, src.use_sound, 50, 0, -5) orient2hud(user) if (user.s_active) diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm index 6f651bfb915..cbbf3e3cb08 100644 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ b/code/game/objects/items/weapons/storage/toolbox.dm @@ -14,6 +14,7 @@ max_storage_space = 14 //enough to hold all starting contents origin_tech = list(TECH_COMBAT = 1) attack_verb = list("robusted") + use_sound = 'sound/items/storage/toolbox.ogg' var/stunhit = 0 /obj/item/weapon/storage/toolbox/Initialize() diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index fe9b50bc857..bd2c48c208c 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -258,3 +258,14 @@ new /obj/item/weapon/spacecash/c1000(src) new /obj/item/weapon/spacecash/c1000(src) new /obj/item/weapon/spacecash/c1000(src) + +/obj/item/weapon/storage/box/syndie_kit/stimulants + name = "box of stimulants" + desc = "Comes with a combat inhaler, a large cartridge of hyperzine, a large cartridge of inaprovaline, and a large empty cartridge." + +/obj/item/weapon/storage/box/syndie_kit/stimulants/fill() + ..() + new /obj/item/weapon/personal_inhaler/combat( src ) + new /obj/item/weapon/reagent_containers/personal_inhaler_cartridge/large/hyperzine( src ) + new /obj/item/weapon/reagent_containers/personal_inhaler_cartridge/large/inaprovaline( src ) + new /obj/item/weapon/reagent_containers/personal_inhaler_cartridge/large( src ) \ No newline at end of file diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm index fc39a7d0d9e..f1e758692c7 100644 --- a/code/game/objects/items/weapons/tape.dm +++ b/code/game/objects/items/weapons/tape.dm @@ -30,6 +30,7 @@ if(!H || !src || !H.organs_by_name["head"] || !H.has_eyes() || H.glasses || (H.head && (H.head.body_parts_covered & FACE))) return + playsound(src, 'sound/items/tape.ogg',25) user.visible_message("\The [user] has taped up \the [H]'s eyes!") H.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses/blindfold/tape(H), slot_glasses) H.update_inv_glasses() @@ -47,6 +48,8 @@ if(H.head && (H.head.body_parts_covered & FACE)) user << "Remove their [H.head] first." return + + playsound(src, 'sound/items/tape.ogg',25) user.visible_message("\The [user] begins taping up \the [H]'s mouth!") if(!do_after(user, 30)) @@ -56,11 +59,13 @@ if(!H || !src || !H.organs_by_name["head"] || !H.check_has_mouth() || H.wear_mask || (H.head && (H.head.body_parts_covered & FACE))) return + playsound(src, 'sound/items/tape.ogg',25) user.visible_message("\The [user] has taped up \the [H]'s mouth!") H.equip_to_slot_or_del(new /obj/item/clothing/mask/muzzle/tape(H), slot_wear_mask) H.update_inv_wear_mask() else if(target_zone == "r_hand" || target_zone == "l_hand") + playsound(src, 'sound/items/tape.ogg',25) var/obj/item/weapon/handcuffs/cable/tape/T = new(user) if(!T.place_handcuffs(H, user)) user.unEquip(T) @@ -132,6 +137,7 @@ return // reduce papers around corners issue. user.drop_from_inventory(src) + playsound(src, 'sound/items/tape.ogg',25) forceMove(source_turf) if(params) diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm index e04605c026f..197045c4f1f 100644 --- a/code/game/objects/random/random.dm +++ b/code/game/objects/random/random.dm @@ -196,7 +196,8 @@ /obj/item/seeds/ambrosiavulgarisseed = 2, /obj/item/seeds/ambrosiadeusseed = 1, /obj/item/clothing/mask/gas/voice = 1, - /obj/item/clothing/gloves/brassknuckles = 2 + /obj/item/clothing/gloves/brassknuckles = 2, + /obj/item/weapon/reagent_containers/inhaler/space_drugs = 2 ) /obj/random/energy @@ -815,7 +816,9 @@ /obj/random/junk = 0.9, /obj/item/weapon/spacecash/ewallet/lotto = 0.3, /obj/random/spacecash = 0.3, - /obj/item/device/firing_pin = 0.3 + /obj/item/device/firing_pin = 0.3, + /obj/item/weapon/reagent_containers/inhaler/hyperzine = 0.1, + /obj/item/weapon/storage/box/pineapple = 0.1 ) /obj/random/hoodie @@ -939,3 +942,46 @@ /obj/item/weapon/material/sword/gladius ) +/obj/random/arcade + name = "random arcade loot" + desc = "Arcade loot!" + icon = 'icons/obj/items.dmi' + icon_state = "gift3" + spawnlist = 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 + ) \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index cd8fc764238..f7d41ed3097 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -111,6 +111,7 @@ new /obj/item/weapon/reagent_containers/hypospray(src) new /obj/item/clothing/suit/storage/toggle/labcoat/cmo(src) new /obj/item/clothing/suit/storage/toggle/labcoat/cmoalt(src) + new /obj/item/weapon/storage/box/inhalers(src) /obj/structure/closet/secure_closet/CMO2 name = "chief medical officer's attire" @@ -168,7 +169,8 @@ new /obj/item/weapon/storage/box/pillbottles(src) new /obj/item/weapon/storage/box/spraybottles(src) new /obj/item/weapon/storage/box/spraybottles(src) - + new /obj/item/weapon/storage/box/inhalers(src) + new /obj/item/weapon/storage/box/inhalers(src) /obj/structure/closet/secure_closet/medical_wall name = "first aid closet" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 7479bfb90b7..483f9cffdf0 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -148,10 +148,13 @@ new /obj/item/taperoll/police(src) new /obj/item/device/flash(src) new /obj/item/device/holowarrant(src) + new /obj/item/device/breath_analyzer(src) //Belts new /obj/item/clothing/accessory/holster/waist(src) new /obj/item/weapon/storage/belt/security(src) + + /obj/structure/closet/secure_closet/hos2 name = "head of security's attire" req_access = list(access_hos) @@ -178,6 +181,8 @@ new /obj/item/weapon/storage/belt/security(src) new /obj/item/clothing/accessory/holster/waist(src) + new /obj/item/device/breath_analyzer(src) + /obj/structure/closet/secure_closet/warden name = "warden's locker" req_access = list(access_armory) diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm index d995e358bf4..a1de0fb4dc5 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm @@ -28,6 +28,7 @@ new /obj/item/clothing/mask/breath(src) new /obj/item/clothing/suit/space/emergency(src) new /obj/item/clothing/head/helmet/space/emergency(src) + new /obj/item/device/oxycandle(src) if ("aid") new /obj/item/weapon/tank/emergency_oxygen(src) new /obj/item/weapon/storage/toolbox/emergency(src) @@ -35,11 +36,14 @@ new /obj/item/weapon/storage/firstaid/o2(src) new /obj/item/clothing/suit/space/emergency(src) new /obj/item/clothing/head/helmet/space/emergency(src) + new /obj/item/device/oxycandle(src) if ("tank") new /obj/item/weapon/tank/emergency_oxygen/engi(src) new /obj/item/clothing/mask/breath(src) new /obj/item/weapon/tank/emergency_oxygen/engi(src) new /obj/item/clothing/mask/breath(src) + new /obj/item/device/oxycandle(src) + new /obj/item/device/oxycandle(src) if ("both") new /obj/item/weapon/storage/toolbox/emergency(src) new /obj/item/weapon/tank/emergency_oxygen/engi(src) @@ -49,6 +53,9 @@ new /obj/item/clothing/suit/space/emergency(src) new /obj/item/clothing/head/helmet/space/emergency(src) new /obj/item/clothing/head/helmet/space/emergency(src) + new /obj/item/device/oxycandle(src) + new /obj/item/device/oxycandle(src) + new /obj/item/device/oxycandle(src) /obj/structure/closet/emcloset/legacy/fill() ..() diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm index ba7ab11a82d..f496d4c0b12 100644 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm @@ -377,9 +377,9 @@ new /obj/item/clothing/under/color/green(src) new /obj/item/clothing/under/color/orange(src) new /obj/item/clothing/under/color/pink(src) - new /obj/item/clothing/under/dress/plaid_blue(src) - new /obj/item/clothing/under/dress/plaid_red(src) - new /obj/item/clothing/under/dress/plaid_purple(src) + new /obj/item/clothing/under/skirt/plaid_blue(src) + new /obj/item/clothing/under/skirt/plaid_red(src) + new /obj/item/clothing/under/skirt/plaid_purple(src) new /obj/item/clothing/shoes/blue(src) new /obj/item/clothing/shoes/yellow(src) new /obj/item/clothing/shoes/green(src) diff --git a/code/game/periodic_news.dm b/code/game/periodic_news.dm index a6ef3e49564..eda911f93ca 100644 --- a/code/game/periodic_news.dm +++ b/code/game/periodic_news.dm @@ -52,14 +52,14 @@ random_junk cheesy_honkers - author = "Assistant Editor Carl Ritz" + author = "Editor Carl Ritz" channel_name = "The Gibson Gazette" message = {"Do cheesy honkers increase risk of having a miscarriage? Several health administrations say so!"} round_time = 60 * 15 net_block - author = "Assistant Editor Carl Ritz" + author = "Editor Carl Ritz" channel_name = "The Gibson Gazette" message = {"Several corporations banding together to block access to 'wetskrell.nt', site administrators claiming violation of net laws."} @@ -129,19 +129,10 @@ proc/check_for_newscaster_updates(type) announce_newscaster_news(news) proc/announce_newscaster_news(datum/news_announcement/news) - var/datum/feed_channel/sendto - for(var/datum/feed_channel/FC in news_network.network_channels) - if(FC.channel_name == news.channel_name) - sendto = FC - break - + var/datum/feed_channel/sendto = SSnews.GetFeedChannel(news.channel_name) if(!sendto) - sendto = new /datum/feed_channel - sendto.channel_name = news.channel_name - sendto.author = news.author - sendto.locked = 1 - sendto.is_admin_channel = 1 - news_network.network_channels += sendto + SSnews.CreateFeedChannel(news.channel_name, news.author, 1, 1) var/author = news.author ? news.author : sendto.author - news_network.SubmitArticle(news.message, author, news.channel_name, null, !news.can_be_redacted, news.message_type) + var/datum/feed_channel/ch = SSnews.GetFeedChannel(news.channel_name) + SSnews.SubmitArticle(news.message, author, ch, null, !news.can_be_redacted, news.message_type) diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index 2c6d3482a0d..3290f4177be 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -1,9 +1,4 @@ //Config stuff -#define SUPPLY_DOCKZ 3 //Z-level of the Dock. -#define SUPPLY_STATIONZ 1 //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 - //Supply packs are in /code/defines/obj/supplypacks.dm //Computers are in /code/game/machinery/computer/supply.dm diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index c7c445bd66f..4ce983e0c73 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -350,7 +350,7 @@ proc/admin_notice(var/message, var/rights)
Feed channels and stories entered through here will be uneditable and handled as official news by the rest of the units.
Note that this panel allows full freedom over the news network, there are no constrictions except the few basic ones. Don't break things! "} - if(news_network.wanted_issue) + if(SSnews.wanted_issue) dat+= "
Read Wanted Issue" dat+= {"

Create Feed Channel @@ -360,7 +360,7 @@ proc/admin_notice(var/message, var/rights) "} var/wanted_already = 0 - if(news_network.wanted_issue) + if(SSnews.wanted_issue) wanted_already = 1 dat+={"
Feed Security functions:
@@ -371,14 +371,15 @@ proc/admin_notice(var/message, var/rights) "} if(1) dat+= "Station Feed Channels
" - if( isemptylist(news_network.network_channels) ) + if( isemptylist(SSnews.network_channels) ) dat+="No active channels found..." else - for(var/datum/feed_channel/CHANNEL in news_network.network_channels) - if(CHANNEL.is_admin_channel) - dat+="[CHANNEL.channel_name]
" + for(var/channel in SSnews.network_channels) + var/datum/feed_channel/FC = SSnews.GetFeedChannel(channel) + if(FC.is_admin_channel) + dat+="[FC.channel_name]
" else - dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
" + dat+="[FC.channel_name] [(FC.censored) ? ("***") : ()]
" dat+={"

Refresh
Back "} @@ -421,7 +422,8 @@ proc/admin_notice(var/message, var/rights) if(src.admincaster_feed_channel.channel_name =="" || src.admincaster_feed_channel.channel_name == "\[REDACTED\]") dat+="•Invalid channel name.
" 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.admincaster_feed_channel.channel_name) check = 1 break @@ -458,11 +460,12 @@ proc/admin_notice(var/message, var/rights) Keep in mind that users attempting to view a censored feed will instead see the \[REDACTED\] tag above it.
Select Feed channel to get Stories from:
"} - if(isemptylist(news_network.network_channels)) + if(isemptylist(SSnews.network_channels)) dat+="No feed channels found active...
" else - for(var/datum/feed_channel/CHANNEL in news_network.network_channels) - dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
" + for(var/channel in SSnews.network_channels) + var/datum/feed_channel/FC = SSnews.GetFeedChannel(channel) + dat+="[FC.channel_name] [(FC.censored) ? ("***") : ()]
" dat+="
Cancel" if(11) dat+={" @@ -471,11 +474,12 @@ proc/admin_notice(var/message, var/rights) morale, integrity or disciplinary behaviour. A D-Notice will render a channel unable to be updated by anyone, without deleting any feed stories it might contain at the time. You can lift a D-Notice if you have the required access at any time.
"} - if(isemptylist(news_network.network_channels)) + if(isemptylist(SSnews.network_channels)) dat+="No feed channels found active...
" else - for(var/datum/feed_channel/CHANNEL in news_network.network_channels) - dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
" + for(var/channel in SSnews.network_channels) + var/datum/feed_channel/FC = SSnews.GetFeedChannel(channel) + dat+="[FC.channel_name] [(FC.censored) ? ("***") : ()]
" dat+="
Back" if(12) @@ -514,7 +518,7 @@ proc/admin_notice(var/message, var/rights) dat+="Wanted Issue Handler:" var/wanted_already = 0 var/end_param = 1 - if(news_network.wanted_issue) + if(SSnews.wanted_issue) wanted_already = 1 end_param = 2 if(wanted_already) @@ -525,7 +529,7 @@ proc/admin_notice(var/message, var/rights) Description: [src.admincaster_feed_message.body]
"} if(wanted_already) - dat+="Wanted Issue created by: [news_network.wanted_issue.backup_author]
" + dat+="Wanted Issue created by: [SSnews.wanted_issue.backup_author]
" else dat+="Wanted Issue will be created under prosecutor: [src.admincaster_signature]
" dat+="
[(wanted_already) ? ("Edit Issue") : ("Submit")]" @@ -551,13 +555,13 @@ proc/admin_notice(var/message, var/rights) "} if(18) dat+={" - -- STATIONWIDE WANTED ISSUE --
\[Submitted by: [news_network.wanted_issue.backup_author]\]
- Criminal: [news_network.wanted_issue.author]
- Description: [news_network.wanted_issue.body]
+ -- STATIONWIDE WANTED ISSUE --
\[Submitted by: [SSnews.wanted_issue.backup_author]\]
+ Criminal: [SSnews.wanted_issue.author]
+ Description: [SSnews.wanted_issue.body]
Photo:: "} - if(news_network.wanted_issue.img) - usr << browse_rsc(news_network.wanted_issue.img, "tmp_photow.png") + if(SSnews.wanted_issue.img) + usr << browse_rsc(SSnews.wanted_issue.img, "tmp_photow.png") dat+="
" else dat+="None" @@ -1204,7 +1208,7 @@ proc/admin_notice(var/message, var/rights) H.regenerate_icons() -/proc/get_options_bar(whom, detail = 2, name = 0, link = 1, highlight_special = 1, var/datum/ticket/ticket = null) +/proc/get_options_bar(whom, detail = 2, name = 0, link = 1, highlight_special = 1, var/datum/ticket/ticket = null) if(!whom) return "(*null*)" var/mob/M @@ -1216,25 +1220,25 @@ proc/admin_notice(var/message, var/rights) M = whom C = M.client else - return "(*not a mob*)" + return "(*not a mob*)" switch(detail) if(0) - return "[key_name(C, link, name, highlight_special, ticket)]" + return "[key_name(C, link, name, highlight_special, ticket)]" if(1) //Private Messages - return "[key_name(C, link, name, highlight_special, ticket)](?)" + return "[key_name(C, link, name, highlight_special, ticket)](?)" if(2) //Admins var/ref_mob = "\ref[M]" - return "[key_name(C, link, name, highlight_special, ticket)](?) (PP) (VV) (SM) ([admin_jump_link(M, src)]) (CA)" + return "[key_name(C, link, name, highlight_special, ticket)](?) (PP) (VV) (SM) ([admin_jump_link(M, src)]) (CA)" - if(3) //Devs + if(3) //Devs var/ref_mob = "\ref[M]" - return "[key_name(C, link, name, highlight_special, ticket)](VV)([admin_jump_link(M, src)])" + return "[key_name(C, link, name, highlight_special, ticket)](VV)([admin_jump_link(M, src)])" if(4) //Mentors var/ref_mob = "\ref[M]" - return "[key_name(C, link, name, highlight_special, ticket)] (?) (PP) (VV) (SM) ([admin_jump_link(M, src)])" + return "[key_name(C, link, name, highlight_special, ticket)] (?) (PP) (VV) (SM) ([admin_jump_link(M, src)])" // //ALL DONE diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 3692b7c5ef3..883c1271239 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1312,7 +1312,8 @@ else if(href_list["ac_submit_new_channel"]) 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.admincaster_feed_channel.channel_name) check = 1 break @@ -1321,7 +1322,7 @@ else var/choice = alert("Please confirm Feed channel creation","Network Channel Handler","Confirm","Cancel") if(choice=="Confirm") - news_network.CreateFeedChannel(admincaster_feed_channel.channel_name, admincaster_signature, admincaster_feed_channel.locked, 1) + SSnews.CreateFeedChannel(admincaster_feed_channel.channel_name, admincaster_signature, admincaster_feed_channel.locked, 1) feedback_inc("newscaster_channels",1) //Adding channel to the global network log_admin("[key_name_admin(usr)] created command feed channel: [src.admincaster_feed_channel.channel_name]!",admin_key=key_name(usr)) src.admincaster_screen=5 @@ -1329,8 +1330,9 @@ else if(href_list["ac_set_channel_receiving"]) var/list/available_channels = list() - for(var/datum/feed_channel/F in news_network.network_channels) - available_channels += F.channel_name + for(var/channel in SSnews.network_channels) + var/datum/feed_channel/FC = SSnews.GetFeedChannel(channel) + available_channels += FC.channel_name src.admincaster_feed_channel.channel_name = sanitizeSafe(input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels ) src.access_news_network() @@ -1343,7 +1345,8 @@ src.admincaster_screen = 6 else feedback_inc("newscaster_stories",1) - news_network.SubmitArticle(src.admincaster_feed_message.body, src.admincaster_signature, src.admincaster_feed_channel.channel_name, null, 1) + var/datum/feed_channel/ch = SSnews.GetFeedChannel(src.admincaster_feed_channel.channel_name) + SSnews.SubmitArticle(src.admincaster_feed_message.body, src.admincaster_signature, ch, null, 1) src.admincaster_screen=4 log_admin("[key_name_admin(usr)] submitted a feed story to channel: [src.admincaster_feed_channel.channel_name]!",admin_key=key_name(usr)) @@ -1367,12 +1370,12 @@ else if(href_list["ac_menu_wanted"]) var/already_wanted = 0 - if(news_network.wanted_issue) + if(SSnews.wanted_issue) already_wanted = 1 if(already_wanted) - src.admincaster_feed_message.author = news_network.wanted_issue.author - src.admincaster_feed_message.body = news_network.wanted_issue.body + src.admincaster_feed_message.author = SSnews.wanted_issue.author + src.admincaster_feed_message.body = SSnews.wanted_issue.body src.admincaster_screen = 14 src.access_news_network() @@ -1397,15 +1400,15 @@ WANTED.body = src.admincaster_feed_message.body //Wanted desc WANTED.backup_author = src.admincaster_signature //Submitted by WANTED.is_admin_message = 1 - news_network.wanted_issue = WANTED + SSnews.wanted_issue = WANTED for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) NEWSCASTER.newsAlert() NEWSCASTER.update_icon() src.admincaster_screen = 15 else - news_network.wanted_issue.author = src.admincaster_feed_message.author - news_network.wanted_issue.body = src.admincaster_feed_message.body - news_network.wanted_issue.backup_author = src.admincaster_feed_message.backup_author + SSnews.wanted_issue.author = src.admincaster_feed_message.author + SSnews.wanted_issue.body = src.admincaster_feed_message.body + SSnews.wanted_issue.backup_author = src.admincaster_feed_message.backup_author src.admincaster_screen = 19 log_admin("[key_name_admin(usr)] issued a Station-wide Wanted Notification for [src.admincaster_feed_message.author]!",admin_key=key_name(usr)) src.access_news_network() @@ -1413,7 +1416,7 @@ else if(href_list["ac_cancel_wanted"]) 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.admincaster_screen=17 diff --git a/code/modules/ambient_occlusion/ao_turf.dm b/code/modules/ambient_occlusion/ao_turf.dm index 8c8047cb6e0..54bc1da744b 100644 --- a/code/modules/ambient_occlusion/ao_turf.dm +++ b/code/modules/ambient_occlusion/ao_turf.dm @@ -1,7 +1,9 @@ #ifdef AO_USE_LIGHTING_OPACITY #define AO_TURF_CHECK(T) (!T.has_opaque_atom || !T.permit_ao) +#define AO_SELF_CHECK(T) (!T.has_opaque_atom) #else #define AO_TURF_CHECK(T) (!T.density || !T.opacity || !T.permit_ao) +#define AO_SELF_CHECK(T) (!T.density && !T.opacity) #endif /turf @@ -29,7 +31,7 @@ var/turf/T if (flags & MIMIC_BELOW) CALCULATE_NEIGHBORS(src, ao_neighbors_mimic, T, (T.flags & MIMIC_BELOW)) - if (!has_opaque_atom && !(flags & MIMIC_NO_AO)) + if (AO_SELF_CHECK(src) && !(flags & MIMIC_NO_AO)) CALCULATE_NEIGHBORS(src, ao_neighbors, T, AO_TURF_CHECK(T)) /proc/make_ao_image(corner, i, px = 0, py = 0, pz = 0, pw = 0) @@ -41,6 +43,7 @@ I.alpha = WALL_AO_ALPHA I.blend_mode = BLEND_OVERLAY I.appearance_flags = RESET_ALPHA|RESET_COLOR|TILE_BOUND + I.layer = AO_LAYER // If there's an offset, counteract it. if (px || py || pz || pw) I.pixel_x = -px @@ -109,3 +112,5 @@ #undef REGEN_AO #undef PROCESS_AO_CORNER +#undef AO_TURF_CHECK +#undef AO_SELF_CHECK diff --git a/code/modules/cargo/randomstock.dm b/code/modules/cargo/randomstock.dm index 3faf7c7444d..5a1f7920163 100644 --- a/code/modules/cargo/randomstock.dm +++ b/code/modules/cargo/randomstock.dm @@ -58,6 +58,8 @@ var/global/stockname = "" */ var/list/global/random_stock_common = list( + "backpack" = 1, + "drawing" = 1, "toolbox" = 4, "meds" = 5, "steel" = 7, @@ -74,8 +76,6 @@ var/list/global/random_stock_common = list( "light" = 1.8, "aid" = 4, "flame" = 2, - "crayons" = 1.5, - "figure" = 1, "bombsupply" = 4.5, "tech" = 5, "smokes" = 2, @@ -85,13 +85,12 @@ var/list/global/random_stock_common = list( "circuitboard" = 2, "smalloxy" = 3.2, "belts" = 2, - "backpack" = 4.5, "weldgear" = 2, "inflatable" = 3, "wheelchair" = 1, "meson" = 1.5, "beartrap" = 2, - "trays" = 1.8, + "trays" = 0.8, "utensil" = 2, "metalfoam" = 1.5, "nanopaste" = 2, @@ -122,8 +121,7 @@ var/list/global/random_stock_common = list( "hailer" = 1.1, "target" = 2, "snacks" = 4, - "oxytank" = 2.5,// - "signs" = 4, + "oxytank" = 2.5, "posters" = 3, "parts" = 6, "cane" = 2, @@ -134,9 +132,11 @@ var/list/global/random_stock_common = list( "paicard" = 2, "phoronsheets" = 2, "hide" = 1, + "arcade" = 2, "nothing" = 0) var/list/global/random_stock_uncommon = list( + "beekit" = 1, "glowshrooms" = 2, "plasteel" = 3, "silver" = 2, @@ -152,19 +152,17 @@ var/list/global/random_stock_uncommon = list( "monkey" = 2, "specialcrayon" = 1.5, "contraband" = 2, - "figure" = 4, - "plushie" = 4, "mediumcell" = 3, "chempack" = 5, "robolimbs" = 3, "circuitboards" = 3, "jetpack" = 3, "xenocostume" = 1, - "bible" = 1, + "inhaler" = 1, "advwelder" = 2, "sord" = 1, "policebaton" = 1.5, - "stunbaton" = 0.75,//batons spawn with no powercell + "stunbaton" = 0.75, //batons spawn with no powercell "firingpin" = 3, "watches" = 3, "MMI" = 1.5, @@ -183,7 +181,6 @@ var/list/global/random_stock_uncommon = list( "fireaxe" = 1, "service" = 2, "robot" = 2, - "latexb" = 0.5, "taperoll" = 1, "headset" = 2, "bat" = 1.2, @@ -196,7 +193,6 @@ var/list/global/random_stock_uncommon = list( "exoquip" = 2, "laserscalpel" = 1.3, "electropack" = 1, - "beesmoker" = 1.5, "monkeyhide" = 0.5, "cathide" = 0.5, "corgihide" = 0.5, @@ -465,6 +461,11 @@ var/list/global/random_stock_large = list( /proc/spawn_stock(var/stock, var/atom/L, var/datum/cargospawner/CS = null) //L is the location we spawn in. Using a single letter as shorthand because its written so often switch(stock) + if("arcade") + new /obj/random/arcade(L) + new /obj/random/arcade(L) + new /obj/random/arcade(L) + if ("toolbox") if (prob(5)) new /obj/item/weapon/storage/toolbox/syndicate(L) @@ -562,8 +563,6 @@ var/list/global/random_stock_large = list( new /obj/item/weapon/flame/lighter/random(L) new /obj/item/weapon/storage/fancy/candle_box(L) new /obj/item/weapon/storage/fancy/candle_box(L) - if ("crayons") - new /obj/item/weapon/storage/fancy/crayons(L) if("bombsupply") new /obj/random/bomb_supply(L) @@ -640,9 +639,6 @@ var/list/global/random_stock_large = list( if("belts") new /obj/random/belt(L) new /obj/random/belt(L) - if("backpack") - new /obj/random/backpack(L) - new /obj/random/backpack(L) if("weldgear") if (prob(50)) new /obj/item/clothing/glasses/welding(L) @@ -708,6 +704,7 @@ var/list/global/random_stock_large = list( //A random scanning device, most are useless var/list/possible = list( /obj/item/device/healthanalyzer = 5, + /obj/item/device/breath_analyzer = 1, /obj/item/device/analyzer = 0.5, /obj/item/device/mass_spectrometer = 0.5, /obj/item/device/mass_spectrometer/adv = 0.5, @@ -976,13 +973,11 @@ var/list/global/random_stock_large = list( new type(L) if ("cleanernades") - new /obj/item/weapon/grenade/chem_grenade/cleaner(L) - new /obj/item/weapon/grenade/chem_grenade/cleaner(L) - if (prob(50)) + if(prob(90)) new /obj/item/weapon/grenade/chem_grenade/cleaner(L) new /obj/item/weapon/grenade/chem_grenade/cleaner(L) - - + else + new /obj/item/weapon/grenade/chem_grenade/large/phoroncleaner(L) if ("mining") if (prob(50)) @@ -1007,12 +1002,35 @@ var/list/global/random_stock_large = list( if ("hide") new /obj/item/stack/material/animalhide(L, rand(5,50)) + if("drawing") + var/list/drawing = list( + /obj/item/weapon/pen/crayon/rainbow = 2, + /obj/item/weapon/pen/crayon/mime = 2, + /obj/item/weapon/storage/fancy/crayons = 4, + /obj/item/weapon/pen/chameleon = 1, + /obj/item/weapon/pen/invisible = 2, + /obj/item/weapon/pen/multi = 2 + ) + var/type = pickweight(drawing) + new type(L) + + if("backpack") + var/obj/item/weapon/storage/pack = new /obj/random/backpack(src) + if(istype(pack) && prob(75)) + new /obj/random/loot(pack) + new /obj/random/loot(pack) + new /obj/random/loot(pack) + //Uncommon items below here //============================================================= //============================================================= //============================================================= - if ("glowshrooms") + if("beekit") + new /obj/item/bee_pack(src) + new /obj/item/weapon/bee_net(src) + new /obj/item/weapon/bee_smoker(src) + if("glowshrooms") new /obj/item/seeds/glowshroom(L) new /obj/item/seeds/glowshroom(L) new /obj/item/seeds/glowshroom(L) @@ -1059,12 +1077,6 @@ var/list/global/random_stock_large = list( while (number > 0) new /obj/random/contraband(L) number-- - if("figure") - new /obj/random/action_figure(L) - new /obj/random/action_figure(L) - new /obj/random/action_figure(L) - if("plushie") - new /obj/random/plushie(L) if("firingpin") new /obj/item/weapon/storage/box/firingpins(L) if("mediumcell") @@ -1130,11 +1142,6 @@ var/list/global/random_stock_large = list( if ("xenocostume") new /obj/item/clothing/suit/xenos(L) new /obj/item/clothing/head/xenos(L) - if ("bible") - if (prob(25)) - new /obj/item/weapon/storage/bible/booze(L) - else - new /obj/item/weapon/storage/bible(L) if ("advwelder") new /obj/item/weapon/weldingtool/hugetank(L) @@ -1157,22 +1164,6 @@ var/list/global/random_stock_large = list( if ("voidsuit") new /obj/random/voidsuit(L,1) - if ("signs") - var/list/allsigns = subtypesof(/obj/structure/sign) - allsigns -= typesof(/obj/structure/sign/double) - allsigns -= typesof(/obj/structure/sign/poster) - allsigns -= /obj/structure/sign/directions - allsigns -= typesof(/obj/structure/sign/christmas) - allsigns -= typesof(/obj/structure/sign/flag) - - var/number = rand(1,5) - - while (number > 0) - var/newsign = pick(allsigns) - if (newsign != /obj/structure/sign)//Dont want to spawn the generic parent class - var/obj/structure/sign/S = new newsign(L) - S.unfasten() - number-- if ("posters") new /obj/item/weapon/contraband/poster(L) if (prob(50)) @@ -1244,8 +1235,6 @@ var/list/global/random_stock_large = list( newbot.on = 0//Deactivated if (prob(10)) newbot.emag_act(9999,null) - if ("latexb") - new /obj/item/latexballon(L) //Random headsets for low-security department //No command or sec @@ -1372,9 +1361,6 @@ var/list/global/random_stock_large = list( cr.rigged = 1//Boobytrapped crate, will electrocute when you attempt to open it //Can be disarmed with wirecutters or ignored with insulated gloves - if ("beesmoker") - new /obj/item/weapon/bee_smoker(L) - if("monkeyhide") new /obj/item/stack/material/animalhide/monkey(L, 50) @@ -1390,7 +1376,6 @@ var/list/global/random_stock_large = list( if ("wintercoat") new /obj/random/hoodie(L) - if("cookingoil") var/turf/T = get_turf(L) if (!turf_clear(T)) @@ -1539,6 +1524,35 @@ var/list/global/random_stock_large = list( if ("contraband") new /obj/random/contraband(L) + if ("inhaler") + if(prob(33)) + if(prob(10)) + new/obj/item/weapon/storage/box/inhalers_large(src) + else + new /obj/item/weapon/storage/box/inhalers(src) + else + var/number = rand(2,3) + var/list/inhalers = list( + /obj/item/weapon/reagent_containers/inhaler/dexalin = 8, + /obj/item/weapon/reagent_containers/inhaler/hyperzine = 2, + /obj/item/weapon/reagent_containers/inhaler/phoron = 2, + /obj/item/weapon/reagent_containers/inhaler/soporific = 1, + /obj/item/weapon/reagent_containers/inhaler/space_drugs = 3 + ) + while(number > 0) + var/type = pickweight(inhalers) + var/obj/item/weapon/reagent_containers/inhaler/spawned = new type(L) + if(prob(10) || istype(spawned,/obj/item/weapon/reagent_containers/inhaler/space_drugs)) + spawned.name = "unlabeled inhaler" + spawned.desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one is unlabeled." + number -= 1 + + if(prob(33)) + new /obj/item/device/breath_analyzer(L) + + + + //Large items go below here //============================================================= //============================================================= diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories.dm b/code/modules/client/preference_setup/loadout/loadout_accessories.dm index 840d91e7b92..92001e13e7c 100644 --- a/code/modules/client/preference_setup/loadout/loadout_accessories.dm +++ b/code/modules/client/preference_setup/loadout/loadout_accessories.dm @@ -51,6 +51,15 @@ ties["blue tie"] = /obj/item/clothing/accessory/blue ties["red tie"] = /obj/item/clothing/accessory/red ties["horrible tie"] = /obj/item/clothing/accessory/horrible + ties["blue tie with a clip"] = /obj/item/clothing/accessory/tie/blue_clip + ties["blue long tie"] = /obj/item/clothing/accessory/tie/blue_long + ties["red tie with a clip"] = /obj/item/clothing/accessory/tie/red_clip + ties["red long tie"] = /obj/item/clothing/accessory/tie/red_long + ties["black tie"] = /obj/item/clothing/accessory/tie/black + ties["dark green tie"] = /obj/item/clothing/accessory/tie/darkgreen + ties["yellow tie"] = /obj/item/clothing/accessory/tie/yellow + ties["navy tie"] = /obj/item/clothing/accessory/tie/navy + ties["white tie"] = /obj/item/clothing/accessory/tie/white gear_tweaks += new/datum/gear_tweak/path(ties) /datum/gear/accessory/brown_vest @@ -97,6 +106,18 @@ display_name = "silver locket" path = /obj/item/clothing/accessory/locket +/datum/gear/accessory/locket + display_name = "silver locket" + path = /obj/item/clothing/accessory/locket + +/datum/gear/accessory/sweater + display_name = "sweater" + path = /obj/item/clothing/accessory/sweater + +/datum/gear/accessory/sweater/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) + /datum/gear/accessory/scarf display_name = "scarf selection" path = /obj/item/clothing/accessory/scarf diff --git a/code/modules/client/preference_setup/loadout/loadout_eyes.dm b/code/modules/client/preference_setup/loadout/loadout_eyes.dm index ae64bc0f7a0..1d8443707b3 100644 --- a/code/modules/client/preference_setup/loadout/loadout_eyes.dm +++ b/code/modules/client/preference_setup/loadout/loadout_eyes.dm @@ -94,4 +94,8 @@ display_name = "HUDpatch, Welding" path = /obj/item/clothing/glasses/eyepatch/hud/welder allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Engineering Apprentice","Research Director","Roboticist") - cost = 2 \ No newline at end of file + cost = 2 + +/datum/gear/eyes/spiffygogs + display_name = "Orange Goggles" + path = /obj/item/clothing/glasses/spiffygogs diff --git a/code/modules/client/preference_setup/loadout/loadout_general.dm b/code/modules/client/preference_setup/loadout/loadout_general.dm index 81b42ab4c84..ca5c76e1b99 100644 --- a/code/modules/client/preference_setup/loadout/loadout_general.dm +++ b/code/modules/client/preference_setup/loadout/loadout_general.dm @@ -36,7 +36,7 @@ /datum/gear/flask/New() ..() - gear_tweaks += new/datum/gear_tweak/reagents(lunchables_ethanol_reagents()) + gear_tweaks += new/datum/gear_tweak/reagents(lunchables_alcohol_reagents()) /datum/gear/vacflask display_name = "vacuum-flask" diff --git a/code/modules/client/preference_setup/loadout/loadout_head.dm b/code/modules/client/preference_setup/loadout/loadout_head.dm index a00f445fb29..0dfbc181ab8 100644 --- a/code/modules/client/preference_setup/loadout/loadout_head.dm +++ b/code/modules/client/preference_setup/loadout/loadout_head.dm @@ -173,3 +173,11 @@ surgical["surgical cap, green"] = /obj/item/clothing/head/surgery/green surgical["surgical cap, black"] = /obj/item/clothing/head/surgery/black gear_tweaks += new/datum/gear_tweak/path(surgical) + +/datum/gear/head/headbando + display_name = "Basic Headband" + path = /obj/item/clothing/head/headbando + +/datum/gear/head/headbando/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_shoes.dm b/code/modules/client/preference_setup/loadout/loadout_shoes.dm index 71ea8011ef3..f5af4e4bb84 100644 --- a/code/modules/client/preference_setup/loadout/loadout_shoes.dm +++ b/code/modules/client/preference_setup/loadout/loadout_shoes.dm @@ -54,4 +54,32 @@ shoes["dress flats, blue"] = /obj/item/clothing/shoes/flats/blue shoes["dress flats, green"] = /obj/item/clothing/shoes/flats/green shoes["dress flats, purple"] = /obj/item/clothing/shoes/flats/purple - gear_tweaks += new/datum/gear_tweak/path(shoes) \ No newline at end of file + gear_tweaks += new/datum/gear_tweak/path(shoes) + +/datum/gear/shoes/cowboy + display_name = "cowboy boots selection" + path = /obj/item/clothing/shoes/cowboy + +/datum/gear/shoes/cowboy/New() + ..() + var/shoes = list() + shoes["cowboy boots"] = /obj/item/clothing/shoes/cowboy + shoes["classic cowboy boots"] = /obj/item/clothing/shoes/cowboy/classic + shoes["snakeskin cowboy boots"] = /obj/item/clothing/shoes/cowboy/snakeskin + gear_tweaks += new/datum/gear_tweak/path(shoes) + +/datum/gear/shoes/heels + display_name = "high heels" + path = /obj/item/clothing/shoes/heels + +/datum/gear/shoes/heels/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) + +/datum/gear/shoes/tongs + display_name = "flip flops" + path = /obj/item/clothing/shoes/sandal/flipflop + +/datum/gear/shoes/tongs/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_suit.dm b/code/modules/client/preference_setup/loadout/loadout_suit.dm index 50e9800a4ac..883e46cd5f7 100644 --- a/code/modules/client/preference_setup/loadout/loadout_suit.dm +++ b/code/modules/client/preference_setup/loadout/loadout_suit.dm @@ -25,6 +25,10 @@ jackets["flannel jacket, grey"] = /obj/item/clothing/suit/storage/toggle/flannel/gray jackets["flannel jacket, purple"] = /obj/item/clothing/suit/storage/toggle/flannel/purple jackets["flannel jacket, yellow"] = /obj/item/clothing/suit/storage/toggle/flannel/yellow + jackets["black vest"] = /obj/item/clothing/suit/storage/toggle/leather_vest + jackets["brown vest"] = /obj/item/clothing/suit/storage/toggle/brown_jacket/sleeveless + jackets["leather coat"] = /obj/item/clothing/suit/leathercoat + gear_tweaks += new/datum/gear_tweak/path(jackets) /datum/gear/suit/hazard_vest @@ -172,4 +176,18 @@ /datum/gear/suit/secjackethos display_name = "navy security jacket (Head of Security)" path = /obj/item/clothing/suit/security/navyhos - allowed_roles = list("Head of Security") \ No newline at end of file + allowed_roles = list("Head of Security") + +/datum/gear/suit/dominia + display_name = "dominia great coat selection" + path = /obj/item/clothing/suit/storage/toggle/dominia + +/datum/gear/suit/dominia/New() + ..() + var/coat = list() + coat["dominia great coat"] = /obj/item/clothing/suit/storage/toggle/dominia + coat["dominia great coat, alternative"] = /obj/item/clothing/suit/storage/toggle/dominia/alt + coat["dominia cape"] = /obj/item/clothing/suit/storage/dominia + coat["dominia great coat, black"] = /obj/item/clothing/suit/storage/toggle/dominia/black + coat["dominia great coat, alternative black"] = /obj/item/clothing/suit/storage/toggle/dominia/black/alt + gear_tweaks += new/datum/gear_tweak/path(coat) \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform.dm b/code/modules/client/preference_setup/loadout/loadout_uniform.dm index a401a8ec5e3..d903500f7cb 100644 --- a/code/modules/client/preference_setup/loadout/loadout_uniform.dm +++ b/code/modules/client/preference_setup/loadout/loadout_uniform.dm @@ -40,16 +40,23 @@ /datum/gear/uniform/skirt display_name = "skirt selection" - path = /obj/item/clothing/under/dress/plaid_blue + path = /obj/item/clothing/under/skirt/ /datum/gear/uniform/skirt/New() ..() var/skirts = list() - skirts["plaid skirt, blue"] = /obj/item/clothing/under/dress/plaid_blue - skirts["plaid skirt, purple"] = /obj/item/clothing/under/dress/plaid_purple - skirts["plaid skirt, red"] = /obj/item/clothing/under/dress/plaid_red - skirts["jumpskirt, black"] = /obj/item/clothing/under/blackjumpskirt - skirts["skirt, black"] = /obj/item/clothing/under/blackskirt + skirts["plaid skirt, blue"] = /obj/item/clothing/under/skirt/plaid_blue + skirts["plaid skirt, purple"] = /obj/item/clothing/under/skirt/plaid_purple + skirts["plaid skirt, red"] = /obj/item/clothing/under/skirt/plaid_red + skirts["jumpskirt, black"] = /obj/item/clothing/under/skirt/blackjumpskirt + skirts["skirt, black"] = /obj/item/clothing/under/skirt/ + skirts["skirt, khaki"] = /obj/item/clothing/under/skirt/khaki + skirts["short skirt, black"] = /obj/item/clothing/under/skirt/short_black + skirts["short skirt, blue"] = /obj/item/clothing/under/skirt/blue + skirts["short skirt, red"] = /obj/item/clothing/under/skirt/red + skirts["skirt, swept"] = /obj/item/clothing/under/skirt/swept + + gear_tweaks += new/datum/gear_tweak/path(skirts) /datum/gear/uniform/suit @@ -168,17 +175,39 @@ pants["khaki pants"] = /obj/item/clothing/under/pants/khaki pants["track pants"] = /obj/item/clothing/under/pants/track pants["camo pants"] = /obj/item/clothing/under/pants/camo + pants["athletic shorts, black"] = /obj/item/clothing/under/shorts + pants["athletic shorts, red"] = /obj/item/clothing/under/shorts/red + pants["athletic shorts, green"] = /obj/item/clothing/under/shorts/green + pants["athletic shorts, black"] = /obj/item/clothing/under/shorts/black + pants["athletic shorts, grey"] = /obj/item/clothing/under/shorts/grey + pants["jean shorts"] = /obj/item/clothing/under/shorts/jeans + pants["jean short shorts"] = /obj/item/clothing/under/shorts/jeans/female + pants["classic jeans shorts"] = /obj/item/clothing/under/shorts/jeans/classic + pants["classic jeans shorts shorts"] = /obj/item/clothing/under/shorts/jeans/classic/female + pants["mustang jeans shorts"] = /obj/item/clothing/under/shorts/jeans/mustang + pants["mustang jeans shorts shorts"] = /obj/item/clothing/under/shorts/jeans/mustang/female + pants["young folks jeans shorts"] = /obj/item/clothing/under/shorts/jeans/youngfolks + pants["young folks jeans shorts shorts"] = /obj/item/clothing/under/shorts/jeans/youngfolks/female + pants["black jeans shorts"] = /obj/item/clothing/under/shorts/jeans/black + pants["black jeans shorts shorts"] = /obj/item/clothing/under/shorts/jeans/black/female + pants["grey jeans shorts"] = /obj/item/clothing/under/shorts/jeans/grey + pants["grey jeans shorts shorts"] = /obj/item/clothing/under/shorts/jeans + pants["khaki shorts"] = /obj/item/clothing/under/shorts/khaki + pants["khaki shorts shorts"] = /obj/item/clothing/under/shorts/khaki/female gear_tweaks += new/datum/gear_tweak/path(pants) /datum/gear/uniform/turtleneck display_name = "tacticool turtleneck" path = /obj/item/clothing/under/syndicate/tacticool +/datum/gear/uniform/dominia + display_name = "dominia suit selection" + path = /obj/item/clothing/under/dominia -/datum/gear/uniform/sweater - display_name = "sweater" - path = /obj/item/clothing/under/sweater - -/datum/gear/uniform/sweater/New() +/datum/gear/uniform/dominia/New() ..() - gear_tweaks = list(gear_tweak_free_color_choice) \ No newline at end of file + var/suit = list() + suit["dominia suit"] = /obj/item/clothing/under/dominia + suit["dominia suit, black"] = /obj/item/clothing/under/dominia/black + suit["lyodsuit"] = /obj/item/clothing/under/dom_thermal + gear_tweaks += new/datum/gear_tweak/path(suit) \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_xeno.dm b/code/modules/client/preference_setup/loadout/loadout_xeno.dm index 1d023de6eb0..14abd0e64f5 100644 --- a/code/modules/client/preference_setup/loadout/loadout_xeno.dm +++ b/code/modules/client/preference_setup/loadout/loadout_xeno.dm @@ -140,11 +140,19 @@ gear_tweaks += new/datum/gear_tweak/path(taj_gloves) /datum/gear/suit/tajara_coat - display_name = "tajaran naval coat (Tajara)" + display_name = "tajara coat selection (Tajara)" path = /obj/item/clothing/suit/storage/tajaran whitelisted = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") sort_category = "Xenowear" +/datum/gear/suit/tajara_coat/New() + ..() + var/coat = list() + coat["tajaran naval coat"] = /obj/item/clothing/suit/storage/tajaran + coat["commoner cloak"] = /obj/item/clothing/suit/storage/tajaran/cloak + coat["royal cloak"] = /obj/item/clothing/suit/storage/tajaran/cloak/fancy + gear_tweaks += new/datum/gear_tweak/path(coat) + /datum/gear/suit/tajaran_labcoat display_name = "PRA medical coat (Tajara)" path = /obj/item/clothing/suit/storage/toggle/labcoat/tajaran @@ -152,6 +160,70 @@ allowed_roles = list("Chief Medical Officer", "Medical Doctor", "Chemist", "Geneticist", "Paramedic", "Medical Resident") sort_category = "Xenowear" +/datum/gear/uniform/tajara + display_name = "tajaran uniform selection (Tajara)" + path = /obj/item/clothing/under/tajaran + whitelisted = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") + sort_category = "Xenowear" + +/datum/gear/uniform/tajara/New() + ..() + var/uniform = list() + uniform["laborers clothes"] = /obj/item/clothing/under/tajaran + uniform["fancy uniform"] = /obj/item/clothing/under/tajaran/fancy + uniform["NanoTrasen overalls"] = /obj/item/clothing/under/tajaran/nt + gear_tweaks += new/datum/gear_tweak/path(uniform) + +/datum/gear/uniform/tajara_dress + display_name = "tajaran dress selection (Tajara)" + path = /obj/item/clothing/under/dress/tajaran + whitelisted = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") + sort_category = "Xenowear" + +/datum/gear/uniform/tajara_dress/New() + ..() + var/dress = list() + dress["white fancy adhomian dress"] = /obj/item/clothing/under/dress/tajaran + dress["blue fancy adhomian dress"] = /obj/item/clothing/under/dress/tajaran/blue + dress["green fancy adhomian dress"] = /obj/item/clothing/under/dress/tajaran/green + dress["red fancy adhomian dress"] = /obj/item/clothing/under/dress/tajaran/red + dress["red noble adhomian dress"] = /obj/item/clothing/under/dress/tajaran/fancy + dress["black noble adhomian dress"] = /obj/item/clothing/under/dress/tajaran/fancy/black + gear_tweaks += new/datum/gear_tweak/path(dress) + +/datum/gear/accessory/tajara + display_name = "fur scarf (Tajara)" + path = /obj/item/clothing/accessory/tajaran + whitelisted = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") + sort_category = "Xenowear" + +/datum/gear/accessory/tajara/New() + ..() + var/scarf = list() + scarf["brown fur scarf"] = /obj/item/clothing/accessory/tajaran + scarf["light brown fur scarf"] = /obj/item/clothing/accessory/tajaran/lbrown + scarf["cinnamon fur scarf"] = /obj/item/clothing/accessory/tajaran/cinnamon + scarf["blue fur scarf"] = /obj/item/clothing/accessory/tajaran/blue + scarf["silver fur scarf"] = /obj/item/clothing/accessory/tajaran/silver + scarf["black fur scarf"] = /obj/item/clothing/accessory/tajaran/black + scarf["ruddy fur scarf"] = /obj/item/clothing/accessory/tajaran/ruddy + scarf["orange fur scarf"] = /obj/item/clothing/accessory/tajaran/orange + scarf["cream fur scarf"] = /obj/item/clothing/accessory/tajaran/cream + gear_tweaks += new/datum/gear_tweak/path(scarf) + +/datum/gear/head/tajara + display_name = "dress circlet selection (Tajara)" + path = /obj/item/clothing/head/tajaran/circlet + whitelisted = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") + sort_category = "Xenowear" + +/datum/gear/head/tajara/New() + ..() + var/circlet = list() + circlet["golden dress circlet"] = /obj/item/clothing/head/tajaran/circlet + circlet["silver dress circlet"] = /obj/item/clothing/head/tajaran/circlet/silver + gear_tweaks += new/datum/gear_tweak/path(circlet) + //other things /datum/gear/uniform/gearharness diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 9da255e32bb..8c210e649ce 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -597,6 +597,7 @@ if(usr.put_in_hands(holding)) usr.visible_message("\The [usr] pulls \a [holding] out of their boot!") holding = null + playsound(get_turf(src), 'sound/items/holster/sheathout.ogg', 25) else usr << "Your need an empty, unbroken hand to do that." holding.forceMove(src) diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 236a5f27b51..751b99dd0dc 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -505,3 +505,41 @@ BLIND // can't see anything ..() overlay = global_hud.nvg +//from verkister +/obj/item/clothing/glasses/spiffygogs + name = "Orange Goggles" + desc = "You can almost feel the raw power radiating off these strange specs." + icon_state = "spiffygogs" + item_state = "spiffygogs" + action_button_name = "Adjust Goggles" + var/up = 0 + item_flags = AIRTIGHT + +/obj/item/clothing/glasses/spiffygogs/attack_self() + toggle() + + +/obj/item/clothing/glasses/spiffygogs/verb/toggle() + set category = "Object" + set name = "Adjust Goggles" + set src in usr + + if(usr.canmove && !usr.stat && !usr.restrained()) + if(src.up) + src.up = !src.up + flags_inv |= HIDEEYES + body_parts_covered |= EYES + icon_state = initial(icon_state) + item_state = initial(item_state) + item_flags |= AIRTIGHT + usr << "You flip \the [src] down over your eyes." + else + src.up = !src.up + flags_inv &= ~HIDEEYES + body_parts_covered &= ~EYES + icon_state = "[initial(icon_state)]up" + item_state = "[initial(item_state)]up" + item_flags &= ~AIRTIGHT + usr << "You push \the [src] up off your eyes." + update_clothing_icon() + usr.update_action_buttons() diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 8c340616ce7..9bb3bb0aafa 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -361,3 +361,10 @@ /obj/item/clothing/head/turban/yellow icon_state = "turban_yellow" item_state = "turban_yellow" + +//praise verkister +/obj/item/clothing/head/headbando + name = "basic headband" + desc = "Perfect for martial artists, sweaty rogue operators, and tunnel gangsters." + icon_state = "headbando" + item_state = "headbando" \ No newline at end of file diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 9688918f302..94f21e508cc 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -42,6 +42,7 @@ set_slowdown() force = 5 if(icon_base) icon_state = "[icon_base]1" + playsound(get_turf(src), 'sound/effects/magnetclamp.ogg', 20) user << "You enable the mag-pulse traction system." user.update_inv_shoes() //so our mob-overlays update user.update_action_buttons() diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 29b7250fcfd..e43946bd4e2 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -54,6 +54,11 @@ icon_state = "black" body_parts_covered = FEET +/obj/item/clothing/shoes/sandal/flipflop + name = "flip flops" + desc = "A pair of foam flip flops. For those not afraid to show a little ankle." + icon_state = "thongsandal" + /obj/item/clothing/shoes/clown_shoes desc = "The prankster's standard-issue clowning shoes. Damn they're huge!" name = "clown shoes" @@ -140,4 +145,24 @@ cold_protection = FEET|LEGS min_cold_protection_temperature = SHOE_MIN_COLD_PROTECTION_TEMPERATURE heat_protection = FEET|LEGS - max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE \ No newline at end of file + max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE + +/obj/item/clothing/shoes/cowboy + name = "cowboy boots" + desc = "Lacking a durasteel horse to ride." + icon_state = "cowboy" + +/obj/item/clothing/shoes/cowboy/classic + name = "classic cowboy boots" + desc = "A classic looking pair of durable cowboy boots." + icon_state = "cowboy_classic" + +/obj/item/clothing/shoes/cowboy/snakeskin + name = "snakeskin cowboy boots" + desc = "A pair of cowboy boots made from python skin." + icon_state = "cowboy_snakeskin" + +/obj/item/clothing/shoes/heels + name = "high heels" + desc = "A pair of high-heeled shoes. Fancy!" + icon_state = "heels" \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/rig/suits/station.dm b/code/modules/clothing/spacesuits/rig/suits/station.dm index 8cc433dad9c..d27d6182d72 100644 --- a/code/modules/clothing/spacesuits/rig/suits/station.dm +++ b/code/modules/clothing/spacesuits/rig/suits/station.dm @@ -170,7 +170,7 @@ helm_type = /obj/item/clothing/head/helmet/space/rig/hazmat - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/stack/flag,/obj/item/weapon/storage/box/excavation,/obj/item/weapon/pickaxe,/obj/item/device/healthanalyzer,/obj/item/device/measuring_tape,/obj/item/device/ano_scanner,/obj/item/device/depth_scanner,/obj/item/device/core_sampler,/obj/item/device/gps,/obj/item/device/beacon_locator,/obj/item/device/radio/beacon,/obj/item/weapon/pickaxe/hand,/obj/item/weapon/storage/bag/fossils) + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/stack/flag,/obj/item/weapon/storage/box/excavation,/obj/item/weapon/pickaxe,/obj/item/device/healthanalyzer,/obj/item/device/measuring_tape,/obj/item/device/ano_scanner,/obj/item/device/depth_scanner,/obj/item/device/core_sampler,/obj/item/device/gps,/obj/item/device/beacon_locator,/obj/item/device/radio/beacon,/obj/item/weapon/pickaxe/hand,/obj/item/weapon/storage/bag/fossils, /obj/item/device/breath_analyzer) req_access = list() req_one_access = list() @@ -197,7 +197,7 @@ helm_type = /obj/item/clothing/head/helmet/space/rig/medical - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical,/obj/item/roller ) + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical,/obj/item/roller, /obj/item/device/breath_analyzer ) req_access = list() req_one_access = list() diff --git a/code/modules/clothing/spacesuits/void/station.dm b/code/modules/clothing/spacesuits/void/station.dm index 4813055a981..7d54b6469da 100644 --- a/code/modules/clothing/spacesuits/void/station.dm +++ b/code/modules/clothing/spacesuits/void/station.dm @@ -68,7 +68,7 @@ slot_l_hand_str = "medical_hardsuit", slot_r_hand_str = "medical_hardsuit" ) - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical) + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical, /obj/item/device/breath_analyzer ) armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 50) //Security diff --git a/code/modules/clothing/suits/alien.dm b/code/modules/clothing/suits/alien.dm index 4c3d2bb64a4..b0436ec85b9 100644 --- a/code/modules/clothing/suits/alien.dm +++ b/code/modules/clothing/suits/alien.dm @@ -52,6 +52,45 @@ icon_open = "taj_jacket_open" icon_closed = "taj_jacket" +/obj/item/clothing/suit/storage/tajaran/cloak + name = "commoner cloak" + desc = "A tajaran cloak made with the middle class in mind, fancy but nothing special." + icon = 'icons/obj/tajara_items.dmi' + icon_state = "taj_commoncloak" + item_state = "taj_commoncloak" + contained_sprite = TRUE + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + +/obj/item/clothing/suit/storage/tajaran/cloak/fancy + name = "royal cloak" + desc = "A cloak fashioned from the best materials, meant for tajara of high standing." + icon_state = "taj_fancycloak" + item_state = "taj_fancycloak" + +/obj/item/clothing/suit/storage/hooded/tajaran + name = "gruff cloak" + desc = "A cloak designated for the lowest classes." + icon = 'icons/obj/tajara_items.dmi' + icon_state = "taj_cloak" + item_state = "taj_cloak" + contained_sprite = TRUE + hoodtype = /obj/item/clothing/head/winterhood + +/obj/item/clothing/head/tajaran/circlet + name = "golden dress circlet" + desc = "A golden circlet with a pearl in the middle of it." + icon = 'icons/obj/tajara_items.dmi' + icon_state = "taj_circlet" + item_state = "taj_circlet" + contained_sprite = TRUE + body_parts_covered = 0 + +/obj/item/clothing/head/tajaran/circlet/silver + name = "silver dress circlet" + desc = "A silver circlet with a pearl in the middle of it." + icon_state = "taj_circlet_s" + item_state = "taj_circlet_s" + //Vaurca clothing /obj/item/clothing/suit/vaurca diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 4a86ed8c5fc..50de5cf8365 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -25,7 +25,7 @@ icon_state = "surgeon" item_state = "surgeon" allowed = list(/obj/item/stack/medical, /obj/item/weapon/reagent_containers/dropper, /obj/item/weapon/reagent_containers/hypospray, /obj/item/weapon/reagent_containers/syringe, \ - /obj/item/device/healthanalyzer, /obj/item/device/flashlight, /obj/item/device/radio, /obj/item/weapon/tank/emergency_oxygen) + /obj/item/device/healthanalyzer, /obj/item/device/flashlight, /obj/item/device/radio, /obj/item/weapon/tank/emergency_oxygen, /obj/item/device/breath_analyzer) //Captain /obj/item/clothing/suit/captunic @@ -247,7 +247,7 @@ icon_closed = "fr_jacket" blood_overlay_type = "armor" allowed = list(/obj/item/stack/medical, /obj/item/weapon/reagent_containers/dropper, /obj/item/weapon/reagent_containers/hypospray, /obj/item/weapon/reagent_containers/syringe, \ - /obj/item/device/healthanalyzer, /obj/item/device/flashlight, /obj/item/device/radio, /obj/item/weapon/tank/emergency_oxygen) + /obj/item/device/healthanalyzer, /obj/item/device/flashlight, /obj/item/device/radio, /obj/item/weapon/tank/emergency_oxygen, /obj/item/device/breath_analyzer) body_parts_covered = UPPER_TORSO|ARMS /obj/item/clothing/suit/storage/toggle/fr_jacket/ems diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index d8769c4238c..ccbed75e15e 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -7,7 +7,7 @@ icon_closed = "labcoat" blood_overlay_type = "coat" body_parts_covered = UPPER_TORSO|ARMS - allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper) + allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper, /obj/item/device/breath_analyzer) armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0) /obj/item/clothing/suit/storage/toggle/labcoat/red diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 1fe74e5c85e..dc9cc99bb81 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -195,8 +195,11 @@ /obj/item/clothing/suit/leathercoat name = "leather coat" desc = "A long, thick black leather coat." - icon_state = "leathercoat" - item_state = "leathercoat" + icon_state = "leathercoat_alt" + item_state = "leathercoat_alt" + body_parts_covered = UPPER_TORSO|ARMS + min_cold_protection_temperature = T0C - 20 + siemens_coefficient = 0.7 /obj/item/clothing/suit/browncoat name = "brown leather coat" @@ -272,6 +275,15 @@ desc = "A black leather coat. A corporate logo is proudly displayed on the back." icon_state = "leather_jacket_nt" +/obj/item/clothing/suit/storage/toggle/leather_vest + name = "leather vest" + desc = "A black leather vest." + icon_state = "leather_jacket_sleeveless" + item_state = "leather_jacket_sleeveless" + icon_open = "leather_jacket_sleeveless_open" + icon_closed = "leather_jacket_sleeveless" + body_parts_covered = UPPER_TORSO + //This one has buttons for some reason /obj/item/clothing/suit/storage/toggle/brown_jacket name = "leather jacket" @@ -282,6 +294,15 @@ icon_closed = "brown_jacket" body_parts_covered = UPPER_TORSO|ARMS +/obj/item/clothing/suit/storage/toggle/brown_jacket/sleeveless + name = "brown vest" + desc = "A brown leather vest." + icon_state = "brown_jacket_sleeveless" + item_state = "brown_jacket_sleeveless" + icon_open = "brown_jacket_sleeveless_open" + icon_closed = "brown_jacket_sleeveless" + body_parts_covered = UPPER_TORSO + /obj/item/clothing/suit/storage/toggle/brown_jacket/nanotrasen desc = "A brown leather coat. A corporate logo is proudly displayed on the back." icon_state = "brown_jacket_nt" @@ -376,4 +397,36 @@ item_state = "trench2" icon_open = "trench2_open" icon_closed = "trench2" - blood_overlay_type = "coat" \ No newline at end of file + blood_overlay_type = "coat" + +/obj/item/clothing/suit/storage/dominia + name = "dominia cape" + desc = "This is a cape in the style of Dominia nobility. It's the latest fashion across Dominian space." + icon_state = "dominian_cape" + item_state = "dominian_cape" + +/obj/item/clothing/suit/storage/toggle/dominia + name = "dominia great coat" + desc = "This is a great coat in the style of Dominia nobility. It's the latest fashion across Dominian space." + icon_state = "dominian_noble" + item_state = "dominian_noble" + icon_open = "dominian_noble_open" + icon_closed = "dominian_noble" + +/obj/item/clothing/suit/storage/toggle/dominia/alt + icon_state = "dominian_noble2" + item_state = "dominian_noble2" + icon_open = "dominian_noble2_open" + icon_closed = "dominian_noble2" + +/obj/item/clothing/suit/storage/toggle/dominia/black + icon_state = "dominian_noble4" + item_state = "dominian_noble4" + icon_open = "dominian_noble4_open" + icon_closed = "dominian_noble4" + +/obj/item/clothing/suit/storage/toggle/dominia/black/alt + icon_state = "dominian_noble5" + item_state = "dominian_noble5" + icon_open = "dominian_noble5_open" + icon_closed = "dominian_noble5" \ No newline at end of file diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index 74f8a8c7b2e..4b2dc148de8 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -91,6 +91,42 @@ desc = "A neosilk clip-on tie. This one is disgusting." icon_state = "horribletie" +/obj/item/clothing/accessory/tie/blue_clip + name = "blue tie with a clip" + icon_state = "bluecliptie" + +/obj/item/clothing/accessory/tie/blue_long + name = "blue long tie" + icon_state = "bluelongtie" + +/obj/item/clothing/accessory/tie/red_clip + name = "red tie with a clip" + icon_state = "redcliptie" + +/obj/item/clothing/accessory/tie/red_long + name = "red long tie" + icon_state = "redlongtie" + +/obj/item/clothing/accessory/tie/black + name = "black tie" + icon_state = "blacktie" + +/obj/item/clothing/accessory/tie/darkgreen + name = "dark green tie" + icon_state = "dgreentie" + +/obj/item/clothing/accessory/tie/yellow + name = "yellow tie" + icon_state = "yellowtie" + +/obj/item/clothing/accessory/tie/navy + name = "navy tie" + icon_state = "navytie" + +/obj/item/clothing/accessory/tie/white + name = "white tie" + icon_state = "whitetie" + /obj/item/clothing/accessory/stethoscope name = "stethoscope" desc = "An outdated medical apparatus for listening to the sounds of the human body. It also makes you look like you know what you're doing." @@ -154,7 +190,7 @@ desc = "A bronze medal." icon_state = "bronze" item_state = "bronze" - + /obj/item/clothing/accessory/medal/conduct name = "distinguished conduct medal" desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award on offer. It is often awarded by a captain to a member of their crew." @@ -225,52 +261,58 @@ icon_state = "suspenders" item_state = "suspenders" +/obj/item/clothing/accessory/sweater + name = "sweater" + desc = "A warm knit sweater." + icon_state = "sweater" + item_state = "sweater" + /obj/item/clothing/accessory/scarf name = "white scarf" desc = "A simple scarf, to protect your neck from the cold of space." icon_state = "whitescarf" item_state = "whitescarf" - + /obj/item/clothing/accessory/scarf/yellow name = "yellow scarf" icon_state = "yellowscarf" item_state = "yellowscarf" - + /obj/item/clothing/accessory/scarf/green name = "green scarf" icon_state = "greenscarf" item_state = "greenscarf" - + /obj/item/clothing/accessory/scarf/purple name = "purple scarf" icon_state = "purplescarf" item_state = "purplescarf" - + /obj/item/clothing/accessory/scarf/black name = "black scarf" icon_state = "blackscarf" item_state = "blackscarf" - + /obj/item/clothing/accessory/scarf/red name = "red scarf" icon_state = "redscarf" item_state = "redscarf" - + /obj/item/clothing/accessory/scarf/orange name = "orange scarf" icon_state = "orangescarf" item_state = "orangescarf" - + /obj/item/clothing/accessory/scarf/light_blue name = "light blue scarf" icon_state = "lightbluescarf" item_state = "lightbluescarf" - + /obj/item/clothing/accessory/scarf/dark_blue name = "dark blue scarf" icon_state = "darkbluescarf" item_state = "darkbluescarf" - + /obj/item/clothing/accessory/scarf/zebra name = "zebra scarf" icon_state = "zebrascarf" diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm index 766f05654e9..6b3e2ed5432 100644 --- a/code/modules/clothing/under/accessories/holster.dm +++ b/code/modules/clothing/under/accessories/holster.dm @@ -4,6 +4,8 @@ icon_state = "holster" slot = "utility" var/obj/item/holstered = null + var/sound_in = 'sound/items/holster/holsterin.ogg' + var/sound_out = 'sound/items/holster/holsterout.ogg' /obj/item/clothing/accessory/holster/proc/holster(var/obj/item/I, var/mob/living/user) if(holstered && istype(user)) @@ -14,6 +16,9 @@ user << "[I] won't fit in [src]!" return + if(sound_in) + playsound(get_turf(src), sound_in, 50) + if(istype(user)) user.stop_aiming(no_message=1) holstered = I @@ -35,7 +40,9 @@ if(istype(user.get_active_hand(),/obj) && istype(user.get_inactive_hand(),/obj)) user << "You need an empty hand to draw \the [holstered]!" else + var/sound_vol = 25 if(user.a_intent == I_HURT) + sound_vol = 50 usr.visible_message( "[user] draws \the [holstered], ready to shoot!", "You draw \the [holstered], ready to shoot!" @@ -45,6 +52,10 @@ "[user] draws \the [holstered], pointing it at the ground.", "You draw \the [holstered], pointing it at the ground." ) + + if(sound_out) + playsound(get_turf(src), sound_out, sound_vol) + user.put_in_hands(holstered) holstered.add_fingerprint(user) w_class = initial(w_class) @@ -134,3 +145,5 @@ name = "thigh holster" desc = "A drop leg holster made of a durable synthetic fiber." icon_state = "holster_thigh" + sound_in = 'sound/items/holster/tactiholsterin.ogg' + sound_out = 'sound/items/holster/tactiholsterout.ogg' diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 3e99ef1ce9a..f0150a1148e 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -225,14 +225,6 @@ item_state = "r_suit" worn_state = "red_suit" -/obj/item/clothing/under/blackskirt - name = "black skirt" - desc = "A black skirt, very fancy!" - icon_state = "blackskirt" - item_state = "bl_suit" - worn_state = "blackskirt" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS - /obj/item/clothing/under/schoolgirl name = "schoolgirl uniform" desc = "It's just like one of my Japanese animes!" @@ -364,26 +356,6 @@ worn_state = "huresource" body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS -/obj/item/clothing/under/dress/plaid_blue - name = "blue plaid skirt" - desc = "A preppy blue skirt with a white blouse." - icon_state = "plaid_blue" - worn_state = "plaid_blue" - -/obj/item/clothing/under/dress/plaid_red - name = "red plaid skirt" - desc = "A preppy red skirt with a white blouse." - icon_state = "plaid_red" - item_state = "kilt" - worn_state = "plaid_red" - -/obj/item/clothing/under/dress/plaid_purple - name = "blue purple skirt" - desc = "A preppy purple skirt with a white blouse." - icon_state = "plaid_purple" - item_state = "kilt" - worn_state = "plaid_purple" - //wedding stuff /obj/item/clothing/under/wedding/ body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS @@ -445,13 +417,6 @@ worn_state = "sundress_white" body_parts_covered = UPPER_TORSO|LOWER_TORSO -/obj/item/clothing/under/blackjumpskirt - name = "black jumpskirt" - desc = "A black jumpskirt, Sol size 0." - icon_state = "blackjumpskirt" - item_state = "bl_suit" - worn_state = "blackjumpskirt" - /obj/item/clothing/under/captainformal name = "captain's formal uniform" desc = "A captain's formal-wear, for special occasions." @@ -572,7 +537,19 @@ item_state = "blue_blazer" worn_state = "blue_blazer" +/obj/item/clothing/under/dominia + name = "dominia suit" + desc = "This is a suit in the style of Dominia nobility. It's the latest fashion across Dominian space." + icon_state = "domsuit" +/obj/item/clothing/under/dominia/black + icon_state = "domsuit2" + +/obj/item/clothing/under/dom_thermal + name = "lyodsuit" + desc = "An imitation Lyodsuit from Dominia. Though it is not able to protect against extreme cold like a true lyodsuit it's lightweight and high quality fabric make it extremely comfortable to wear. \ + Fashionable amongst the middle and lower classes of Dominia" + icon_state = "dom_thermal" //stripper /obj/item/clothing/under/stripper diff --git a/code/modules/clothing/under/shorts.dm b/code/modules/clothing/under/shorts.dm index 0e017866a33..02deaf0ff79 100644 --- a/code/modules/clothing/under/shorts.dm +++ b/code/modules/clothing/under/shorts.dm @@ -7,27 +7,99 @@ /obj/item/clothing/under/shorts/red name = "red athletic shorts" icon_state = "redshorts" - worn_state = "redshorts" + item_state = "redshorts" /obj/item/clothing/under/shorts/green name = "green athletic shorts" icon_state = "greenshorts" - worn_state = "greenshorts" + item_state = "greenshorts" /obj/item/clothing/under/shorts/blue name = "blue athletic shorts" icon_state = "blueshorts" - worn_state = "blueshorts" + item_state = "blueshorts" /obj/item/clothing/under/shorts/black name = "black athletic shorts" icon_state = "blackshorts" - worn_state = "blackshorts" + item_state = "blackshorts" /obj/item/clothing/under/shorts/grey name = "grey athletic shorts" icon_state = "greyshorts" - worn_state = "greyshorts" + item_state = "greyshorts" + +/obj/item/clothing/under/shorts/jeans + name = "jeans shorts" + desc = "Some jeans! Just in short form!" + icon_state = "jeans_shorts" + item_state = "jeans_shorts" + +/obj/item/clothing/under/shorts/jeans/female + name = "jeans short shorts" + icon_state = "jeans_shorts_f" + item_state = "jeans_shorts_f" + +/obj/item/clothing/under/shorts/jeans/classic + name = "classic jeans shorts" + icon_state = "jeansclassic_shorts" + item_state = "jeansclassic_shorts" + +/obj/item/clothing/under/shorts/jeans/classic/female + name = "classic jeans short shorts" + icon_state = "jeansclassic_shorts_f" + item_state = "jeansclassic_shorts_f" + +/obj/item/clothing/under/shorts/jeans/mustang + name = "mustang jeans shorts" + icon_state = "jeansmustang_shorts" + item_state = "jeansmustang_shorts" + +/obj/item/clothing/under/shorts/jeans/mustang/female + name = "mustang jeans short shorts" + icon_state = "jeansmustang_shorts_f" + item_state = "jeansmustang_shorts_f" + +/obj/item/clothing/under/shorts/jeans/youngfolks + name = "young folks jeans shorts" + icon_state = "jeansyoungfolks_shorts" + item_state = "jeansyoungfolks_shorts" + +/obj/item/clothing/under/shorts/jeans/youngfolks/female + name = "young folks jeans short shorts" + icon_state = "jeansyoungfolks_shorts_f" + item_state = "jeansyoungfolks_shorts_f" + +/obj/item/clothing/under/shorts/jeans/black + name = "black jeans shorts" + icon_state = "blackpants_shorts" + item_state = "blackpants_shorts" + +/obj/item/clothing/under/shorts/jeans/black/female + name = "black jeans short shorts" + icon_state = "black_shorts_f" + item_state = "black_shorts_f" + +/obj/item/clothing/under/shorts/jeans/grey + name = "grey jeans shorts" + icon_state = "greypants_shorts" + item_state = "greypants_shorts" + +/obj/item/clothing/under/shorts/jeans/grey/female + name = "grey jeans short shorts" + icon_state = "grey_shorts_f" + item_state = "grey_shorts_f" + +/obj/item/clothing/under/shorts/khaki + name = "khaki shorts" + desc = "For that island getaway. It's five o'clock somewhere, right?" + icon_state = "tanpants_shorts" + item_state = "tanpants_shorts" + +/obj/item/clothing/under/shorts/khaki/female + name = "khaki short shorts" + icon_state = "khaki_shorts_f" + item_state = "khaki_shorts_f" //pants diff --git a/code/modules/clothing/under/skirts.dm b/code/modules/clothing/under/skirts.dm new file mode 100644 index 00000000000..cadb8d2638b --- /dev/null +++ b/code/modules/clothing/under/skirts.dm @@ -0,0 +1,67 @@ +//skirts + +/obj/item/clothing/under/skirt/ + name = "black skirt" + desc = "A black skirt, very fancy!" + icon_state = "blackskirt" + item_state = "bl_suit" + worn_state = "blackskirt" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + rolled_sleeves = -1 + +/obj/item/clothing/under/skirt/khaki + name = "khaki skirt" + desc = "A skirt that is a khaki color." + icon_state = "skirt_khaki" + worn_state = "skirt_khaki" + +/obj/item/clothing/under/skirt/short_black + name = "short black skirt" + desc = "A skirt that is a shiny black." + icon_state = "skirt_short_black" + worn_state = "skirt_short_black" + +/obj/item/clothing/under/skirt/blue + name = "short blue skirt" + desc = "A skirt that is a shiny blue." + icon_state = "skirt_short_blue" + worn_state = "skirt_short_blue" + +/obj/item/clothing/under/skirt/red + name = "short red skirt" + desc = "A skirt that is a shiny red." + icon_state = "skirt_short_red" + worn_state = "skirt_short_red" + +/obj/item/clothing/under/skirt/swept + name = "swept skirt" + desc = "A skirt that is swept to one side." + icon_state = "skirt_swept" + worn_state = "skirt_swept" + +/obj/item/clothing/under/skirt/plaid_blue + name = "blue plaid skirt" + desc = "A preppy blue skirt with a white blouse." + icon_state = "plaid_blue" + worn_state = "plaid_blue" + +/obj/item/clothing/under/skirt/plaid_red + name = "red plaid skirt" + desc = "A preppy red skirt with a white blouse." + icon_state = "plaid_red" + item_state = "kilt" + worn_state = "plaid_red" + +/obj/item/clothing/under/skirt/plaid_purple + name = "blue purple skirt" + desc = "A preppy purple skirt with a white blouse." + icon_state = "plaid_purple" + item_state = "kilt" + worn_state = "plaid_purple" + +/obj/item/clothing/under/skirt/blackjumpskirt + name = "black jumpskirt" + desc = "A black jumpskirt, Sol size 0." + icon_state = "blackjumpskirt" + item_state = "bl_suit" + worn_state = "blackjumpskirt" \ No newline at end of file diff --git a/code/modules/clothing/under/xenos/tajara.dm b/code/modules/clothing/under/xenos/tajara.dm new file mode 100644 index 00000000000..a04d34686a0 --- /dev/null +++ b/code/modules/clothing/under/xenos/tajara.dm @@ -0,0 +1,105 @@ +/obj/item/clothing/under/tajaran + name = "laborers clothes" + desc = "A rough but thin outfit, providing air flow but also protection from working hazards." + icon = 'icons/obj/tajara_items.dmi' + icon_state = "taj_labor" + item_state = "taj_labor" + contained_sprite = TRUE + +/obj/item/clothing/under/tajaran/fancy + name = "fancy uniform" + desc = "Worn by princess, barons and lords of Adhomai, now in stores near you!" + icon_state = "male_taj_fancy" + item_state = "male_taj_fancy" + +/obj/item/clothing/under/tajaran/nt + name = "NanoTrasen overalls" + desc = "Overalls meant for NanoTrasen employees of xeno descend, modified to prevent overheating." + icon_state = "ntoveralls" + item_state = "ntoveralls" + +/obj/item/clothing/under/dress/tajaran + name = "fancy adhomian dress" + desc = "Created for the rich and party-loving circles of Adhomai, this dress is fashioned from smooth silk and is see through at parts. This one is white." + icon = 'icons/obj/tajara_items.dmi' + icon_state = "taj_dress_white" + item_state = "taj_dress_white" + contained_sprite = TRUE + +/obj/item/clothing/under/dress/tajaran/blue + desc = "Created for the rich and party-loving circles of Adhomai, this dress is fashioned from smooth silk and is see through at parts. This one is blue." + icon = 'icons/obj/tajara_items.dmi' + icon_state = "taj_dress_skyblue" + item_state = "taj_dress_skyblue" + +/obj/item/clothing/under/dress/tajaran/green + desc = "Created for the rich and party-loving circles of Adhomai, this dress is fashioned from smooth silk and is see through at parts. This one is green." + icon = 'icons/obj/tajara_items.dmi' + icon_state = "taj_dress_green" + item_state = "taj_dress_green" + +/obj/item/clothing/under/dress/tajaran/red + desc = "Created for the rich and party-loving circles of Adhomai, this dress is fashioned from smooth silk and is see through at parts. This one is red." + icon = 'icons/obj/tajara_items.dmi' + icon_state = "taj_dress_red" + item_state = "taj_dress_red" + +/obj/item/clothing/under/dress/tajaran/fancy + name = "noble adhomian dress" + desc = "The classical dress of the Adhomai royalty, only to be worn during the special occassions. This one is crimson red." + icon = 'icons/obj/tajara_items.dmi' + icon_state = "taj_dress_fancy" + item_state = "taj_dress_fancy" + +/obj/item/clothing/under/dress/tajaran/fancy/black + desc = "The classical dress of the Adhomai royalty, only to be worn during the special occassions. This one is dark black." + icon_state = "taj_dress_fancy_dark" + item_state = "taj_dress_fancy_dark" + +/obj/item/clothing/accessory/tajaran + name = "fur scarf" + desc = "A furred scarf, a common tajaran vanity item, this one is brown." + icon = 'icons/obj/tajara_items.dmi' + icon_state = "furscarf_brown" + item_state = "furscarf_brown" + contained_sprite = TRUE + +/obj/item/clothing/accessory/tajaran/lbrown + desc = "A furred scarf, a common tajaran vanity item, this one is light brown." + icon_state = "furscarf_lbrown" + item_state = "furscarf_lbrown" + +/obj/item/clothing/accessory/tajaran/cinnamon + desc = "A furred scarf, a common tajaran vanity item, this one is cinnamon." + icon_state = "furscarf_cinnamon" + item_state = "furscarf_cinnamon" + +/obj/item/clothing/accessory/tajaran/blue + desc = "A furred scarf, a common tajaran vanity item, this one is blue." + icon_state = "furscarf_blue" + item_state = "furscarf_blue" + +/obj/item/clothing/accessory/tajaran/silver + desc = "A furred scarf, a common tajaran vanity item, this one is silver." + icon_state = "furscarf_silver" + item_state = "furscarf_silver" + +/obj/item/clothing/accessory/tajaran/black + desc = "A furred scarf, a common tajaran vanity item, this one is black." + icon_state = "furscarf_black" + item_state = "furscarf_black" + +/obj/item/clothing/accessory/tajaran/ruddy + desc = "A furred scarf, a common tajaran vanity item, this one is ruddy." + icon_state = "furscarf_ruddy" + item_state = "furscarf_ruddy" + +/obj/item/clothing/accessory/tajaran/orange + desc = "A furred scarf, a common tajaran vanity item, this one is orange." + icon_state = "furscarf_lasaga" + item_state = "furscarf_lasaga" + +/obj/item/clothing/accessory/tajaran/cream + desc = "A furred scarf, a common tajaran vanity item, this one is cream." + icon_state = "furscarf_cream" + item_state = "furscarf_cream" \ No newline at end of file diff --git a/code/modules/economy/Events.dm b/code/modules/economy/Events.dm index d5cb34a5d94..4c0556cec1a 100644 --- a/code/modules/economy/Events.dm +++ b/code/modules/economy/Events.dm @@ -89,7 +89,8 @@ if(FESTIVAL) body = "A [pick("festival","week long celebration","day of revelry","planet-wide holiday")] has been declared on [affected_dest.name] by [pick("Governor","Commissioner","General","Commandant","Administrator")] [random_name(pick(MALE,FEMALE))] to celebrate [pick("the birth of their [pick("son","daughter")]","coming of age of their [pick("son","daughter")]","the pacification of rogue military cell","the apprehension of a violent criminal who had been terrorising the planet")]. Massive stocks of food and meat have been bought driving up prices across the planet." - news_network.SubmitArticle(body, author, channel, null, 1) + var/datum/feed_channel/ch = SSnews.GetFeedChannel(channel) + SSnews.SubmitArticle(body, author, ch, null, 1) /datum/event/economic_event/end() for(var/good_type in dearer_goods) diff --git a/code/modules/economy/Events_Mundane.dm b/code/modules/economy/Events_Mundane.dm index 2c4f8e48115..e5f540825d8 100644 --- a/code/modules/economy/Events_Mundane.dm +++ b/code/modules/economy/Events_Mundane.dm @@ -121,100 +121,6 @@ body += "Tourists are flocking to [affected_dest.name] after the surprise announcement of [pick("major shopping bargains by a wily retailer",\ "a huge new ARG by a popular entertainment company","a secret tour by popular artiste [random_name(pick(MALE,FEMALE))]")]. \ Tau Ceti Daily is offering discount tickets for two to see [random_name(pick(MALE,FEMALE))] live in return for eyewitness reports and up to the minute coverage." - - news_network.SubmitArticle(body, author, channel, null, 1) - -/datum/event/trivial_news - endWhen = 10 - -/datum/event/trivial_news/announce() - var/author = "Editor Mike Hammers" - var/channel = "The Gibson Gazette" - - var/datum/trade_destination/affected_dest = pick(weighted_mundaneevent_locations) - var/body = pick( - "Tree stuck in tajaran; firefighters baffled.",\ - "Armadillos want aardvarks removed from dictionary claims 'here first'.",\ - "Angel found dancing on pinhead ordered to stop; cited for public nuisance.",\ - "Letters claim they are better than number; 'Always have been'.",\ - "Pens proclaim pencils obsolete, 'lead is dead'.",\ - "Rock and paper sues scissors for discrimination.",\ - "Steak tell-all book reveals he never liked sitting by potato.",\ - "Woodchuck stops counting how many times heÂ’s chucked 'Never again'.",\ - "[affected_dest.name] clerk first person able to pronounce '@*$%!'.",\ - "[affected_dest.name] delis serving boiled paperback dictionaries, 'Adjectives chewy' customers declare.",\ - "[affected_dest.name] weather deemed 'boring'; meteors and rad storms to be imported.",\ - "Most [affected_dest.name] security officers prefer cream over sugar.",\ - "Palindrome speakers conference in [affected_dest.name]; 'Wow!' says Otto.",\ - "Question mark worshipped as deity by ancient [affected_dest.name] dwellers.",\ - "Spilled milk causes whole [affected_dest.name] populace to cry.",\ - "World largest carp patty at display on [affected_dest.name].",\ - "'Here kitty kitty' no longer preferred tajaran retrieval technique.",\ - "Man travels 7000 light years to retrieve lost hankie, 'It was my favourite'.",\ - "New bowling lane that shoots mini-meteors at bowlers very popular.",\ - "[pick("Unathi","Spacer")] gets tattoo of Tau Ceti on chest '[pick("CentComm","star","starship","asteroid")] tickles most'.",\ - "Skrell marries computer; wedding attended by 100 modems.",\ - "Chef reports successfully using harmonica as cheese grater.",\ - "[current_map.company_name] invents handkerchief that says 'Bless you' after sneeze.",\ - "Clone accused of posing for other clonesÂ’s school photo.",\ - "Clone accused of stealing other clonesÂ’s employee of the month award.",\ - "Woman robs station with hair dryer; crewmen love new style.",\ - "This space for rent.",\ - "[affected_dest.name] Baker Wins Pickled Crumpet Toss Three Years Running",\ - "Skrell Scientist Discovers Abacus Can Be Used To Dry Towels",\ - "Survey: 'Cheese Louise' Voted Best Pizza Restaurant In Tau Ceti",\ - "I Was Framed, jokes [affected_dest.name] artist",\ - "Mysterious Loud Rumbling Noises In [affected_dest.name] Found To Be Mysterious Loud Rumblings",\ - "Alien ambassador becomes lost on [affected_dest.name], refuses to ask for directions",\ - "Swamp Gas Verified To Be Exhalations Of Stars--Movie Stars--Long Passed",\ - "Tainted Broccoli Weapon Of Choice For Efficient Assassins",\ - "Chefs Find Broccoli Effective Tool For Cutting Cheese",\ - "Broccoli Found To Cause Grumpiness In Monkeys",\ - "Survey: 80% Of People on [affected_dest.name] Love Clog-Dancing",\ - "Giant Hairball Has Perfect Grammar But Rolls rr's Too Much, Linguists Say",\ - "[affected_dest.name] Phonebooks Print All Wrong Numbers; Results In 15 New Marriages",\ - "Tajaran Burglar Spotted on [affected_dest.name], Mistaken For Dalmatian",\ - "Gibson Gazette Updates Frequently Absurd, Poll Indicates",\ - "Esoteric Verbosity Culminates In Communicative Ennui, [affected_dest.name] Academics Note",\ - "Taj Demand Longer Breaks, Cleaner Litter, Slower Mice",\ - "Survey: 3 Out Of 5 Skrell Loathe Modern Art",\ - "Skrell Scientist Discovers Gravity While Falling Down Stairs",\ - "Boy Saves Tajaran From Tree on [affected_dest.name], Thousands Cheer",\ - "Shipment Of Apples Overturns, [affected_dest.name] Diner Offers Applesauce Special",\ - "Spotted Owl Spotted on [affected_dest.name]",\ - "Humans Everywhere Agree: Purring Tajarans Are Happy Tajarans",\ - "From The Desk Of Wise Guy Sammy: One Word In This Gazette Is Sdrawkcab",\ - "From The Desk Of Wise Guy Sammy: It's Hard To Have Too Much Shelf Space",\ - "From The Desk Of Wise Guy Sammy: Wine And Friendships Get Better With Age",\ - "From The Desk Of Wise Guy Sammy: The Insides Of Golf Balls Are Mostly Rubber Bands",\ - "From The Desk Of Wise Guy Sammy: You Don't Have To Fool All The People, Just The Right Ones",\ - "From The Desk Of Wise Guy Sammy: If You Made The Mess, You Clean It Up",\ - "From The Desk Of Wise Guy Sammy: It Is Easier To Get Forgiveness Than Permission",\ - "From The Desk Of Wise Guy Sammy: Check Your Facts Before Making A Fool Of Yourself",\ - "From The Desk Of Wise Guy Sammy: You Can't Outwait A Bureaucracy",\ - "From The Desk Of Wise Guy Sammy: It's Better To Yield Right Of Way Than To Demand It",\ - "From The Desk Of Wise Guy Sammy: A Person Who Likes Cats Can't Be All Bad",\ - "From The Desk Of Wise Guy Sammy: Help Is The Sunny Side Of Control",\ - "From The Desk Of Wise Guy Sammy: Two Points Determine A Straight Line",\ - "From The Desk Of Wise Guy Sammy: Reading Improves The Mind And Lifts The Spirit",\ - "From The Desk Of Wise Guy Sammy: Better To Aim High And Miss Then To Aim Low And Hit",\ - "From The Desk Of Wise Guy Sammy: Meteors Often Strike The Same Place More Than Once",\ - "Tommy B. Saif Sez: Look Both Ways Before Boarding The Shuttle",\ - "Tommy B. Saif Sez: Hold On; Sudden Stops Sometimes Necessary",\ - "Tommy B. Saif Sez: Keep Fingers Away From Moving Panels",\ - "Tommy B. Saif Sez: No Left Turn, Except Shuttles",\ - "Tommy B. Saif Sez: Return Seats And Trays To Their Proper Upright Position",\ - "Tommy B. Saif Sez: Eating And Drinking In Docking Bays Is Prohibited",\ - "Tommy B. Saif Sez: Accept No Substitutes, And Don't Be Fooled By Imitations",\ - "Tommy B. Saif Sez: Do Not Remove This Tag Under Penalty Of Law",\ - "Tommy B. Saif Sez: Always Mix Thoroughly When So Instructed",\ - "Tommy B. Saif Sez: Try To Keep Six Month's Expenses In Reserve",\ - "Tommy B. Saif Sez: Change Not Given Without Purchase",\ - "Tommy B. Saif Sez: If You Break It, You Buy It",\ - "Tommy B. Saif Sez: Reservations Must Be Cancelled 48 Hours Prior To Event To Obtain Refund",\ - "Doughnuts: Is There Anything They Can't Do",\ - "If Tin Whistles Are Made Of Tin, What Do They Make Foghorns Out Of?",\ - "Broccoli discovered to be colonies of tiny aliens with murder on their minds"\ - ) - - news_network.SubmitArticle(body, author, channel, null, 1) + + var/datum/feed_channel/ch = SSnews.GetFeedChannel(channel) + SSnews.SubmitArticle(body, author, ch, null, 1) \ No newline at end of file diff --git a/code/modules/economy/economy_misc.dm b/code/modules/economy/economy_misc.dm index db8bf5bb1d1..0ec20aa1103 100644 --- a/code/modules/economy/economy_misc.dm +++ b/code/modules/economy/economy_misc.dm @@ -77,9 +77,6 @@ var/global/economy_init = 0 if(economy_init) return 2 - news_network.CreateFeedChannel("Tau Ceti Daily", "CentComm Minister of Information", 1, 1) - news_network.CreateFeedChannel("The Gibson Gazette", "Editor Mike Hammers", 1, 1) - for(var/loc_type in typesof(/datum/trade_destination) - /datum/trade_destination) var/datum/trade_destination/D = new loc_type weighted_randomevent_locations[D] = D.viable_random_events.len diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 6959905d6a5..43d5c0d0d59 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -137,7 +137,6 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 1, 5, 15), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mundane News", /datum/event/mundane_news, 300), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 0, 25, 50), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation", /datum/event/infestation, 60, list(ASSIGNMENT_JANITOR = 20, ASSIGNMENT_SECURITY = 10)), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 75, list(ASSIGNMENT_ENGINEER = 5, ASSIGNMENT_GARDENER = 20)), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Clogged Vents", /datum/event/vent_clog, 55), @@ -159,6 +158,8 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, 0, list(ASSIGNMENT_AI = 45, ASSIGNMENT_CYBORG = 25, ASSIGNMENT_ENGINEER = 6, ASSIGNMENT_SCIENTIST = 6)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_shower, 40, list(ASSIGNMENT_ENGINEER = 13)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 15, ASSIGNMENT_CYBORG = 20),1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Containment Error - Virology", /datum/event/prison_break/virology, 0, list(ASSIGNMENT_MEDICAL = 15, ASSIGNMENT_CYBORG = 20),1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Containment Error - Xenobiology", /datum/event/prison_break/xenobiology, 0, list(ASSIGNMENT_SCIENTIST = 15, ASSIGNMENT_CYBORG = 20),1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 100), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Random Antagonist", /datum/event/random_antag, 0, list(ASSIGNMENT_ANY = 1, ASSIGNMENT_SECURITY = 1),0,10,125, list("Extended")), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, 50, list(ASSIGNMENT_SECURITY = 25)), diff --git a/code/modules/events/event_dynamic.dm b/code/modules/events/event_dynamic.dm index 83e4972e94c..6d224494d91 100644 --- a/code/modules/events/event_dynamic.dm +++ b/code/modules/events/event_dynamic.dm @@ -51,7 +51,6 @@ var/list/event_last_fired = list() // Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events_Mundane.dm possibleEvents[/datum/event/economic_event] = 300 - possibleEvents[/datum/event/trivial_news] = 400 possibleEvents[/datum/event/mundane_news] = 300 possibleEvents[/datum/event/pda_spam] = max(min(25, player_list.len) * 4, 200) diff --git a/code/modules/events/money_lotto.dm b/code/modules/events/money_lotto.dm index b196354bd38..a9c8df6107c 100644 --- a/code/modules/events/money_lotto.dm +++ b/code/modules/events/money_lotto.dm @@ -29,5 +29,5 @@ var/body = "Tau Ceti Daily wishes to congratulate [winner_name] for recieving the Tau Ceti Stellar Slam Lottery, and receiving the out of this world sum of [winner_sum] credits!" if(!deposit_success) body += "
Unfortunately, we were unable to verify the account details provided, so we were unable to transfer the money. Send a cheque containing the sum of 5000 credits to ND 'Stellar Slam' office on the Tau Ceti gateway containing updated details, and your winnings'll be re-sent within the month." - - news_network.SubmitArticle(body, author, channel, null, 1) + var/datum/feed_channel/ch = SSnews.GetFeedChannel(channel) + SSnews.SubmitArticle(body, author, ch, null, 1) diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm index 6e32f766671..6f2a8ec9f4c 100644 --- a/code/modules/food/recipes_microwave.dm +++ b/code/modules/food/recipes_microwave.dm @@ -34,10 +34,6 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/boiledegg - - - - /datum/recipe/humanburger items = list( /obj/item/weapon/reagent_containers/food/snacks/meat/human, @@ -621,8 +617,6 @@ I said no! reagents = list("water" = 10) result = /obj/item/weapon/reagent_containers/food/snacks/beetsoup - - /datum/recipe/tossedsalad fruit = list("cabbage" = 2, "tomato" = 1, "carrot" = 1, "apple" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/tossedsalad @@ -1121,3 +1115,42 @@ I said no! /obj/item/weapon/reagent_containers/food/snacks/friedegg ) result = /obj/item/weapon/reagent_containers/food/snacks/bacon_and_eggs + +/datum/recipe/baconburger + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/bacon + ) + result = /obj/item/weapon/reagent_containers/food/snacks/baconburger + +/datum/recipe/ntmuffin + items = list( + /obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit, + /obj/item/weapon/reagent_containers/food/snacks/cutlet, + /obj/item/weapon/reagent_containers/food/snacks/friedegg, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/spreads/butter + ) + result = /obj/item/weapon/reagent_containers/food/snacks/nt_muffin + +/datum/recipe/fish_taco + fruit = list("chili" = 1, "lemon" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/carpmeat, + /obj/item/weapon/reagent_containers/food/snacks/tortilla + ) + result = /obj/item/weapon/reagent_containers/food/snacks/fish_taco + +/datum/recipe/blt + fruit = list("tomato" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/bread, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/bread, + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/bacon + ) + result = /obj/item/weapon/reagent_containers/food/snacks/blt diff --git a/code/modules/food/recipes_oven.dm b/code/modules/food/recipes_oven.dm index 34b1d6c305b..7a00be0a509 100644 --- a/code/modules/food/recipes_oven.dm +++ b/code/modules/food/recipes_oven.dm @@ -384,9 +384,16 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza - - - +/datum/recipe/pineapplepizza + appliance = OVEN + fruit = list("tomato" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/pineapple_ring, + /obj/item/weapon/reagent_containers/food/snacks/pineapple_ring + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/pineapple //Spicy //================ @@ -521,3 +528,32 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/bacon/oven result_quantity = 6 + +/datum/recipe/meat_pocket + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/meatball, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/meat_pocket + result_quantity = 2 + +/datum/recipe/bacon_flatbread + fruit = list("tomato" = 2) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/bacon + ) + result = /obj/item/weapon/reagent_containers/food/snacks/bacon_flatbread + +/datum/recipe/truffle + reagents = list("sugar" = 5, "cream" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/chocolatebar + ) + result = /obj/item/weapon/reagent_containers/food/snacks/truffle + result_quantity = 4 \ No newline at end of file diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index 3faf63a7ee6..1682913b9dc 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -292,7 +292,7 @@ // Handle light requirements. if(!light_supplied) - if (current_turf.dynamic_lighting) + if (TURF_IS_DYNAMICALLY_LIT(current_turf)) light_supplied = current_turf.get_lumcount(0, 3) * 10 else light_supplied = 5 diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm index 1927e238ee1..66ca8455117 100644 --- a/code/modules/hydroponics/seed_datums.dm +++ b/code/modules/hydroponics/seed_datums.dm @@ -513,7 +513,7 @@ name = "amanita" seed_name = "fly amanita" display_name = "fly amanita mushrooms" - mutants = list("destroyingangel","plastic") + mutants = list("destroyingangel","plastic","panocelium") chems = list("nutriment" = list(1), "amatoxin" = list(3,3), "psilocybin" = list(1,25)) /datum/seed/mushroom/poison/setup_traits() @@ -543,7 +543,24 @@ set_trait(TRAIT_PRODUCT_COLOUR,"#EDE8EA") set_trait(TRAIT_PLANT_COLOUR,"#E6D8DD") set_trait(TRAIT_PLANT_ICON,"mushroom5") + +/datum/seed/mushroom/poison/panocelium + name = "panocelium" + seed_name = "panocelium" + display_name = "panocelium mushrooms" + mutants = null + chems = list("nutriment" = list(1,50), "panotoxin" = list(10,3), "psilocybin" = list(1,25)) +/datum/seed/mushroom/poison/panocelium/setup_traits() + ..() + set_trait(TRAIT_MATURATION,12) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,20) + set_trait(TRAIT_PRODUCT_ICON,"mushroom6") + set_trait(TRAIT_PRODUCT_COLOUR,"#88FFFF") + set_trait(TRAIT_PLANT_COLOUR,"#88FFFF") + set_trait(TRAIT_PLANT_ICON,"mushroom6") + /datum/seed/mushroom/towercap name = "towercap" seed_name = "tower cap" diff --git a/code/modules/hydroponics/seed_packets.dm b/code/modules/hydroponics/seed_packets.dm index d1a56dcc19e..c0959752055 100644 --- a/code/modules/hydroponics/seed_packets.dm +++ b/code/modules/hydroponics/seed_packets.dm @@ -165,6 +165,9 @@ var/global/list/plant_seed_sprites = list() /obj/item/seeds/amanitamycelium seed_type = "amanita" +/obj/item/seeds/panocelium + seed_type = "panocelium" + /obj/item/seeds/angelmycelium seed_type = "destroyingangel" diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index 479b4a0a55a..ce627e501e1 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -647,10 +647,11 @@ light_string = "that the internal lights are set to [tray_light] lumens" else var/light_available - if(T.dynamic_lighting) + if(TURF_IS_DYNAMICALLY_LIT(T)) light_available = T.get_lumcount(0, 3) * 10 else - light_available = 5 + light_available = 5 + light_string = "a light level of [light_available] lumens" usr << "The tray's sensor suite is reporting [light_string] and a temperature of [environment.temperature]K." diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 8cea43fec01..1da1b29143e 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -295,7 +295,8 @@ inputs = list() outputs = list( "X"= IC_PINTYPE_NUMBER, - "Y" = IC_PINTYPE_NUMBER + "Y" = IC_PINTYPE_NUMBER, + "Z" = IC_PINTYPE_NUMBER ) activators = list( "get coordinates" = IC_PINTYPE_PULSE_IN, @@ -309,11 +310,13 @@ set_pin_data(IC_OUTPUT, 1, null) set_pin_data(IC_OUTPUT, 2, null) + set_pin_data(IC_OUTPUT, 3, null) if(!T) return set_pin_data(IC_OUTPUT, 1, T.x) set_pin_data(IC_OUTPUT, 2, T.y) + set_pin_data(IC_OUTPUT, 3, T.z) push_data() activate_pin(2) diff --git a/code/modules/item_worth/reagents.dm b/code/modules/item_worth/reagents.dm index f1a424a1ff8..193af6a0d9c 100644 --- a/code/modules/item_worth/reagents.dm +++ b/code/modules/item_worth/reagents.dm @@ -597,12 +597,6 @@ /datum/reagent/mental/truthserum value = 8 -/datum/reagent/mental/hextrasenil - value = 12 - -/datum/reagent/mental/trisyndicotin - value = 16 - /datum/reagent/mental/nicotine value = 2 diff --git a/code/modules/item_worth/worths_list.dm b/code/modules/item_worth/worths_list.dm index fec7e9d22b1..6e5af9fa7fc 100644 --- a/code/modules/item_worth/worths_list.dm +++ b/code/modules/item_worth/worths_list.dm @@ -91,6 +91,7 @@ var/list/worths = list( /obj/item/weapon/gun/projectile/automatic = 2000, //PROJECTILE, /obj/item/weapon/gun/projectile/shotgun/pump/combat = 5500, + /obj/item/weapon/gun/projectile/shotgun/pump/rifle = 1200, /obj/item/weapon/gun/projectile/shotgun/pump = 3500, /obj/item/weapon/gun/projectile/shotgun/doublebarrel = 2500, /obj/item/weapon/gun/projectile/shotgun/improvised = 1000, @@ -107,7 +108,6 @@ var/list/worths = list( /obj/item/weapon/gun/projectile/heavysniper/tranq = 6000, /obj/item/weapon/gun/projectile/heavysniper = 12000, /obj/item/weapon/gun/projectile/silenced = 1700, - /obj/item/weapon/gun/projectile/boltaction = 1200, /obj/item/weapon/gun/projectile/dragunov = 4500, /obj/item/weapon/gun/projectile/contender = 1300, /obj/item/weapon/gun/projectile = 1500, diff --git a/code/modules/law/incident.dm b/code/modules/law/incident.dm index 3b02dbc1f11..c3e592dc09f 100644 --- a/code/modules/law/incident.dm +++ b/code/modules/law/incident.dm @@ -134,14 +134,25 @@ return max -/datum/crime_incident/proc/renderGuilty( var/mob/living/user ) +//type: 0 - brig sentence, 1 - fine, 2 - prison sentence +/datum/crime_incident/proc/renderGuilty( var/mob/living/user, var/type=0 ) if( !criminal ) return created_by = "[user.ckey] - [user.real_name]" + if(type == 0) + prison_sentence = 0 + fine = 0 + else if(type == 1) + brig_sentence = 0 + prison_sentence = 0 + else if(type == 2) + brig_sentence = 0 + fine = 0 + saveCharInfraction() - generateReport() + return generateReport() /datum/crime_incident/proc/generateReport() . = "
Security Incident Report

" @@ -149,18 +160,18 @@ . += "
" . += "CRIMINAL: [criminal]

" - . += "[criminal] was found guilty of the following crimes on [time2text(world.realtime, "DD/MMM")]/[game_year]. " + . += "[criminal] was found guilty of the following crimes on [game_year]-[time2text(world.realtime, "MMM-DD")].
" - if( !brig_sentence && !prison_sentence ) - . += "As decided by the arbiter(s), they will serve no time for their crimes." - else + if( brig_sentence != 0 ) . += "As decided by the arbiter(s), they will serve the following sentence:
" - if( brig_sentence ) - if( brig_sentence >= PERMABRIG_SENTENCE ) - . += "\tBRIG: Holding until transfer
" - else - . += "\tBRIG: [brig_sentence] minutes
" - + if( brig_sentence >= PERMABRIG_SENTENCE ) + . += "\tBRIG: Holding until transfer
" + else + . += "\tBRIG: [brig_sentence] minutes
" + else if ( fine != 0 ) + . += "As decided by the arbiter(s), they have been fined [fine] credits.
" + else + . += "As decided by the arbiter(s), they will serve no time for their crimes.
" . += "
" . += "" for( var/datum/law/L in charges ) diff --git a/code/modules/law/law.dm b/code/modules/law/law.dm index 042922915fb..de2fb1732a9 100644 --- a/code/modules/law/law.dm +++ b/code/modules/law/law.dm @@ -30,4 +30,22 @@ $PRISONER_NAME was found guilty of $CRIME on $DATE. Their sentence was $SENTENCE var/max_prison_time = 0 A sentence totalling 60 days or more is a life sentence*/ var/severity = 0 // 1 - Low, 2 - Medium, 3 - High - var/felony = 0 // Does this law carry a felony conviction? \ No newline at end of file + var/felony = 0 // Does this law carry a felony conviction? + +/datum/law/proc/can_fine() + if(max_fine == 0) + return FALSE + return TRUE + +/datum/law/proc/get_fine_string() + if(max_fine == 0) + return "n.a." + return "[min_fine] - [max_fine] cR" + +/datum/law/proc/get_brig_time_string() + if(min_brig_time >= PERMABRIG_SENTENCE) + return "HuT" + if(max_brig_time >= PERMABRIG_SENTENCE) + return "[min_brig_time] minutes - HuT" + else + return "[min_brig_time] - [max_brig_time] minutes" \ No newline at end of file diff --git a/code/modules/lighting/lighting_corner.dm b/code/modules/lighting/lighting_corner.dm index 2244eac44b0..85f227c6745 100644 --- a/code/modules/lighting/lighting_corner.dm +++ b/code/modules/lighting/lighting_corner.dm @@ -11,16 +11,20 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1) /datum/lighting_corner var/turf/t1 // These are in no particular order. + var/t1i // Our index in this turf's corners list. var/turf/t2 + var/t2i var/turf/t3 + var/t3i var/turf/t4 + var/t4i var/list/datum/light_source/affecting // Light sources affecting us. var/active = FALSE // TRUE if one of our masters has dynamic lighting. - var/x = 0 - var/y = 0 - var/z = 0 + var/x = 0 + var/y = 0 + var/z = 0 var/lum_r = 0 var/lum_g = 0 @@ -34,11 +38,12 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1) var/cache_b = LIGHTING_SOFT_THRESHOLD var/cache_mx = 0 -/datum/lighting_corner/New(var/turf/new_turf, var/diagonal) +/datum/lighting_corner/New(turf/new_turf, diagonal) SSlighting.lighting_corners += src t1 = new_turf z = new_turf.z + t1i = REVERSE_LIGHTING_CORNER_DIAGONAL[diagonal] var/vertical = diagonal & ~(diagonal - 1) // The horizontal directions (4 and 8) are bigger than the vertical ones (1 and 2), so we can reliably say the lsb is the horizontal direction. var/horizontal = diagonal & ~vertical // Now that we know the horizontal one we can get the vertical one. @@ -60,6 +65,7 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1) t2 = T i = REVERSE_LIGHTING_CORNER_DIAGONAL[diagonal] + t2i = i T.corners[i] = src // Now the horizontal one. @@ -70,6 +76,7 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1) t3 = T i = REVERSE_LIGHTING_CORNER_DIAGONAL[((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH)] // Get the dir based on coordinates. + t3i = i T.corners[i] = src // And finally the vertical one. @@ -80,6 +87,7 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1) t4 = T i = REVERSE_LIGHTING_CORNER_DIAGONAL[((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH)] // Get the dir based on coordinates. + t4i = i T.corners[i] = src update_active() @@ -95,18 +103,21 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1) #undef OVERLAY_PRESENT // God that was a mess, now to do the rest of the corner code! Hooray! -/datum/lighting_corner/proc/update_lumcount(var/delta_r, var/delta_g, var/delta_b, var/delta_u, var/now = FALSE) +/datum/lighting_corner/proc/update_lumcount(delta_r, delta_g, delta_b, delta_u, now = FALSE) + if (!(delta_r + delta_g + delta_b)) // Don't check u since the overlay doesn't care about it. + return + lum_r += delta_r lum_g += delta_g lum_b += delta_b lum_u += delta_u - if (needs_update || !(delta_r + delta_g + delta_b)) // Don't check u since the overlay doesn't care about it. + // This needs to be down here instead of the above if so the lum values are properly updated. + if (needs_update) return if (!now) needs_update = TRUE - update_overlays(FALSE) SSlighting.corner_queue += src else update_overlays(TRUE) @@ -122,9 +133,60 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1) } \ } -/datum/lighting_corner/proc/update_overlays(var/now = FALSE) + +#define AVERAGE_BELOW_CORNER(Tt, Ti) \ + if (TURF_IS_MIMICING(Tt)) { \ + T = GET_BELOW(Tt); \ + if (T && T.corners && TURF_IS_DYNAMICALLY_LIT_UNSAFE(T)) { \ + C = T.corners[Ti]; \ + if (C) { \ + divisor += 1; \ + lr += C.lum_r; \ + lg += C.lum_g; \ + lb += C.lum_b; \ + } \ + } \ + } + +#define UPDATE_ABOVE_CORNER(Tt, Ti) \ + if (Tt) { \ + T = GET_ABOVE(Tt); \ + if (TURF_IS_MIMICING(T) && TURF_IS_DYNAMICALLY_LIT_UNSAFE(T)) { \ + if (!T.corners) { \ + T.generate_missing_corners(); \ + } \ + C = T.corners[Ti]; \ + if (C && !C.needs_update) { \ + C.update_overlays(FALSE); \ + } \ + } \ + } + +/datum/lighting_corner/proc/update_overlays(now = FALSE) + var/lr = lum_r + var/lg = lum_g + var/lb = lum_b + +#ifdef USE_CORNER_ZBLEED + + var/divisor = 1 + var/datum/lighting_corner/C + var/turf/T + + AVERAGE_BELOW_CORNER(t1, t1i) + AVERAGE_BELOW_CORNER(t2, t2i) + AVERAGE_BELOW_CORNER(t3, t3i) + AVERAGE_BELOW_CORNER(t4, t4i) + + if (divisor > 1) + lr /= divisor + lg /= divisor + lb /= divisor + +#endif + // Cache these values a head of time so 4 individual lighting overlays don't all calculate them individually. - var/mx = max(lum_r, lum_g, lum_b) // Scale it so 1 is the strongest lum, if it is above 1. + var/mx = max(lr, lg, lb) // Scale it so 1 is the strongest lum, if it is above 1. . = 1 // factor if (mx > 1) . = 1 / mx @@ -132,9 +194,13 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1) else if (mx < LIGHTING_SOFT_THRESHOLD) . = 0 // 0 means soft lighting. - cache_r = round(lum_r * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD - cache_g = round(lum_g * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD - cache_b = round(lum_b * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD + if (.) + cache_r = round(lr * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD + cache_g = round(lg * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD + cache_b = round(lb * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD + else + cache_r = cache_g = cache_b = LIGHTING_SOFT_THRESHOLD + cache_mx = round(mx, LIGHTING_ROUND_VALUE) UPDATE_MASTER(t1) @@ -142,7 +208,18 @@ var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1) UPDATE_MASTER(t3) UPDATE_MASTER(t4) +#ifdef USE_CORNER_ZBLEED + + UPDATE_ABOVE_CORNER(t1, t1i) + UPDATE_ABOVE_CORNER(t2, t2i) + UPDATE_ABOVE_CORNER(t3, t3i) + UPDATE_ABOVE_CORNER(t4, t4i) + +#endif + #undef UPDATE_MASTER +#undef AVERAGE_BELOW_CORNER +#undef UPDATE_ABOVE_CORNER /datum/lighting_corner/Destroy(force = FALSE) crash_with("Some fuck [force ? "force-" : ""]deleted a lighting corner.") diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm index b9515df3774..2e4848b8d60 100644 --- a/code/modules/lighting/lighting_source.dm +++ b/code/modules/lighting/lighting_source.dm @@ -355,12 +355,7 @@ var/test_x var/test_y - var/zlights_going_up = FALSE - var/turf/originalT // This is needed to reset our search point for bidirectional Z-lights. - - FOR_DVIEW(originalT, Ceiling(actual_range), source_turf, 0) - T = originalT - zlights_going_up = FALSE + FOR_DVIEW(T, Ceiling(actual_range), source_turf, 0) check_t: if (light_angle && !facing_opaque) // Directional lighting coordinate filter. @@ -371,7 +366,7 @@ if ((PSEUDO_WEDGE(limit_a_x, limit_a_y, test_x, test_y) > 0) || (PSEUDO_WEDGE(test_x, test_y, limit_b_x, limit_b_y) > 0)) continue - if (T.dynamic_lighting || T.light_sources) + if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(T) || T.light_sources) Tcorners = T.corners if (!T.lighting_corners_initialised) T.lighting_corners_initialised = TRUE @@ -396,19 +391,10 @@ // Note: above is defined on ALL turfs, but below is only defined on OPEN TURFS. - zlight_check: - if (zlights_going_up) // If we're searching upwards, check above. - if (istype(T.above)) // We escape the goto loop if this condition is false. - T = T.above - goto check_t - else - if (T && (T.flags & MIMIC_BELOW) && T.below) // Not searching upwards and we have a below turf. - T = T.below // Consider the turf below us as well. (Z-lights) - goto check_t - else // Not searching upwards and we don't have a below turf. - zlights_going_up = TRUE - T = originalT - goto zlight_check + // Upwards lights are handled at the corner level, so only search down. + if (T && (T.flags & MIMIC_BELOW) && T.below) + T = T.below + goto check_t END_FOR_DVIEW diff --git a/code/modules/lighting/lighting_source_sunlight.dm b/code/modules/lighting/lighting_source_sunlight.dm index ec3ed80d026..bd0c3e0f5e7 100644 --- a/code/modules/lighting/lighting_source_sunlight.dm +++ b/code/modules/lighting/lighting_source_sunlight.dm @@ -73,7 +73,7 @@ check_t: - if (T.dynamic_lighting || T.light_sources) + if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(T) || T.light_sources) Tcorners = T.corners if (!T.lighting_corners_initialised) T.lighting_corners_initialised = TRUE diff --git a/code/modules/lighting/lighting_verbs.dm b/code/modules/lighting/lighting_verbs.dm index 2cae09c5fbd..c14e2aaca90 100644 --- a/code/modules/lighting/lighting_verbs.dm +++ b/code/modules/lighting/lighting_verbs.dm @@ -49,7 +49,7 @@ var/list/admin_verbs_lighting = list( if (!check_rights(R_DEBUG|R_DEV)) return - if (!T.dynamic_lighting) + if (TURF_IS_DYNAMICALLY_LIT(T)) src << "That turf is not dynamically lit." return diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm index 2ba613a389d..04d9ebd32e0 100644 --- a/code/modules/mining/abandonedcrates.dm +++ b/code/modules/mining/abandonedcrates.dm @@ -104,7 +104,7 @@ if(87) new/obj/item/xenos_claw(src) if(88) - new/obj/item/weapon/gun/projectile/boltaction(src) + new/obj/item/weapon/gun/projectile/shotgun/pump/rifle(src) new/obj/item/ammo_magazine/boltaction(src) new/obj/item/clothing/under/soviet(src) new/obj/item/clothing/head/ushanka(src) @@ -113,7 +113,7 @@ if(90) new/obj/item/organ/heart(src) if(91) - new/obj/item/device/soulstone(src) + new/obj/item/poppet(src) if(92) new/obj/item/weapon/material/sword/katana(src) if(93) diff --git a/code/modules/mob/abstract/new_player/sprite_accessories.dm b/code/modules/mob/abstract/new_player/sprite_accessories.dm index 3a5f57cdd65..73b93c9f33c 100644 --- a/code/modules/mob/abstract/new_player/sprite_accessories.dm +++ b/code/modules/mob/abstract/new_player/sprite_accessories.dm @@ -618,11 +618,6 @@ icon_state = "hair_hightight" gender = MALE - regulationmohawk - name = "Shaved Mohawk" - icon_state = "hair_shavedmohawk" - gender = MALE - topknot name = "Topknot" icon_state = "hair_topknot" @@ -658,6 +653,46 @@ icon_state = "hair_manbun" gender = MALE + shavedbun + name = "Shaved Bun" + icon_state = "hair_shavedbun" + + halfshaved + name = "Half-Shaved" + icon_state = "hair_halfshaved" + + halfshavedemo + name = "Half-Shaved Emo" + icon_state = "hair_halfshavedemo" + + longsideemo + name = "Long Side Emo" + icon_state = "hair_longsideemo" + + sideswept + name = "Sideswept Hair" + icon_state = "hair_sideswept" + + mohawkshaved + name = "Shaved Mohawk" + icon_state = "hair_mohawkshaved" + + mohawkshaved2 + name = "Tight Shaved Mohawk" + icon_state = "hair_mohawkshaved2" + + mohawkshavednaomi + name = "Naomi Mohawk" + icon_state = "hair_mohawkshavednaomi" + + leftsidecut + name = "Left Sidecut" + icon_state = "hair_leftside" + + rightsidecut + name = "Right Sidecut" + icon_state = "hair_rightside" + // TG-format hair - uses ICON_MULTIPLY instead of ICON_ADD uniter icon = 'icons/mob/human_face/hair_multiply.dmi' diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index 1b5702329e6..eaa53ea72ad 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -37,7 +37,7 @@ message = pick(S.speak) else if(language) - message = language.scramble(message) + message = language.scramble(message, languages) else message = stars(message) @@ -107,7 +107,7 @@ return else if(language) - message = language.scramble(message) + message = language.scramble(message, languages) else message = stars(message) diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm index 074935a613f..3ef9e8dddc2 100644 --- a/code/modules/mob/language/language.dm +++ b/code/modules/mob/language/language.dm @@ -18,6 +18,7 @@ var/native // If set, non-native speakers will have trouble speaking. var/list/syllables // Used when scrambling text for a non-speaker. var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string + var/list/partial_understanding // List of languages that can /somehwat/ understand it, format is: name = chance of understanding a word /datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4, syllable_divisor=2) if(!syllables || !syllables.len) @@ -40,8 +41,41 @@ /datum/language var/list/scramble_cache = list() -/datum/language/proc/scramble(var/input) +/datum/language/proc/scramble(var/input, var/list/known_languages) + var/understand_chance = 0 + for(var/datum/language/L in known_languages) + if(partial_understanding && partial_understanding[L.name]) + understand_chance += partial_understanding[L.name] + if(L.partial_understanding && L.partial_understanding[name]) + understand_chance += L.partial_understanding[name] * 0.5 + + var/scrambled_text = "" + var/list/words = splittext(input, " ") + for(var/w in words) + if(prob(understand_chance)) + scrambled_text += " [w] " + else + var/nword = scramble_word(w) + var/ending = copytext(scrambled_text, length(scrambled_text)-1) + if(findtext(ending,".")) + nword = capitalize(nword) + scrambled_text += nword + scrambled_text = replacetext(scrambled_text," "," ") + + scrambled_text = capitalize(scrambled_text) + scrambled_text = trim(scrambled_text) + var/ending = copytext(scrambled_text, length(scrambled_text)) + if(ending == ".") + scrambled_text = copytext(scrambled_text,1,length(scrambled_text)-1) + + var/input_ending = copytext(input, length(input)) + if(input_ending in list("!","?",".")) + scrambled_text += input_ending + + return scrambled_text + +/datum/language/proc/scramble_word(var/input) if(!syllables || !syllables.len) return stars(input) @@ -54,7 +88,7 @@ var/input_size = length(input) var/scrambled_text = "" - var/capitalize = 1 + var/capitalize = 0 while(length(scrambled_text) < input_size) var/next = pick(syllables) @@ -69,14 +103,6 @@ else if(chance > 5 && chance <= space_chance) scrambled_text += " " - scrambled_text = trim(scrambled_text) - var/ending = copytext(scrambled_text, length(scrambled_text)) - if(ending == ".") - scrambled_text = copytext(scrambled_text,1,length(scrambled_text)-1) - var/input_ending = copytext(input, input_size) - if(input_ending in list("!","?",".")) - scrambled_text += input_ending - // Add it to cache, cutting old entries if the list is too long scramble_cache[input] = scrambled_text if(scramble_cache.len > SCRAMBLE_CACHE_LEN) diff --git a/code/modules/mob/language/station.dm b/code/modules/mob/language/station.dm index cdd0e66d1b1..d328bb80f1e 100644 --- a/code/modules/mob/language/station.dm +++ b/code/modules/mob/language/station.dm @@ -39,11 +39,12 @@ "ra", "ar", "re", "er", "ri", "ir", "ro", "or", "ru", "ur", "rs", "sr", "a", "a", "e", "e", "i", "i", "o", "o", "u", "u", "s", "s" ) + partial_understanding = list(LANGUAGE_AZAZIBA = 25) // tajaran languages /datum/language/tajaran name = LANGUAGE_SIIK_MAAS - desc = "The traditionally employed tongue of Adhomai, composed of expressive yowls and chirps. Native to the Tajaran." + desc = "The traditionally employed tongue of Adhomai, composed of expressive yowls and chirps. Native to the Tajara." speech_verb = "mrowls" ask_verb = "mrowls" exclaim_verb = "yowls" @@ -54,6 +55,7 @@ "mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r", "ka","aasi","far","wa","baq","ara","qara","zir","sam","mak","hrar","nja","rir","khan","jun","dar","rik","kah", "hal","ket","jurl","mah","tul","cresh","azu","ragh","mro","mra","mrro","mrra") + partial_understanding = list(LANGUAGE_SIIK_TAJR = 50, LANGUAGE_YA_SSA = 25, LANGUAGE_DELVAHII = 50) /datum/language/tajaran/get_random_name(var/gender) @@ -74,6 +76,7 @@ colour = "i" key = "i" flags = NO_STUTTER | SIGNLANG | WHITELISTED + partial_understanding = list(LANGUAGE_SIIK_TAJR = 50) /datum/language/siik_tajr name = LANGUAGE_SIIK_TAJR @@ -89,6 +92,7 @@ "mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r", "ka","aasi","far","wa","baq","ara","qara","zir","sam","mak","hrar","nja","rir","khan","jun","dar","rik","kah", "hal","ket","jurl","mah","tul","cresh","azu","ragh","mro","mra","mrro","mrra") + partial_understanding = list(LANGUAGE_SIIK_MAAS = 50, LANGUAGE_SIGN_TAJARA = 25) /datum/language/yassa name = LANGUAGE_YA_SSA @@ -103,6 +107,22 @@ "mi","jhri","dynher","manqi","rhas","shar","drhaz","kalh","shur","echi","tha","draer","jurl","maher","sanii","dra","ii'r", "kan","aesi","fare","we","bash","arha","quara","zhir","sem","make","hrer","nja","rir","can","jhun","dar","rik","kah", "hal","kete","juril","mah","tul","cresh","azu","ragh","miro","mara","mrero","mrara") + partial_understanding = list(LANGUAGE_SIIK_MAAS = 50) + +/datum/language/delvahhi + name = LANGUAGE_DELVAHII + desc = "A dialect developed by the Zhan-Khazan communities, commonly used in religious ceremonies dedicated to the Snow God and amongst settlements comprised mostly of Zhan-Khazan." + speech_verb = "mrowls" + ask_verb = "mrowls" + exclaim_verb = "yowls" + colour = "delvahhi" + key = "n" + flags = WHITELISTED + syllables = list("hrr","rhr","tarj","khir","rajh","kir","mier","kre","ahek","nlhal","veh","khaz","dri","rhan","darrer", + "mi","jhri","dynher","manqi","rhas","shar","drhaz","kalh","shur","echi","tha","draer","jurl","maher","sanii","dra","ii'r", + "kan","aesi","fare","we","bash","arha","quara","zhir","sem","make","hrer","nja","rir","can","jhun","dar","rik","kah", + "hal","kete","juril","mah","tul","cresh","azu","ragh","miro","mara","mrero","mrara") + partial_understanding = list(LANGUAGE_SIIK_MAAS = 50) /datum/language/skrell name = LANGUAGE_SKRELLIAN @@ -259,6 +279,7 @@ key = "p" flags = WHITELISTED | NONVERBAL syllables = list("azs","zis","zau","azua","skiu","zuakz","izo","aei","ki","kut","zo") + partial_understanding = list(LANGUAGE_UNATHI = 50) //Syllable Lists /* diff --git a/code/modules/mob/living/autohiss.dm b/code/modules/mob/living/autohiss.dm index 9763c6bb5bf..ee260c45ab1 100644 --- a/code/modules/mob/living/autohiss.dm +++ b/code/modules/mob/living/autohiss.dm @@ -62,7 +62,8 @@ LANGUAGE_SIIK_MAAS, LANGUAGE_SIIK_TAJR, LANGUAGE_SIGN_TAJARA, - LANGUAGE_YA_SSA + LANGUAGE_YA_SSA, + LANGUAGE_DELVAHII ) /datum/species/bug diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index 7e62327706d..2ba8d73bf97 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -4,7 +4,7 @@ icon_state = "secbot0" maxHealth = 50 health = 50 - req_one_access = list(access_security, access_forensics_lockers) + req_one_access = list(access_security, access_forensics_lockers, access_weapons) botcard_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels) var/mob/target diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index c0eb7946a01..ca2818062dc 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -27,7 +27,7 @@ //the second is the message in question. var/last_taste_time = 0 var/last_taste_text = "" - + var/last_smell_time = 0 var/last_smell_text = "" diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index e5b9ab34f16..3e1bf0d9e26 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -649,7 +649,7 @@ message = "buzzes." playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) m_type = 1 - + if("vomit") if (!check_has_mouth(src)) src << "You are unable to vomit." diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 04201d9e101..13ce241cac1 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -219,9 +219,9 @@ if (!(src.species.flags & NO_CHUBBY)) - if(nutrition < 100) + if(nutrition < max(max_nutrition - 300, 0)) msg += "[T.He] [T.is] severely malnourished.\n" - else if(nutrition >= 500) + else if(nutrition >= max_nutrition + 100) msg += "[T.He] [T.is] quite chubby.\n" diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index 58096264bcb..a603e34c8b9 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -29,7 +29,7 @@ log_debug("Organ [DEBUG_REF(src)] was not properly removed from its parent!") internal_organs -= I continue - + I.process() handle_stance() @@ -173,3 +173,7 @@ var/list/all_bits = internal_organs|organs for(var/obj/item/organ/O in all_bits) O.set_dna(dna) + +/mob/living/carbon/human/proc/get_blood_alcohol() + return round(intoxication/max(vessel.get_reagent_amount("blood"),1),0.01) + diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 50ddb565ad1..e58932eaa83 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -549,7 +549,7 @@ 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) src << "The destination is too bright." return diff --git a/code/modules/mob/living/carbon/human/intoxication.dm b/code/modules/mob/living/carbon/human/intoxication.dm index 127ea18c52d..8a924ce3f28 100644 --- a/code/modules/mob/living/carbon/human/intoxication.dm +++ b/code/modules/mob/living/carbon/human/intoxication.dm @@ -1,25 +1,9 @@ -#define AE_DIZZY 5 -#define AE_BUZZED_MIN 6 -#define AE_SLURRING 15 -#define AE_CONFUSION 18 -#define AE_CLUMSY 22 -#define AE_BUZZED_MAX 24 -#define AE_BLURRING 25 -#define AE_VOMIT 40 -#define AE_DROWSY 55 -#define AE_OVERDOSE 70 -#define AE_BLACKOUT 80 - -#define BASE_DIZZY 100 - -#define ALCOHOL_FILTRATION_RATE 0.015//The base rate at which intoxication decreases per proc. this is actually multiplied by 3 most of the time if the liver is healthy -#define BASE_VOMIT_CHANCE 2 -#define VOMIT_CHANCE_SCALE 0.2//An extra 1% for every 5 units over the vomiting threshold - var/mob/living/carbon/human/alcohol_clumsy = 0 //This proc handles the effects of being intoxicated. Removal of intoxication is done elswhere: By the liver, in organ_internal.dm /mob/living/carbon/human/proc/handle_intoxication() + + var/SR = species.ethanol_resistance if (SR == -1) //This species can't get drunk, how did we even get here? @@ -37,58 +21,72 @@ var/mob/living/carbon/human/alcohol_clumsy = 0 sleeping = 0 //Many of these parameters normally tick down in life code, but some parts of that code don't run in godmode, so this prevents a BST being stuck with blurred vision - if(intoxication > AE_DIZZY*SR) // Early warning + var/bac = get_blood_alcohol() + + if(bac > INTOX_BUZZED*SR && bac < INTOX_MUSCLEIMP*SR && !(locate(/datum/modifier/buzzed) in modifiers)) + to_chat(src,"You feel buzzed.") + add_modifier(/datum/modifier/buzzed, MODIFIER_CUSTOM) + + if(bac > INTOX_JUDGEIMP*SR) if (dizziness == 0) - src << "The room starts spinning!" - var/target_dizziness = min(1000,(BASE_DIZZY + ((intoxication - AE_DIZZY*SR)*10)/SR)) - make_dizzy(target_dizziness - dizziness) // We will repeatedly set our target dizziness to a desired value based on intoxication level + to_chat(src,"You feel a little tipsy.") + var/target_dizziness = BASE_DIZZY + ((bac - INTOX_JUDGEIMP*SR)*DIZZY_ADD_SCALE*100) + make_dizzy(target_dizziness - dizziness) - if(intoxication > AE_SLURRING*SR) // Slurring - slurring = max(slurring, 30) + if(bac > INTOX_MUSCLEIMP*SR) + slurring = max(slurring, 25) + if (!(locate(/datum/modifier/drunk) in modifiers)) + to_chat(src,"You feel drunk!") + add_modifier(/datum/modifier/drunk, MODIFIER_CUSTOM) - if(intoxication > AE_CONFUSION*SR) // Confusion - walking in random directions + if(bac > INTOX_REACTION*SR) if (confused == 0) - src << "You feel unsteady on your feet!" - confused = max(confused, 20) - - //Make the drinker temporarily clumsy if intoxication is high enough - //We use a var to track if alcohol caused it, we won't add nor remove it if the drinker was already clumsy from some other source - if(intoxication > AE_CLUMSY*SR) + to_chat(src,"You feel uncoordinated and unsteady on your feet!") + confused = max(confused, 10) + slurring = max(slurring, 50) if (!alcohol_clumsy && !(CLUMSY in mutations)) - src << "You feel a bit clumsy and uncoordinated." mutations.Add(CLUMSY) alcohol_clumsy = 1 - else //Remove it if intoxication drops too low. We'll also have another check to remove it in life.dm - if (alcohol_clumsy) - src << "You feel more sober and steady" - mutations.Remove(CLUMSY) - alcohol_clumsy = 0 + else if (alcohol_clumsy) + to_chat(src,"You feel more sober and steady.") + mutations.Remove(CLUMSY) + alcohol_clumsy = 0 - if(intoxication > AE_BLURRING*SR) // Blurry vision - if (prob(10))//blurry vision effect is annoying, so nerfing it - eye_blurry = max(eye_blurry, 2) - adjustBrainLoss(1, 15) - - if(intoxication > AE_DROWSY*SR) // Drowsyness - periodically falling asleep - drowsyness = max(drowsyness, 20) - - if(intoxication > AE_VOMIT*SR)//Vomiting, the body's natural defense mechanism against poisoning. - if (life_tick % 4 == 1)//Only process vomit chance periodically - var/chance = BASE_VOMIT_CHANCE + ((intoxication - AE_VOMIT)*VOMIT_CHANCE_SCALE) + if(bac > INTOX_VOMIT*SR) + slurring = max(slurring, 75) + if (life_tick % 4 == 1) + var/chance = BASE_VOMIT_CHANCE + ((bac - INTOX_VOMIT*SR)*VOMIT_CHANCE_SCALE*100) if (prob(chance)) delayed_vomit() + add_chemical_effect(CE_ALCOHOL_TOXIC, 1) - if(intoxication > AE_OVERDOSE*SR) // Toxic dose - add_chemical_effect(CE_ALCOHOL_TOXIC, 1) - adjustBrainLoss(0.4, 55) + if(bac > INTOX_BALANCE*SR) + slurring = max(slurring, 100) + if (life_tick % 4 == 1 && !lying && !buckled && prob(10)) + src.visible_message("[src] loses balance and falls to the ground!","You lose balance and fall to the ground!") + Paralyse(3 SECONDS) + if(bac > INTOX_CONSCIOUS*SR) + slurring = max(slurring, 90) + src.visible_message("[src] loses consciousness!","You lose consciousness!") + paralysis = max(paralysis, 60 SECONDS) + sleeping = max(sleeping, 60 SECONDS) + adjustBrainLoss(5,30) + else if(bac > INTOX_BLACKOUT*SR) + slurring = max(slurring, 80) + src.visible_message("[src] blackouts!","You blackout!") + paralysis = max(paralysis, 20 SECONDS) + sleeping = max(sleeping, 20 SECONDS) + adjustBrainLoss(3,10) + else if(prob(10)) + slurring = max(slurring, 70) + to_chat(src,"You decide that you like the ground and spend a few seconds to rest.") + sleeping = max(sleeping, 6 SECONDS) + adjustBrainLoss(1,5) - if(intoxication > AE_BLACKOUT*SR) // Pass out - paralysis = max(paralysis, 20) - sleeping = max(sleeping, 30) - adjustBrainLoss(0.4, 55) - - if( intoxication >= AE_BUZZED_MIN && intoxication <= AE_BUZZED_MAX && !(locate(/datum/modifier/buzzed) in modifiers)) - add_modifier(/datum/modifier/buzzed, MODIFIER_CUSTOM) + if (bac > INTOX_DEATH*SR && !src.reagents.has_reagent("ethylredoxrazine")) //Death usually occurs here + add_chemical_effect(CE_ALCOHOL_TOXIC, 10) + adjustOxyLoss(3,100) + adjustBrainLoss(1,50) //Pleasant feeling from being slightly drunk @@ -98,36 +96,50 @@ var/mob/living/carbon/human/alcohol_clumsy = 0 /datum/modifier/buzzed/activate() ..() - if (ishuman(target)) - var/mob/living/carbon/human/H = target + var/mob/living/carbon/human/H = target + if(istype(H)) H.move_delay_mod += -0.75 - H.sprint_cost_factor += -0.1 /datum/modifier/buzzed/deactivate() ..() - if (ishuman(target)) - var/mob/living/carbon/human/H = target + var/mob/living/carbon/human/H = target + if(istype(H)) H.move_delay_mod -= -0.75 - H.sprint_cost_factor -= -0.1 /datum/modifier/buzzed/custom_validity() - if (ishuman(target)) - var/mob/living/carbon/human/H = target - if (H.intoxication >= AE_BUZZED_MIN && H.intoxication <= AE_BUZZED_MAX) + var/mob/living/carbon/human/H = target + if(!istype(H)) + return 0 + var/bac = H.get_blood_alcohol() + if(bac >= INTOX_BUZZED*H.species.ethanol_resistance && bac <= INTOX_MUSCLEIMP*H.species.ethanol_resistance) + return 1 + + return 0 + +/datum/modifier/drunk + +/datum/modifier/drunk/activate() + ..() + var/mob/living/carbon/human/H = target + if(istype(H)) + H.move_delay_mod += 2 + H.sprint_cost_factor += 0.2 + +/datum/modifier/drunk/deactivate() + ..() + var/mob/living/carbon/human/H = target + if(istype(H)) + H.move_delay_mod -= 2 + H.sprint_cost_factor -= -0.2 + +/datum/modifier/drunk/custom_validity() + var/mob/living/carbon/human/H = target + if(istype(H)) + return 0 + if(H.get_blood_alcohol() >= INTOX_MUSCLEIMP*H.species.ethanol_resistance) + return 1 - return 1 return 0 -#undef AE_DIZZY -#undef AE_BUZZED_MIN -#undef AE_SLURRING -#undef AE_CONFUSION -#undef AE_CLUMSY -#undef AE_BUZZED_MAX -#undef AE_BLURRING -#undef AE_VOMIT -#undef AE_DROWSY -#undef AE_OVERDOSE -#undef AE_BLACKOUT \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index d00d4e65822..4367b398ef3 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1287,7 +1287,7 @@ //0.1% chance of playing a scary sound to someone who's in complete darkness if(isturf(loc) && rand(1,1000) == 1) var/turf/T = loc - if(T.dynamic_lighting && T.get_lumcount() < 0.01) // give a little bit of tolerance for near-dark areas. + if(T.get_lumcount() < 0.01) // give a little bit of tolerance for near-dark areas. playsound_local(src,pick(scarySounds),50, 1, -1) /mob/living/carbon/human/proc/handle_changeling() diff --git a/code/modules/mob/living/carbon/human/species/station/tajaran_subspecies.dm b/code/modules/mob/living/carbon/human/species/station/tajaran_subspecies.dm index 58e3166b53c..f59d189a5e2 100644 --- a/code/modules/mob/living/carbon/human/species/station/tajaran_subspecies.dm +++ b/code/modules/mob/living/carbon/human/species/station/tajaran_subspecies.dm @@ -9,7 +9,7 @@ from their fellow Tajara who cite their lackluster test scores, even among Tajara, and their higher \ crime rates." - secondary_langs = list(LANGUAGE_SIIK_MAAS, LANGUAGE_SIIK_TAJR) + secondary_langs = list(LANGUAGE_SIIK_MAAS, LANGUAGE_SIIK_TAJR, LANGUAGE_DELVAHII) slowdown = -0.8 //As opposed to -1 for Base tajara sprint_speed_factor = 0.55 // As opposed to 0.65 diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 63aafdf98f6..c87fdc5483f 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -97,7 +97,7 @@ proc/get_radio_key_from_channel(var/channel) verb = pick("yells","roars","hollers") speech_problem_flag = 1 if(slurring) - message = slur(message) + message = slur(message,slurring) verb = pick("slobbers","slurs") speech_problem_flag = 1 if(stuttering) @@ -105,11 +105,11 @@ proc/get_radio_key_from_channel(var/channel) verb = pick("stammers","stutters") speech_problem_flag = 1 if(tarded) - message = slur(message) + message = slur(message,100) verb = pick("gibbers","gabbers") speech_problem_flag = 1 if(brokejaw) - message = slur(message) + message = slur(message,100) verb = pick("slobbers","slurs") speech_problem_flag = 1 if(prob(50)) diff --git a/code/modules/mob/living/silicon/robot/presets.dm b/code/modules/mob/living/silicon/robot/presets.dm index 3f89ba7934c..00c724d7d44 100644 --- a/code/modules/mob/living/silicon/robot/presets.dm +++ b/code/modules/mob/living/silicon/robot/presets.dm @@ -9,7 +9,7 @@ scrambledcodes = 1 lawupdate = 0 lawpreset = /datum/ai_laws/nanotrasen_aggressive - idcard_type = /obj/item/weapon/card/id/centcom/ERT + idcard_type = /obj/item/weapon/card/id/ert key_type = /obj/item/device/encryptionkey/ert /mob/living/silicon/robot/combat/ert/init() diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index af885b34d19..ebaf3a715a2 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -564,8 +564,8 @@ var/global/list/robot_modules = list( /obj/item/weapon/robot_module/janitor name = "custodial robot module" - channels = list("Engineering" = 1) - networks = list(NETWORK_ENGINEERING) + channels = list("Service" = 1) + networks = list(NETWORK_SERVICE) sprites = list( "Basic" = "robotjani", "Mopbot" = "janitorrobot", @@ -601,6 +601,7 @@ var/global/list/robot_modules = list( /obj/item/weapon/robot_module/clerical name = "service robot module" channels = list("Service" = 1) + networks = list(NETWORK_SERVICE) languages = list( LANGUAGE_SOL_COMMON = 1, LANGUAGE_TRADEBAND = 1, @@ -719,6 +720,7 @@ var/global/list/robot_modules = list( /obj/item/weapon/robot_module/research name = "research module" channels = list("Science" = 1) + networks = list(NETWORK_RESEARCH) sprites = list( "Droid" = "droid-science", "Drone" = "drone-science", diff --git a/code/modules/mob/living/simple_animal/borer/borer_powers.dm b/code/modules/mob/living/simple_animal/borer/borer_powers.dm index 3df3d27991c..bba3c6fdada 100644 --- a/code/modules/mob/living/simple_animal/borer/borer_powers.dm +++ b/code/modules/mob/living/simple_animal/borer/borer_powers.dm @@ -9,13 +9,12 @@ if(stat) src << "You cannot leave your host in your current state." + return if(docile) src << "You are feeling far too docile to do that." return - if(!host || !src) return - src << "You begin disconnecting from [host]'s synapses and prodding at their internal ear canal." if(!host.stat) @@ -76,6 +75,7 @@ var/obj/item/organ/external/E = H.organs_by_name["head"] if(!E || E.is_stump()) src << "\The [H] does not have a head!" + return if(!H.species.has_organ["brain"]) src << "\The [H] does not seem to have an ear canal to breach." @@ -130,7 +130,6 @@ src << "They are no longer in range!" return - /mob/living/simple_animal/borer/verb/devour_brain() set category = "Abilities" set name = "Devour Brain" @@ -140,18 +139,18 @@ src << "You are not inside a host body." return + if(stat) + src << "You cannot do that in your current state." + return + if(host.stat != 2) src << "Your host is still alive." return - if(stat) - src << "You cannot do that in your current state." - if(docile) src << "You are feeling far too docile to do that." return - src << "It only takes a few moments to render the dead host brain down into a nutrient-rich slurry..." replace_brain() @@ -214,6 +213,7 @@ if(stat) src << "You cannot secrete chemicals in your current state." + return if(docile) src << "You are feeling far too docile to do that." @@ -221,10 +221,11 @@ if(chemicals < 50) src << "You don't have enough chemicals!" + return var/chem = input("Select a chemical to secrete.", "Chemicals") as null|anything in list("alkysine","bicaridine","hyperzine","tramadol") - if(!chem || chemicals < 50 || !host || controlling || !src || stat) //Sanity check. + if(!chem || docile || chemicals < 50 || !host || controlling || !src || stat) //Sanity check. return src << "You squirt a measure of [chem] from your reservoirs into [host]'s bloodstream." diff --git a/code/modules/mob/living/simple_animal/hostile/commanded/commanded.dm b/code/modules/mob/living/simple_animal/hostile/commanded/commanded.dm index 5aab4a5e0a7..5fcac67d5a3 100644 --- a/code/modules/mob/living/simple_animal/hostile/commanded/commanded.dm +++ b/code/modules/mob/living/simple_animal/hostile/commanded/commanded.dm @@ -4,12 +4,18 @@ melee_damage_lower = 0 melee_damage_upper = 0 density = 0 + var/short_name = null var/list/command_buffer = list() var/list/known_commands = list("stay", "stop", "attack", "follow") var/mob/master = null //undisputed master. Their commands hold ultimate sway and ultimate power. var/list/allowed_targets = list() //WHO CAN I KILL D: var/retribution = 1 //whether or not they will attack us if we attack them like some kinda dick. +/mob/living/simple_animal/hostile/commanded/Initialize() + ..() + if(!short_name) + short_name = name + /mob/living/simple_animal/hostile/commanded/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol) if(thinking_enabled && !stat && ((speaker in friends) || speaker == master)) command_buffer.Add(speaker) @@ -27,7 +33,8 @@ var/mob/speaker = command_buffer[1] var/text = command_buffer[2] var/filtered_name = lowertext(html_decode(name)) - if(dd_hasprefix(text,filtered_name) || dd_hasprefix(text,"everyone") || dd_hasprefix(text, "everybody")) //in case somebody wants to command 8 bears at once. + var/filtered_short = lowertext(html_decode(short_name)) + if(dd_hasprefix(text,filtered_name) || dd_hasprefix(text,filtered_short) || dd_hasprefix(text,"everyone") || dd_hasprefix(text, "everybody")) //in case somebody wants to command 8 bears at once. var/substring = copytext(text,length(filtered_name)+1) //get rid of the name. listen(speaker,substring) command_buffer.Remove(command_buffer[1],command_buffer[2]) diff --git a/code/modules/mob/living/simple_animal/hostile/commanded/guard_dog.dm b/code/modules/mob/living/simple_animal/hostile/commanded/guard_dog.dm index 3e8e49c0964..af8c737a6aa 100644 --- a/code/modules/mob/living/simple_animal/hostile/commanded/guard_dog.dm +++ b/code/modules/mob/living/simple_animal/hostile/commanded/guard_dog.dm @@ -1,5 +1,6 @@ /mob/living/simple_animal/hostile/commanded/dog name = "guard dog" + short_name = "dog" desc = "A dog trained to listen and obey its owner commands, this one is a german shepherd." icon = 'icons/mob/dog.dmi' @@ -83,10 +84,13 @@ if(!name_changed) var/input = sanitizeSafe(input("What do you want to name the dog?", ,""), MAX_NAME_LEN) + var/short_input = sanitizeSafe(input("What nickname do you want to give the dog ?", , ""), MAX_NAME_LEN) if(src && input && !M.stat && in_range(M,src)) name = input real_name = input + if(short_input != "") + short_name = short_input name_changed = 1 return 1 @@ -103,6 +107,7 @@ /mob/living/simple_animal/hostile/commanded/dog/columbo name = "Lt. Columbo" + short_name = "Columbo" desc = "A dog trained to listen and obey its owner commands. This one looks about three days from retirement." melee_damage_lower = 5 diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index cfe3ca1f027..21bce1f0d1b 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -18,10 +18,13 @@ hunger_enabled = 0//Until automated eating mechanics are enabled, disable hunger for hostile mobs var/shuttletarget = null var/enroute = 0 + var/list/targets = list() + var/attacked_times = 0 /mob/living/simple_animal/hostile/Destroy() friends = null target_mob = null + targets = null return ..() /mob/living/simple_animal/hostile/proc/FindTarget() @@ -30,8 +33,10 @@ return null var/atom/T = null + var/lowest_health = 100 stop_automated_movement = 0 - for(var/atom/A in ListTargets(10)) + + for(var/atom/A in targets) if(A == src) continue @@ -45,33 +50,64 @@ var/mob/living/L = A if((L.faction == src.faction) && !attack_same) continue - else if(L in friends) + if(L in friends) continue - else - if(!L.stat) - stance = HOSTILE_STANCE_ATTACK - T = L - break + + if(!L.stat && (L.health < lowest_health)) + lowest_health = L.health + T = L + break else if(istype(A, /obj/mecha)) // Our line of sight stuff was already done in ListTargets(). var/obj/mecha/M = A if (M.occupant) - stance = HOSTILE_STANCE_ATTACK T = M break if(istype(A, /obj/machinery/bot)) var/obj/machinery/bot/B = A if (B.health > 0) - stance = HOSTILE_STANCE_ATTACK T = B break if (T != target_mob) target_mob = T FoundTarget() + if(!isnull(T)) + stance = HOSTILE_STANCE_ATTACK return T +/mob/living/simple_animal/hostile/bullet_act(var/obj/item/projectile/P, var/def_zone) + ..() + if (ismob(P.firer) && target_mob != P.firer) + target_mob = P.firer + stance = HOSTILE_STANCE_ATTACK + +/mob/living/simple_animal/hostile/attackby(var/obj/item/O, var/mob/user) + ..() + if(target_mob != user) + target_mob = user + stance = HOSTILE_STANCE_ATTACK + +mob/living/simple_animal/hostile/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)//Standardization and logging -Sieve + ..() + if(istype(AM,/obj/)) + var/obj/O = AM + if((target_mob != O.thrower) && ismob(O.thrower)) + target_mob = O.thrower + stance = HOSTILE_STANCE_ATTACK + +/mob/living/simple_animal/hostile/attack_generic(var/mob/user, var/damage, var/attack_message) + ..() + if(target_mob != user) + target_mob = user + stance = HOSTILE_STANCE_ATTACK + +/mob/living/simple_animal/hostile/attack_hand(mob/living/carbon/human/M as mob) + ..() + if(target_mob != M) + target_mob = M + stance = HOSTILE_STANCE_ATTACK //This proc is called after a target is acquired /mob/living/simple_animal/hostile/proc/FoundTarget() @@ -84,7 +120,7 @@ stop_automated_movement = 1 if(QDELETED(target_mob) || SA_attackable(target_mob)) LoseTarget() - if(target_mob in ListTargets(10)) + if(target_mob in targets) if(ranged) if(get_dist(src, target_mob) <= 6) OpenFire(target_mob) @@ -100,13 +136,14 @@ if(QDELETED(target_mob) || SA_attackable(target_mob)) LoseTarget() return 0 - if(!(target_mob in ListTargets(10))) + if(!(target_mob in targets)) LoseTarget() return 0 if(next_move >= world.time) return 0 if(get_dist(src, target_mob) <= 1) //Attacking AttackingTarget() + attacked_times += 1 return 1 /mob/living/simple_animal/hostile/proc/AttackingTarget() @@ -153,6 +190,7 @@ ..() switch(stance) if(HOSTILE_STANCE_IDLE) + targets = ListTargets(10) target_mob = FindTarget() if(HOSTILE_STANCE_ATTACK) @@ -163,6 +201,10 @@ if(HOSTILE_STANCE_ATTACKING) if(!AttackTarget() && destroy_surroundings) //hit a window OR a mob, not both at once DestroySurroundings() + if(attacked_times >= rand(0, 4)) + targets = ListTargets(10) + target_mob = FindTarget() + attacked_times = 0 /mob/living/simple_animal/hostile/proc/OpenFire(target_mob) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 98bd0d27214..e4549449193 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -288,7 +288,7 @@ var/list/global/organ_rel_size = list( p++ return t -proc/slur(phrase) +proc/slur(phrase, strength = 100) phrase = html_decode(phrase) var/leng=lentext(phrase) var/counter=lentext(phrase) @@ -296,18 +296,16 @@ proc/slur(phrase) var/newletter="" while(counter>=1) newletter=copytext(phrase,(leng-counter)+1,(leng-counter)+2) - if(rand(1,3)==3) - if(lowertext(newletter)=="o") newletter="u" - if(lowertext(newletter)=="s") newletter="ch" - if(lowertext(newletter)=="a") newletter="ah" - if(lowertext(newletter)=="c") newletter="k" - switch(rand(1,15)) - if(1,3,5,8) newletter="[lowertext(newletter)]" - if(2,4,6,15) newletter="[uppertext(newletter)]" - if(7) newletter+="'" - //if(9,10) newletter="[newletter]" - //if(11,12) newletter="[newletter]" - //if(13) newletter="[newletter]" + if(prob(strength)) + if(rand(1,3)==3) + if(lowertext(newletter)=="o") newletter="u" + if(lowertext(newletter)=="s") newletter="ch" + if(lowertext(newletter)=="a") newletter="ah" + if(lowertext(newletter)=="c") newletter="k" + switch(rand(1,15)) + if(1,3,5,8) newletter="[lowertext(newletter)]" + if(2,4,6,15) newletter="[uppertext(newletter)]" + if(7) newletter+="'" newphrase+="[newletter]";counter-=1 return newphrase @@ -710,7 +708,7 @@ proc/is_blind(A) nutrition -= 60 if (intoxication)//The pain and system shock of vomiting, sobers you up a little - intoxication *= 0.8 + intoxication *= 0.9 if (istype(src, /mob/living/carbon/human)) ingested.trans_to_turf(location,30)//Vomiting empties the stomach, transferring 30u reagents to the floor where you vomited diff --git a/code/modules/multiz/basic.dm b/code/modules/multiz/basic.dm index 5615e69bb54..284233a1c26 100644 --- a/code/modules/multiz/basic.dm +++ b/code/modules/multiz/basic.dm @@ -17,35 +17,25 @@ var/z_levels = 0 // Each bit represents a connection between adjacent levels. S SSatlas.height_markers -= src return ..() -// The storage of connections between adjacent levels means some bitwise magic is needed. +// Legacy shims. /proc/HasAbove(var/z) - if(z >= world.maxz || z > 16 || z < 1) - return 0 - return z_levels & (1 << (z - 1)) + return HAS_ABOVE(z) /proc/HasBelow(var/z) - if(z > world.maxz || z > 17 || z < 2) - return 0 - return z_levels & (1 << (z - 2)) + return HAS_BELOW(z) // Thankfully, no bitwise magic is needed here. -/proc/GetAbove(var/atom/atom) - var/turf/turf = get_turf(atom) - if(!turf) - return null - return HasAbove(turf.z) ? get_step(turf, UP) : null +/proc/GetAbove(atom/A) + return A ? GET_ABOVE(A) : null -/proc/GetBelow(var/atom/atom) - var/turf/turf = get_turf(atom) - if(!turf) - return null - return HasBelow(turf.z) ? get_step(turf, DOWN) : null +/proc/GetBelow(atom/A) + return A ? GET_BELOW(A) : null /proc/GetConnectedZlevels(z) . = list(z) - for(var/level = z, HasBelow(level), level--) + for(var/level = z, HAS_BELOW(level), level--) . += level-1 - for(var/level = z, HasAbove(level), level++) + for(var/level = z, HAS_ABOVE(level), level++) . += level+1 /proc/AreConnectedZLevels(var/zA, var/zB) @@ -68,9 +58,10 @@ var/z_levels = 0 // Each bit represents a connection between adjacent levels. S return new_entry[zB] /proc/get_zstep(ref, dir) - if(dir == UP) - . = GetAbove(ref) - else if (dir == DOWN) - . = GetBelow(ref) - else - . = get_step(ref, dir) + switch (dir) + if (UP) + . = GET_ABOVE(ref) + if (DOWN) + . = GET_BELOW(ref) + else + . = get_step(ref, dir) diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm index ba212f4cb67..3e8f8e7d181 100644 --- a/code/modules/organs/organ_internal.dm +++ b/code/modules/organs/organ_internal.dm @@ -28,7 +28,7 @@ if (germ_level > INFECTION_LEVEL_ONE) if(prob(5)) - owner.emote("cough") //respitory tract infection + owner.emote("cough") //Respiratory tract infection if(is_bruised()) if(prob(2)) @@ -135,27 +135,22 @@ if(src.damage < 0) src.damage = 0 - // Get the effectiveness of the liver. - var/filter_effect = 3 + var/filter_strength = INTOX_FILTER_HEALTHY if(is_bruised()) - filter_effect -= 1 + filter_strength = INTOX_FILTER_BRUISED if(is_broken()) - filter_effect -= 2 + filter_strength = INTOX_FILTER_DAMAGED if (owner.intoxication > 0) - //ALCOHOL_FILTRATION_RATE is defined in intoxication.dm - owner.intoxication -= ALCOHOL_FILTRATION_RATE*filter_effect*PROCESS_ACCURACY//A weakened liver filters out alcohol more slowly + owner.intoxication -= filter_strength*PROCESS_ACCURACY owner.intoxication = max(owner.intoxication, 0) if (!owner.intoxication) - //If intoxication has just been reduced to zero, this will handle removing any effects owner.handle_intoxication() - // Do some reagent processing. if(owner.chem_effects[CE_ALCOHOL_TOXIC]) - if(filter_effect < 3) + take_damage(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY, prob(1)) + if(is_damaged()) owner.adjustToxLoss(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY) - else - take_damage(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY, prob(1)) // Chance to warn them /obj/item/organ/appendix name = "appendix" diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 8da2bc790db..d44a4108da8 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -392,6 +392,7 @@ usr << browse("[name][info_links][stamps]", "window=[name]") // Update the window + playsound(src, pick('sound/items/pen1.ogg','sound/items/pen2.ogg'), 10) update_icon() @@ -501,6 +502,7 @@ stamped += P.type add_overlay(stampoverlay) + playsound(src, 'sound/items/stamp.ogg', 50, 1) user << "You stamp the paper with \the [P]." else if(istype(P, /obj/item/weapon/flame)) diff --git a/code/modules/projectiles/guns/projectile/rifle.dm b/code/modules/projectiles/guns/projectile/rifle.dm index 617de99c60f..3808acf2c11 100644 --- a/code/modules/projectiles/guns/projectile/rifle.dm +++ b/code/modules/projectiles/guns/projectile/rifle.dm @@ -1,88 +1,36 @@ -/obj/item/weapon/gun/projectile/boltaction - name = "\improper bolt action rifle" +/obj/item/weapon/gun/projectile/shotgun/pump/rifle + name = "bolt action rifle" desc = "A cheap ballistic rifle often found in the hands of crooks and frontiersmen. Uses 7.62mm rounds." icon_state = "moistnugget" item_state = "moistnugget" origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2) fire_sound = 'sound/weapons/rifleshot.ogg' - slot_flags = SLOT_BACK - load_method = SINGLE_CASING|SPEEDLOADER - handle_casings = HOLD_CASINGS caliber = "a762" ammo_type = /obj/item/ammo_casing/a762 max_shells = 5 - w_class = 4.0 - force = 10 - var/recentpump = 0 + + pump_fail_msg = "You cannot work the rifle's bolt without gripping it with both hands!" + pump_snd = 'sound/weapons/riflebolt.ogg' + has_wield_state = FALSE + + can_sawoff = TRUE + sawnoff_workmsg = "shorten the barrel and stock" action_button_name = "Wield rifle" -/obj/item/weapon/gun/projectile/boltaction/can_wield() - return 1 +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/saw_off(mob/user, obj/item/tool) + icon_state = "obrez" + w_class = 3 + recoil = 2 + accuracy = -2 + item_state = "obrez" + slot_flags &= ~SLOT_BACK + slot_flags |= (SLOT_BELT|SLOT_HOLSTER) + name = "obrez" + desc = "A shortened bolt action rifle, not really acurate. Uses 7.62mm rounds." + to_chat(user, "You shorten the barrel and stock of the rifle!") -/obj/item/weapon/gun/projectile/boltaction/ui_action_click() - if(src in usr) - toggle_wield(usr) - -/obj/item/weapon/gun/projectile/boltaction/verb/wield_shotgun() - set name = "Wield rifle" - set category = "Object" - set src in usr - - toggle_wield(usr) - -/obj/item/weapon/gun/projectile/boltaction/consume_next_projectile() - if(chambered) - return chambered.BB - return null - -/obj/item/weapon/gun/projectile/boltaction/attack_self(mob/living/user as mob) - if(world.time >= recentpump + 10) - pump(user) - recentpump = world.time - -/obj/item/weapon/gun/projectile/boltaction/proc/pump(mob/M as mob) - if(!wielded) - M << "You cannot work the rifle's bolt without gripping it with both hands!" - return - - playsound(M, 'sound/weapons/riflebolt.ogg', 60, 1) - - if(chambered)//We have a shell in the chamber - chambered.loc = get_turf(src)//Eject casing - chambered = null - - if(loaded.len) - var/obj/item/ammo_casing/AC = loaded[1] //load next casing. - loaded -= AC //Remove casing from loaded list. - chambered = AC - - update_icon() - - -/obj/item/weapon/gun/projectile/boltaction/attackby(var/obj/item/A as obj, mob/user as mob) - if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/gun/energy/plasmacutter) && w_class != 3) - user << "You begin to shorten the barrel and stock of \the [src]." - if(loaded.len) - afterattack(user, user) - playsound(user, fire_sound, 50, 1) - user.visible_message("[src] goes off!", "The rifle goes off in your face!") - return - if(do_after(user, 30)) - icon_state = "obrez" - w_class = 3 - recoil = 2 - accuracy = -2 - item_state = "obrez" - slot_flags &= ~SLOT_BACK - slot_flags |= (SLOT_BELT|SLOT_HOLSTER) - name = "\improper obrez" - desc = "A shortened bolt action rifle, not really acurate. Uses 7.62mm rounds." - user << "You shorten the barrel and stock of the rifle!" - else - ..() - -/obj/item/weapon/gun/projectile/boltaction/obrez +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/obrez name = "obrez" desc = "A shortened bolt action rifle, not really accurate. Uses 7.62mm rounds." icon_state = "obrez" @@ -142,7 +90,7 @@ return ..() -/obj/item/weapon/gun/projectile/boltaction/vintage +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/vintage name = "\improper vintage bolt action rifle" desc = "An extremely old-looking rifle. Words you can't read are stamped on the gun. Doesn't look like it'll take any modern rounds." icon_state = "springfield" @@ -156,10 +104,7 @@ var/open_bolt = 0 var/obj/item/ammo_magazine/boltaction/vintage/has_clip - action_button_name = "Wield rifle" - - -/obj/item/weapon/gun/projectile/boltaction/vintage/attack_self(mob/living/user as mob) +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/vintage/attack_self(mob/living/user as mob) if(wielded) if(world.time >= recentpump + 10) pump(user) @@ -171,11 +116,11 @@ load_ammo(has_clip, user) src.cut_overlays() if(!has_clip.stored_ammo.len) - src.add_overlay(image('icons/obj/gun.dmi', "springfield-clip-empty")) + add_overlay("springfield-clip-empty") else if(has_clip.stored_ammo.len <= 3) - src.add_overlay(image('icons/obj/gun.dmi', "springfield-clip-half")) + add_overlay("springfield-clip-half") else - src.add_overlay(image('icons/obj/gun.dmi', "springfield-clip-full")) + add_overlay("springfield-clip-full") else user << "There is no ammo in \the [has_clip.name]!" else if(!open_bolt) @@ -183,9 +128,9 @@ else user << "There is no clip in \the [src.name]!" -/obj/item/weapon/gun/projectile/boltaction/vintage/pump(mob/M as mob) +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/vintage/pump(mob/M as mob) if(!wielded) - M << "You cannot work \the [src.name]'s bolt without gripping it with both hands!" + M << "You cannot work \the [src]'s bolt without gripping it with both hands!" return if(!open_bolt) open_bolt = 1 @@ -199,7 +144,7 @@ if(has_clip) has_clip.forceMove(get_turf(src)) has_clip = null - src.cut_overlays() + cut_overlays() if(chambered)//We have a shell in the chamber @@ -213,7 +158,7 @@ update_icon() -/obj/item/weapon/gun/projectile/boltaction/vintage/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/vintage/attackby(var/obj/item/A as obj, mob/user as mob) if(istype(A, /obj/item/ammo_magazine/boltaction/vintage)) if(!open_bolt) user << "You need to open the bolt of \the [src] first." @@ -224,25 +169,25 @@ has_clip = A user << "You load the clip into \the [src]." if(!has_clip.stored_ammo.len) - src.add_overlay(image('icons/obj/gun.dmi', "springfield-clip-empty")) + add_overlay("springfield-clip-empty") else if(has_clip.stored_ammo.len <= 3) - src.add_overlay(image('icons/obj/gun.dmi', "springfield-clip-half")) + add_overlay("springfield-clip-half") else - src.add_overlay(image('icons/obj/gun.dmi', "springfield-clip-full")) + add_overlay("springfield-clip-full") else - user << "There's already a clip in \the [src]." + to_chat(user, "There's already a clip in \the [src].") else ..() -/obj/item/weapon/gun/projectile/boltaction/vintage/load_ammo(var/obj/item/A, mob/user) +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/vintage/load_ammo(var/obj/item/A, mob/user) if(!open_bolt) - user << "The bolt is closed on \the [src.name]!" + user << "The bolt is closed on \the [src]!" return ..() -/obj/item/weapon/gun/projectile/boltaction/vintage/Fire(atom/target, mob/living/user, clickparams, pointblank=0, reflex=0) +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/vintage/Fire(atom/target, mob/living/user, clickparams, pointblank=0, reflex=0) if(open_bolt) - user << "The bolt is open on \the [src.name]!" + user << "The bolt is open on \the [src]!" return - ..() \ No newline at end of file + ..() diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 150c4791262..37af48d925b 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -1,12 +1,51 @@ +/obj/item/weapon/gun/projectile/shotgun + name = "strange shotgun" + desc = "A strange shotgun that doesn't seem to belong anywhere. You feel like you shouldn't be able to see this and should... submit an issue?" + + var/can_sawoff = FALSE + var/sawnoff_workmsg + var/sawing_in_progress = FALSE + +/obj/item/weapon/gun/projectile/shotgun + +/obj/item/weapon/gun/projectile/shotgun/attackby(obj/item/A, mob/user) + if (!can_sawoff || sawing_in_progress) + return ..() + + var/static/list/barrel_cutting_tools = typecacheof(list( + /obj/item/weapon/circular_saw, + /obj/item/weapon/melee/energy, + /obj/item/weapon/gun/energy/plasmacutter // does this even work? + )) + if(is_type_in_typecache(A, barrel_cutting_tools) && w_class != 3) + to_chat(user, "You begin to [sawnoff_workmsg] of \the [src].") + if(loaded.len) + for(var/i in 1 to max_shells) + Fire(user, user) //will this work? //it will. we call it twice, for twice the FUN + user.visible_message("\The [src] goes off!", "\The [src] goes off in your face!") + return + + sawing_in_progress = TRUE + if(do_after(user, 30, act_target = src)) //SHIT IS STEALTHY EYYYYY + sawing_in_progress = FALSE + saw_off(user, A) + else + ..() + +// called on a SUCCESSFUL saw-off. +/obj/item/weapon/gun/projectile/shotgun/proc/saw_off(mob/user, obj/item/tool) + to_chat(user, "You attempt to cut [src]'s barrel with [tool], but nothing happens.") + log_debug("shotgun: attempt to saw-off shotgun with no saw-off behavior.") + /obj/item/weapon/gun/projectile/shotgun/pump name = "pump shotgun" desc = "An ubiquitous unbranded shotgun. Useful for sweeping alleys." icon_state = "shotgun" item_state = "shotgun" max_shells = 4 - w_class = 4.0 + w_class = ITEMSIZE_LARGE force = 10 - flags = CONDUCT + flags = CONDUCT slot_flags = SLOT_BACK caliber = "shotgun" origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 2) @@ -15,8 +54,11 @@ handle_casings = HOLD_CASINGS fire_sound = 'sound/weapons/shotgun.ogg' var/recentpump = 0 // to prevent spammage + var/pump_fail_msg = "You cannot rack the shotgun without gripping it with both hands!" + var/pump_snd = 'sound/weapons/shotgunpump.ogg' + var/has_wield_state = TRUE - action_button_name = "Wield rifle" + action_button_name = "Wield shotgun" /obj/item/weapon/gun/projectile/shotgun/pump/can_wield() return 1 @@ -26,7 +68,7 @@ toggle_wield(usr) /obj/item/weapon/gun/projectile/shotgun/pump/verb/wield_shotgun() - set name = "Wield shotgun" + set name = "Wield" set category = "Object" set src in usr @@ -37,20 +79,20 @@ return chambered.BB return null -/obj/item/weapon/gun/projectile/shotgun/pump/attack_self(mob/living/user as mob) +/obj/item/weapon/gun/projectile/shotgun/pump/attack_self(mob/living/user) if(world.time >= recentpump + 10) pump(user) recentpump = world.time -/obj/item/weapon/gun/projectile/shotgun/pump/proc/pump(mob/M as mob) +/obj/item/weapon/gun/projectile/shotgun/pump/proc/pump(mob/M) if(!wielded) - M << "You cannot rack the shotgun without gripping it with both hands!" + to_chat(M, pump_fail_msg) return - playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1) + playsound(M, pump_snd, 60, 1) if(chambered)//We have a shell in the chamber - chambered.loc = get_turf(src)//Eject casing + chambered.forceMove(get_turf(src)) //Eject casing chambered = null if(loaded.len) @@ -62,7 +104,7 @@ /obj/item/weapon/gun/projectile/shotgun/pump/update_icon() ..() - if(wielded) + if(wielded && has_wield_state) item_state = "[icon_state]-wielded" else item_state = "[icon_state]" @@ -103,6 +145,9 @@ list(mode_name="fire both barrels at once", burst=2) ) + can_sawoff = TRUE + sawnoff_workmsg = "shorten the barrel" + /obj/item/weapon/gun/projectile/shotgun/doublebarrel/pellet ammo_type = /obj/item/ammo_casing/shotgun/pellet @@ -114,28 +159,16 @@ /obj/item/weapon/gun/projectile/shotgun/doublebarrel/unload_ammo(user, allow_dump) ..(user, allow_dump=1) -//this is largely hacky and bad :( -Pete -/obj/item/weapon/gun/projectile/shotgun/doublebarrel/attackby(var/obj/item/A as obj, mob/user as mob) - if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/gun/energy/plasmacutter) && w_class != 3) - user << "You begin to shorten the barrel of \the [src]." - if(loaded.len) - for(var/i in 1 to max_shells) - Fire(user, user) //will this work? //it will. we call it twice, for twice the FUN - user.visible_message("The shotgun goes off!", "The shotgun goes off in your face!") - return - if(do_after(user, 30)) //SHIT IS STEALTHY EYYYYY - icon_state = "sawnshotgun" - item_state = "sawnshotgun" - w_class = 3 - force = 5 - slot_flags &= ~SLOT_BACK //you can't sling it on your back - slot_flags |= (SLOT_BELT|SLOT_HOLSTER) //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) - or in a holster, why not. - name = "sawn-off shotgun" - desc = "Omar's coming!" - user << "You shorten the barrel of \the [src]!" - else - ..() - +/obj/item/weapon/gun/projectile/shotgun/doublebarrel/saw_off(mob/user, obj/item/tool) + icon_state = "sawnshotgun" + item_state = "sawnshotgun" + w_class = 3 + force = 5 + slot_flags &= ~SLOT_BACK //you can't sling it on your back + slot_flags |= (SLOT_BELT|SLOT_HOLSTER) //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) - or in a holster, why not. + name = "sawn-off shotgun" + desc = "Omar's coming!" + to_chat(user, "You shorten the barrel of \the [src]!") /obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn name = "sawn-off shotgun" diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm index e8d05b6df9d..afbeaccfc00 100644 --- a/code/modules/projectiles/pins.dm +++ b/code/modules/projectiles/pins.dm @@ -70,7 +70,7 @@ Firing pins as a rule can't be removed without replacing them, blame a really sh user.show_message(fail_message, 1) if(selfdestruct)//sound stolen from the lawgiver. todo, remove this from the lawgiver. there can only be one. user.show_message("SELF-DESTRUCTING...
", 1) - visible_message("[gun] explodes!") + visible_message("\The [gun] explodes!") playsound(user, 'sound/weapons/lawgiver_idfail.ogg', 40, 1) var/obj/item/organ/external/E = user.organs_by_name[user.hand ? "l_hand" : "r_hand"] E.droplimb(0,DROPLIMB_BLUNT) @@ -122,7 +122,7 @@ Pins Below. desc = "This implant-locked firing pin authorizes the weapon for only loyalty-implanted users." icon_state = "firing_pin_loyalty" req_implant = /obj/item/weapon/implant/loyalty - + // Honk pin, clown joke item. // Can replace other pins. Replace a pin in cap's laser for extra fun! This is generally adminbus only unless someone thinks of a use for it. /obj/item/device/firing_pin/clown @@ -204,4 +204,17 @@ Pins Below. /obj/item/device/firing_pin/Destroy() if(gun) gun.pin = null - return ..() \ No newline at end of file + return ..() + +//this firing pin checks for access +/obj/item/device/firing_pin/access + name = "access-keyed firing pin" + desc = "This access locked firing pin allows weapons to be fired only when the user has the required access." + fail_message = "ACCESS CHECK FAILED." + req_access = list(access_weapons) + +/obj/item/device/firing_pin/access/pin_auth(mob/living/user) + if(!allowed(user)) + return 0 + else + return 1 \ No newline at end of file diff --git a/code/modules/random_map/automata/caves.dm b/code/modules/random_map/automata/caves.dm index a4dffaffbe9..53ecd8929cc 100644 --- a/code/modules/random_map/automata/caves.dm +++ b/code/modules/random_map/automata/caves.dm @@ -1,6 +1,3 @@ -#define GET_BELOW_OR_NULL(atom, z) \ - (!(z > world.maxz || z > 17 || z < 2) && z_levels & (1 << (z - 2))) ? get_step(atom, DOWN) : null - /datum/random_map/automata/cave_system iterations = 5 descriptor = "moon caves" @@ -131,7 +128,7 @@ if(EMPTY_CHAR) new_path = mineral_rich if(FLOOR_CHAR) - var/turf/below = GET_BELOW_OR_NULL(T, T.z) + var/turf/below = GET_BELOW(T) if(below) var/area/below_area = below.loc // Let's just assume that the turf is not in nullspace. if(below_area.station_area) @@ -164,5 +161,3 @@ target_turf_type = /turf/unsimulated/chasm_mask mineral_sparse = /turf/simulated/floor/asteroid/ash mineral_rich = /turf/simulated/floor/asteroid/ash - -#undef GET_BELOW_OR_NULL diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index bfbd7b99ab9..351558de2a3 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -252,7 +252,7 @@ return amount /datum/reagents/proc/trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]). - + if(!target || !istype(target)) return 0 @@ -276,7 +276,7 @@ handle_reactions() target.handle_reactions() - + return amount /* Holder-to-atom and similar procs */ @@ -389,7 +389,7 @@ if(!target || !istype(target) || !target.simulated) return 0 - + var/mob/living/carbon/C = target if(istype(C)) if(type == CHEM_BREATHE) diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 8096750e812..2168e91a43d 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -12,6 +12,9 @@ var/ingest_met = 0 var/touch_met = 0 var/breathe_met = 0 + var/ingest_mul = 0.5 + var/touch_mul = 0 + var/breathe_mul = 0.75 var/dose = 0 var/max_dose = 0 var/overdose = 0 @@ -25,7 +28,7 @@ var/color_weight = 1 var/unaffected_species = IS_DIONA | IS_MACHINE // Species that aren't affected by this reagent. Does not prevent affect_touch. var/metabolism_min = 0.01 //How much for the medicine to be present in the system to actually have an effect. - var/list/conflicting_reagents //Reagents that conflict with this medicine, and cause adverse effects when in the blood. + var/conflicting_reagent //Reagents that conflict with this medicine, and cause adverse effects when in the blood. /datum/reagent/proc/remove_self(var/amount) // Shortcut if (!holder) @@ -71,10 +74,9 @@ dose = min(dose + removed, max_dose) - for(var/conflicting_reagent in conflicting_reagents) - var/amount_min = conflicting_reagents[conflicting_reagent] - if(M.reagents.has_reagent(conflicting_reagent,amount_min)) - affect_conflicting(M,alien,removed,conflicting_reagent) + for(var/datum/reagent/R in M.bloodstr.reagent_list) + if(istype(R, conflicting_reagent)) + affect_conflicting(M,alien,removed,R) if(removed >= metabolism_min) switch(location) if(CHEM_BLOOD) @@ -98,13 +100,16 @@ M.adjustToxLoss(removed) /datum/reagent/proc/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) - affect_blood(M, alien, removed * 0.5) + if(ingest_mul) + affect_blood(M, alien, removed * ingest_mul) /datum/reagent/proc/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) - return + if(touch_mul) + affect_blood(M, alien, removed * touch_mul) /datum/reagent/proc/affect_breathe(var/mob/living/carbon/M, var/alien, var/removed) - affect_blood(M, alien, removed * 0.75) + if(breathe_mul) + affect_blood(M, alien, removed * breathe_mul) /datum/reagent/proc/overdose(var/mob/living/carbon/M, var/alien, var/removed = 0, var/scale = 1) // Overdose effect. Doesn't happen instantly. M.adjustToxLoss(REM) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm index b3066981805..8c659f09025 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm @@ -39,12 +39,14 @@ /datum/reagent/ammonia name = "Ammonia" id = "ammonia" - description = "A caustic substance commonly used in fertilizer or household cleaners." + description = "A caustic substance commonly used in fertilizer or household cleaners. Poisonous to most lifeforms, lingers for a while if inhaled." reagent_state = LIQUID color = "#404030" metabolism = REM * 0.5 taste_description = "mordant" taste_mult = 2 + breathe_mul = 2 + breathe_met = REM * 0.25 /datum/reagent/ammonia/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_VOX) @@ -127,7 +129,8 @@ M.adjustToxLoss(removed * 2) /datum/reagent/alcohol/affect_ingest(mob/living/carbon/M, alien, removed) - M.intoxication += (strength / 100) * removed + + M.intoxication += (strength * removed) * 0.075 if (druggy != 0) M.druggy = max(M.druggy, druggy) @@ -343,6 +346,13 @@ /datum/reagent/acid/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.take_organ_damage(0, removed * power) +/datum/reagent/acid/affect_breathe(var/mob/living/carbon/human/H, var/alien, var/removed) + . = ..() + if(istype(H)) + var/obj/item/organ/L = H.internal_organs_by_name["lungs"] + if(istype(L)) + L.take_damage(removed * power * 0.5) + /datum/reagent/acid/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) // This is the most interesting if(ishuman(M)) var/mob/living/carbon/human/H = M @@ -424,6 +434,16 @@ meltdose = 8 taste_description = "stomach acid" +/datum/reagent/acid/polyacid //Not in dispensers, but it should be here + name = "Polytrinic acid" + id = "pacid" + description = "Polytrinic acid is a an extremely corrosive chemical substance." + reagent_state = LIQUID + color = "#8E18A9" + power = 6 + meltdose = 4 + taste_description = "acid" + /datum/reagent/silicon name = "Silicon" id = "silicon" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index b0393eb3d9b..a843697b5e1 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -113,8 +113,7 @@ M.nutrition += nutriment_factor * removed // For hunger and fatness M.nutrition_attrition_rate = Clamp(M.nutrition_attrition_rate + attrition_factor, 1, 2) M.add_chemical_effect(CE_BLOODRESTORE, blood_factor * removed) - - + M.intoxication -= min(M.intoxication,nutriment_factor*removed*0.05) //Nutrients can absorb alcohol. /* Coatings are used in cooking. Dipping food items in a reagent container with a coating in it @@ -507,6 +506,10 @@ overdose = REAGENTS_OVERDOSE taste_description = "salt" +/datum/reagent/sodiumchloride/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + . = ..() + M.intoxication -= min(M.intoxication,removed*2) //Salt absorbs alcohol + /datum/reagent/blackpepper name = "Black Pepper" id = "blackpepper" @@ -861,6 +864,17 @@ glass_name = "glass of watermelon juice" glass_desc = "Delicious juice made from watermelon." +/datum/reagent/drink/pineapplejuice + name = "Pineapple Juice" + id = "pineapplejuice" + description = "From freshly canned pineapples." + color = "#FFFF00" + taste_description = "pineapple" + + glass_icon_state = "lemonjuice" + glass_name = "glass of pineapple juice" + glass_desc = "What the hell is this?" + // Everything else /datum/reagent/drink/milk diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index 8ce6b07d1db..ab5073d7dad 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -9,6 +9,7 @@ overdose = REAGENTS_OVERDOSE * 2 metabolism = REM * 0.5 metabolism_min = REM * 0.125 + breathe_mul = 0.5 scannable = 1 taste_description = "bitterness" var/datum/modifier/modifier @@ -26,7 +27,7 @@ /datum/reagent/bicaridine name = "Bicaridine" id = "bicaridine" - description = "Bicaridine is an analgesic medication and can be used to treat blunt trauma." + description = "Bicaridine is an analgesic medication and can be used to treat blunt trauma. When inhaled, it treats minor damage to the lungs." reagent_state = LIQUID color = "#BF0000" overdose = REAGENTS_OVERDOSE @@ -35,9 +36,19 @@ taste_description = "bitterness" taste_mult = 3 + breathe_met = 0.5 + breathe_mul = 0.1 + /datum/reagent/bicaridine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.heal_organ_damage(5 * removed, 0) +/datum/reagent/bicaridine/affect_breathe(var/mob/living/carbon/human/H, var/alien, var/removed) + . = ..() + if(istype(H)) + var/obj/item/organ/L = H.internal_organs_by_name["lungs"] + if(istype(L) && !L.robotic && !L.is_broken()) + L.take_damage(-1*removed) //Every 10 units heals 1 lung damage. + /datum/reagent/bicaridine/overdose(var/mob/living/carbon/M, var/alien) ..()//Bicard overdose heals internal wounds if(ishuman(M)) @@ -97,12 +108,14 @@ /datum/reagent/dexalin name = "Dexalin" id = "dexalin" - description = "Dexalin is used in the treatment of oxygen deprivation." + description = "Dexalin is used in the treatment of oxygen deprivation. The medication is twice as powerful and lasts twice as long when inhaled." reagent_state = LIQUID color = "#0080FF" overdose = REAGENTS_OVERDOSE scannable = 1 taste_description = "bitterness" + breathe_met = 0.5 + breathe_mul = 2 /datum/reagent/dexalin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_VOX) @@ -115,12 +128,14 @@ /datum/reagent/dexalinp name = "Dexalin Plus" id = "dexalinp" - description = "Dexalin Plus is used in the treatment of oxygen deprivation. It is highly effective." + description = "Dexalin Plus is used in the treatment of oxygen deprivation. It is highly effective, and is twice as powerful and lasts twice as long when inhaled." reagent_state = LIQUID color = "#0040FF" overdose = REAGENTS_OVERDOSE * 0.5 scannable = 1 taste_description = "bitterness" + breathe_met = 0.5 + breathe_mul = 2 /datum/reagent/dexalinp/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_VOX) @@ -133,12 +148,12 @@ /datum/reagent/tricordrazine name = "Tricordrazine" id = "tricordrazine" - description = "Tricordrazine is a highly potent stimulant, originally derived from cordrazine. Can be used to treat a wide range of injuries." + description = "Tricordrazine is a highly potent stimulant, originally derived from cordrazine. Can be used to treat a wide range of injuries, however it does not work when inhaled." reagent_state = LIQUID color = "#8040FF" scannable = 1 - taste_description = "bitterness" + breathe_mul = 0 /datum/reagent/tricordrazine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.adjustOxyLoss(-6 * removed) @@ -184,7 +199,7 @@ /datum/reagent/paracetamol name = "Paracetamol" id = "paracetamol" - description = "Most probably know this as Tylenol, but this chemical is a mild, simple painkiller." + description = "Most probably know this as Tylenol, but this chemical is a mild, simple painkiller. Does not work when inhaled." reagent_state = LIQUID color = "#C8A5DC" overdose = 60 @@ -192,6 +207,7 @@ metabolism = 0.02 taste_description = "sickness" metabolism_min = 0.005 + breathe_mul = 0 /datum/reagent/paracetamol/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.add_chemical_effect(CE_PAINKILLER, 50) @@ -203,7 +219,7 @@ /datum/reagent/tramadol name = "Tramadol" id = "tramadol" - description = "A simple, yet effective painkiller." + description = "Tramadol is a very effective painkiller designed for victims of heavy physical trauma. Does not work when inhaled." reagent_state = LIQUID color = "#CB68FC" overdose = 30 @@ -211,6 +227,7 @@ metabolism = 0.02 taste_description = "sourness" metabolism_min = 0.005 + breathe_mul = 0 /datum/reagent/tramadol/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.add_chemical_effect(CE_PAINKILLER, 80) @@ -222,26 +239,28 @@ /datum/reagent/oxycodone name = "Oxycodone" id = "oxycodone" - description = "An effective and very addictive painkiller." + description = "Oxycodone is incredibly potent and very addictive painkiller. Do not mix with alcohol. Does not work when inhaled." reagent_state = LIQUID color = "#800080" overdose = 20 metabolism = 0.02 taste_description = "bitterness" metabolism_min = 0.005 - conflicting_reagents = list(/datum/reagent/alcohol/ = 5) + breathe_mul = 0 /datum/reagent/oxycodone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.add_chemical_effect(CE_PAINKILLER, 200) - -/datum/reagent/oxycodone/affect_conflicting(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagent/conflicting) - ..() - M.hallucination = max(M.hallucination, 60) - M.druggy = max(M.druggy, 10) + var/mob/living/carbon/human/H = M + if(!istype(H)) + return + var/bac = H.get_blood_alcohol() + if(bac >= 0.02) + M.hallucination = max(M.hallucination, bac * 300) + M.druggy = max(M.druggy, bac * 100) /datum/reagent/oxycodone/overdose(var/mob/living/carbon/M, var/alien) ..() - M.druggy = max(M.druggy, 10) + M.druggy = max(M.druggy, 20) M.hallucination = max(M.hallucination, 60) /* Other medicine */ @@ -249,7 +268,7 @@ /datum/reagent/synaptizine name = "Synaptizine" id = "synaptizine" - description = "Synaptizine is used to treat various diseases." + description = "Synaptizine is used to treat a robust array of conditions, such as drowsyness, paralysis, weakness, LSD overdose, hallucinations, and pain. Moderately poisonous, and should only be used as a last resort." reagent_state = LIQUID color = "#99CCFF" metabolism = REM * 0.05 @@ -275,7 +294,6 @@ QDEL_NULL(modifier) return ..() - /datum/reagent/alkysine name = "Alkysine" id = "alkysine" @@ -357,7 +375,7 @@ /datum/reagent/hyperzine name = "Hyperzine" id = "hyperzine" - description = "Hyperzine is a highly effective, long lasting, muscle stimulant." + description = "Hyperzine is a highly effective, long lasting, muscle stimulant. Lasts twice as long when inhaled." reagent_state = LIQUID color = "#FF3300" metabolism = REM * 0.15 @@ -365,6 +383,7 @@ var/datum/modifier = null taste_description = "acid" metabolism_min = REM * 0.025 + breathe_met = 0.5 /datum/reagent/hyperzine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(prob(5)) @@ -524,51 +543,61 @@ #define ANTIDEPRESSANT_MESSAGE_DELAY 1800 //3 minutes /datum/reagent/mental - name = "Experimental Antidepressant" + name = null //Just like alcohol id = "mental" description = "Some nameless, experimental antidepressant that you should obviously not have your hands on." reagent_state = LIQUID color = "#FFFFFF" - metabolism = 0.001 + metabolism = 0.001 * REM metabolism_min = 0 data = 0 + scannable = 1 + overdose = REAGENTS_OVERDOSE taste_description = "bugs" - var/goodmessage = list("Your mind feels healthy.","You feel calm and relaxed.","The world seems like a better place now.") //Messages when all your brain traumas are cured. - var/badmessage = list("Your mind seems lost...","You feel agitated...","It feels like the world is out to get you...") //Messages when you still have at least one brain trauma it's suppose to cure. - var/worstmessage = list("Your mind starts to break down...","Things aren't what they seem...","You hate yourself...") //Messages when the user is at possible risk for more trauma - var/list/suppress_traumas //List of brain traumas that the medication temporarily suppresses, with the key being the brain trauma and the value being the minimum dosage required to cure. + ingest_mul = 1 + var/alchohol_affected = 1 + var/min_dose = 1 + var/messagedelay = ANTIDEPRESSANT_MESSAGE_DELAY + var/list/goodmessage = list() //Messages when all your brain traumas are cured. + var/list/badmessage = list() //Messages when you still have at least one brain trauma it's suppose to cure. + var/list/worstmessage = list() //Messages when the user is at possible risk for more trauma + var/list/suppress_traumas //List of brain traumas that the medication temporarily suppresses, with the key being the brain trauma and the value being the minimum dosage required to cure. Negative values means that the trauma is temporarily gained on the value instead. var/list/dosage_traumas //List of brain traumas that the medication permanently adds at these dosages, with the key being the brain trauma and the value being base percent chance to add. var/list/withdrawal_traumas //List of withdrawl effects that the medication permanently adds during withdrawl, with the key being the brain trauma, and the value being the base percent chance to add. - var/messagedelay = ANTIDEPRESSANT_MESSAGE_DELAY - conflicting_reagents = list(/datum/reagent/alcohol/ = 5) - var/suppressing_reagents = list(/datum/reagent/synaptizine = 5) // List of reagents that suppress the withdrawal effects, with the key being the reagent and the vlue being the minimum dosage required to suppress. + var/list/suppressing_reagents = list() // List of reagents that suppress the withdrawal effects, with the key being the reagent and the vlue being the minimum dosage required to suppress. /datum/reagent/mental/affect_blood(var/mob/living/carbon/human/H, var/alien, var/removed) - if(!istype(H) || world.time < data) + if(!istype(H) || max_dose < min_dose || (world.time < data && volume > removed) || messagedelay == -1) return + //max_dose < min_dose and volume > removed prevents message startup/startdown spam if you're using something like a cigarette or similiar device that transfers a little bit of reagents at a time. + //If in the case that a cigarette has a lower transfer rate than the metabolism rate, then message spam will occur since it's starting and stopping constantly. + //This also prevents the whole code from working if the dosage is very small. + var/hastrauma = 0 //whether or not the brain has trauma var/obj/item/organ/brain/B = H.internal_organs_by_name["brain"] + var/bac = H.get_blood_alcohol() + + if(alchohol_affected && bac > 0.01) + H.hallucination = max(H.hallucination, bac * 400) if(B) //You won't feel anything if you don't have a brain. for(var/datum/brain_trauma/BT in B.traumas) - var/goal_volume = suppress_traumas [BT] + var/goal_volume = suppress_traumas[BT] if (volume >= goal_volume) // If the dosage is greater than the goal, then suppress the trauma. - if(!BT.suppressed) - BT.on_lose() + if(!BT.suppressed && !BT.permanent) BT.suppressed = 1 - else if(volume < goal_volume-1) // -1 So it doesn't spam back and forth constantly if reagents are being metabolized + BT.on_lose() + else if(volume < goal_volume-1 && goal_volume > 0) // -1 So it doesn't spam back and forth constantly if reagents are being metabolized if(BT.suppressed) - BT.on_gain() BT.suppressed = 0 + BT.on_gain() hastrauma = 1 - for(var/datum/brain_trauma/BT in dosage_traumas) var/percentchance = max(0,dosage_traumas[BT] - dose*10) // If you've been taking this medication for a while then side effects are rarer. if(!H.has_trauma_type(BT) && prob(percentchance)) B.gain_trauma(BT,FALSE) - - if(volume < max_dose*0.25) //If you haven't been taking youre regular dose, then cause issues. + if(volume < max_dose*0.25) //If you haven't been taking your regular dose, then cause issues. var/suppress_withdrawl = FALSE for(var/k in suppressing_reagents) var/datum/reagent/v = suppressing_reagents[k] @@ -576,21 +605,24 @@ suppress_withdrawl = TRUE break if(!suppress_withdrawl) - H << "[pick(worstmessage)]" + if (H.shock_stage < 20 && worstmessage.len) + to_chat(H,"[pick(worstmessage)]") + messagedelay = initial(messagedelay) * 0.25 for(var/k in withdrawal_traumas) var/datum/brain_trauma/BT = k var/percentchance = max(withdrawal_traumas[k] * (dose/20)) //The higher the dosage, the more likely it is do get withdrawal traumas. if(!H.has_trauma_type(BT) && prob(percentchance)) B.gain_trauma(BT,FALSE) else if(hastrauma || volume < max_dose*0.5) //If your current dose is not high enough, then alert the player. - H << "[pick(badmessage)]" + if (H.shock_stage < 10 && badmessage.len) + to_chat(H,"[pick(badmessage)]") + messagedelay = initial(messagedelay) * 0.5 else - H << "[pick(goodmessage)]" + if (H.shock_stage < 5 && goodmessage.len) + to_chat(H,"[pick(goodmessage)]") + messagedelay = initial(messagedelay) - data = world.time + messagedelay - -/datum/reagent/mental/affect_conflicting(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagent/conflicting) - M.hallucination = max(M.hallucination, 10) + data = world.time + (messagedelay SECONDS) /datum/reagent/mental/nicotine name = "Nicotine" @@ -598,7 +630,7 @@ description = "Nicotine is a stimulant and relaxant commonly found in tobacco products. It is very poisonous, unless at very low doses." reagent_state = LIQUID color = "#333333" - metabolism = 0.0005 + metabolism = 0.0016 * REM overdose = 3 data = 0 taste_description = "bitterness" @@ -606,10 +638,11 @@ badmessage = list("You start to crave nicotine...") worstmessage = list("You need your nicotine fix!") suppress_traumas = list( - /datum/brain_trauma/mild/phobia = 0.01, - /datum/brain_trauma/mild/muscle_weakness/ = 0.01 + /datum/brain_trauma/mild/phobia = 0.1, + /datum/brain_trauma/mild/muscle_weakness/ = 0.05 ) - conflicting_reagents = list() + conflicting_reagent = null + min_dose = 0.0064 * REM var/datum/modifier/modifier /datum/reagent/mental/nicotine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -626,17 +659,17 @@ id = "methylphenidate" description = "Methylphenidate is an AHDH treatment drug that treats basic distractions such as phobias and hallucinations at moderate doses. Withdrawl effects are rare. Side effects are rare, and include hallucinations." reagent_state = LIQUID - color = "#888888" - metabolism = 0.01 + color = "#8888AA" + metabolism = 0.01 * REM data = 0 taste_description = "paper" goodmessage = list("You feel focused.","You feel like you have no distractions.","You feel willing to work.") badmessage = list("You feel a little distracted...","You feel slight agitation...","You feel a dislike towards work...") worstmessage = list("You feel completely distrtacted...","You feel like you don't want to work...","You think you see things...") suppress_traumas = list( - /datum/brain_trauma/special/imaginary_friend = 40, - /datum/brain_trauma/mild/hallucinations = 20, - /datum/brain_trauma/mild/phobia/ = 20 + /datum/brain_trauma/special/imaginary_friend = 20, + /datum/brain_trauma/mild/hallucinations = 10, + /datum/brain_trauma/mild/phobia/ = 10 ) dosage_traumas = list( /datum/brain_trauma/mild/hallucinations = 5 @@ -652,17 +685,17 @@ description = "Fluvoxamine is safe and effective at treating basic phobias, as well as schizophrenia and muscle weakness at higher doses. Withdrawl effects are rare. Side effects are rare, and include hallucinations." reagent_state = LIQUID color = "#888888" - metabolism = 0.01 + metabolism = 0.01 * REM data = 0 - taste_description = "paper" + taste_description = "bitterness" goodmessage = list("You do not feel the need to worry about simple things.","You feel calm and level-headed.","You feel fine.") badmessage = list("You feel a little blue.","You feel slight agitation...","You feel a little nervous...") worstmessage = list("You worry about the littlest thing...","You feel like you are at risk...","You think you see things...") suppress_traumas = list( - /datum/brain_trauma/mild/phobia/ = 5, - /datum/brain_trauma/severe/split_personality = 20, - /datum/brain_trauma/special/imaginary_friend = 40, - /datum/brain_trauma/mild/muscle_weakness = 20 + /datum/brain_trauma/mild/phobia/ = 2, + /datum/brain_trauma/severe/split_personality = 10, + /datum/brain_trauma/special/imaginary_friend = 20, + /datum/brain_trauma/mild/muscle_weakness = 10 ) dosage_traumas = list( /datum/brain_trauma/mild/hallucinations = 5 @@ -677,15 +710,15 @@ id = "sertraline" description = "Sertraline is cheap, safe, and effective at treating basic phobias, however it does not last as long as other drugs of it's class. Withdrawl effects are uncommon. Side effects are rare." reagent_state = LIQUID - color = "#888888" - metabolism = 0.02 + color = "#88AA88" + metabolism = 0.02 * REM data = 0 taste_description = "paper" goodmessage = list("You feel fine.","You feel rational.","You feel decent.") badmessage = list("You feel a little blue.","You feel slight agitation...","You feel a little nervous...") worstmessage = list("You worry about the littlest thing...","You feel like you are at risk...","You think you see things...") suppress_traumas = list( - /datum/brain_trauma/mild/phobia/ = 5 + /datum/brain_trauma/mild/phobia/ = 2 ) dosage_traumas = list( /datum/brain_trauma/mild/hallucinations = 5 @@ -701,16 +734,16 @@ id = "escitalopram" description = "Escitalopram is expensive, safe and very effective at treating basic phobias as well as advanced phobias like monophobia. A common side effect is drowsiness, and a rare side effect is hallucinations. Withdrawl effects are uncommon." reagent_state = LIQUID - color = "#888888" - metabolism = 0.01 + color = "#FF8888" + metabolism = 0.01 * REM data = 0 - taste_description = "paper" + taste_description = "duct tape" goodmessage = list("You feel relaxed.","You feel at ease.","You feel care free.") badmessage = list("You feel worried.","You feel slight agitation.","You feel nervous.") worstmessage = list("You worry about the littlest thing...","You feel like you are at risk...","You think you see things...") suppress_traumas = list( /datum/brain_trauma/mild/phobia/ = 1, - /datum/brain_trauma/severe/monophobia = 10 + /datum/brain_trauma/severe/monophobia = 5 ) dosage_traumas = list( /datum/brain_trauma/mild/hallucinations = 5 @@ -729,15 +762,16 @@ id = "paroxetine" description = "Paroxetine is effective at treating basic phobias while also preventing the body from overheating. Side effects are rare, and include hallucinations. Withdrawl effects are frequent and unsafe." reagent_state = LIQUID - color = "#888888" - metabolism = 0.01 + color = "#AA8866" + metabolism = 0.01 * REM data = 0 - taste_description = "paper" + taste_description = "bandaid" goodmessage = list("You do not feel the need to worry about simple things.","You feel calm and level-headed.","You feel decent.") badmessage = list("You worry about the littlest thing.","You feel like you are at risk.","You think you see things.") worstmessage = list("You start to overreact to sounds and movement...","Your hear dangerous thoughts in your head...","You are really starting to see things...") + messagedelay = ANTIDEPRESSANT_MESSAGE_DELAY * 0.75 suppress_traumas = list( - /datum/brain_trauma/mild/phobia/ = 10 + /datum/brain_trauma/mild/phobia/ = 5 ) dosage_traumas = list( /datum/brain_trauma/mild/hallucinations = 5 @@ -762,16 +796,17 @@ id = "duloxetine" description = "Duloxetine is effective at treating basic phobias and concussions. A rare side effect is hallucinations. Withdrawl effects are common." reagent_state = LIQUID - color = "#888888" - metabolism = 0.01 + color = "#88FFFF" + metabolism = 0.01 * REM data = 0 - taste_description = "paper" + taste_description = "scotch tape" goodmessage = list("You feel at ease.","Your mind feels healthy..") badmessage = list("You worry about the littlest thing.","Your head starts to feel weird...","You think you see things.") worstmessage = list("You start to overreact to sounds and movement...","Your head feels really weird.","You are really starting to see things...") + messagedelay = ANTIDEPRESSANT_MESSAGE_DELAY * 0.75 suppress_traumas = list( - /datum/brain_trauma/mild/concussion = 10, - /datum/brain_trauma/mild/phobia/ = 10 + /datum/brain_trauma/mild/concussion = 5, + /datum/brain_trauma/mild/phobia/ = 5 ) dosage_traumas = list( /datum/brain_trauma/mild/hallucinations = 5 @@ -793,17 +828,18 @@ id = "venlafaxine" description = "Venlafaxine is effective at treating basic phobias, monophobia, and stuttering. Side effects are uncommon and include hallucinations. Withdrawl effects are common." reagent_state = LIQUID - color = "#888888" - metabolism = 0.01 + color = "#FF88FF" + metabolism = 0.01 * REM data = 0 - taste_description = "paper" + taste_description = "glue" goodmessage = list("You feel at ease.","Your mind feels healthy..","You feel unafraid to speak...") badmessage = list("You worry about the littlest thing.","You think you see things.") worstmessage = list("You start to overreact to sounds and movement...","You are really starting to see things...") + messagedelay = ANTIDEPRESSANT_MESSAGE_DELAY * 0.75 suppress_traumas = list( - /datum/brain_trauma/mild/phobia = 10, - /datum/brain_trauma/mild/stuttering = 5, - /datum/brain_trauma/severe/monophobia = 10 + /datum/brain_trauma/mild/phobia = 5, + /datum/brain_trauma/mild/stuttering = 2, + /datum/brain_trauma/severe/monophobia = 5 ) dosage_traumas = list( /datum/brain_trauma/mild/hallucinations = 10 @@ -825,22 +861,23 @@ id = "risperidone" description = "Risperidone is a potent antipsychotic medication used to treat schizophrenia, stuttering, speech impediment, monophobia, hallucinations, tourettes, and muscle spasms. Side effects are common and include pacifism. Withdrawl symptoms are dangerous and almost always occur." reagent_state = LIQUID - color = "#888888" - metabolism = 0.02 + color = "#FF4444" + metabolism = 0.02 * REM data = 0 - taste_description = "paper" + taste_description = "cardboard" goodmessage = list("Your mind feels as one.","You feel comfortable speaking.","Your body feels good.","Your thoughts are pure.") badmessage = list("You start hearing voices...","You think you see things...","You feel really upset...","You want attention...") - worstmessage = list("You think you start seeing things...","You swear someone inside you spoke to you...","You hate feeling alone...","You feel really upset.") + worstmessage = list("You think you start seeing things...","You swear someone inside you spoke to you...","You hate feeling alone...","You feel really upset...") + messagedelay = ANTIDEPRESSANT_MESSAGE_DELAY * 0.5 suppress_traumas = list( - /datum/brain_trauma/severe/split_personality = 10, - /datum/brain_trauma/special/imaginary_friend = 20, - /datum/brain_trauma/mild/stuttering = 5, - /datum/brain_trauma/mild/speech_impediment = 10, - /datum/brain_trauma/severe/monophobia = 10, - /datum/brain_trauma/mild/hallucinations = 10, - /datum/brain_trauma/mild/muscle_spasms = 20, - /datum/brain_trauma/mild/tourettes = 20 + /datum/brain_trauma/severe/split_personality = 5, + /datum/brain_trauma/special/imaginary_friend = 10, + /datum/brain_trauma/mild/stuttering = 2, + /datum/brain_trauma/mild/speech_impediment = 5, + /datum/brain_trauma/severe/monophobia = 5, + /datum/brain_trauma/mild/hallucinations = 5, + /datum/brain_trauma/mild/muscle_spasms = 10, + /datum/brain_trauma/mild/tourettes = 10 ) dosage_traumas = list( /datum/brain_trauma/severe/pacifism = 25 @@ -864,21 +901,22 @@ id = "olanzapine" description = "Olanzapine is a high-strength, expensive antipsychotic medication used to treat schizophrenia, stuttering, speech impediment, monophobia, hallucinations, tourettes, and muscle spasms. Side effects are common and include pacifism. The medication metabolizes quickly, and withdrawl is dangerous." reagent_state = LIQUID - color = "#888888" - metabolism = 0.02 + color = "#FF8844" + metabolism = 0.02 * REM data = 0 - taste_description = "paper" + taste_description = "paint" goodmessage = list("Your mind feels as one.","You feel comfortable speaking.","Your body feels good.","Your thoughts are pure.","Your body feels responsive.","You can handle being alone.") badmessage = list("You start hearing voices...","You think you see things...","You want a friend...") worstmessage = list("You think you start seeing things...","You swear someone inside you spoke to you...") + messagedelay = ANTIDEPRESSANT_MESSAGE_DELAY * 0.5 suppress_traumas = list( /datum/brain_trauma/severe/split_personality = 5, /datum/brain_trauma/special/imaginary_friend = 10, - /datum/brain_trauma/mild/stuttering = 2, - /datum/brain_trauma/mild/speech_impediment = 5, - /datum/brain_trauma/severe/monophobia = 5, - /datum/brain_trauma/mild/muscle_spasms = 10, - /datum/brain_trauma/mild/tourettes = 20 + /datum/brain_trauma/mild/stuttering = 1, + /datum/brain_trauma/mild/speech_impediment = 2, + /datum/brain_trauma/severe/monophobia = 2, + /datum/brain_trauma/mild/muscle_spasms = 5, + /datum/brain_trauma/mild/tourettes = 10 ) dosage_traumas = list( /datum/brain_trauma/severe/pacifism = 25 @@ -895,52 +933,15 @@ /datum/reagent/mental/escitalopram = 20 ) -/datum/reagent/mental/hextrasenil - name = "Hextrasenil" - id = "hextrasenil" - description = "Hextrasenil is a super-strength, fast-metabolizing, expensive antipsychotic medication intended for the use in criminal rehabilitation that treats tourettes, schizophrenia, hallucinations, and loyalty issues. Side effects include undying loyalty to NanoTrasen and respect for authority. Withdrawl effects include undying hatred towards NanoTrasen." - reagent_state = LIQUID - color = "#888888" - metabolism = 0.04 //Not meant to last a long time. - data = 0 - taste_description = "paper" - goodmessage = list("You feel loyal to NanoTrasen. Please take your pills.","You feel the need to contribute to cause of NanoTrasen. Please take your pills.","You wouldn't think about hurting NanoTrasen at all. Please take your pills.","You do not feel the need to express emotion. Please take your pills.","You feel that NanoTrasen has your best interests at heart. Please take your pills.","You respect the Chain of Command. Please take your pills.") - badmessage = list("You start to think if you need these pills...","Do I need these pills?","Should I be taking pills anymore?") - worstmessage = list("You start to realise that the system is corrupt...","NanoTrasen is corrupt...") - suppress_traumas = list( - /datum/brain_trauma/severe/split_personality = 5, //Gotta remove those enemies to nanotrasen. - /datum/brain_trauma/special/imaginary_friend = 5, - /datum/brain_trauma/mild/tourettes = 5 - ) - dosage_traumas = list( - /datum/brain_trauma/severe/pacifism = 25 - ) - withdrawal_traumas = list() - -/datum/reagent/mental/trisyndicotin - name = "Trisyndicotin" - id = "trisyndicotin" - description = "Trisyndicotin is a super-strength, expensive antipsychotic medication intended for the use in interigation. Side effects include undying hatred to NanoTrasen and disrespect for authority." - reagent_state = LIQUID - color = "#888888" - metabolism = 0.03 - data = 0 - taste_description = "freedom" - goodmessage = list("You distrust Nanotrasen and their people.","You feel woke.","You have urges to speak out against NanoTrasen.","You feel the need to complain about NanoTrasen on the web.","You feel like things should be better.") - badmessage = list() //Actual Freedom. - worstmessage = list() //Actual Freedom. - suppress_traumas = list( - /datum/brain_trauma/severe/pacifism = 10 - ) - /datum/reagent/mental/truthserum name = "Truth serum" id = "truthserum" - description = "This highly illegal, expensive, military strength truth serum is a must have for secret corporate interrogations. One 50u pill is good for almost 10 minutes of interrogation." + description = "This highly illegal, expensive, military strength truth serum is a must have for secret corporate interrogations. Do not ingest." reagent_state = LIQUID color = "#888888" - metabolism = 0.1 + metabolism = 0.05 * REM data = 0 + scannable = 0 taste_description = "something" goodmessage = list("You feel like you have nothing to hide.","You feel compelled to spill your secrets.","You feel like you can trust those around you.") badmessage = list() @@ -952,6 +953,7 @@ /datum/brain_trauma/severe/pacifism = 25 ) messagedelay = 30 + ingest_mul = 0 //Stomach acid will melt the nanobots //Things that are not cured by medication: //Dumbness @@ -964,6 +966,73 @@ //Discoordination //Aphasia +/datum/reagent/calomel + name = "Calomel" + id = "calomel" + description = "A highly toxic medicine that quickly purges most chemicals from the bloodstream. Overdose causes bloodloss and more toxin buildup, however works twice as fast." + color = "#222244" + metabolism = 0.5 * REM + overdose = 30 + scannable = 1 + taste_description = "thick salt" + reagent_state = SOLID + +/datum/reagent/calomel/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + var/is_overdosed = overdose && (dose > overdose) + if(is_overdosed) + removed *= 2 + + var/amount_to_purge = removed*4 //Every unit removes 4 units of other chemicals + var/amount_purged = 0 + + for(var/datum/reagent/selected in M.reagents.reagent_list) + if(selected == src) + continue + if(selected.id == "blood" && !is_overdosed) + continue + var/local_amount = min(amount_to_purge, selected.volume) + M.reagents.remove_reagent(selected.id, local_amount) + amount_to_purge -= local_amount + amount_purged += local_amount + if(amount_to_purge <= 0) + break + + M.adjustToxLoss(removed + amount_purged*0.5) //15u has the potential to do 15 + 30 toxin damage in 30 seconds + + . = ..() + +/datum/reagent/pulmodeiectionem + name = "Pulmodeiectionem" + id = "pulmodeiectionem" + description = "A powdery chemical that damages the mucus lining in the the main broncus and the trachea, allowing particles to easily escape the lungs. Only works when inhaled. May cause long term damage to the lungs, and oxygen deprevation." + color = "#550055" + metabolism = 2 * REM + overdose = 10 + scannable = 1 + taste_description = "coarse dust" + reagent_state = SOLID + +/datum/reagent/pulmodeiectionem/affect_breathe(var/mob/living/carbon/human/H, var/alien, var/removed) + if(istype(H)) + var/obj/item/organ/L = H.internal_organs_by_name["lungs"] + if(istype(L) && !L.robotic && !L.is_broken()) + var/amount_to_purge = removed*5 //Every unit removes 5 units of other chemicals. + for(var/datum/reagent/selected in H.breathing.reagent_list) + if(selected == src) + continue + var/local_amount = min(amount_to_purge, selected.volume) + H.breathing.remove_reagent(selected.id, local_amount) + amount_to_purge -= local_amount + if(amount_to_purge <= 0) + break + + H.adjustOxyLoss(2*removed) //Every unit deals 2 oxy damage + if(prob(75)) //Cough uncontrolably + H.emote("cough") + L.take_damage(0.2*removed) //Every 5 units deals 1 lung damage, absolute worse case scenario. + + . = ..() + /datum/reagent/rezadone name = "Rezadone" id = "rezadone" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm index a4f59cafdc6..b64a5f0cd6b 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm @@ -368,30 +368,6 @@ if(volume >= 1) T.wet_floor(2) -/datum/reagent/cardox - name = "Cardox" - id = "cardox" - description = "Cardox is an expensive, NanoTrasen designed cleaner intended to eliminate liquid phoron stains from suits." - reagent_state = LIQUID - color = "#EEEEEE" - taste_description = "cherry" - -/datum/reagent/toxin/cardox/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) - .. () - if(alien == IS_VAURCA) - affect_blood(M, alien, removed * 0.25) - -/datum/reagent/cardox/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) - if(alien == IS_VAURCA) - M.adjustToxLoss(removed * 5) - else - M.adjustToxLoss(removed * 2) - -/datum/reagent/cardox/touch_turf(var/turf/T) - if(volume >= 1) - for(var/mob/living/carbon/slime/M in T) - M.adjustToxLoss(rand(10, 20)) - /datum/reagent/silicate name = "Silicate" id = "silicate" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index 3aab5d1da6e..5df7eefae71 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -47,20 +47,33 @@ return ..() +/datum/reagent/toxin/panotoxin + name = "Panotoxin" + id = "panotoxin" + description = "A strange poison from the strange panocelium mushroom that causes intense pain when injected." + reagent_state = LIQUID + color = "#008844" + strength = 0 + taste_description = "stinging needles" + +/datum/reagent/toxin/panotoxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + M.adjustHalLoss(removed*15) + /datum/reagent/toxin/phoron name = "Phoron" id = "phoron" - description = "Phoron in its liquid form." + description = "Phoron in its liquid form. Twice as potent when breathed in." reagent_state = LIQUID color = "#9D14DB" strength = 30 touch_met = 5 taste_mult = 1.5 + breathe_mul = 2 /datum/reagent/toxin/phoron/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.species.has_organ["filtration bit"] && alien == IS_VAURCA) + if(alien == IS_VAURCA && H.species.has_organ["filtration bit"]) metabolism = REM * 20 //vaurcae metabolise phoron faster than other species - good for them if their filter isn't broken. var/obj/item/organ/vaurca/filtrationbit/F = H.internal_organs_by_name["filtration bit"] if(isnull(F)) @@ -80,6 +93,9 @@ else ..() + + + /datum/reagent/toxin/phoron/touch_mob(var/mob/living/L, var/amount) if(istype(L)) L.adjust_fire_stacks(amount / 5) @@ -97,6 +113,40 @@ T.assume_gas("phoron", volume, T20C) remove_self(volume) +/datum/reagent/toxin/cardox + name = "Cardox" + id = "cardox" + description = "Cardox is an mildly toxic, expensive, NanoTrasen designed cleaner intended to eliminate liquid phoron stains from suits." + reagent_state = LIQUID + color = "#EEEEEE" + taste_description = "cherry" + conflicting_reagent = /datum/reagent/toxin/phoron + strength = 1 + +/datum/reagent/toxin/cardox/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) + .. () + if(alien == IS_VAURCA) + affect_blood(M, alien, removed * 0.25) + +/datum/reagent/toxin/cardox/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + if(alien == IS_VAURCA) + M.adjustToxLoss(removed * strength*2) + else + M.adjustToxLoss(removed * strength) + +/datum/reagent/toxin/cardox/affect_conflicting(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagent/conflicting) + var/amount = min(removed, conflicting.volume) + holder.remove_reagent(conflicting.id, amount) + +/datum/reagent/toxin/cardox/touch_turf(var/turf/T, var/amount) + + if(amount >= 1) + for(var/mob/living/carbon/slime/M in T) + M.adjustToxLoss(amount*10) + + var/datum/gas_mixture/environment = T.return_air() + environment.adjust_gas("phoron",-amount*10) + /datum/reagent/toxin/cyanide //Fast and Lethal name = "Cyanide" id = "cyanide" @@ -251,16 +301,6 @@ removed *= M.reagent_permeability() affect_blood(M, alien, removed*0.5) -/datum/reagent/acid/polyacid - name = "Polytrinic acid" - id = "pacid" - description = "Polytrinic acid is a an extremely corrosive chemical substance." - reagent_state = LIQUID - color = "#8E18A9" - power = 6 - meltdose = 4 - taste_description = "acid" - /datum/reagent/lexorin name = "Lexorin" id = "lexorin" @@ -333,12 +373,14 @@ /datum/reagent/soporific name = "Soporific" id = "stoxin" - description = "An effective hypnotic used to treat insomnia." + description = "An effective hypnotic used to treat insomnia, can act as a sedative. Lasts three times longer when inhaled." reagent_state = LIQUID color = "#009CA8" metabolism = REM * 0.5 overdose = REAGENTS_OVERDOSE taste_description = "bitterness" + breathe_met = 0.33 + var/total_strength = 0 /datum/reagent/soporific/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) var/mob/living/carbon/human/H = M @@ -360,12 +402,13 @@ /datum/reagent/chloralhydrate name = "Chloral Hydrate" id = "chloralhydrate" - description = "A powerful sedative." + description = "A powerful sedative. Lasts three times longer when inhaled." reagent_state = SOLID color = "#000067" metabolism = REM * 0.5 overdose = REAGENTS_OVERDOSE * 0.5 taste_description = "bitterness" + breathe_met = 0.33 /datum/reagent/chloralhydrate/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) var/mob/living/carbon/human/H = M @@ -401,13 +444,15 @@ /datum/reagent/space_drugs name = "Space drugs" id = "space_drugs" - description = "An illegal chemical compound used as drug." + description = "An illegal chemical compound used as drug. Lasts twice as long when inhaled." reagent_state = LIQUID color = "#60A584" metabolism = REM * 0.5 overdose = REAGENTS_OVERDOSE taste_description = "bitterness" taste_mult = 0.4 + breathe_mul = 2 + breathe_met = REM * 0.25 /datum/reagent/space_drugs/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) var/mob/living/carbon/human/H = M diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index b43b06b886f..cb845a26457 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -516,6 +516,42 @@ required_reagents = list("phoron" = 1, "hydrazine" = 1, "ammonia" = 1) result_amount = 3 +/datum/chemical_reaction/calomel + name = "Calomel" + id = "calomel" + result = "calomel" + required_reagents = list("mercury" = 1, "sodiumchloride" = 1, "ammonia" = 1) + result_amount = 3 + +/datum/chemical_reaction/cardox + name = "Cardox" + id = "cardox" + result = "cardox" + required_reagents = list("platinum" = 1, "carbon" = 1, "sterilizine" = 1) + result_amount = 3 + +/datum/chemical_reaction/cardox_removal + name = "Cardox Removal" + id = "cardox_removal" + result = "carbon" + required_reagents = list("cardox" = 0.1, "phoron" = 1) + result_amount = 0 + +/datum/chemical_reaction/koispasteclean + name = "Filtered K'ois" + id = "koispasteclean" + result = "koispasteclean" + required_reagents = list("koispaste" = 2,"cardox" = 0.1) + catalysts = list("cardox" = 5) + result_amount = 1 + +/datum/chemical_reaction/pulmodeiectionem + name = "Pulmodeiectionem" + id = "pulmodeiectionem" + result = "pulmodeiectionem" + required_reagents = list("calomel" = 1, "lexorin" = 1) + result_amount = 2 + //Mental Medication /datum/chemical_reaction/methylphenidate @@ -588,20 +624,6 @@ required_reagents = list("mindbreaker" = 1, "space_drugs" = 1, "silicon" = 1) result_amount = 3 -/datum/chemical_reaction/hextrasenil - name = "Hextrasenil" - id = "hextrasenil" - result = "hextrasenil" - required_reagents = list("truthserum" = 1, "risperidone" = 1, "mindbreaker" = 1) - result_amount = 3 - -/datum/chemical_reaction/trisyndicotin - name = "Trisyndicotin" - id = "trisyndicotin" - result = "trisyndicotin" - required_reagents = list("truthserum" = 1, "risperidone" = 1, "space_drugs" = 1) - result_amount = 3 - /datum/chemical_reaction/truthserum name = "Truthserum" id = "truthserum" @@ -609,26 +631,11 @@ required_reagents = list("mindbreaker" = 1, "synaptizine" = 1, "phoron" = 0.1) result_amount = 2 -/datum/chemical_reaction/cardox - name = "Cardox" - id = "cardox" - result = "cardox" - required_reagents = list("platinum" = 1, "carbon" = 1, "sterilizine" = 1) - result_amount = 3 - -/datum/chemical_reaction/cardox_removal - name = "Cardox Removal" - id = "cardox_removal" - result = "carbon" - required_reagents = list("cardox" = 0.1, "phoron" = 1) - result_amount = 0 - -/datum/chemical_reaction/koispasteclean - name = "Filtered K'ois" - id = "koispasteclean" - result = "koispasteclean" - required_reagents = list("koispaste" = 2,"cardox" = 0.1) - catalysts = list("cardox" = 5) +/datum/chemical_reaction/feartoxin + name = "Feartoxin" + id = "feartoxin" + result = "feartoxin" + required_reagents = list("mindbreaker" = 1, "synaptizine" = 1, "space_drugs" = 1) result_amount = 1 /* Solidification */ @@ -1446,12 +1453,6 @@ Z.loc = get_turf(holder.my_atom) Z.announce_to_ghosts() - - - - - - /* ==================== Food diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 23b4c59ce2a..85c1b619bcc 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -173,5 +173,6 @@ return 1 var/trans = reagents.trans_to(target, amount_per_transfer_from_this) + playsound(src, 'sound/effects/pour.ogg', 25, 1) user << "You transfer [trans] units of the solution to [target]." return 1 diff --git a/code/modules/reagents/reagent_containers/food/lunch.dm b/code/modules/reagents/reagent_containers/food/lunch.dm index 0ff862e53e7..f274c5bb6c8 100644 --- a/code/modules/reagents/reagent_containers/food/lunch.dm +++ b/code/modules/reagents/reagent_containers/food/lunch.dm @@ -75,7 +75,9 @@ var/list/lunchables_drink_reagents_ = list( ) // This default list is a bit different, it contains items we don't want -var/list/lunchables_ethanol_reagents_ = list( +var/list/lunchables_alcohol_reagents_ = list( + /datum/reagent/alcohol/ethanol, + /datum/reagent/alcohol/butanol, /datum/reagent/alcohol/ethanol/acid_spit, /datum/reagent/alcohol/ethanol/atomicbomb, /datum/reagent/alcohol/ethanol/beepsky_smash, @@ -110,10 +112,10 @@ var/list/lunchables_ethanol_reagents_ = list( lunchables_drink_reagents_ = init_lunchable_reagent_list(lunchables_drink_reagents_, /datum/reagent/drink) return lunchables_drink_reagents_ -/proc/lunchables_ethanol_reagents() - if(!(lunchables_ethanol_reagents_[lunchables_ethanol_reagents_[1]])) - lunchables_ethanol_reagents_ = init_lunchable_reagent_list(lunchables_ethanol_reagents_, /datum/reagent/alcohol/ethanol) - return lunchables_ethanol_reagents_ +/proc/lunchables_alcohol_reagents() + if(!(lunchables_alcohol_reagents_[lunchables_alcohol_reagents_[1]])) + lunchables_alcohol_reagents_ = init_lunchable_reagent_list(lunchables_alcohol_reagents_, /datum/reagent/alcohol) + return lunchables_alcohol_reagents_ /proc/init_lunchable_list(var/list/lunches) . = list() diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index 57d0c9edf10..bc3e12cd33c 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -4728,6 +4728,15 @@ nutriment_desc = list("hellfire" = 6) nutriment_amt = 24// 10 Chilis is a lot. +/obj/item/weapon/reagent_containers/food/snacks/breakfast_wrap + name = "breakfast wrap" + desc = "Bacon, eggs, cheese, and tortilla grilled to perfection." + icon_state = "breakfast_wrap" + bitesize = 4 + center_of_mass = list("x"=16, "y"=16) + nutriment_desc = list("tortilla" = 6) + nutriment_amt = 6 + /obj/item/weapon/reagent_containers/food/snacks/burrito_hell/Initialize() . = ..() reagents.add_reagent("protein", 9) @@ -4963,5 +4972,136 @@ . = ..() reagents.add_reagent("protein", 3) +/obj/item/weapon/reagent_containers/food/snacks/truffle + name = "chocolate truffle" + desc = "Rich bite-sized chocolate." + icon_state = "truffle" + nutriment_amt = 0 + bitesize = 4 + +/obj/item/weapon/reagent_containers/food/snacks/Initialize() + . = ..() + reagents.add_reagent("coco", 4) + +/obj/item/weapon/reagent_containers/food/snacks/truffle/random + name = "mystery chocolate truffle" + desc = "Rich bite-sized chocolate with a mystery filling!" + +/obj/item/weapon/reagent_containers/food/snacks/random/Initialize() + . = ..() + var/reagent_string = pick(list("cream","cherryjelly","mint","frostoil","capsaicin","cream","coffee","milkshake")) + reagents.add_reagent(reagent_string, 4) + +/obj/item/weapon/reagent_containers/food/snacks/bacon_flatbread + name = "bacon cheese flatbread" + desc = "Not a pizza." + icon_state = "bacon_pizza" + nutriment_desc = list("flatbread" = 5) + nutriment_amt = 5 + +/obj/item/weapon/reagent_containers/food/snacks/bacon_flatbread/Initialize() + . = ..() + reagents.add_reagent("protein", 5) + +/obj/item/weapon/reagent_containers/food/snacks/meat_pocket + name = "meat pocket" + desc = "Meat and cheese stuffed in a flatbread pocket, grilled to perfection." + icon_state = "meat_pocket" + nutriment_desc = list("flatbread" = 3) + nutriment_amt = 3 + +/obj/item/weapon/reagent_containers/food/snacks/meat_pocket/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + +/obj/item/weapon/reagent_containers/food/snacks/fish_taco + name = "carp taco" + desc = "A questionably cooked fish taco decorated with herbs, spices, and special sauce." + icon_state = "fish_taco" + nutriment_desc = list("flatbread" = 3) + nutriment_amt = 3 + +/obj/item/weapon/reagent_containers/food/snacks/fish_taco/Initialize() + . = ..() + reagents.add_reagent("seafood",3) + +/obj/item/weapon/reagent_containers/food/snacks/nt_muffin + name = "\improper NtMuffin" + desc = "A NanoTrasen sponsered biscuit with egg, cheese, and sausage." + icon_state = "nt_muffin" + nutriment_desc = list("biscuit" = 3) + nutriment_amt = 3 + +/obj/item/weapon/reagent_containers/food/snacks/nt_muffin/Initialize() + . = ..() + reagents.add_reagent("protein",5) + +/obj/item/weapon/reagent_containers/food/snacks/pineapple_ring + name = "pineapple ring" + desc = "What the hell is this?" + icon_state = "pineapple_ring" + nutriment_desc = list("sweetness" = 2) + nutriment_amt = 2 + +/obj/item/weapon/reagent_containers/food/snacks/pineapple_ring/Initialize() + . = ..() + reagents.add_reagent("pineapplejuice",3) + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/pineapple + name = "ham & pineapple pizza" + desc = "One of the most debated pizzas in existence." + icon_state = "pineapple_pizza" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/pineappleslice + slices_num = 6 + center_of_mass = list("x"=16, "y"=11) + nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "ham" = 10) + nutriment_amt = 30 + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/pineapple/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + reagents.add_reagent("cheese", 5) + reagents.add_reagent("tomatojuice", 6) + +/obj/item/weapon/reagent_containers/food/snacks/pineappleslice + name = "ham & pineapple pizza slice" + desc = "A slice of contraband." + icon_state = "pineapple_pizza_slice" + filling_color = "#BAA14C" + bitesize = 2 + center_of_mass = list("x"=18, "y"=13) + +/obj/item/weapon/reagent_containers/food/snacks/pineappleslice/filled + nutriment_desc = list("pizza crust" = 5, "tomato" = 5) + nutriment_amt = 5 + +/obj/item/weapon/reagent_containers/food/snacks/baconburger + name = "bacon burger" + desc = "The cornerstone of every nutritious breakfast, now with bacon!" + icon_state = "hburger" + filling_color = "#D63C3C" + center_of_mass = list("x"=16, "y"=11) + nutriment_desc = list("bun" = 2) + nutriment_amt = 3 + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/baconburger/Initialize() + reagents.add_reagent("protein", 4) + +/obj/item/weapon/reagent_containers/food/snacks/blt + name = "BLT" + desc = "Bacon, lettuce, tomatoes. The perfect lunch." + icon_state = "blt" + filling_color = "#D63C3C" + center_of_mass = list("x"=16, "y"=16) + nutriment_desc = list("bread" = 4) + nutriment_amt = 4 + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/blt/Initialize() + reagents.add_reagent("protein", 4) + + #undef NUTRIMENT_GOOD #undef NUTRIMENT_BAD diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 69af679aaf6..583ceadd10b 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -41,6 +41,7 @@ user.do_attack_animation(M) user << "You inject [M] with [src]." M << "You feel a tiny prick!" + playsound(src, 'sound/items/hypospray.ogg',25) if(M.reagents) var/contained = reagentlist() diff --git a/code/modules/reagents/reagent_containers/inhaler.dm b/code/modules/reagents/reagent_containers/inhaler.dm new file mode 100644 index 00000000000..122c9593d8a --- /dev/null +++ b/code/modules/reagents/reagent_containers/inhaler.dm @@ -0,0 +1,189 @@ +//Inhalers +//Just like hypopsray code +/obj/item/weapon/reagent_containers/inhaler + name = "autoinhaler" + desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel." + icon = 'icons/obj/syringe.dmi' + item_state = "autoinjector" + icon_state = "inhaler" + unacidable = 1 + amount_per_transfer_from_this = 5 + volume = 5 + w_class = 2 + possible_transfer_amounts = null + flags = OPENCONTAINER + slot_flags = SLOT_BELT + +/obj/item/weapon/reagent_containers/inhaler/attack(mob/living/M as mob, mob/user as mob) + + if(!reagents.total_volume) + to_chat(user,"\The [src] is empty.") + return + + var/mob/living/carbon/human/H = M + + if (!istype(H)) + return + + if ( ((CLUMSY in user.mutations) || (DUMB in user.mutations)) && prob(10)) + to_chat(user,"Your hand slips from clumsiness!") + eyestab(M,user) + if(M.reagents) + var/contained = reagentlist() + var/trans = reagents.trans_to_mob(M, amount_per_transfer_from_this, CHEM_TOUCH) + admin_inject_log(user, M, src, contained, trans) + playsound(src.loc, 'sound/items/stimpack.ogg', 50, 1) + user.visible_message("[user] accidentally sticks the [src] in [M]'s eyes!","You accidentally stick the [src] in [M]'s eyes!") + to_chat(user,"[trans] units injected. [reagents.total_volume] units remaining in \the [src].") + return + + if (!user.IsAdvancedToolUser()) + to_chat(user,"You don't have the dexterity to do this!") + return + + if(user == M) + if(!M.can_eat(src)) + return + else + if(!M.can_force_feed(user, src)) + return + + user.setClickCooldown(DEFAULT_QUICK_COOLDOWN) + user.do_attack_animation(M) + + if(user == M) + user.visible_message("[user] injects themselves with the [src]","You stick the [src] in your mouth and press the injection button") + else + user.visible_message("[user] attempts to administer \the [src] to [M]...","You attempt to administer \the [src] to [M]...") + if (!do_after(user, 1 SECONDS, act_target = M)) + to_chat(user,"You and the target need to be standing still in order to inject \the [src].") + return + + user.visible_message("[user] injects [M] with the [src].","You stick the [src] in [M]'s mouth and press the injection button") + + if(M.reagents) + var/contained = reagentlist() + var/trans = reagents.trans_to_mob(M, amount_per_transfer_from_this, CHEM_BREATHE) + admin_inject_log(user, M, src, contained, trans) + playsound(src.loc, 'sound/items/stimpack.ogg', 50, 1) + to_chat(user,"[trans] units injected. [reagents.total_volume] units remaining in \the [src].") + + return + +/obj/item/weapon/reagent_containers/inhaler/attack(mob/M as mob, mob/user as mob) + ..() + if(reagents.total_volume <= 0) //Prevents autoinjectors to be refilled. + flags &= ~OPENCONTAINER + update_icon() + return + +/obj/item/weapon/reagent_containers/inhaler/update_icon() + if(reagents.total_volume > 0) + icon_state = "[initial(icon_state)]1" + else + icon_state = "[initial(icon_state)]0" + +/obj/item/weapon/reagent_containers/inhaler/examine(mob/user) + ..(user) + if(reagents && reagents.reagent_list.len) + user << "It is currently loaded." + else + user << "It is spent." + +/obj/item/weapon/reagent_containers/inhaler/dexalin + name = "autoinhaler (dexalin)" + desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains dexalin." + + Initialize() + . =..() + reagents.add_reagent("dexalin", volume) + update_icon() + return + +/obj/item/weapon/reagent_containers/inhaler/peridaxon + name = "autoinhaler (peridaxon)" + desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains peridaxon." + + Initialize() + . =..() + reagents.add_reagent("peridaxon", volume) + update_icon() + return + +/obj/item/weapon/reagent_containers/inhaler/hyperzine + name = "autoinhaler (hyperzine)" + desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains hyperzine." + + Initialize() + . =..() + reagents.add_reagent("hyperzine", volume) + update_icon() + return + +/obj/item/weapon/reagent_containers/inhaler/phoron + name = "autoinhaler (phoron)" + desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains phoron." + + Initialize() + . =..() + reagents.add_reagent("phoron", volume) + update_icon() + return + +/obj/item/weapon/reagent_containers/inhaler/phoron_special + name = "vaurca autoinhaler (phoron)" + desc = "A strange device that contains some sort of heavy-duty bag and mouthpiece combo." + icon_state = "anthaler" + volume = 10 + Initialize() + . =..() + reagents.add_reagent("phoron", volume) + update_icon() + return + +/obj/item/weapon/reagent_containers/inhaler/soporific + name = "autoinhaler (soporific)" + desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains soporific." + icon_state = "so_inhaler" + volume = 10 + + Initialize() + . =..() + reagents.add_reagent("stoxin", volume) + update_icon() + return + +/obj/item/weapon/reagent_containers/inhaler/space_drugs + name = "autoinhaler (space drugs)" + desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains space drugs." + + Initialize() + . =..() + reagents.add_reagent("space_drugs", volume) + update_icon() + return + +/obj/item/weapon/reagent_containers/inhaler/ammonia + name = "autoinhaler (ammonia)" + desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains ammonia." + + Initialize() + . =..() + reagents.add_reagent("ammonia", volume) + update_icon() + return + +/obj/item/weapon/reagent_containers/inhaler/pulmodeiectionem + name = "autoinhaler (pulmodeiectionem)" + desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains pulmodeiectionem." + + Initialize() + . =..() + reagents.add_reagent("pulmodeiectionem", volume) + update_icon() + return + + + + + diff --git a/code/modules/reagents/reagent_containers/inhaler_advanced.dm b/code/modules/reagents/reagent_containers/inhaler_advanced.dm new file mode 100644 index 00000000000..c3b134ed043 --- /dev/null +++ b/code/modules/reagents/reagent_containers/inhaler_advanced.dm @@ -0,0 +1,201 @@ +//Advanced Inhalers +//Just like hypopsray code + +/obj/item/weapon/reagent_containers/personal_inhaler_cartridge + name = "small inhaler cartridge" + desc = "Fill this when chemicals and attach this to personal inhalers. Contains enough areosol for 15u of reagents. The container must be activated for aerosol reagents to mix for the use in inhalers." + icon = 'icons/obj/syringe.dmi' + item_state = "buildpipe" + icon_state = "pi_cart_small" + volume = 15 + w_class = 2 + unacidable = 1 + amount_per_transfer_from_this = 5 + possible_transfer_amounts = list(5,10,15) + flags = OPENCONTAINER + slot_flags = SLOT_BELT + origin_tech = list(TECH_BIO = 2, TECH_MATERIAL = 2) + matter = list(DEFAULT_WALL_MATERIAL = 250) + +/obj/item/weapon/reagent_containers/personal_inhaler_cartridge/examine(var/mob/user) + if(!..(user, 2)) + return + + if(is_open_container()) + if(reagents && reagents.reagent_list.len) + to_chat(user,"It contains [round(reagents.total_volume, accuracy)] units of non-aerosol mix.") + else + to_chat(user,"It is empty.") + else + to_chat(user,"The reagents are secured in the aerosol mix.") + +/obj/item/weapon/reagent_containers/personal_inhaler_cartridge/attack_self(mob/user as mob) + if(is_open_container()) + to_chat(user,"With a quick twist of the lid, you secure the reagents inside \the [src].") + flags ^= OPENCONTAINER + else + to_chat(user,"\The reagents inside [src] are already secured.") + return + +/obj/item/weapon/reagent_containers/personal_inhaler_cartridge/large + name = "large inhaler cartridge" + icon_state = "pi_cart_medium" + volume = 30 + w_class = 3 + amount_per_transfer_from_this = 10 + possible_transfer_amounts = list(5,10,15,30) + origin_tech = list(TECH_BIO = 4, TECH_MATERIAL = 4) + +/obj/item/weapon/reagent_containers/personal_inhaler_cartridge/bluespace + name = "bluespace inhaler cartridge" + icon_state = "pi_cart_large" + volume = 60 + w_class = 3 + amount_per_transfer_from_this = 10 + possible_transfer_amounts = list(5,10,15,30,60) + origin_tech = list(TECH_BLUESPACE = 2, TECH_BIO = 6, TECH_MATERIAL = 6) + +/obj/item/weapon/personal_inhaler + name = "inhaler" + desc = "A safe way to administer small amounts of drugs into the lungs by trained personnel." + icon = 'icons/obj/syringe.dmi' + item_state = "buildpipe" + icon_state = "pi" + w_class = 2 + slot_flags = SLOT_BELT + var/obj/item/weapon/reagent_containers/stored_cartridge + var/transfer_amount = 5 + origin_tech = list(TECH_BIO = 2, TECH_MATERIAL = 2) + var/eject_when_empty = FALSE + +/obj/item/weapon/personal_inhaler/examine(var/mob/user) + if(!..(user, 2)) + return + if(stored_cartridge) + to_chat(user,"\The [stored_cartridge] is attached to \the [src].") + +/obj/item/weapon/personal_inhaler/update_icon() + cut_overlays() + if(stored_cartridge) + add_overlay(stored_cartridge.icon_state) + +/obj/item/weapon/personal_inhaler/attack_self(mob/user as mob) + if(stored_cartridge) + user.put_in_hands(stored_cartridge) + to_chat(user,"You remove \the [stored_cartridge] from \the [src].") + stored_cartridge.update_icon() + stored_cartridge = null + + update_icon() + +/obj/item/weapon/personal_inhaler/attack(mob/living/M as mob, mob/user as mob) + + var/mob/living/carbon/human/H = M + + if (!istype(H)) + return + + if(!stored_cartridge) + to_chat(user,"\The [src] has no cartridge installed!") + return + + if(!stored_cartridge.reagents || !stored_cartridge.reagents.total_volume) + to_chat(user,"\The [src]'s cartridge is empty!") + return + + if ( ((CLUMSY in user.mutations) || (DUMB in user.mutations)) && prob(10)) + to_chat(user,"Your hand slips from clumsiness!") + eyestab(M,user) + if(M.reagents) + var/contained = stored_cartridge.reagentlist() + var/trans = stored_cartridge.reagents.trans_to_mob(M, transfer_amount, CHEM_TOUCH) + admin_inject_log(user, M, src, contained, trans) + user.visible_message("[user] accidentally sticks \the [src] in [M]'s eye and presses the injection button!","You accidentally stick the [src] in [M]'s eye and press the injection button!") + to_chat(user,"[trans] units injected. [reagents.total_volume] units remaining in \the [src].") + playsound(src.loc, 'sound/items/stimpack.ogg', 50, 1) + if(eject_when_empty) + to_chat(user,"\The [stored_cartridge] automatically ejects from \the [src].") + stored_cartridge.forceMove(user.loc) + stored_cartridge.update_icon() + stored_cartridge = null + update_icon() + 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(M) + + if(user == M) + user.visible_message("[user] sticks \the [src] in their mouth and presses the injection button.","You stick \the [src] in your mouth and press the injection button") + else + user.visible_message("[user] attempts to administer \the [src] to [M]...","You attempt to administer \the [src] to [M]...") + if (!do_after(user, 1 SECONDS, act_target = M)) + to_chat(user,"You and \the [M] need to be standing still in order to inject \the [src].") + return + + user.visible_message("[user] sticks \the [src] in [M]'s mouth and presses the injection button.","You stick \the [src] in [M]'s mouth and press the injection button") + + if(M.reagents) + var/contained = stored_cartridge.reagentlist() + var/trans = stored_cartridge.reagents.trans_to_mob(M, transfer_amount, CHEM_BREATHE) + admin_inject_log(user, M, src, contained, trans) + to_chat(user,"[trans] units injected. [reagents.total_volume] units remaining in \the [src].") + playsound(src.loc, 'sound/items/stimpack.ogg', 50, 1) + if(eject_when_empty) + to_chat(user,"\The [stored_cartridge] automatically ejects from \the [src].") + stored_cartridge.forceMove(user.loc) + stored_cartridge.update_icon() + stored_cartridge = null + update_icon() + + return + +/obj/item/weapon/personal_inhaler/attackby(var/obj/item/weapon/reagent_containers/personal_inhaler_cartridge/cartridge as obj, var/mob/user as mob) + if(istype(cartridge)) + if(src.stored_cartridge) + to_chat(user,"\The [src] already has a cartridge.") + return + if(cartridge.is_open_container()) + to_chat(user,"\The [cartridge] needs to be secured first.") + return + user.remove_from_mob(cartridge) + src.stored_cartridge = cartridge + cartridge.loc = src + update_icon() + return + . = ..() + +/obj/item/weapon/personal_inhaler/combat + name = "combat inhaler" + desc = "A large, bulky inhaler design that injects the entire contents of the loaded cartridge via an aerosol system in a single button press." + icon_state = "pi_combat" + w_class = 3 + transfer_amount = 60 + origin_tech = list(TECH_BIO = 4, TECH_MATERIAL = 4, TECH_ENGINEERING = 4) + eject_when_empty = TRUE + +/obj/item/weapon/reagent_containers/personal_inhaler_cartridge/large/hyperzine + name = "large inhaler cartridge (hyperzine)" + Initialize() + . =..() + reagents.add_reagent("hyperzine", 30) + flags ^= OPENCONTAINER + update_icon() + return + +/obj/item/weapon/reagent_containers/personal_inhaler_cartridge/large/inaprovaline + name = "large inhaler cartridge (inaprovaline)" + Initialize() + . =..() + reagents.add_reagent("inaprovaline", 30) + flags ^= OPENCONTAINER + update_icon() + return \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 545fc0fba86..df2257f58fa 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -170,22 +170,6 @@ Initialize() . = ..() reagents.add_reagent("escitalopram", 15) - -/obj/item/weapon/reagent_containers/pill/hextrasenil - name = "Hextrasenil pill" - desc = "Don't forget to take your pills." - icon_state = "pill6" - Initialize() - . = ..() - reagents.add_reagent("hextrasenil", 30) - -/obj/item/weapon/reagent_containers/pill/trisyndicotin - name = "Trisyndicotin pill" - desc = "For when you need a little convincing." - icon_state = "pill4" - Initialize() - . = ..() - reagents.add_reagent("trisyndicotin", 30) /obj/item/weapon/reagent_containers/pill/inaprovaline name = "Inaprovaline pill" diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 5070f5ffcf5..8e8a4d0f291 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -339,12 +339,21 @@ desc = "Contains aggressive drugs meant for torture." Initialize() . = ..() - reagents.add_reagent("space_drugs", 5) - reagents.add_reagent("mindbreaker", 5) - reagents.add_reagent("cryptobiolin", 5) + reagents.add_reagent("panotoxin", 5) + reagents.add_reagent("mindbreaker", 10) mode = SYRINGE_INJECT update_icon() +/obj/item/weapon/reagent_containers/syringe/calomel + name = "Syringe (calomel)" + desc = "Contains purging medicine." + Initialize() + . = ..() + reagents.add_reagent("calomel", 15) + mode = SYRINGE_INJECT + update_icon() + + /obj/item/weapon/reagent_containers/syringe/ld50_syringe/choral Initialize() . = ..() diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 22e5ec87513..1ce22422be1 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -108,4 +108,49 @@ req_tech = list(TECH_BIO = 4, TECH_MATERIAL = 7, TECH_MAGNET = 5, TECH_DATA = 4) materials = list (DEFAULT_WALL_MATERIAL = 12500, "glass" = 7500, "silver" = 1500, "gold" = 1500, "diamond" = 750) build_path = /obj/item/weapon/scalpel/manager - sort_string = "MBBAD" \ No newline at end of file + sort_string = "MBBAD" + +/datum/design/item/medical/inhaler + name = "Inhaler" + desc = "A very basic personal inhaler that directly injects chemicals into the lungs using a basic cartridge aerosol method." + id = "inhaler" + req_tech = list(TECH_BIO = 2, TECH_MATERIAL = 2) + materials = list(DEFAULT_WALL_MATERIAL = 3000, "glass" = 1000) + build_path = /obj/item/weapon/personal_inhaler + sort_string = "MBCAA" + +/datum/design/item/medical/inhaler_combat + name = "Combat Inhaler" + desc = "An improved inhaler design that injects the entirety of the chemicals in the loaded cartridge in a single button press." + id = "inhaler_combat" + req_tech = list(TECH_BIO = 4, TECH_MATERIAL = 4, TECH_ENGINEERING = 4 ) + materials = list(DEFAULT_WALL_MATERIAL = 6000, "glass" = 3000, "silver" = 1500) + build_path = /obj/item/weapon/personal_inhaler/combat + sort_string = "MBCAB" + +/datum/design/item/medical/inhaler_cartridge_small + name = "Small Inhaler Cartridge" + desc = "A small aerosol cartridge that can hold a small amount of chemicals. For use in an inhaler." + id = "inhaler_cartridge_small" + req_tech = list(TECH_BIO = 2, TECH_MATERIAL = 2) + materials = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 500) + build_path = /obj/item/weapon/reagent_containers/personal_inhaler_cartridge + sort_string = "MBCAC" + +/datum/design/item/medical/inhaler_cartridge_large + name = "Large Inhaler Cartridge" + desc = "A large aerosol cartridge that can hold a decent amount of chemicals. For use in an inhaler." + id = "inhaler_cartridge_large" + req_tech = list(TECH_BIO = 4, TECH_MATERIAL = 4) + materials = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 500, "silver" = 500) + build_path = /obj/item/weapon/reagent_containers/personal_inhaler_cartridge/large + sort_string = "MBCAD" + +/datum/design/item/medical/inhaler_cartridge_bluespace + name = "Bluespace Inhaler Cartridge" + desc = "A bluespace aerosol cartridge that can hold a robust amount of chemicals. For use in an inhaler." + id = "inhaler_cartridge_bluespace" + req_tech = list(TECH_BLUESPACE = 2, TECH_MATERIAL = 6, TECH_BIO = 6) + materials = list(DEFAULT_WALL_MATERIAL = 3000, "phoron" = 3000, "diamond" = 500) + build_path = /obj/item/weapon/reagent_containers/personal_inhaler_cartridge/bluespace + sort_string = "MBCAE" \ No newline at end of file diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm b/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm index 559d07a5747..b887a891041 100644 --- a/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm +++ b/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm @@ -35,6 +35,7 @@ /obj/item/device/flash,\ /obj/item/device/flashlight,\ /obj/item/device/healthanalyzer,\ + /obj/item/device/breath_analyzer,\ /obj/item/device/multitool,\ /obj/item/device/paicard,\ /obj/item/device/radio,\ diff --git a/code/modules/spells/artifacts.dm b/code/modules/spells/artifacts.dm index 1565f706388..9d7d44c4ca3 100644 --- a/code/modules/spells/artifacts.dm +++ b/code/modules/spells/artifacts.dm @@ -142,8 +142,8 @@ /obj/item/phylactery/Initialize() . = ..() world_phylactery += src - create_reagents(30) - reagents.add_reagent("undead_ichor", 30) + create_reagents(120) + reagents.add_reagent("undead_ichor", 120) /obj/item/phylactery/Destroy() lich << "Your phylactery was destroyed, your soul is cast into the abyss as your immortality vanishes away!" @@ -170,4 +170,162 @@ if(!user.is_wizard() && src.lich) user << "As you pick up \the [src], you feel a wave of dread wash over you." for(var/obj/machinery/light/P in view(7, user)) - P.flicker(1) \ No newline at end of file + P.flicker(1) + + +//magic poppet +/obj/item/poppet + name = "poppet" + desc = "A rustic doll with a vague humanoid shape." + icon = 'icons/obj/wizard.dmi' + icon_state = "poppet" + w_class = 2 + var/datum/weakref/target = null + var/countenance = null //what species does it looks like? + var/cooldown_time = 120 + var/cooldown = 0 + +/obj/item/poppet/Destroy() + if(target) + to_chat(target, "The strange presence vanishes away...") + return ..() + +/obj/item/poppet/examine(mob/user) + ..(user) + if(countenance) + to_chat(user, "It is modeled after a [countenance].") + +/obj/item/poppet/afterattack(var/atom/A, var/mob/user, var/proximity) + + if(!proximity) + return + + if(A.blood_DNA) + var/marked = pick(A.blood_DNA) + + for(var/mob/living/carbon/human/H in mob_list) + if(H.dna.unique_enzymes == marked) + target = WEAKREF(H) + countenance = H.dna.species + to_chat(H, "You feel a strange presence looming over you.") + + +/obj/item/poppet/attack_self(mob/user as mob) + var/mob/living/carbon/human/H = target.resolve() + if(H && cooldown < world.time) + var/target_zone = user.zone_sel.selecting + + if(target_zone == "mouth") + var/voice = sanitize(input(user, "What would you like the victim to say", "Poppet", null) as text) + H.say(voice) + log_and_message_admins("forced [H] to say [voice] with a poppet", user) + + if(target_zone == "eyes") + to_chat(user, "You cover \the [src]'s eyes.") + to_chat(H, "Your vision is covered by a shadow!") + H.eye_blind = 3 + H.eye_blurry = 5 + + if(target_zone == "r_leg" || target_zone == "l_leg") + to_chat(user, "You move \the [src]'s legs around.") + if(H.canmove && !H.restrained() && !(istype(H.loc, /turf/space))) + step(H, pick(cardinal)) + + if(target_zone == "l_hand" || target_zone == "l_arm") + to_chat(user, "You twist \the [src]'s left arm.") + H.drop_l_hand() + + if(target_zone == "r_hand" || target_zone == "r_arm") + to_chat(user, "You twist \the [src]'s right arm..") + H.drop_r_hand() + + if(target_zone == "head") + to_chat(user, "You smack \the [src]'s head with your hand.") + H.confused += 10 + H.stuttering += 5 + to_chat(H, "You suddenly feel as if your head was hit by something!") + playsound(get_turf(H), "punch", 50, 1, -1) + + cooldown = world.time + cooldown_time + +/obj/item/poppet/attackby(obj/item/W as obj, mob/user as mob) + var/mob/living/carbon/human/H = target.resolve() + if(H && cooldown < world.time) + var/target_zone = user.zone_sel.selecting + + if(isflamesource(W)) + fire_act() + + if(istype(W, /obj/item/weapon/melee/baton)) + H.electrocute_act(W.force * 2, W, def_zone = target_zone) + playsound(get_turf(H), 'sound/weapons/Egloves.ogg', 50, 1, -1) + + if(istype(W, /obj/item/device/flashlight)) + to_chat(H, "You direct \the [W] towards \the [src]'s eyes!") + playsound(get_turf(H), 'sound/items/flashlight.ogg', 50, 1, -1) + flick("flash", H.flash) + H.eye_blurry = 5 + + if(iscoil(W)) + to_chat(H, "You strangle \the [src] with \the [W]!") + H.silent += 10 + playsound(get_turf(H), 'sound/effects/noosed.ogg', 50, 1, -1) + if(!(H.species.flags & NO_BREATHE)) + H.emote("me", 1, "gasps for air!") + H.losebreath += 5 + + if(istype(W, /obj/item/weapon/bikehorn)) + playsound(get_turf(H), 'sound/items/bikehorn.ogg', 50, 1, -1) + + if(W.edge) + to_chat(H, "You stab \the [src] with \the [W]!") + H.apply_damage(2, BRUTE, target_zone, edge = TRUE) + playsound(get_turf(H), 'sound/weapons/bladeslice.ogg', 50, 1, -1) + if(!(H.species.flags & NO_PAIN)) + var/obj/item/organ/external/organ = H.get_organ(target_zone) + to_chat(H, "You feel a stabbing pain in your [organ.name]!") + + + cooldown = world.time + cooldown_time + +/obj/item/poppet/throw_impact(atom/hit_atom) + ..() + var/mob/living/carbon/human/H = target.resolve() + if(H) + H.throw_at(get_edge_target_turf(H,pick(alldirs)), 5, 1) + +/obj/item/poppet/emp_act(severity) + var/mob/living/carbon/human/H = target.resolve() + if(H) + H.emp_act(severity) + playsound(get_turf(H), 'sound/effects/EMPulse.ogg', 50, 1, -1) + +/obj/item/poppet/ex_act(severity) + var/mob/living/carbon/human/H = target.resolve() + if(H) + H.ex_act(severity) + +/obj/item/poppet/tesla_act(var/power) + var/mob/living/carbon/human/H = target.resolve() + if(H) + H.electrocute_act(power, src) + +/obj/item/poppet/bullet_act(var/obj/item/projectile/Proj) + var/mob/living/carbon/human/H = target.resolve() + if(H) + H.apply_damage(Proj.damage, HALLOSS) + +/obj/item/poppet/fire_act() + var/mob/living/carbon/human/H = target.resolve() + if(H) + H.adjust_fire_stacks(2) + H.IgniteMob() + to_chat(H, "You suddenly burst into flames!!") + +/obj/item/poppet/crush_act() + var/mob/living/carbon/human/H = target.resolve() + if(H) + to_chat(H, "You feel an outworldly force crushing you!") + H.adjustBruteLoss(35) + H.apply_effect(6, WEAKEN) + qdel(src) \ No newline at end of file diff --git a/code/modules/spells/spellbook/battlemage.dm b/code/modules/spells/spellbook/battlemage.dm index db166e4a8f8..e093ebf0329 100644 --- a/code/modules/spells/spellbook/battlemage.dm +++ b/code/modules/spells/spellbook/battlemage.dm @@ -25,11 +25,11 @@ /spell/targeted/flesh_to_stone = 1, /spell/noclothes = 1, /obj/structure/closet/wizard/armor = 1, + /spell/aoe_turf/blink = 1, /obj/item/weapon/gun/energy/staff/focus = 1, /obj/item/weapon/gun/energy/staff/chaos = 1, /obj/item/weapon/storage/belt/wands/full = 2, /obj/item/weapon/melee/energy/wizard = 2, /obj/item/weapon/monster_manual = 2, - /obj/item/weapon/contract/apprentice = 1, - /spell/aoe_turf/blink = 1 + /obj/item/weapon/contract/apprentice = 1 ) diff --git a/code/modules/spells/spellbook/cleric.dm b/code/modules/spells/spellbook/cleric.dm index 457b97776f4..57465c3aac4 100644 --- a/code/modules/spells/spellbook/cleric.dm +++ b/code/modules/spells/spellbook/cleric.dm @@ -30,5 +30,6 @@ /spell/targeted/mindcontrol = 2, /obj/item/weapon/gun/energy/staff/focus = 2, /obj/item/weapon/storage/belt/wands/full = 2, - /obj/item/weapon/contract/apprentice = 1 + /obj/item/weapon/contract/apprentice = 1, + /obj/item/poppet = 1 ) diff --git a/code/modules/spells/spellbook/druid.dm b/code/modules/spells/spellbook/druid.dm index 1511802389d..a28820d104b 100644 --- a/code/modules/spells/spellbook/druid.dm +++ b/code/modules/spells/spellbook/druid.dm @@ -29,5 +29,6 @@ /spell/targeted/flesh_to_stone = 1, /obj/structure/closet/wizard/souls = 1, /obj/item/weapon/monster_manual = 1, - /obj/item/weapon/contract/apprentice = 1 + /obj/item/weapon/contract/apprentice = 1, + /obj/item/poppet = 1 ) diff --git a/code/stylesheet.dm b/code/stylesheet.dm index ea2dde66a5a..24400b88ba6 100644 --- a/code/stylesheet.dm +++ b/code/stylesheet.dm @@ -98,6 +98,7 @@ h1.alert, h2.alert {color: #000000;} .rough {font-family: "Trebuchet MS", cursive, sans-serif;} .say_quote {font-family: Georgia, Verdana, sans-serif;} .yassa {color: #400987;} +.delvahhi {color: #5E2612; font-weight: bold;} .interface {color: #330033;} diff --git a/html/changelog.html b/html/changelog.html index 878d0d8cb3c..60ea531e19a 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,65 @@ -->
+

13 May 2018

+

Alberyk updated:

+ +

Arrow768 updated:

+ +

Banditoz updated:

+ +

BurgerBB updated:

+ +

ParadoxSpace updated:

+ +

PoZe updated:

+ +

Skull132 updated:

+ +

10 May 2018

Kaedwuff updated:

- - {{if data.reception != 1}} - No reception with newscaster network. - {{/if}}
@@ -1032,12 +1028,7 @@ Used In File(s): \code\game\objects\items\devices\PDA\PDA.dm {{else data.mode == 61}}

{{:data.feed.channel}}

- Created by: {{:data.feed.author}}
- - {{if data.reception != 1}} - No reception with newscaster network. - {{/if}} - + Created by: {{:data.feed.author}}
diff --git a/sound/effects/magnetclamp.ogg b/sound/effects/magnetclamp.ogg new file mode 100644 index 00000000000..0405d853a09 Binary files /dev/null and b/sound/effects/magnetclamp.ogg differ diff --git a/sound/effects/pour.ogg b/sound/effects/pour.ogg new file mode 100644 index 00000000000..e22c0627500 Binary files /dev/null and b/sound/effects/pour.ogg differ diff --git a/sound/items/holster/holsterin.ogg b/sound/items/holster/holsterin.ogg new file mode 100644 index 00000000000..a0f3c639db5 Binary files /dev/null and b/sound/items/holster/holsterin.ogg differ diff --git a/sound/items/holster/holsterout.ogg b/sound/items/holster/holsterout.ogg new file mode 100644 index 00000000000..743280a40d5 Binary files /dev/null and b/sound/items/holster/holsterout.ogg differ diff --git a/sound/items/holster/sheathin.ogg b/sound/items/holster/sheathin.ogg new file mode 100644 index 00000000000..10fcbdf4601 Binary files /dev/null and b/sound/items/holster/sheathin.ogg differ diff --git a/sound/items/holster/sheathout.ogg b/sound/items/holster/sheathout.ogg new file mode 100644 index 00000000000..6b20f970a08 Binary files /dev/null and b/sound/items/holster/sheathout.ogg differ diff --git a/sound/items/holster/tactiholsterin.ogg b/sound/items/holster/tactiholsterin.ogg new file mode 100644 index 00000000000..aaec847ebc5 Binary files /dev/null and b/sound/items/holster/tactiholsterin.ogg differ diff --git a/sound/items/holster/tactiholsterout.ogg b/sound/items/holster/tactiholsterout.ogg new file mode 100644 index 00000000000..f1c44c45861 Binary files /dev/null and b/sound/items/holster/tactiholsterout.ogg differ diff --git a/sound/items/hypospray.ogg b/sound/items/hypospray.ogg new file mode 100644 index 00000000000..e4dd0331d0e Binary files /dev/null and b/sound/items/hypospray.ogg differ diff --git a/sound/items/match.ogg b/sound/items/match.ogg new file mode 100644 index 00000000000..84f5f39729d Binary files /dev/null and b/sound/items/match.ogg differ diff --git a/sound/items/ointment.ogg b/sound/items/ointment.ogg new file mode 100644 index 00000000000..efafb431a45 Binary files /dev/null and b/sound/items/ointment.ogg differ diff --git a/sound/items/pen1.ogg b/sound/items/pen1.ogg new file mode 100644 index 00000000000..064624c1fc2 Binary files /dev/null and b/sound/items/pen1.ogg differ diff --git a/sound/items/pen2.ogg b/sound/items/pen2.ogg new file mode 100644 index 00000000000..2a6781b45f3 Binary files /dev/null and b/sound/items/pen2.ogg differ diff --git a/sound/items/rip1.ogg b/sound/items/rip1.ogg new file mode 100644 index 00000000000..ab0fabbb3d6 Binary files /dev/null and b/sound/items/rip1.ogg differ diff --git a/sound/items/rip2.ogg b/sound/items/rip2.ogg new file mode 100644 index 00000000000..93a5cec50f8 Binary files /dev/null and b/sound/items/rip2.ogg differ diff --git a/sound/items/stamp.ogg b/sound/items/stamp.ogg new file mode 100644 index 00000000000..f243cc96836 Binary files /dev/null and b/sound/items/stamp.ogg differ diff --git a/sound/items/stimpack.ogg b/sound/items/stimpack.ogg new file mode 100644 index 00000000000..b2f37a0e101 Binary files /dev/null and b/sound/items/stimpack.ogg differ diff --git a/sound/items/storage/box.ogg b/sound/items/storage/box.ogg new file mode 100644 index 00000000000..9d25a761cc8 Binary files /dev/null and b/sound/items/storage/box.ogg differ diff --git a/sound/items/storage/briefcase.ogg b/sound/items/storage/briefcase.ogg new file mode 100644 index 00000000000..e841e03747c Binary files /dev/null and b/sound/items/storage/briefcase.ogg differ diff --git a/sound/items/storage/pillbottle.ogg b/sound/items/storage/pillbottle.ogg new file mode 100644 index 00000000000..1c47fbeb73f Binary files /dev/null and b/sound/items/storage/pillbottle.ogg differ diff --git a/sound/items/storage/toolbox.ogg b/sound/items/storage/toolbox.ogg new file mode 100644 index 00000000000..ec1ff0cde56 Binary files /dev/null and b/sound/items/storage/toolbox.ogg differ diff --git a/sound/items/tape.ogg b/sound/items/tape.ogg new file mode 100644 index 00000000000..7a7047e3246 Binary files /dev/null and b/sound/items/tape.ogg differ diff --git a/tools/Event Probabilities/Event Probabilities.xlsx b/tools/Event Probabilities/Event Probabilities.xlsx index 7007a506955..8341cc91d8d 100644 Binary files a/tools/Event Probabilities/Event Probabilities.xlsx and b/tools/Event Probabilities/Event Probabilities.xlsx differ
CHARGES