diff --git a/.gitignore b/.gitignore index 47ee524374b..5d93bb91162 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,27 @@ -###Files and folders specified here will never be tracked. +### Files and folders specified here will never be tracked. -#Ignore everything in datafolder and subdirectories +# Ignore everything in datafolder and subdirectories /data/**/* /tmp/**/* -#Ignore byond config folder. +# Ignore byond config folder. /cfg/**/* +# Ignore IDE files we don't need in the repo. +/.vs/**/* +/tgstation/FileContentIndex/**/* +/FileContentIndex/**/* +/v17/**/* +/v18/**/* +/v19/**/* +/v20/**/* +/v21/**/* +/v22/**/* + # Ignore compiled linux libs in the root folder, e.g. librust_g.so /*.so -#Ignore compiled files and other files generated during compilation. +# Ignore compiled files and other files generated during compilation. *.mdme *.mdme.* *.dmb @@ -24,7 +35,7 @@ *~ -# temporary files which can be created if a process still has a handle open of a deleted file +# Temporary files which can be created if a process still has a handle open of a deleted file .fuse_hidden* # KDE directory preferences @@ -155,29 +166,32 @@ Temporary Items *.before -#Sublime +# Sublime *.sublime-project *.sublime-workspace -#Visual studio stuff +# Visual studio stuff *.vscode/* /tools/MapAtmosFixer/MapAtmosFixer/obj/* /tools/MapAtmosFixer/MapAtmosFixer/bin/* /tools/CreditsTool/bin/* /tools/CreditsTool/obj/* -#GitHub Atom +# GitHub Atom .atom-build.json -#KDevelop and Kate +# KDevelop and Kate *.kdev4* *.kate-swp -#extra map stuff +# Extra map stuff /_maps/**/backup/ /_maps/templates.dm /maps/**/backup/ +# Extra DMI stuff +/icons/*.dme + #dmdoc default folder /dmdoc @@ -198,5 +212,17 @@ Temporary Items /tools/LinuxOneShot/TGS_Instances /tools/LinuxOneShot/TGS_Logs -# Autowiki -/tools/autowiki/node_modules +# Built auxtools libraries and intermediate files +aux*.dll +libaux*.so +aux*.pdb + +# byond-tracy, we intentionally do not ship this and do not want to maintain it +prof.dll +libprof.so + +# JavaScript tools +**/node_modules + +# Screenshot tests +/artifacts diff --git a/citadel.dme b/citadel.dme index 79af566be9b..07b3d8551e2 100644 --- a/citadel.dme +++ b/citadel.dme @@ -112,6 +112,7 @@ #include "code\__DEFINES\_flags\obj_flags.dm" #include "code\__DEFINES\_flags\turf_flags.dm" #include "code\__DEFINES\admin\keybindings.dm" +#include "code\__DEFINES\assets\medical.dm" #include "code\__DEFINES\atmospherics\atmos.dm" #include "code\__DEFINES\atmospherics\atmospheres.dm" #include "code\__DEFINES\atmospherics\constants.dm" @@ -124,6 +125,7 @@ #include "code\__DEFINES\client\player_flags.dm" #include "code\__DEFINES\color\color.dm" #include "code\__DEFINES\color\colour_priority.dm" +#include "code\__DEFINES\color\lights.dm" #include "code\__DEFINES\color\lum.dm" #include "code\__DEFINES\combat\atom_damage.dm" #include "code\__DEFINES\combat\explosions.dm" @@ -412,12 +414,14 @@ #include "code\controllers\subsystem\air.dm" #include "code\controllers\subsystem\airflow.dm" #include "code\controllers\subsystem\alarm.dm" +#include "code\controllers\subsystem\asset_loading.dm" #include "code\controllers\subsystem\assets.dm" #include "code\controllers\subsystem\atoms.dm" #include "code\controllers\subsystem\automata.dm" #include "code\controllers\subsystem\bellies_vr.dm" #include "code\controllers\subsystem\chat.dm" #include "code\controllers\subsystem\dcs.dm" +#include "code\controllers\subsystem\early_assets.dm" #include "code\controllers\subsystem\emergency_shuttle.dm" #include "code\controllers\subsystem\events.dm" #include "code\controllers\subsystem\fail2topic.dm" @@ -1842,6 +1846,7 @@ #include "code\modules\asset_cache\assets\arcade.dm" #include "code\modules\asset_cache\assets\chat.dm" #include "code\modules\asset_cache\assets\common.dm" +#include "code\modules\asset_cache\assets\condiments.dm" #include "code\modules\asset_cache\assets\fontawesome.dm" #include "code\modules\asset_cache\assets\genetics.dm" #include "code\modules\asset_cache\assets\inventory.dm" @@ -1853,10 +1858,8 @@ #include "code\modules\asset_cache\assets\notes.dm" #include "code\modules\asset_cache\assets\orbit.dm" #include "code\modules\asset_cache\assets\paper.dm" -#include "code\modules\asset_cache\assets\patches.dm" #include "code\modules\asset_cache\assets\pda.dm" #include "code\modules\asset_cache\assets\permission.dm" -#include "code\modules\asset_cache\assets\pills.dm" #include "code\modules\asset_cache\assets\pipes.dm" #include "code\modules\asset_cache\assets\radar.dm" #include "code\modules\asset_cache\assets\safe.dm" @@ -1864,6 +1867,9 @@ #include "code\modules\asset_cache\assets\tgfont.dm" #include "code\modules\asset_cache\assets\tgui.dm" #include "code\modules\asset_cache\assets\vv.dm" +#include "code\modules\asset_cache\assets\chemistry\bottles.dm" +#include "code\modules\asset_cache\assets\chemistry\patches.dm" +#include "code\modules\asset_cache\assets\chemistry\pills.dm" #include "code\modules\asset_cache\transports\asset_transport.dm" #include "code\modules\asset_cache\transports\webroot_transport.dm" #include "code\modules\atmospherics\atmosphere\_atmosphere.dm" @@ -3665,29 +3671,29 @@ #include "code\modules\random_map\noise\noise.dm" #include "code\modules\random_map\noise\ore.dm" #include "code\modules\random_map\noise\tundra.dm" -#include "code\modules\reagents\Chemistry-Colours.dm" -#include "code\modules\reagents\Chemistry-Holder.dm" -#include "code\modules\reagents\Chemistry-Logging.dm" -#include "code\modules\reagents\Chemistry-Machinery.dm" -#include "code\modules\reagents\Chemistry-Metabolism.dm" -#include "code\modules\reagents\Chemistry-Readme.dm" -#include "code\modules\reagents\Chemistry-Reagents-Helpers.dm" -#include "code\modules\reagents\Chemistry-Reagents.dm" -#include "code\modules\reagents\Chemistry-Recipes.dm" #include "code\modules\reagents\Drink-Recipes.dm" #include "code\modules\reagents\exposedprocs.dm" #include "code\modules\reagents\Food-Recipes.dm" #include "code\modules\reagents\Misc-Recipes.dm" #include "code\modules\reagents\reagent_containers.dm" #include "code\modules\reagents\Topical-Recipes.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Core.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Dispenser.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Food-Drinks.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Medicine.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Modifiers.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Other.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Toxins.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Topical.dm" +#include "code\modules\reagents\chemistry\_readme.dm" +#include "code\modules\reagents\chemistry\chemical_reactions.dm" +#include "code\modules\reagents\chemistry\colors.dm" +#include "code\modules\reagents\chemistry\helpers.dm" +#include "code\modules\reagents\chemistry\holder.dm" +#include "code\modules\reagents\chemistry\logging.dm" +#include "code\modules\reagents\chemistry\machinery.dm" +#include "code\modules\reagents\chemistry\metabolism.dm" +#include "code\modules\reagents\chemistry\reagents.dm" +#include "code\modules\reagents\chemistry\reagents\Chemistry-Reagents-Core.dm" +#include "code\modules\reagents\chemistry\reagents\Chemistry-Reagents-Dispenser.dm" +#include "code\modules\reagents\chemistry\reagents\Chemistry-Reagents-Food-Drinks.dm" +#include "code\modules\reagents\chemistry\reagents\Chemistry-Reagents-Medicine.dm" +#include "code\modules\reagents\chemistry\reagents\Chemistry-Reagents-Modifiers.dm" +#include "code\modules\reagents\chemistry\reagents\Chemistry-Reagents-Other.dm" +#include "code\modules\reagents\chemistry\reagents\Chemistry-Reagents-Toxins.dm" +#include "code\modules\reagents\chemistry\reagents\Chemistry-Topical.dm" #include "code\modules\reagents\distilling\Distilling-Recipes.dm" #include "code\modules\reagents\distilling\distilling.dm" #include "code\modules\reagents\machinery\chem_master.dm" diff --git a/code/__DEFINES/assets/medical.dm b/code/__DEFINES/assets/medical.dm new file mode 100644 index 00000000000..1e7925d6f21 --- /dev/null +++ b/code/__DEFINES/assets/medical.dm @@ -0,0 +1,14 @@ +//! Used by chem masters and pill presses +#define PILL_STYLE_COUNT 22 // Update this if you add more pill icons or you die. +#define RANDOM_PILL_STYLE 22 // Don't change this one though. + +#define PILL_STYLE_RED list("pill4", "pill5", "pill12") // Red pills have an extra spooky description. +#define PILL_STYLE_COLORABLE list("pill9", "pill18", "pill19", "pill21") // Put your pill here if it's greyscale. + +#define BOTTLE_STYLE_COUNT 4 // Update this if you add more bottle icons or you die. +#define RANDOM_BOTTLE_STYLE 4 // Don't change this one though. + +//used by chem masters and pill presses +//update this if you add more patch icons +#define PATCH_STYLE_LIST list("patch", "patch_brute", "patch_burn", "patch_both") //icon_state list +#define DEFAULT_PATCH_STYLE "patch" diff --git a/code/__DEFINES/chemistry.dm b/code/__DEFINES/chemistry.dm index a667a2931ef..147c9e3dcb7 100644 --- a/code/__DEFINES/chemistry.dm +++ b/code/__DEFINES/chemistry.dm @@ -4,9 +4,21 @@ #define DEFAULT_THIRST_FACTOR 0.03 /// Means 'Reagent Effect Multiplier'. This is how many units of reagent are consumed per tick #define REM 0.2 -#define CHEM_TOUCH 1 -#define CHEM_INGEST 2 -#define CHEM_BLOOD 3 + +//! Reagent exposure methods. +/// Used for splashing. +#define CHEM_TOUCH (1<<0) +/// Used for ingesting the reagents. Food, drinks, inhaling smoke. +#define CHEM_INGEST (1<<1) +/// Used by foams, sprays, and blob attacks. +#define CHEM_VAPOR (1<<2) +/// Used by medical patches and gels. +#define CHEM_PATCH (1<<3) +/// Used for direct injection of reagents. +#define CHEM_INJECT (1<<4) +/// Used for blood contamination. +#define CHEM_BLOOD (1<<5) + #define MINIMUM_CHEMICAL_VOLUME 0.01 @@ -67,10 +79,6 @@ var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_ 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 -///Max icon state of the pill sprites -#define MAX_PILL_SPRITE 24 -///Max icon state of the pill sprites -#define MAX_BOTTLE_SPRITE 4 ///Max number of pills/patches that can be made at once #define MAX_MULTI_AMOUNT 20 ///Max amount of units in a pill @@ -90,6 +98,7 @@ var/list/cheartstopper = list("potassium_chloride") // Thi #define SYRINGE_DRAW 0 #define SYRINGE_INJECT 1 #define SYRINGE_BROKEN 2 +#define SYRINGE_CAPPED 3 //reagents_holder_flags defines ///Makes it possible to add reagents through droppers and syringes. @@ -108,3 +117,27 @@ var/list/cheartstopper = list("potassium_chloride") // Thi #define AMOUNT_VISIBLE (1<<5) ///Applied to a reagent holder, the contents will not react with each other. #define NO_REACT (1<<6) + +//! Used by chem master +#define CONDIMASTER_STYLE_AUTO "auto" +#define CONDIMASTER_STYLE_FALLBACK "_" + +/// When processing a reaction, iterate this many times. +#define PROCESS_REACTION_ITER 5 + +/** + * Helper that ensures the reaction rate holds after iterating + * Ex. REACTION_RATE(0.3) means that 30% of the reagents will react each chemistry tick (~2 seconds by default). + */ +#define REACTION_RATE(rate) (1.0 - (1.0-rate)**(1.0/PROCESS_REACTION_ITER)) + +/** + * Helper to define reaction rate in terms of half-life + * + * Ex. + * HALF_LIFE(0) -> Reaction completes immediately (default chems) + * HALF_LIFE(1) -> Half of the reagents react immediately, the rest over the following ticks. + * HALF_LIFE(2) -> Half of the reagents are consumed after 2 chemistry ticks. + * HALF_LIFE(3) -> Half of the reagents are consumed after 3 chemistry ticks. + */ +#define HALF_LIFE(ticks) (ticks? 1.0 - (0.5)**(1.0/(ticks*PROCESS_REACTION_ITER)) : 1.0) diff --git a/code/__DEFINES/color/lights.dm b/code/__DEFINES/color/lights.dm new file mode 100644 index 00000000000..ad777e2f687 --- /dev/null +++ b/code/__DEFINES/color/lights.dm @@ -0,0 +1,37 @@ +//Some defines to generalise colours used in lighting. +//! ## GENERAL COLORS +//? Important note on colors. Colors can end up significantly different from the basic html picture, especially when saturated! +#define LIGHT_COLOR_WHITE "#FFFFFF" // rgb(255, 255, 255) Pure white. +#define LIGHT_COLOR_RED "#FA8282" // rgb(250, 130, 130) Warm but extremely diluted red. +#define LIGHT_COLOR_GREEN "#64C864" // rgb(100, 200, 100) Bright but quickly dissipating neon green. +#define LIGHT_COLOR_BLUE "#6496FA" // rgb(100, 150, 250) Cold, diluted blue. +#define LIGHT_COLOR_BLUEGREEN "#7DE1AF" // rgb(125, 225, 175) Light blueish green. +#define LIGHT_COLOR_PALEBLUE "#7DAFE1" // rgb(125, 175, 225) A pale blue-ish color. +#define LIGHT_COLOR_CYAN "#7DE1E1" // rgb(125, 225, 225) Diluted cyan. +#define LIGHT_COLOR_LIGHT_CYAN "#40CEFF" // rgb(64, 206, 255) More-saturated cyan. +#define LIGHT_COLOR_DARK_BLUE "#6496FA" // rgb(51, 117, 248) Saturated blue. +#define LIGHT_COLOR_PINK "#E17DE1" // rgb(225, 125, 225) Diluted, mid-warmth pink. +#define LIGHT_COLOR_YELLOW "#E1E17D" // rgb(225, 225, 125) Dimmed yellow, leaning kaki. +#define LIGHT_COLOR_BROWN "#966432" // rgb(150, 100, 50) Clear brown, mostly dim. +#define LIGHT_COLOR_ORANGE "#FA9632" // rgb(250, 150, 50) Mostly pure orange. +#define LIGHT_COLOR_PURPLE "#952CF4" // rgb(149, 44, 244) Light Purple. +#define LIGHT_COLOR_LAVENDER "#9B51FF" // rgb(155, 81, 255) Less-saturated light purple. +#define LIGHT_COLOR_HOLY_MAGIC "#FFF743" // rgb(255, 247, 67) Slightly desaturated bright yellow. +#define LIGHT_COLOR_BLOOD_MAGIC "#D00000" // rgb(208, 0, 0) Deep crimson. + +//?These ones aren't a direct colour like the ones above, because nothing would fit + +#define LIGHT_COLOR_FIRE "#FAA019" // rgb(250, 160, 25) Warm orange color, leaning strongly towards yellow. +#define LIGHT_COLOR_LAVA "#C48A18" // rgb(196, 138, 24) Very warm yellow, leaning slightly towards orange. +#define LIGHT_COLOR_FLARE "#FA644B" // rgb(250, 100, 75) Bright, non-saturated red. Leaning slightly towards pink for visibility. +#define LIGHT_COLOR_SLIME_LAMP "#AFC84B" // rgb(175, 200, 75) Weird color, between yellow and green, very slimy. +#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" // rgb(250, 225, 175) Extremely diluted yellow, close to skin color (for some reason). +#define LIGHT_COLOR_HALOGEN "#F0FAFA" // rgb(240, 250, 250) Barely visible cyan-ish hue, as the doctor prescribed. + +//! ## STATION LIGHT COLORS +#define LIGHT_COLOR_FLUORESCENT_TUBE "#B3D7FF" // rgb(179, 215, 255) Bright, slightly blueish white. +#define LIGHT_COLOR_FLUORESCENT_FLASHLIGHT "#CDDDFF" // rgb(205, 221, 255) Bright, slightly blueish white. +#define LIGHT_COLOR_INCANDESCENT_TUBE "#E0EFF0" // rgb(224, 239, 240) Slightly blueish white. +#define LIGHT_COLOR_INCANDESCENT_BULB "#FFFEB8" // rgb(255, 254, 184) Slightly yellowish white. +#define LIGHT_COLOR_INCANDESCENT_FLASHLIGHT "#FFCC66" // rgb(255, 204, 102) Slightly yellowish white. +#define LIGHT_COLOR_NIGHTSHIFT "#EFCC86" // rgb(239, 204, 134) Slightly yellowish white. diff --git a/code/__DEFINES/controllers/_subsystems.dm b/code/__DEFINES/controllers/_subsystems.dm index f8574de92f8..0b14c0830c9 100644 --- a/code/__DEFINES/controllers/_subsystems.dm +++ b/code/__DEFINES/controllers/_subsystems.dm @@ -81,6 +81,7 @@ DEFINE_BITFIELD(runlevels, list( #define INIT_ORDER_SERVER_MAINT 65 #define INIT_ORDER_TIMER 60 #define INIT_ORDER_INSTRUMENTS 50 +#define INIT_ORDER_EARLY_ASSETS 48 #define INIT_ORDER_SQLITE 40 #define INIT_ORDER_CHEMISTRY 35 #define INIT_ORDER_SKYBOX 30 @@ -135,6 +136,7 @@ DEFINE_BITFIELD(runlevels, list( #define FIRE_PRIORITY_PLANETS 75 #define FIRE_PRIORITY_INSTRUMENTS 90 #define FIRE_PRIORITY_MACHINES 100 +#define FIRE_PRIORITY_ASSETS 105 #define FIRE_PRIORITY_TGUI 110 #define FIRE_PRIORITY_PROJECTILES 150 #define FIRE_PRIORITY_THROWING 150 @@ -142,8 +144,7 @@ DEFINE_BITFIELD(runlevels, list( #define FIRE_PRIORITY_OVERLAYS 500 #define FIRE_PRIORITY_SMOOTHING 500 #define FIRE_PRIORITY_TIMER 700 -///never drop input -#define FIRE_PRIORITY_INPUT 1000 +#define FIRE_PRIORITY_INPUT 1000 //! Never drop input /** Create a new timer and add it to the queue. diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm index 62b93db1624..595bb93bee2 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm @@ -35,9 +35,9 @@ /// From base of [/atom/update_icon]: () #define COMSIG_ATOM_UPDATE_ICON "atom_update_icon" ///? If returned from [COMSIG_ATOM_UPDATE_ICON] it prevents the atom from updating its icon state. - ////#define COMSIG_ATOM_NO_UPDATE_ICON_STATE UPDATE_ICON_STATE + #define COMSIG_ATOM_NO_UPDATE_ICON_STATE UPDATE_ICON_STATE ///? If returned from [COMSIG_ATOM_UPDATE_ICON] it prevents the atom from updating its overlays. - ////#define COMSIG_ATOM_NO_UPDATE_OVERLAYS UPDATE_OVERLAYS + #define COMSIG_ATOM_NO_UPDATE_OVERLAYS UPDATE_OVERLAYS /// From base of [atom/update_icon_state]: () #define COMSIG_ATOM_UPDATE_ICON_STATE "atom_update_icon_state" /// From base of [/atom/update_overlays]: (list/new_overlays) diff --git a/code/__DEFINES/inventory/icons.dm b/code/__DEFINES/inventory/icons.dm index 922793b1234..593b277fb1d 100644 --- a/code/__DEFINES/inventory/icons.dm +++ b/code/__DEFINES/inventory/icons.dm @@ -13,6 +13,8 @@ #define INHAND_DEFAULT_ICON_HATS "hats" /// holders #define INHAND_DEFAULT_ICON_HOLDERS "holders" +/// kitchen +#define INHAND_DEFAULT_ICON_KITCHEN "kitchen" /// magic #define INHAND_DEFAULT_ICON_MAGIC "magic" /// masks diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 9453063a6e3..82fb2c54612 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -41,7 +41,9 @@ #define isairlock(A) istype(A, /obj/machinery/door/airlock) -#define isbelly(A) istype(A, /obj/belly) +#define isbelly(A) istype(A, /obj/belly) + +#define is_reagent_container(O) (istype(O, /obj/item/reagent_containers)) //Areas diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index a2759343330..c5bd4d117d1 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -29,65 +29,6 @@ 0, 0, 0, 1 \ ) \ -//Some defines to generalise colours used in lighting. -//! ## GENERAL COLORS -//? Important note on colors. Colors can end up significantly different from the basic html picture, especially when saturated! -#define LIGHT_COLOR_WHITE "#FFFFFF" -/// Warm but extremely diluted red. rgb(250, 130, 130) -#define LIGHT_COLOR_RED "#FA8282" -/// Bright but quickly dissipating neon green. rgb(100, 200, 100) -#define LIGHT_COLOR_GREEN "#64C864" -/// Cold, diluted blue. rgb(100, 150, 250) -#define LIGHT_COLOR_BLUE "#6496FA" -/// Light blueish green. rgb(125, 225, 175) -#define LIGHT_COLOR_BLUEGREEN "#7DE1AF" -/// A pale blue-ish color. rgb(125, 175, 225) -#define LIGHT_COLOR_PALEBLUE "#7DAFE1" -/// Diluted cyan. rgb(125, 225, 225) -#define LIGHT_COLOR_CYAN "#7DE1E1" -/// More-saturated cyan. rgb(64, 206, 255) -#define LIGHT_COLOR_LIGHT_CYAN "#40CEFF" -/// Saturated blue. rgb(51, 117, 248) -#define LIGHT_COLOR_DARK_BLUE "#6496FA" -/// Diluted, mid-warmth pink. rgb(225, 125, 225) -#define LIGHT_COLOR_PINK "#E17DE1" -/// Dimmed yellow, leaning kaki. rgb(225, 225, 125) -#define LIGHT_COLOR_YELLOW "#E1E17D" -/// Clear brown, mostly dim. rgb(150, 100, 50) -#define LIGHT_COLOR_BROWN "#966432" -/// Mostly pure orange. rgb(250, 150, 50) -#define LIGHT_COLOR_ORANGE "#FA9632" -/// Light Purple. rgb(149, 44, 244) -#define LIGHT_COLOR_PURPLE "#952CF4" -/// Less-saturated light purple. rgb(155, 81, 255) -#define LIGHT_COLOR_LAVENDER "#9B51FF" -/// Slightly desaturated bright yellow. -#define LIGHT_COLOR_HOLY_MAGIC "#FFF743" -/// Deep crimson. -#define LIGHT_COLOR_BLOOD_MAGIC "#D00000" - -//?These ones aren't a direct colour like the ones above, because nothing would fit -/// Warm orange color, leaning strongly towards yellow. rgb(250, 160, 25) -#define LIGHT_COLOR_FIRE "#FAA019" -/// Very warm yellow, leaning slightly towards orange. rgb(196, 138, 24) -#define LIGHT_COLOR_LAVA "#C48A18" -/// Bright, non-saturated red. Leaning slightly towards pink for visibility. rgb(250, 100, 75) -#define LIGHT_COLOR_FLARE "#FA644B" -/// Weird color, between yellow and green, very slimy. rgb(175, 200, 75) -#define LIGHT_COLOR_SLIME_LAMP "#AFC84B" -/// Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175) -#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" -/// Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250) -#define LIGHT_COLOR_HALOGEN "#F0FAFA" - -//! ## STATION LIGHT COLORS -#define LIGHT_COLOR_FLUORESCENT_TUBE "#B3D7FF" -#define LIGHT_COLOR_FLUORESCENT_FLASHLIGHT "#CDDDFF" -#define LIGHT_COLOR_INCANDESCENT_TUBE "#E0EFF0" -#define LIGHT_COLOR_INCANDESCENT_BULB "#FFFEB8" -#define LIGHT_COLOR_INCANDESCENT_FLASHLIGHT "#FFCC66" -#define LIGHT_COLOR_NIGHTSHIFT "#EFCC86" - /// How many tiles standard fires glow. #define LIGHT_RANGE_FIRE 3 diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 39c3fa18695..54563f376dd 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -369,3 +369,14 @@ #define EXAMINE_MORE_TIME 1 SECONDS #define SLEEP_CHECK_DEATH(X) sleep(X); if(QDELETED(src) || stat == DEAD) return; + +//! Blood levels +#define BLOOD_VOLUME_MAX_LETHAL 2150 +#define BLOOD_VOLUME_EXCESS 2100 +#define BLOOD_VOLUME_MAXIMUM 2000 +#define BLOOD_VOLUME_SLIME_SPLIT 1120 +#define BLOOD_VOLUME_NORMAL 560 +#define BLOOD_VOLUME_SAFE 475 +#define BLOOD_VOLUME_OKAY 336 +#define BLOOD_VOLUME_BAD 224 +#define BLOOD_VOLUME_SURVIVE 122 diff --git a/code/__DEFINES/mobs/mobility.dm b/code/__DEFINES/mobs/mobility.dm index 0265b9a5532..d0a45837b5a 100644 --- a/code/__DEFINES/mobs/mobility.dm +++ b/code/__DEFINES/mobs/mobility.dm @@ -1,26 +1,29 @@ -//Mob mobility var flags +//! Mob mobility var flags /// any flag #define CHECK_MOBILITY(target, flags) (target.mobility_flags & flags) #define CHECK_ALL_MOBILITY(target, flags) CHECK_MULTIPLE_BITFIELDS(target.mobility_flags, flags) -/// can move -#define MOBILITY_MOVE (1<<0) -/// can, and is, standing up. -#define MOBILITY_STAND (1<<1) -/// can pickup items -#define MOBILITY_PICKUP (1<<2) -/// can use items and interact with world objects like opening closets/etc -#define MOBILITY_USE (1<<3) -/// can use interfaces like consoles -#define MOBILITY_UI (1<<4) -/// can use storage item -#define MOBILITY_STORAGE (1<<5) -/// can pull things -#define MOBILITY_PULL (1<<6) -/// can hold non-nodropped items voluntarily -#define MOBILITY_HOLD (1<<7) -/// Can resist out of buckling, grabs, cuffs, etc, in the usual order (buckle --> cuffs --> grab) -#define MOBILITY_RESIST (1<<8) +#define MOBILITY_MOVE (1<<0) // Can move. +#define MOBILITY_STAND (1<<1) // Can, and is, standing up. +#define MOBILITY_PICKUP (1<<2) // Can pickup items. +#define MOBILITY_USE (1<<3) // Can use items and interact with world objects like opening closets/etc. +#define MOBILITY_UI (1<<4) // Can use interfaces like consoles. +#define MOBILITY_STORAGE (1<<5) // Can use storage item. +#define MOBILITY_PULL (1<<6) // Can pull things. +#define MOBILITY_HOLD (1<<7) // Can hold non-nodropped items voluntarily. +#define MOBILITY_RESIST (1<<8) // Can resist out of buckling, grabs, cuffs, etc, in the usual order (buckle --> cuffs --> grab) #define MOBILITY_FLAGS_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND | MOBILITY_PICKUP | MOBILITY_USE | MOBILITY_UI | MOBILITY_STORAGE | MOBILITY_PULL | MOBILITY_RESIST) #define MOBILITY_FLAGS_ANY_INTERACTION (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_UI | MOBILITY_STORAGE) + +DEFINE_BITFIELD(mobility_flags, list( + "MOVE" = MOBILITY_MOVE, + "STAND" = MOBILITY_STAND, + "PICKUP" = MOBILITY_PICKUP, + "USE" = MOBILITY_USE, + "UI" = MOBILITY_UI, + "STORAGE" = MOBILITY_STORAGE, + "PULL" = MOBILITY_PULL, + "HOLD" = MOBILITY_HOLD, + "RESIST" = MOBILITY_RESIST, +)) diff --git a/code/___compile_options.dm b/code/___compile_options.dm index 4349437410b..fc83239269d 100644 --- a/code/___compile_options.dm +++ b/code/___compile_options.dm @@ -1,45 +1,103 @@ //* Core settings //! Fastboot flags - useful for debugging -/// disable automatic roundstart icon smoothing +/// Disable automatic roundstart icon smoothing. // #define FASTBOOT_DISABLE_SMOOTHING (1<<0) -/// disable loading late maps +/// Disable loading late maps. // #define FASTBOOT_DISABLE_LATELOAD (1<<1) -/// disable atmospherics zone build +/// Disable atmospherics zone build. // #define FASTBOOT_DISABLE_ZONES (1<<2) -///By using the testing("message") proc you can create debug-feedback for people with this -//#define TESTING - //uncommented, but not visible in the release version) +/** + * By using the testing("message") proc you can create debug-feedback for people with this uncommented, + * but not visible in the release version + */ +// #define TESTING -///Enables the ability to cache datum vars and retrieve later for debugging which vars changed. -//#define DATUMVAR_DEBUGGING_MODE -// Comment this out if you are debugging problems that might be obscured by custom error handling in world/Error +/// Enables the ability to cache datum vars and retrieve later for debugging which vars changed. +// #define DATUMVAR_DEBUGGING_MODE + +/// Comment this out if you are debugging problems that might be obscured by custom error handling in world/Error #ifdef DEBUG - #define USE_CUSTOM_ERROR_HANDLER +#define USE_CUSTOM_ERROR_HANDLER +#define DEBUG_SHUTTLES #endif -#define DEBUG_SHUTTLES #ifdef TESTING #define DATUMVAR_DEBUGGING_MODE -///Used to find the sources of harddels, quite laggy, don't be surpised if it freezes your client for a good while +/// Used to find the sources of harddels, quite laggy, don't be surpised if it freezes your client for a good while +// #define REFERENCE_TRACKING #ifdef REFERENCE_TRACKING -///Run a lookup on things hard deleting by default. -//#define GC_FAILURE_HARD_LOOKUP +/// Used for doing dry runs of the reference finder, to test for feature completeness +/// Slightly slower, higher in memory. Just not optimal +// #define REFERENCE_TRACKING_DEBUG + +/// Run a lookup on things hard deleting by default. +// #define GC_FAILURE_HARD_LOOKUP #ifdef GC_FAILURE_HARD_LOOKUP +/// Don't stop when searching, go till you're totally done #define FIND_REF_NO_CHECK_TICK #endif //ifdef GC_FAILURE_HARD_LOOKUP #endif //ifdef REFERENCE_TRACKING -///Highlights atmos active turfs in green -//#define VISUALIZE_ACTIVE_TURFS +/** + * Enables debug messages for every single reaction step. + * This is 1 message per 0.5s for a SINGLE reaction. + * Useful for tracking down bugs/asking me for help in the main reaction handiler (equilibrium.dm). + * + * * Requires TESTING to be defined to work. + * ! Not implemented yet. + */ +// #define REAGENTS_TESTING + +/** + * Displays static object lighting updates. + * + * Also enables some debug vars on sslighting that can be used to modify + * how extensively we prune lighting corners to update. + */ +#define VISUALIZE_LIGHT_UPDATES + +/// Highlights atmos active turfs in green. +#define VISUALIZE_ACTIVE_TURFS #endif //ifdef TESTING -///Enables unit tests via TEST_RUN_PARAMETER -//#define UNIT_TESTS +/// If this is uncommented, we do a single run though of the game setup and tear down process with unit tests in between +// #define UNIT_TESTS + +/** + * If this is uncommented, will attempt to load and initialize prof.dll/libprof.so. + * We do not ship byond-tracy. Build it yourself here: https://github.com/mafemergency/byond-tracy/ + */ +// #define USE_BYOND_TRACY + +/// If defined, we will NOT defer asset generation till later in the game, and will instead do it all at once, during initiialize. +//#define DO_NOT_DEFER_ASSETS + +/// If this is uncommented, Autowiki will generate edits and shut down the server. +/// Prefer the autowiki build target instead. +// #define AUTOWIKI + +/// If this is uncommented, will profile mapload atom initializations +// #define PROFILE_MAPLOAD_INIT_ATOM + +/// If this is uncommented, force our verb processing into just the 2% of a tick +/// We normally reserve for it +/// NEVER run this on live, it's for simulating highpop only +// #define VERB_STRESS_TEST + +#ifdef VERB_STRESS_TEST +/// Uncomment this to force all verbs to run into overtime all of the time +/// Essentially negating the reserve 2% + +// #define FORCE_VERB_OVERTIME +#warn Hey brother, you're running in LAG MODE. +#warn IF YOU PUT THIS ON LIVE I WILL FIND YOU AND MAKE YOU WISH YOU WERE NEVE- +#endif + #ifndef PRELOAD_RSC //set to: /// 0 to allow using external resources or on-demand behaviour; #define PRELOAD_RSC 2 diff --git a/code/controllers/subsystem/asset_loading.dm b/code/controllers/subsystem/asset_loading.dm new file mode 100644 index 00000000000..5010d7e13af --- /dev/null +++ b/code/controllers/subsystem/asset_loading.dm @@ -0,0 +1,30 @@ +/** + * Allows us to lazyload asset datums. + * Anything inserted here will fully load if directly gotten. + * So this just serves to remove the requirement to load assets fully during init. + */ +SUBSYSTEM_DEF(asset_loading) + name = "Asset Loading" + priority = FIRE_PRIORITY_ASSETS + subsystem_flags = SS_NO_INIT + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT + var/list/datum/asset/generate_queue = list() + +/datum/controller/subsystem/asset_loading/fire(resumed) + while(length(generate_queue)) + var/datum/asset/to_load = generate_queue[generate_queue.len] + + to_load.queued_generation() + + if(MC_TICK_CHECK) + return + generate_queue.len-- + +/datum/controller/subsystem/asset_loading/proc/queue_asset(datum/asset/queue) +#ifdef DO_NOT_DEFER_ASSETS + stack_trace("We queued an instance of [queue.type] for lateloading despite not allowing it") +#endif + generate_queue += queue + +/datum/controller/subsystem/asset_loading/proc/dequeue_asset(datum/asset/queue) + generate_queue -= queue diff --git a/code/controllers/subsystem/assets.dm b/code/controllers/subsystem/assets.dm index fe2abb4879f..cf8c2780a98 100644 --- a/code/controllers/subsystem/assets.dm +++ b/code/controllers/subsystem/assets.dm @@ -26,11 +26,11 @@ SUBSYSTEM_DEF(assets) for(var/type in typesof(/datum/asset)) var/datum/asset/A = type if (type != initial(A._abstract)) - get_asset_datum(type) + load_asset_datum(type) transport.Initialize(cache) - ..() + return ..() /datum/controller/subsystem/assets/Recover() cache = SSassets.cache diff --git a/code/controllers/subsystem/early_assets.dm b/code/controllers/subsystem/early_assets.dm new file mode 100644 index 00000000000..f77c6875186 --- /dev/null +++ b/code/controllers/subsystem/early_assets.dm @@ -0,0 +1,26 @@ +/** + * Initializes any assets that need to be loaded ASAP. + * This houses preference menu assets, since they can be loaded at any time, + * most dangerously before the atoms SS initializes. + * Thus, we want it to fail consistently in CI as if it would've if a player + * opened it up early. + */ +SUBSYSTEM_DEF(early_assets) + name = "Early Assets" + init_order = INIT_ORDER_EARLY_ASSETS + subsystem_flags = SS_NO_FIRE + +/datum/controller/subsystem/early_assets/Initialize(timeofday) + for (var/datum/asset/asset_type as anything in subtypesof(/datum/asset)) + if (initial(asset_type._abstract) == asset_type) + continue + + if (!initial(asset_type.early)) + continue + + if (!load_asset_datum(asset_type)) + stack_trace("Could not initialize early asset [asset_type]!") + + CHECK_TICK + + return ..() diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm index f7c36c68271..72b61cacb8d 100644 --- a/code/controllers/subsystem/lighting.dm +++ b/code/controllers/subsystem/lighting.dm @@ -1,7 +1,12 @@ -GLOBAL_LIST_EMPTY(lighting_update_lights) // List of lighting sources queued for update. -GLOBAL_LIST_EMPTY(lighting_update_corners) // List of lighting corners queued for update. +GLOBAL_LIST_EMPTY(lighting_update_lights) // List of lighting sources queued for update. +GLOBAL_LIST_EMPTY(lighting_update_corners) // List of lighting corners queued for update. GLOBAL_LIST_EMPTY(lighting_update_objects) // List of lighting objects queued for update. +#ifdef VISUALIZE_LIGHT_UPDATES +GLOBAL_VAR_INIT(allow_duped_values, FALSE) +GLOBAL_VAR_INIT(allow_duped_corners, FALSE) +#endif + SUBSYSTEM_DEF(lighting) name = "Lighting" wait = 2 diff --git a/code/controllers/subsystem/processing/chemistry.dm b/code/controllers/subsystem/processing/chemistry.dm index 1e489ffa37d..9a10c3c2f83 100644 --- a/code/controllers/subsystem/processing/chemistry.dm +++ b/code/controllers/subsystem/processing/chemistry.dm @@ -17,12 +17,14 @@ PROCESSING_SUBSYSTEM_DEF(chemistry) initialize_chemical_reagents() return ..() -//Chemical Reactions - Initialises all /datum/chemical_reaction into a list -// It is filtered into multiple lists within a list. -// For example: -// chemical_reaction_list["phoron"] is a list of all reactions relating to phoron -// Note that entries in the list are NOT duplicated. So if a reaction pertains to -// more than one chemical it will still only appear in only one of the sublists. +/** + * Chemical Reactions - Initialises all /datum/chemical_reaction into a list + * It is filtered into multiple lists within a list. + * For example: + * - chemical_reaction_list["phoron"] is a list of all reactions relating to phoron + * - Note that entries in the list are NOT duplicated. So if a reaction pertains to + * - more than one chemical it will still only appear in only one of the sublists. + */ /datum/controller/subsystem/processing/chemistry/proc/initialize_chemical_reactions() var/paths = typesof(/datum/chemical_reaction) - /datum/chemical_reaction chemical_reactions = list() @@ -36,7 +38,7 @@ PROCESSING_SUBSYSTEM_DEF(chemistry) LAZYINITLIST(chemical_reactions_by_reagent[reagent_id]) chemical_reactions_by_reagent[reagent_id] += D -//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id +/// Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id /datum/controller/subsystem/processing/chemistry/proc/initialize_chemical_reagents() var/paths = typesof(/datum/reagent) - /datum/reagent chemical_reagents = list() diff --git a/code/datums/elements/update_icon_blocker.dm b/code/datums/elements/update_icon_blocker.dm new file mode 100644 index 00000000000..45206772564 --- /dev/null +++ b/code/datums/elements/update_icon_blocker.dm @@ -0,0 +1,18 @@ +/// Prevents calling anything in update_icon() like update_icon_state() or update_overlays() +/datum/element/update_icon_blocker + +/datum/element/update_icon_blocker/Attach(datum/target) + . = ..() + if(!isatom(target)) + return ELEMENT_INCOMPATIBLE + + RegisterSignal(target, COMSIG_ATOM_UPDATE_ICON, .proc/block_update_icon) + +/datum/element/update_icon_blocker/Detach(datum/source, ...) + UnregisterSignal(source, COMSIG_ATOM_UPDATE_ICON) + return ..() + +/datum/element/update_icon_blocker/proc/block_update_icon() + SIGNAL_HANDLER + + return COMSIG_ATOM_NO_UPDATE_ICON_STATE | COMSIG_ATOM_NO_UPDATE_OVERLAYS diff --git a/code/game/atoms/atoms.dm b/code/game/atoms/atoms.dm index b38373dea61..ff16bc124d5 100644 --- a/code/game/atoms/atoms.dm +++ b/code/game/atoms/atoms.dm @@ -845,11 +845,12 @@ /atom/proc/InsertedContents() return contents +/// Where atoms should drop if taken from this atom. /atom/proc/drop_location() - var/atom/L = loc - if(!L) + var/atom/location = loc + if(!location) return null - return L.AllowDrop() ? L : L.drop_location() + return location.AllowDrop() ? location : location.drop_location() /atom/proc/AllowDrop() return FALSE diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index b8ca5857b6a..91d8322ed7e 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -287,3 +287,9 @@ /// Used below, simple injection modifier. /proc/probinj(pr, inj) return prob(pr+inj*pr) + +/mob/proc/has_dna() + return + +/mob/living/carbon/has_dna() + return dna diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 51b39c8dd2e..b9868ca4eac 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -42,7 +42,7 @@ /obj/machinery/dna_scannernew name = "\improper DNA modifier" desc = "It scans DNA structures." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "scanner_0" density = TRUE anchored = TRUE diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 45921ae95c5..118a36d9047 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -1,6 +1,6 @@ /obj/machinery/sleep_console name = "sleeper console" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "sleeperconsole" var/obj/machinery/sleeper/sleeper anchored = TRUE @@ -160,7 +160,7 @@ /obj/machinery/sleeper name = "sleeper" desc = "A stasis pod with built-in injectors, a dialysis machine, and a limited health scanner." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "sleeper_0" density = TRUE anchored = TRUE diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index c612d6af9e0..805020690fd 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -105,10 +105,12 @@ var/machine_stat = 0 var/emagged = FALSE + /** + * USE_POWER_OFF = dont run the auto + * USE_POWER_IDLE = run auto, use idle + * USE_POWER_ACTIVE = run auto, use active + */ var/use_power = USE_POWER_IDLE - //0 = dont run the auto - //1 = run auto, use idle - //2 = run auto, use active /// idle power usage in watts var/idle_power_usage = 0 /// active power usage in watts @@ -456,7 +458,8 @@ /obj/machinery/proc/dismantle() playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) - //TFF 3/6/19 - port Cit RP fix of infinite frames. If it doesn't have a circuit board, don't create a frame. Return a smack instead. BONK! + on_deconstruction() + // If it doesn't have a circuit board, don't create a frame. Return a smack instead. BONK! if(!circuit) return 0 var/obj/structure/frame/A = new /obj/structure/frame(src.loc) @@ -501,3 +504,36 @@ M.after_deconstruct(src) qdel(src) return 1 + +//called on machinery construction (i.e from frame to machinery) but not on initialization +// /obj/machinery/proc/on_construction() //! Not used yet. +// return + +//called on deconstruction before the final deletion +/obj/machinery/proc/on_deconstruction() + return + +/** + * Puts passed object in to user's hand + * + * Puts the passed object in to the users hand if they are adjacent. + * If the user is not adjacent then place the object on top of the machine. + * + * Vars: + * * object (obj) The object to be moved in to the users hand. + * * user (mob/living) The user to recive the object + */ +/obj/machinery/proc/try_put_in_hand(obj/object, mob/living/user) + if(!issilicon(user) && in_range(src, user)) + user.put_in_hands(object) + else + object.forceMove(drop_location()) + +/// Adjust item drop location to a 3x3 grid inside the tile, returns slot id from 0 to 8. +/obj/machinery/proc/adjust_item_drop_location(atom/movable/dropped_atom) + var/md5 = md5(dropped_atom.name) // Oh, and it's deterministic too. A specific item will always drop from the same slot. + for (var/i in 1 to 32) + . += hex2num(md5[i]) + . = . % 9 + dropped_atom.pixel_x = -8 + ((.%3)*8) + dropped_atom.pixel_y = -8 + (round( . / 3)*8) diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 6d935d291ff..b3f4b0ad4ee 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -4,7 +4,7 @@ var/mob/living/carbon/occupant var/locked name = "Body Scanner" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "scanner_open" density = 1 anchored = 1 @@ -166,7 +166,7 @@ var/delete var/temphtml name = "Body Scanner Console" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "scanner_terminal_off" dir = 8 density = 1 diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 79f6ee0d859..1fd3d6d3e2e 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -2,7 +2,7 @@ #define HEAT_CAPACITY_HUMAN 100 /obj/machinery/atmospherics/component/unary/cryo_cell name = "cryo cell" - icon = 'icons/obj/cryogenics.dmi' // map only + icon = 'icons/obj/medical/cryogenics.dmi' // map only icon_state = "pod_preview" density = TRUE anchored = TRUE @@ -27,7 +27,7 @@ /obj/machinery/atmospherics/component/unary/cryo_cell/Initialize(mapload) . = ..() - icon = 'icons/obj/cryogenics_split.dmi' + icon = 'icons/obj/medical/cryogenics_split.dmi' icon_state = "base" initialize_directions = dir diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 160051cc68d..598de3f4e66 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -11,7 +11,7 @@ /obj/machinery/computer/cryopod name = "cryogenic oversight console" desc = "An interface between crew and the cryogenic storage oversight systems." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "cellconsole" circuit = /obj/item/circuitboard/cryopodcontrol density = FALSE @@ -190,7 +190,7 @@ name = "cryogenic feed" desc = "A bewildering tangle of machinery and pipes." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "cryo_rear" anchored = TRUE dir = WEST @@ -199,7 +199,7 @@ /obj/machinery/cryopod name = "cryogenic freezer" desc = "A man-sized pod for entering suspended animation." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "cryopod_0" density = TRUE anchored = TRUE diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index a5e2db02de4..0428bfe6ff6 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -1,74 +1,160 @@ +#define IV_TAKING 0 +#define IV_INJECTING 1 + +#define MIN_IV_TRANSFER_RATE 0.1 +#define MAX_IV_TRANSFER_RATE 5 + + +/// Universal IV that can drain blood or feed reagents over a period of time from or to a replaceable container. /obj/machinery/iv_drip name = "\improper IV drip" - icon = 'icons/obj/iv_drip.dmi' + icon = 'icons/obj/medical/iv_drip.dmi' + icon_state = "iv_drip" + base_icon_state = "iv_drip" anchored = FALSE - density = FALSE + mouse_drag_pointer = MOUSE_ACTIVE_POINTER + use_power = USE_POWER_OFF pass_flags_self = ATOM_PASS_TABLE | ATOM_PASS_OVERHEAD_THROW - var/mob/living/carbon/human/attached = null - var/mode = 1 // 1 is injecting, 0 is taking blood. - var/obj/item/reagent_containers/beaker = null + /// Who are we sticking our needle in? + var/mob/living/carbon/attached + /// Are we donating or injecting? + var/mode = IV_INJECTING + /// Whether we feed slower. + var/transfer_rate = MAX_IV_TRANSFER_RATE + /// Internal beaker. + var/obj/item/reagent_container = null + ///Typecache of containers we accept + var/static/list/drip_containers = typecacheof(list( + /obj/item/reagent_containers/blood, + )) + /// If the blood draining tab should be greyed out. + ///! Not Used. + var/inject_only = FALSE -/obj/machinery/iv_drip/update_icon() +/obj/machinery/iv_drip/Initialize(mapload) + . = ..() + update_appearance() + // if(use_internal_storage) + // create_reagents(100, TRANSPARENT) + interaction_flags_machine |= INTERACT_MACHINE_OFFLINE + +/obj/machinery/iv_drip/Destroy() + attached = null + QDEL_NULL(reagent_container) + return ..() + +/obj/machinery/iv_drip/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "IVDrip", name) + ui.open() + +/obj/machinery/iv_drip/ui_data(mob/user) + var/list/data = list() + data["transferRate"] = transfer_rate + data["maxInjectRate"] = MAX_IV_TRANSFER_RATE + data["minInjectRate"] = MIN_IV_TRANSFER_RATE + data["mode"] = mode == IV_INJECTING ? TRUE : FALSE + data["connected"] = attached ? TRUE : FALSE + data["beakerAttached"] = reagent_container ? TRUE : FALSE + // data["useInternalStorage"] = use_internal_storage + return data + +/obj/machinery/iv_drip/ui_act(action, params) + . = ..() + if(.) + return + switch(action) + if("changeMode") + toggle_mode() + . = TRUE + if("eject") + eject_beaker() + . = TRUE + if("changeRate") + var/target_rate = params["rate"] + if(text2num(target_rate) != null) + target_rate = text2num(target_rate) + transfer_rate = round(clamp(target_rate, MIN_IV_TRANSFER_RATE, MAX_IV_TRANSFER_RATE), 0.1) + . = TRUE + update_appearance() + +/obj/machinery/iv_drip/update_icon_state() if(attached) - icon_state = "hooked" + icon_state = "[base_icon_state]_[mode ? "injecting" : "donating"]" else - icon_state = "" + icon_state = "[base_icon_state]_[mode ? "injectidle" : "donateidle"]" + return ..() - overlays = null +/obj/machinery/iv_drip/update_overlays() + . = ..() - if(beaker) - var/datum/reagents/reagents = beaker.reagents - if(reagents.total_volume) - var/image/filling = image('icons/obj/iv_drip.dmi', src, "reagent") + if(!reagent_container) + return - var/percent = round((reagents.total_volume / beaker.volume) * 100) - switch(percent) - if(0 to 9) - filling.icon_state = "reagent0" - if(10 to 24) - filling.icon_state = "reagent10" - if(25 to 49) - filling.icon_state = "reagent25" - if(50 to 74) - filling.icon_state = "reagent50" - if(75 to 79) - filling.icon_state = "reagent75" - if(80 to 90) - filling.icon_state = "reagent80" - if(91 to INFINITY) - filling.icon_state = "reagent100" + . += attached ? "beakeractive" : "beakeridle" + var/datum/reagents/target_reagents = get_reagent_holder() + if(!target_reagents) + return - filling.icon += reagents.get_color() - overlays += filling + var/mutable_appearance/filling_overlay = mutable_appearance('icons/obj/medical/iv_drip.dmi', "reagent") + var/percent = round((target_reagents.total_volume / target_reagents.maximum_volume) * 100) + switch(percent) + if(0 to 9) + filling_overlay.icon_state = "reagent0" + if(10 to 24) + filling_overlay.icon_state = "reagent10" + if(25 to 49) + filling_overlay.icon_state = "reagent25" + if(50 to 74) + filling_overlay.icon_state = "reagent50" + if(75 to 79) + filling_overlay.icon_state = "reagent75" + if(80 to 90) + filling_overlay.icon_state = "reagent80" + if(91 to INFINITY) + filling_overlay.icon_state = "reagent100" -/obj/machinery/iv_drip/OnMouseDropLegacy(over_object, src_location, over_location) - ..() - if(!isliving(usr)) + filling_overlay.color = mix_color_from_reagents(target_reagents.reagent_list) + . += filling_overlay + +/obj/machinery/iv_drip/OnMouseDropLegacy(mob/living/target) + . = ..() + if(!ishuman(usr) || !usr.canUseTopic(src, be_close = TRUE) || !isliving(target)) return if(attached) - visible_message(SPAN_NOTICE("[attached] is detached from \the [src]")) + visible_message(SPAN_WARNING("[attached] is detached from [src].")) attached = null - update_icon() + update_appearance() return - if(in_range(src, usr) && ishuman(over_object) && get_dist(over_object, src) <= 1) - visible_message(SPAN_NOTICE("[usr] attaches \the [src] to \the [over_object].")) - attached = over_object - update_icon() + if(!target.has_dna()) + to_chat(usr, SPAN_DANGER("The drip beeps: Warning, incompatible creature!")) + return + if(Adjacent(target) && usr.Adjacent(target)) + if(get_reagent_holder()) + attach_iv(target, usr) + else + to_chat(usr, SPAN_WARNING("There's nothing attached to the IV drip!")) -/obj/machinery/iv_drip/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/reagent_containers)) - if(!isnull(beaker)) - to_chat(user, SPAN_WARNING("There is already a reagent container loaded!")) +/obj/machinery/iv_drip/attackby(obj/item/W, mob/user, params) + // if(use_internal_storage) + // return ..() + + if(is_type_in_typecache(W, drip_containers)) + if(reagent_container) + to_chat(user, SPAN_WARNING("[reagent_container] is already loaded on [src]!")) return if(!user.attempt_insert_item_for_installation(W, src)) return - beaker = W - to_chat(user, SPAN_NOTICE("You attach \the [W] to \the [src].")) - update_icon() + reagent_container = W + to_chat(user, SPAN_NOTICE("You attach [W] to [src].")) + // user.log_message("attached a [W] to [src] at [AREACOORD(src)] containing ([reagent_container.reagents.get_reagent_log_string()])", LOG_ATTACK) + add_fingerprint(user) + update_appearance() return if(W.is_screwdriver()) @@ -78,109 +164,174 @@ to_chat(user, SPAN_NOTICE("You dismantle the IV drip.")) var/obj/item/stack/rods/A = new /obj/item/stack/rods(src.loc) A.amount = 6 - if(beaker) - beaker.loc = get_turf(src) - beaker = null + if(reagent_container) + reagent_container.loc = get_turf(src) + reagent_container = null qdel(src) return else return ..() - -/obj/machinery/iv_drip/process(delta_time) - set background = 1 - - if(attached) - - if(!(get_dist(src, attached) <= 1 && isturf(attached.loc))) - visible_message("The needle is ripped out of [attached], doesn't that hurt?") - attached:apply_damage(3, BRUTE, pick("r_arm", "l_arm")) - attached = null - update_icon() - return - - if(attached && beaker) - // Give blood - if(mode) - if(beaker.volume > 0) - var/transfer_amount = REM - if(istype(beaker, /obj/item/reagent_containers/blood)) - // speed up transfer on blood packs - transfer_amount = 4 - beaker.reagents.trans_to_mob(attached, transfer_amount, CHEM_BLOOD) - update_icon() - - // Take blood - else - var/amount = beaker.reagents.maximum_volume - beaker.reagents.total_volume - amount = min(amount, 4) - // If the beaker is full, ping - if(amount == 0) - if(prob(5)) - visible_message(SPAN_NOTICE("\The [src] pings.")) - return - - var/mob/living/carbon/human/T = attached - - if(!istype(T)) - return - if(!T.dna) - return - if(MUTATION_NOCLONE in T.mutations) - return - - if(!T.should_have_organ(O_HEART)) - return - - // If the human is losing too much blood, beep. - if(T.vessel.get_reagent_amount("blood") < T.species.blood_volume*T.species.blood_level_safe) - visible_message(SPAN_BOLDNOTICE("\The [src] beeps loudly.")) - - var/datum/reagent/B = T.take_blood(beaker,amount) - - if(B) - beaker.reagents.reagent_list |= B - beaker.reagents.update_total() - beaker.on_reagent_change() - beaker.reagents.handle_reactions() - update_icon() - /obj/machinery/iv_drip/attack_hand(mob/user) - if(beaker) - beaker.loc = get_turf(src) - beaker = null - update_icon() + if(reagent_container) + reagent_container.loc = get_turf(src) + reagent_container = null + update_appearance() else return ..() +/obj/machinery/iv_drip/process(delta_time) + if(!attached) + return PROCESS_KILL + + if(!(get_dist(src, attached) <= 1 && isturf(attached.loc))) + to_chat(attached, SPAN_USERDANGER("The IV drip needle is ripped out of you, leaving an open bleeding wound!")) + var/list/arm_zones = shuffle(list(BP_R_ARM, BP_L_ARM)) + var/obj/item/organ/external/chosen_limb = attached.get_organ(arm_zones[1]) || attached.get_organ(arm_zones[2]) || attached.get_organ(BP_TORSO) + chosen_limb.take_damage(3) + chosen_limb.createwound(CUT, 5) + detach_iv() + return PROCESS_KILL + + var/datum/reagents/target_reagents = get_reagent_holder() + if(target_reagents) + // Give blood + if(mode) + if(target_reagents.total_volume) + var/real_transfer_amount = transfer_rate + if(istype(reagent_container, /obj/item/reagent_containers/blood)) + // speed up transfer on blood packs + real_transfer_amount *= 2 + target_reagents.trans_to_mob(attached, real_transfer_amount * delta_time * 0.5, type = CHEM_BLOOD) + update_appearance() + + // Take blood + else + var/amount = target_reagents.maximum_volume - target_reagents.total_volume + amount = min(amount, 4) * delta_time * 0.5 + // If the beaker is full, ping + if(!amount) + if(prob(5)) + visible_message(SPAN_HEAR("[src] pings.")) + return + + // If the human is losing too much blood, beep. + if(attached.species.blood_volume < BLOOD_VOLUME_SAFE && prob(5)) + visible_message(SPAN_HEAR("[src] beeps loudly.")) + playsound(loc, 'sound/machines/twobeep_high.ogg', 50, TRUE) + // var/atom/movable/target = use_internal_storage ? src : reagent_container + var/atom/movable/target = reagent_container + attached.inject_blood(target, amount) + update_appearance() + +/// called when an IV is attached. +/obj/machinery/iv_drip/proc/attach_iv(mob/living/target, mob/user) + user.visible_message( + SPAN_WARNING("[usr] begins attaching [src] to [target]..."), + SPAN_WARNING("You begin attaching [src] to [target]."), + ) + if(!do_after(usr, 1 SECONDS, target)) + return + usr.visible_message( + SPAN_WARNING("[usr] attaches [src] to [target]."), + SPAN_NOTICE("You attach [src] to [target]."), + ) + // var/datum/reagents/container = get_reagent_holder() + // log_combat(usr, target, "attached", src, "containing: ([container.get_reagent_log_string()])") + add_fingerprint(usr) + attached = target + // START_PROCESSING(SSmachines, src) + update_appearance() + + //! Plumbing Signal + // SEND_SIGNAL(src, COMSIG_IV_ATTACH, target) + +/** + * Called when an iv is detached. + * doesn't include chat stuff because there's multiple options and its better handled by the caller. + */ +/obj/machinery/iv_drip/proc/detach_iv() + //! Plumbing Signal + // SEND_SIGNAL(src, COMSIG_IV_DETACH, attached) + + attached = null + update_appearance() + +/obj/machinery/iv_drip/proc/get_reagent_holder() + // return use_internal_storage ? reagents : reagent_container?.reagents + return reagent_container?.reagents + +/obj/machinery/iv_drip/verb/eject_beaker() + set category = "Object" + set name = "Remove IV Container" + set src in view(1) + + if(!isliving(usr)) + to_chat(usr, SPAN_WARNING("You can't do that!")) + return + if (!usr.canUseTopic()) + return + if(usr.incapacitated()) + return + if(reagent_container) + if(attached) + visible_message(SPAN_WARNING("[attached] is detached from [src].")) + detach_iv() + reagent_container.forceMove(drop_location()) + reagent_container = null + update_appearance() /obj/machinery/iv_drip/verb/toggle_mode() set category = "Object" set name = "Toggle Mode" set src in view(1) - if(!istype(usr, /mob/living)) - to_chat(usr, SPAN_WARNING("You can't do that.")) + if(!isliving(usr)) + to_chat(usr, SPAN_WARNING("You can't do that!")) return - - if(usr.stat) + if (!usr.canUseTopic()) + return + if(usr.incapacitated()) return - mode = !mode - to_chat(usr, SPAN_INFO("The IV drip is now [mode ? "injecting" : "taking blood"].")) + to_chat(usr, SPAN_NOTICE("The IV drip is now [mode ? "injecting" : "taking blood"].")) + update_appearance() /obj/machinery/iv_drip/examine(mob/user) . = ..() - if(!(user in view(2)) && user != src.loc) + if(get_dist(user, src) > 2) return - . += SPAN_INFO("The IV drip is [mode ? "injecting" : "taking blood"].") - if(beaker) - if(beaker.reagents && beaker.reagents.reagent_list.len) - . += SPAN_NOTICE("Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.") + . += "[src] is [mode ? "injecting" : "taking blood"]." + + if(reagent_container) + if(reagent_container.reagents && reagent_container.reagents.reagent_list.len) + . += SPAN_NOTICE("Attached is \a [reagent_container] with [reagent_container.reagents.total_volume] units of liquid.") else - . += SPAN_NOTICE("Attached is an empty [beaker].") - else + . += SPAN_NOTICE("Attached is an empty [reagent_container.name].") + // else if(use_internal_storage) + // . += SPAN_NOTICE("It has an internal chemical storage.") + // else . += SPAN_NOTICE("No chemicals are attached.") . += SPAN_NOTICE("[attached ? attached : "No one"] is attached.") +/* +/obj/machinery/iv_drip/saline + name = "saline drip" + desc = "An all-you-can-drip saline canister designed to supply a hospital without running out, with a scary looking pump rigged to inject saline into containers, but filling people directly might be a bad idea." + icon_state = "saline" + base_icon_state = "saline" + density = TRUE + inject_only = TRUE + +/obj/machinery/iv_drip/saline/Initialize(mapload) + AddElement(/datum/element/update_icon_blocker) + . = ..() + reagent_container = new /obj/item/reagent_containers/cup/saline(src) + +/obj/machinery/iv_drip/saline/eject_beaker() + return + +/obj/machinery/iv_drip/saline/toggle_mode() + return +*/ diff --git a/code/game/machinery/virtual_reality/ar_console.dm b/code/game/machinery/virtual_reality/ar_console.dm index 85916d437d1..8941321769a 100644 --- a/code/game/machinery/virtual_reality/ar_console.dm +++ b/code/game/machinery/virtual_reality/ar_console.dm @@ -6,7 +6,7 @@ /obj/machinery/vr_sleeper/alien name = "strange pod" desc = "A strange machine with what appears to be a comfortable, if quite vertical, bed. Numerous mechanical cylinders dot the ceiling, their purpose uncertain." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "alienpod_0" base_state = "alienpod_" diff --git a/code/game/machinery/virtual_reality/vr_console.dm b/code/game/machinery/virtual_reality/vr_console.dm index 258fd29d3a0..938dc3de600 100644 --- a/code/game/machinery/virtual_reality/vr_console.dm +++ b/code/game/machinery/virtual_reality/vr_console.dm @@ -1,7 +1,7 @@ /obj/machinery/vr_sleeper name = "virtual reality sleeper" desc = "A fancy bed with built-in sensory I/O ports and connectors to interface users' minds with their bodies in virtual reality." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "syndipod_0" var/base_state = "syndipod_" diff --git a/code/game/machinery/vr_console.dm b/code/game/machinery/vr_console.dm index e76980eba38..de72c441912 100644 --- a/code/game/machinery/vr_console.dm +++ b/code/game/machinery/vr_console.dm @@ -1,7 +1,7 @@ /obj/machinery/vr_sleeper name = "virtual reality sleeper" desc = "A fancy bed with built-in sensory I/O ports and connectors to interface users' minds with their bodies in virtual reality." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "syndipod_0" density = TRUE anchored = TRUE diff --git a/code/game/mecha/equipment/tools/sleeper.dm b/code/game/mecha/equipment/tools/sleeper.dm index 5f3d429f49b..03c6c68c8cd 100644 --- a/code/game/mecha/equipment/tools/sleeper.dm +++ b/code/game/mecha/equipment/tools/sleeper.dm @@ -1,7 +1,7 @@ /obj/item/mecha_parts/mecha_equipment/tool/sleeper name = "mounted sleeper" desc = "A sleeper. Mountable to an exosuit. (Can be attached to: Medical Exosuits)" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "sleeper_0" origin_tech = list(TECH_DATA = 2, TECH_BIO = 3) energy_drain = 20 diff --git a/code/game/mecha/equipment/tools/syringe_gun.dm b/code/game/mecha/equipment/tools/syringe_gun.dm index 28510cba26c..582bde85df5 100644 --- a/code/game/mecha/equipment/tools/syringe_gun.dm +++ b/code/game/mecha/equipment/tools/syringe_gun.dm @@ -66,7 +66,7 @@ S.forceMove(get_turf(chassis)) reagents.trans_to_obj(S, min(S.volume, reagents.total_volume)) syringes -= S - S.icon = 'icons/obj/chemical.dmi' + S.icon = 'icons/obj/medical/chemical.dmi' S.icon_state = "syringeproj" playsound(src, 'sound/items/syringeproj.ogg', 50, 1) log_message("Launched [S] from [src], targeting [target].") diff --git a/code/game/objects/effects/chem/water.dm b/code/game/objects/effects/chem/water.dm index bb4da7d1fbb..b5f941c096c 100644 --- a/code/game/objects/effects/chem/water.dm +++ b/code/game/objects/effects/chem/water.dm @@ -48,5 +48,6 @@ //Used by spraybottles. /obj/effect/water/chempuff name = "chemicals" - icon = 'icons/obj/chempuff.dmi' + icon = 'icons/obj/medical/chempuff.dmi' icon_state = "" + layer = FLY_LAYER diff --git a/code/game/objects/effects/debris/cleanable/misc.dm b/code/game/objects/effects/debris/cleanable/misc.dm index d6c79e4ecd3..2bca9ff33cb 100644 --- a/code/game/objects/effects/debris/cleanable/misc.dm +++ b/code/game/objects/effects/debris/cleanable/misc.dm @@ -72,7 +72,7 @@ density = 0 anchored = 1 plane = OBJ_PLANE - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "molten" /obj/effect/debris/cleanable/cobweb2 diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index a96a9a7f8cb..adc47411457 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -3,7 +3,7 @@ /obj/item/bodybag name = "body bag" desc = "A folded bag designed for the storage and transportation of cadavers." - icon = 'icons/obj/bodybag.dmi' + icon = 'icons/obj/medical/bodybag.dmi' icon_state = "bodybag_folded" w_class = ITEMSIZE_SMALL @@ -32,7 +32,7 @@ /obj/structure/closet/body_bag name = "body bag" desc = "A plastic bag designed for the storage and transportation of cadavers." - icon = 'icons/obj/bodybag.dmi' + icon = 'icons/obj/medical/bodybag.dmi' icon_state = "bodybag_closed" icon_closed = "bodybag_closed" icon_opened = "bodybag_open" @@ -118,7 +118,7 @@ name = "stasis bag" desc = "A non-reusable plastic bag designed to slow down bodily functions such as circulation and breathing, \ especially useful if short on time or in a hostile enviroment." - icon = 'icons/obj/cryobag.dmi' + icon = 'icons/obj/medical/cryobag.dmi' icon_state = "bodybag_folded" item_state = "bodybag_cryo_folded" origin_tech = list(TECH_BIO = 4) @@ -136,7 +136,7 @@ name = "stasis bag" desc = "A non-reusable plastic bag designed to slow down bodily functions such as circulation and breathing, \ especially useful if short on time or in a hostile enviroment." - icon = 'icons/obj/cryobag.dmi' + icon = 'icons/obj/medical/cryobag.dmi' item_path = /obj/item/bodybag/cryobag store_misc = 0 store_items = 0 diff --git a/code/game/objects/items/circuitboards/other.dm b/code/game/objects/items/circuitboards/other.dm index 900476518a9..da7e89e1b4c 100644 --- a/code/game/objects/items/circuitboards/other.dm +++ b/code/game/objects/items/circuitboards/other.dm @@ -15,6 +15,7 @@ board_type = new /datum/frame/frame_types/machine origin_tech = list(TECH_DATA = 3, TECH_MAGNET = 2) req_components = list( + /obj/item/reagent_containers/glass/beaker = 2, /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 2, ) diff --git a/code/game/objects/items/devices/defib.dm b/code/game/objects/items/devices/defib.dm index f89da8cab2f..ee31c521df4 100644 --- a/code/game/objects/items/devices/defib.dm +++ b/code/game/objects/items/devices/defib.dm @@ -6,7 +6,7 @@ /obj/item/defib_kit name = "defibrillator" desc = "A device that delivers powerful shocks to detachable paddles that resuscitate incapacitated patients." - icon = 'icons/obj/defibrillator.dmi' + icon = 'icons/obj/medical/defibrillator.dmi' icon_state = "defibunit" item_state = "defibunit" slot_flags = SLOT_BACK @@ -187,7 +187,7 @@ /obj/item/shockpaddles name = "defibrillator paddles" desc = "A pair of plastic-gripped paddles with flat metal surfaces that are used to deliver powerful electric shocks." - icon = 'icons/obj/defibrillator.dmi' + icon = 'icons/obj/medical/defibrillator.dmi' icon_state = "defibpaddles" item_state = "defibpaddles" gender = PLURAL diff --git a/code/game/objects/items/robobag.dm b/code/game/objects/items/robobag.dm index e9c46db31e5..22224379ce5 100644 --- a/code/game/objects/items/robobag.dm +++ b/code/game/objects/items/robobag.dm @@ -3,7 +3,7 @@ name = "synthmorph bag" desc = "A reusable polymer bag designed to slow down synthetic functions such as data corruption and coolant flow, \ especially useful if short on time or in a hostile enviroment." - icon = 'icons/obj/robobag.dmi' + icon = 'icons/obj/medical/robobag.dmi' icon_state = "bodybag_folded" item_state = "bodybag_cryo_folded" origin_tech = list(TECH_ENGINEERING = 3) @@ -20,7 +20,7 @@ name = "synthmorph bag" desc = "A reusable polymer bag designed to slow down synthetic functions such as data corruption and coolant flow, \ especially useful if short on time or in a hostile enviroment." - icon = 'icons/obj/robobag.dmi' + icon = 'icons/obj/medical/robobag.dmi' item_path = /obj/item/bodybag/cryobag/robobag tank_type = /obj/item/tank/stasis/nitro_cryo stasis_level = 2 // Lower than the normal cryobag, because it's not made for meat that dies. It's made for robots and is freezing. diff --git a/code/game/objects/items/storage/_storage.dm b/code/game/objects/items/storage/_storage.dm index 36f6909f4a5..f9345dbebbd 100644 --- a/code/game/objects/items/storage/_storage.dm +++ b/code/game/objects/items/storage/_storage.dm @@ -716,4 +716,4 @@ . += "\The [src] contains \the [display_item]!" /obj/item/storage/AllowDrop() - return TRUE + return FALSE diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index 60038e7e4f0..3dc238d69b7 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -162,7 +162,7 @@ name = "pill bottle" desc = "It's an airtight container for storing medication." icon_state = "pill_canister" - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' drop_sound = 'sound/items/drop/pillbottle.ogg' pickup_sound = 'sound/items/pickup/pillbottle.ogg' item_state_slots = list(SLOT_ID_RIGHT_HAND = "contsolid", SLOT_ID_LEFT_HAND = "contsolid") @@ -244,7 +244,7 @@ /obj/item/storage/pill_bottle/update_icon() ..() if(labeled == 1) - add_overlay(image(icon = 'icons/obj/chemical.dmi', icon_state = "pill_canister_label")) + add_overlay(image(icon = 'icons/obj/medical/chemical.dmi', icon_state = "pill_canister_label")) if(base_icon == "pill_canister") if(bottle_color == "orange") icon_state = "[base_icon]" diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index b7979233d7f..b96add03c94 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -388,7 +388,7 @@ var/obj/effect/decal/D = new/obj/effect/decal/(get_turf(src)) D.name = "water" - D.icon = 'icons/obj/chemical.dmi' + D.icon = 'icons/obj/medical/chemical.dmi' D.icon_state = "chempuff" D.create_reagents(5) src.reagents.trans_to_obj(D, 1) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 333e6d613c7..700b133fa6a 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -29,6 +29,9 @@ var/list/req_access var/list/req_one_access + /// Set when a player renames a renamable object. + var/renamed_by_player = FALSE + /obj/Initialize(mapload) if(register_as_dangerous_object) register_dangerous_to_step() diff --git a/code/game/objects/random/misc.dm b/code/game/objects/random/misc.dm index f875c01ffa6..f6d0cfed736 100644 --- a/code/game/objects/random/misc.dm +++ b/code/game/objects/random/misc.dm @@ -187,7 +187,7 @@ /obj/random/medical/pillbottle name = "Random Pill Bottle" desc = "This is a random pill bottle." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "pill_canister" /obj/random/medical/pillbottle/item_to_spawn() diff --git a/code/game/objects/random/unidentified/medicine.dm b/code/game/objects/random/unidentified/medicine.dm index 1d26d93abf8..61c03551690 100644 --- a/code/game/objects/random/unidentified/medicine.dm +++ b/code/game/objects/random/unidentified/medicine.dm @@ -14,7 +14,7 @@ much more likely to show up. This is done for several purposes; /obj/random/unidentified_medicine name = "unidentified medicine" desc = "This will make a random hypo." - icon = 'icons/obj/syringe.dmi' + icon = 'icons/obj/medical/syringe.dmi' icon_state = "autoinjector1" /obj/random/unidentified_medicine/item_to_spawn() diff --git a/code/game/objects/structures/ghost_pods/human.dm b/code/game/objects/structures/ghost_pods/human.dm index efefe4140e2..92dda473cec 100644 --- a/code/game/objects/structures/ghost_pods/human.dm +++ b/code/game/objects/structures/ghost_pods/human.dm @@ -5,7 +5,7 @@ desc = "This is a pod which appears to contain a body." description_info = "This contains a body, which may wake at any time. The external controls\ seem to be malfunctioning." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "sleeper_1" icon_state_opened = "sleeper_0" density = TRUE @@ -132,7 +132,7 @@ desc = "This is a pod which appears to contain a body." description_info = "This contains a body, which may wake at any time. The external controls\ seem to be functioning, though the warning lights that flash give no solace.." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "sleeper_1" icon_state_opened = "sleeper_0" density = TRUE diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index 5d0ecfc0209..d1de4e28801 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -197,7 +197,7 @@ /obj/structure/bed/roller name = "roller bed" desc = "A portable bed-on-wheels made for transporting medical patients." - icon = 'icons/obj/rollerbed.dmi' + icon = 'icons/obj/medical/rollerbed.dmi' icon_state = "rollerbed" base_icon_state = "rollerbed" anchored = FALSE @@ -266,7 +266,7 @@ /obj/item/roller name = "roller bed" desc = "A collapsed roller bed that can be carried around." - icon = 'icons/obj/rollerbed.dmi' + icon = 'icons/obj/medical/rollerbed.dmi' icon_state = "folded_rollerbed" slot_flags = SLOT_BACK w_class = ITEMSIZE_LARGE @@ -303,7 +303,7 @@ /obj/item/roller_holder name = "roller bed rack" desc = "A rack for carrying a collapsed roller bed." - icon = 'icons/obj/rollerbed.dmi' + icon = 'icons/obj/medical/rollerbed.dmi' icon_state = "rollerbed" var/obj/item/roller/held diff --git a/code/game/world.dm b/code/game/world.dm index a22d9fe1582..820dae69e0e 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -18,6 +18,10 @@ GLOBAL_LIST(topic_status_cache) //This happens after the Master subsystem new(s) (it's a global datum) //So subsystems globals exist, but are not initialised /world/New() +#ifdef USE_BYOND_TRACY + #warn USE_BYOND_TRACY is enabled + init_byond_tracy() +#endif log_world("World loaded at [TIME_STAMP("hh:mm:ss", FALSE)]!") var/tempfile = "data/logs/config_error.[GUID()].log" //temporary file used to record errors with loading config, moved to log directory once logging is set @@ -461,3 +465,18 @@ GLOBAL_LIST(topic_status_cache) #endif //! END + +/world/proc/init_byond_tracy() + var/library + + switch (system_type) + if (MS_WINDOWS) + library = "prof.dll" + if (UNIX) + library = "libprof.so" + else + CRASH("Unsupported platform: [system_type]") + + var/init_result = call(library, "init")() + if (init_result != "0") + CRASH("Error initializing byond-tracy: [init_result]") diff --git a/code/modules/asset_cache/asset_list.dm b/code/modules/asset_cache/asset_list.dm index 8fc87721798..a6431a6bf43 100644 --- a/code/modules/asset_cache/asset_list.dm +++ b/code/modules/asset_cache/asset_list.dm @@ -6,8 +6,16 @@ //all of our asset datums, used for referring to these later GLOBAL_LIST_EMPTY(asset_datums) -//get an assetdatum or make a new one +/// Get an assetdatum or make a new one. /proc/get_asset_datum(type) + var/datum/asset/loaded_asset = GLOB.asset_datums[type] || new type() + return loaded_asset.ensure_ready() + +/** + * Get an assetdatum or make a new one. + *! But does NOT ensure it's filled, if you want that use get_asset_datum() + */ +/proc/load_asset_datum(type) return GLOB.asset_datums[type] || new type() /datum/asset @@ -18,11 +26,25 @@ GLOBAL_LIST_EMPTY(asset_datums) /// Whether or not this asset should be loaded in the "early assets" SS var/early = FALSE - /// Whether or not this asset can be cached across rounds of the same commit under the `CACHE_ASSETS` config. - /// This is not a *guarantee* the asset will be cached. Not all asset subtypes respect this field, and the - /// config can, of course, be disabled. + /** + * Whether or not this asset can be cached across rounds of the same commit under the `CACHE_ASSETS` config. + * This is not a *guarantee* the asset will be cached. Not all asset subtypes respect this field, and the + * config can, of course, be disabled. + */ var/cross_round_cachable = FALSE +/** + * Stub that allows us to react to something trying to get us. + * Not useful here, more handy for sprite sheets. + */ +/datum/asset/proc/ensure_ready() + return src + +/// Stub to hook into if your asset is having its generation queued by SSasset_loading +/datum/asset/proc/queued_generation() + CRASH("[type] inserted into SSasset_loading despite not implementing /proc/queued_generation") + + /datum/asset/New() GLOB.asset_datums[type] = src register() @@ -51,12 +73,16 @@ GLOBAL_LIST_EMPTY(asset_datums) /// If you don't need anything complicated. /datum/asset/simple _abstract = /datum/asset/simple - /// list of assets for this datum in the form of: - /// asset_filename = asset_file. At runtime the asset_file will be - /// converted into a asset_cache datum. + /** + * List of assets for this datum in the form of: + * * asset_filename = asset_file. + * At runtime the asset_file will be converted into a asset_cache datum. + */ var/assets = list() - /// Set to true to have this asset also be sent via the legacy browse_rsc - /// system when cdn transports are enabled? + /** + * Set to true to have this asset also be sent via the legacy browse_rsc + * system when cdn transports are enabled? + */ var/legacy = FALSE /// TRUE for keeping local asset names when browse_rsc backend is used var/keep_local_name = FALSE @@ -88,7 +114,7 @@ GLOBAL_LIST_EMPTY(asset_datums) /datum/asset/group/register() for(var/type in children) - get_asset_datum(type) + load_asset_datum(type) /datum/asset/group/send(client/C) for(var/type in children) @@ -101,28 +127,44 @@ GLOBAL_LIST_EMPTY(asset_datums) var/datum/asset/A = get_asset_datum(type) . += A.get_url_mappings() -// spritesheet implementation - coalesces various icons into a single .png file -// and uses CSS to select icons out of that file - saves on transferring some -// 1400-odd individual PNG files +/** + * spritesheet implementation - coalesces various icons into a single .png file + * and uses CSS to select icons out of that file - saves on transferring some + * 1400-odd individual PNG files + */ #define SPR_SIZE 1 -#define SPR_IDX 2 -#define SPRSZ_COUNT 1 -#define SPRSZ_ICON 2 +#define SPR_IDX 2 + +#define SPRSZ_COUNT 1 +#define SPRSZ_ICON 2 #define SPRSZ_STRIPPED 3 /datum/asset/spritesheet _abstract = /datum/asset/spritesheet var/name - var/list/sizes = list() // "32x32" -> list(10, icon/normal, icon/stripped) - var/list/sprites = list() // "foo_bar" -> list("32x32", 5) + /** + * List of arguments to pass into queuedInsert. + * Exists so we can queue icon insertion, mostly for stuff like preferences. + */ + var/list/to_generate = list() + /// "32x32" -> list(10, icon/normal, icon/stripped) + var/list/sizes = list() + /// "foo_bar" -> list("32x32", 5) + var/list/sprites = list() var/list/cached_spritesheets_needed var/generating_cache = FALSE + var/fully_generated = FALSE + /** + * If this asset should be fully loaded on new + * Defaults to false so we can process this stuff nicely + */ + var/load_immediately = FALSE /datum/asset/spritesheet/should_refresh() if (..()) return TRUE - // Static so that the result is the same, even when the files are created, for this run + /// Static so that the result is the same, even when the files are created, for this run. var/static/should_refresh = null if (isnull(should_refresh)) @@ -140,7 +182,25 @@ GLOBAL_LIST_EMPTY(asset_datums) if (!should_refresh() && read_from_cache()) return + /// If it's cached, may as well load it now, while the loading is cheap + if(CONFIG_GET(flag/cache_assets) && cross_round_cachable) + load_immediately = TRUE + create_spritesheets() + if(load_immediately) + realize_spritesheets(yield = FALSE) + else + SSasset_loading.generate_queue += src + +/datum/asset/spritesheet/proc/realize_spritesheets(yield) + if(fully_generated) + return + while(length(to_generate)) + var/list/stored_args = to_generate[to_generate.len] + to_generate.len-- + queuedInsert(arglist(stored_args)) + if(yield && TICK_CHECK) + return ensure_stripped() for(var/size_id in sizes) @@ -156,6 +216,18 @@ GLOBAL_LIST_EMPTY(asset_datums) if (CONFIG_GET(flag/cache_assets) && cross_round_cachable) write_to_cache() + fully_generated = TRUE + // If we were ever in there, remove ourselves + SSasset_loading.generate_queue -= src + +/datum/asset/spritesheet/queued_generation() + realize_spritesheets(yield = TRUE) + +/datum/asset/spritesheet/ensure_ready() + if(!fully_generated) + realize_spritesheets(yield = FALSE) + return ..() + /datum/asset/spritesheet/send(client/client) if (!name) return @@ -270,17 +342,31 @@ GLOBAL_LIST_EMPTY(asset_datums) return mappings -/// Override this in order to start the creation of the spritehseet. -/// This is where all your Insert, InsertAll, etc calls should be inside. +/** + *! Override this in order to start the creation of the spritehseet. + *! This is where all your Insert, InsertAll, etc calls should be inside. + */ /datum/asset/spritesheet/proc/create_spritesheets() SHOULD_CALL_PARENT(FALSE) CRASH("create_spritesheets() not implemented for [type]!") /datum/asset/spritesheet/proc/Insert(sprite_name, icon/I, icon_state="", dir=SOUTH, frame=1, moving=FALSE) + if(load_immediately) + queuedInsert(sprite_name, I, icon_state, dir, frame, moving) + else + to_generate += list(args.Copy()) + +/** + * LEMON NOTE + * A GOON CODER SAYS BAD ICON ERRORS CAN BE THROWN BY THE "ICON CACHE" + * APPARENTLY IT MAKES ICONS IMMUTABLE + * LOOK INTO USING THE MUTABLE APPEARANCE PATTERN HERE + */ +/datum/asset/spritesheet/proc/queuedInsert(sprite_name, icon/I, icon_state="", dir=SOUTH, frame=1, moving=FALSE) I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving) - if (!I || !length(icon_states(I))) // that direction or state doesn't exist + if (!I || !length(icon_states(I))) // That direction or state doesn't exist! return - //any sprite modifications we want to do (aka, coloring a greyscaled asset) + // Any sprite modifications we want to do (aka, coloring a greyscaled asset) I = ModifyInserted(I) var/size_id = "[I.Width()]x[I.Height()]" var/size = sizes[size_id] @@ -291,8 +377,10 @@ GLOBAL_LIST_EMPTY(asset_datums) if (size) var/position = size[SPRSZ_COUNT]++ var/icon/sheet = size[SPRSZ_ICON] + var/icon/sheet_copy = icon(sheet) size[SPRSZ_STRIPPED] = null - sheet.Insert(I, icon_state=sprite_name) + sheet_copy.Insert(I, icon_state=sprite_name) + size[SPRSZ_ICON] = sheet_copy sprites[sprite_name] = list(size_id, position) else sizes[size_id] = size = list(1, I, null) diff --git a/code/modules/asset_cache/assets/chemistry/bottles.dm b/code/modules/asset_cache/assets/chemistry/bottles.dm new file mode 100644 index 00000000000..f875dbf8e58 --- /dev/null +++ b/code/modules/asset_cache/assets/chemistry/bottles.dm @@ -0,0 +1,8 @@ +/datum/asset/spritesheet/simple/bottles + name = "bottles" + assets = list( + "bottle1" = 'icons/runtime/assets/medical/bottles/bottle1.png', + "bottle2" = 'icons/runtime/assets/medical/bottles/bottle2.png', + "bottle3" = 'icons/runtime/assets/medical/bottles/bottle3.png', + "bottle4" = 'icons/runtime/assets/medical/bottles/bottle4.png', + ) diff --git a/code/modules/asset_cache/assets/chemistry/patches.dm b/code/modules/asset_cache/assets/chemistry/patches.dm new file mode 100644 index 00000000000..4483167c263 --- /dev/null +++ b/code/modules/asset_cache/assets/chemistry/patches.dm @@ -0,0 +1,8 @@ +/datum/asset/spritesheet/simple/patches + name = "patches" + assets = list( + "patch" = 'icons/runtime/assets/medical/patches/patch.png', + "patch_brute" = 'icons/runtime/assets/medical/patches/patch_brute.png', + "patch_burn" = 'icons/runtime/assets/medical/patches/patch_burn.png', + "patch_both" = 'icons/runtime/assets/medical/patches/patch_both.png', + ) diff --git a/code/modules/asset_cache/assets/chemistry/pills.dm b/code/modules/asset_cache/assets/chemistry/pills.dm new file mode 100644 index 00000000000..9c852b6e31b --- /dev/null +++ b/code/modules/asset_cache/assets/chemistry/pills.dm @@ -0,0 +1,26 @@ +/datum/asset/spritesheet/simple/pills + name = "pills" + assets = list( + "pill1" = 'icons/runtime/assets/medical/pills/pill1.png', + "pill2" = 'icons/runtime/assets/medical/pills/pill2.png', + "pill3" = 'icons/runtime/assets/medical/pills/pill3.png', + "pill4" = 'icons/runtime/assets/medical/pills/pill4.png', + "pill5" = 'icons/runtime/assets/medical/pills/pill5.png', + "pill6" = 'icons/runtime/assets/medical/pills/pill6.png', + "pill7" = 'icons/runtime/assets/medical/pills/pill7.png', + "pill8" = 'icons/runtime/assets/medical/pills/pill8.png', + "pill9" = 'icons/runtime/assets/medical/pills/pill9.png', + "pill10" = 'icons/runtime/assets/medical/pills/pill10.png', + "pill11" = 'icons/runtime/assets/medical/pills/pill11.png', + "pill12" = 'icons/runtime/assets/medical/pills/pill12.png', + "pill13" = 'icons/runtime/assets/medical/pills/pill13.png', + "pill14" = 'icons/runtime/assets/medical/pills/pill14.png', + "pill15" = 'icons/runtime/assets/medical/pills/pill15.png', + "pill16" = 'icons/runtime/assets/medical/pills/pill16.png', + "pill17" = 'icons/runtime/assets/medical/pills/pill17.png', + "pill18" = 'icons/runtime/assets/medical/pills/pill18.png', + "pill19" = 'icons/runtime/assets/medical/pills/pill19.png', + "pill20" = 'icons/runtime/assets/medical/pills/pill20.png', + "pill21" = 'icons/runtime/assets/medical/pills/pill21.png', + "pill22" = 'icons/runtime/assets/medical/pills/pill22.png', + ) diff --git a/code/modules/asset_cache/assets/condiments.dm b/code/modules/asset_cache/assets/condiments.dm index d72716f778c..58a9f2e6072 100644 --- a/code/modules/asset_cache/assets/condiments.dm +++ b/code/modules/asset_cache/assets/condiments.dm @@ -1,20 +1,20 @@ /datum/asset/spritesheet/simple/condiments name = "condiments" assets = list( - CONDIMASTER_STYLE_FALLBACK = 'icons/ui_icons/condiments/emptycondiment.png', - "enzyme" = 'icons/ui_icons/condiments/enzyme.png', - "flour" = 'icons/ui_icons/condiments/flour.png', - "mayonnaise" = 'icons/ui_icons/condiments/mayonnaise.png', - "milk" = 'icons/ui_icons/condiments/milk.png', - "blackpepper" = 'icons/ui_icons/condiments/peppermillsmall.png', - "rice" = 'icons/ui_icons/condiments/rice.png', - "sodiumchloride" = 'icons/ui_icons/condiments/saltshakersmall.png', - "soymilk" = 'icons/ui_icons/condiments/soymilk.png', - "soysauce" = 'icons/ui_icons/condiments/soysauce.png', - "sugar" = 'icons/ui_icons/condiments/sugar.png', - "ketchup" = 'icons/ui_icons/condiments/ketchup.png', - "capsaicin" = 'icons/ui_icons/condiments/hotsauce.png', - "frostoil" = 'icons/ui_icons/condiments/coldsauce.png', - "bbqsauce" = 'icons/ui_icons/condiments/bbqsauce.png', - "cornoil" = 'icons/ui_icons/condiments/oliveoil.png', + CONDIMASTER_STYLE_FALLBACK = 'icons/runtime/assets/condiments/emptycondiment.png', + "enzyme" = 'icons/runtime/assets/condiments/enzyme.png', + "flour" = 'icons/runtime/assets/condiments/flour.png', + "mayonnaise" = 'icons/runtime/assets/condiments/mayonnaise.png', + "milk" = 'icons/runtime/assets/condiments/milk.png', + "blackpepper" = 'icons/runtime/assets/condiments/peppermillsmall.png', + "rice" = 'icons/runtime/assets/condiments/rice.png', + "sodiumchloride" = 'icons/runtime/assets/condiments/saltshakersmall.png', + "soymilk" = 'icons/runtime/assets/condiments/soymilk.png', + "soysauce" = 'icons/runtime/assets/condiments/soysauce.png', + "sugar" = 'icons/runtime/assets/condiments/sugar.png', + "ketchup" = 'icons/runtime/assets/condiments/ketchup.png', + "capsaicin" = 'icons/runtime/assets/condiments/hotsauce.png', + "frostoil" = 'icons/runtime/assets/condiments/coldsauce.png', + "bbqsauce" = 'icons/runtime/assets/condiments/bbqsauce.png', + "cornoil" = 'icons/runtime/assets/condiments/oliveoil.png', ) diff --git a/code/modules/asset_cache/assets/patches.dm b/code/modules/asset_cache/assets/patches.dm deleted file mode 100644 index 2c5bf7e252a..00000000000 --- a/code/modules/asset_cache/assets/patches.dm +++ /dev/null @@ -1,8 +0,0 @@ -/datum/asset/spritesheet/simple/patches - name = "patches" - assets = list( - "bandaid" = 'icons/ui_icons/patches/bandaid.png', - "bandaid_brute" = 'icons/ui_icons/patches/bandaid_brute.png', - "bandaid_burn" = 'icons/ui_icons/patches/bandaid_burn.png', - "bandaid_both" = 'icons/ui_icons/patches/bandaid_both.png' - ) diff --git a/code/modules/asset_cache/assets/pills.dm b/code/modules/asset_cache/assets/pills.dm deleted file mode 100644 index 98a4b62de53..00000000000 --- a/code/modules/asset_cache/assets/pills.dm +++ /dev/null @@ -1,40 +0,0 @@ -/datum/asset/simple/namespaced/chem_master - keep_local_name = TRUE - -/datum/asset/simple/namespaced/chem_master/register() - for(var/i = 1 to 24) - assets["pill[i].png"] = icon('icons/obj/chemical.dmi', "pill[i]") - - for(var/i = 1 to 4) - assets["bottle-[i].png"] = icon('icons/obj/chemical.dmi', "bottle-[i]") - - return ..() - -/* -/datum/asset/spritesheet/simple/pills - name = "pills" - assets = list( - "pill1" = 'icons/ui_icons/pills/pill1.png', - "pill2" = 'icons/ui_icons/pills/pill2.png', - "pill3" = 'icons/ui_icons/pills/pill3.png', - "pill4" = 'icons/ui_icons/pills/pill4.png', - "pill5" = 'icons/ui_icons/pills/pill5.png', - "pill6" = 'icons/ui_icons/pills/pill6.png', - "pill7" = 'icons/ui_icons/pills/pill7.png', - "pill8" = 'icons/ui_icons/pills/pill8.png', - "pill9" = 'icons/ui_icons/pills/pill9.png', - "pill10" = 'icons/ui_icons/pills/pill10.png', - "pill11" = 'icons/ui_icons/pills/pill11.png', - "pill12" = 'icons/ui_icons/pills/pill12.png', - "pill13" = 'icons/ui_icons/pills/pill13.png', - "pill14" = 'icons/ui_icons/pills/pill14.png', - "pill15" = 'icons/ui_icons/pills/pill15.png', - "pill16" = 'icons/ui_icons/pills/pill16.png', - "pill17" = 'icons/ui_icons/pills/pill17.png', - "pill18" = 'icons/ui_icons/pills/pill18.png', - "pill19" = 'icons/ui_icons/pills/pill19.png', - "pill20" = 'icons/ui_icons/pills/pill20.png', - "pill21" = 'icons/ui_icons/pills/pill21.png', - "pill22" = 'icons/ui_icons/pills/pill22.png', - ) -*/ diff --git a/code/modules/atmospherics/machinery/components/unary/cold_sink.dm b/code/modules/atmospherics/machinery/components/unary/cold_sink.dm index 75ee4af1dee..7337e94a39a 100644 --- a/code/modules/atmospherics/machinery/components/unary/cold_sink.dm +++ b/code/modules/atmospherics/machinery/components/unary/cold_sink.dm @@ -2,7 +2,7 @@ /obj/machinery/atmospherics/component/unary/freezer name = "gas cooling system" desc = "Cools gas when connected to pipe network" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "freezer_0" density = 1 anchored = 1 diff --git a/code/modules/atmospherics/machinery/components/unary/heat_source.dm b/code/modules/atmospherics/machinery/components/unary/heat_source.dm index d10462bd12d..ebcb7c9c12f 100644 --- a/code/modules/atmospherics/machinery/components/unary/heat_source.dm +++ b/code/modules/atmospherics/machinery/components/unary/heat_source.dm @@ -2,7 +2,7 @@ /obj/machinery/atmospherics/component/unary/heater name = "gas heating system" desc = "Heats gas when connected to a pipe network" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/medical/cryogenic2.dmi' icon_state = "heater_0" density = TRUE anchored = TRUE diff --git a/code/modules/food/food/drinks/drinkingglass.dm b/code/modules/food/food/drinks/drinkingglass.dm index 3f69342da38..e088eebcb26 100644 --- a/code/modules/food/food/drinks/drinkingglass.dm +++ b/code/modules/food/food/drinks/drinkingglass.dm @@ -119,7 +119,7 @@ overlays.Cut() if(reagents.total_volume) - var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]1") + var/image/filling = image('icons/obj/medical/reagentfillings.dmi', src, "[icon_state]1") switch(reagents.total_volume) if(0 to 3) filling.icon_state = "[icon_state]1" @@ -147,7 +147,7 @@ overlays.Cut() if(reagents.total_volume) - var/image/filling = image('icons/obj/reagentfillings.dmi', src, "fitness-cup10") + var/image/filling = image('icons/obj/medical/reagentfillings.dmi', src, "fitness-cup10") switch(reagents.total_volume) if(0 to 10) filling.icon_state = "fitness-cup10" diff --git a/code/modules/food/glass/bottle.dm b/code/modules/food/glass/bottle.dm index 6b360f436fc..cd74c6cf7df 100644 --- a/code/modules/food/glass/bottle.dm +++ b/code/modules/food/glass/bottle.dm @@ -4,7 +4,7 @@ /obj/item/reagent_containers/glass/bottle name = "bottle" desc = "A small bottle." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = null item_state = "atoxinbottle" amount_per_transfer_from_this = 10 @@ -38,7 +38,7 @@ overlays.Cut() if(reagents.total_volume && (icon_state == "bottle-1" || icon_state == "bottle-2" || icon_state == "bottle-3" || icon_state == "bottle-4")) - var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]10") + var/image/filling = image('icons/obj/medical/reagentfillings.dmi', src, "[icon_state]10") var/percent = round((reagents.total_volume / volume) * 100) switch(percent) @@ -60,91 +60,91 @@ /obj/item/reagent_containers/glass/bottle/inaprovaline name = "inaprovaline bottle" desc = "A small bottle. Contains inaprovaline - used to stabilize patients." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("inaprovaline" = 60) /obj/item/reagent_containers/glass/bottle/toxin name = "toxin bottle" desc = "A small bottle of toxins. Do not drink, it is poisonous." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-3" prefill = list("toxin" = 60) /obj/item/reagent_containers/glass/bottle/cyanide name = "cyanide bottle" desc = "A small bottle of cyanide. Bitter almonds?" - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-3" prefill = list("cyanide" = 30) //volume changed to match chloral /obj/item/reagent_containers/glass/bottle/stoxin name = "soporific bottle" desc = "A small bottle of soporific. Just the fumes make you sleepy." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-3" prefill = list("stoxin" = 60) /obj/item/reagent_containers/glass/bottle/chloralhydrate name = "chloral hydrate bottle" desc = "A small bottle of Choral Hydrate. Mickey's Favorite!" - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-3" prefill = list("chloralhydrate" = 30) //Intentionally low since it is so strong. Still enough to knock someone out. /obj/item/reagent_containers/glass/bottle/antitoxin name = "dylovene bottle" desc = "A small bottle of dylovene. Counters poisons, and repairs damage. A wonder drug." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("anti_toxin" = 60) /obj/item/reagent_containers/glass/bottle/mutagen name = "unstable mutagen bottle" desc = "A small bottle of unstable mutagen. Randomly changes the DNA structure of whoever comes in contact." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-1" prefill = list("mutagen" = 60) /obj/item/reagent_containers/glass/bottle/ammonia name = "ammonia bottle" desc = "A small bottle." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-1" prefill = list("ammonia" = 60) /obj/item/reagent_containers/glass/bottle/eznutrient name = "\improper EZ NUtrient bottle" desc = "A small bottle." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("eznutrient" = 60) /obj/item/reagent_containers/glass/bottle/left4zed name = "\improper Left-4-Zed bottle" desc = "A small bottle." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("left4zed" = 60) /obj/item/reagent_containers/glass/bottle/robustharvest name = "\improper Robust Harvest" desc = "A small bottle." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("robustharvest" = 60) /obj/item/reagent_containers/glass/bottle/diethylamine name = "diethylamine bottle" desc = "A small bottle." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("diethylamine" = 60) /obj/item/reagent_containers/glass/bottle/pacid name = "polytrinic acid bottle" desc = "A small bottle. Contains a small amount of Polytrinic Acid" - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("pacid" = 60) @@ -158,20 +158,20 @@ /obj/item/reagent_containers/glass/bottle/capsaicin name = "capsaicin bottle" desc = "A small bottle. Contains hot sauce." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("capsaicin" = 60) /obj/item/reagent_containers/glass/bottle/frostoil name = "frost oil bottle" desc = "A small bottle. Contains cold sauce." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("frostoil" = 60) /obj/item/reagent_containers/glass/bottle/biomass name = "biomass bottle" desc = "A bottle of raw biomass! Gross!" - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-3" prefill = list("biomass" = 60) diff --git a/code/modules/food/glass/bottle/robot.dm b/code/modules/food/glass/bottle/robot.dm index f9c7ab33e94..ecd0b67fcbe 100644 --- a/code/modules/food/glass/bottle/robot.dm +++ b/code/modules/food/glass/bottle/robot.dm @@ -10,7 +10,7 @@ /obj/item/reagent_containers/glass/bottle/robot/inaprovaline name = "internal inaprovaline bottle" desc = "A small bottle. Contains inaprovaline - used to stabilize patients." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" reagent = "inaprovaline" prefill = list("inaprovaline" = 60) @@ -19,8 +19,7 @@ /obj/item/reagent_containers/glass/bottle/robot/antitoxin name = "internal anti-toxin bottle" desc = "A small bottle of Anti-toxins. Counters poisons, and repairs damage, a wonder drug." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" reagent = "anti_toxin" prefill = list("anti_toxin" = 60) - diff --git a/code/modules/food/glass/bottle_vr.dm b/code/modules/food/glass/bottle_vr.dm index 840a6049681..408ab71aca5 100644 --- a/code/modules/food/glass/bottle_vr.dm +++ b/code/modules/food/glass/bottle_vr.dm @@ -1,140 +1,140 @@ /obj/item/reagent_containers/glass/bottle/bicaridine name = "bicaridine bottle" desc = "A small bottle. Bicaridine is an analgesic medication and can be used to treat blunt trauma." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("bicaridine" = 60) /obj/item/reagent_containers/glass/bottle/keloderm name = "keloderm bottle" desc = "A small bottle. A fifty-fifty mix of the popular burn medications kelotane and deramline." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("dermaline" = 30, "kelotane" = 30) /obj/item/reagent_containers/glass/bottle/dermaline name = "dermaline bottle" desc = "A small bottle. Dermaline is the next step in burn medication. Works twice as good as kelotane and enables the body to restore even the direst heat-damaged tissue." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("dermaline" = 60) /obj/item/reagent_containers/glass/bottle/carthatoline name = "carthatoline bottle" desc = "A small bottle. Carthatoline is strong evacuant used to treat severe poisoning." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("carthatoline" = 60) /obj/item/reagent_containers/glass/bottle/dexalinp name = "dexalinp bottle" desc = "A small bottle. Dexalin Plus is used in the treatment of oxygen deprivation. It is highly effective." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("dexalinp" = 60) /obj/item/reagent_containers/glass/bottle/tramadol name = "tramadol bottle" desc = "A small bottle. A simple, yet effective painkiller." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("tramadol" = 60) /obj/item/reagent_containers/glass/bottle/oxycodone name = "oxycodone bottle" desc = "A small bottle. An effective and very addictive painkiller." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("oxycodone" = 60) /obj/item/reagent_containers/glass/bottle/alkysine name = "alkysine bottle" desc = "A small bottle. Alkysine is a drug used to lessen the damage to neurological tissue after a catastrophic injury. Can heal brain tissue." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("alkysine" = 60) /obj/item/reagent_containers/glass/bottle/imidazoline name = "imidazoline bottle" desc = "A small bottle. Heals eye damage." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("imidazoline" = 60) /obj/item/reagent_containers/glass/bottle/peridaxon name = "peridaxon bottle" desc = "A small bottle. Used to encourage recovery of internal organs and nervous systems. Medicate cautiously." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("peridaxon" = 60) /obj/item/reagent_containers/glass/bottle/osteodaxon name = "osteodaxon bottle" desc = "A small bottle. An experimental drug used to heal bone fractures." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("osteodaxon" = 60) /obj/item/reagent_containers/glass/bottle/myelamine name = "myelamine bottle" desc = "A small bottle. Used to rapidly clot internal hemorrhages by increasing the effectiveness of platelets." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("myelamine" = 60) /obj/item/reagent_containers/glass/bottle/hyronalin name = "hyronalin bottle" desc = "A small bottle. Hyronalin is a medicinal drug used to counter the effect of radiation poisoning." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("hyronalin" = 60) /obj/item/reagent_containers/glass/bottle/arithrazine name = "arithrazine bottle" desc = "A small bottle. Arithrazine is an unstable medication used for the most extreme cases of radiation poisoning." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("arithrazine" = 60) /obj/item/reagent_containers/glass/bottle/spaceacillin name = "spaceacillin bottle" desc = "A small bottle. An all-purpose antiviral agent." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("spaceacillin" = 60) /obj/item/reagent_containers/glass/bottle/corophizine name = "corophizine bottle" desc = "A small bottle. A wide-spectrum antibiotic drug. Powerful and uncomfortable in equal doses." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("corophizine" = 60) /obj/item/reagent_containers/glass/bottle/rezadone name = "rezadone bottle" desc = "A small bottle. A powder with almost magical properties, this substance can effectively treat genetic damage in humanoids, though excessive consumption has side effects." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("rezadone" = 60) /obj/item/reagent_containers/glass/bottle/healing_nanites name = "healing nanites bottle" desc = "A small bottle. Miniature medical robots that swiftly restore bodily damage." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("healing_nanites" = 60) /obj/item/reagent_containers/glass/bottle/ickypak name = "ickypak bottle" desc = "A small bottle of ickypak. The smell alone makes you gag." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-3" prefill = list("ickypak" = 60) /obj/item/reagent_containers/glass/bottle/unsorbitol name = "unsorbitol bottle" desc = "A small bottle of unsorbitol. Sickeningly sweet." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-3" prefill = list("unsorbitol" = 60) diff --git a/code/modules/hydroponics/trays/tray_reagents.dm b/code/modules/hydroponics/trays/tray_reagents.dm index 67201900680..851842f309f 100644 --- a/code/modules/hydroponics/trays/tray_reagents.dm +++ b/code/modules/hydroponics/trays/tray_reagents.dm @@ -26,7 +26,7 @@ /obj/item/plantspray/pests/old name = "bottle of pestkiller" - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle16" /obj/item/plantspray/pests/old/carbaryl @@ -53,28 +53,28 @@ /obj/item/weedkiller name = "bottle of weedkiller" - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle16" var/toxicity = 0 var/weed_kill_str = 0 /obj/item/weedkiller/triclopyr name = "bottle of glyphosate" - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle16" toxicity = 4 weed_kill_str = 2 /obj/item/weedkiller/lindane name = "bottle of triclopyr" - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle18" toxicity = 6 weed_kill_str = 4 /obj/item/weedkiller/D24 name = "bottle of 2,4-D" - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle15" toxicity = 8 weed_kill_str = 7 diff --git a/code/modules/lighting/lighting_corner.dm b/code/modules/lighting/lighting_corner.dm index 7932f5c183e..61f73afbb15 100644 --- a/code/modules/lighting/lighting_corner.dm +++ b/code/modules/lighting/lighting_corner.dm @@ -1,14 +1,18 @@ -// Because we can control each corner of every lighting object. -// And corners get shared between multiple turfs (unless you're on the corners of the map, then 1 corner doesn't). -// For the record: these should never ever ever be deleted, even if the turf doesn't have dynamic lighting. - +/** + * Because we can control each corner of every lighting object. + * And corners get shared between multiple turfs (unless you're on the corners of the map, then 1 corner doesn't). + * For the record: these should never ever ever be deleted, even if the turf doesn't have dynamic lighting. + */ /datum/lighting_corner var/turf/northeast var/turf/northwest var/turf/southeast var/turf/southwest - var/list/datum/light_source/affecting // Light sources affecting us. - var/active = FALSE // TRUE if one of our masters has dynamic lighting. + + /// Light sources affecting us. + var/list/datum/light_source/affecting + /// TRUE if one of our masters has dynamic lighting. + var/active = FALSE var/x = 0 var/y = 0 @@ -72,10 +76,15 @@ active = TRUE // 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) +/datum/lighting_corner/proc/update_lumcount(delta_r, delta_g, delta_b) - if ((abs(delta_r)+abs(delta_g)+abs(delta_b)) == 0) +#ifdef VISUALIZE_LIGHT_UPDATES + if (!GLOB.allow_duped_values && !(delta_r || delta_g || delta_b)) // 0 is falsey ok return +#else + if (!(delta_r || delta_g || delta_b)) // 0 is falsey ok + return +#endif lum_r += delta_r lum_g += delta_g @@ -86,7 +95,7 @@ GLOB.lighting_update_corners += src /datum/lighting_corner/proc/update_objects() - // Cache these values a head of time so 4 individual lighting objects don't all calculate them individually. + // Cache these values ahead of time so 4 individual lighting objects don't all calculate them individually. var/lum_r = src.lum_r var/lum_g = src.lum_g var/lum_b = src.lum_b @@ -95,6 +104,10 @@ if (mx > 1) . = 1 / mx + var/old_r = cache_r + var/old_g = cache_g + var/old_b = cache_b + #if LIGHTING_SOFT_THRESHOLD != 0 else if (mx < LIGHTING_SOFT_THRESHOLD) . = 0 // 0 means soft lighting. @@ -109,6 +122,14 @@ #endif cache_mx = round(mx, LIGHTING_ROUND_VALUE) +#ifdef VISUALIZE_LIGHT_UPDATES + if(!GLOB.allow_duped_corners && old_r == cache_r && old_g == cache_g && old_b == cache_b) + return +#else + if(old_r == cache_r && old_g == cache_g && old_b == cache_b) + return +#endif + #define QUEUE(turf) if(turf?.lighting_object && !turf.lighting_object.needs_update) { turf.lighting_object.needs_update = TRUE; GLOB.lighting_update_objects += turf.lighting_object } QUEUE(northeast) QUEUE(northwest) @@ -120,7 +141,7 @@ return -/datum/lighting_corner/Destroy(var/force) +/datum/lighting_corner/Destroy(force) if (!force) return QDEL_HINT_LETMELIVE diff --git a/code/modules/lighting/lighting_object.dm b/code/modules/lighting/lighting_object.dm index 33e593a46e6..433f722da49 100644 --- a/code/modules/lighting/lighting_object.dm +++ b/code/modules/lighting/lighting_object.dm @@ -1,15 +1,15 @@ /atom/movable/lighting_object - name = "" - anchored = TRUE - flags = ATOM_ABSTRACT + name = "" + anchored = TRUE + flags = ATOM_ABSTRACT - icon = LIGHTING_ICON - icon_state = "transparent" - color = null //we manually set color in init instead - plane = LIGHTING_PLANE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - layer = LIGHTING_LAYER - invisibility = INVISIBILITY_LIGHTING + icon = LIGHTING_ICON + icon_state = "transparent" + color = null //we manually set color in init instead + plane = LIGHTING_PLANE + layer = LIGHTING_LAYER + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + invisibility = INVISIBILITY_LIGHTING var/needs_update = FALSE var/turf/myturf @@ -33,9 +33,9 @@ needs_update = TRUE GLOB.lighting_update_objects += src -/atom/movable/lighting_object/Destroy(var/force) +/atom/movable/lighting_object/Destroy(force) if (force) - GLOB.lighting_update_objects -= src + GLOB.lighting_update_objects -= src if (loc != myturf) var/turf/oldturf = get_turf(myturf) var/turf/newturf = get_turf(loc) @@ -71,10 +71,16 @@ // See LIGHTING_CORNER_DIAGONAL in lighting_corner.dm for why these values are what they are. var/static/datum/lighting_corner/dummy/dummy_lighting_corner = new - var/datum/lighting_corner/cr = myturf.lc_bottomleft || dummy_lighting_corner +#ifdef VISUALIZE_LIGHT_UPDATES + myturf.add_atom_colour(LIGHT_COLOR_LIGHT_CYAN, ADMIN_COLOUR_PRIORITY) + animate(myturf, 10, color = null) + addtimer(CALLBACK(myturf, /atom/proc/remove_atom_colour, ADMIN_COLOUR_PRIORITY, LIGHT_COLOR_LIGHT_CYAN), 10, TIMER_UNIQUE|TIMER_OVERRIDE) +#endif + + var/datum/lighting_corner/cr = myturf.lc_bottomleft || dummy_lighting_corner var/datum/lighting_corner/cg = myturf.lc_bottomright || dummy_lighting_corner - var/datum/lighting_corner/cb = myturf.lc_topleft || dummy_lighting_corner - var/datum/lighting_corner/ca = myturf.lc_topright || dummy_lighting_corner + var/datum/lighting_corner/cb = myturf.lc_topleft || dummy_lighting_corner + var/datum/lighting_corner/ca = myturf.lc_topright || dummy_lighting_corner var/max = max(cr.cache_mx, cg.cache_mx, cb.cache_mx, ca.cache_mx) diff --git a/code/modules/mob/_modifiers/traits_phobias.dm b/code/modules/mob/_modifiers/traits_phobias.dm index b50bb21aa5a..cc253e0743e 100644 --- a/code/modules/mob/_modifiers/traits_phobias.dm +++ b/code/modules/mob/_modifiers/traits_phobias.dm @@ -496,7 +496,7 @@ if(istype(thing, /obj/machinery/iv_drip)) var/obj/machinery/iv_drip/I = thing - if(I.beaker) + if(I.reagent_container) fear_amount += 8 else fear_amount += 6 @@ -670,4 +670,3 @@ "WetSkrell was a mistake." ) return pick(generic_responses) - diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 9ccb214e33d..00fe1d2d59e 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -850,3 +850,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/datum/perspective/P = ..() P.SetSight(SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF) P.SetSeeInvis(SEE_INVISIBLE_OBSERVER) + +/mob/dead/observer/canUseTopic(atom/movable/M, be_close=FALSE, no_dexterity=FALSE, no_tk=FALSE) + return isAdminGhostAI(usr) diff --git a/code/modules/mob/inventory/slot_meta.dm b/code/modules/mob/inventory/slot_meta.dm index b34f0525518..e47c08fdd36 100644 --- a/code/modules/mob/inventory/slot_meta.dm +++ b/code/modules/mob/inventory/slot_meta.dm @@ -741,6 +741,7 @@ GLOBAL_LIST_EMPTY(inventory_slot_type_cache) INHAND_DEFAULT_ICON_GUNS = 'icons/mob/items/lefthand_guns.dmi', INHAND_DEFAULT_ICON_HATS = 'icons/mob/items/lefthand_hats.dmi', INHAND_DEFAULT_ICON_HOLDERS = 'icons/mob/items/lefthand_holder.dmi', + INHAND_DEFAULT_ICON_KITCHEN = 'icons/mob/items/lefthand_kitchen.dmi', INHAND_DEFAULT_ICON_MAGIC = 'icons/mob/items/lefthand_magic.dmi', INHAND_DEFAULT_ICON_MASKS = 'icons/mob/items/lefthand_masks.dmi', INHAND_DEFAULT_ICON_MATERIAL = 'icons/mob/items/lefthand_material.dmi', @@ -768,6 +769,7 @@ GLOBAL_LIST_EMPTY(inventory_slot_type_cache) INHAND_DEFAULT_ICON_GUNS = 'icons/mob/items/righthand_guns.dmi', INHAND_DEFAULT_ICON_HATS = 'icons/mob/items/righthand_hats.dmi', INHAND_DEFAULT_ICON_HOLDERS = 'icons/mob/items/righthand_holder.dmi', + INHAND_DEFAULT_ICON_KITCHEN = 'icons/mob/items/righthand_kitchen.dmi', INHAND_DEFAULT_ICON_MAGIC = 'icons/mob/items/righthand_magic.dmi', INHAND_DEFAULT_ICON_MASKS = 'icons/mob/items/righthand_masks.dmi', INHAND_DEFAULT_ICON_MATERIAL = 'icons/mob/items/righthand_material.dmi', diff --git a/code/modules/mob/living/carbon/metroid/items.dm b/code/modules/mob/living/carbon/metroid/items.dm index d6434ced211..71c25fa9a3d 100644 --- a/code/modules/mob/living/carbon/metroid/items.dm +++ b/code/modules/mob/living/carbon/metroid/items.dm @@ -120,7 +120,7 @@ icon_state = "rainbow slime extract" /obj/item/slimepotion - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' ////Pet Slime Creation/// /* @@ -183,7 +183,7 @@ /obj/item/slimepotion2 name = "advanced docility potion" desc = "A potent chemical mix that will nullify a slime's powers, causing it to become docile and tame. This one is meant for adult slimes" - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle19" attack(mob/living/carbon/slime/M as mob, mob/user as mob) @@ -215,7 +215,7 @@ /obj/item/slimesteroid name = "slime steroid" desc = "A potent chemical mix that will cause a slime to generate more extract." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle16" attack(mob/living/carbon/slime/M as mob, mob/user as mob) @@ -239,7 +239,7 @@ /obj/item/slimesteroid2 name = "extract enhancer" desc = "A potent chemical mix that will give a slime extract three uses." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle17" /*afterattack(obj/target, mob/user , flag) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 3906e961b0a..6a9bd7445df 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1098,3 +1098,15 @@ default behaviour is: . = ..() // since we're shifted up by transforms.. . += ((size_multiplier * icon_scale_y) - 1) * 16 + +/mob/living/canUseTopic(atom/movable/M, be_close=FALSE, no_dexterity=FALSE, no_tk=FALSE) + if(incapacitated()) + to_chat(src, SPAN_WARNING("You can't do that right now!")) + return FALSE + if(be_close && !in_range(M, src)) + to_chat(src, SPAN_WARNING("You are too far away!")) + return FALSE + if(!no_dexterity && !IsAdvancedToolUser()) + to_chat(src, SPAN_WARNING("You don't have the dexterity to do this!")) + return FALSE + return TRUE diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 50f91a45456..c13a4654555 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -916,3 +916,9 @@ var/list/ai_verbs_default = list( #undef AI_CHECK_WIRELESS #undef AI_CHECK_RADIO + +/mob/living/silicon/ai/canUseTopic(atom/movable/M, be_close=FALSE, no_dexterity=FALSE, no_tk=FALSE) + if(control_disabled) + to_chat(src, SPAN_WARNING("You can't do that right now!")) + return FALSE + return can_see(M) && ..() //stop AIs from leaving windows open and using then after they lose vision diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index c973aaca37b..b911dc9a4c2 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -493,3 +493,8 @@ visible_message("[src] fades away from the screen, the pAI device goes silent.") card.removePersonality() clear_client() + +// See software.dm for Topic() +/mob/living/silicon/pai/canUseTopic(atom/movable/movable, be_close = FALSE, no_dexterity = FALSE, no_tk = FALSE) + // Resting is just an aesthetic feature for them. + return ..(movable, be_close, no_dexterity, no_tk) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 97e7fad1345..edae7160744 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1405,3 +1405,9 @@ to_chat(src,"Your connection with the shell is suddenly interrupted!") undeploy() ..() + +/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close=FALSE, no_dexterity=FALSE, no_tk=FALSE) + if(lockcharge) + to_chat(src, SPAN_WARNING("You can't do that right now!")) + return FALSE + return ..() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index e8f5021f5ce..d071e1c8a65 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1235,3 +1235,16 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) /mob/CanReachIn(atom/movable/mover, atom/target, obj/item/tool, list/cache) return FALSE + +/** + * Whether the mob can use Topic to interact with machines + * + * Args: + * be_close - Whether you need to be next to/on top of M + * no_dexterity - Whether you need to be an ADVANCEDTOOLUSER + * no_tk - If be_close is TRUE, this will block Telekinesis from bypassing the requirement + * need_hands - Whether you need hands to use this + * floor_okay - Whether mobility flags should be checked for MOBILITY_UI to use. + */ +/mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dexterity=FALSE, no_tk=FALSE) + return diff --git a/code/modules/reagents/Chemistry-Readme.dm b/code/modules/reagents/chemistry/_readme.dm similarity index 100% rename from code/modules/reagents/Chemistry-Readme.dm rename to code/modules/reagents/chemistry/_readme.dm diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/chemistry/chemical_reactions.dm similarity index 95% rename from code/modules/reagents/Chemistry-Recipes.dm rename to code/modules/reagents/chemistry/chemical_reactions.dm index e28a49e9200..67aeb047944 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/chemistry/chemical_reactions.dm @@ -1,15 +1,3 @@ -//helper that ensures the reaction rate holds after iterating -//Ex. REACTION_RATE(0.3) means that 30% of the reagents will react each chemistry tick (~2 seconds by default). -#define REACTION_RATE(rate) (1.0 - (1.0-rate)**(1.0/PROCESS_REACTION_ITER)) - -//helper to define reaction rate in terms of half-life -//Ex. -//HALF_LIFE(0) -> Reaction completes immediately (default chems) -//HALF_LIFE(1) -> Half of the reagents react immediately, the rest over the following ticks. -//HALF_LIFE(2) -> Half of the reagents are consumed after 2 chemistry ticks. -//HALF_LIFE(3) -> Half of the reagents are consumed after 3 chemistry ticks. -#define HALF_LIFE(ticks) (ticks? 1.0 - (0.5)**(1.0/(ticks*PROCESS_REACTION_ITER)) : 1.0) - /datum/chemical_reaction var/name = null var/id = null @@ -35,7 +23,7 @@ var/log_is_important = 0 // If this reaction should be considered important for logging. Important recipes message admins when mixed, non-important ones just log to file. -/datum/chemical_reaction/proc/can_happen(var/datum/reagents/holder) +/datum/chemical_reaction/proc/can_happen(datum/reagents/holder) //check that all the required reagents are present if(!holder.has_all_reagents(required_reagents)) return 0 diff --git a/code/modules/reagents/Chemistry-Colours.dm b/code/modules/reagents/chemistry/colors.dm similarity index 66% rename from code/modules/reagents/Chemistry-Colours.dm rename to code/modules/reagents/chemistry/colors.dm index 6b8a96062e9..ace030e3bfe 100644 --- a/code/modules/reagents/Chemistry-Colours.dm +++ b/code/modules/reagents/chemistry/colors.dm @@ -1,3 +1,25 @@ +/proc/mix_color_from_reagents(list/reagent_list) + if(!istype(reagent_list)) + return + + var/mixcolor + var/vol_counter = 0 + var/vol_temp + + for(var/datum/reagent/R in reagent_list) + vol_temp = R.volume + vol_counter += vol_temp + + if(!mixcolor) + mixcolor = R.color + + else if (length(mixcolor) >= length(R.color)) + mixcolor = BlendRGB(mixcolor, R.color, vol_temp/vol_counter) + else + mixcolor = BlendRGB(R.color, mixcolor, vol_temp/vol_counter) + + return mixcolor + /datum/reagents/proc/get_color() if(!reagent_list || !reagent_list.len) return "#ffffffff" diff --git a/code/modules/reagents/Chemistry-Reagents-Helpers.dm b/code/modules/reagents/chemistry/helpers.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents-Helpers.dm rename to code/modules/reagents/chemistry/helpers.dm diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/chemistry/holder.dm similarity index 93% rename from code/modules/reagents/Chemistry-Holder.dm rename to code/modules/reagents/chemistry/holder.dm index 52a4e3fbd7e..d595790528f 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -1,5 +1,3 @@ -///when processing a reaction, iterate this many times -#define PROCESS_REACTION_ITER 5 /datum/reagents var/list/datum/reagent/reagent_list = list() var/total_volume = 0 @@ -293,11 +291,13 @@ /* Holder-to-atom and similar procs */ -//The general proc for applying reagents to things. This proc assumes the reagents are being applied externally, -//not directly injected into the contents. It first calls touch, then the appropriate trans_to_*() or splash_mob(). -//If for some reason touch effects are bypassed (e.g. injecting stuff directly into a reagent container or person), -//call the appropriate trans_to_*() proc. -/datum/reagents/proc/trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0) +/** + * The general proc for applying reagents to things. This proc assumes the reagents are being applied externally, + * not directly injected into the contents. It first calls touch, then the appropriate trans_to_*() or splash_mob(). + * If for some reason touch effects are bypassed (e.g. injecting stuff directly into a reagent container or person), + * call the appropriate trans_to_*() proc. + */ +/datum/reagents/proc/trans_to(atom/target, amount = 1, multiplier = 1, copy = 0) touch(target) //First, handle mere touch effects if(ismob(target)) @@ -417,7 +417,8 @@ R.touch_turf(target, amount) return -/datum/reagents/proc/trans_to_obj(var/obj/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Objects may or may not; if they do, it's probably a beaker or something and we need to transfer properly; otherwise, just touch. +/// Objects may or may not; if they do, it's probably a beaker or something and we need to transfer properly; otherwise, just touch. +/datum/reagents/proc/trans_to_obj(var/obj/target, var/amount = 1, var/multiplier = 1, var/copy = 0) if(!target) return @@ -495,3 +496,18 @@ for(var/datum/reagent/R in cached_reagents) R.on_update (A) update_total() + +// I wrote this while :headempty: and I'm not sure if it's correct. @Zandario +/datum/reagents/proc/can_reactions_happen() + var/do_happen = FALSE + var/list/eligible_reactions = list() + for(var/i in reagent_list) + var/datum/reagent/R = i + if(SSchemistry.chemical_reactions_by_reagent[R.id]) + eligible_reactions |= SSchemistry.chemical_reactions_by_reagent[R.id] + + for(var/i in eligible_reactions) + var/datum/chemical_reaction/C = i + if(C.can_happen(src)) + do_happen = TRUE + return do_happen diff --git a/code/modules/reagents/Chemistry-Logging.dm b/code/modules/reagents/chemistry/logging.dm similarity index 100% rename from code/modules/reagents/Chemistry-Logging.dm rename to code/modules/reagents/chemistry/logging.dm diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/chemistry/machinery.dm similarity index 99% rename from code/modules/reagents/Chemistry-Machinery.dm rename to code/modules/reagents/chemistry/machinery.dm index 6ad96cd81c9..80b57dc0564 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/chemistry/machinery.dm @@ -284,7 +284,7 @@ It may also identify the liquid contents of unknown objects." description_info = "This machine will try to tell you what reagents are inside of something capable of holding reagents. \ It is also used to 'identify' specific reagent-based objects with their properties obscured from inspection by normal means." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "chem_analyzer" density = TRUE anchored = TRUE diff --git a/code/modules/reagents/Chemistry-Metabolism.dm b/code/modules/reagents/chemistry/metabolism.dm similarity index 100% rename from code/modules/reagents/Chemistry-Metabolism.dm rename to code/modules/reagents/chemistry/metabolism.dm diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/chemistry/reagents.dm similarity index 97% rename from code/modules/reagents/Chemistry-Reagents.dm rename to code/modules/reagents/chemistry/reagents.dm index 31cef3e9acf..415bb4cded8 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -1,4 +1,11 @@ +GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) +/proc/build_name2reagent() + . = list() + for (var/t in subtypesof(/datum/reagent)) + var/datum/reagent/R = t + if (length(initial(R.name))) + .[ckey(initial(R.name))] = t /datum/reagent diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/chemistry/reagents/Chemistry-Reagents-Core.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm rename to code/modules/reagents/chemistry/reagents/Chemistry-Reagents-Core.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/chemistry/reagents/Chemistry-Reagents-Dispenser.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm rename to code/modules/reagents/chemistry/reagents/Chemistry-Reagents-Dispenser.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/chemistry/reagents/Chemistry-Reagents-Food-Drinks.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm rename to code/modules/reagents/chemistry/reagents/Chemistry-Reagents-Food-Drinks.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/chemistry/reagents/Chemistry-Reagents-Medicine.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm rename to code/modules/reagents/chemistry/reagents/Chemistry-Reagents-Medicine.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm b/code/modules/reagents/chemistry/reagents/Chemistry-Reagents-Modifiers.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm rename to code/modules/reagents/chemistry/reagents/Chemistry-Reagents-Modifiers.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/chemistry/reagents/Chemistry-Reagents-Other.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm rename to code/modules/reagents/chemistry/reagents/Chemistry-Reagents-Other.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/chemistry/reagents/Chemistry-Reagents-Toxins.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm rename to code/modules/reagents/chemistry/reagents/Chemistry-Reagents-Toxins.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Topical.dm b/code/modules/reagents/chemistry/reagents/Chemistry-Topical.dm similarity index 96% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Topical.dm rename to code/modules/reagents/chemistry/reagents/Chemistry-Topical.dm index 8d3ef21c2b5..3e90cd6694b 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Topical.dm +++ b/code/modules/reagents/chemistry/reagents/Chemistry-Topical.dm @@ -7,7 +7,7 @@ description = "A gel meant to be applied to the skin." taste_description = "Sourness" taste_mult = 2 - + metabolism = REM / 2//The skin is not directly connected to any filter organs so reagents are removed much slower overdose = REAGENTS_OVERDOSE //Usually we want topicals to overdose just as other chems do. @@ -30,10 +30,10 @@ else//or half the reagent passes through into blood(rest is filtered off) and alittle bit affects the inner skin affect_blood(M, alien, removed/2) affect_touch(M, alien, removed/10) - + /datum/reagent/topical/affect_touch(mob/living/carbon/M, alien, removed) M.add_chemical_effect(CE_PAINKILLER, 1)//just so there is something here... - + /datum/reagent/topical/bicarilaze name = "Bicarilaze" id = "bicarilaze" @@ -112,7 +112,7 @@ if(world.time > (data + (60*10))) data = world.time to_chat(M, "You feel like all your nerves are itching.") - + /datum/reagent/topical/neurolaze/affect_blood(mob/living/carbon/M, alien, removed) if(alien != IS_DIONA) M.apply_damage(5 * removed, HALLOSS)//holodeck boxing glove damage @@ -151,7 +151,7 @@ /datum/reagent/topical/cleansalaze/affect_touch(mob/living/carbon/M, alien, removed) if(alien != IS_DIONA) M.radiation = max(M.radiation - 15 * removed, 0)//Half as potent as hyroaline - + /datum/reagent/topical/lotion//Because chemistry should have some recreational uses name = "Lotion" id = "lotion" @@ -182,55 +182,55 @@ /obj/item/reagent_containers/glass/bottle/inaprovalaze name = "Inaprovalaze bottle" desc = "A small bottle of Inaprovalaze. Do NOT drink." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-2" prefill = list("inaprovalaze" = 60) /obj/item/reagent_containers/glass/bottle/bicarilaze name = "Bicarilaze bottle" desc = "A small bottle of Bicarilaze. Do NOT drink." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-2" prefill = list("bicarilaze" = 60) /obj/item/reagent_containers/glass/bottle/kelotalaze name = "Kelotalaze bottle" desc = "A small bottle of Kelotalaze. Do NOT drink." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-2" prefill = list("kelotalaze" = 60) /obj/item/reagent_containers/glass/bottle/tricoralaze name = "Tricoralaze bottle" desc = "A small bottle of Tricoralaze. Do NOT drink." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-2" prefill = list("tricoralaze" = 60) /obj/item/reagent_containers/glass/bottle/neurolaze name = "Neurolaze bottle" desc = "A small bottle of Neurolaze. Do NOT drink." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-2" prefill = list("neurolaze" = 60) /obj/item/reagent_containers/glass/bottle/sterilaze name = "Sterilaze bottle" desc = "A small bottle of Sterilaze. Do NOT drink." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-2" prefill = list("sterilaze" = 60) /obj/item/reagent_containers/glass/bottle/cleansalaze name = "Cleansalaze bottle" desc = "A small bottle of Cleansalaze. Do NOT drink." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-2" prefill = list("cleansalaze" = 60) /obj/item/reagent_containers/glass/bottle/lotion name = "Lotion bottle" desc = "A small bottle of Lotion. Do NOT drink." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-2" prefill = list("lotion" = 60) diff --git a/code/modules/reagents/exposedprocs.dm b/code/modules/reagents/exposedprocs.dm index ffee71dc0e8..28fbe79acca 100644 --- a/code/modules/reagents/exposedprocs.dm +++ b/code/modules/reagents/exposedprocs.dm @@ -12,7 +12,7 @@ if(!src) return reagents.trans_to_obj(D, amount_per_transfer_from_this) - D.set_color() + D.color = mix_color_from_reagents(D.reagents.reagent_list) D.set_up(my_target, spray_size, delay) return @@ -34,7 +34,7 @@ return playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6) reagents.trans_to_obj(D, amount_per_transfer_from_this) - D.set_color() + D.color = mix_color_from_reagents(D.reagents.reagent_list) spray_size ? null : (spray_size = rand(6, 8)) D.set_up(my_target, spray_size, delay) return diff --git a/code/modules/reagents/machinery/chem_master.dm b/code/modules/reagents/machinery/chem_master.dm index 872dd9d00d0..de2684a6fa3 100644 --- a/code/modules/reagents/machinery/chem_master.dm +++ b/code/modules/reagents/machinery/chem_master.dm @@ -1,37 +1,81 @@ +//TODO: We don't have check_reactions or something like it, so we can't prevent idiot transfers. @Zandario /obj/machinery/chem_master name = "ChemMaster 3000" desc = "Used to seperate and package chemicals in to autoinjectors, lollipops, patches, pills, or bottles. Warranty void if used to create Space Drugs." density = TRUE anchored = TRUE - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "mixer0" + base_icon_state = "mixer" circuit = /obj/item/circuitboard/chem_master use_power = USE_POWER_IDLE idle_power_usage = 20 + flags = OPENCONTAINER + clicksound = "button" + + /// Input reagents container. var/obj/item/reagent_containers/beaker = null - var/obj/item/storage/pill_bottle/loaded_pill_bottle = null - var/mode = 0 - var/condi = 0 + /// Pill pill_bottle for newly created pills. + var/obj/item/storage/pill_bottle/pill_bottle = null var/useramount = 15 // Last used amount var/pillamount = 10 var/lolliamount = 5 var/autoamount = 5 - var/list/bottle_styles - var/bottlesprite = 1 - var/pillsprite = 1 - var/lollisprite = 1 - var/autosprite = 1 var/max_pill_count = 20 var/max_lolli_count = 10 var/max_auto_count = 5 var/printing = FALSE - flags = OPENCONTAINER - clicksound = "button" + var/autosprite = TRUE + + /// Current UI screen. On the moment of writing this comment there were two: 'home' - main screen, and 'analyze' - info about specific reagent + var/screen = "home" + /// Info to display on 'analyze' screen + var/analyze_vars[0] + + /// Whether separated reagents should be moved back to container or destroyed. 1 - move, 0 - destroy + var/mode = 1 + /// Decides what UI to show. If TRUE shows UI of CondiMaster, if FALSE - ChemMaster + var/condi = FALSE + + /// Currently selected pill style. + var/chosen_pill_style = 1 + /// List of available pill styles for UI + var/list/pill_styles + + /// Currently selected pill_bottle style. + var/chosen_bottle_style = 1 + /// List of available pill_bottle styles for UI + var/list/bottle_styles + + /// Currently selected patch style. + var/chosen_patch_style = DEFAULT_PATCH_STYLE + /// List of available patch styles for UI + var/list/patch_styles + + /// Currently selected condi style. + var/chosen_condi_style = CONDIMASTER_STYLE_AUTO + /// List of available condi styles for UI + var/list/condi_styles + +/obj/machinery/chem_master/condimaster + name = "CondiMaster 3000" + condi = TRUE /obj/machinery/chem_master/Initialize(mapload, newdir) . = ..() - default_apply_parts() create_reagents(1000) + default_apply_parts() + +/obj/machinery/chem_master/Destroy() + QDEL_NULL(beaker) + QDEL_NULL(pill_bottle) + return ..() + +/obj/machinery/chem_master/RefreshParts() + . = ..() + reagents.maximum_volume = 0 + for(var/obj/item/reagent_containers/glass/beaker/B in component_parts) + reagents.maximum_volume += B.reagents.maximum_volume /obj/machinery/chem_master/legacy_ex_act(severity) switch(severity) @@ -43,41 +87,65 @@ qdel(src) return -/obj/machinery/chem_master/update_icon() - icon_state = "mixer[beaker ? "1" : "0"]" +/obj/machinery/chem_master/update_icon_state() + icon_state = "[base_icon_state][beaker ? 1 : 0][(machine_stat & BROKEN) ? "_b" : (powered() ? null : "_nopower")]" + return ..() -/obj/machinery/chem_master/attackby(var/obj/item/B as obj, var/mob/user as mob) +/obj/machinery/chem_master/update_overlays() + . = ..() + if(machine_stat & BROKEN) + . += "waitlight" - if(istype(B, /obj/item/reagent_containers/glass) || istype(B, /obj/item/reagent_containers/food)) +/obj/machinery/chem_master/blob_act(obj/structure/blob/B) + if (prob(50)) + qdel(src) +/obj/machinery/chem_master/attackby(obj/item/I, mob/user, params) + if(default_unfasten_wrench(user, I, 20)) + return + else if(default_deconstruction_screwdriver(user, I)) + return + + else if(default_deconstruction_crowbar(user, I)) + return + + if(is_reagent_container(I) && !(I.item_flags & ATOM_ABSTRACT) && I.is_open_container()) + . = TRUE // no afterattack + if(panel_open) + to_chat(user, SPAN_WARNING("You can't use the [src.name] while its panel is opened!")) + return if(src.beaker) to_chat(user, "\A [beaker] is already loaded into the machine.") return - if(!user.attempt_insert_item_for_installation(B, src)) - return - src.beaker = B - to_chat(user, "You add \the [B] to the machine.") - update_icon() - - else if(istype(B, /obj/item/storage/pill_bottle)) - - if(src.loaded_pill_bottle) - to_chat(user, "A \the [loaded_pill_bottle] s already loaded into the machine.") - return + var/obj/item/reagent_containers/B = I + . = TRUE // no afterattack if(!user.attempt_insert_item_for_installation(B, src)) return - src.loaded_pill_bottle = B - to_chat(user, "You add \the [loaded_pill_bottle] into the dispenser slot.") + replace_beaker(user, B) + to_chat(user, SPAN_NOTICE("You add [B] to [src].")) + ui_interact(user) + update_appearance() - else if(default_unfasten_wrench(user, B, 20)) - return - if(default_deconstruction_screwdriver(user, B)) - return - if(default_deconstruction_crowbar(user, B)) - return + else if(!condi && istype(I, /obj/item/storage/pill_bottle)) + if(pill_bottle) + to_chat(user, SPAN_WARNING("A pill pill_bottle is already loaded into [src]!")) + return + if(!user.attempt_insert_item_for_installation(I, src)) + return + pill_bottle = I + to_chat(user, SPAN_NOTICE("You add [I] into the dispenser slot.")) + ui_interact(user) + else + return ..() - return +/obj/machinery/chem_master/on_deconstruction() + replace_beaker() + if(pill_bottle) + pill_bottle.forceMove(drop_location()) + adjust_item_drop_location(pill_bottle) + pill_bottle = null + return ..() /obj/machinery/chem_master/attack_hand(mob/user) if(machine_stat & BROKEN) @@ -85,9 +153,62 @@ user.set_machine(src) ui_interact(user) +/** + * Handles process of moving input reagents containers in/from machine + * + * When called checks for previously inserted beaker and gives it to user. + * Then, if new_beaker provided, places it into src.beaker. + * Returns `boolean`. TRUE if user provided (ignoring whether threre was any beaker change) and FALSE if not. + * + * Arguments: + * * user - Mob that initialized replacement, gets previously inserted beaker if there's any + * * new_beaker - New beaker to insert. Optional + */ +/obj/machinery/chem_master/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) + if(!user) + return FALSE + if(beaker) + try_put_in_hand(beaker, user) + beaker = null + if(new_beaker) + beaker = new_beaker + update_appearance() + return TRUE + +/obj/machinery/chem_master/proc/load_styles() + /// Calculate the span tags and ids fo all the available pill icons. + var/datum/asset/spritesheet/simple/pill_assets = get_asset_datum(/datum/asset/spritesheet/simple/pills) + pill_styles = list() + for (var/x in 1 to PILL_STYLE_COUNT) + var/list/pill_style_list = list() + pill_style_list["id"] = x + pill_style_list["className"] = pill_assets.icon_class_name("pill[x]") + pill_styles += list(pill_style_list) + + var/datum/asset/spritesheet/simple/bottle_assets = get_asset_datum(/datum/asset/spritesheet/simple/bottles) + bottle_styles = list() + for (var/x in 1 to BOTTLE_STYLE_COUNT) + var/list/bottle_style_list = list() + bottle_style_list["id"] = x + bottle_style_list["className"] = bottle_assets.icon_class_name("bottle[x]") + bottle_styles += list(bottle_style_list) + + var/datum/asset/spritesheet/simple/patches_assets = get_asset_datum(/datum/asset/spritesheet/simple/patches) + patch_styles = list() + for (var/raw_patch_style in PATCH_STYLE_LIST) + //adding className for use in UI + var/list/patch_style = list() + patch_style["id"] = raw_patch_style + patch_style["className"] = patches_assets.icon_class_name(raw_patch_style) + patch_styles += list(patch_style) + + condi_styles = strip_condi_styles_to_icons(get_condi_styles()) + /obj/machinery/chem_master/ui_assets(mob/user) return list( - get_asset_datum(/datum/asset/simple/namespaced/chem_master), + get_asset_datum(/datum/asset/spritesheet/simple/pills), + get_asset_datum(/datum/asset/spritesheet/simple/bottles), + get_asset_datum(/datum/asset/spritesheet/simple/patches), ) /obj/machinery/chem_master/ui_interact(mob/user, datum/tgui/ui = null) @@ -96,470 +217,306 @@ ui = new(user, src, "ChemMaster", name) ui.open() -/** - * Display the NanoUI window for the chem master. - * - * See NanoUI documentation for details. - */ /obj/machinery/chem_master/ui_data(mob/user) var/list/data = list() - data["condi"] = condi + data["mode"] = mode + data["condi"] = condi + data["screen"] = screen + data["analyzeVars"] = analyze_vars - data["loaded_pill_bottle"] = !!loaded_pill_bottle - if(loaded_pill_bottle) - data["loaded_pill_bottle_name"] = loaded_pill_bottle.name - data["loaded_pill_bottle_contents_len"] = loaded_pill_bottle.contents.len - data["loaded_pill_bottle_storage_slots"] = loaded_pill_bottle.max_storage_space + data["chosen_pill_style"] = chosen_pill_style + data["chosen_bottle_style"] = chosen_bottle_style + data["chosen_patch_style"] = chosen_patch_style + data["chosen_condi_style"] = chosen_condi_style - data["beaker"] = !!beaker + data["auto_condi_style"] = CONDIMASTER_STYLE_AUTO + + data["is_pill_bottle_loaded"] = pill_bottle ? TRUE : FALSE + if(pill_bottle) + data["pill_bottle_current_amount"] = pill_bottle.contents.len + data["pill_bottle_max_amount"] = pill_bottle.max_storage_space + + data["is_beaker_loaded"] = beaker ? TRUE : FALSE + data["beaker_current_volume"] = beaker ? round(beaker.reagents.total_volume, 0.01) : null + data["beaker_max_volume"] = beaker ? beaker.volume : null + + var/beaker_contents[0] if(beaker) - var/list/beaker_reagents_list = list() - data["beaker_reagents"] = beaker_reagents_list for(var/datum/reagent/R in beaker.reagents.reagent_list) - beaker_reagents_list[++beaker_reagents_list.len] = list("name" = R.name, "volume" = R.volume, "description" = R.description, "id" = R.id) + beaker_contents.Add(list(list( //! list in a list because Byond merges the first list... + "name" = R.name, + "volume" = round(R.volume, 0.01), + "description" = R.description, + "id" = R.id, + ))) + data["beaker_contents"] = beaker_contents - var/list/buffer_reagents_list = list() - data["buffer_reagents"] = buffer_reagents_list + var/buffer_contents[0] + if(reagents.total_volume) for(var/datum/reagent/R in reagents.reagent_list) - buffer_reagents_list[++buffer_reagents_list.len] = list("name" = R.name, "volume" = R.volume, "id" = R.id, "description" = R.description) - - data["pillsprite"] = pillsprite - data["bottlesprite"] = bottlesprite - data["lollisprite"] = lollisprite - data["autosprite"] = autosprite - data["mode"] = mode - data["printing"] = printing - - // Transfer modal information if there is one - data["modal"] = ui_modal_data(src) + buffer_contents.Add(list(list( //! ^ + "name" = R.name, + "volume" = round(R.volume, 0.01), + "description" = R.description, + "id" = R.id, + ))) + data["buffer_contents"] = buffer_contents return data -/** - * Called in ui_act() to process modal actions - * - * Arguments: - * * action - The action passed by tgui - * * params - The params passed by tgui - */ -/obj/machinery/chem_master/proc/ui_act_modal(action, params, datum/tgui/ui, datum/ui_state/state) - . = TRUE - var/id = params["id"] // The modal's ID - var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"] - switch(ui_modal_act(src, action, params)) - if(UI_MODAL_OPEN) - switch(id) - if("analyze") - var/idx = text2num(arguments["idx"]) || 0 - var/from_beaker = text2num(arguments["beaker"]) || FALSE - var/reagent_list = from_beaker ? beaker.reagents.reagent_list : reagents.reagent_list - if(idx < 1 || idx > length(reagent_list)) - return +/obj/machinery/chem_master/ui_static_data(mob/user) + var/list/static_data = list() + //Calculated once since it'll never change + if(!pill_styles || !bottle_styles || !chosen_patch_style || !patch_styles) + load_styles() + static_data["pill_styles"] = pill_styles + static_data["bottle_styles"] = bottle_styles + static_data["patch_styles"] = patch_styles + static_data["condi_styles"] = condi_styles - var/datum/reagent/R = reagent_list[idx] - var/list/result = list("idx" = idx, "name" = R.name, "desc" = R.description) - if(!condi && istype(R, /datum/reagent/blood)) - var/datum/reagent/blood/B = R - result["blood_type"] = B.data["blood_type"] - result["blood_dna"] = B.data["blood_DNA"] + return static_data - arguments["analysis"] = result - ui_modal_message(src, id, "", null, arguments) - // if("change_pill_bottle_style") - // if(!loaded_pill_bottle) - // return - // if(!pill_bottle_wrappers) - // pill_bottle_wrappers = list( - // "CLEAR" = "Default", - // COLOR_RED = "Red", - // COLOR_GREEN = "Green", - // COLOR_PALE_BTL_GREEN = "Pale green", - // COLOR_BLUE = "Blue", - // COLOR_CYAN_BLUE = "Light blue", - // COLOR_TEAL = "Teal", - // COLOR_YELLOW = "Yellow", - // COLOR_ORANGE = "Orange", - // COLOR_PINK = "Pink", - // COLOR_MAROON = "Brown" - // ) - // var/current = pill_bottle_wrappers[loaded_pill_bottle.wrapper_color] || "Default" - // ui_modal_choice(src, id, "Please select a pill bottle wrapper:", null, arguments, current, pill_bottle_wrappers) - if("addcustom") - if(!beaker || !beaker.reagents.total_volume) - return - ui_modal_input(src, id, "Please enter the amount to transfer to buffer:", null, arguments, useramount) - if("removecustom") - if(!reagents.total_volume) - return - ui_modal_input(src, id, "Please enter the amount to transfer to [mode ? "beaker" : "disposal"]:", null, arguments, useramount) - if("create_condi_pack") - if(!condi || !reagents.total_volume) - return - ui_modal_input(src, id, "Please name your new condiment pack:", null, arguments, reagents.get_master_reagent_name(), MAX_CUSTOM_NAME_LEN) - if("create_pill") - if(condi || !reagents.total_volume) - return - var/num = round(text2num(arguments["num"] || 1)) - if(!num) - return - arguments["num"] = num - var/amount_per_pill = clamp(reagents.total_volume / num, 0, MAX_UNITS_PER_PILL) - var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_pill]u)" - var/pills_text = num == 1 ? "new pill" : "[num] new pills" - ui_modal_input(src, id, "Please name your [pills_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) - if("create_pill_multiple") - if(condi || !reagents.total_volume) - return - ui_modal_input(src, id, "Please enter the amount of pills to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) - if("change_pill_style") - var/list/choices = list() - for(var/i = 1 to MAX_PILL_SPRITE) - choices += "pill[i].png" - ui_modal_bento(src, id, "Please select the new style for pills:", null, arguments, pillsprite, choices) - if("create_patch") - if(condi || !reagents.total_volume) - return - var/num = round(text2num(arguments["num"] || 1)) - if(!num) - return - arguments["num"] = num - var/amount_per_patch = clamp(reagents.total_volume / num, 0, MAX_UNITS_PER_PATCH) - var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_patch]u)" - var/patches_text = num == 1 ? "new patch" : "[num] new patches" - ui_modal_input(src, id, "Please name your [patches_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) - if("create_patch_multiple") - if(condi || !reagents.total_volume) - return - ui_modal_input(src, id, "Please enter the amount of patches to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) - if("create_lollipop") - if(condi || !reagents.total_volume) - return - var/num = round(text2num(arguments["num"] || 1)) - if(!num) - return - arguments["num"] = num - var/amount_per_lolli = clamp(reagents.total_volume / num, 0, MAX_UNITS_PER_LOLLI) - var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_lolli]u)" - var/lolli_text = num == 1 ? "new lollipop" : "[num] new lollipops" - ui_modal_input(src, id, "Please name your [lolli_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) - if("create_lollipop_multiple") - if(condi || !reagents.total_volume) - return - ui_modal_input(src, id, "Please enter the amount of lollipops to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, lolliamount, 5) - if("create_autoinjector") - if(condi || !reagents.total_volume) - return - var/num = round(text2num(arguments["num"] || 1)) - if(!num) - return - arguments["num"] = num - var/amount_per_auto = clamp(reagents.total_volume / num, 0, MAX_UNITS_PER_AUTO) - var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_auto]u)" - var/auto_text = num == 1 ? "new autoinjector" : "[num] new autoinjectors" - ui_modal_input(src, id, "Please name your [auto_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) - if("create_autoinjector_multiple") - if(condi || !reagents.total_volume) - return - ui_modal_input(src, id, "Please enter the amount of autoinjectors to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, autoamount, 5) - if("create_bottle") - if(condi || !reagents.total_volume) - return - var/num = round(text2num(arguments["num"] || 1)) - if(!num) - return - arguments["num"] = num - var/amount_per_bottle = clamp(reagents.total_volume / num, 0, MAX_UNITS_PER_BOTTLE) - var/default_name = "[reagents.get_master_reagent_name()]" - var/bottles_text = num == 1 ? "new bottle" : "[num] new bottles" - ui_modal_input(src, id, "Please name your [bottles_text] ([amount_per_bottle]u in bottle):", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) - if("create_bottle_multiple") - if(condi || !reagents.total_volume) - return - ui_modal_input(src, id, "Please enter the amount of bottles to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, 2, 5)//two bottles on default - if("change_bottle_style") - var/list/choices = list() - for(var/i = 1 to MAX_BOTTLE_SPRITE) - choices += "bottle-[i].png" - ui_modal_bento(src, id, "Please select the new style for bottles:", null, arguments, bottlesprite, choices) - else - return FALSE - if(UI_MODAL_ANSWER) - var/answer = params["answer"] - switch(id) - // if("change_pill_bottle_style") - // if(!pill_bottle_wrappers || !loaded_pill_bottle) // wat? - // return - // var/color = "CLEAR" - // for(var/col in pill_bottle_wrappers) - // var/col_name = pill_bottle_wrappers[col] - // if(col_name == answer) - // color = col - // break - // if(length(color) && color != "CLEAR") - // loaded_pill_bottle.wrapper_color = color - // loaded_pill_bottle.apply_wrap() - // else - // loaded_pill_bottle.wrapper_color = null - // loaded_pill_bottle.cut_overlays() - if("addcustom") - var/amount = isgoodnumber(text2num(answer)) - if(!amount || !arguments["id"]) - return - ui_act("add", list("id" = arguments["id"], "amount" = amount), ui, state) - if("removecustom") - var/amount = isgoodnumber(text2num(answer)) - if(!amount || !arguments["id"]) - return - ui_act("remove", list("id" = arguments["id"], "amount" = amount), ui, state) - if("create_condi_pack") - if(!condi || !reagents.total_volume) - return - if(!length(answer)) - answer = reagents.get_master_reagent_name() - var/obj/item/reagent_containers/pill/P = new(loc) - P.name = "[answer] pack" - P.desc = "A small condiment pack. The label says it contains [answer]." - P.icon_state = "bouilloncube"//Reskinned monkey cube - reagents.trans_to_obj(P, 10) - if("create_pill") - if(condi || !reagents.total_volume) - return - var/count = clamp(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) - if(!count) - return - - if(!length(answer)) - answer = reagents.get_master_reagent_name() - var/amount_per_pill = clamp(reagents.total_volume / count, 0, MAX_UNITS_PER_PILL) - while(count--) - if(reagents.total_volume <= 0) - to_chat(usr, "Not enough reagents to create these pills!") - return - - var/obj/item/reagent_containers/pill/P = new(loc) - P.name = "[answer] pill" - P.pixel_x = rand(-7, 7) // Random position - P.pixel_y = rand(-7, 7) - P.icon_state = "pill[pillsprite]" - if(P.icon_state in list("pill1", "pill2", "pill3", "pill4")) // if using greyscale, take colour from reagent - P.color = reagents.get_color() - reagents.trans_to_obj(P, amount_per_pill) - // Load the pills in the bottle if there's one loaded - if(istype(loaded_pill_bottle) && length(loaded_pill_bottle.contents) < loaded_pill_bottle.max_storage_space) - P.forceMove(loaded_pill_bottle) - if("create_pill_multiple") - if(condi || !reagents.total_volume) - return - ui_act("modal_open", list("id" = "create_pill", "arguments" = list("num" = answer)), ui, state) - if("change_pill_style") - var/new_style = clamp(text2num(answer) || 0, 0, MAX_PILL_SPRITE) - if(!new_style) - return - pillsprite = new_style - if("create_patch") - if(condi || !reagents.total_volume) - return - var/count = clamp(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) - if(!count) - return - - if(!length(answer)) - answer = reagents.get_master_reagent_name() - var/amount_per_patch = clamp(reagents.total_volume / count, 0, MAX_UNITS_PER_PATCH) - // var/is_medical_patch = chemical_safety_check(reagents) - while(count--) - if(reagents.total_volume <= 0) - to_chat(usr, "Not enough reagents to create these patches!") - return - - var/obj/item/reagent_containers/pill/patch/P = new(loc) - P.name = "[answer] patch" - P.pixel_x = rand(-7, 7) // random position - P.pixel_y = rand(-7, 7) - reagents.trans_to_obj(P, amount_per_patch) - // if(is_medical_patch) - // P.instant_application = TRUE - // P.icon_state = "bandaid_med" - if("create_patch_multiple") - if(condi || !reagents.total_volume) - return - ui_act("modal_open", list("id" = "create_patch", "arguments" = list("num" = answer)), ui, state) - if("create_lollipop") - if(condi || !reagents.total_volume) - return - var/count = clamp(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) - if(!count) - return - - if(!length(answer)) - answer = reagents.get_master_reagent_name() - var/amount_per_lolli = clamp(reagents.total_volume / count, 0, MAX_UNITS_PER_LOLLI) - // var/is_medical_patch = chemical_safety_check(reagents) - while(count--) - if(reagents.total_volume <= 0) - to_chat(usr, "Not enough reagents to create these candies!") - return - - var/obj/item/reagent_containers/hard_candy/lollipop/L = new(loc) - L.name = "[answer] lollipop" - L.pixel_x = rand(-7, 7) // random position - L.pixel_y = rand(-7, 7) - reagents.trans_to_obj(L, amount_per_lolli) - if("create_lollipop_multiple") - if(condi || !reagents.total_volume) - return - ui_act("modal_open", list("id" = "create_lollipop", "arguments" = list("num" = answer)), ui, state) - if("create_autoinjector") - if(condi || !reagents.total_volume) - return - var/count = clamp(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) - if(!count) - return - - if(!length(answer)) - answer = reagents.get_master_reagent_name() - var/amount_per_auto = clamp(reagents.total_volume / count, 0, MAX_UNITS_PER_AUTO) - // var/is_medical_patch = chemical_safety_check(reagents) - while(count--) - if(reagents.total_volume <= 0) - to_chat(usr, "Not enough reagents to create these injectors!") - return - - var/obj/item/reagent_containers/hypospray/autoinjector/empty/A = new(loc) - A.name = "[answer] autoinjector" - A.pixel_x = rand(-7, 7) // random position - A.pixel_y = rand(-7, 7) - reagents.trans_to_obj(A, amount_per_auto) - if("create_autoinjector_multiple") - if(condi || !reagents.total_volume) - return - ui_act("modal_open", list("id" = "create_autoinjector", "arguments" = list("num" = answer)), ui, state) - if("create_bottle") - if(condi || !reagents.total_volume) - return - var/count = clamp(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) - if(!count) - return - - if(!length(answer)) - answer = reagents.get_master_reagent_name() - var/amount_per_bottle = clamp(reagents.total_volume / count, 0, MAX_UNITS_PER_BOTTLE) - while(count--) - if(reagents.total_volume <= 0) - to_chat(usr, "Not enough reagents to create these bottles!") - return - var/obj/item/reagent_containers/glass/bottle/P = new(loc) - P.name = "[answer] bottle" - P.pixel_x = rand(-7, 7) // random position - P.pixel_y = rand(-7, 7) - P.icon_state = "bottle-[bottlesprite]" || "bottle-1" - reagents.trans_to_obj(P, amount_per_bottle) - P.update_icon() - if("create_bottle_multiple") - if(condi || !reagents.total_volume) - return - ui_act("modal_open", list("id" = "create_bottle", "arguments" = list("num" = answer)), ui, state) - if("change_bottle_style") - var/new_style = clamp(text2num(answer) || 0, 0, MAX_BOTTLE_SPRITE) - if(!new_style) - return - bottlesprite = new_style - else - return FALSE - else - return FALSE - -/obj/machinery/chem_master/ui_act(action, params, datum/tgui/ui, datum/ui_state/state) - if(..()) - return TRUE - - if(ui_act_modal(action, params, ui, state)) - return TRUE - - add_fingerprint(usr) - usr.set_machine(src) - - . = TRUE - switch(action) - if("toggle") - mode = !mode - if("ejectp") - if(loaded_pill_bottle) - loaded_pill_bottle.forceMove(get_turf(src)) - if(Adjacent(usr) && !issilicon(usr)) - usr.put_in_hands(loaded_pill_bottle) - loaded_pill_bottle = null - if("print") - if(printing || condi) - return - - var/idx = text2num(params["idx"]) || 0 - var/from_beaker = text2num(params["beaker"]) || FALSE - var/reagent_list = from_beaker ? beaker.reagents.reagent_list : reagents.reagent_list - if(idx < 1 || idx > length(reagent_list)) - return - - var/datum/reagent/R = reagent_list[idx] - - printing = TRUE - visible_message("[src] rattles and prints out a sheet of paper.") - // playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) - - var/obj/item/paper/P = new /obj/item/paper(loc) - P.info = "
Chemical Analysis

" - P.info += "Time of analysis: [worldtime2stationtime(world.time)]

" - P.info += "Chemical name: [R.name]
" - if(istype(R, /datum/reagent/blood)) - var/datum/reagent/blood/B = R - P.info += "Description: N/A
Blood Type: [B.data["blood_type"]]
DNA: [B.data["blood_DNA"]]" - else - P.info += "Description: [R.description]" - P.info += "

Notes:
" - P.name = "Chemical Analysis - [R.name]" - spawn(50) - printing = FALSE - else - . = FALSE - - if(. || !beaker) +/obj/machinery/chem_master/ui_act(action, params) + . = ..() + if(.) return - . = TRUE - var/datum/reagents/R = beaker.reagents switch(action) - if("add") - var/id = params["id"] - var/amount = text2num(params["amount"]) - if(!id || !amount) - return - R.trans_id_to(src, id, amount) - if("remove") - var/id = params["id"] - var/amount = text2num(params["amount"]) - if(!id || !amount) - return - if(mode) - reagents.trans_id_to(beaker, id, amount) - else - reagents.remove_reagent(id, amount) if("eject") - if(!beaker) - return - beaker.forceMove(get_turf(src)) - if(Adjacent(usr) && !issilicon(usr)) - usr.put_in_hands(beaker) - beaker = null - reagents.clear_reagents() - update_icon() - if("create_condi_bottle") - if(!condi || !reagents.total_volume) - return - var/obj/item/reagent_containers/food/condiment/P = new(loc) - reagents.trans_to_obj(P, 50) - else + replace_beaker(usr) + return TRUE + + if("ejectPillBottle") + if(!pill_bottle) + return FALSE + pill_bottle.forceMove(drop_location()) + adjust_item_drop_location(pill_bottle) + pill_bottle = null + return TRUE + + if("transfer") + var/id = params["id"] + var/amount = text2num(params["amount"]) + var/to_container = params["to"] + // Custom amount + if (amount == -1) + amount = text2num(input( + "Enter the amount you want to transfer:", + name, "")) + if (amount == null || amount <= 0) + return FALSE + use_power(active_power_usage) + if (to_container == "beaker" && !mode) + reagents.remove_reagent(id, amount) + return TRUE + if (!beaker) + return FALSE + if (to_container == "buffer") + beaker.reagents.trans_id_to(src, id, amount) + return TRUE + if (to_container == "beaker" && mode) + reagents.trans_id_to(beaker, id, amount) + return TRUE return FALSE + if("toggleMode") + mode = !mode + return TRUE + + if("create") + if(reagents.total_volume == 0) + return FALSE + var/item_type = params["type"] + // Get amount of items + var/amount = text2num(params["amount"]) + if(amount == null) + amount = text2num(input(usr, + "Max 10. Buffer content will be split evenly.", + "How many to make?", 1)) + amount = clamp(round(amount), 0, 10) + if (amount <= 0) + return FALSE + // Get units per item + var/vol_each = text2num(params["volume"]) + var/vol_each_text = params["volume"] + var/vol_each_max = reagents.total_volume / amount + var/list/style + use_power(active_power_usage) + if (item_type == "pill") + vol_each_max = min(60, vol_each_max) + else if (item_type == "patch") + vol_each_max = min(40, vol_each_max) + else if (item_type == "pill_bottle") + vol_each_max = min(30, vol_each_max) + else if (item_type == "bottle") + vol_each_max = min(30, vol_each_max) + else if (item_type == "condiment_pack") + vol_each_max = min(10, vol_each_max) + else if (item_type == "condiment_bottle") + var/list/styles = get_condi_styles() + if (chosen_condi_style == CONDIMASTER_STYLE_AUTO || !(chosen_condi_style in styles)) + style = guess_condi_style(reagents) + else + style = styles[chosen_condi_style] + vol_each_max = min(50, vol_each_max) + else + return FALSE + if(vol_each_text == "auto") + vol_each = vol_each_max + if(vol_each == null) + vol_each = text2num(input(usr, + "Maximum [vol_each_max] units per item.", + "How many units to fill?", + vol_each_max)) + vol_each = round(clamp(vol_each, 0, vol_each_max), 0.01) + if(vol_each <= 0) + return FALSE + // Get item name + var/name = params["name"] + var/name_has_units = item_type == "pill" || item_type == "patch" + if(!name) + var/name_default + if (style && style["name"] && !style["generate_name"]) + name_default = style["name"] + else + name_default = reagents.get_master_reagent_name() + if (name_has_units) + name_default += " ([vol_each]u)" + name = tgui_input_text(usr, + "Give it a name!", + "Name", + name_default, + MAX_NAME_LEN) + if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr))) + return FALSE + + //! Start filling + if(item_type == "pill") + var/obj/item/reagent_containers/pill/P + var/target_loc = drop_location() + var/drop_threshold = INFINITY + if(pill_bottle) + if(pill_bottle.max_storage_space) + drop_threshold = pill_bottle.max_storage_space - pill_bottle.contents.len + target_loc = pill_bottle + for(var/i in 1 to amount) + if(i-1 < drop_threshold) + P = new/obj/item/reagent_containers/pill(target_loc) + else + P = new/obj/item/reagent_containers/pill(drop_location()) + P.name = trim("[name] pill") + if(chosen_pill_style == RANDOM_PILL_STYLE) + P.icon_state ="pill[rand(1,21)]" + else + P.icon_state = "pill[chosen_pill_style]" + if(P.icon_state in PILL_STYLE_RED) + P.desc = "A tablet or capsule, but not just any, a red one, one taken by the ones not scared of knowledge, freedom, uncertainty and the brutal truths of reality." + if(P.icon_state in PILL_STYLE_COLORABLE) // if using greyscale, take colour from reagent + P.color = reagents.get_color() + adjust_item_drop_location(P) + reagents.trans_to_obj(P, vol_each,/* transfered_by = usr*/) + return TRUE + + if(item_type == "patch") + var/obj/item/reagent_containers/pill/patch/P + for(var/i in 1 to amount) + P = new/obj/item/reagent_containers/pill/patch(drop_location()) + P.name = trim("[name] patch") + P.icon_state = chosen_patch_style + adjust_item_drop_location(P) + reagents.trans_to_obj(P, vol_each,/* transfered_by = usr*/) + return TRUE + + if(item_type == "pill_bottle") + var/obj/item/storage/pill_bottle/P + for(var/i in 1 to amount) + P = new/obj/item/storage/pill_bottle(drop_location()) + P.name = trim("[name] pill_bottle") + adjust_item_drop_location(P) + reagents.trans_to_obj(P, vol_each,/* transfered_by = usr*/) + return TRUE + + // if(item_type == "condiment_pack") + // var/obj/item/reagent_containers/condiment/pack/P + // for(var/i in 1 to amount) + // P = new/obj/item/reagent_containers/condiment/pack(drop_location()) + // P.originalname = name + // P.name = trim("[name] pack") + // P.desc = "A small condiment pack. The label says it contains [name]." + // reagents.trans_to_obj(P, vol_each,/* transfered_by = usr*/) + // return TRUE + + if(item_type == "bottle") + var/obj/item/reagent_containers/glass/bottle/P + for(var/i in 1 to amount) + P = new/obj/item/reagent_containers/glass/bottle(drop_location()) + P.name = trim("[name] bottle") + P.icon_state = "bottle[chosen_bottle_style]" + P.renamed_by_player = TRUE + reagents.trans_to_obj(P, vol_each,/* transfered_by = usr*/) + return TRUE + + if(item_type == "condiment_bottle") + var/obj/item/reagent_containers/food/condiment/P + for(var/i in 1 to amount) + P = new/obj/item/reagent_containers/food/condiment(drop_location()) + if (style) + apply_condi_style(P, style) + P.renamed_by_player = TRUE + P.name = name + reagents.trans_to_obj(P, vol_each,/* transfered_by = usr*/) + return TRUE + + return FALSE + + if("analyze") + var/datum/reagent/analyzed_reagent = GLOB.name2reagent[params["id"]] + if(analyzed_reagent) + var/state = "Unknown" + if(initial(analyzed_reagent.reagent_state) == REAGENT_SOLID) + state = "Solid" + else if(initial(analyzed_reagent.reagent_state) == REAGENT_LIQUID) + state = "Liquid" + else if(initial(analyzed_reagent.reagent_state) == REAGENT_GAS) + state = "Gas" + var/metabolization_rate = initial(analyzed_reagent.metabolism)// * (60 / SSMOBS_DT) + analyze_vars = list( + "name" = initial(analyzed_reagent.name), + "state" = state, + "color" = initial(analyzed_reagent.color), + "description" = initial(analyzed_reagent.description), + "metaRate" = metabolization_rate, + "overD" = initial(analyzed_reagent.overdose), + // "pH" = initial(analyzed_reagent.ph), + ) + screen = "analyze" + return TRUE + + if("goScreen") + screen = params["screen"] + return TRUE + + if("change_pill_style") + var/id = text2num(params["id"]) + chosen_pill_style = id + return TRUE + + if("change_bottle_style") + var/id = text2num(params["id"]) + chosen_bottle_style = id + return TRUE + + if("change_condi_style") + chosen_condi_style = params["id"] + return TRUE + + if("change_patch_style") + chosen_patch_style = params["chosen_patch_style"] + return TRUE + + return FALSE + /obj/machinery/chem_master/attack_ai(mob/user) return attack_hand(user) @@ -580,6 +537,258 @@ // all_safe = FALSE // return all_safe -/obj/machinery/chem_master/condimaster - name = "CondiMaster 3000" - condi = 1 +/obj/machinery/chem_master/adjust_item_drop_location(atom/movable/AM) // Special version for chemmasters and condimasters + if (AM == beaker) + AM.pixel_x = AM.base_pixel_x - 8 + AM.pixel_y = AM.base_pixel_y + 8 + return null + else if (AM == pill_bottle) + if (length(pill_bottle.contents)) + AM.pixel_x = AM.base_pixel_x - 13 + else + AM.pixel_x = AM.base_pixel_x - 7 + AM.pixel_y = AM.base_pixel_y - 8 + return null + else if (istype(AM, /obj/item/reagent_containers/pill)) + AM.pixel_x = AM.base_pixel_x + rand(-10, 10) + AM.pixel_y = AM.base_pixel_y + rand(-10, 10) + return null + else + var/md5 = md5(AM.name) + for (var/i in 1 to 32) + . += hex2num(md5[i]) + . = . % 9 + AM.pixel_x = AM.base_pixel_x + ((.%3)*6) + AM.pixel_y = AM.base_pixel_y - 8 + (round( . / 3)*8) + +/** + * Translates styles data into UI compatible format + * + * Expects to receive list of availables condiment styles in its complete format, and transforms them in simplified form with enough data to get UI going. + * Returns list(list("id" = , "className" = , "title" = ),..). + * + * Arguments: + * * styles - List of styles for condiment bottles in internal format: [/obj/machinery/chem_master/proc/get_condi_styles] + */ +/obj/machinery/chem_master/proc/strip_condi_styles_to_icons(list/styles) + var/list/icons = list() + for (var/s in styles) + if (styles[s] && styles[s]["className"]) + var/list/icon = list() + var/list/style = styles[s] + icon["id"] = s + icon["className"] = style["className"] + icon["title"] = "[style["name"]]\n[style["desc"]]" + icons += list(icon) + + return icons + +/** + * Defines and provides list of available condiment bottle styles + * + * Uses typelist() for styles storage after initialization. + * For fallback style must provide style with key (const) CONDIMASTER_STYLE_FALLBACK + * Returns list( + * = list( + * "icon_state" = , + * "name" = , + * "desc" = , + * ?"generate_name" = , + * ?"icon_empty" = , + * ?"fill_icon_thresholds" = , + * ?"inhand_icon_state" = , + * ?"lefthand_file" = , + * ?"righthand_file" = , + * ), + * .. + * ) + * + */ +/obj/machinery/chem_master/proc/get_condi_styles() + var/list/styles = typelist("condi_styles") + if (!styles.len) + //Possible_states has the reagent type as key and a list of, in order, the icon_state, the name and the desc as values. Was used in the condiment/on_reagent_change(changetype) to change names, descs and sprites. + styles += list( + CONDIMASTER_STYLE_FALLBACK = list( + "icon_state" = "emptycondiment", + "icon_empty" = "", + "name" = "condiment bottle", + "desc" = "Just your average condiment bottle.", + // "fill_icon_thresholds" = list(0, 10, 25, 50, 75, 100), + "generate_name" = TRUE, + ), + "enzyme" = list( + "icon_state" = "enzyme", + "icon_empty" = "", + "name" = "universal enzyme bottle", + "desc" = "Used in cooking various dishes.", + ), + "flour" = list( + "icon_state" = "flour", + "icon_empty" = "", + "name" = "flour sack", + "desc" = "A big bag of flour. Good for baking!", + ), + "mayonnaise" = list( + "icon_state" = "mayonnaise", + "icon_empty" = "", + "name" = "mayonnaise jar", + "desc" = "An oily condiment made from egg yolks.", + ), + "milk" = list( + "icon_state" = "milk", + "icon_empty" = "", + "name" = "space milk", + "desc" = "It's milk. White and nutritious goodness!", + ), + "blackpepper" = list( + "icon_state" = "peppermillsmall", + "inhand_icon_state" = "", + "icon_empty" = "emptyshaker", + "name" = "pepper mill", + "desc" = "Often used to flavor food or make people sneeze.", + ), + "rice" = list( + "icon_state" = "rice", + "icon_empty" = "", + "name" = "rice sack", + "desc" = "A big bag of rice. Good for cooking!", + ), + "sodiumchloride" = list( + "icon_state" = "saltshakersmall", + "inhand_icon_state" = "", + "icon_empty" = "emptyshaker", + "name" = "salt shaker", + "desc" = "Salt. From dead crew, presumably.", + ), + "soymilk" = list( + "icon_state" = "soymilk", + "icon_empty" = "", + "name" = "soy milk", + "desc" = "It's soy milk. White and nutritious goodness!", + ), + "soysauce" = list( + "icon_state" = "soysauce", + "inhand_icon_state" = "", + "icon_empty" = "", + "name" = "soy sauce bottle", + "desc" = "A salty soy-based flavoring.", + ), + "sugar" = list( + "icon_state" = "sugar", + "icon_empty" = "", + "name" = "sugar sack", + "desc" = "Tasty spacey sugar!", + ), + "ketchup" = list( + "icon_state" = "ketchup", + "icon_empty" = "", + "name" = "ketchup bottle", + "desc" = "You feel more American already.", + ), + "capsaicin" = list( + "icon_state" = "hotsauce", + "icon_empty" = "", + "name" = "hotsauce bottle", + "desc" = "You can almost TASTE the stomach ulcers!", + ), + "frostoil" = list( + "icon_state" = "coldsauce", + "icon_empty" = "", + "name" = "coldsauce bottle", + "desc" = "Leaves the tongue numb from its passage.", + ), + "cornoil" = list( + "icon_state" = "oliveoil", + "icon_empty" = "", + "name" = "corn oil bottle", + "desc" = "A delicious oil used in cooking. Made from corn.", + ), + "bbqsauce" = list( + "icon_state" = "bbqsauce", + "icon_empty" = "", + "name" = "bbq sauce bottle", + "desc" = "Hand wipes not included.", + ), + "peanut_butter" = list( + "icon_state" = "peanutbutter", + "icon_empty" = "", + "name" = "peanut butter jar", + "desc" = "A creamy paste made from ground peanuts.", + ), + "honey" = list( + "icon_state" = "honey", + "icon_empty" = "", + "name" = "honey bottle", + "desc" = "A cheerful bear-shaped bottle of tasty honey.", + ), + "cherryjelly" = list( + "icon_state" = "cherryjelly", + "icon_empty" = "", + "name" = "cherry jelly jar", + "desc" = "A jar of super-sweet cherry jelly.", + ), + ) + + var/list/carton_in_hand = list( + "inhand_icon_state" = "carton", + "lefthand_file" = 'icons/mob/items/lefthand_kitchen.dmi', + "righthand_file" = 'icons/mob/items/righthand_kitchen.dmi', + ) + for (var/style_reagent in list( + "flour", + "milk", + "rice", + "soymilk", + "sugar", + )) + if (style_reagent in styles) + styles[style_reagent] += carton_in_hand + + var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/condiments) + for (var/reagent in styles) + styles[reagent]["className"] = assets.icon_class_name(reagent) + return styles + +/** + * Provides condiment bottle style based on reagents. + * + * Gets style from available by key, using last part of main reagent type (eg. "rice" for /datum/reagent/consumable/rice) as key. + * If not available returns fallback style, or null if no such thing. + * Returns list that is one of condibottle styles from [/obj/machinery/chem_master/proc/get_condi_styles] + */ +/obj/machinery/chem_master/proc/guess_condi_style(datum/reagents/reagents) + var/list/styles = get_condi_styles() + if (reagents.reagent_list.len > 0) + var/main_reagent = reagents.get_master_reagent_id() + if (main_reagent) + var/list/path = splittext("[main_reagent]", "/") + main_reagent = path[path.len] + if(main_reagent in styles) + return styles[main_reagent] + return styles[CONDIMASTER_STYLE_FALLBACK] + +/** + * Applies style to condiment bottle. + * + * Applies props provided in "style" assuming that "container" is freshly created with no styles applied before. + * User specified name for bottle applied after this method during bottle creation, + * so container.name overwritten here for consistency rather than with some purpose in mind. + * + * Arguments: + * * container - condiment bottle that gets style applied to it + * * style - assoc list, must probably one from [/obj/machinery/chem_master/proc/get_condi_styles] + */ +/obj/machinery/chem_master/proc/apply_condi_style(obj/item/reagent_containers/food/condiment/container, list/style) + container.name = style["name"] + container.desc = style["desc"] + container.icon_state = style["icon_state"] + /* + container.icon_empty = style["icon_empty"] + container.fill_icon_thresholds = style["fill_icon_thresholds"] + if ("inhand_icon_state" in style) + container.inhand_icon_state = style["inhand_icon_state"] + if (style["lefthand_file"] || style["righthand_file"]) + container.lefthand_file = style["lefthand_file"] + container.righthand_file = style["righthand_file"] + */ diff --git a/code/modules/reagents/machinery/dispenser/dispenser2.dm b/code/modules/reagents/machinery/dispenser/dispenser2.dm index c7daebf72f1..8dee2f76afd 100644 --- a/code/modules/reagents/machinery/dispenser/dispenser2.dm +++ b/code/modules/reagents/machinery/dispenser/dispenser2.dm @@ -1,6 +1,6 @@ /obj/machinery/chemical_dispenser name = "chemical dispenser" - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "dispenser" var/list/spawn_cartridges = null // Set to a list of types to spawn one of each on New() diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index a5a770f908d..7cf7053c477 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -1,7 +1,7 @@ /obj/item/reagent_containers name = "Container" desc = "..." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = null w_class = ITEMSIZE_SMALL var/amount_per_transfer_from_this = 5 diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index 9026095e239..f9a600cc51b 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -1,7 +1,7 @@ /obj/item/reagent_containers/borghypo name = "cyborg hypospray" desc = "An advanced chemical synthesizer and injection system, designed for heavy-duty medical equipment." - icon = 'icons/obj/syringe.dmi' + icon = 'icons/obj/medical/syringe.dmi' item_state = "hypo" icon_state = "borghypo" amount_per_transfer_from_this = 5 diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index 1df56bcb91d..7916e35b0a0 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -4,7 +4,7 @@ /obj/item/reagent_containers/dropper name = "dropper" desc = "A dropper. Transfers up to 5 units at a time." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "dropper0" amount_per_transfer_from_this = 5 possible_transfer_amounts = list(1,2,3,4,5) diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 0d20394b73a..0b37d1dfae0 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -7,7 +7,7 @@ var/base_name = " " desc = " " var/base_desc = " " - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "null" item_state = "null" amount_per_transfer_from_this = 10 @@ -144,8 +144,9 @@ /obj/item/reagent_containers/glass/beaker name = "beaker" desc = "A beaker." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "beaker" + base_icon_state = "beaker" item_state = "beaker" matter = list(MAT_GLASS = 500) drop_sound = 'sound/items/drop/glass.ogg' @@ -174,29 +175,30 @@ overlays.Cut() if(reagents.total_volume) - var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]10") + var/image/filling = image('icons/obj/medical/reagentfillings.dmi', src, "[base_icon_state]10") var/percent = round((reagents.total_volume / volume) * 100) switch(percent) - if(0 to 9) filling.icon_state = "[icon_state]-10" - if(10 to 24) filling.icon_state = "[icon_state]10" - if(25 to 49) filling.icon_state = "[icon_state]25" - if(50 to 74) filling.icon_state = "[icon_state]50" - if(75 to 79) filling.icon_state = "[icon_state]75" - if(80 to 90) filling.icon_state = "[icon_state]80" - if(91 to INFINITY) filling.icon_state = "[icon_state]100" + if(0 to 9) filling.icon_state = "[base_icon_state]-10" + if(10 to 24) filling.icon_state = "[base_icon_state]10" + if(25 to 49) filling.icon_state = "[base_icon_state]25" + if(50 to 74) filling.icon_state = "[base_icon_state]50" + if(75 to 79) filling.icon_state = "[base_icon_state]75" + if(80 to 90) filling.icon_state = "[base_icon_state]80" + if(91 to INFINITY) filling.icon_state = "[base_icon_state]100" filling.color = reagents.get_color() overlays += filling if (!is_open_container()) - var/image/lid = image(icon, src, "lid_[initial(icon_state)]") + var/image/lid = image(icon, src, "lid_[base_icon_state]") overlays += lid /obj/item/reagent_containers/glass/beaker/large name = "large beaker" desc = "A large beaker." icon_state = "beakerlarge" + base_icon_state = "beakerlarge" matter = list(MAT_GLASS = 1000) volume = 120 amount_per_transfer_from_this = 10 @@ -207,6 +209,7 @@ name = "cryostasis beaker" desc = "A cryostasis beaker that allows for chemical storage without reactions." icon_state = "beakernoreact" + base_icon_state = "beakernoreact" matter = list(MAT_GLASS = 500) volume = 60 amount_per_transfer_from_this = 10 @@ -216,6 +219,7 @@ name = "bluespace beaker" desc = "A bluespace beaker, powered by experimental bluespace technology." icon_state = "beakerbluespace" + base_icon_state = "beakerbluespace" matter = list(MAT_GLASS = 5000) volume = 300 amount_per_transfer_from_this = 10 @@ -225,7 +229,8 @@ /obj/item/reagent_containers/glass/beaker/vial name = "vial" desc = "A small glass vial." - icon_state = "vial" + icon_state = "vial0" + base_icon_state = "vial" matter = list(MAT_GLASS = 250) volume = 30 w_class = ITEMSIZE_TINY @@ -247,6 +252,7 @@ name = "bucket" icon = 'icons/obj/janitor.dmi' icon_state = "bucket" + base_icon_state = "bucket" item_state = "bucket" matter = list(MAT_STEEL = 200) w_class = ITEMSIZE_NORMAL @@ -302,6 +308,7 @@ name = "wooden bucket" icon = 'icons/obj/janitor.dmi' icon_state = "woodbucket" + base_icon_state = "woodbucket" item_state = "woodbucket" matter = list(MAT_WOOD = 50) w_class = ITEMSIZE_LARGE @@ -338,6 +345,7 @@ name = "water-cooler bottle" icon = 'icons/obj/vending.dmi' icon_state = "water_cooler_bottle" + base_icon_state = "water_cooler_bottle" matter = list(MAT_GLASS = 2000) w_class = ITEMSIZE_NORMAL amount_per_transfer_from_this = 20 @@ -350,6 +358,7 @@ desc = "A small fuel canister used to refuel tools and gear in the field." icon = 'icons/obj/tank.dmi' icon_state = "portable_fuelcan" + base_icon_state = "portable_fuelcan" matter = list("metal" = 2000) w_class = ITEMSIZE_SMALL amount_per_transfer_from_this = 10 @@ -377,6 +386,7 @@ name = "miniature fuel canister" desc = "A tiny fuel canister used to refuel tools and gear in the field. Useful for single recharges." icon_state = "portable_fuelcan_tiny" + base_icon_state = "portable_fuelcan_tiny" matter = list("metal" = 500) w_class = ITEMSIZE_TINY volume = 20 @@ -385,6 +395,7 @@ name = "stone mortar" desc = "A hand-crafted stone mortar, designed to hold ground up herbs and reagents." icon_state = "stonebeaker" + base_icon_state = "stonebeaker" //Vials /obj/item/reagent_containers/glass/beaker/vial/bicaridine diff --git a/code/modules/reagents/reagent_containers/glass/bottle_vr.dm b/code/modules/reagents/reagent_containers/glass/bottle_vr.dm index 765d3095e28..1b7563bb629 100644 --- a/code/modules/reagents/reagent_containers/glass/bottle_vr.dm +++ b/code/modules/reagents/reagent_containers/glass/bottle_vr.dm @@ -1,13 +1,13 @@ /obj/item/reagent_containers/glass/bottle/ickypak name = "ickypak bottle" desc = "A small bottle of ickypak. The smell alone makes you gag." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-3" prefill = list("ickypak" = 60) /obj/item/reagent_containers/glass/bottle/unsorbitol name = "unsorbitol bottle" desc = "A small bottle of unsorbitol. Sickeningly sweet." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-3" prefill = list("unsorbitol" = 60) diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 3173747d602..4c2eeba376f 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -5,7 +5,7 @@ /obj/item/reagent_containers/hypospray name = "hypospray" desc = "The DeForest Medical Corporation hypospray is a sterile, air-needle autoinjector for rapid administration of drugs to patients." - icon = 'icons/obj/syringe.dmi' + icon = 'icons/obj/medical/syringe.dmi' item_state = "hypo" icon_state = "hypo" amount_per_transfer_from_this = 5 diff --git a/code/modules/reagents/reagent_containers/organic.dm b/code/modules/reagents/reagent_containers/organic.dm index 2f276f75c4e..9a3d00ef5c5 100644 --- a/code/modules/reagents/reagent_containers/organic.dm +++ b/code/modules/reagents/reagent_containers/organic.dm @@ -4,7 +4,7 @@ var/base_name = " " desc = " " var/base_desc = " " - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "null" item_state = "null" amount_per_transfer_from_this = 10 diff --git a/code/modules/reagents/reagent_containers/patch.dm b/code/modules/reagents/reagent_containers/patch.dm index a1dcf95262b..21ea964af70 100644 --- a/code/modules/reagents/reagent_containers/patch.dm +++ b/code/modules/reagents/reagent_containers/patch.dm @@ -6,12 +6,11 @@ /obj/item/reagent_containers/pill/patch name = "patch" desc = "A patch." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = null + base_icon_state = "patch" item_state = "pill" - base_state = "patch" - possible_transfer_amounts = null w_class = ITEMSIZE_TINY slot_flags = SLOT_EARS @@ -19,6 +18,28 @@ var/pierce_material = FALSE // If true, the patch can be used through thick material. +//! Non-implemented Subtypes +/* +/obj/item/reagent_containers/pill/patch/libital + name = "libital patch (brute)" + desc = "A pain reliever. Does minor liver damage. Diluted with Granibitaluri." + list_reagents = list(/datum/reagent/medicine/c2/libital = 2, /datum/reagent/medicine/granibitaluri = 8) //10 iterations + icon_state = "bandaid_brute" + +/obj/item/reagent_containers/pill/patch/aiuri + name = "aiuri patch (burn)" + desc = "Helps with burn injuries. Does minor eye damage. Diluted with Granibitaluri." + list_reagents = list(/datum/reagent/medicine/c2/aiuri = 2, /datum/reagent/medicine/granibitaluri = 8) + icon_state = "bandaid_burn" + +/obj/item/reagent_containers/pill/patch/synthflesh + name = "synthflesh patch" + desc = "Helps with brute and burn injuries. Slightly toxic." + list_reagents = list(/datum/reagent/medicine/c2/synthflesh = 20) + icon_state = "bandaid_both" +*/ +//! End ofNon-implemented Subtypes + /obj/item/reagent_containers/pill/patch/attack(mob/M as mob, mob/user as mob) var/mob/living/L = user @@ -27,22 +48,22 @@ var/mob/living/carbon/human/H = M var/obj/item/organ/external/affecting = H.get_organ(check_zone(L.zone_sel.selecting)) if(!affecting) - to_chat(user, "The limb is missing!") + to_chat(user, SPAN_WARNING("The limb is missing!")) return if(affecting.robotic >= ORGAN_ROBOT) - to_chat(user, "\The [src] won't work on a robotic limb!") + to_chat(user, SPAN_WARNING("\The [src] won't work on a robotic limb!")) return if(!H.can_inject(user, FALSE, L.zone_sel.selecting, pierce_material)) - to_chat(user, "\The [src] can't be applied through such a thick material!") + to_chat(user, SPAN_NOTICE("\The [src] can't be applied through such a thick material!")) return if(affecting.open)// you cant place Bandaids on open surgeries, why chemical patches. - to_chat(user, "The [affecting.name] is cut open, you'll need more than a bandage!") + to_chat(user, SPAN_NOTICE("The [affecting.name] is cut open, you'll need more than a bandage!")) return - to_chat(H, "\The [src] is placed on your [affecting].") + to_chat(H, SPAN_NOTICE("\The [src] is placed on your [affecting].")) M.temporarily_remove_from_inventory(src, INV_OP_FORCE) if(reagents.total_volume) reagents.trans_to_mob(M, reagents.total_volume, CHEM_TOUCH) @@ -56,39 +77,43 @@ W.bandage() break;//dont bandage more than one wound, its only one patch you can have in your stack affecting.update_damages() - return 1 + return TRUE else if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M var/obj/item/organ/external/affecting = H.get_organ(check_zone(L.zone_sel.selecting)) if(!affecting) - to_chat(user, "The limb is missing!") + to_chat(user, SPAN_WARNING("The limb is missing!")) return if(affecting.robotic >= ORGAN_ROBOT) - to_chat(user, "\The [src] won't work on a robotic limb!") + to_chat(user, SPAN_NOTICE("\The [src] won't work on a robotic limb!")) return if(!H.can_inject(user, FALSE, L.zone_sel.selecting, pierce_material)) - to_chat(user, "\The [src] can't be applied through such a thick material!") + to_chat(user, SPAN_NOTICE("\The [src] can't be applied through such a thick material!")) return if(affecting.open)// you cant place Bandaids on open surgeries, why chemical patches. - to_chat(user, "The [affecting.name] is cut open, you'll need more than a bandage!") + to_chat(user, SPAN_NOTICE("The [affecting.name] is cut open, you'll need more than a bandage!")) return - user.visible_message("[user] attempts to place \the [src] onto [H]`s [affecting].") + user.visible_message(SPAN_WARNING("[user] attempts to place \the [src] onto [H]`s [affecting].")) user.setClickCooldown(user.get_attack_speed(src)) if(!do_mob(user, M)) return user.temporarily_remove_from_inventory(src, INV_OP_FORCE) - user.visible_message("[user] applies \the [src] to [H].") + user.visible_message(SPAN_WARNING("[user] applies \the [src] to [H].")) + user.visible_message( + SPAN_NOTICE("[user] applies \the [src] to [H]."), + SPAN_NOTICE("You apply \the [src] to [H]."), + ) var/contained = reagentlist() - add_attack_logs(user,M,"Applied a patch containing [contained]") + add_attack_logs(user, M, "Applied a patch containing [contained]") - to_chat(H, "\The [src] is placed on your [affecting].") + to_chat(H, SPAN_NOTICE("\The [src] is placed on your [affecting].")) M.temporarily_remove_from_inventory(src, INV_OP_FORCE) if(reagents.total_volume) @@ -96,14 +121,13 @@ qdel(src) for(var/datum/wound/W in affecting.wounds) - if (W.internal)//ignore internal wounds and check the remaining + if (W.internal) //ignore internal wounds and check the remaining continue - if(W.bandaged)//already bandaged wounds dont need to be bandaged again + if(W.bandaged) //already bandaged wounds dont need to be bandaged again continue W.bandage() - break;//dont bandage more than one wound, its only one patch you can have in your stack + break //dont bandage more than one wound, its only one patch you can have in your stack affecting.update_damages() - return 1 - - return 0 + return TRUE + return FALSE diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index cd22858c95e..f232e8bdd7c 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -4,23 +4,27 @@ /obj/item/reagent_containers/pill name = "pill" desc = "A pill." - icon = 'icons/obj/chemical.dmi' - icon_state = null + icon = 'icons/obj/medical/chemical.dmi' + icon_state = "pill" + base_icon_state = "pill" item_state = "pill" drop_sound = 'sound/items/drop/food.ogg' pickup_sound = 'sound/items/pickup/food.ogg' - var/base_state = "pill" - possible_transfer_amounts = null w_class = ITEMSIZE_TINY slot_flags = SLOT_EARS volume = 60 + /// When set, we allow automatic naming on init. + var/rename_with_volume = FALSE + /obj/item/reagent_containers/pill/Initialize(mapload) . = ..() if(!icon_state) - icon_state = "[base_state][rand(1, 4)]" //preset pills only use colour changing or unique icons + icon_state = "pill[rand(1,20)]" + if(reagents.total_volume && rename_with_volume) + name += " ([reagents.total_volume]u)" /obj/item/reagent_containers/pill/attack(mob/M as mob, mob/user as mob) if(M == user) diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 3b21802540d..bfc04277e6a 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -65,7 +65,7 @@ if(!src) return reagents.trans_to_obj(D, amount_per_transfer_from_this) - D.set_color() + D.color = mix_color_from_reagents(D.reagents.reagent_list) D.set_up(my_target, spray_size, 10) return diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index d31a89fc469..2ec0ad02936 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -5,7 +5,7 @@ /obj/item/reagent_containers/syringe name = "syringe" desc = "A syringe." - icon = 'icons/obj/syringe.dmi' + icon = 'icons/obj/medical/syringe.dmi' item_state = "syringe_0" icon_state = "0" matter = list(MAT_GLASS = 150) diff --git a/code/modules/reagents/reagent_containers/syringes_vr.dm b/code/modules/reagents/reagent_containers/syringes_vr.dm index 5a4cacf6243..4298757eb24 100644 --- a/code/modules/reagents/reagent_containers/syringes_vr.dm +++ b/code/modules/reagents/reagent_containers/syringes_vr.dm @@ -1,5 +1,3 @@ -#define SYRINGE_CAPPED 10 - /obj/item/reagent_containers/syringe icon = 'icons/goonstation/objects/syringe_vr.dmi' mode = SYRINGE_CAPPED //Override diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm index 02a4c025460..39e8fbc40ea 100644 --- a/code/modules/species/species.dm +++ b/code/modules/species/species.dm @@ -155,6 +155,7 @@ /// Name for the species' blood. var/blood_name = "blood" /// Initial blood volume. + /// TODO: Put this on living so this is moreso an override. @Zandario var/blood_volume = 560 /// Multiplier for how fast a species bleeds out. Higher = Faster var/bloodloss_rate = 1 diff --git a/code/modules/xenoarcheaology/artifacts/autocloner.dm b/code/modules/xenoarcheaology/artifacts/autocloner.dm index 786c64ee469..9429d0c9ff2 100644 --- a/code/modules/xenoarcheaology/artifacts/autocloner.dm +++ b/code/modules/xenoarcheaology/artifacts/autocloner.dm @@ -1,7 +1,7 @@ /obj/machinery/auto_cloner name = "mysterious pod" desc = "It's full of a viscous liquid, but appears dark and silent." - icon = 'icons/obj/cryogenics.dmi' + icon = 'icons/obj/medical/cryogenics.dmi' icon_state = "cellold0" var/spawn_type var/time_spent_spawning = 0 diff --git a/code/modules/xenobio/items/extracts.dm b/code/modules/xenobio/items/extracts.dm index 726c6706317..e180a955b6f 100644 --- a/code/modules/xenobio/items/extracts.dm +++ b/code/modules/xenobio/items/extracts.dm @@ -140,7 +140,7 @@ /obj/item/reagent_containers/glass/bottle/metamorphic name = "Metamorphic Metal Bottle" desc = "A small bottle. Contains some really weird liquid metal." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("metamorphic" = 60) @@ -211,7 +211,7 @@ /obj/item/reagent_containers/glass/bottle/binding name = "Binding Metal Bottle" desc = "A small bottle. Contains some really weird liquid metal." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' icon_state = "bottle-4" prefill = list("binding" = 60) diff --git a/code/modules/xenobio/items/slimepotions.dm b/code/modules/xenobio/items/slimepotions.dm index 1f98f2fbaed..31e613711d1 100644 --- a/code/modules/xenobio/items/slimepotions.dm +++ b/code/modules/xenobio/items/slimepotions.dm @@ -3,7 +3,7 @@ /obj/item/slimepotion name = "slime agent" desc = "A flask containing strange, mysterious substances excreted by a slime." - icon = 'icons/obj/chemical.dmi' + icon = 'icons/obj/medical/chemical.dmi' w_class = ITEMSIZE_TINY origin_tech = list(TECH_BIO = 4) diff --git a/code/modules/xenobio2/machinery/gene_manipulators.dm b/code/modules/xenobio2/machinery/gene_manipulators.dm index 593a7bc72b2..e5ca40233d6 100644 --- a/code/modules/xenobio2/machinery/gene_manipulators.dm +++ b/code/modules/xenobio2/machinery/gene_manipulators.dm @@ -257,7 +257,7 @@ /obj/machinery/xenobio/editor name = "biological genetic bombarder" - icon = 'icons/obj/cryogenics.dmi' + icon = 'icons/obj/medical/cryogenics.dmi' icon_state = "cellold0" disk_needs_genes = 1 circuit = /obj/item/circuitboard/biobombarder diff --git a/icons/mob/items/lefthand_kitchen.dmi b/icons/mob/items/lefthand_kitchen.dmi new file mode 100644 index 00000000000..3d8843c8575 Binary files /dev/null and b/icons/mob/items/lefthand_kitchen.dmi differ diff --git a/icons/mob/items/righthand_kitchen.dmi b/icons/mob/items/righthand_kitchen.dmi new file mode 100644 index 00000000000..5f0e2c9264c Binary files /dev/null and b/icons/mob/items/righthand_kitchen.dmi differ diff --git a/icons/obj/chempuff.dmi b/icons/obj/chempuff.dmi deleted file mode 100644 index 811c5e82142..00000000000 Binary files a/icons/obj/chempuff.dmi and /dev/null differ diff --git a/icons/obj/cryogenics.dmi b/icons/obj/cryogenics.dmi deleted file mode 100644 index ae4681657c1..00000000000 Binary files a/icons/obj/cryogenics.dmi and /dev/null differ diff --git a/icons/obj/iv_drip.dmi b/icons/obj/iv_drip.dmi deleted file mode 100644 index 0976a3dc43d..00000000000 Binary files a/icons/obj/iv_drip.dmi and /dev/null differ diff --git a/icons/obj/medical/bloodpack.dmi b/icons/obj/medical/bloodpack.dmi new file mode 100644 index 00000000000..fdbc5bceb9e Binary files /dev/null and b/icons/obj/medical/bloodpack.dmi differ diff --git a/icons/obj/bodybag.dmi b/icons/obj/medical/bodybag.dmi similarity index 100% rename from icons/obj/bodybag.dmi rename to icons/obj/medical/bodybag.dmi diff --git a/icons/obj/medical/chemical.dmi b/icons/obj/medical/chemical.dmi new file mode 100644 index 00000000000..533ca1100a9 Binary files /dev/null and b/icons/obj/medical/chemical.dmi differ diff --git a/icons/obj/medical/chemical_tanks.dmi b/icons/obj/medical/chemical_tanks.dmi new file mode 100644 index 00000000000..41f859b1d9e Binary files /dev/null and b/icons/obj/medical/chemical_tanks.dmi differ diff --git a/icons/obj/medical/chempuff.dmi b/icons/obj/medical/chempuff.dmi new file mode 100644 index 00000000000..012aa081a13 Binary files /dev/null and b/icons/obj/medical/chempuff.dmi differ diff --git a/icons/obj/cryobag.dmi b/icons/obj/medical/cryobag.dmi similarity index 100% rename from icons/obj/cryobag.dmi rename to icons/obj/medical/cryobag.dmi diff --git a/icons/obj/Cryogenic2.dmi b/icons/obj/medical/cryogenic2.dmi similarity index 100% rename from icons/obj/Cryogenic2.dmi rename to icons/obj/medical/cryogenic2.dmi diff --git a/icons/obj/medical/cryogenics.dmi b/icons/obj/medical/cryogenics.dmi new file mode 100644 index 00000000000..1e34ed1477b Binary files /dev/null and b/icons/obj/medical/cryogenics.dmi differ diff --git a/icons/obj/cryogenics_split.dmi b/icons/obj/medical/cryogenics_split.dmi similarity index 100% rename from icons/obj/cryogenics_split.dmi rename to icons/obj/medical/cryogenics_split.dmi diff --git a/icons/obj/defibrillator.dmi b/icons/obj/medical/defibrillator.dmi similarity index 100% rename from icons/obj/defibrillator.dmi rename to icons/obj/medical/defibrillator.dmi diff --git a/icons/obj/medical/iv_drip.dmi b/icons/obj/medical/iv_drip.dmi new file mode 100644 index 00000000000..7e06a0c851d Binary files /dev/null and b/icons/obj/medical/iv_drip.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/medical/og.dmi similarity index 100% rename from icons/obj/chemical.dmi rename to icons/obj/medical/og.dmi diff --git a/icons/obj/reagentfillings.dmi b/icons/obj/medical/reagentfillings.dmi similarity index 100% rename from icons/obj/reagentfillings.dmi rename to icons/obj/medical/reagentfillings.dmi diff --git a/icons/obj/robobag.dmi b/icons/obj/medical/robobag.dmi similarity index 100% rename from icons/obj/robobag.dmi rename to icons/obj/medical/robobag.dmi diff --git a/icons/obj/rollerbed.dmi b/icons/obj/medical/rollerbed.dmi similarity index 100% rename from icons/obj/rollerbed.dmi rename to icons/obj/medical/rollerbed.dmi diff --git a/icons/obj/medical/stack_medical .dmi b/icons/obj/medical/stack_medical .dmi new file mode 100644 index 00000000000..4aee0043103 Binary files /dev/null and b/icons/obj/medical/stack_medical .dmi differ diff --git a/icons/obj/medical/surgery_table.dmi b/icons/obj/medical/surgery_table.dmi new file mode 100644 index 00000000000..2db30fee06d Binary files /dev/null and b/icons/obj/medical/surgery_table.dmi differ diff --git a/icons/obj/medical/surgery_tools.dmi b/icons/obj/medical/surgery_tools.dmi new file mode 100644 index 00000000000..594f0a8d43f Binary files /dev/null and b/icons/obj/medical/surgery_tools.dmi differ diff --git a/icons/obj/medical/syringe.dmi b/icons/obj/medical/syringe.dmi new file mode 100644 index 00000000000..53858ebf549 Binary files /dev/null and b/icons/obj/medical/syringe.dmi differ diff --git a/icons/obj/syringefilling.dmi b/icons/obj/medical/syringefilling.dmi similarity index 100% rename from icons/obj/syringefilling.dmi rename to icons/obj/medical/syringefilling.dmi diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi deleted file mode 100644 index a91f11958e2..00000000000 Binary files a/icons/obj/syringe.dmi and /dev/null differ diff --git a/icons/obj/syringe_vr.dmi b/icons/obj/syringe_vr.dmi deleted file mode 100644 index 3d3473f25f7..00000000000 Binary files a/icons/obj/syringe_vr.dmi and /dev/null differ diff --git a/icons/UI_Icons/condiments/bbqsauce.png b/icons/runtime/assets/condiments/bbqsauce.png similarity index 100% rename from icons/UI_Icons/condiments/bbqsauce.png rename to icons/runtime/assets/condiments/bbqsauce.png diff --git a/icons/UI_Icons/condiments/coldsauce.png b/icons/runtime/assets/condiments/coldsauce.png similarity index 100% rename from icons/UI_Icons/condiments/coldsauce.png rename to icons/runtime/assets/condiments/coldsauce.png diff --git a/icons/UI_Icons/condiments/condi_empty.png b/icons/runtime/assets/condiments/condi_empty.png similarity index 100% rename from icons/UI_Icons/condiments/condi_empty.png rename to icons/runtime/assets/condiments/condi_empty.png diff --git a/icons/UI_Icons/condiments/emptycondiment.png b/icons/runtime/assets/condiments/emptycondiment.png similarity index 100% rename from icons/UI_Icons/condiments/emptycondiment.png rename to icons/runtime/assets/condiments/emptycondiment.png diff --git a/icons/UI_Icons/condiments/enzyme.png b/icons/runtime/assets/condiments/enzyme.png similarity index 100% rename from icons/UI_Icons/condiments/enzyme.png rename to icons/runtime/assets/condiments/enzyme.png diff --git a/icons/UI_Icons/condiments/flour.png b/icons/runtime/assets/condiments/flour.png similarity index 100% rename from icons/UI_Icons/condiments/flour.png rename to icons/runtime/assets/condiments/flour.png diff --git a/icons/UI_Icons/condiments/hotsauce.png b/icons/runtime/assets/condiments/hotsauce.png similarity index 100% rename from icons/UI_Icons/condiments/hotsauce.png rename to icons/runtime/assets/condiments/hotsauce.png diff --git a/icons/UI_Icons/condiments/ketchup.png b/icons/runtime/assets/condiments/ketchup.png similarity index 100% rename from icons/UI_Icons/condiments/ketchup.png rename to icons/runtime/assets/condiments/ketchup.png diff --git a/icons/UI_Icons/condiments/mayonnaise.png b/icons/runtime/assets/condiments/mayonnaise.png similarity index 100% rename from icons/UI_Icons/condiments/mayonnaise.png rename to icons/runtime/assets/condiments/mayonnaise.png diff --git a/icons/UI_Icons/condiments/milk.png b/icons/runtime/assets/condiments/milk.png similarity index 100% rename from icons/UI_Icons/condiments/milk.png rename to icons/runtime/assets/condiments/milk.png diff --git a/icons/UI_Icons/condiments/oliveoil.png b/icons/runtime/assets/condiments/oliveoil.png similarity index 100% rename from icons/UI_Icons/condiments/oliveoil.png rename to icons/runtime/assets/condiments/oliveoil.png diff --git a/icons/UI_Icons/condiments/peppermillsmall.png b/icons/runtime/assets/condiments/peppermillsmall.png similarity index 100% rename from icons/UI_Icons/condiments/peppermillsmall.png rename to icons/runtime/assets/condiments/peppermillsmall.png diff --git a/icons/UI_Icons/condiments/rice.png b/icons/runtime/assets/condiments/rice.png similarity index 100% rename from icons/UI_Icons/condiments/rice.png rename to icons/runtime/assets/condiments/rice.png diff --git a/icons/UI_Icons/condiments/saltshakersmall.png b/icons/runtime/assets/condiments/saltshakersmall.png similarity index 100% rename from icons/UI_Icons/condiments/saltshakersmall.png rename to icons/runtime/assets/condiments/saltshakersmall.png diff --git a/icons/UI_Icons/condiments/soymilk.png b/icons/runtime/assets/condiments/soymilk.png similarity index 100% rename from icons/UI_Icons/condiments/soymilk.png rename to icons/runtime/assets/condiments/soymilk.png diff --git a/icons/UI_Icons/condiments/soysauce.png b/icons/runtime/assets/condiments/soysauce.png similarity index 100% rename from icons/UI_Icons/condiments/soysauce.png rename to icons/runtime/assets/condiments/soysauce.png diff --git a/icons/UI_Icons/condiments/sugar.png b/icons/runtime/assets/condiments/sugar.png similarity index 100% rename from icons/UI_Icons/condiments/sugar.png rename to icons/runtime/assets/condiments/sugar.png diff --git a/icons/runtime/assets/medical/bottles/bottle1.png b/icons/runtime/assets/medical/bottles/bottle1.png new file mode 100644 index 00000000000..6821a1ed3e4 Binary files /dev/null and b/icons/runtime/assets/medical/bottles/bottle1.png differ diff --git a/icons/runtime/assets/medical/bottles/bottle2.png b/icons/runtime/assets/medical/bottles/bottle2.png new file mode 100644 index 00000000000..9195de497d7 Binary files /dev/null and b/icons/runtime/assets/medical/bottles/bottle2.png differ diff --git a/icons/runtime/assets/medical/bottles/bottle3.png b/icons/runtime/assets/medical/bottles/bottle3.png new file mode 100644 index 00000000000..d62dfd56817 Binary files /dev/null and b/icons/runtime/assets/medical/bottles/bottle3.png differ diff --git a/icons/runtime/assets/medical/bottles/bottle4.png b/icons/runtime/assets/medical/bottles/bottle4.png new file mode 100644 index 00000000000..530b5e4edc7 Binary files /dev/null and b/icons/runtime/assets/medical/bottles/bottle4.png differ diff --git a/icons/UI_Icons/patches/bandaid.png b/icons/runtime/assets/medical/patches/patch.png similarity index 100% rename from icons/UI_Icons/patches/bandaid.png rename to icons/runtime/assets/medical/patches/patch.png diff --git a/icons/UI_Icons/patches/bandaid_both.png b/icons/runtime/assets/medical/patches/patch_both.png similarity index 100% rename from icons/UI_Icons/patches/bandaid_both.png rename to icons/runtime/assets/medical/patches/patch_both.png diff --git a/icons/UI_Icons/patches/bandaid_brute.png b/icons/runtime/assets/medical/patches/patch_brute.png similarity index 100% rename from icons/UI_Icons/patches/bandaid_brute.png rename to icons/runtime/assets/medical/patches/patch_brute.png diff --git a/icons/UI_Icons/patches/bandaid_burn.png b/icons/runtime/assets/medical/patches/patch_burn.png similarity index 100% rename from icons/UI_Icons/patches/bandaid_burn.png rename to icons/runtime/assets/medical/patches/patch_burn.png diff --git a/icons/UI_Icons/pills/pill1.png b/icons/runtime/assets/medical/pills/pill1.png similarity index 100% rename from icons/UI_Icons/pills/pill1.png rename to icons/runtime/assets/medical/pills/pill1.png diff --git a/icons/UI_Icons/pills/pill10.png b/icons/runtime/assets/medical/pills/pill10.png similarity index 100% rename from icons/UI_Icons/pills/pill10.png rename to icons/runtime/assets/medical/pills/pill10.png diff --git a/icons/UI_Icons/pills/pill11.png b/icons/runtime/assets/medical/pills/pill11.png similarity index 100% rename from icons/UI_Icons/pills/pill11.png rename to icons/runtime/assets/medical/pills/pill11.png diff --git a/icons/UI_Icons/pills/pill12.png b/icons/runtime/assets/medical/pills/pill12.png similarity index 100% rename from icons/UI_Icons/pills/pill12.png rename to icons/runtime/assets/medical/pills/pill12.png diff --git a/icons/UI_Icons/pills/pill13.png b/icons/runtime/assets/medical/pills/pill13.png similarity index 100% rename from icons/UI_Icons/pills/pill13.png rename to icons/runtime/assets/medical/pills/pill13.png diff --git a/icons/UI_Icons/pills/pill14.png b/icons/runtime/assets/medical/pills/pill14.png similarity index 100% rename from icons/UI_Icons/pills/pill14.png rename to icons/runtime/assets/medical/pills/pill14.png diff --git a/icons/UI_Icons/pills/pill15.png b/icons/runtime/assets/medical/pills/pill15.png similarity index 100% rename from icons/UI_Icons/pills/pill15.png rename to icons/runtime/assets/medical/pills/pill15.png diff --git a/icons/UI_Icons/pills/pill16.png b/icons/runtime/assets/medical/pills/pill16.png similarity index 100% rename from icons/UI_Icons/pills/pill16.png rename to icons/runtime/assets/medical/pills/pill16.png diff --git a/icons/UI_Icons/pills/pill17.png b/icons/runtime/assets/medical/pills/pill17.png similarity index 100% rename from icons/UI_Icons/pills/pill17.png rename to icons/runtime/assets/medical/pills/pill17.png diff --git a/icons/UI_Icons/pills/pill18.png b/icons/runtime/assets/medical/pills/pill18.png similarity index 100% rename from icons/UI_Icons/pills/pill18.png rename to icons/runtime/assets/medical/pills/pill18.png diff --git a/icons/UI_Icons/pills/pill19.png b/icons/runtime/assets/medical/pills/pill19.png similarity index 100% rename from icons/UI_Icons/pills/pill19.png rename to icons/runtime/assets/medical/pills/pill19.png diff --git a/icons/UI_Icons/pills/pill2.png b/icons/runtime/assets/medical/pills/pill2.png similarity index 100% rename from icons/UI_Icons/pills/pill2.png rename to icons/runtime/assets/medical/pills/pill2.png diff --git a/icons/UI_Icons/pills/pill20.png b/icons/runtime/assets/medical/pills/pill20.png similarity index 100% rename from icons/UI_Icons/pills/pill20.png rename to icons/runtime/assets/medical/pills/pill20.png diff --git a/icons/UI_Icons/pills/pill21.png b/icons/runtime/assets/medical/pills/pill21.png similarity index 100% rename from icons/UI_Icons/pills/pill21.png rename to icons/runtime/assets/medical/pills/pill21.png diff --git a/icons/UI_Icons/pills/pill22.png b/icons/runtime/assets/medical/pills/pill22.png similarity index 100% rename from icons/UI_Icons/pills/pill22.png rename to icons/runtime/assets/medical/pills/pill22.png diff --git a/icons/UI_Icons/pills/pill3.png b/icons/runtime/assets/medical/pills/pill3.png similarity index 100% rename from icons/UI_Icons/pills/pill3.png rename to icons/runtime/assets/medical/pills/pill3.png diff --git a/icons/UI_Icons/pills/pill4.png b/icons/runtime/assets/medical/pills/pill4.png similarity index 100% rename from icons/UI_Icons/pills/pill4.png rename to icons/runtime/assets/medical/pills/pill4.png diff --git a/icons/UI_Icons/pills/pill5.png b/icons/runtime/assets/medical/pills/pill5.png similarity index 100% rename from icons/UI_Icons/pills/pill5.png rename to icons/runtime/assets/medical/pills/pill5.png diff --git a/icons/UI_Icons/pills/pill6.png b/icons/runtime/assets/medical/pills/pill6.png similarity index 100% rename from icons/UI_Icons/pills/pill6.png rename to icons/runtime/assets/medical/pills/pill6.png diff --git a/icons/UI_Icons/pills/pill7.png b/icons/runtime/assets/medical/pills/pill7.png similarity index 100% rename from icons/UI_Icons/pills/pill7.png rename to icons/runtime/assets/medical/pills/pill7.png diff --git a/icons/UI_Icons/pills/pill8.png b/icons/runtime/assets/medical/pills/pill8.png similarity index 100% rename from icons/UI_Icons/pills/pill8.png rename to icons/runtime/assets/medical/pills/pill8.png diff --git a/icons/UI_Icons/pills/pill9.png b/icons/runtime/assets/medical/pills/pill9.png similarity index 100% rename from icons/UI_Icons/pills/pill9.png rename to icons/runtime/assets/medical/pills/pill9.png diff --git a/icons/runtime/placeholder b/icons/runtime/placeholder deleted file mode 100644 index 522ee0789dd..00000000000 --- a/icons/runtime/placeholder +++ /dev/null @@ -1 +0,0 @@ -placeholder file, delete when folder used. diff --git a/tgui/docs/component-reference.md b/tgui/docs/component-reference.md index c5963e4ab0c..77c4fa38d49 100644 --- a/tgui/docs/component-reference.md +++ b/tgui/docs/component-reference.md @@ -14,6 +14,7 @@ Make sure to add new items to this list if you document new components. - [`AnimatedNumber`](#animatednumber) - [`BlockQuote`](#blockquote) - [`Box`](#box) + - [Box Units](#box-units) - [`Button`](#button) - [`Button.Checkbox`](#buttoncheckbox) - [`Button.Confirm`](#buttonconfirm) @@ -137,7 +138,7 @@ This way, `Button` can pull out the `className` generated by the `Box`. ``` -**Box Units** +#### Box Units `Box` units, like width, height and margins can be defined in two ways: @@ -222,7 +223,7 @@ Buttons allow users to take actions, and make choices, with a single click. - `selected: boolean` - Activates the button (gives it a green color). - `tooltip: string` - A fancy, boxy tooltip, which appears when hovering over the button. -- `tooltipPosition?: string` - Position of the tooltip. See [`Popper`](#Popper) for valid options. +- `tooltipPosition?: string` - Position of the tooltip. See [`Popper`](#popper) for valid options. - `ellipsis: boolean` - If button width is constrained, button text will be truncated with an ellipsis. Be careful however, because this prop breaks the baseline alignment. @@ -280,7 +281,7 @@ interface. Example (button): -``` +```dm { - const { - className, - children, - ...rest - } = props; +export const Modal = (props) => { + const { className, children, ...rest } = props; return (
{children}
diff --git a/tgui/packages/tgui/interfaces/ChemMaster.js b/tgui/packages/tgui/interfaces/ChemMaster.js deleted file mode 100644 index 633d87b04ab..00000000000 --- a/tgui/packages/tgui/interfaces/ChemMaster.js +++ /dev/null @@ -1,487 +0,0 @@ -import { Fragment } from 'inferno'; -import { useBackend } from "../backend"; -import { Box, Button, Flex, Icon, LabeledList, Section } from "../components"; -import { Window } from "../layouts"; -import { BeakerContents } from './common/BeakerContents'; -import { ComplexModal, modalOpen, modalRegisterBodyOverride } from './common/ComplexModal'; - -const transferAmounts = [1, 5, 10, 30, 60]; -const bottleStyles = [ - "bottle.png", - "small_bottle.png", - "wide_bottle.png", - "round_bottle.png", - "reagent_bottle.png", -]; - -const analyzeModalBodyOverride = (modal, context) => { - const { act, data } = useBackend(context); - const result = modal.args.analysis; - return ( -
- - - - {result.name} - - - {(result.desc || "").length > 0 ? result.desc : "N/A"} - - {result.blood_type && ( - - - {result.blood_type} - - - {result.blood_dna} - - - )} - {!data.condi && ( -
- ); -}; - -export const ChemMaster = (props, context) => { - const { data } = useBackend(context); - const { - condi, - beaker, - beaker_reagents = [], - buffer_reagents = [], - mode, - } = data; - return ( - - - - 0} - /> - - 0} - /> - {/* */} - - - ); -}; - -const ChemMasterBeaker = (props, context) => { - const { act, data } = useBackend(context); - const { - beaker, - beakerReagents, - bufferNonEmpty, - } = props; - - let headerButton = bufferNonEmpty ? ( - act('eject')} - /> - ) : ( - - - - - - - ); -}; - -const ChemMasterProductionCondiment = (props, context) => { - const { act } = useBackend(context); - return ( - - + ))} + + )} + {!condi && ( + setPillAmount(value)} + onCreate={() => + act('create', { + type: 'pill', + amount: pillAmount, + volume: 'auto', + })} + /> + )} + {!condi && ( + + {patch_styles.map((patch) => ( + + ))} + + )} + {!condi && ( + setPatchAmount(value)} + onCreate={() => + act('create', { + type: 'patch', + amount: patchAmount, + volume: 'auto', + })} + /> + )} + {!condi && ( + + {bottle_styles.map((bottle) => ( + + ))} + + )} + {!condi && ( + setBottleAmount(value)} + onCreate={() => + act('create', { + type: 'bottle', + amount: bottleAmount, + volume: 'auto', + })} + /> + )} + {!!condi && ( + + + act('change_condi_style', { + id: auto_condi_style_chosen ? condi_styles[0].id : auto_condi_style, + })} + checked={auto_condi_style_chosen} + disabled={!condi_styles.length}> + Guess from contents + + + )} + {!!condi && !auto_condi_style_chosen && ( + + {condi_styles.map((style) => ( + + ))} + + )} + {!!condi && ( + setBottleAmount(value)} + onCreate={() => + act('create', { + type: 'condiment_bottle', + amount: bottleAmount, + volume: 'auto', + })} + /> + )} + {!!condi && ( + setPackAmount(value)} + onCreate={() => + act('create', { + type: 'condiment_pack', + amount: packAmount, + volume: 'auto', + })} + /> + )} + + ); +}; + +const AnalysisResults = (props, context) => { + const { act, data } = useBackend(context); + const { analyzeVars } = data; + return ( +
+ act('goScreen', { + screen: 'home', + })} + /> + }> + + {analyzeVars.name} + {analyzeVars.state} + {/* {analyzeVars.ph} */} + + + {analyzeVars.color} + + + {analyzeVars.description} + + + {analyzeVars.metaRate} + + + {analyzeVars.overD} + + {/* + {analyzeVars.addicD} + */} + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/ChemPress.js b/tgui/packages/tgui/interfaces/ChemPress.js index f9df812c2b1..75d86bc8930 100644 --- a/tgui/packages/tgui/interfaces/ChemPress.js +++ b/tgui/packages/tgui/interfaces/ChemPress.js @@ -7,11 +7,13 @@ export const ChemPress = (props, context) => { const { current_volume, product_name, - pill_style, - pill_styles = [], product, min_volume, max_volume, + bottle_style, + bottle_styles = [], + pill_style, + pill_styles = [], patch_style, patch_styles = [], } = data; @@ -86,17 +88,16 @@ export const ChemPress = (props, context) => { ))} )} - {product === "patch" && ( - - {patch_styles.map(patch => ( + {!condi && ( + + {patch_styles.map((patch) => ( ))} diff --git a/tgui/packages/tgui/interfaces/common/ComplexModal.js b/tgui/packages/tgui/interfaces/common/ComplexModal.tsx similarity index 85% rename from tgui/packages/tgui/interfaces/common/ComplexModal.js rename to tgui/packages/tgui/interfaces/common/ComplexModal.tsx index d46dde0d7fd..37a97e88ffc 100644 --- a/tgui/packages/tgui/interfaces/common/ComplexModal.js +++ b/tgui/packages/tgui/interfaces/common/ComplexModal.tsx @@ -3,6 +3,14 @@ import { Box, Button, Dropdown, Flex, Input, Modal } from '../../components'; let bodyOverrides = {}; +type ModalData = { + id: number; + text: string; + type: string; + uid: string; + modal: any; +}; + /** * Sends a call to BYOND to open a modal * @param {any} context The React context @@ -10,7 +18,7 @@ let bodyOverrides = {}; * @param {object=} args The arguments to pass to the modal */ export const modalOpen = (context, id, args) => { - const { act, data } = useBackend(context); + const { act, data } = useBackend(context); const newArgs = Object.assign(data.modal ? data.modal.args : {}, args || {}); act('modal_open', { @@ -30,7 +38,7 @@ export const modalRegisterBodyOverride = (id, bodyOverride) => { }; const modalAnswer = (context, id, answer, args) => { - const { act, data } = useBackend(context); + const { act, data } = useBackend(context); if (!data.modal) { return; } @@ -68,7 +76,7 @@ const modalClose = (context, id) => { * @param {object} context */ export const ComplexModal = (props, context) => { - const { data } = useBackend(context); + const { data } = useBackend(context); if (!data.modal) { return; } @@ -87,7 +95,7 @@ export const ComplexModal = (props, context) => { icon="arrow-left" content="Cancel" color="grey" - onClick={() => modalClose(context)} + onClick={() => modalClose(context, null)} /> ); @@ -96,7 +104,7 @@ export const ComplexModal = (props, context) => { modalBody = bodyOverrides[id](data.modal, context); } else if (type === "input") { const [curValue, setCurValue] = useLocalState(context, 'curValue' + data.modal.uid.toString(), data.modal.value.toString()); - modalOnEnter = e => modalAnswer(context, id, curValue); + modalOnEnter = e => modalAnswer(context, id, curValue, null); modalBody = ( { icon="arrow-left" content="Cancel" color="grey" - onClick={() => modalClose(context)} + onClick={() => modalClose(context, null)} /> @@ -169,7 +177,7 @@ export const ComplexModal = (props, context) => { color="bad" float="left" mb="0" - onClick={() => modalAnswer(context, id, 0)} + onClick={() => modalAnswer(context, id, 0, null)} />